|
Antwort |
Registriert seit: 9. Jun 2004 Ort: Leipzig 105 Beiträge Delphi 7 Enterprise |
#1
Hallo Leute,
langsam verstehe ich den VST. Habe mir für die Bearbeitung eine ComboBox gebastelt und sie nach Anleitung der Hilfe von VST eingebunden. Allerdings bin ich in der Komponentenentwicklung noch "unterentwickelt", heißt ich habe nch gar keine Erfahrungen damit. Als erstes: es läuft alles wie's soll, aber:
So, wenn ihr Zeit und Lust habt schaut euch das bitte mal an und sagt mir bitte, wie ich die obigen Punkte "beheben" kann. Als erstes muss halt die Procedur SetItems eingefügt werden:
Delphi-Quellcode:
Dann hab ich mir die ComboBox erstellt:
IVTEditLink = interface
['{2BE3EAFA-5ACB-45B4-9D9A-B58BCC496E17}'] function BeginEdit: Boolean; stdcall; // Called when editing actually starts. function CancelEdit: Boolean; stdcall; // Called when editing has been cancelled by the tree. function EndEdit: Boolean; stdcall; // Called when editing has been finished by the tree. function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall; // Called after creation to allow a setup. function GetBounds: TRect; stdcall; // Called to get the current size of the edit window // (only important if the edit resizes itself). procedure ProcessMessage(var Message: TMessage); stdcall; // Used to forward messages to the edit window(s)- procedure SetBounds(R: TRect); stdcall; // Called to place the editor. procedure SetItems(List: TStringList); stdcall; end;
Delphi-Quellcode:
Und als nächstes den EditLink:
TVTComboBox = class(TCustomComboBox)
private FRefLink: IVTEditLink; FLink: TComboBoxEditLink; procedure CMAutoAdjust(var Message: TMessage); message CM_AUTOADJUST; procedure CMExit(var Message: TMessage); message CM_EXIT; procedure CMRelease(var Message: TMessage); message CM_RELEASE; procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; procedure WMChar(var Message: TWMChar); message WM_CHAR; procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY; procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE; procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN; protected procedure AutoAdjustSize; procedure CreateParams(var Params: TCreateParams); override; public constructor Create(Link: TComboBoxEditLink); reintroduce; procedure Release; virtual; property AutoComplete; property CharCase; property Items; property MaxLength; property Sorted; property Style; end;
Delphi-Quellcode:
Hier die Funktionen/Procedure für die TVTComboBox
TComboBoxEditLink = class(TInterfacedObject, IVTEditLink)
private FList: TStringList; FEdit: TVTComboBox; FTree: TCustomVirtualStringTree; FNode: PVirtualNode; FColumn: TColumnINdex; FAlignment: TAlignment; FTextBounds: TRect; FStopping: Boolean; FStartIndex: Integer; procedure SetEdit(const Value: TVTComboBox); public constructor Create; destructor Destroy; override; function BeginEdit: Boolean; virtual; stdcall; function CancelEdit: Boolean; virtual; stdcall; property ComboBoxEdit: TVTComboBox read FEdit write SetEdit; function EndEdit: Boolean; virtual; stdcall; function GetBounds: TRect; virtual; stdcall; function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall; procedure ProcessMessage(var Message: TMessage); virtual; stdcall; procedure SetBounds(R: TRect); virtual; stdcall; procedure SetItems(List: TStringList); virtual; stdcall; end;
Delphi-Quellcode:
Und zum Schluss das ganze für den TComboBoxEditLink:
//******************************************************************************
//****************************************************************************** //****************************************************************************** constructor TVTComboBox.Create(Link: TComboBoxEditLink); begin inherited Create(nil); ShowHint := False; ParentShowHint := False; FRefLink := Link; FLink := Link; end; //****************************************************************************** procedure TVTComboBox.CMAutoAdjust(var Message: TMessage); begin AutoAdjustSize; end; //****************************************************************************** procedure TVTComboBox.CMExit(var Message: TMessage); begin if Assigned(FLink) and NOT FLink.FStopping then with FLink, FTree do begin if (toAutoAcceptEditChange in TreeOptions.StringOptions) then DoEndEdit else DoCancelEdit; end; end; //****************************************************************************** procedure TVTComboBox.CMRelease(var Message: TMessage); begin Free; end; //****************************************************************************** procedure TVTComboBox.CNCommand(var Message: TWMCommand); begin if Assigned(FLink) and Assigned(FLink.FTree) and (Message.NotifyCode = EN_UPDATE) and NOT (toGridExtensions in FLink.FTree.FOptions.FMiscOptions) and NOT (vsMultiLine in FLink.FNode.States) then if False and IsWinNT then AutoAdjustSize else PostMessage(Handle, CM_AUTOADJUST, 0, 0); end; //****************************************************************************** procedure TVTComboBox.WMChar(var Message: TWMChar); begin if NOT (Message.CharCode in [VK_ESCAPE, VK_TAB]) then inherited; end; //****************************************************************************** procedure TVTComboBox.WMDestroy(var Message: TWMDestroy); begin if Assigned(FLink) and NOT FLink.FStopping then begin with FLink, FTree do begin if (toAutoAcceptEditChange in TreeOptions.StringOptions) and DroppedDown then Text[FNode, FColumn] := FEdit.Text; end; FLink := nil; FRefLink := nil; end; inherited; end; //****************************************************************************** procedure TVTComboBox.WMGetDlgCode(var Message: TWMGetDlgCode); begin inherited; Message.Result := Message.Result or DLGC_WANTALLKEYS or DLGC_WANTTAB or DLGC_WANTARROWS; end; //****************************************************************************** procedure TVTComboBox.WMKeyDown(var Message: TWMKeyDown); var Shift: TShiftState; EndEdit: Boolean; Tree: TBaseVirtualTree; begin case Message.CharCode of VK_ESCAPE: begin Tree := FLink.FTree; FLink.FTree.DoCancelEdit; Tree.SetFocus; end; VK_RETURN: begin EndEdit := NOT (vsMultiLine in FLink.FNode.States); if NOT EndEdit then begin Shift := KeyDataToShiftState(Message.KeyData); EndEdit := ssCtrl in Shift; end; if EndEdit then begin Tree := FLink.FTree; FLink.FTree.InvalidateNode(FLink.FNode); FLink.FTree.DoEndEdit; Tree.SetFocus; end; end; VK_UP: begin if NOT (vsMultiLine in FLink.FNode.States) then Message.CharCode := VK_LEFT; inherited; end; VK_DOWN: begin if NOT (vsMultiLine in FLink.FNode.States) then Message.CharCode := VK_RIGHT; inherited; end; else inherited; end; end; //****************************************************************************** procedure TVTComboBox.AutoAdjustSize; var DC: HDC; Size: TSize; LastFont: THandle; begin if NOT (vsMultiLine in FLink.FNode.States) then begin SendMessage(Handle, WM_SETREDRAW, 0, 0); DC := GetDC(Handle); LastFont := SelectObject(DC, Font.Handle); try GetTextExtentPoint32(DC, PChar(Text), Length(Text), Size); Inc(Size.cx, 2 * FLink.FTree.FTextMargin); if Size.cx < Width then FLink.FTree.InvalidateNode(Flink.FNode); if FLink.FAlignment = taRightJustify then FLink.SetBounds(Rect(Left + Width - Size.cx, Top, Left + Width, Top + Height)) else FLink.SetBounds(Rect(Left, Top, Left + Size.cx, Top + Height)); finally SelectObject(DC, LastFont); ReleaseDC(Handle, DC); SendMessage(Handle, WM_SETREDRAW, 0, 0); end; end; end; //****************************************************************************** procedure TVTComboBox.CreateParams(var Params: TCreateParams); begin inherited; with Params do begin Style := Style or ES_MULTILINE; if (vsMultiLine in FLink.FNode.States) then Style := Style and NOT (ES_AUTOHSCROLL or WS_HSCROLL) or WS_VSCROLL or ES_AUTOVSCROLL; if (tsUseThemes in FLink.FTree.FStates) then begin Style := Style and NOT WS_BORDER; ExStyle := ExStyle or WS_EX_CLIENTEDGE; end else begin Style := Style or WS_BORDER; ExStyle := ExStyle and NOT WS_EX_CLIENTEDGE; end; end; end; //****************************************************************************** procedure TVTComboBox.Release; begin if HandleAllocated then PostMessage(Handle, CM_RELEASE, 0, 0); end; //****************************************************************************** //****************************************************************************** //******************************************************************************
Delphi-Quellcode:
//******************************************************************************
//****************************************************************************** //****************************************************************************** constructor TComboBoxEditLink.Create; begin inherited; FEdit := TVTComboBox.Create(Self); with FEdit do begin Visible := False; AutoSize := False; AutoComplete := False; Style := csDropDownList; Sorted := True; end; end; //****************************************************************************** destructor TComboBoxEditLink.Destroy; begin FEdit.Release; inherited; end; //****************************************************************************** function TComboBoxEditLink.BeginEdit: Boolean; begin Result := NOT FStopping; if Result then begin FEdit.Show; FEdit.SetFocus; end; end; //****************************************************************************** procedure TComboBoxEditLink.SetEdit(const Value: TVTComboBox); begin if Assigned(FEdit) then FEdit.Free; FEdit := Value; end; //****************************************************************************** function TComboBoxEditLink.CancelEdit: Boolean; begin Result := NOT FStopping; if Result then begin FStopping := True; FEdit.Hide; FTree.CancelEditNode; FEdit.FLink := nil; FEdit.FRefLink := nil; end; end; //****************************************************************************** function TComboBoxEditLink.EndEdit: Boolean; begin Result := NOT FStopping; if Result then try FStopping := True; if FEdit.ItemIndex <> FStartIndex then FTree.Text[FNode, FColumn] := FEdit.Text; FEdit.Hide; FEdit.FLink := nil; FEdit.FRefLink := nil; except FStopping := False; end; end; //****************************************************************************** function TComboBoxEditLink.GetBounds: TRect; begin Result := Fedit.BoundsRect; end; //****************************************************************************** function TComboBoxEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; var Text: WideString; i: Integer; begin FStartIndex := -1; Result := Tree is TCustomVirtualStringTree; if Result then begin FTree := Tree as TCustomVirtualStringTree; FNode := Node; FColumn := Column; FTree.GetTextInfo(Node, Column, FEdit.Font, FTextBounds, Text); FEdit.Font.Color := clBlack; FEdit.Parent := Tree; FEdit.RecreateWnd; FEdit.HandleNeeded; if Assigned(FList) then begin for i := 0 to FList.Count-1 do begin FEdit.Items.Add(FList.Strings[i]); if FEdit.Items.Strings[i] = Text then FEdit.ItemIndex := i; end; FStartIndex := FEdit.ItemIndex; end; if Column <= NoColumn then begin FEdit.BiDiMode := FTree.BiDiMode; FAlignment := FTree.Alignment; end else begin FEdit.BiDiMode := FTree.Header.Columns[Column].BiDiMode; FAlignment := FTree.Header.Columns[Column].Alignment; end; if FEdit.BiDiMode <> bdLeftToRight then ChangeBidiModeAlignment(FAlignment); end; end; //****************************************************************************** procedure TComboBoxEditLink.ProcessMessage(var Message: TMessage); begin FEdit.WindowProc(Message); end; //****************************************************************************** procedure TComboBoxEditLink.SetBounds(R: TRect); var Offset: Integer; begin if NOT FStopping then begin with R do begin if Left < 0 then Left := 0; if Right - Left < 30 then begin if FAlignment = taRightJustify then Left := Right - 30 else Right := Left + 30; end; if Right > FTree.ClientWidth then Right := FTree.ClientWidth; FEdit.BoundsRect := R; R := FEdit.ClientRect; Offset := 2; if (tsUseThemes in FTree.FStates) then Inc(Offset); InflateRect(R, -FTree.FTextMargin + Offset, Offset); if NOT (vsMultiLine in FNode.States) then OffsetRect(R, 0, FTextBounds.Top - FEdit.Top); SendMessage(FEdit.Handle, EM_SETRECTNP, 0, Integer(@R)); end; end; end; //****************************************************************************** procedure TComboBoxEditLink.SetItems(List: TStringList); var i: Integer; begin FList := TStringList.Create; for i := 0 to List.Count - 1 do begin FList.Add(List.Strings[i]); end; end; //****************************************************************************** //****************************************************************************** //****************************************************************************** //****************************************************************************** Eingebunden habe ich das dann über das OnCreateEditor-Ereignis des VST:
Delphi-Quellcode:
GenreList ist übrigens vom Typ TStringList
procedure TFMain.VSTLibraryCreateEditor(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink); begin case Column of 3: begin EditLink := TComboBoxEditLink.Create; EditLink.SetItems(GenreList); end; else EditLink := TStringEditLink.Create; end; end; So, ich hoffe ich hab euch jetzt nicht mit Code erschlagen
Thomas Maßmann
"...ihr würdet selbst den lieben Gott einbetonieren, wenn eure Datenbank ihn eines Tag's erfasst..." H.-R.-Kunze Auch Delphi 9 Preview-Inhaber bin |
Zitat |
Registriert seit: 24. Feb 2003 Ort: Graz (A) 705 Beiträge Delphi 7 Enterprise |
#2
Hallo Thomas,
ich habe Deinen Code jetzt nicht durchgesehen, aber es gibt bei den VirtualTree-Demos unter "Advanced" die PropertiesDemo.
Delphi-Quellcode:
Dabei demonstriert Mike z.B. einen NodeEditor mit einer ComboBox, vielleicht wirst Du ja dort fündig.
// Virtual Treeview sample form demonstrating following features:
// - Property page like string tree with individual node editors. // - Incremental search. // Written by Mike Lischke. Das Patchen der VirtualTrees.pas würde ich nicht empfehlen.
Armin P. Pressler
BEGIN ...real programmers are using C/C++ - smart developers Delphi; END; |
Zitat |
Registriert seit: 9. Jun 2004 Ort: Leipzig 105 Beiträge Delphi 7 Enterprise |
#3
Das hab ich mir auch schon angesehen. Als ich es so probiert habe, ist mein ganzes Projekt gecrashed. Zum Glück hatte ich ein Backup
Am besten lernt man durch probieren... PS: Anbei mal ein Bild wie's aussieht
Thomas Maßmann
"...ihr würdet selbst den lieben Gott einbetonieren, wenn eure Datenbank ihn eines Tag's erfasst..." H.-R.-Kunze Auch Delphi 9 Preview-Inhaber bin |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |