⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 027.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
        invoke SetDlgToolArea,hDlg,addr ti,addr MainDialogText4,id,addr rect 
        invoke EnumChildWindows,hDlg,addr EnumChild,addr ti 


    .elseif uMsg==WM_CLOSE 
        invoke EndDialog,hDlg,NULL 
    .else 
        mov eax,FALSE 
        ret 
    .endif 
    mov eax,TRUE 
    ret 
DlgProc endp 

EnumChild proc uses edi hwndChild:DWORD,lParam:DWORD 
    LOCAL buffer[256]:BYTE 
    mov edi,lParam 
    assume edi:ptr TOOLINFO 
    push hwndChild 
    pop [edi].uId 
    or [edi].uFlags,TTF_IDISHWND 
    invoke GetWindowText,hwndChild,addr buffer,255 
    lea eax,buffer 
    mov [edi].lpszText,eax 
    invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi 
    assume edi:nothing 
    ret 
EnumChild endp 

SetDlgToolArea proc uses edi esi hDlg:DWORD,lpti:DWORD,lpText:DWORD,id:DWORD,lprect:DWORD 
    mov edi,lpti 
    mov esi,lprect 
    assume esi:ptr RECT 
    assume edi:ptr TOOLINFO 
    .if id==0 
        mov [edi].rect.left,0 
        mov [edi].rect.top,0 
        mov eax,[esi].right 
        sub eax,[esi].left 
        shr eax,1 
        mov [edi].rect.right,eax 
        mov eax,[esi].bottom 
        sub eax,[esi].top 
        shr eax,1 
        mov [edi].rect.bottom,eax 
    .elseif id==1 
        mov eax,[esi].right 
        sub eax,[esi].left 
        shr eax,1 
        inc eax 
        mov [edi].rect.left,eax 
        mov [edi].rect.top,0 
        mov eax,[esi].right 
        sub eax,[esi].left 
        mov [edi].rect.right,eax 
        mov eax,[esi].bottom 
        sub eax,[esi].top 
        mov [edi].rect.bottom,eax 
    .elseif id==2 
        mov [edi].rect.left,0 
        mov eax,[esi].bottom 
        sub eax,[esi].top 
        shr eax,1 
        inc eax 
        mov [edi].rect.top,eax 
        mov eax,[esi].right 
        sub eax,[esi].left 
        shr eax,1 
        mov [edi].rect.right,eax 
        mov eax,[esi].bottom 
        sub eax,[esi].top 
        mov [edi].rect.bottom,eax 
    .else 
        mov eax,[esi].right 
        sub eax,[esi].left 
        shr eax,1 
        inc eax 
        mov [edi].rect.left,eax 
        mov eax,[esi].bottom 
        sub eax,[esi].top 
        shr eax,1 
        inc eax 
        mov [edi].rect.top,eax 
        mov eax,[esi].right 
        sub eax,[esi].left 
        mov [edi].rect.right,eax 
        mov eax,[esi].bottom 
        sub eax,[esi].top 
        mov [edi].rect.bottom,eax 
    .endif 
    push lpText 
    pop [edi].lpszText 
    invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti 
    assume edi:nothing 
    assume esi:nothing 
    ret 
SetDlgToolArea endp 


end start 

分析:

创建主对话框窗口之后,使用CreateWindowEx创建工具提示控件.

invoke InitCommonControls 
invoke CreateWindowEx,NULL,ADDR ToolTipsClassName,NULL,\ 
       TTS_ALWAYSTIP,CW_USEDEFAULT,\ 
       CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ 
       hInstance,NULL 
mov hwndTool,eax 
   
之后,我们继续定义对话框四个角作为焦点域.

mov id,0        ; 焦点域ID 
    mov ti.cbSize,sizeof TOOLINFO 
    mov ti.uFlags,TTF_SUBCLASS    ; 告诉控件子类化窗口. 
    push hDlg 
    pop ti.hWnd    ; 包含焦点域的窗口句柄
    invoke GetWindowRect,hDlg,addr rect    ; 获得客户区的大小
    invoke SetDlgToolArea,hDlg,addr ti,addr MainDialogText1,id,addr rect 

我们初始化TOOLINFO结构. 注意我们要把客户区分成4个焦点域,因此我们需要知道客户区的大小,所以调用GetWindowRect.因为我们不想自己向控件转发消息,因此指定TIF_SUBCLASS 标志.
SetDlgToolArea 是计算焦点域矩形范围的并向控件注册的函数,我不详细解释计算过程.只说明它把对话框分成4个焦点域.然后向控件发送TTM_ADDTOOL 消息, 在lParam参数中传递TOOLINFO结构的地址. 

    invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti 

在四个控件注册之后,我们来看看对话框的按钮,我们可以用ID来处理每个按钮,但是实在太乏味了.我们使用EnumChildWindows函数列举对话框上的所有控件并把他们注册给控件,EnumChildWindows原型如下: 

EnumChildWindows proto hWnd:DWORD, lpEnumFunc:DWORD, lParam:DWORD
hWnd 是父窗口句柄. 

lpEnumFunc 是每个控件将调用的EnumChildProc函数地址.lParam 是应用程序定义的要传给EnumChildProc 函数的值. EnumChildProc 函数定义如下:

EnumChildProc proto hwndChild:DWORD, lParam:DWORD
hwndChild是EnumChildWindows函数枚举的句柄. lParam 就是你传递给EnumChildWindows函数的同一个lParam. 
在例子中.我们如此调用 EnumChildWindows 函数: 
invoke EnumChildWindows,hDlg,addr EnumChild,addr ti 
我们把TOOLINFO结构的地址放在lParam参数中传递,是因为我们要在EnumChild函数中注册每个子控件.如果我们不使用这种方法,就需要将ti声明为全局变量,但这可能会引入很多bug.
当我们调用 EnumChildWindows时, Windows会枚举出对话框上所有的子控件并为每个子控件调用一次EnumChild f函数. 这样如果我们的对话框有两个控件,EnumChild将被调用两次.
EnumChild 函数填充TOOLINFO 结构的相应成员并向控件注册. 
EnumChild proc uses edi hwndChild:DWORD,lParam:DWORD 
    LOCAL buffer[256]:BYTE 
    mov edi,lParam 
    assume edi:ptr TOOLINFO 
    push hwndChild 
    pop [edi].uId    ; we use the whole client area of the control as the tool 
    or [edi].uFlags,TTF_IDISHWND 
    invoke GetWindowText,hwndChild,addr buffer,255 
    lea eax,buffer    ; use the window text as the tooltip text 
    mov [edi].lpszText,eax 
    invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi 
    assume edi:nothing 
    ret 
EnumChild endp 
注意在例子中,我们使用了一种不同"工具":覆盖整个客户区的"工具",因此我们需要用包含"工具"窗口的句柄来填充uID成员,也必须在uFlags 成员中指定TTF_IDISHWND标志. 
--------------------------------------------------------------------------------




--------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -