> in front of the two Styles of Folder selection dialog box implementation method, see the article " Win7 interface and API implementation of the Old Interface folder selection dialog box code implementation detailed explanation ". and the Old Interface folder selection dialog box is very small, also cause the choice is very inconvenient, so many people do not like this dialog box. But today's talk about customizing the style and size of this folder selection dialog box may greatly enhance the user experience. Hey.
First look at the implementation, look at the picture to speak, there is a picture of the truth!
The first picture is horizontal, the second one is portrait, and the third picture is horizontal and vertical. dialog box, you also added an edit box that allows you to enter the folder path directly. When a folder is selected, the selected folder path is automatically updated in the edit box. Look, the effect is good, below to see how to customize, get rid of the original small selection box bar.
Implementation principle is, in fact, simple, which is to provide a callback function for customization. Why the callback function is easy to customize, see the detailed analysis of the "Deep comparative analysis of the design principles of function call and callback function". The callback function mechanism is not discussed in detail here. Using a callback function gives you the opportunity to customize the interface, so the callback function is a very good thing. In the callback function, you respond to the message bffm_initialized, and then iterate through all the child controls in the folder selection dialog box, then resize and position them for customization.
Take a look at the implementation code:
To use a callback function, you provide a callback function that passes the address of the callback function to the member LPFN in the structure of the Folder selection dialog box. The code for the Startup Folder selection dialog box is as follows:
const tchar* lppath=_t ("C:\\Program Files\\"); TCHAR lptemp[max_path]={0};//-Stores the selected folder path Browseinfo bi;memset (&bi, 0, sizeof (BI)); Lpitemidlist Pitemlist;bi.hwndowner = m_hwnd;//-Sets the owner window handle, if NULL, equivalent to the non-modal window Bi.lpsztitle = _t ("★c++ Technology network reminder ★?"); /-Select the hint text in the folder Bi.ulflags = Bif_returnonlyfsdirs | BIF_EDITBOX;BI.LPFN = browsecallbackproc;//-callback function for customizing Folder selection dialog box bi.lparam= (LParam) lppath;//-Incoming default selected folder Pitemlist = SHBrowseForFolder (&BI); if (pitemlist!=null) {shgetpathfromidlist (pitemlist,lptemp);//-Get selected folder path}
code description:
The comments in the code have been written very clearly, each step is basically marked clearly, so not much to explain. The only thing to say is the browseinfo structure. This struct is used to pass various parameters to the folder selection dialog box, including a callback function for customizing the interface. The member ulflags of a struct can be used in combination with multiple identities to enable customization of the interface. Bif_editbox is the more out of the edit box. Bif_returnonlyfsdirs indicates that only the folder is returned. There are many of these signs, specific to their own MSDN, the inside said very clearly, I do not repeat the explanation, just tell you the method, you have to do your own to find out to learn. SHBrowseForFolder is the Shell function that launches the Folder selection dialog box. After execution, and then determine whether the success, and then call SHGetPathFromIDList to get the Folder List of selected folders, stored in lptemp.
We are going to provide a callback function, first declare this callback function, declared as follows:
static int __ StdCall Browsecallbackproc (HWND hwnd, UINT umsg, LPARAM LPARAM, LPARAM lpdata);
must be class-static, so add the static keyword. Other formats are in the API's prescribed format. Before implementing the callback function, I customized a struct to store the style of the child controls, storing the left and right margins, width and height. Storing this information in a structured form can simplify the code and make the logic clearer. and use typedef to redefine the structure type, make the use more convenient.
typedef struct CONTROLLAYOUT{INT iwidth; -width int iheight; -height int imargin_left; -Left margin int imargin_right; -Right margin int imargin_top; -Top margin int imargin_bottom;//-bottom margin}ctrllayout;
The code for the callback function is implemented as follows:
int CALLBACK Cfolderdlg::browsecallbackproc (HWND hwnd,uint umsg,lparam lparam,lparam lpdata) {cwnd* pmainwnd; CRect orgmainclientrect;//-Adjust Front Folder dialog box client area rectangle CRect newmainwndrect;//-Resize Folder dialog box entire window rectangle cwnd* pchildwnd;//-child window pointer TCHAR szclassname[max_path];//-Control Windows window class class name CRect Treerect; -Tree Control Rectangle Area CRect buttonrect;//-button control rectangular area ctrllayout treelayout={0};//-tree control style ctrllayout buttonlayout[2]={0};//- tree control style int iIndex = 0;//-To button array count switch (umsg) {Case bffm_initialized:pmainwnd = Cwnd::fromhandle (hwnd);//-depending on the window handle, Get folder selection The dialog pointer Pmainwnd->getclientrect (orgmainclientrect);//-Gets the size of the main window client area, which is the area where the control is placed Pchildwnd = Pmainwnd->getwindow (gw_ Child); -Get pointer to child window/*-Loop Convenient folder selection dialog control and store control's location information-*/while (Pchildwnd! = NULL) {getclassname (Pchildwnd->m_hwnd, Szclassname, MAX_PATH); if (_tcscmp (_t ("SysTreeView32"), szclassname) = = 0) {/*-storage tree control style-*/pchildwnd->getwindowrect (treerect);p mainwnd->screentoclient (treerect); Treelayout.imargin_left = Treerect.left; Treelayout.imargin_top = Treerect.top; TreelaYout.imargin_right = Orgmainclientrect.right-treerect.right; Treelayout.imargin_bottom = Orgmainclientrect.bottom-treerect.bottom;} if (_tcscmp (_t ("button"), szclassname) = = 0) {/*-store button control style-*/pchildwnd->getwindowrect (buttonrect);p mainwnd-> ScreenToClient (Buttonrect); Buttonlayout[iindex].iwidth = Buttonrect.width (); Buttonlayout[iindex].iheight = Buttonrect.height (); Buttonlayout[iindex].imargin_right = Orgmainclientrect.right-buttonrect.right; Buttonlayout[iindex].imargin_bottom = orgmainclientrect.bottom-buttonrect.bottom;iindex++;} Pchildwnd = Pchildwnd->getnextwindow ();} /*-Increase the client area in the Folder dialog box and dialog box-*/pmainwnd->getwindowrect (Newmainwndrect); orgmainclientrect.inflaterect (0, 0, 240, 300); Newmainwndrect.inflaterect (0, 0, +);p Mainwnd->movewindow (newmainwndrect);/*-Modify the size and position of the control-*/iindex = 0; Pchildwnd = Pmainwnd->getwindow (gw_child);//-Move the main window and get the child window pointer while (Pchildwnd! = NULL) {getclassname (pchildwnd->m _hwnd, Szclassname, MAX_PATH); if (_tcscmp (_t ("SysTreeView32"), szclassname) = = 0) {treerect.left = Treelayout.imargin_left; Treerect.top = Treelayout.imargin_top; Treerect.right = Orgmainclientrect.right-treelayout.imargin_right; Treerect.bottom = Orgmainclientrect.bottom-treelayout.imargin_bottom;pchildwnd->movewindow (TreeRect);} if (_tcscmp (_t ("button"), szclassname) = = 0) {buttonrect.right = Orgmainclientrect.right-buttonlayout[iindex].imargin _right; Buttonrect.bottom = Orgmainclientrect.bottom-buttonlayout[iindex].imargin_bottom; Buttonrect.left = Buttonrect.right-buttonlayout[iindex].iwidth; Buttonrect.top = Buttonrect.bottom-buttonlayout[iindex].iheight;pchildwnd->movewindow (ButtonRect); iIndex++;} Pchildwnd = Pchildwnd->getnextwindow ();} Pmainwnd->sendmessage (Bffm_setselection, TRUE, lpdata);//-Set the default selected folder Break;default:break;} return 0;}
< Span style= "LINE-HEIGHT:2;" >
code description:
The comments for each code are basically clear. Here's the whole idea of the process. The callback function responds only to the bffm_initialized message, which is to customize the dialog box only when the folder selection dialog is initialized, and the rest of the message is out of control.
use Treelayout to store the folder tree size and layout (relative position), Use the Buttonlayout array to store the size and layout of two buttons. Use the Incoming folder selection dialog handle to get the main window pointer, and then get the child window and client area. Phoenix Entertainment Platform The structure of the Folder selection dialog box is this: the entire window as a parent window, each control in the window as a child window. To modify these child windows, iterate through the Subwindow, call GetWindow (Gw_child) to get the first child window, and then call Getnextwindow () to get the subsequent subwindow until Getnextwindow () Gets the child window pointer to null. The corresponding layout is stored according to the corresponding control class. Bole Entertainment platform to traverse once again, adjust the control, of course, if Yaotu easy, can also be modified at once, is also possible. Noah's entertainment platform here is just a reference code that can be optimized based on this. The Inflaterect () function expands the rectangle, the parameter is positive, the rectangle is enlarged, and the rectangle is reduced to a negative number. For details, please see the MSDN explanations. Finally send a message to set the default selected folder.
Customize folder selection dialog box style and size implementation method