Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   OpenDirDialog (https://www.delphipraxis.net/96316-opendirdialog.html)

ASM 24. Aug 2010 17:12

AW: OpenDirDialog
 
Obwohl die Komponente ja auch zur Verwendung für Delphi 7 angegeben ist, kann ich sie nicht unter D7 zum Laufen bringen. Zwar wird sie bei ihrer Installation in die Komponenten-Palette scheinbar fehlerfrei kompiliert und in die Palette übernommen. Aber bei dem Versuch, aus der Palette eine Instanz dieser Komponente in eine Form aufzunehmen, wird dies mit der Fehlermeldung einer "Access violation" im entsprechenden bpl-Module vereitelt. Die gleiche "Access violation" tritt auf, wenn ich versuche, eine Instanz von TOpenDirDialog zur Laufzeit dynamisch zu generieren.

Allerdings habe ich in der Typdeklaration von TTreeView = class(TCustomTreeView) die published Properties
OnMouseActivate, OnMouseEnter und OnMouseLeave auskommentieren müssen, da sich der D7-Kompiler ansonsten mit einer Errormessage beklagt hatte, dass diese Properties nicht in der Basisklasse existieren. Möglicherweise hängt das o.g. Problem mit dem folglichen Fehlen dieser Properties zusammen ?

Auch TCustomTreeView (das aus der TTreeView abgeleitet ist) wird in der Komponentenunit gfOpenDirDlg deklariert, tatsächlich ohne diese genannten Properties. Diese müssten sich also von der nächst tieferen Basisklasse, das ist TWinControl, vererben, welche in der Unit Controls deklariert ist. Tun sie aber nicht. Dort gibt es Eventhandler für verschiedene OnMouse-Events, aber definitiv keine, die den o.g. (eben nicht vorhandenen) Properties zugewiesen wären,

Heißt das nun, dass die aktuelle Komponente grundsätzlich nicht mehr für D7 eingesetzt werden kann ?
Und wenn ja, wäre es dann möglich, noch einmal Zugriff auf die ursprüngliche, D7-kompatible Version der Komponente zu bekommen ?

Garfield 26. Aug 2010 00:28

AW: OpenDirDialog
 
Hallo ASM,

vielen Dank für Deinen Bericht.

Unter Delphi 7 Personal fing es an. Dann kam Turbo Delphi dazu und ab Build 10 entfiel Delphi 7. Leider muss ich zugeben, dass ich die Komponente genauso wie in der Demo nur zur Laufzeit einbinde und nicht installiert habe.

Die Classes TCustomTreeView und TTreeView habe ich aus TurboDelphi kopiert und angepasst. Die Properties OnMouseActivate, OnMouseEnter und OnMouseLeave dürften wohl nach Delphi 7 dazugekommen sein. Das scheint auch für einige ControlStyles zuzutreffen.

Mal sehen, was da machen kann.

Garfield 27. Aug 2010 00:18

AW: OpenDirDialog
 
Liste der Anhänge anzeigen (Anzahl: 1)
Jetzt läuft die Komponente unter D7 und TD. Allerdings mit dem Unterschied, dass unter D7 kein Text im TreeView ist. Warum weiß ich allerdings nicht; die Unterschiede in der Komponente sind nicht allerdings nicht dafür ursächlich. Entweder habe ich noch einen Fehler in der Komponente oder es liegt an den TNT Controls.

Garfield 28. Aug 2010 01:25

AW: OpenDirDialog
 
Sieht so aus, als würde Delphi 7 die Widestrings trotz TNT Controls nicht im TreeView anzeigen können.

Möglicherweis hängt es mit den Events TTVCustomDrawEvent, TTVCustomDrawItemEvent, TTVAdvancedCustomDrawEvent und TTVAdvancedCustomDrawItemEvent zusammen.

Garfield 28. Aug 2010 16:41

AW: OpenDirDialog
 
Es scheint an der procedure TCustomTreeViewW.CNNotify(var Message: TWMNotify); zu hängen. Bei TurboDelphi wird diese ab dem ShowModal ständig aufgerufen und das Tree neu gezeichnet. Bei Delphi 7 nicht.

Garfield 28. Aug 2010 18:41

AW: OpenDirDialog
 
Also die Messages kommen doch. Allerdings anstelle der *W die *A, obwohl der Tree auf Unicode eingestellt sein sollte.

Garfield 29. Aug 2010 20:21

AW: OpenDirDialog
 
Warum auch immer wird anscheinend aus dem TTreeViewW beim ShowModal ein TTreeViewA. Das habe ich im Moment nicht so hinbekommen wie ich es mir gewünscht habe. Deshalb habe ich die Versionen, welche anstelle des TTreeView noch das TShellTreeView verwenden durchgesehen und bei der letzten ein paar Fehler, welche nicht unter Turbo Delphi aber unter Delphi 7 aufgetreten sind, bereinigt. Die Komponente samt Demo gibt es im ersen Beitrag (OpenDirDialog_9a.7z).

himitsu 29. Aug 2010 20:42

AW: OpenDirDialog
 
Das ältere Delphi hat nur die ANSI-APIs in seiner Message-Loop.

Garfield 29. Aug 2010 21:24

AW: OpenDirDialog
 
Ich habe die TTreeView teilweise aus TurboDelphi kopiert und modifiziert. Bevor das Treeview angezeigt wird, werden auch WideMessages verschickt. Nur müssen da die Widestrings der Nodes zur Anzeige in Strings konvertiert werden. Wenn das Treeview angezeigt wird, gibt es nur noch Ansimessages. Ich habe den Eindruck, ich habe zu wenig kopiert.

himitsu 29. Aug 2010 21:41

AW: OpenDirDialog
 
Messages werden in die Message-Queue eingetragen
und die Message-Loop in Application.Run, bzw. Application.ProcessMessages fragen nur über die Ansi-APIs die Message-Queue ab und leiten dann diese Messages als "ANSI" an die Komponenten weiter.

Delphi 7 hat eine reine Ansi-MessageLoop, wärend in Turbo Delphi für Unicode-Messages auf die Unicode-API umgeschaltet wird.


Delphi-Quellcode:
// Delphi 7-MessageLoop

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
  Handled: Boolean;
begin
  Result := False;
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  begin
    Result := True;
    if Msg.Message <> WM_QUIT then
    begin
      Handled := False;
      if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
      if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
        not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
    end
    else
      FTerminate := True;
  end;
end;
Delphi-Quellcode:
// Turbo Delphi-, bzw. Delphi 2006-MessageLoop

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
  Unicode: Boolean;
  Handled: Boolean;
  MsgExists: Boolean;
begin
  Result := False;
  if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
  begin
    Unicode := (Msg.hwnd <> 0) and IsWindowUnicode(Msg.hwnd);
    if Unicode then
      MsgExists := PeekMessageW(Msg, 0, 0, 0, PM_REMOVE)
    else
      MsgExists := PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
    if not MsgExists then Exit;
    Result := True;
    if Msg.Message <> WM_QUIT then
    begin
      Handled := False;
      if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
      if not IsPreProcessMessage(Msg) and not IsHintMsg(Msg) and
        not Handled and not IsMDIMsg(Msg) and
        not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
      begin
        TranslateMessage(Msg);
        if Unicode then
          DispatchMessageW(Msg)
        else
          DispatchMessage(Msg);
      end;
    end
    else
      FTerminate := True;
  end;
end;
Schon erstaunlich wann man bei Codegear anfing sich für's Unicode vorzubereiten, wärend Einige jetzt erst rumheulen, wegen D2009+ :roll:

Garfield 29. Aug 2010 22:37

AW: OpenDirDialog
 
:? Ein Teil Unicode muss schon enthalten sein. Zumindest sind einige Konstanten und Funktionen bereits in D7 enthalten bzw. bekannt. Muss morgen mal weitersehen. Ich will es ja am liebsten in nonVCL weitermachen, aber das will nicht so ganz.

himitsu 30. Aug 2010 07:14

AW: OpenDirDialog
 
Wenn man selber Messages verschickt und dort der "Text" nur als zusätzlicher/unabhängiger Parameter mit übergeben wird, dann passiert nichts,
aber wenn man TextMessages nutzt, bei welchen explizit Text angegeben wird, dann wird dieses in Delphi 7, durch die Ansi-WinAPI, nach ANSI übersetzt.

Vielleicht hilft es dir ja etwas:
Delphi-Quellcode:
Uses Windows, Messages, ActiveX, ShlObj;

Type TFolderRec = Record
    Title, Caption, Folder: PWideChar;
  End;
  PFolderRec = ^TFolderRec;

Function FolderCallback(Dlg: HWND; Msg: LongWord; LParam: Pointer; Data: PFolderRec): LongWord; StdCall;
  Var Temp: Array[0..MAX_PATH-1] of WideChar;

  Begin
    Case Msg of
      BFFM_INITIALIZED: Begin
        If Data^.Title <> nil Then
          SendMessageW(Dlg, WM_SETTEXT, 0, Integer(Data^.Title));
        If Data^.Folder <> nil Then
          SendMessage(Dlg, BFFM_SETSELECTION, LongInt(True), Integer(Data^.Folder));
      End;
      BFFM_SELCHANGED: Begin
        SHGetPathFromIDListW(PItemIDList(LParam), @Temp);
        If SendMessageW(Dlg, BFFM_SETSTATUSTEXT, 0, LongWord(@Temp)) = 0 Then
          SetWindowTextW(GetDlgItem(Dlg, 14146), PWideChar(WideString(Data^.Caption)
            + sLineBreak + sLineBreak + Temp));
      End;
      BFFM_VALIDATEFAILED: Begin
        Result := 1;
        Exit;
      End;
    End;
    Result := 0;
  End;

Function BrowseForFolder(Wnd: HWND; Const Title, Caption, PreSelectedFolder: WideString; AllowNewFolder: Boolean; Var SelectedDir: WideString): Boolean;
  Var BI:      TBrowseInfo;
    FolderRec: TFolderRec;
    pidlResult: PItemIDList;
    Temp:      Array[0..MAX_PATH-1] of WideChar;
    Malloc:    IMalloc;

  Begin
    Result := False;
    ZeroMemory(@BI, SizeOf(TBrowseInfo));
    BI.hwndOwner := Wnd;
    BI.lpszTitle := PWideChar(Caption);
    BI.ulFlags  := BIF_STATUSTEXT {or BIF_NEWDIALOGSTYLE} or BIF_SHAREABLE or BIF_RETURNONLYFSDIRS;
    BI.lpfn     := @FolderCallBack;
    BI.lParam   := Integer(@FolderRec);
    If not AllowNewFolder Then BI.ulFlags := BI.ulFlags or BIF_NONEWFOLDERBUTTON;
    FolderRec.Title  := PWideChar(Title);
    FolderRec.Caption := PWideChar(Caption);
    FolderRec.Folder := PWideChar(PreSelectedFolder);
    pidlResult       := SHBrowseForFolderW(BI);
    If pidlResult = nil Then Exit;
    If SHGetPathFromIdListW(pidlResult, @Temp[0]) Then Begin
      Result     := True;
      SelectedDir := Temp;
    End;
    If SHGetMalloc(Malloc) = S_OK Then
      Try
        Malloc.Free(pidlResult);
      Finally
        Malloc := nil;
      End;
  End;
Ich nutzte diesen Code allerdings selber nur mit Char/PChar/String und weiß jetzt nicht, ob er auch in Delphi 7 läuft.
In TDE lief er zwar auch als UnicodeVersion, aber das hat ja nicht viel zu sagen.

Wie gesagt, bei sowas wie SendMessage+WM_SETTEXT und SetWindowText mußt du aufpassen, da diese nach Ansi übersetzt werden könnten.

Garfield 30. Aug 2010 09:19

AW: OpenDirDialog
 
Unter Turbo Delphi wird der Text so zugewiesen:
Delphi-Quellcode:
    TVN_GETDISPINFOW:
    with PTVDispInfoW(NMHdr)^
    do begin
      Node := GetNodeFromItem(item);
      if Node <> nil
      then begin
        if (item.mask and TVIF_TEXT) <> 0
        then lStrCpyNW(item.pszText, PWideChar(Node.Text), item.cchTextMax - 1);
        if (item.mask and TVIF_IMAGE) <> 0
        then begin
          GetImageIndex(Node);
          item.iImage := Node.ImageIndex;
        end;
        if (item.mask and TVIF_SELECTEDIMAGE) <> 0
        then begin
          GetSelectedIndex(Node);
          item.iSelectedImage := Node.SelectedIndex;
        end;
      end;
    end;
Unter Delphi 7 hat man dann einen leeren Eintrag und muss Node.Text in einen String umwandeln, damit man einen Text bekommt.

Garfield 5. Okt 2010 13:51

AW: OpenDirDialog
 
Kleines Update.

05.10.2010 - Build 15
  • destructor TOpenDirDialog.Destroy entfernt.
  • procedure TOpenDirDialog.FormClose eingefügt.
  • Auswertung von DelphiCompilerVersionen eingefügt.
  • Root war als String anstelle als Widestring deklariert.
Die beiden Formulare werden mit ShowModal angezeigt. Deshalb habe ich für diese ein FormClose mit der Zeile "Action := caFree;" eingefügt. Das Überschreiben von Destroy ist nicht notwendig und wurde entfernt.

David Martens 27. Jun 2011 13:28

AW: OpenDirDialog
 
Die Komponente unterstützt anscheinend Delphi XE nicht.

Ich kann sie installieren aber auf die Oberfläche lässt es sich nicht ziehen.

Code:
  // Delphi XE
  {$ifdef VER220}
    {$define DELPHI_10_UP}
    {$define DELPHI_9_UP}
    {$define DELPHI_7_UP}
  {$endif}
habe ich schon hinzugefügt.

edit:

keiner eine Idee?

So, ich hab nicht dem Problem nochmal angenommen. Was bei mir hilft ist ein
Delphi-Quellcode:
inherited;
im
Delphi-Quellcode:
constructor
.

Ist zwar schon besser als der alte W*-Kram, aber immer noch nicht das was ich haben will. --> Win7 -> Rechtsklick(Taskleiste) -> "Neue Symbolleiste..."

Ich hab mich schon wund gesucht (wohl auch wegen dem verschwundenen Plus Operator in google). Ich kann einfach keine Möglichkeit finden (noch nicht mal für andere Sprachen)


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:38 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz