🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #4210

Re: Positioning the SHBrowseForFolder window

#4210
From: Dennis Jones
Date: Tue, 07 Mar 2006 03:59
142 lines
5491 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:440cd987$1@newsgroups.borland.com...

Remy,

Thank you for your reply.  However...  ;-)


> The callback function receives the BFFM_INITIALIZED notification when the
> dialog has been fully initialized.  You can then query the dialog's
current
> size and then re-position it as needed.

Yes, but my point is that the size that is returned for the window is NOT
correct.  Please read on...


> > Thus, if I try to execute my centering code from anywhere within the
> > BrowseCallbackProc function, it is always too early because the
> > window's size has not been updated yet.
>
> Works fine when I use it.

Yes, of course it does, because you failed to set the BIF_NEWDIALOGSTYLE
flag, without which you cannot resize the browse window!  If I couldn't
resize the browse window, I wouldn't be having any trouble either!  The
whole point of this discussion was to find out why it won't restore to its
previous size *before* I need to center it.  So, try setting the
BIF_NEWDIALOGSTYLE flag in your code first (note: you will need to use
CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) for that flag to work),
then do the following:

Resize the browse window (any arbitrarily large size will do -- stretch it
horizontally, for example), then close the window, then re-open it.  It will
not re-open centered on the desired form.  It will always get positioned as
if the browse window were opened at its (apparently) default size at the
time that it gets centered.  Then after it gets resized, it appears offset
from the desired form, after which the BrowseCallbackProc function will not
be called again, thereby preventing any opportunity to re-position the
window using its restored size.

Your sample code is very similar to mine, with the exception that I don't
pass the form pointer in bi.lParam because I need it for the initial
directory (thus, the form's handle comes from elsewhere) and, of course, the
*necessary* BIF_NEWDIALOGSTYLE flag.   Here is my code:

(And since I know how you think, Remy, I'm gonna head you off at the pass --
forget about the call to CenterWindowTo() -- it is not at fault.  You will
find that your centering code will not work as expected either.)

int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /*lParam*/,
LPARAM lpData)
{
  LPITEMIDLIST  pidl = NULL;

  SHPathToPIDL( (char *)lpData, &pidl );

  switch (uMsg) {
    case BFFM_INITIALIZED:
      ::SendMessage(hwnd, BFFM_SETSELECTION, false, (LPARAM)pidl);

      CenterWindowTo( hwnd, TFileMonitorDialog::hBrowseOwner );
      break;
  }

  // Global pointer to the shell's IMalloc interface.
  LPMALLOC g_pMalloc;

  // Get the shell's allocator.
  if (!SUCCEEDED(SHGetMalloc(&g_pMalloc)))
    return false;

  g_pMalloc->Free(pidl);

  return 0;
}

bool BrowseForFolder(HWND hWnd, char *buf, char *prompt)
{
  // Global pointer to the shell's IMalloc interface.
  LPMALLOC g_pMalloc = NULL;

  // Get the shell's allocator.
  if (!SUCCEEDED(SHGetMalloc(&g_pMalloc)))
    return false;

  LPITEMIDLIST pidlMyComputer = NULL;  // PIDL for MyComputer folder

  // Get the PIDL for the Desktop folder.
  if (!SUCCEEDED(SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP,
&pidlMyComputer)))
    return false;

  HRESULT hResult = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );  //
required for BIF_NEWDIALOGSTYLE
  if ( hResult != S_OK && hResult != S_FALSE )
  {
    // Free the PIDL returned by SHGetSpecialFolderLocation
    g_pMalloc->Free(pidlMyComputer);
    pidlMyComputer = NULL;

    return false;
  }

  BROWSEINFO bi;
  memset( &bi, 0, sizeof(bi) );

  // Fill in the BROWSEINFO structure.
  bi.hwndOwner = hWnd;
  bi.pidlRoot = pidlMyComputer;
  bi.pszDisplayName = buf;
  bi.lpszTitle = prompt;
  bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS |
BIF_NEWDIALOGSTYLE;
  bi.lpfn = BrowseCallbackProc;
  bi.lParam = (LPARAM)buf;

  // Browse for a folder and return its PIDL.
  LPITEMIDLIST pidlBrowse = SHBrowseForFolder(&bi);

  CoUninitialize();

  bool result = (pidlBrowse != 0);
  if (result)
  {
    if (!SHGetPathFromIDList(pidlBrowse, buf))
      result = false;

    // Free the PIDL returned by SHBrowseForFolder.
    g_pMalloc->Free(pidlBrowse);
    pidlBrowse = NULL;
  }

  // Free the PIDL returned by SHGetSpecialFolderLocation
  g_pMalloc->Free(pidlMyComputer);
  pidlMyComputer = NULL;

  return result;
}

- Dennis
Technical Details
Message-ID: <440d053b$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!news3.google.com!news.glorb.com!npeer.de.kpn-eurorings.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <440cc788$1@newsgroups.borland.com> <440cd987$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,722adf2ba600e8df
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Dennis Jones" <nospam@nospam.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <440cc788$1@newsgroups.borland.com> <440cd987$1@newsgroups.borland.com>
Subject: Re: Positioning the SHBrowseForFolder window
Date: Mon, 6 Mar 2006 19:59:57 -0800
Lines: 144
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1106
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
NNTP-Posting-Host: 204.200.27.7
Message-ID: <440d053b$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1141703995 204.200.27.7 (6 Mar 2006 19:59:55 -0700)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!news3.google.com!news.glorb.com!npeer.de.kpn-eurorings.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail