Autor Beitrag
schitho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Sa 05.06.04 23:06 
Hi,

ich verwende folgenden Code aus SwissDelphiCenter, um eine Dialogbox zur Auswahl von Ordnern anzeigen zu lassen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
{....}

uses
  ShlObj, ActiveX;

{....}


{
  This code shows the SelectDirectory dialog with additional expansions:
  - an edit box, where the user can type the path name,
  - also files can appear in the list,
  - a button to create new directories.


  Dieser Code zeigt den SelectDirectory-Dialog mit zusätzlichen Erweiterungen:
  - eine Edit-Box, wo der Benutzer den Verzeichnisnamen eingeben kann,
  - auch Dateien können in der Liste angezeigt werden,
  - eine Schaltfläche zum Erstellen neuer Verzeichnisse.
}


function AdvSelectDirectory(const Caption: stringconst Root: WideString;
  var Directory: string; EditBox: Boolean = False; ShowFiles: Boolean = False;
  AllowCreateDirs: Boolean = True): Boolean;
  // callback function that is called when the dialog has been initialized
  //or a new directory has been selected

  // Callback-Funktion, die aufgerufen wird, wenn der Dialog initialisiert oder
  //ein neues Verzeichnis selektiert wurde
  function SelectDirCB(Wnd: HWND; uMsg: UINT; lParam, lpData: lParam): Integer;
    stdcall;
  var
    PathName: array[0..MAX_PATH] of Char;
  begin
    case uMsg of
      BFFM_INITIALIZED: SendMessage(Wnd, BFFM_SETSELECTION, Ord(True), Integer(lpData));
      // include the following comment into your code if you want to react on the
      //event that is called when a new directory has been selected
      // binde den folgenden Kommentar in deinen Code ein, wenn du auf das Ereignis
      //reagieren willst, das aufgerufen wird, wenn ein neues Verzeichnis selektiert wurde
      {BFFM_SELCHANGED:
      begin
        SHGetPathFromIDList(PItemIDList(lParam), @PathName);
        // the directory "PathName" has been selected
        // das Verzeichnis "PathName" wurde selektiert
      end;}

    end;
    Result := 0;
  end;
var
  WindowList: Pointer;
  BrowseInfo: TBrowseInfo;
  Buffer: PChar;
  RootItemIDList, ItemIDList: PItemIDList;
  ShellMalloc: IMalloc;
  IDesktopFolder: IShellFolder;
  Eaten, Flags: LongWord;
const
  // necessary for some of the additional expansions
  // notwendig für einige der zusätzlichen Erweiterungen
  BIF_USENEWUI = $0040;
  BIF_NOCREATEDIRS = $0200;
begin
  Result := False;
  if not DirectoryExists(Directory) then
    Directory := '';
  FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
  if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nilthen
  begin
    Buffer := ShellMalloc.Alloc(MAX_PATH);
    try
      RootItemIDList := nil;
      if Root <> '' then
      begin
        SHGetDesktopFolder(IDesktopFolder);
        IDesktopFolder.ParseDisplayName(Application.Handle, nil,
          POleStr(Root), Eaten, RootItemIDList, Flags);
      end;
      OleInitialize(nil);
      with BrowseInfo do
      begin
        hwndOwner := Application.Handle;
        pidlRoot := RootItemIDList;
        pszDisplayName := Buffer;
        lpszTitle := PChar(Caption);
        // defines how the dialog will appear:
        // legt fest, wie der Dialog erscheint:
        ulFlags := BIF_RETURNONLYFSDIRS or BIF_USENEWUI or
          BIF_EDITBOX * Ord(EditBox) or BIF_BROWSEINCLUDEFILES * Ord(ShowFiles) or
          BIF_NOCREATEDIRS * Ord(not AllowCreateDirs);
        lpfn    := @SelectDirCB;
        if Directory <> '' then
          lParam := Integer(PChar(Directory));
      end;
      WindowList := DisableTaskWindows(0);
      try
        ItemIDList := ShBrowseForFolder(BrowseInfo);
      finally
        EnableTaskWindows(WindowList);
      end;
      Result := ItemIDList <> nil;
      if Result then
      begin
        ShGetPathFromIDList(ItemIDList, Buffer);
        ShellMalloc.Free(ItemIDList);
        Directory := Buffer;
      end;
    finally
      ShellMalloc.Free(Buffer);
    end;
  end;
end;


// Example:
procedure TForm1.Button1Click(Sender: TObject);
var
  dir: string;
begin
  AdvSelectDirectory('Caption''c:\', dir, False, False, True);
  Label1.Caption := dir;
end;


Wie muss ich den Code verändern, damit das Fenster zentriert angezeigt wird?

Gruß
Thomas

_________________
(Sorry! Leider ewiger Delphi-Neuling)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 06.06.04 14:53 
Zentrier das Fenster in der Callback-Funktion mit SetWindowPos.
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: So 06.06.04 20:30 
Hi,

versteh ich das richtig:

Zuerst mit Screen.Width bzw. Screen.Hight die Bildschirmgröße, dann mit GetWindowRect die Fenstergröße ermitteln. Daraus die neuen Koordinaten errechnen. Dann diese neuen Koordinaten mit SetWindowPos festlegen.

Geht das so?

Gruß
Thomas

_________________
(Sorry! Leider ewiger Delphi-Neuling)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 07.06.04 12:48 
Ich an deiner Stelle hätte da smalö eben schnell ausprobiert, anstatt 24 Stunden auf eine Antwort zu warten. ;)
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Mo 07.06.04 17:56 
Luckie hat folgendes geschrieben:
Ich an deiner Stelle hätte da smalö eben schnell ausprobiert, anstatt 24 Stunden auf eine Antwort zu warten. ;)


Hätte ich eh gemacht, wenn ich dafür die Zeit gehabt hätte. Außerdem dachte ich mir, dass es vielleicht auch einen Windows-Befehl gibt, der für die Zentrierung sorgt.

Muss man denn alles selber machen :wink:

Gruß
Thomas

_________________
(Sorry! Leider ewiger Delphi-Neuling)
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 07.06.04 18:01 
schitho hat folgendes geschrieben:
Muss man denn alles selber machen :wink:

Arbeitest du mit Windows?
Ist der Papst katholisch?

:mrgreen:
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Mo 07.06.04 18:08 
MathiasSimmack hat folgendes geschrieben:

Arbeitest du mit Windows?
:mrgreen:


Manchmal - ja leider :nut:

_________________
(Sorry! Leider ewiger Delphi-Neuling)
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Mo 07.06.04 23:12 
Nun zurück zu meinem ursprünglichen Problem:

Ich hab probeweise in der Callback Funktion am Ende folgende Zeile angefügt:

ausblenden Delphi-Quelltext
1:
SetWindowPos(wnd,wnd,20,20,100,500,0);					


Doch leider bewirkt diese Zeile gar nichts. Das Fenster öffnet sich noch immer an der ursprünglichen Stelle.

Was ist daran falsch?

Die Callback-Funktion sieht nun so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
 function SelectDirCB(Wnd: HWND; uMsg: UINT; lParam, lpData: lParam): Integer;
    stdcall;
  var
    PathName: array[0..MAX_PATH] of Char;
    FRect : TRect; // ***** Hab ich ergänzt *****

  begin
    case uMsg of
      BFFM_INITIALIZED: SendMessage(Wnd, BFFM_SETSELECTION, Ord(True), Integer(lpData));
      // include the following comment into your code if you want to react on the
      //event that is called when a new directory has been selected
      // binde den folgenden Kommentar in deinen Code ein, wenn du auf das Ereignis
      //reagieren willst, das aufgerufen wird, wenn ein neues Verzeichnis selektiert wurde
      {BFFM_SELCHANGED:
      begin
        SHGetPathFromIDList(PItemIDList(lParam), @PathName);
        // the directory "PathName" has been selected
        // das Verzeichnis "PathName" wurde selektiert
      end;}

    end;
    SetWindowPos(wnd,wnd,20,20,100,500,0); // ***** Hab ich auch ergänzt ***** 
    Result := 0;
  end;


Danke für Eure Hilfe

Gruß
Thomas

_________________
(Sorry! Leider ewiger Delphi-Neuling)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 07.06.04 23:31 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function SelectDirCB(Wnd: HWND; uMsg: UINT; lParam, lpData: lParam): Integer; 
    stdcall
  var 
    PathName: array[0..MAX_PATH] of Char; 
    FRect : TRect; // ***** Hab ich ergänzt ***** 

  begin 
    case uMsg of 
      BFFM_INITIALIZED: 
      begin
        SendMessage(Wnd, BFFM_SETSELECTION, Ord(True), Integer(lpData)); 
        SetWindowPos(wnd,wnd,20,20,100,500,0); // ***** Hab ich auch ergänzt *****
      end;
      {BFFM_SELCHANGED: 
      begin 
        SHGetPathFromIDList(PItemIDList(lParam), @PathName); 
        // the directory "PathName" has been selected 
        // das Verzeichnis "PathName" wurde selektiert 
      end;}
 
    end
    Result := 0
  end;
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Di 08.06.04 00:03 
Hallo Luckie!

Danke für Deine prompte Antwort.

Doch leider funktioniert das auch nicht. Das Fenster befindet sich nicht an der angegebenen Position. :cry:

Hast Du noch eine Idee, woran das liegen könnte?

Gruß
Thomas

_________________
(Sorry! Leider ewiger Delphi-Neuling)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 08.06.04 00:14 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
// Callback-Funktion, die aufgerufen wird, wenn der Dialog initialisiert oder
  //ein neues Verzeichnis selektiert wurde
  function SelectDirCB(Wnd: HWND; uMsg: UINT; lParam, lpData: lParam): Integer;
    stdcall;
  var
    PathName: array[0..MAX_PATH] of Char;
  begin
    case uMsg of
      BFFM_INITIALIZED:
      begin
        SendMessage(Wnd, BFFM_SETSELECTION, Ord(True), Integer(lpData));
        SetWindowPos(Wnd, 0202000, SWP_NOSIZE or SWP_SHOWWINDOW);
      end;
    end;
    Result := 0;
  end;

Geht. :roll:
schitho Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 288

XP Home SP2
D2005 Prof
BeitragVerfasst: Di 08.06.04 00:33 
Danke für Deine Hilfe

Gruß
Thomas

_________________
(Sorry! Leider ewiger Delphi-Neuling)