2007. augusztus 22., szerda

Center the Windows "Browse for folder" directory picker on screen


Problem/Question/Abstract:

I am using a function from the ShlObj unit to select a networked computer via a Computer Browser. The browser window is called with SHBrowseForFolder(BrowseInfo), the window displayed always seems to position itself in the lower right of the screen. Is it possible to programatically reposition the window to be centered on the screen?

Answer:

Yes, you provide a browse callback function for this task.

uses
  ActiveX, ShlObj;

function CenterVertical(const rect: TRect; h: Integer): Integer;
begin
  Result := (rect.bottom + rect.top - h) div 2;
end;

function CenterHorizontal(const rect: TRect; w: Integer): Integer;
begin
  Result := (rect.right + rect.left - w) div 2;
end;

function BrowserCallback(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer
  stdcall;
var
  r1, r2: TRect;
begin
  result := 0;
  if uMsg = BFFM_INITIALIZED then
  begin
    GetWindowRect(wnd, r1);
    r2 := Rect(0, 0, Screen.Width, Screen.Height);
    MoveWindow(wnd, CenterHorizontal(r2, r1.Right - r1.left), CenterVertical(r2,
      r1.Bottom - r1.Top),
      r1.Right - r1.Left, r1.Bottom - r1.Top, false);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  browseinfo: TBrowseInfo;
  pidl: PItemIDList;
  buf: array[0..MAX_PATH] of Char;
begin
  fillchar(browseinfo, SizeOf(browseinfo), 0);
  browseinfo.hwndOwner := Handle;
  browseinfo.lpszTitle := 'Select directory';
  browseinfo.ulFlags := BIF_RETURNONLYFSDIRS or BIF_NEWDIALOGSTYLE;
  browseinfo.lpfn := BrowserCallback;
  pidl := ShBrowseForFolder(browseinfo);
  if Assigned(pidl) then
  begin
    ShGetPathfromIDList(pidl, buf);
    ShowMessage(buf);
    CoTaskMemFree(pidl);
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése