当前位置:网站首页>Dialog manager Chapter 2: create frame window

Dialog manager Chapter 2: create frame window

2022-07-24 14:09:00 Topomeyer - long development road

The dialog template contains a description of the appearance of the dialog , So the dialog manager simply iterates through the template and creates the dialog box according to the description of the template . This process is very simple and direct , The dialog manager doesn't have much decision-making space , It just does what the template says .
For the sake of simplicity , I will assume that the dialog manager here is an extended version of the dialog template . It's classic DLGTEMPLATE Superset , So I talk about it in general .
in addition , I will also skip some special parts ( for example WM_ENTERIDLE news ), Because they have little to do with the main part I want to be .

meanwhile , Because of the length , I will also skip error handling .

Last , I assume that you already know the structure of various dialog templates and ignore the problem of template statement parsing .

Okay , We can start .

The first task is to study the dialog style and put DS_* Convert style to WS_* and WS_EX_* style , As shown in the figure below :

problem : Why defines DS_CONTROL Style will lead to removal WS_CAPTION and WS_SYSMENU Well ?
answer : By simply adding a style symbol , Make it easier for people to convert existing dialog boxes into DS_CONTROL Sub dialog .
If the dialog template contains menus , Then load the menu from the instance handle passed as part of the creation parameter .
hmenu = LoadMenu(hinst, );

This is a common method in dialog creation : The instance handle passed to the dialog creation function is used for all resource related activities during dialog creation .

The algorithm of getting dialog font is as follows :


Please note that ,DS_SETFONT Prior to the DS_FIXEDFONT.

Once the dialog manager has fonts , It will be measured , So that you can use its size to convert the dialog unit (DLU) Convert to pixels . Everything in the dialog layout is in DLU Finish in . If you forget, you will DLU Formula converted to pixels , Here is a reminder . The formula is as follows :

// 4 xdlu = 1 average character width
// 8 ydlu = 1 average character height
#define XDLU2Pix(xdlu) MulDiv(xdlu, AveCharWidth, 4)
#define YDLU2Pix(ydlu) MulDiv(ydlu, AveCharHeight, 8)

The dialog size comes from the template :
cxDlg = XDLU2Pix(DialogTemplate.cx);
cyDlg = YDLU2Pix(DialogTemplate.cy);

The size of the dialog box in the template is the size of the client area , So we also need to add .
RECT rcAdjust = { 0, 0, cxDlg, cyDlg };
AdjustWindowRectEx(&rcAdjust, dwStyle, hmenu != NULL, dwExStyle);
int cxDlg = rcAdjust.right – rcAdjust.left;
int cyDlg = rcAdjust.bottom – rcAdjust.top;

How do I know that it is the customer area, not the whole window including the non customer area ? Because if it is a full window rectangle , It is impossible to design dialog ! The template designer doesn't know what non client indicators the end user's system will set , Therefore, it cannot be considered in the design .

( This is a special case of the more general rule : If you are not sure whether something is true , Ask yourself ,“ If it is true , What will the world look like ?” If you find an obviously wrong logical result , So you just [ Through contradiction ] Prove that what you are considering is really not true . This is an important logical principle , I will return to again and again . In fact, you saw it a few days ago .)

hypothesis DS_ABSALIGN Style not set , The coordinates given in the dialog template are relative to the parent of the dialog .
POINT pt = { XDLU2Pix(DialogTemplate.x),YDLU2Pix(DialogTemplate.y) };
ClientToScreen(hwndParent, &pt);

But if the caller passes hwndParent = NULL What do I do ? under these circumstances , The dialog position is relative to the upper left corner of the main screen , But don't do this .

> On multi display systems , It will place the dialog box on the main display , Even if your program is running on the secondary display .

> Users may dock their taskbar at the top or left edge of the screen , This will overwrite your dialog .

> Even on single display systems , Your program may also run in the lower right corner of the screen . Placing the conversation in the upper left corner will not establish a meaningful connection between the two .

> If two copies of your program are running , Their dialog boxes will accurately cover each other . We saw the danger of this situation in the previous article .

The moral of the story : Always pass a hwndParent window , So that the dialog box appears in a meaningful position relative to the rest of the program . ( Don't just catch GetDesktopWindow!)

well , We are now ready to create the dialog : We have its class 、 Its font 、 Its menu 、 Its size and location .

Oh, wait , We have to deal with the subtleties of dialog creation discussed earlier : Dialog boxes are always created hidden at the beginning .
BOOL fWasVisible = dwStyle & WS_VISIBLE;
dwStyle &= ~WS_VISIBLE;

The dialog class and title are from the template . Almost everyone only uses the default dialog class , Although I explained how to use custom dialog classes in my previous article .

well , Now we have the information we need to create the window .
HWND hdlg = CreateWindowEx(dwExStyle, pszClass,
pszCaption, dwStyle & 0xFFFF0000, pt.x, pt.y,
cxDlg, cyDlg, hwndParent, hmenu, hinst, NULL);

Please note that , We filtered out all low style bits ( Each class ), Because we already have DS_* Convert style to “ real ” style .

That's why your conversation process doesn't get like WM_CREATE The reason why such a window creates messages . When creating a framework , The dialogue process has not yet entered the screen . Only after the framework is created , Dialog manager can attach dialog process .
// Set the dialog procedure
SetWindowLongPtr(hdlg, DWLP_DLGPROC, (LPARAM)lpDlgProc);

The dialog manager does more tricks on this , Based on dialog template style . Templates may require window context help ID. If the template does not specify allow resizing 、 Maximized or minimized window style , Relevant menu items will be deleted from the system menu of the dialog box .

Next, set the font :
SetWindowFont(hdlg, hf, FALSE);

That's why the first message you receive during your conversation happens to be WM_SETFONT: It is setting DWLP_DLGPROC The first message sent after . Of course , This behavior may change in the future ; You should not rely on message sorting .

well , The dialog framework has now been created . next step : Create controls .

summary

Drag and drop control, it's really simple , But the underlying principle of the operating system is really not so simple .
You can :
> Ignore these complex , Cumbersome things , continue ” Play the music and dance ”.
> Painstaking efforts , Study these details in depth .
Okay , The choice is yours .

Last

Raymond Chen Of 《The Old New Thing》 It's one of my favorite blogs , There's a lot about Windows Little knowledge , For the vast Windows For platform developers , It's really helpful .
This article is from :《The dialog manager, part 2: Creating the frame window》

原网站

版权声明
本文为[Topomeyer - long development road]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/205/202207241401179601.html