CreateWindow创建对话框

CreateWindow创建对话框!

先介绍下系统创建对话框原理,搞清楚后就可以自己模仿来创建了!

一般情况下大家都习惯了用资源创建对话框 对话框有两种:模态和非模态 创建这两种对话框的函数是不相同的 模态用DialogBoxParam 非模态用CreateDialogParam 两种对话框的区别在于 消息循环的区别。

模态对话框调用用DialogBoxParam后,在函数内部会取得对话框资源 然后根据资源里指定的窗口风格来创建窗口 接着就调用消息循环来取得消息 所以该函数不会立马返回 除非调用EndDialog将其结束后函数才返回 所以如果是主窗口的消息里调用这个创建模态对话框则该窗口是不会再处理其他消息 因为窗口函数未返回也就是DispatchMessage函数未返回下一个GetMessage是没机会执行 怎样保证对话框是一直激活状态 在最上面而让用户没机会切换到其他窗口的呢 因为模态对话框会一直检测当前窗口是不是该对话框不是则设置为当前激活窗口 否则还是可以切换到其他窗口 只是这个对话框的父窗口不能再相应消息了!

记得在DialogBoxParam里有个自己指定的回调函数么?对话框是这样管理消息的,对话框类"#32770"的WNDCLASSEX结构里指定的回调函数是user32.dll模块内部的函数,用它来处理对话框消息,在处理之前会首先调用用户定义的对话框过程!

想要结束模态对话框(点右上角的X,关闭)就必须在对话框过程的WM_CLOSE消息中调用EndDialog!WM_CLOSE在winuser.h中定义为:#define WM_CLOSE 0x0010 ,所以根据这个我们知道默认对话框窗口函数是处理这个WM_CLOSE消息时是不会摧毁对话框窗口!而EndDialog又干啥了能摧毁对话框呢?我自己逆向了下这个函数 发现先GetActiveWindow 找到如果当前激活窗口是对话框 再调用SetWindowPos将窗口长宽设置为0 最后调用PostMessage(hWnd,WM_NULL,0,0)来摧毁对话框,WM_NULL是这样定义的:#define WM_NULL 0x0000,这样我们就知道原理了 就是点关闭按钮后发送了一个WM_NULL消息,这个消息是对话框类的窗口函数来处理以摧毁对话框和结束对话框的消息循环 当模态对话框的消息循环退出后DialogBoxParam函数就返回了!

对非模态对话框CreateDialogParam只是负责创建了窗口,根据资源里是否制定WS_VISIBLE来决定创建后窗口是否显示,如果不指定必须在函数返回后自己ShowWindow(hWnd,SW_VISIBLE)来显示窗口,这个函数就是添加了一个WS_VISIBLE风格,然后自己调用消息循环来处理窗口消息!

若要关闭非模态对话框只要在自己的窗口函数里调用DestroyWindow(hWnd)就可以了 该函数会再次发送WM_DESTROY消息 来摧毁非模态对话框!

对于调用自己的窗口函数 会根据需要处理的消息来判断 如果需要处理则自己处理 然后返回TRUE表示已经处理了 否则返回0 内建对话框过程会处理这个消息 唯一注意的就是内建对话框过程不会处理WM_INITDIALOG消息!

这里需要理解的就是窗口和创建这个窗口的线程之间的关系 如果DestroyWindow摧毁窗口后不再手动发送一个PostQuitMessage消息来使得循环退出的 GetMessage如果取得的是WM_QUIT 在winuser定义:#define WM_QUIT 0x0012 会返回0,其他消息返回非0,如果消息循环判断接受到这个WM_QUIT则退出循环 这样线程才会结束 否则可能窗口摧毁了这个窗口线程还在循环中!

因为非模态对话框是自己写消息循环的 所以可以自己定义什么消息下就退出循环!比如WM_QUIT~

对话框的窗口回调函数为 (我机器上的地址) 77D3E577 : USER32.DefDlgProc

77D3E577 USER32.DefDlgProcA          8BFF          mov     edi, edi
77D3E579                         /. 55            push    ebp
77D3E57A                         |. 8BEC          mov     ebp, esp
77D3E57C                         |. 8B4D 08       mov     ecx, dword ptr [ebp+8]
77D3E57F                         |. E8 5C9FFDFF   call    77D184E0
77D3E584                         |. 85C0          test    eax, eax
77D3E586                         |. 74 11         je      short 77D3E599
77D3E588                         |. 6A 01         push    1
77D3E58A                         |. FF75 14       push    dword ptr [ebp+14]
77D3E58D                         |. FF75 10       push    dword ptr [ebp+10]
77D3E590                         |. FF75 0C       push    dword ptr [ebp+C]
77D3E593                         |. 50            push    eax
77D3E594                         |. E8 1855FEFF   call    77D23AB1
77D3E599                         |> 5D            pop     ebp
77D3E59A                         \. C2 1000       retn    10

当有消息来时先调用USER32.DefDlgProcA,然后在其中用下面一句调用用户定义的函数

77D18731                          . FF55 08       call    dword ptr [ebp+8]                ; test.00401070

如果没有则返回由默认窗口过程继续处理!

WM_SETFONT WM_INITDIALOG 都要经过这个用户自定义函数处理下!

该函数用EDI存储消息代码,然后比较进行选择执行相关代码!

ENDDIALOG发送WM_NULL消息,然后发送WM_DESTROY(摧毁窗口)WM_NCDESTROY,

