📄 lion-tut-c18.htm
字号:
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\</B>
<BR><B>
hInst,NULL</B> <BR><B> mov hwnd,eax</B>
<BR><B> .while TRUE</B>
<BR><B> invoke GetMessage, ADDR
msg,NULL,0,0</B> <BR><B> .BREAK .IF
(!eax)</B> <BR><B> invoke
TranslateMessage, ADDR msg</B> <BR><B>
invoke DispatchMessage, ADDR msg</B> <BR><B> .endw</B>
<BR><B> mov eax,msg.wParam</B> <BR><B>
ret</B> <BR><B>WinMain endp</B>
<P><B>WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</B>
<BR><B> .if uMsg==WM_CREATE</B>
<BR><B> invoke
CreateWindowEx,NULL,ADDR ProgressClass,NULL,\</B>
<BR><B>
WS_CHILD+WS_VISIBLE,100,\</B>
<BR><B>
200,300,20,hWnd,IDC_PROGRESS,\</B>
<BR><B>
hInstance,NULL</B> <BR><B> mov
hwndProgress,eax</B> <BR><B> mov
eax,1000
; the lParam of PBM_SETRANGE message contains the range</B>
<BR><B> mov CurrentStep,eax</B>
<BR><B> shl
eax,16
; the high range is in the high word</B>
<BR><B> invoke
SendMessage,hwndProgress,PBM_SETRANGE,0,eax</B>
<BR><B> invoke
SendMessage,hwndProgress,PBM_SETSTEP,10,0</B>
<BR><B> invoke
CreateStatusWindow,WS_CHILD+WS_VISIBLE,NULL,hWnd,IDC_STATUS</B>
<BR><B> mov hwndStatus,eax</B>
<BR><B> invoke
SetTimer,hWnd,IDC_TIMER,100,NULL ;
create a timer</B> <BR><B> mov
TimerID,eax</B> <BR><B> .elseif uMsg==WM_DESTROY</B>
<BR><B> invoke
PostQuitMessage,NULL</B> <BR><B> .if
TimerID!=0</B>
<BR><B> invoke
KillTimer,hWnd,TimerID</B> <BR><B>
.endif</B> <BR><B> .elseif
uMsg==WM_TIMER ; when a timer event
occurs</B> <BR><B> invoke
SendMessage,hwndProgress,PBM_STEPIT,0,0 ; step up the progress
in the progress bar</B> <BR><B> sub
CurrentStep,10</B> <BR><B> .if
CurrentStep==0</B>
<BR><B> invoke
KillTimer,hWnd,TimerID</B>
<BR><B> mov
TimerID,0</B>
<BR><B> invoke
SendMessage,hwndStatus,SB_SETTEXT,0,addr Message</B>
<BR><B> invoke
MessageBox,hWnd,addr Message,addr AppName,MB_OK+MB_ICONINFORMATION</B>
<BR><B> invoke
SendMessage,hwndStatus,SB_SETTEXT,0,0</B>
<BR><B> invoke
SendMessage,hwndProgress,PBM_SETPOS,0,0</B>
<BR><B> .endif</B>
<BR><B> .else</B>
<BR><B> invoke
DefWindowProc,hWnd,uMsg,wParam,lParam</B>
<BR><B> ret</B>
<BR><B> .endif</B> <BR><B> xor eax,eax</B>
<BR><B> ret</B> <BR><B>WndProc endp</B> <BR><B>end start</B>
<H4><FONT color=#ff0000>分析:</FONT></H4>
<UL><B> invoke WinMain, hInstance,NULL,NULL,
SW_SHOWDEFAULT</B> <BR><B> invoke ExitProcess,eax</B>
<BR><B> invoke InitCommonControls</B>
</UL>我故意把函数InitCommonControls放到ExitProcess后,这样就可以验证调用该函数仅仅是为了在我们程序的可执行文件的PE头中的引入段中放入引用了comctl32.dll的信息。您可以看到,即使该函数什么都没有做,我们的通用控件对话框依旧可以正常工作。
<UL><B> .if uMsg==WM_CREATE</B>
<BR><B> invoke
CreateWindowEx,NULL,ADDR ProgressClass,NULL,\</B>
<BR><B>
WS_CHILD+WS_VISIBLE,100,\</B>
<BR><B>
200,300,20,hWnd,IDC_PROGRESS,\</B>
<BR><B>
hInstance,NULL</B> <BR><B> mov
hwndProgress,eax</B>
</UL>在这里我们创建了通用控件。注意CreateWindowEx函数中的参数hWnd是父窗口的句柄。另外它也指定了通用控件的ID号。因为我们直接使用控件的窗口句柄,所以就没有使用该ID号。所有的窗口都必须具有WS_CHILD风格。
<UL><B> mov eax,1000</B>
<BR><B> mov CurrentStep,eax</B>
<BR><B> shl eax,16</B>
<BR><B> invoke
SendMessage,hwndProgress,PBM_SETRANGE,0,eax</B>
<BR><B> invoke
SendMessage,hwndProgress,PBM_SETSTEP,10,0</B>
</UL>在创建了进度条后我们先设定它的范围。缺省的范围是0-100。如果您不满意,可以重新设置,这通过传递PBM_SETRANGE消息来实现。参数lParam中包含了范围值,其中底字和高字分别是范围的起始和终了的值。您可以指定进度条每移动一格的步长。本例子中把步长设置成10,意味着每发送一次PBM_STEPIT消息给进度条,它的显示指针就会移动10。当然您可以调用PBM_SETPOS
来直接设定进度条上的指针的位置。用该消息您可以更方便地设定进度条了。
<UL><B> invoke
CreateStatusWindow,WS_CHILD+WS_VISIBLE,NULL,hWnd,IDC_STATUS</B>
<BR><B> mov hwndStatus,eax</B>
<BR><B> invoke
SetTimer,hWnd,IDC_TIMER,100,NULL ;
create a timer</B> <BR><B> mov
TimerID,eax</B>
</UL>下面我们调用CreateStatusWindow来创建状态条。这个调用很好理解,无需我多解释。在状态条创建后我们创建一个计时器。在本例中我们每隔100毫秒就更新一次进度条。下面时创建记时器的函数原型:
<UL><B>SetTimer PROTO hWnd:DWORD, TimerID:DWORD, TimeInterval:DWORD,
lpTimerProc:DWORD</B> </UL><B>hWnd</B> : 父窗口的句柄。<BR><B>TimerID</B> :
计时器的ID号。您可以指定一个唯一的非零值。<BR><B>TimerInterval</B> :
以毫秒计的时间间隔。<BR><B>lpTimerProc</B> :
计时器回调函数的地址。每当时间间隔到了的时候,该函数就会被系统调用。如果该值为NULL,计时器就会把WM_TIMER消息发送到父窗口。
<P>如果SetTimer调用成功的话就会返回计时器的ID号值,否则返回0。这也是为什么计时器的ID号必须为非零值的原因。
<UL><B> .elseif uMsg==WM_TIMER</B>
<BR><B> invoke
SendMessage,hwndProgress,PBM_STEPIT,0,0</B>
<BR><B> sub CurrentStep,10</B>
<BR><B> .if CurrentStep==0</B>
<BR><B>
invoke KillTimer,hWnd,TimerID</B>
<BR><B> mov
TimerID,0</B>
<BR><B>
invoke SendMessage,hwndStatus,SB_SETTEXT,0,addr Message</B>
<BR><B>
invoke MessageBox,hWnd,addr Message,addr AppName,MB_OK+MB_ICONINFORMATION</B>
<BR><B>
invoke SendMessage,hwndStatus,SB_SETTEXT,0,0</B>
<BR><B>
invoke SendMessage,hwndProgress,PBM_SETPOS,0,0</B>
<BR><B> .endif</B>
</UL>当指定的时间到了的时候,计时器将发送WM_TIMER消息。您可以在处理该消息时作适当的处理。本例中我们将更新进度条,并检查进度条是否超过最大的值。如果超过了的话,我们通过发送SB_SETTEXT消息来在状态条中设置文本。这时,弹出一个对话框,当用户关闭掉对话框后,我们去除掉进度条和状态条中的文本。
<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>翻译:Lxx.阿龙,校对:LuoYunBin's Win32 ASM Page, <A
href="http://asm.yeah.net/">http://asm.yeah.net/</A></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -