程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> (轉)AFX_MANAGE_STATE(AfxGetStaticModuleState()) 深入淺出

(轉)AFX_MANAGE_STATE(AfxGetStaticModuleState()) 深入淺出

編輯:.NET實例教程
最近寫一個程序,是在DLL裡面create一個FrameWnd,搞了一個星期,弄的焦頭爛額,最後才發現少加一條語句
AFX_MANAGE_STATE(AfxGetStaticModuleState()),現在把從網上轉的技術文檔記錄下來,備忘。
(轉)AFX_MANAGE_STATE(AfxGetStaticModuleState())

以前寫MFC的DLL的時候,總會在自動生成的代碼框架裡看到提示,需要在每一個輸出的函數開始添加上AFX_MANAGE_STATE (AfxGetStaticModuleState())。一直不明白這樣做的含義,也一直沒有這樣做,而且代碼也工作得好好的,所以感覺這好像一句廢 話。

最近的項目中,需要在DLL裡使用MFC生成界面,這才發現一旦資源放在不同的動態庫裡,而且還和多線程攪和在一起的時候,事情就變 得異常的復雜,以前對MFC的一知半解已經不足與應付了。程序莫名的崩潰,莫名的ASSERT,資源怎樣也裝載不起來,為什麼呢?每次,總是嘗試著,在每 一個線程的開始,把AFX_MANAGE_STATE(AfxGetStaticModuleState())添加上去,或者在某些地方用 AfxSetResourceHandler()一把,然後問題就解決了,但是不是很明白到底是怎麼回事,總感覺這種解決辦法讓人很不安心,仿佛在下一秒 問題又會突然冒出來。

前天,這個問題終於發揮到了極致,任我花費了好幾個小時,怎樣的嘗試都不能成功,在項目的關鍵時候發生這種事情,讓我暗暗發誓以後再也不用MFC了。正像很多的電影情節一樣,事情最後還是得到了解決,這次我決定不能再這麼算了,一定要把這個事情理解得明明白白。

在這裡,我遇到的問題就是,如何讓DLL裡的界面代碼使用該DLL的資源(Resource),如何在工作線程裡加載有IE控件的對話框?

我問同事,他們是如何實現DLL資源切換的?AFX_MANAGE_STATE(AfxGetStaticModuleState())這就是他們的答案,一如微軟的推薦,原來就是這麼簡單啊!讓我們來看看,這句代碼到底做了什麼?

#define AFX_MANAGE_STATE(p) AFX_MAINTAIN_STATE2 _ctlState(p);

AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2(AFX_MODULE_STATE* pNewState)
{
   m_pThreadState = _afxThreadState;
   m_pPrevModuleState = m_pThreadState->m_pModuleState;
   m_pThreadState->m_pModuleState = pNewState;
}

_AFXWIN_INLINE AFX_MAINTAIN_STATE2::~AFX_MAINTAIN_STATE2()
{ m_pThreadState->m_pModuleState = m_pPrevModuleState; }

原來,就是定義一個局部的對象,利用其構造和析構函數在函數的入口和函數的出口進行State狀態的切換,我猜AfxGetStaticModuleState()一定是獲取當前代碼所在DLL的State。

果然,請看

static _AFX_DLL_MODULE_STATE afxModuleState;

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState()
{
   AFX_MODULE_STATE* pModuleState = &afxModuleState;
   return pModuleState;
}


class _AFX_DLL_MODULE_STATE : public AFX_MODULE_STATE


// AFX_MODULE_STATE (global data for a module)
class AFX_MODULE_STATE : public CNoTrackObject
{
...
   CWinApp* m_pCurrentWinApp;
   HINSTANCE m_hCurrentInstanceHandle;
   HINSTANCE m_hCurrentResourceHandle;
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved