How to customize a BrowseForFolder dialog

2 01 2009

description2

 

 

We all are familiar with BrowseForFolder dialog. A shell type dialog contains SysTreeView32 control, OK button, Cancel button etc. Does anybody face a situation like to customize this dialog?

That means how to add some custom controls to this dialog or how to rearrange the already existing child controls.

Please look at the image, I have customized the default browse for folder dialog by adding some custom controls to it. This could be achieved by using some Win32 APIs like SetWindowPos, FindWindowEx,GetClientRect, CreateWindowEx etc.

custombrowseforfolderdlg

mycodesnippet2

 

 

Where firstly declare the lpfn to the BrowseCallbackProc procedure. Which is a callback function. Then whenever the browse for folder dialog box initializes it will invoke this callback function with “BFFM_INITIALIZED” as the message. That time we could create custom controls on the dialog.

#define BROWSE_WIDTH      380
#define BROWSE_HEIGHT     530
HWND g_hMyEditBox;
void ShowCustomBrowseForFolderDlg()
{
   BROWSEINFO bi  = { 0 };
   bi.lpszTitle   = _T("Pick a Directory");
   bi.lpfn        = BrowseCallbackProc;
  
   LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
}
int BrowseCallbackProc( HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)
{
  
   //Initialization callback message
   if(BFFM_INITIALIZED == uMsg)
   {      
      RECT rtDialog,rtButton;
      RECT DesktopRect;
     
      // Get the desktop window
      HWND hDesktop = ::GetDesktopWindow();
     
      // Get the Desktop rect
      ::GetWindowRect(hDesktop, &DesktopRect);
     
      // Move the window to center
      ::MoveWindow(p_hWnd, (DesktopRect.right/2)-(BROWSE_WIDTH/2) ,(DesktopRect.bottom/2)-(BROWSE_HEIGHT/2), BROWSE_WIDTH, BROWSE_HEIGHT, TRUE);
     
      //Find the listview
      HWND hListView = FindWindowEx(p_hWnd,NULL,"SysTreeView32",NULL);
     
      //Find the handles of OK and Cancel buttons
      HWND hOKButton     = FindWindowEx(p_hWnd, NULL, "Button", NULL);
      HWND hCancelButton = FindWindowEx(p_hWnd, OKButton, "Button", NULL);     
     
      //Gets the OK button position
      ::GetClientRect(hOKButton,&rtButton);
     
      //Gets the dimensions BrowseForFolder dialog
      ::GetClientRect(p_hWnd,&rtDialog);
     
      //Relocate the SysTreeView32 control
      ::SetWindowPos( hListView,0,10 , 43, 360,300,0);
     
      //Relocate the OK button
      ::SetWindowPos( hOKButton, 0, 230,460,60,30,0);
     
      //Relocate the Cancel buttton
      ::SetWindowPos( hCancelButton, 0,300,460,60,30,0);
     
      //Create a static control
      HWND hMyStaticCtrl = CreateWindowEx( 0,"STATIC","My Custom Controls",SS_NOTIFY|WS_CHILD|WS_VISIBLE ,20,370,200,25,p_hWnd,0,NULL,NULL);
     
      //Create a radio button
      HWND hMyRaioBtn = CreateWindowEx( 0,"BUTTON","RadioButton",SS_NOTIFY|WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,20,400,200,20,p_hWnd,0,NULL,NULL);
     
      //Create an Edit box
      g_hMyEditBox = CreateWindowEx( 0,"EDIT","",SS_NOTIFY|WS_CHILD|WS_VISIBLE|WS_BORDER,20,430,340,20,p_hWnd,0,NULL,NULL);
   }
   //Selection change message
   else if(BFFM_SELCHANGED == uMsg)
 {
      TCHAR szDir[MAX_PATH*2] = { 0 };
     
      // fail if non-filesystem
      BOOL bRet = SHGetPathFromIDList((LPITEMIDLIST) lParam, szDir);
     
      if(bRet)
      {
         // set the folder path to edit box
         FromHandle(g_hMyEditBox)->SetWindowText(szDir);
      }
   }
  
   return 1;
}

mynote2

 

 

BROWSEINFO structure Contains parameters for the SHBrowseForFolder function and receives information about the folder selected by the user.

Advertisements

Actions

Information

5 responses

2 04 2011
Ron

This piece of code is excellent, I have been using it as my first tutorial into Visual C++.
I was wondering if you know how to fix this next project, I am simply trying to find one of the open windows ( it is the Browser window ) using FindWindow(NULL,WINDOWTITLE), with a specific Title string. Once I get the handle of the window, I need the coordinates using GetWindowRect.
Not very successful at it :

struct WindowInfo
{
HWND m_hWnd;
string m_title;
WindowInfo(HWND hwnd, string title) : m_hWnd(hwnd), m_title(title) {}
};

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
vector & windows = *(vector*)lParam;
char title[256];

HANDLE wndHandle;
LPCWSTR WINDOWTITLE = L”eBargain 2 Share – Windpos Internet Explorer”;
RECT rRect;
LPRECT lpRect;
RECT rc;

hwnd = FindWindow(NULL,WINDOWTITLE);

GetWindowRect(hwnd,&rc);
printf(“Position: %d x %d\tSize: %d x %d\n”,rc.left,rc.top,rc.right- rc.left,rc.bottom-rc.top);

/* Enumerating through all the windows tells me that I am on the right track… (Should I just try to find the TITLE STRING by comparing every title from the following enumeration ?
*/
GetWindowTextA(hwnd, title, 256);
windows.push_back(new WindowInfo(hwnd,title));
// printf(“%s\n”, title);
return TRUE;

}
int main()
{
vector windows;
BOOL ret = EnumWindows(EnumWindowsProc, (LPARAM) &windows);
if ( ret )
{
//windows have windowinfo of all enumerated windows
}
}

3 04 2011
Sanoop S P

Hello Ron,

Thanks a lot for your comment… I will get in touch with you once I track the problem in your piece of code.

Thanks,
Sanoop

2 04 2011
Ron

The problem with my code is that, instead of just 1 output, it seems to be stuck in an infinte loop, repeating the same output continuously .

3 04 2011
Ron

Hi Sanoop,
Since I posted it, I have been able to find the issue. But now I am trying to solve this puzzle, wondering if you know have any insight into it :

Is it possible to get the coordinates of “any 1 of the windows” with just a mouse-click on that open window ?
.i.e. I can click on any of the windows and get the coordinates of that window I clicked ? Theoretically sounds do-able, I can get the coordinate of a mouseclick, but not the coordinate of the WINDOW where the user just clicked:
Here is how I get the mouseclick :
union compactPOINT { jlong xy; struct tagPOINT point; } compactpoint;

/** code to find out where the mouse is on screen. */

CALLBACK GetMousePosition( …..) { if ( GetCursorPos( &compactpoint.point ) ) { return compactpoint.xy; } else { // failure return -1; } }

And here is how I get coordinates of a window that I know the TItle of, but how do I combine them ?:
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
char title[256];
if (GetWindowTextA(hwnd, title, 256)) {
if (strcmp(title, “eBargain 2 Share – Windpos Internet Explorer”) == 0) {
/* GetWindowRect … */
}
}
return TRUE;
}

3 04 2011
Ron

The reason I am posting it here, is because the code you posted seems like you have a good background in the subject, hope you can help ….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: