当前位置:网站首页>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》

边栏推荐
- Sringboot-plugin-framework 实现可插拔插件服务
- Flink fault tolerance mechanism (V)
- R language uses the tablestack function of epidisplay package to make statistical summary tables (descriptive statistics based on the grouping of target variables, hypothesis testing, etc.), set the b
- Default color setting in uiswitch off state
- Unity行人随机行走不碰撞
- Complete set of JS array common operations
- 对话框管理器第二章:创建框架窗口
- Centos7安装达梦单机数据库
- [untitled] rhcsa first operation
- Ansible服务常用命令模块详细解析
猜你喜欢
随机推荐
字符串——28. 实现 strStr()
R语言使用sort函数排序向量数据实战、返回实际排序后的数据(默认升序)
Nmap security testing tool tutorial
The latest and complete Flink series tutorials in 2021_ Preliminary exploration of Flink principle and flow batch integration API (II. V) V2
字符串——459. 重复的子字符串
Data modification modification
rhcsa第六次笔记
Solve the problem that the ARR containsobject method returns no every time
Source code analysis of ArrayList
解决 uni-starter 使用本地函数可以登录微信 但是使用云函数登录失败
微信小程序 TODO案例
OWASP zap security testing tool tutorial (Advanced)
22-07-23周总结
Csp2021 T3 palindrome
Dameng real-time active and standby cluster construction
Flink comprehensive case (IX)
threw exception [Circular view path [index]: would dispatch back to the current handler URL [/index]
SQL Server 启停作业脚本
[untitled] rhcsa first operation
C# unsafe 非托管对象指针转换









