1銆佸垱寤哄拰緇堟綰跨▼ 銆銆鍦∕FC紼嬪簭涓垱寤轟竴涓嚎紼嬶紝瀹滆皟鐢ˋfxBeginThread鍑芥暟銆傝鍑芥暟鍥犲弬鏁頒笉鍚岃屽叿鏈変袱縐嶉噸杞界増鏈紝鍒嗗埆瀵瑰簲宸ヤ綔鑰呯嚎紼嬪拰鐢ㄦ埛鎺ュ彛錛圲I錛夌嚎紼嬨?br /> 銆銆宸ヤ綔鑰呯嚎紼?br /> CWinThread *AfxBeginThread( 銆AFX_THREADPROC pfnThreadProc, //鎺у埗鍑芥暟 銆LPVOID pParam, //浼犻掔粰鎺у埗鍑芥暟鐨勫弬鏁?br />銆int nPriority = THREAD_PRIORITY_NORMAL, //綰跨▼鐨勪紭鍏堢駭 銆UINT nStackSize = 0, //綰跨▼鐨勫爢鏍堝ぇ灝?br />銆DWORD dwCreateFlags = 0, //綰跨▼鐨勫垱寤烘爣蹇?br />銆LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //綰跨▼鐨勫畨鍏ㄥ睘鎬?br />); |
銆銆宸ヤ綔鑰呯嚎紼嬬紪紼嬭緝涓虹畝鍗曪紝鍙渶緙栧啓綰跨▼鎺у埗鍑芥暟鍜屽惎鍔ㄧ嚎紼嬪嵆鍙備笅闈㈢殑浠g爜緇欏嚭浜嗗畾涔変竴涓帶鍒跺嚱鏁板拰鍚姩瀹冪殑榪囩▼錛?br /> //綰跨▼鎺у埗鍑芥暟 UINT MfcThreadProc(LPVOID lpParam) { 銆CExampleClass *lpObject = (CExampleClass*)lpParam; 銆if (lpObject == NULL || !lpObject->IsKindof(RUNTIME_CLASS(CExampleClass))) 銆銆return - 1; //杈撳叆鍙傛暟闈炴硶 銆//綰跨▼鎴愬姛鍚姩 銆while (1) 銆{ 銆銆...// 銆} 銆return 0; }
//鍦∕FC紼嬪簭涓惎鍔ㄧ嚎紼?br />AfxBeginThread(MfcThreadProc, lpObject); |
銆銆UI綰跨▼ 銆銆鍒涘緩鐢ㄦ埛鐣岄潰綰跨▼鏃訛紝蹇呴』棣栧厛浠嶤WinThread 媧劇敓綾伙紝騫朵嬌鐢?DECLARE_DYNCREATE 鍜?IMPLEMENT_DYNCREATE 瀹忓0鏄庢綾匯?br /> 銆銆涓嬮潰緇欏嚭浜咰WinThread綾葷殑鍘熷瀷錛堟坊鍔犱簡鍏充簬鍏墮噸瑕佸嚱鏁板姛鑳藉拰鏄惁闇瑕佽緇ф壙綾婚噸杞界殑娉ㄩ噴錛夛細 class CWinThread : public CCmdTarget { 銆DECLARE_DYNAMIC(CWinThread)
銆public: 銆銆// Constructors 銆銆CWinThread(); 銆銆BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
銆銆// Attributes 銆銆CWnd* m_pMainWnd; // main window (usually same AfxGetApp()->m_pMainWnd) 銆銆CWnd* m_pActiveWnd; // active main window (may not be m_pMainWnd) 銆銆BOOL m_bAutoDelete; // enables 'delete this' after thread termination
銆銆// only valid while running 銆銆HANDLE m_hThread; // this thread's HANDLE 銆銆operator HANDLE() const; 銆銆DWORD m_nThreadID; // this thread's ID
銆銆int GetThreadPriority(); 銆銆BOOL SetThreadPriority(int nPriority);
銆銆// Operations 銆銆DWORD SuspendThread(); 銆銆DWORD ResumeThread(); 銆銆BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);
銆銆// Overridables 銆銆//鎵ц綰跨▼瀹炰緥鍒濆鍖栵紝蹇呴』閲嶅啓 銆銆virtual BOOL InitInstance();
銆銆// running and idle processing 銆銆//鎺у埗綰跨▼鐨勫嚱鏁幫紝鍖呭惈娑堟伅娉碉紝涓鑸笉閲嶅啓 銆銆virtual int Run();
銆銆//娑堟伅璋冨害鍒癟ranslateMessage鍜孌ispatchMessage涔嬪墠瀵瑰叾榪涜絳涢夛紝 銆銆//閫氬父涓嶉噸鍐?br />銆銆virtual BOOL PreTranslateMessage(MSG* pMsg);
銆銆virtual BOOL PumpMessage(); // low level message pump
銆銆//鎵ц綰跨▼鐗瑰畾鐨勯棽緗椂闂村鐞嗭紝閫氬父涓嶉噸鍐?br />銆銆virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing 銆銆virtual BOOL IsIdleMessage(MSG* pMsg); // checks for special messages
銆銆//綰跨▼緇堟鏃舵墽琛屾竻闄わ紝閫氬父闇瑕侀噸鍐?br />銆銆virtual int ExitInstance(); // default will 'delete this'
銆銆//鎴幏鐢辯嚎紼嬬殑娑堟伅鍜屽懡浠ゅ鐞嗙▼搴忓紩鍙戠殑鏈鐞嗗紓甯革紝閫氬父涓嶉噸鍐?br />銆銆virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg);
銆銆// Advanced: handling messages sent to message filter hook 銆銆virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
銆銆// Advanced: virtual access to m_pMainWnd 銆銆virtual CWnd* GetMainWnd();
銆銆// Implementation 銆public: 銆銆virtual ~CWinThread(); 銆銆#ifdef _DEBUG 銆銆銆virtual void AssertValid() const; 銆銆銆virtual void Dump(CDumpContext& dc) const; 銆銆銆int m_nDisablePumpCount; // Diagnostic trap to detect illegal re-entrancy 銆銆#endif 銆銆void CommonConstruct(); 銆銆virtual void Delete(); 銆銆// 'delete this' only if m_bAutoDelete == TRUE
銆銆// message pump for Run 銆銆MSG m_msgCur; // current message
銆public: 銆銆// constructor used by implementation of AfxBeginThread 銆銆CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam);
銆銆// valid after construction 銆銆LPVOID m_pThreadParams; // generic parameters passed to starting function 銆銆AFX_THREADPROC m_pfnThreadProc;
銆銆// set after OLE is initialized 銆銆void (AFXAPI* m_lpfnOleTermOrFreeLib)(BOOL, BOOL); 銆銆COleMessageFilter* m_pMessageFilter;
銆protected: 銆銆CPoint m_ptCursorLast; // last mouse position 銆銆UINT m_nMsgLast; // last mouse message 銆銆BOOL DispatchThreadMessageEx(MSG* msg); // helper 銆銆void DispatchThreadMessage(MSG* msg); // obsolete };
|
銆銆鍚姩UI綰跨▼鐨凙fxBeginThread鍑芥暟鐨勫師鍨嬩負錛?br /> CWinThread *AfxBeginThread( 銆//浠嶤WinThread媧劇敓鐨勭被鐨?RUNTIME_CLASS 銆CRuntimeClass *pThreadClass, 銆int nPriority = THREAD_PRIORITY_NORMAL, 銆UINT nStackSize = 0, 銆DWORD dwCreateFlags = 0, 銆LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); |
銆銆鎴戜滑鍙互鏂逛究鍦頒嬌鐢╒C++ 6.0綾誨悜瀵煎畾涔変竴涓戶鎵胯嚜CWinThread鐨勭敤鎴風嚎紼嬬被銆備笅闈㈢粰鍑轟駭鐢熸垜浠嚜瀹氫箟鐨凜WinThread瀛愮被CMyUIThread鐨勬柟娉曘?br /> 銆銆鎵撳紑VC++ 6.0綾誨悜瀵鹼紝鍦ㄥ涓嬬獥鍙d腑閫夋嫨Base Class綾諱負CWinThread錛岃緭鍏ュ瓙綾誨悕涓篊MyUIThread錛岀偣鍑?OK"鎸夐挳鍚庡氨浜х敓浜嗙被CMyUIThread銆?br /> 銆銆鍏舵簮浠g爜妗嗘灦涓猴細 ///////////////////////////////////////////////////////////////////////////// // CMyUIThread thread
class CMyUIThread : public CWinThread { 銆DECLARE_DYNCREATE(CMyUIThread) 銆protected: 銆銆CMyUIThread(); // protected constructor used by dynamic creation
銆銆// Attributes 銆public:
銆銆// Operations 銆public:
銆銆// Overrides 銆銆// ClassWizard generated virtual function overrides 銆銆//{{AFX_VIRTUAL(CMyUIThread) 銆銆public: 銆銆銆virtual BOOL InitInstance(); 銆銆銆virtual int ExitInstance(); 銆銆//}}AFX_VIRTUAL
銆銆// Implementation 銆protected: 銆銆virtual ~CMyUIThread();
銆銆// Generated message map functions 銆銆//{{AFX_MSG(CMyUIThread) 銆銆銆// NOTE - the ClassWizard will add and remove member functions here. 銆銆//}}AFX_MSG
銆DECLARE_MESSAGE_MAP() };
///////////////////////////////////////////////////////////////////////////// // CMyUIThread
IMPLEMENT_DYNCREATE(CMyUIThread, CWinThread)
CMyUIThread::CMyUIThread() {}
CMyUIThread::~CMyUIThread() {}
BOOL CMyUIThread::InitInstance() { 銆// TODO: perform and per-thread initialization here 銆return TRUE; }
int CMyUIThread::ExitInstance() { 銆// TODO: perform any per-thread cleanup here 銆return CWinThread::ExitInstance(); }
BEGIN_MESSAGE_MAP(CMyUIThread, CWinThread) //{{AFX_MSG_MAP(CMyUIThread) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() |
銆銆浣跨敤涓嬪垪浠g爜灝卞彲浠ュ惎鍔ㄨ繖涓猆I綰跨▼錛?br /> CMyUIThread *pThread; pThread = (CMyUIThread*) AfxBeginThread( RUNTIME_CLASS(CMyUIThread) ); |
銆銆鍙﹀錛屾垜浠篃鍙互涓嶇敤AfxBeginThread 鍒涘緩綰跨▼錛岃屾槸鍒嗗涓嬩袱姝ュ畬鎴愶細 銆銆錛?錛夎皟鐢ㄧ嚎紼嬬被鐨勬瀯閫犲嚱鏁板垱寤轟竴涓嚎紼嬪璞★紱 銆銆錛?錛夎皟鐢–WinThread::CreateThread鍑芥暟鏉ュ惎鍔ㄨ綰跨▼銆?br /> 銆銆鍦ㄧ嚎紼嬭嚜韜唴璋冪敤AfxEndThread鍑芥暟鍙互緇堟璇ョ嚎紼嬶細 void AfxEndThread( 銆UINT nExitCode //the exit code of the thread ); |
銆銆瀵逛簬UI綰跨▼鑰岃█錛屽鏋滄秷鎭槦鍒椾腑鏀懼叆浜哤M_QUIT娑堟伅錛屽皢緇撴潫綰跨▼銆?br /> 銆銆鍏充簬UI綰跨▼鍜屽伐浣滆呯嚎紼嬬殑鍒嗛厤錛屾渶濂界殑鍋氭硶鏄細灝嗘墍鏈変笌UI鐩稿叧鐨勬搷浣滄斁鍏ヤ富綰跨▼錛屽叾瀹冪殑綰補鐨勮繍綆楀伐浣滀氦緇欑嫭绔嬬殑鏁頒釜宸ヤ綔鑰呯嚎紼嬨?br /> 銆銆鍊欐嵎鍏堢敓鏃╀簺鏃墮棿鍠滄涓篗DI紼嬪簭鐨勬瘡涓獥鍙e垱寤轟竴涓嚎紼嬶紝浠栧悗鏉ユ緞娓呬簡榪欎釜閿欒銆傚洜涓哄鏋滀負MDI紼嬪簭鐨勬瘡涓獥鍙i兘鍗曠嫭鍒涘緩涓涓嚎紼嬶紝鍦ㄧ獥鍙h繘琛屽垏鎹㈢殑鏃跺欙紝灝嗚繘琛岀嚎紼嬬殑涓婁笅鏂囧垏鎹紒
2.綰跨▼闂撮氫俊 銆銆MFC涓畾涔変簡緇ф壙鑷狢SyncObject綾葷殑CCriticalSection
銆丆CEvent銆丆Mutex銆丆Semaphore綾誨皝瑁呭拰綆鍖栦簡WIN32
API鎵鎻愪緵鐨勪復鐣屽尯銆佷簨浠躲佷簰鏂ュ拰淇″彿閲忋備嬌鐢ㄨ繖浜涘悓姝ユ満鍒訛紝蹇呴』鍖呭惈"Afxmt.h"澶存枃浠躲備笅鍥劇粰鍑轟簡綾葷殑緇ф壙鍏崇郴錛?br /> 銆銆浣滀負CSyncObject綾葷殑緇ф壙綾伙紝鎴戜滑浠呬粎浣跨敤鍩虹被CSyncObject鐨勬帴鍙e嚱鏁板氨鍙互鏂逛究銆佺粺涓鐨勬搷浣淐CriticalSection 銆丆CEvent銆丆Mutex銆丆Semaphore綾伙紝涓嬮潰鏄疌SyncObject綾葷殑鍘熷瀷錛?br /> class CSyncObject : public CObject { 銆DECLARE_DYNAMIC(CSyncObject)
銆// Constructor 銆public: 銆銆CSyncObject(LPCTSTR pstrName);
銆銆// Attributes 銆public: 銆銆operator HANDLE() const; 銆銆HANDLE m_hObject;
銆銆// Operations 銆銆virtual BOOL Lock(DWORD dwTimeout = INFINITE); 銆銆virtual BOOL Unlock() = 0; 銆銆virtual BOOL Unlock(LONG /* lCount */, LPLONG /* lpPrevCount=NULL */) 銆銆{ return TRUE; }
銆銆// Implementation 銆public: 銆銆virtual ~CSyncObject(); 銆銆#ifdef _DEBUG 銆銆銆CString m_strName; 銆銆銆virtual void AssertValid() const; 銆銆銆virtual void Dump(CDumpContext& dc) const; 銆銆#endif 銆銆friend class CSingleLock; 銆銆friend class CMultiLock; }; |
銆銆CSyncObject綾繪渶涓昏鐨勪袱涓嚱鏁版槸Lock鍜孶nlock錛岃嫢鎴戜滑鐩存帴浣跨敤CSyncObject綾誨強鍏舵淳鐢熺被錛屾垜浠渶瑕侀潪甯稿皬蹇冨湴鍦↙ock涔嬪悗璋冪敤Unlock銆?br /> 銆銆MFC鎻愪緵鐨勫彟涓や釜綾籆SingleLock錛堢瓑寰呬竴涓璞★級鍜孋MultiLock錛堢瓑寰呭涓璞★級涓烘垜浠紪鍐欏簲鐢ㄧ▼搴忔彁渚涗簡鏇寸伒媧葷殑鏈哄埗錛屼笅闈互瀹為檯鏉ラ槓榪癈SingleLock鐨勭敤娉曪細 class CThreadSafeWnd { 銆public: 銆銆CThreadSafeWnd(){} 銆銆~CThreadSafeWnd(){} 銆銆void SetWindow(CWnd *pwnd) 銆銆{ 銆銆銆m_pCWnd = pwnd; 銆銆} 銆銆void PaintBall(COLORREF color, CRect &rc); 銆private: 銆銆CWnd *m_pCWnd; 銆銆CCriticalSection m_CSect; };
void CThreadSafeWnd::PaintBall(COLORREF color, CRect &rc) { 銆CSingleLock csl(&m_CSect); 銆//緙虹渷鐨凾imeout鏄疘NFINITE錛屽彧鏈塵_Csect琚縺媧伙紝csl.Lock()鎵嶈兘榪斿洖 銆//true錛岃繖閲屼竴鐩寸瓑寰?br />銆if (csl.Lock()) ; 銆{ 銆銆// not necessary 銆銆//AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 銆銆CDC *pdc = m_pCWnd->GetDC(); 銆銆CBrush brush(color); 銆銆CBrush *oldbrush = pdc->SelectObject(&brush); 銆銆pdc->Ellipse(rc); 銆銆pdc->SelectObject(oldbrush); 銆銆GdiFlush(); // don't wait to update the display 銆} } |
銆銆涓婅堪瀹炰緥璁茶堪浜嗙敤CSingleLock瀵筗indows GDI鐩稿叧瀵硅薄榪涜淇濇姢鐨勬柟娉曪紝涓嬮潰鍐嶇粰鍑轟竴涓叾浠栨柟闈㈢殑渚嬪瓙錛?br /> int array1[10], array2[10]; CMutexSection section; //鍒涘緩涓涓狢Mutex綾葷殑瀵硅薄
//璧嬪肩嚎紼嬫帶鍒跺嚱鏁?br />UINT EvaluateThread(LPVOID param) { 銆CSingleLock singlelock; 銆singlelock(§ion);
銆//浜掓枼鍖哄煙 銆singlelock.Lock(); 銆for (int i = 0; i < 10; i++) 銆銆array1[i] = i; 銆singlelock.Unlock(); } //鎷瘋礉綰跨▼鎺у埗鍑芥暟 UINT CopyThread(LPVOID param) { 銆CSingleLock singlelock; 銆singlelock(§ion);
銆//浜掓枼鍖哄煙 銆singlelock.Lock(); 銆for (int i = 0; i < 10; i++) 銆銆array2[i] = array1[i]; 銆singlelock.Unlock(); } }
AfxBeginThread(EvaluateThread, NULL); //鍚姩璧嬪肩嚎紼?br />AfxBeginThread(CopyThread, NULL); //鍚姩鎷瘋礉綰跨▼ |
銆
銆涓婇潰鐨勪緥瀛愪腑鍚姩浜嗕袱涓嚎紼婨valuateThread鍜孋opyThread錛岀嚎紼婨valuateThread鎶?0涓暟璧嬪肩粰鏁扮粍array1
[]錛岀嚎紼婥opyThread灝嗘暟緇刟rray1[]鎷瘋礉緇欐暟緇刟rray2[]銆傜敱浜庢暟緇勭殑鎷瘋礉鍜岃祴鍊奸兘鏄暣浣撹涓猴紝濡傛灉涓嶄互浜掓枼褰㈠紡鎵ц浠g爜孌碉細 for (int i = 0; i < 10; i++) array1[i] = i; |
銆銆鍜?br /> for (int i = 0; i < 10; i++) array2[i] = array1[i]; |
銆銆鍏剁粨鏋滄槸寰堥毦棰勬枡鐨勶紒 銆銆闄や簡鍙嬌鐢–CriticalSection銆丆Event銆丆Mutex銆丆Semaphore浣滀負綰跨▼闂村悓姝ラ氫俊鐨勬柟寮忎互澶栵紝鎴戜滑榪樺彲浠ュ埄鐢≒ostThreadMessage鍑芥暟鍦ㄧ嚎紼嬮棿鍙戦佹秷鎭細 BOOL PostThreadMessage(DWORD idThread, // thread identifier UINT Msg, // message to post WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); |
3.綰跨▼涓庢秷鎭槦鍒?br /> 銆銆鍦╓IN32涓紝姣忎竴涓嚎紼嬮兘瀵瑰簲鐫涓涓秷鎭槦鍒椼傜敱浜庝竴涓嚎紼嬪彲浠ヤ駭鐢熸暟涓獥鍙o紝鎵浠ュ茍涓嶆槸姣忎釜紿楀彛閮藉搴旂潃涓涓秷鎭槦鍒椼備笅鍒楀嚑鍙ヨ瘽搴旇浣滀負"瀹氱悊"琚浣忥細 銆銆"瀹氱悊" 涓 銆銆鎵鏈変駭鐢熺粰鏌愪釜紿楀彛鐨勬秷鎭紝閮藉厛鐢卞垱寤鴻繖涓獥鍙g殑綰跨▼澶勭悊錛?br /> 銆銆"瀹氱悊" 浜?br /> 銆銆Windows灞忓箷涓婄殑姣忎竴涓帶浠墮兘鏄竴涓獥鍙o紝鏈夊搴旂殑紿楀彛鍑芥暟銆?br /> 銆銆娑堟伅鐨勫彂閫侀氬父鏈変袱縐嶆柟寮忥紝涓鏄疭endMessage錛屼竴鏄疨ostMessage錛屽叾鍘熷瀷鍒嗗埆涓猴細 LRESULT SendMessage(HWND hWnd, // handle of destination window 銆UINT Msg, // message to send 銆WPARAM wParam, // first message parameter 銆LPARAM lParam // second message parameter ); BOOL PostMessage(HWND hWnd, // handle of destination window 銆UINT Msg, // message to post 銆WPARAM wParam, // first message parameter 銆LPARAM lParam // second message parameter ); |
銆
銆涓や釜鍑芥暟鍘熷瀷涓殑鍥涗釜鍙傛暟鐨勬剰涔夌浉鍚岋紝浣嗘槸SendMessage鍜孭ostMessage鐨勮涓烘湁宸紓銆係endMessage蹇呴』絳夊緟娑堟伅琚鐞嗗悗
鎵嶈繑鍥烇紝鑰孭ostMessage浠呬粎灝嗘秷鎭斁鍏ユ秷鎭槦鍒椼係endMessage鐨勭洰鏍囩獥鍙e鏋滃睘浜庡彟涓涓嚎紼嬶紝鍒欎細鍙戠敓綰跨▼涓婁笅鏂囧垏鎹紝絳夊緟鍙︿竴綰跨▼
澶勭悊瀹屾垚娑堟伅銆備負浜嗛槻姝㈠彟涓綰跨▼褰撴帀錛屽鑷碨endMessage姘歌繙涓嶈兘榪斿洖錛屾垜浠彲浠ヨ皟鐢⊿endMessageTimeout鍑芥暟錛?br /> LRESULT SendMessageTimeout( 銆HWND hWnd, // handle of destination window 銆UINT Msg, // message to send 銆WPARAM wParam, // first message parameter 銆LPARAM lParam, // second message parameter 銆UINT fuFlags, // how to send the message 銆UINT uTimeout, // time-out duration 銆LPDWORD lpdwResult // return value for synchronous call ); |
銆銆4. MFC綰跨▼銆佹秷鎭槦鍒椾笌MFC紼嬪簭鐨?鐢熸鍥犳灉" 銆銆鍒嗘瀽MFC紼嬪簭鐨勪富綰跨▼鍚姩鍙婃秷鎭槦鍒楀鐞嗙殑榪囩▼灝嗘湁鍔╀簬鎴戜滑榪涗竴姝ョ悊瑙I綰跨▼涓庢秷鎭槦鍒楃殑鍏崇郴錛屼負姝ゆ垜浠渶瑕佺畝鍗曞湴鍙欒堪涓涓婱FC紼嬪簭鐨?鐢熸鍥犳灉"錛堜警鎹鳳細銆婃繁鍏ユ祬鍑篗FC銆嬶級銆?br /> 銆銆浣跨敤VC++ 6.0鐨勫悜瀵煎畬鎴愪竴涓渶綆鍗曠殑鍗曟枃妗f灦鏋凪FC搴旂敤紼嬪簭MFCThread錛?br /> 銆銆錛?錛?杈撳叆MFC EXE宸ョ▼鍚峂FCThread錛?br /> 銆銆錛?錛?閫夋嫨鍗曟枃妗f灦鏋勶紝涓嶆敮鎸丏ocument/View緇撴瀯錛?br /> 銆銆錛?錛?ActiveX銆?D container絳夊叾浠栭夐」閮介夋嫨鏃犮?br /> 銆銆鎴戜滑鏉ュ垎鏋愯繖涓伐紼嬨備笅闈㈡槸浜х敓鐨勬牳蹇冩簮浠g爜錛?br /> 銆銆MFCThread.h 鏂囦歡 class CMFCThreadApp : public CWinApp { 銆public: 銆銆CMFCThreadApp();
銆銆// Overrides 銆銆// ClassWizard generated virtual function overrides 銆銆//{{AFX_VIRTUAL(CMFCThreadApp) 銆銆銆public: 銆銆銆銆virtual BOOL InitInstance(); 銆銆//}}AFX_VIRTUAL
銆銆// Implementation
銆public: 銆銆//{{AFX_MSG(CMFCThreadApp) 銆銆銆afx_msg void OnAppAbout(); 銆銆銆// NOTE - the ClassWizard will add and remove member functions here. 銆銆銆// DO NOT EDIT what you see in these blocks of generated code ! 銆銆//}}AFX_MSG 銆DECLARE_MESSAGE_MAP() }; |
銆銆MFCThread.cpp鏂囦歡 CMFCThreadApp theApp;
///////////////////////////////////////////////////////////////////////////// // CMFCThreadApp initialization
BOOL CMFCThreadApp::InitInstance() { 銆鈥?br />銆CMainFrame* pFrame = new CMainFrame; 銆m_pMainWnd = pFrame;
銆// create and load the frame with its resources 銆pFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,NULL); 銆// The one and only window has been initialized, so show and update it. 銆pFrame->ShowWindow(SW_SHOW); 銆pFrame->UpdateWindow();
銆return TRUE; } |
銆銆MainFrm.h鏂囦歡 #include "ChildView.h"
class CMainFrame : public CFrameWnd { 銆public: 銆銆CMainFrame(); 銆protected: 銆銆DECLARE_DYNAMIC(CMainFrame)
銆銆// Attributes 銆public:
銆銆// Operations 銆public: 銆銆// Overrides 銆銆// ClassWizard generated virtual function overrides 銆銆//{{AFX_VIRTUAL(CMainFrame) 銆銆銆virtual BOOL PreCreateWindow(CREATESTRUCT& cs); 銆銆銆virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); 銆銆//}}AFX_VIRTUAL
銆銆// Implementation 銆public: 銆銆virtual ~CMainFrame(); 銆銆#ifdef _DEBUG 銆銆銆virtual void AssertValid() const; 銆銆銆virtual void Dump(CDumpContext& dc) const; 銆銆#endif 銆銆CChildView m_wndView;
銆銆// Generated message map functions 銆protected: 銆//{{AFX_MSG(CMainFrame) 銆銆afx_msg void OnSetFocus(CWnd *pOldWnd); 銆銆// NOTE - the ClassWizard will add and remove member functions here. 銆銆// DO NOT EDIT what you see in these blocks of generated code! 銆//}}AFX_MSG 銆DECLARE_MESSAGE_MAP() }; |
銆銆MainFrm.cpp鏂囦歡 IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) 銆//{{AFX_MSG_MAP(CMainFrame) 銆銆// NOTE - the ClassWizard will add and remove mapping macros here. 銆銆// DO NOT EDIT what you see in these blocks of generated code ! 銆銆ON_WM_SETFOCUS() 銆//}}AFX_MSG_MAP END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CMainFrame construction/destruction
CMainFrame::CMainFrame() { 銆// TODO: add member initialization code here }
CMainFrame::~CMainFrame() {}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { 銆if( !CFrameWnd::PreCreateWindow(cs) ) 銆銆return FALSE; 銆銆// TODO: Modify the Window class or styles here by modifying 銆銆// the CREATESTRUCT cs
銆cs.dwExStyle &= ~WS_EX_CLIENTEDGE; 銆cs.lpszClass = AfxRegisterWndClass(0); 銆return TRUE; } |
銆銆ChildView.h鏂囦歡 // CChildView window
class CChildView : public CWnd { 銆// Construction 銆public: 銆銆CChildView();
銆銆// Attributes 銆public: 銆銆// Operations 銆public: 銆銆// Overrides 銆銆// ClassWizard generated virtual function overrides 銆銆//{{AFX_VIRTUAL(CChildView) 銆銆銆protected: 銆銆銆銆virtual BOOL PreCreateWindow(CREATESTRUCT& cs); 銆銆//}}AFX_VIRTUAL
銆銆// Implementation 銆public: 銆銆virtual ~CChildView();
銆銆// Generated message map functions 銆protected: 銆銆//{{AFX_MSG(CChildView) 銆銆銆afx_msg void OnPaint(); 銆銆//}}AFX_MSG 銆DECLARE_MESSAGE_MAP() };
ChildView.cpp鏂囦歡 // CChildView
CChildView::CChildView() {}
CChildView::~CChildView() {}
BEGIN_MESSAGE_MAP(CChildView,CWnd ) //{{AFX_MSG_MAP(CChildView) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) { 銆if (!CWnd::PreCreateWindow(cs)) 銆銆return FALSE;
銆cs.dwExStyle |= WS_EX_CLIENTEDGE; 銆cs.style &= ~WS_BORDER; 銆cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1),NULL);
銆return TRUE; }
void CChildView::OnPaint() { 銆CPaintDC dc(this); // device context for painting
銆// TODO: Add your message handler code here 銆// Do not call CWnd::OnPaint() for painting messages } |
銆
銆鏂囦歡MFCThread.h鍜孧FCThread.cpp瀹氫箟鍜屽疄鐜扮殑綾籆MFCThreadApp緇ф壙鑷狢WinApp綾伙紝鑰孋WinApp綾誨張緇ф壙
鑷狢WinThread綾伙紙CWinThread綾誨張緇ф壙鑷狢CmdTarget綾伙級錛屾墍浠MFCThread鏈川涓婃槸涓涓狹FC綰跨▼綾伙紝涓嬪浘緇欏嚭浜嗙浉
鍏崇殑綾誨眰嬈$粨鏋勶細
鎴戜滑鎻愬彇CWinApp綾誨師鍨嬬殑涓閮ㄥ垎錛?br /> class CWinApp : public CWinThread { 銆DECLARE_DYNAMIC(CWinApp) 銆public: 銆銆// Constructor 銆銆CWinApp(LPCTSTR lpszAppName = NULL);// default app name 銆銆// Attributes 銆銆// Startup args (do not change) 銆銆HINSTANCE m_hInstance; 銆銆HINSTANCE m_hPrevInstance; 銆銆LPTSTR m_lpCmdLine; 銆銆int m_nCmdShow; 銆銆// Running args (can be changed in InitInstance) 銆銆LPCTSTR m_pszAppName; // human readable name 銆銆LPCTSTR m_pszExeName; // executable name (no spaces) 銆銆LPCTSTR m_pszHelpFilePath; // default based on module path 銆銆LPCTSTR m_pszProfileName; // default based on app name
銆銆// Overridables 銆銆virtual BOOL InitApplication(); 銆銆virtual BOOL InitInstance(); 銆銆virtual int ExitInstance(); // return app exit code 銆銆virtual int Run(); 銆銆virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing 銆銆virtual LRESULT ProcessWndProcException(CException* e,const MSG* pMsg);
銆public: 銆銆virtual ~CWinApp(); 銆protected: 銆銆DECLARE_MESSAGE_MAP() }; |
銆銆SDK紼嬪簭鐨刉inMain 鎵瀹屾垚鐨勫伐浣滅幇鍦ㄧ敱CWinApp 鐨勪笁涓嚱鏁板畬鎴愶細 virtual BOOL InitApplication(); virtual BOOL InitInstance(); virtual int Run(); |
銆
銆"CMFCThreadApp theApp;"璇彞瀹氫箟鐨勫叏灞鍙橀噺theApp鏄暣涓▼寮忕殑application object錛屾瘡涓涓狹FC
搴旂敤紼嬪簭閮芥湁涓涓傚綋鎴戜滑鎵цMFCThread紼嬪簭鐨勬椂鍊欙紝榪欎釜鍏ㄥ眬鍙橀噺琚瀯閫犮倀heApp
閰嶇疆瀹屾垚鍚庯紝WinMain寮濮嬫墽琛屻備絾鏄▼搴忎腑騫舵病鏈塛inMain鐨勪唬鐮侊紝瀹冨湪鍝噷鍛紵鍘熸潵MFC鏃╁凡鍑嗗濂藉茍鐢盠inker鐩存帴鍔犲埌搴旂敤紼嬪簭浠g爜涓?
鐨勶紝鍏跺師鍨嬩負錛堝瓨鍦ㄤ簬VC++6.0瀹夎鐩綍涓嬫彁渚涚殑APPMODUL.CPP鏂囦歡涓級錛?br /> extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { 銆// call shared/exported WinMain 銆return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } |
銆銆鍏朵腑璋冪敤鐨凙fxWinMain濡備笅錛堝瓨鍦ㄤ簬VC++6.0瀹夎鐩綍涓嬫彁渚涚殑WINMAIN.CPP鏂囦歡涓級錛?br /> int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { 銆ASSERT(hPrevInstance == NULL);
銆int nReturnCode = -1; 銆CWinThread* pThread = AfxGetThread(); 銆CWinApp* pApp = AfxGetApp();
銆// AFX internal initialization 銆if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) 銆銆goto InitFailure;
銆// App global initializations (rare) 銆if (pApp != NULL && !pApp->InitApplication()) 銆銆goto InitFailure;
銆// Perform specific initializations 銆if (!pThread->InitInstance()) 銆{ 銆銆if (pThread->m_pMainWnd != NULL) 銆銆{ 銆銆銆TRACE0("Warning: Destroying non-NULL m_pMainWnd\n"); 銆銆銆pThread->m_pMainWnd->DestroyWindow(); 銆銆} 銆銆nReturnCode = pThread->ExitInstance(); 銆銆goto InitFailure; 銆} 銆nReturnCode = pThread->Run();
銆InitFailure: 銆#ifdef _DEBUG 銆銆// Check for missing AfxLockTempMap calls 銆銆if (AfxGetModuleThreadState()->m_nTempMapLock != 0) 銆銆{ 銆銆銆TRACE1("Warning: Temp map lock count non-zero (%ld).\n", AfxGetModuleThreadState()->m_nTempMapLock); 銆銆} 銆銆AfxLockTempMaps(); 銆銆AfxUnlockTempMaps(-1); 銆#endif
銆AfxWinTerm(); 銆return nReturnCode; } |
銆銆鎴戜滑鎻愬彇涓誨共錛屽疄闄呬笂錛岃繖涓嚱鏁板仛鐨勪簨鎯呬富瑕佹槸錛?br /> CWinThread* pThread = AfxGetThread(); CWinApp* pApp = AfxGetApp(); AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow) pApp->InitApplication() pThread->InitInstance() pThread->Run(); |
銆
銆鍏朵腑錛孖nitApplication
鏄敞鍐岀獥鍙g被鍒殑鍦烘墍錛汭nitInstance鏄駭鐢熺獥鍙e茍鏄劇ず紿楀彛鐨勫満鎵錛汻un鏄彁鍙栧茍鍒嗘淳娑堟伅鐨勫満鎵銆傝繖鏍鳳紝MFC灝卞悓WIN32
SDK紼嬪簭瀵瑰簲璧鋒潵浜嗐侰WinThread::Run鏄▼搴忕敓鍛界殑"媧繪按婧愬ご"錛堜警鎹鳳細銆婃繁鍏ユ祬鍑篗FC銆嬶紝鍑芥暟瀛樺湪浜嶸C++
6.0瀹夎鐩綍涓嬫彁渚涚殑THRDCORE.CPP鏂囦歡涓級錛?br /> // main running routine until thread exits int CWinThread::Run() { 銆ASSERT_VALID(this);
銆// for tracking the idle time state 銆BOOL bIdle = TRUE; 銆LONG lIdleCount = 0;
銆// acquire and dispatch messages until a WM_QUIT message is received. 銆for (;;) 銆{ 銆銆// phase1: check to see if we can do idle work 銆銆while (bIdle && !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) 銆銆{ 銆銆銆// call OnIdle while in bIdle state 銆銆銆if (!OnIdle(lIdleCount++)) 銆銆銆銆bIdle = FALSE; // assume "no idle" state 銆銆}
銆銆// phase2: pump messages while available 銆銆do 銆銆{ 銆銆銆// pump message, but quit on WM_QUIT 銆銆銆if (!PumpMessage()) 銆銆銆銆return ExitInstance();
銆銆銆// reset "no idle" state after pumping "normal" message 銆銆銆if (IsIdleMessage(&m_msgCur)) 銆銆銆{ 銆銆銆銆bIdle = TRUE; 銆銆銆銆lIdleCount = 0; 銆銆銆}
銆銆} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); 銆} 銆ASSERT(FALSE); // not reachable } |
銆銆鍏朵腑鐨凱umpMessage鍑芥暟鍙堝搴斾簬錛?br /> ///////////////////////////////////////////////////////////////////////////// // CWinThread implementation helpers
BOOL CWinThread::PumpMessage() { 銆ASSERT_VALID(this);
銆if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) 銆{ 銆銆return FALSE; 銆}
銆// process this message 銆if(m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur)) 銆{ 銆銆::TranslateMessage(&m_msgCur); 銆銆::DispatchMessage(&m_msgCur); 銆} 銆return TRUE; } |
銆銆鍥犳錛屽拷鐣DLE鐘舵侊紝鏁翠釜RUN鐨勬墽琛屾彁鍙栦富騫插氨鏄細 do { 銆::GetMessage(&msg,...); 銆PreTranslateMessage{&msg); 銆::TranslateMessage(&msg); 銆::DispatchMessage(&msg); 銆... } while (::PeekMessage(...)); |
銆銆鐢辨錛屾垜浠緩绔嬩簡MFC娑堟伅鑾峰彇鍜屾淳鐢熸満鍒朵笌WIN32 SDK紼嬪簭涔嬮棿鐨勫搴斿叧緋匯備笅闈㈢戶緇垎鏋怣FC娑堟伅鐨?緇曡"榪囩▼銆?br /> 銆
銆鍦∕FC涓紝鍙鏄疌Wnd 琛嶇敓綾誨埆錛屽氨鍙互鎷︿笅浠諱綍Windows娑堟伅銆備笌紿楀彛鏃犲叧鐨凪FC綾誨埆錛堜緥濡侰Document
鍜孋WinApp錛夊鏋滀篃鎯沖鐞嗘秷鎭紝蹇呴』琛嶇敓鑷狢CmdTarget錛屽茍涓斿彧鍙兘鏀跺埌WM_COMMAND娑堟伅銆傛墍鏈夎兘榪涜MESSAGE_MAP鐨勭被
閮界戶鎵胯嚜CCmdTarget錛屽錛?br /> 銆銆MFC涓璏ESSAGE_MAP鐨勫畾涔変緷璧栦簬浠ヤ笅涓変釜瀹忥細 DECLARE_MESSAGE_MAP()
BEGIN_MESSAGE_MAP( 銆theClass, //Specifies the name of the class whose message map this is 銆baseClass //Specifies the name of the base class of theClass )
END_MESSAGE_MAP() |
銆銆鎴戜滑紼嬪簭涓秹鍙婂埌鐨勬湁錛歁FCThread.h銆丮ainFrm.h銆丆hildView.h鏂囦歡 DECLARE_MESSAGE_MAP() MFCThread.cpp鏂囦歡 BEGIN_MESSAGE_MAP(CMFCThreadApp, CWinApp) //{{AFX_MSG_MAP(CMFCThreadApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG_MAP END_MESSAGE_MAP() MainFrm.cpp鏂囦歡 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code ! ON_WM_SETFOCUS() //}}AFX_MSG_MAP END_MESSAGE_MAP() ChildView.cpp鏂囦歡 BEGIN_MESSAGE_MAP(CChildView,CWnd ) //{{AFX_MSG_MAP(CChildView) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() |
銆銆鐢辮繖浜涘畯錛孧FC寤虹珛浜嗕竴涓秷鎭槧灝勮〃錛堟秷鎭祦鍔ㄧ綉錛夛紝鎸夌収娑堟伅嫻佸姩緗戝尮閰嶅搴旂殑娑堟伅澶勭悊鍑芥暟錛屽畬鎴愭暣涓秷鎭殑"緇曡"銆?br /> 銆銆鐪嬪埌榪欓噷鐩鎬俊浣犳湁榪欐牱鐨勭枒闂細紼嬪簭瀹氫箟浜咰WinApp綾葷殑theApp鍏ㄥ眬鍙橀噺錛屽彲鏄粠鏉ユ病鏈夎皟鐢ˋfxBeginThread鎴杢heApp.CreateThread鍚姩綰跨▼鍛錛宼heApp瀵瑰簲鐨勭嚎紼嬫槸鎬庝箞鍚姩鐨勶紵 銆銆絳旓細MFC鍦ㄨ繖閲岀敤浜嗗緢楂樻槑鐨勪竴鎷涖傚疄闄呬笂錛岀▼搴忓紑濮嬭繍琛岋紝絎竴涓嚎紼嬫槸鐢辨搷浣滅郴緇燂紙OS錛夊惎鍔ㄧ殑錛屽湪CWinApp鐨勬瀯閫犲嚱鏁伴噷錛孧FC灝唗heApp"瀵瑰簲"鍚戜簡榪欎釜綰跨▼錛屽叿浣撶殑瀹炵幇鏄繖鏍風殑錛?br /> CWinApp::CWinApp(LPCTSTR lpszAppName) { 銆if (lpszAppName != NULL) 銆銆m_pszAppName = _tcsdup(lpszAppName); 銆else 銆銆m_pszAppName = NULL;
銆// initialize CWinThread state 銆AFX_MODULE_STATE *pModuleState = _AFX_CMDTARGET_GETSTATE(); 銆AFX_MODULE_THREAD_STATE *pThreadState = pModuleState->m_thread; 銆ASSERT(AfxGetThread() == NULL); 銆pThreadState->m_pCurrentWinThread = this; 銆ASSERT(AfxGetThread() == this); 銆m_hThread = ::GetCurrentThread(); 銆m_nThreadID = ::GetCurrentThreadId();
銆// initialize CWinApp state 銆ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please 銆pModuleState->m_pCurrentWinApp = this; 銆ASSERT(AfxGetApp() == this);
銆// in non-running state until WinMain 銆m_hInstance = NULL; 銆m_pszHelpFilePath = NULL; 銆m_pszProfileName = NULL; 銆m_pszRegistryKey = NULL; 銆m_pszExeName = NULL; 銆m_pRecentFileList = NULL; 銆m_pDocManager = NULL; 銆m_atomApp = m_atomSystemTopic = NULL; //寰蔣鎳掗錛熸垨鑰呬粬璁や負 銆//榪欐牱榪炵瓑鍚箟鏇存槑紜紵 銆m_lpCmdLine = NULL; 銆m_pCmdInfo = NULL;
銆// initialize wait cursor state 銆m_nWaitCursorCount = 0; 銆m_hcurWaitCursorRestore = NULL;
銆// initialize current printer state 銆m_hDevMode = NULL; 銆m_hDevNames = NULL; 銆m_nNumPreviewPages = 0; // not specified (defaults to 1)
銆// initialize DAO state 銆m_lpfnDaoTerm = NULL; // will be set if AfxDaoInit called
銆// other initialization 銆m_bHelpMode = FALSE; 銆m_nSafetyPoolSize = 512; // default size } |
銆銆寰堟樉鐒訛紝theApp鎴愬憳鍙橀噺閮借璧嬩簣OS鍚姩鐨勮繖涓綋鍓嶇嚎紼嬬浉鍏崇殑鍊鹼紝濡備唬鐮侊細 m_hThread = ::GetCurrentThread();//theApp鐨勭嚎紼嬪彞鏌勭瓑浜庡綋鍓嶇嚎紼嬪彞鏌? m_nThreadID = ::GetCurrentThreadId();//theApp鐨勭嚎紼婭D絳変簬褰撳墠綰跨▼ID |
銆
銆鎵浠WinApp綾誨嚑涔庡彧鏄負MFC紼嬪簭鐨勭涓涓嚎紼嬮噺韜畾鍒剁殑錛屽畠涓嶉渶瑕佷篃涓嶈兘琚獳fxBeginThread鎴?
theApp.CreateThread"鍐嶆"鍚姩銆傝繖灝辨槸CWinApp綾誨拰theApp鍏ㄥ眬鍙橀噺鐨勫唴娑碉紒濡傛灉浣犺鍐嶅鍔犱竴涓猆I綰跨▼錛屼笉瑕佺戶鎵跨被
CWinApp錛岃屽簲緇ф壙綾籆WinThread銆傝屽弬鑰冪1鑺傦紝鐢變簬鎴戜滑涓鑸互涓葷嚎紼嬶紙鍦∕FC紼嬪簭閲屽疄闄呬笂灝辨槸OS鍚姩鐨勭涓涓嚎紼嬶級澶勭悊鎵鏈夌獥鍙g殑
娑堟伅錛屾墍浠ユ垜浠嚑涔庢病鏈夊啀鍚姩UI綰跨▼鐨勯渶姹傦紒
|