亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ch27.htm

?? Learning language of Visual C++6
?? HTM
?? 第 1 頁 / 共 4 頁
字號:
Stop Thread command to the Thread menu.</I></P>

<DL>
	<DT><I></I></DT>
	<P>
	<DD><B>2.</B> Use ClassWizard to associate the ID_STOPTHREAD command with the OnStopthread()
	message-response function, as shown in Figure 27.7. Make sure that you have <B>CThreadView</B>
	selected in the Class Name box before you add the function. Add the following line
	to the OnStopthread() function, replacing the TODO: Add your command handler code
	here comment:
</DL>



<BLOCKQUOTE>
	<PRE>threadController = 0;</PRE>

</BLOCKQUOTE>

<PRE></PRE>
<P><A HREF="javascript:popUp('27uvc07.gif')"><B>FIG. 27.7</B></A><B> </B><I>Add the
OnStopthread() message-response function.</I></P>

<P><I></I></P>

<DL>
	<DD>This refers to a new global variable you are about to declare.
	<P>
	<DT></DT>
	<DD><B>3. </B>Add the following line to the top of the ThreadView.cpp file, right
	after the endif directive:
</DL>



<BLOCKQUOTE>
	<PRE>volatile int threadController;</PRE>

</BLOCKQUOTE>

<PRE></PRE>

<DL>
	<DT></DT>
	<DD>The volatile keyword means that you expect this variable will be changed from
	outside a thread that uses it. The keyword requests that the compiler not cache the
	variable in a register or in any way count on the value staying unchanged just because
	code in one thread doesn't seem to change it.
	<P>
	<DT></DT>
	<DD><B>4. </B>Add the following line to the OnStartthread() function, before the
	two lines you added earlier:
</DL>



<BLOCKQUOTE>
	<PRE>    threadController = 1;</PRE>

</BLOCKQUOTE>

<PRE></PRE>

<DL>
	<DT></DT>
	<DD>By now, perhaps, you've guessed that the value of threadController determines
	whether the thread will continue. Replace the ThreadProc() function with the one
	shown in Listing 27.2.
	<P>
</DL>

<H4>Listing 27.2&#160;&#160;The New ThreadProc() Function</H4>
<PRE>UINT ThreadProc(LPVOID param)
{
    ::MessageBox((HWND)param, &quot;Thread activated.&quot;, &quot;Thread&quot;, MB_OK);
    
     while (threadController == 1)
     {
          ;
     }
    ::MessageBox((HWND)param, &quot;Thread stopped.&quot;, &quot;Thread&quot;, MB_OK);
    return 0;
</PRE>
<PRE>}
</PRE>
<P>Now the thread first displays a message box, telling the user that the thread
is starting. Then a while loop continues to check the threadController global variable,
waiting for its value to change to 0. Although this while loop is trivial, it is
here that you would place the code that performs whatever task you want the thread
to perform, making sure not to tie things up for too long before rechecking the value
of threadController.</P>
<P>Try a test: Build and run the program, and choose Thread, Start Thread to start
the secondary thread. When you do, a message box appears, telling you that the new
thread was started. To stop the thread, select the Thread, Stop Thread command. Again,
a message box appears, this time telling you that the thread is stopping.</P>


<BLOCKQUOTE>
	<P>
<HR>
<strong>CAUTION:</strong><B> </B>Using global variables to communicate between threads is,
	to say the least, an unsophisticated approach to thread communication and can be
	a dangerous technique if you're not sure how C++ handles variables from an assembly-language
	level. Other thread-communication techniques are safer and more elegant. 
<HR>


</BLOCKQUOTE>

<H3><A NAME="Heading4"></A>Communicating with User-Defined Messages</H3>
<P>Now you have a simple, albeit unsophisticated, method for communicating information
from your main program to your thread. How about the reverse? That is, how can your
thread communicate with the main program? The easiest method to accomplish this communication
is to incorporate user-defined Windows messages into the program.</P>
<P>The first step is to define a user message, which you can do easily, like this:</P>
<P>
<PRE>const WM_USERMSG = WM_USER + 100;
</PRE>
<P>The WM_USER constant, defined by Windows, holds the first available user-message
number. Because other parts of your program may use some user messages for their
own purposes, the preceding line sets WM_USERMSG to WM_USER+100.</P>
<P>After defining the message, you call ::PostMessage() from the thread to send the
message to the main program whenever you need to. (Message handling was discussed
in Chapter 3, &quot;Messages and Commands.&quot; Sending your own messages allows
you to take advantage of the message-handling facility built into MFC.) A typical
call to ::PostMessage() might look like this:</P>
<P>
<PRE>::PostMessage((HWND)param, WM_USERMSG, 0, 0);
</PRE>
<P>PostMessage()'s four arguments are the handle of the window to which the message
should be sent, the message identifier, and the message's WPARAM and LPARAM parameters.</P>
<P>Modify the Thread application according to the next steps to see how to implement
posting user messages from a thread.</P>

<DL>
	<DT></DT>
	<DD><B>1. </B>Add the following line to the top of the ThreadView.h header file,
	right before the beginning of the class declaration:
	<P>
</DL>

<PRE>const WM_THREADENDED = WM_USER + 100;
</PRE>

<DL>
	<DT></DT>
	<DD><B>2.</B> Still in the header file, add the following line to the message map,
	right after the //{{AFX_MSG(CThreadView) comment and before DECLARE_MESSAGE_MAP:
	<P>
</DL>

<PRE>    afx_msg LONG OnThreadended(WPARAM wParam, LPARAM lParam);
</PRE>

<DL>
	<DT></DT>
	<DD><B>3. </B>Switch to the ThreadView.cpp file and add the following line to the
	class's message map, making sure to place it right <I>after</I> the }}AFX_MSG_MAP
	comment:
	<P>
</DL>

<PRE>    ON_MESSAGE(WM_THREADENDED, OnThreadended)
</PRE>

<DL>
	<DT></DT>
	<DD><B>4. </B>Replace the ThreadProc() function with the one shown in Listing 27.3.
	<P>
</DL>

<H4>Listing 27.3&#160;&#160;The Message-Posting ThreadProc()</H4>
<PRE>UINT ThreadProc(LPVOID param)
{
    ::MessageBox((HWND)param, &quot;Thread activated.&quot;, &quot;Thread&quot;, MB_OK);
    
     while (threadController == 1)
     {
          ;
     }
    ::PostMessage((HWND)param, WM_THREADENDED, 0, 0);
    return 0;
</PRE>
<PRE>}
</PRE>

<DL>
	<DT></DT>
	<DD><B>5. </B>Add the function shown in Listing 27.4 to the end of the ThreadView.cpp
	file.
	<P>
</DL>

<H4>Listing 27.4&#160;&#160;CThreadView::OnThreadended()</H4>
<PRE>LONG CThreadView::OnThreadended(WPARAM wParam, LPARAM lParam)
{
    AfxMessageBox(&quot;Thread ended.&quot;);
    return 0;
</PRE>
<PRE>}
</PRE>
<P>When you run the new version of the Thread program, select the Thread, Start Thread
command to start the thread. When you do, a message box appears, telling you that
the thread has started. To end the thread, select the Thread, Stop Thread command.
Just as with the previous version of the program, a message box appears, telling
you that the thread has ended.</P>
<P>Although this version of the Thread application seems to run identically to the
previous version, there's a subtle difference. Now the program displays the message
box that signals the end of the thread in the main program rather than from inside
the thread. The program can do this because, when the user selects the Stop Thread
command, the thread sends a WM_THREADENDED message to the main program. When the
program receives that message, it displays the final message box.</P>
<P>
<H3><A NAME="Heading5"></A>Communicating with Event Objects</H3>
<P>A slightly more sophisticated method of signaling between threads is to use <I>event
objects,</I> which under MFC are represented by the CEvent class. An event object
can be in one of two states: signaled and nonsignaled. Threads can watch for events
to be signaled and so perform their operations at the appropriate time. Creating
an event object is as easy as declaring a global variable, like this:</P>
<P>
<PRE>CEvent threadStart;
</PRE>
<P>Although the CEvent constructor has a number of optional arguments, you can usually
get away with creating the default object, as shown in the previous line of code.
On creation, the event object is automatically in its nonsignaled state. To signal
the event, you call the event object's SetEvent() member function, like this:</P>
<P>
<PRE>threadStart.SetEvent();
</PRE>
<P>After the preceding line executes, the threadStart event object will be in its
signaled state. Your thread should be watching for this signal so that the thread
knows it's okay to get to work. How does a thread watch for a signal? By calling
the Windows API function, WaitForSingleObject():</P>
<P>
<PRE>::WaitForSingleObject(threadStart.m_hObject, INFINITE);
</PRE>
<P>This function's two arguments are</P>

<UL>
	<LI>The handle of the event for which to check (stored in the event object's m_hObject
	data member)
	<P>
	<LI>The length of time the function should wait for the event
</UL>

<P>The predefined INFINITE constant tells WaitForSingleObject() not to return until
the specified event is signaled. In other words, if you place the preceding line
at the beginning of your thread, the system suspends the thread until the event is
signaled. Even though you've started the thread execution, it's halted until whatever
you need to happen happens. When your program is ready for the thread to perform
its duty, you call the SetEvent() function, as previously described.</P>
<P>When the thread is no longer suspended, it can go about its business. However,
if you want to signal the end of the thread from the main program, the thread must
watch for this next event to be signaled. The thread can do this by polling for the
event. To poll for the event, you again call WaitForSingleObject(), only this time
you give the function a wait time of 0, like this:</P>
<P>
<PRE>::WaitForSingleObject(threadend.m_hObject, 0);
</PRE>
<P>In this case, if WaitForSingleObject() returns WAIT_OBJECT_0, the event has been
signaled. Otherwise, the event is still in its nonsignaled state.</P>
<P>To better see how event objects work, follow these steps to further modify the
Thread application:</P>

<DL>
	<DT></DT>
	<DD><B>1. </B>Add the following line to the top of the ThreadView.cpp file, right
	after the line #include &quot;ThreadView.h&quot;:
	<P>
</DL>

<PRE>#include &quot;afxmt.h&quot;
</PRE>

<DL>
	<DT></DT>
	<DD><B>2. </B>Add the following lines near the top of the ThreadView.cpp file, after
	the volatile int threadController line that you placed there previously:
	<P>
</DL>

<PRE>CEvent threadStart;
CEvent threadEnd;
</PRE>

<DL>
	<DT></DT>
	<DD><B>3. </B>Delete the volatile int threadController line from the file.
	<P>
	<DT></DT>
	<DD><B>4. </B>Replace the ThreadProc() function with the one shown in Listing 27.5.
	<P>
</DL>

<H4>Listing 27.5&#160;&#160;Yet Another ThreadProc()</H4>
<PRE>UINT ThreadProc(LPVOID param)
{
    ::WaitForSingleObject(threadStart.m_hObject, INFINITE);
    ::MessageBox((HWND)param, &quot;Thread activated.&quot;,
        &quot;Thread&quot;, MB_OK);
    BOOL keepRunning = TRUE;
    while (keepRunning)
    {
        int result =
            ::WaitForSingleObject(threadEnd.m_hObject, 0);
        if (result == WAIT_OBJECT_0)
            keepRunning = FALSE;
    }
    ::PostMessage((HWND)param, WM_THREADENDED, 0, 0);
    return 0;
</PRE>
<PRE>}
</PRE>

<DL>
	<DT></DT>
	<DD><B>5. </B>Replace all the code in the OnStartthread() function with the following
	line:
	<P>
</DL>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲不卡av一区二区三区| 国内精品伊人久久久久影院对白| 亚洲图片欧美综合| 国产精品综合久久| 欧美综合在线视频| 国产精品欧美一区二区三区| 三级成人在线视频| 92国产精品观看| 久久九九国产精品| 另类小说综合欧美亚洲| 欧美在线啊v一区| 国产精品美日韩| 国产精一品亚洲二区在线视频| 91.xcao| 亚洲私人黄色宅男| 国产精品99久久久| 欧美电影免费观看高清完整版在线观看| 亚洲精品免费一二三区| 国产成人一区二区精品非洲| 欧美大片在线观看| 免费欧美在线视频| 91精品在线观看入口| 亚洲自拍另类综合| 91福利在线导航| 亚洲欧美另类小说视频| 成人丝袜18视频在线观看| 久久看人人爽人人| 国产呦精品一区二区三区网站| 7777精品伊人久久久大香线蕉| 亚洲精品成a人| 色综合久久久久综合体桃花网| 中文字幕在线播放不卡一区| 国产91精品久久久久久久网曝门| 久久综合色8888| 国产精品一区二区三区乱码| 精品免费国产二区三区 | 国产精品三级久久久久三级| 久久国产精品色婷婷| 日韩一级黄色片| 久久精品av麻豆的观看方式| 日韩欧美一区二区久久婷婷| 蜜臀a∨国产成人精品| 欧美一区二区三区视频在线观看| 视频在线观看一区| 日韩一区二区电影网| 久久精品国产成人一区二区三区| 日韩欧美专区在线| 国产一区二区三区香蕉| 久久久欧美精品sm网站| 春色校园综合激情亚洲| 国产精品毛片久久久久久久| 99精品视频在线观看| 亚洲高清不卡在线观看| 在线播放国产精品二区一二区四区 | 欧美日韩久久一区二区| 亚洲成a人片在线不卡一二三区| 欧美日韩国产a| 极品美女销魂一区二区三区免费| 精品免费一区二区三区| 高清视频一区二区| 一区二区三区av电影| 欧美精品xxxxbbbb| 国产乱码精品一区二区三区忘忧草 | 精品视频一区 二区 三区| 日韩av在线播放中文字幕| 久久久综合精品| 日本韩国精品在线| 麻豆国产精品官网| 最新国产成人在线观看| 91麻豆精品91久久久久同性| 国产精品一区免费视频| 一区二区三区美女| 久久蜜桃av一区二区天堂| 在线一区二区三区四区| 国内久久精品视频| 亚洲国产一区二区a毛片| 精品国产凹凸成av人导航| 91小视频在线免费看| 裸体一区二区三区| 一个色综合网站| 久久亚洲捆绑美女| 欧美人与性动xxxx| 91丨porny丨中文| 激情综合网av| 午夜精品在线看| 中文字幕一区二区三区在线观看| 777色狠狠一区二区三区| av电影在线观看不卡| 久久成人免费电影| 日韩专区一卡二卡| 亚洲九九爱视频| 国产日产欧美精品一区二区三区| 欧美日韩国产高清一区二区三区 | 久久久午夜精品| 欧美日韩国产在线播放网站| 国产成人精品免费在线| 日本视频一区二区| 亚洲综合色丁香婷婷六月图片| 久久久久88色偷偷免费| 日韩欧美一级在线播放| 精品视频1区2区| 色又黄又爽网站www久久| 成人激情小说乱人伦| 精品一区二区三区久久久| 日韩电影在线看| 亚洲国产一区二区三区| 一二三四区精品视频| 国产精品看片你懂得| 国产女主播在线一区二区| 精品成人一区二区三区| 欧美一区二区二区| 欧美一个色资源| 欧美一区二区网站| 777午夜精品视频在线播放| 欧美日韩在线精品一区二区三区激情| 99精品欧美一区二区蜜桃免费| 国产suv一区二区三区88区| 国产精品中文字幕欧美| 国产一区二区精品久久99| 国内精品免费**视频| 韩国v欧美v日本v亚洲v| 国产原创一区二区| 国产99精品国产| 成人av网站免费观看| 91小视频在线| 欧美日韩在线播| 4hu四虎永久在线影院成人| 在线播放日韩导航| 日韩精品一区二区三区四区视频 | 国产精品乱子久久久久| 国产精品久久久久影院老司| 国产精品传媒入口麻豆| 亚洲欧洲中文日韩久久av乱码| 亚洲色图一区二区| 亚洲成a人v欧美综合天堂| 日韩av电影免费观看高清完整版在线观看| 日韩高清在线一区| 韩国成人在线视频| 91一区一区三区| 欧美情侣在线播放| 久久日一线二线三线suv| 中文幕一区二区三区久久蜜桃| 18成人在线观看| 亚洲国产va精品久久久不卡综合| 日韩中文欧美在线| 国产乱码精品一区二区三区忘忧草| 国产91高潮流白浆在线麻豆| 在线观看视频一区| 欧美一三区三区四区免费在线看| 久久综合久久综合九色| 亚洲天堂2016| 久久99蜜桃精品| av激情亚洲男人天堂| 5858s免费视频成人| 日本一区二区三区久久久久久久久不| 一区二区三区中文字幕精品精品| 日本少妇一区二区| 成人一区二区三区中文字幕| 欧美午夜精品一区二区三区 | 国内精品伊人久久久久av影院| av一区二区三区四区| 欧美一二三区在线| 亚洲欧美一区二区三区极速播放| 视频一区二区不卡| av成人动漫在线观看| 欧美高清视频在线高清观看mv色露露十八 | 欧美丝袜自拍制服另类| 国产亚洲精品bt天堂精选| 亚洲国产精品麻豆| 成人av资源站| 久久免费看少妇高潮| 午夜欧美大尺度福利影院在线看 | 在线精品视频一区二区| 久久久www免费人成精品| 亚洲国产精品一区二区www| 成人99免费视频| 精品乱码亚洲一区二区不卡| 亚洲国产欧美在线| 91毛片在线观看| 欧美国产一区视频在线观看| 亚洲第一福利视频在线| 色综合久久久久综合体| 中文字幕欧美国产| 国产精品一区二区免费不卡| 日韩三区在线观看| 天天综合色天天综合色h| 在线亚洲人成电影网站色www| 国产色一区二区| 韩国精品主播一区二区在线观看 | 日本韩国精品在线| 中文字幕在线免费不卡| 国产成人久久精品77777最新版本 国产成人鲁色资源国产91色综 | 欧美在线小视频| 亚洲精品久久7777| 91香蕉视频在线| 亚洲精品免费在线观看| gogogo免费视频观看亚洲一| 国产欧美视频在线观看| 经典三级在线一区| 久久伊99综合婷婷久久伊|