📄 lion-tut-c16.htm
字号:
<BR><B> .if
ax==IDM_START_THREAD</B>
<BR><B>
invoke SetEvent,hEventStart</B>
<BR><B>
invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_GRAYED</B>
<BR><B>
invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_ENABLED</B>
<BR><B>
.elseif ax==IDM_STOP_THREAD</B>
<BR><B>
mov EventStop,TRUE</B>
<BR><B>
invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_ENABLED</B>
<BR><B>
invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_GRAYED</B>
<BR><B>
.else</B>
<BR><B>
invoke DestroyWindow,hWnd</B>
<BR><B>
.endif</B> <BR><B> .endif</B>
<BR><B> .ELSEIF uMsg==WM_FINISH</B>
<BR><B> invoke MessageBox,NULL,ADDR
SuccessString,ADDR AppName,MB_OK</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>
<P><B>ThreadProc PROC USES ecx Param:DWORD</B>
<BR><B> invoke
WaitForSingleObject,hEventStart,INFINITE</B>
<BR><B> mov ecx,600000000</B>
<BR><B> .WHILE ecx!=0</B>
<BR><B>
.if EventStop!=TRUE</B>
<BR><B>
add eax,eax</B>
<BR><B>
dec ecx</B>
<BR><B>
.else</B>
<BR><B>
invoke MessageBox,hwnd,ADDR StopString,ADDR AppName,MB_OK</B>
<BR><B>
mov EventStop,FALSE</B>
<BR><B>
jmp ThreadProc</B>
<BR><B>
.endif</B> <BR><B> .ENDW</B>
<BR><B> invoke
PostMessage,hwnd,WM_FINISH,NULL,NULL</B>
<BR><B> invoke
EnableMenuItem,hMenu,IDM_START_THREAD,MF_ENABLED</B>
<BR><B> invoke
EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_GRAYED</B>
<BR><B> jmp ThreadProc</B>
<BR><B> ret</B> <BR><B>ThreadProc
ENDP</B> <BR><B>end start</B>
<H3><FONT color=#ff0000>分析:</FONT></H3>本例中,我们演示另一种技巧:
<P><B> .IF uMsg==WM_CREATE</B>
<BR><B> invoke
CreateEvent,NULL,FALSE,FALSE,NULL</B>
<BR><B> mov hEventStart,eax</B>
<BR><B> mov eax,OFFSET
ThreadProc</B> <BR><B> invoke
CreateThread,NULL,NULL,eax,\</B>
<BR><B>
NULL,0,\</B>
<BR><B>
ADDR ThreadID</B> <BR><B> invoke
CloseHandle,eax</B>
<P>在WM_CREATE
消息的处理中我们生成事件同步对象并创建线程。我们设置了相关的值让同步对象生成时处于”无信号”状态而且在调用了WaitForSingleObject后可以自动把事件对象的状态设为”无信号”。然后我们创建线程。
线程的代码开始执行后立即被阻塞:
<P><B>ThreadProc PROC USES ecx Param:DWORD</B>
<BR><B> invoke
WaitForSingleObject,hEventStart,INFINITE</B>
<BR><B> mov ecx,600000000</B>
<P>您可以看到线程的执行体的第一条代码就是调用WaitForSingleObject函数,该函数使得线程阻塞并且一直处于等待事件对象变成”有信号”。这也就是说,我们以开始就让该线程进入了睡眠状态。
当用户选择了菜单项”run thread”后,我们把事件对象得状态变成”有信号”:
<P><B> .if
ax==IDM_START_THREAD</B>
<BR><B>
invoke SetEvent,hEventStart</B>
<P>函数SetEvent可以让同步对象变成”有信号”状态,那么下一次线程得到时间片运行时,WaitForSingleObject函数就会返回,线程余下的代码就可以得到执行了。当用户选择了菜单项”stop
thread” 时,我们把全局变量EventStop设为TRUE。
<P><B>
.if EventStop==FALSE</B>
<BR><B>
add eax,eax</B>
<BR><B>
dec ecx</B>
<BR><B>
.else</B>
<BR><B>
invoke MessageBox,hwnd,ADDR StopString,ADDR AppName,MB_OK</B>
<BR><B>
mov EventStop,FALSE</B>
<BR><B>
jmp ThreadProc</B>
<BR><B>
.endif</B>
<P>这样线程得计数工作结束,然后跳转到重新执行WaitForSingleObject函数的地方。注意:我们不用手动清除事件对象的信号,因为在调用CreateEvent函数时把参数bManualReset的值设为了FALSE。
<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 + -