77D27603                                . 6A 01         push    1                                ; /RemoveMsg = PM_REMOVE
77D27605                                . 53            push    ebx                              ; |MsgFilterMax
77D27606                                . 53            push    ebx                              ; |MsgFilterMin
77D27607                                . 53            push    ebx                              ; |hWnd
77D27608                                . 8D45 E0       lea     eax, dword ptr [ebp-20]          ; |
77D2760B                                . 50            push    eax                              ; |pMsg
77D2760C                                . E8 8A1CFFFF   call    PeekMessageW                     ; \PeekMessageW
77D27611                                . 85C0          test    eax, eax
77D27613                                . 0F84 A0000000 je      77D276B9
77D27619                                . 837D E4 12    cmp     dword ptr [ebp-1C], 12
77D2761D                                . 895D FC       mov     dword ptr [ebp-4], ebx
77D27620                                . 0F84 C2A50000 je      77D31BE8
77D27626                                . F646 14 20    test    byte ptr [esi+14], 20
77D2762A                                . 0F85 99290100 jnz     77D39FC9
77D27630                                > 8D45 E0       lea     eax, dword ptr [ebp-20]
77D27633                                . 50            push    eax                              ; /pMsg
77D27634                                . FF75 08       push    dword ptr [ebp+8]                ; |hWnd
77D27637                                . E8 E8FDFFFF   call    IsDialogMessageW                 ; \IsDialogMessageW
77D2763C                                . 85C0          test    eax, eax
77D2763E                                . 0F84 CB000000 je      77D2770F
77D27644                                > 395D 10       cmp     dword ptr [ebp+10], ebx
77D27647                                . 0F84 AFA50000 je      77D31BFC
77D2764D                                > 8B4D 08       mov     ecx, dword ptr [ebp+8]
77D27650                                . B2 01         mov     dl, 1
77D27652                                . E8 CA510000   call    77D2C821
77D27657                                . 85C0          test    eax, eax
77D27659                                .^ 75 98         jnz     short 77D275F3
77D2765B                                > 53            push    ebx                              ; /ObjectId
77D2765C                                . 53            push    ebx                              ; |ObjectTypeId
77D2765D                                . FF75 08       push    dword ptr [ebp+8]                ; |hWnd
77D27660                                . 6A 11         push    11                               ; |Event = EVENT_SYSTEM_DIALOGEND
77D27662                                . E8 64230000   call    NotifyWinEvent                   ; \NotifyWinEvent
77D27667                                . 8B4D 08       mov     ecx, dword ptr [ebp+8]
77D2766A                                . B2 01         mov     dl, 1
77D2766C                                . E8 B0510000   call    77D2C821
77D27671                                . 85C0          test    eax, eax
77D27673                                . 5F            pop     edi
77D27674                                . 74 3D         je      short 77D276B3
77D27676                                . 8BB6 A8000000 mov     esi, dword ptr [esi+A8]
77D2767C                                . 3BF3          cmp     esi, ebx
77D2767E                                . 0F84 71A50000 je      77D31BF5
77D27684                                . 8B76 18       mov     esi, dword ptr [esi+18]
77D27687                                > FF75 08       push    dword ptr [ebp+8]                ; /hWnd
77D2768A                                . E8 0D3B0000   call    DestroyWindow                    ; \DestroyWindow
77D2768F                                . 395D 0C       cmp     dword ptr [ebp+C], ebx
77D27692                                . 74 1D         je      short 77D276B1
77D27694                                . 6A 0C         push    0C
77D27696                                . E8 0B220000   call    77D298A6
77D2769B                                . 85C0          test    eax, eax
77D2769D                                . 74 12         je      short 77D276B1
77D2769F                                . 6A 06         push    6
77D276A1                                . FF75 0C       push    dword ptr [ebp+C]
77D276A4                                . E8 3210FFFF   call    77D186DB
77D276A9                                . 85C0          test    eax, eax
77D276AB                                . 0F84 37140200 je      77D48AE8
77D276B1                                > 8BC6          mov     eax, esi
77D276B3                                > 5E            pop     esi
77D276B4                                . 5B            pop     ebx
77D276B5                                . C9            leave
77D276B6                                . C2 1000       retn    10
77D276B9                                > 395D 10       cmp     dword ptr [ebp+10], ebx
77D276BC                                . 0F84 F7A40000 je      77D31BB9
77D276C2                                . 395D 0C       cmp     dword ptr [ebp+C], ebx
77D276C5                                . 74 22         je      short 77D276E9
77D276C7                                . FF75 0C       push    dword ptr [ebp+C]                ; /hWnd
77D276CA                                . E8 441C0000   call    IsWindow                         ; \IsWindow
77D276CF                                . 85C0          test    eax, eax
77D276D1                                . 0F84 09140200 je      77D48AE0
77D276D7                                > 395D 0C       cmp     dword ptr [ebp+C], ebx
77D276DA                                . 74 0D         je      short 77D276E9
77D276DC                                . 3BFB          cmp     edi, ebx
77D276DE                                . 74 09         je      short 77D276E9
77D276E0                                . 395D FC       cmp     dword ptr [ebp-4], ebx
77D276E3                                . 0F84 B9700100 je      77D3E7A2
77D276E9                                > 8B4D 08       mov     ecx, dword ptr [ebp+8]
77D276EC                                . B2 01         mov     dl, 1
77D276EE                                . E8 2E510000   call    77D2C821
77D276F3                                . 85C0          test    eax, eax
77D276F5                                .^ 0F84 60FFFFFF je      77D2765B
77D276FB                                . F646 2B C0    test    byte ptr [esi+2B], 0C0
77D276FF                                .^ 0F85 56FFFFFF jnz     77D2765B
77D27705                                . E8 021DFFFF   call    WaitMessage                      ; [WaitMessage
77D2770A                                .^ E9 3EFFFFFF   jmp     77D2764D
77D2770F                                > 8D45 E0       lea     eax, dword ptr [ebp-20]
77D27712                                . 50            push    eax                              ; /pMsg
77D27713                                . E8 DE14FFFF   call    TranslateMessage                 ; \TranslateMessage
77D27718                                . 8D45 E0       lea     eax, dword ptr [ebp-20]
77D2771B                                . 50            push    eax                              ; /pMsg
77D2771C                                . E8 E012FFFF   call    DispatchMessageW                 ; \DispatchMessageW
77D27721                                .^ E9 1EFFFFFF   jmp     77D27644

所以自己用CreateWindow创建对话框 类用"#32770" 必须要窗口子类化 把窗口过程设置成自己的 然后处理下就OK!

转载于:https://my.oschina.net/ypimgt/blog/65250

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值