📄 lion-tut-c27.htm
字号:
LOCAL rect:RECT <BR>
.if uMsg==WM_INITDIALOG <BR>
invoke InitCommonControls <BR>
invoke CreateWindowEx,NULL,ADDR
ToolTipsClassName,NULL,\ <BR>
TTS_ALWAYSTIP,CW_USEDEFAULT,\
<BR>
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
<BR>
hInstance,NULL
<BR>
mov hwndTool,eax <BR>
mov id,0 <BR>
mov ti.cbSize,sizeof TOOLINFO <BR>
mov ti.uFlags,TTF_SUBCLASS <BR>
push hDlg <BR>
pop ti.hWnd <BR>
invoke GetWindowRect,hDlg,addr
rect <BR>
invoke SetDlgToolArea,hDlg,addr
ti,addr MainDialogText1,id,addr rect <BR>
inc id <BR>
invoke SetDlgToolArea,hDlg,addr
ti,addr MainDialogText2,id,addr rect <BR>
inc id <BR>
invoke SetDlgToolArea,hDlg,addr
ti,addr MainDialogText3,id,addr rect <BR>
inc id <BR>
invoke SetDlgToolArea,hDlg,addr
ti,addr MainDialogText4,id,addr rect <BR>
invoke EnumChildWindows,hDlg,addr
EnumChild,addr ti </p>
<p><BR>
.elseif uMsg==WM_CLOSE <BR>
invoke EndDialog,hDlg,NULL <BR>
.else <BR>
mov eax,FALSE <BR>
ret <BR>
.endif <BR>
mov eax,TRUE <BR>
ret <BR>
DlgProc endp </p>
<p>EnumChild proc uses edi hwndChild:DWORD,lParam:DWORD <BR>
LOCAL buffer[256]:BYTE <BR>
mov edi,lParam <BR>
assume edi:ptr TOOLINFO <BR>
push hwndChild <BR>
pop [edi].uId <BR>
or [edi].uFlags,TTF_IDISHWND <BR>
invoke GetWindowText,hwndChild,addr buffer,255 <BR>
lea eax,buffer <BR>
mov [edi].lpszText,eax <BR>
invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi <BR>
assume edi:nothing <BR>
ret <BR>
EnumChild endp </p>
<p>SetDlgToolArea proc uses edi esi hDlg:DWORD,lpti:DWORD,lpText:DWORD,id:DWORD,lprect:DWORD
<BR>
mov edi,lpti <BR>
mov esi,lprect <BR>
assume esi:ptr RECT <BR>
assume edi:ptr TOOLINFO <BR>
.if id==0 <BR>
mov [edi].rect.left,0 <BR>
mov [edi].rect.top,0 <BR>
mov eax,[esi].right <BR>
sub eax,[esi].left <BR>
shr eax,1 <BR>
mov [edi].rect.right,eax <BR>
mov eax,[esi].bottom <BR>
sub eax,[esi].top <BR>
shr eax,1 <BR>
mov [edi].rect.bottom,eax <BR>
.elseif id==1 <BR>
mov eax,[esi].right <BR>
sub eax,[esi].left <BR>
shr eax,1 <BR>
inc eax <BR>
mov [edi].rect.left,eax <BR>
mov [edi].rect.top,0 <BR>
mov eax,[esi].right <BR>
sub eax,[esi].left <BR>
mov [edi].rect.right,eax <BR>
mov eax,[esi].bottom <BR>
sub eax,[esi].top <BR>
mov [edi].rect.bottom,eax <BR>
.elseif id==2 <BR>
mov [edi].rect.left,0 <BR>
mov eax,[esi].bottom <BR>
sub eax,[esi].top <BR>
shr eax,1 <BR>
inc eax <BR>
mov [edi].rect.top,eax <BR>
mov eax,[esi].right <BR>
sub eax,[esi].left <BR>
shr eax,1 <BR>
mov [edi].rect.right,eax <BR>
mov eax,[esi].bottom <BR>
sub eax,[esi].top <BR>
mov [edi].rect.bottom,eax <BR>
.else <BR>
mov eax,[esi].right <BR>
sub eax,[esi].left <BR>
shr eax,1 <BR>
inc eax <BR>
mov [edi].rect.left,eax <BR>
mov eax,[esi].bottom <BR>
sub eax,[esi].top <BR>
shr eax,1 <BR>
inc eax <BR>
mov [edi].rect.top,eax <BR>
mov eax,[esi].right <BR>
sub eax,[esi].left <BR>
mov [edi].rect.right,eax <BR>
mov eax,[esi].bottom <BR>
sub eax,[esi].top <BR>
mov [edi].rect.bottom,eax <BR>
.endif <BR>
push lpText <BR>
pop [edi].lpszText <BR>
invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti <BR>
assume edi:nothing <BR>
assume esi:nothing <BR>
ret <BR>
SetDlgToolArea endp </p>
<p><BR>
end start </p>
</BLOCKQUOTE>
<p>分析:</p>
<p>创建主对话框窗口之后,使用CreateWindowEx创建工具提示控件.</p>
<BLOCKQUOTE>invoke InitCommonControls <BR>invoke CreateWindowEx,NULL,ADDR
ToolTipsClassName,NULL,\ <BR>
TTS_ALWAYSTIP,CW_USEDEFAULT,\ <BR>
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
<BR> hInstance,NULL <BR>mov hwndTool,eax
</BLOCKQUOTE>
<p>之后,我们继续定义对话框四个角作为焦点域.</p>
<p>mov id,0 ; 焦点域ID <BR>
mov ti.cbSize,sizeof TOOLINFO <BR>
mov ti.uFlags,TTF_SUBCLASS ; 告诉控件子类化窗口.
<BR>
push hDlg <BR>
pop ti.hWnd ; 包含焦点域的窗口句柄<BR>
invoke GetWindowRect,hDlg,addr rect ; 获得客户区的大小<BR>
invoke SetDlgToolArea,hDlg,addr ti,addr MainDialogText1,id,addr
rect </p>
<P>我们初始化<B>TOOLINFO</B>结构. 注意我们要把客户区分成4个焦点域,因此我们需要知道客户区的大小,所以调用<b>GetWindowRect</b>.因为我们不想自己向控件转发消息,因此指定<b>TIF_SUBCLASS
</b>标志.<BR>
<B>SetDlgToolArea</B> 是计算焦点域矩形范围的并向控件注册的函数,我不详细解释计算过程.只说明它把对话框分成4个焦点域.然后向控件发送<B>TTM_ADDTOOL</B>
消息, 在<B>lParam</B>参数中传递<B>TOOLINFO</B>结构的地址.
<P><B> invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti </B>
<P> 在四个控件注册之后,我们来看看对话框的按钮,我们可以用ID来处理每个按钮,但是实在太乏味了.我们使用<b>EnumChildWindows</b>函数列举对话框上的所有控件并把他们注册给控件,<b>EnumChildWindows</b>原型如下:
<BLOCKQUOTE><B>EnumChildWindows proto hWnd:DWORD, lpEnumFunc:DWORD,
lParam:DWORD</B></BLOCKQUOTE>
<p>hWnd 是父窗口句柄. </p>
<p>lpEnumFunc 是每个控件将调用的<B>EnumChildProc</B>函数地址.lParam 是应用程序定义的要传给<B>EnumChildProc</B>
函数的值. <B>EnumChildProc</B> 函数定义如下:</p>
<BLOCKQUOTE><B>EnumChildProc proto hwndChild:DWORD,
lParam:DWORD</B></BLOCKQUOTE>
hwndChild是<B>EnumChildWindows</B>函数枚举的句柄. lParam 就是你传递给<B>EnumChildWindows</B>函数的同一个lParam.
<BR>
在例子中.我们如此调用<B> EnumChildWindows</B> 函数:
<BLOCKQUOTE><B>invoke EnumChildWindows,hDlg,addr EnumChild,addr ti
</B></BLOCKQUOTE>
我们把<b>TOOLINFO</b>结构的地址放在lParam参数中传递,是因为我们要在<b>EnumChild</b>函数中注册每个子控件.如果我们不使用这种方法,就需要将<b>ti</b>声明为全局变量,但这可能会引入很多bug.<BR>
当我们调用<B> EnumChildWindows</B>时, Windows会枚举出对话框上所有的子控件并为每个子控件调用一次<B>EnumChild</B>
f函数. 这样如果我们的对话框有两个控件,<b>EnumChild</b>将被调用两次.<BR>
EnumChild 函数填充TOOLINFO 结构的相应成员并向控件注册.
<BLOCKQUOTE><B>EnumChild proc uses edi hwndChild:DWORD,lParam:DWORD
</B><BR><B> LOCAL buffer[256]:BYTE
</B><BR><B> mov edi,lParam </B><BR><B>
assume edi:ptr TOOLINFO </B><BR><B> push hwndChild
</B><BR><B> pop [edi].uId ; we use the
whole client area of the control as the tool </B><BR><B> or
[edi].uFlags,TTF_IDISHWND </B><BR><B> invoke
GetWindowText,hwndChild,addr buffer,255 </B><BR><B> lea
eax,buffer ; use the window text as the tooltip text
</B><BR><B> mov [edi].lpszText,eax
</B><BR><B> invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi
</B><BR><B> assume edi:nothing </B><BR><B>
ret </B><BR><B>EnumChild endp </B></BLOCKQUOTE>
<font size="2" face="宋体">注意在例子中,我们使用了一种不同"工具":覆盖整个客户区的</font>"工具",因此我们需要用包含"工具"窗口的句柄来填充<b>uID</b>成员,也必须在<b>uFlags</b>
成员中指定<b>TTF_IDISHWND</b>标志.
<HR SIZE=1>
<DIV align=center>
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
<BR>
</DIV>
<!-- 10:1 文本广告交换 -->
<DIV align=center>
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
<!-- 10:1 文本广告交换 --></DIV>
<HR SIZE=1>
<DIV align=center>This article come from Iczelion's asm page, Welcom to <A
href="http://asm.yeah.net/">http://asm.yeah.net/</A></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -