?? lion-tut-c15.htm
字號:
<BR><B>
hInst,NULL</B> <BR><B> mov hwnd,eax</B>
<BR><B> invoke ShowWindow, hwnd,SW_SHOWNORMAL</B>
<BR><B> invoke UpdateWindow, hwnd</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_DESTROY</B>
<BR><B> invoke
PostQuitMessage,NULL</B> <BR><B> .ELSEIF uMsg==WM_COMMAND</B>
<BR><B> mov eax,wParam</B>
<BR><B> .if lParam==0</B>
<BR><B> .if
ax==IDM_CREATE_THREAD</B>
<BR><B>
mov eax,OFFSET ThreadProc</B>
<BR><B>
invoke CreateThread,NULL,NULL,eax,\</B>
<BR><B>
0,\</B>
<BR><B>
ADDR ThreadID</B>
<BR><B>
invoke CloseHandle,eax</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> mov ecx,600000000</B>
<BR><B>Loop1:</B> <BR><B> add
eax,eax</B> <BR><B> dec ecx</B>
<BR><B> jz Get_out</B>
<BR><B> jmp Loop1</B>
<BR><B>Get_out:</B> <BR><B> invoke
PostMessage,hwnd,WM_FINISH,NULL,NULL</B>
<BR><B> ret</B> <BR><B>ThreadProc
ENDP</B>
<P><B>end start</B> <BR>
<H3><FONT color=#ff0000>分析:</FONT></H3>主程序的主線程是一個用戶界面線程,它有一個普通窗口。用戶選擇菜單項"Create
Thread",程序就會產生一個線程:
<P><B> .if
ax==IDM_CREATE_THREAD</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> <BR><B> </B>
<BR>上面的代碼段產生一個線程,線程的主體代碼是函數ThreadProc,該函數和主線程并行運行。在調用成功后,CreateThread函數立即返回,ThreadProc也開始運行。因為我們不再用線程句柄,我們立即關閉它以避免內存泄漏。我們前面講過關閉句柄不會終止線程的執行,而只是減少起引用計數。
<P><B>ThreadProc PROC USES ecx Param:DWORD</B>
<BR><B> mov ecx,600000000</B>
<BR><B>Loop1:</B> <BR><B> add
eax,eax</B> <BR><B> dec ecx</B>
<BR><B> jz Get_out</B>
<BR><B> jmp Loop1</B>
<BR><B>Get_out:</B> <BR><B> invoke
PostMessage,hwnd,WM_FINISH,NULL,NULL</B>
<BR><B> ret</B> <BR><B>ThreadProc
ENDP</B>
<P>我們看到上面的線程的代碼僅僅是做簡單的計數工作,因為我們設了一個很大的基數,所以該線程會持續一段您能感覺得到的時間,當結束后它會向主線程發送WM_FINISH消息。WM_FINISH消息是我們自己定義的,它的定義如下:
<UL><B>WM_FINISH equ WM_USER+100h</B>
</UL>WM_USER消息是我們能夠使用的最小消息值。<BR>顯然我們一看到WM_FINISH,就能從字面上理解該消息的意義。主線程接收到該消息后,會彈出一個對話框告訴用戶,計算線程已經結束了。<BR>通過線程之間的通訊,用戶可以多次選擇"Create
Thread",那樣就可以運行多個計算線程了。<BR>本例子中,線程之間的通訊是單向的。如果您想讓主線程也能向工作者線程發送消息的話,譬如加入一個菜單項來控制工作者線程的結束,您可以這樣做:
<UL>
<LI>add a menu item saying something like "Kill Thread" in the menu
<LI>a global variable which is used as a command flag. TRUE=Stop the thread,
FALSE=continue the thread
<LI>Modify ThreadProc to check the value of the command flag in the loop.
</LI></UL>設立一個全局變量,當線程啟動前,我們設置它的值為FALSE,當用戶激活了我們加的菜單項時,該值變成TRUE。在線程的代碼段ThreadProc中每次減1前,判斷該值,如果為TRUE的話線程就結束循環體中的計算并退出線程。
<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 + -