?? lion-tutorial16.htm
字號:
<html>
<head>
<link rel="stylesheet" href="../../asm.css">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>
<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 16: Event Object</p>
<hr size="1">
<strong> </strong> We will learn what an event object is and how to use it in
a multithreaded program.
<p>Download the example <a href="files/tut16.zip">here</a>.
<h3> Theory:</h3>
From the previous tutorial, I demonstrated how threads communicate with a custom
window message. I left out two other methods: global variable and event object.
We will use both of them in this tutorial. <br>
An event object is like a switch: it has only two states: on or off. When an event
object is turned on, it's in the "signalled" state. When it is turned off, it's
in the "nonsignalled" state. You create an event object and put in a code snippet
in the relevant threads to watch for the state of the event object. If the event
object is in the nonsignalled state, the threads that wait for it will be asleep.When
the threads are in wait state, they consume little CPU time. <br>
You create an event object by calling CreateEvent function which has the following
syntax:
<p><b>CreateEvent proto lpEventAttributes:DWORD,\</b> <br>
<b>
bManualReset:DWORD,\</b> <br>
<b>
bInitialState:DWORD,\</b> <br>
<b>
lpName:DWORD</b>
<p><b>lpEventAttribute</b>--> If you specify NULL value, the event object is created
with default security descriptor. <br>
<b>bManualReset</b>--> If you want Windows to automatically reset the event
object to nonsignalled state after WaitForSingleObject call, you must specify
FALSE as this parameter. Else you must manually reset the event object with
the call to ResetEvent. <br>
<b>bInitialState</b>--> If you want the event object to be created in the signalled
state, specify TRUE as this parameter else the event object will be created
in the nonsignalled state. <br>
<b>lpName</b> --> Pointer to an ASCIIZ string that is the name of the event
object. This name is used when you want to call OpenEvent.
<p>If the call is successful, it returns the handle to the newly created event
object else it returns NULL. <br>
You can modify the state of an event object with two API calls: SetEvent and
ResetEvent. SetEvent function sets the event object into signalled state. ResetEvent
does the reverse. <br>
When the event object is created, you must put the call to WaitForSingleObject
in the thread that wants to watch for the state of the event object. WaitForSingleObject
has the following syntax:
<p><b>WaitForSingleObject proto hObject:DWORD, dwTimeout:DWORD</b>
<p><b>hObject</b> --> A handle to one of the synchronization object. Event object
is a type of synchronization object. <br>
<b>dwTimeout </b>--> specify the time in milliseconds that this function will
wait for the object to be in signalled state. If the specified time has passed
and the event object is still in nonsignalled state, WaitForSingleObject returns
the the caller. If you want to wait for the object indefinitely, you must specify
the value INFINITE as this parameter.
<h3> Example:</h3>
The example below displays a window waiting for the user to select a command from
the menu. If the user selects "run thread", the thread starts the savage calculation.
When it's finished, a message box appears informing the user that the job is done.
During the time that the thread is running, the user can select "stop thread"
to stop the thread.
<p><b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b> <br>
<b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b>
<p><b>.const</b> <br>
<b>IDM_START_THREAD equ 1</b> <br>
<b>IDM_STOP_THREAD equ 2</b> <br>
<b>IDM_EXIT equ 3</b> <br>
<b>WM_FINISH equ WM_USER+100h</b>
<p><b>.data</b> <br>
<b>ClassName db "Win32ASMEventClass",0</b> <br>
<b>AppName db "Win32 ASM Event Example",0</b> <br>
<b>MenuName db "FirstMenu",0</b> <br>
<b>SuccessString db "The calculation is completed!",0</b> <br>
<b>StopString db "The thread is stopped",0</b> <br>
<b>EventStop BOOL FALSE</b>
<p><b>.data?</b> <br>
<b>hInstance HINSTANCE ?</b> <br>
<b>CommandLine LPSTR ?</b> <br>
<b>hwnd HANDLE ?</b> <br>
<b>hMenu HANDLE ?</b> <br>
<b>ThreadID DWORD ?</b> <br>
<b>ExitCode DWORD ?</b> <br>
<b>hEventStart HANDLE ?</b>
<p><b>.code</b> <br>
<b>start:</b> <br>
<b> invoke GetModuleHandle, NULL</b> <br>
<b> mov hInstance,eax</b> <br>
<b> invoke GetCommandLine</b> <br>
<b> mov CommandLine,eax</b> <br>
<b> invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT</b>
<br>
<b> invoke ExitProcess,eax</b>
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b>
<br>
<b> LOCAL wc:WNDCLASSEX</b> <br>
<b> LOCAL msg:MSG</b> <br>
<b> mov wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
<b> mov wc.style, CS_HREDRAW or CS_VREDRAW</b>
<br>
<b> mov wc.lpfnWndProc, OFFSET WndProc</b> <br>
<b> mov wc.cbClsExtra,NULL</b> <br>
<b> mov wc.cbWndExtra,NULL</b> <br>
<b> push hInst</b> <br>
<b> pop wc.hInstance</b> <br>
<b> mov wc.hbrBackground,COLOR_WINDOW+1</b> <br>
<b> mov wc.lpszMenuName,OFFSET MenuName</b> <br>
<b> mov wc.lpszClassName,OFFSET ClassName</b>
<br>
<b> invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
<b> mov wc.hIcon,eax</b> <br>
<b> mov wc.hIconSm,eax</b> <br>
<b> invoke LoadCursor,NULL,IDC_ARROW</b> <br>
<b> mov wc.hCursor,eax</b> <br>
<b> invoke RegisterClassEx, addr wc</b> <br>
<b> invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,\</b>
<br>
<b> ADDR
AppName,\</b> <br>
<b> WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b>
<br>
<b> CW_USEDEFAULT,300,200,NULL,NULL,\</b>
<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> invoke GetMenu,hwnd</b> <br>
<b> mov hMenu,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>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -