AfxGetMainWnd 返回值

 AfxGetMainWnd,這個函數我們在MFC中經常用到,在VC6中是沒有問題的,但在2005中會出現返回值爲空,出現這個原因是AfxGetThread在VC6和2005代碼不一樣,VC6中有空值保護,先取得前臺進程,爲空在取後臺進程,但2005只取前臺進程。下面轉載的別人文章,可以看看

 

http://hi.baidu.com/rootlife/blog/item/45335cd0060e738da0ec9c41.html

 顧名思義,前臺指看得見,既然看得見自然要有窗口,而後臺是看不見,看不見可以理解爲沒有窗口,既然沒有窗口,那麼用AfxGetMainWnd()取得其窗口句柄,未免有些搞笑,爲什麼呢?聰明的你想必早已明白,如果你曾經跟蹤過AfxGetMainWnd()的調用,會發現它取得的是AFX_MODULE_THREAD_STATE線程模塊中保存的活動線程的窗口句柄,而後臺線程既然沒有窗口,那你又從何而言取得窗口句柄呢,(也許有人對後臺的理解是不顯示窗口,就算有窗口,只要不顯示就是後臺線程,嚴格的說不是這樣,窗口主要用來與用戶交互,有窗口就難免阻塞,而後臺線程往往用來進行一些後面的運算或處理,是通過前臺傳遞的信息或數據進行相應運做的,如果窗口隱藏談何信息傳遞呢?況又不能像其它線程那樣進行後臺運做.不過你如此理解也無防 ,關鍵是明白有什麼區別,及怎麼用.)
AfxGetApp()->GetMainWnd()取得的是主窗口句柄,無論在那個線程裏調用都是沒有問題的,因爲它先取得主線程句柄,再取得主線程的活動窗口(如視圖切換可能導致的替代,這種情況我也不大清楚),如果沒有活動窗口則取主窗口,任何程序總要有一個主窗口,所以它的調用不會出現問題,如果想取得程序的主窗口建議用AfxGetApp()->GetMainWnd().

  要注意的是控制檯程序沒有窗口,其窗口句柄始終爲0.其次後臺線程其實就是一個控制檯式的程序,只不過不是主線程罷了.還有就是用API Createthread之類的函數創建的線程無法生成CWinThread對象.所以如果想使用CWinThread對象裏的函數,以及一些全局函數進行操作,如上面的AfxGetMainWnd(),就必須用CWinThread對象的CreateThread函數,或用AfxBeginThread()函數創建線程,否則很可能出現錯誤,因爲MFC對線程的管理是通過CWinThread對象來完成的,通過下面的跟蹤代碼你不難看出.  記得當初有一位前輩曾提到過這個問題,只是不知它是否理解這其中的原因.(我在這裏估且稱它一聲前輩,算是尊敬他,但那些不把初學者當回事,自己又未必真有那麼些真才實學的人,我即便稱一聲前輩也不過是客氣而已,不高興了照樣罵這些混帳王巴蛋)

以下是跟蹤代碼:

_AFXWIN_INLINE CWnd* AFXAPI AfxGetMainWnd()
{ CWinThread* pThread = AfxGetThread();
        return pThread != NULL ? pThread->GetMainWnd() : NULL; }


CWinThread* AFXAPI AfxGetThread()
{
// check for current thread in module thread state
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
CWinThread* pThread = pState->m_pCurrentWinThread;

// if no CWinThread for the module, then use the global app
if (pThread == NULL)
        pThread = AfxGetApp();

return pThread;
}

可以看出當取得的線程句柄爲空時,則返回主線程句柄,所以在主線程裏調用AfxGetMainWnd()是一定沒問題的,(控制檯程序除外)

_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
{ return afxCurrentWinApp; }


CWnd* CWinThread::GetMainWnd()
{
if (m_pActiveWnd != NULL)
        return m_pActiveWnd;          // probably in-place active

// when not inplace active, just return main window
if (m_pMainWnd != NULL)
        return m_pMainWnd;

return CWnd::GetActiveWindow();
}

那個afxCurrentWinApp就不用說了吧.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章