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

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

?? atlapp.h文件剖析.txt

?? WTL源碼剖析 --- ATLAPP.H
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
WTL源碼剖析 --- ATLAPP.H  

作者:姜江
QQ:457283
E-mail:jznsmail@163.net

ATLAPP.H包含了消息循環類、接口類、和產生應用程序所必需的一些基礎類定義。
       類定義如下:
              CmessageFilter類---用于消息過濾的
        CidleHandler 類---用于空閑消息處理的
        CmessageLoop類---用于消息循環的
              CappModule 類---應用程序基礎類
              CserverAppModule類---用于Com服務構架的應用程序類
       另外還有3個全局函數:
              AtlGetDefaultGuiFont()獲得默認的顯示字體
              AtlCreateBoldFont()   產生一個粗體字體
              AtlInitCommonControls()初始化一些控件所需共同的DLL
      WTL程序的結構
       一個窗口程序的創建到銷毀過程主要經過如下幾個階段
1. 注冊窗口類
2. 創建窗口
3. 進入消息循環
如果用C寫過Win32窗口程序的人一定會記得如下的結構:
//窗口過程處理函數
LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
          HWND hwnd = NULL;
          MSG msg;
          WNDCLASS wndclass;
          wndclass.style       = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc = WndProc;
     //注冊窗口
     if(!RegisterClass(&wndclass))
     {
          MessageBox(NULL,TEXT("Porgram requires Windows NT!"),szAppName,MB_ICONERROR);
          return 0;
          }
     //創建窗口
     hwnd = CreateWindow(szAppName,TEXT("My Application"),
     WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
     CW_USEDEFAULT,CW_USEDEFAULT,
     CW_USEDEFAULT,CW_USEDEFAULT,
     NULL,NULL,hInstance,NULL);
 
          ShowWindow(hwnd,iCmdShow);
          UpdateWindow(hwnd);
         
         //進入消息循環
          while(GetMessage(&msg,NULL,0,0))
          {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
     }
 
     return msg.wParam;
}
那么你可能會問WTL的WinMain函數再哪里?如果你通過WTL/ATL導向生成一個應用程序,那么你會在跟工程名字同名的.cpp文件中發現如下的代碼:
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
     HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to 
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//     HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
          ATLASSERT(SUCCEEDED(hRes));
 
// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
          ::DefWindowProc(NULL, 0, 0, 0L);
 
        AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES); // add flags to support other controls
 
     hRes = _Module.Init(NULL, hInstance); //等下分析它的實現     ATLASSERT(SUCCEEDED(hRes));
 
     int nRet = Run(lpstrCmdLine, nCmdShow);//程序的關鍵分
 
     _Module.Term();
     ::CoUninitialize();
 
     return nRet;
}    
從這個_tWinMain函數的定義,你可以發現程序的關鍵部分是我紫色標記出來的Run()函數。這個函數是一個自定義的函數,不過如果通過ATL/WTL導向程序,那么會自動生成這樣一個Run()函數的,下面我們先分析一下這個自動生成的Run函數。
int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
     CMessageLoop theLoop;                  //定義消息循環
     _Module.AddMessageLoop(&theLoop);   //將消息添加到消息循環
 
     CMainFrame wndMain;                //應用程序框架類
 
     //生成框架
     if(wndMain.CreateEx() == NULL)
     {
          ATLTRACE(_T("Main window creation failed!\n"));
         return 0;
     }
 
     //顯示框架
     wndMain.ShowWindow(nCmdShow);
 
     //運行消息循環
     int nRet = theLoop.Run();
 
     //清除消息
     _Module.RemoveMessageLoop();
     return nRet;
}
通過這個Run函數我們可以看到在函數中完成了如下幾個過程:
1. 生成一個消息循環對象(theLoop)
2. 在全局的_Module中加入這個消息循環
3. 生成一個應用程序框架對象
4. 顯示應用程序框架
5. 開始消息循環
6. 結束消息循環
7. 返回WinMain函數,結束程序
實現分析
在這篇文章我不想過多的分析應用程序框架和窗口的細節,這些內容將放在以后的幾篇文章中詳細分析,本文主要對ATLAPP.H頭文件中實現的一些過程進行詳細分析。
首先從全局變量_Module開始。
_Module維持著生成應用程序的主線程,控制著程序的消息循環隊列,是一個CAppModule的對象。該CAppModule從ATL::CcomModule繼承。
在WTL::CappModule中定義了8個公有成員函數,分別為:
AddMessageLoop()添加一個消息循環,進入消息循環隊列里。
RemoveMessageLoop()移除消息循環隊列。
GetMessageLoop()獲得消息循環。
InitSettingChangeNotify()初始化環境
AddSettingChangeNotify()添加一個窗口句柄。
RemoveSettingChangeNotify()清理環境
除了8個公有成員函數外,該類還定義了3個公有成員變量
m_dwMainThreadID負責保存該應用程序的主線程ID
m_pMsgLoopMap負責存儲消息循環
m_pSettingChangeNotify負責存放窗口句柄
下面分別來分析幾個主要成員函數的實現:
BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
{
     CStaticDataInitCriticalSectionLock lock;
     //鎖住關鍵片斷,由于進程同步的關系!!!
     if(FAILED(lock.Lock()))
     {
          ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
          ATLASSERT(FALSE);
     return FALSE;
     }
         
     ATLASSERT(pMsgLoop != NULL);
     ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL);   // not in map yet
 
     BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop);
 
     lock.Unlock();
 
     return bRet;
}
     關鍵部分我用紅色的字體標記出來了,意思是什么?通過當前線程的Id來標示一個消息循環,存儲在m_pMsgLoopMap中。
 
BOOL RemoveMessageLoop()
     {
          CStaticDataInitCriticalSectionLock lock;
          if(FAILED(lock.Lock()))
         {
              ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
              ATLASSERT(FALSE);
              return FALSE;
         }
 
         BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId());
 
          lock.Unlock();
 
         return bRet;
     }
       關鍵部分同樣通過紅色字體標記出來,嗯,沒錯正如AddMessageLoop函數一樣,該函數也是通過線程Id來尋找消息循環移除對象的。
 
CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
     {
          CStaticDataInitCriticalSectionLock lock;
          if(FAILED(lock.Lock()))
         {
              ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
              ATLASSERT(FALSE);
              return NULL;
         }
 
          CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID);
 
          lock.Unlock();
 
         return pLoop;
     }
該函數通過線程Id在m_pMsgLoopMap消息隊列中尋找對應的消息循環,找到后返回。
 
     BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc)
     {
          CStaticDataInitCriticalSectionLock lock;
          if(FAILED(lock.Lock()))
         {
              ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
              ATLASSERT(FALSE);
              return FALSE;
         }
 
          if(m_pSettingChangeNotify == NULL)
         {
              typedef ATL::CSimpleArray<HWND>   _notifyClass;
              ATLTRY(m_pSettingChangeNotify = new _notifyClass);
              ATLASSERT(m_pSettingChangeNotify != NULL);
         }
 
         BOOL bRet = (m_pSettingChangeNotify != NULL);
          if(bRet && m_pSettingChangeNotify->GetSize() == 0)
         {
              // init everything
              _ATL_EMPTY_DLGTEMPLATE templ;
              //增加一個無模式對話框
              HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc);
              ATLASSERT(::IsWindow(hNtfWnd));

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩欧美一级二级三级| 婷婷久久综合九色综合绿巨人| 欧美在线视频全部完| av欧美精品.com| 成人动漫中文字幕| 成人av动漫在线| 色综合中文字幕国产 | 亚洲国产日韩一区二区| 国产精品乱子久久久久| 欧美国产日韩亚洲一区| 综合久久一区二区三区| 亚洲丝袜另类动漫二区| 亚洲一区二区三区小说| 亚洲国产精品精华液网站| 亚洲成人av在线电影| 日本欧美加勒比视频| 精久久久久久久久久久| 国产999精品久久久久久| 99国产精品久久久久久久久久| 在线视频亚洲一区| 91精品国产综合久久精品性色 | 国产一区啦啦啦在线观看| 国产精品一区免费在线观看| 高清不卡一二三区| 在线观看一区不卡| 亚洲精品一区二区在线观看| 亚洲免费在线视频一区 二区| 午夜亚洲国产au精品一区二区| 激情都市一区二区| 91色.com| xnxx国产精品| 一区二区三区欧美在线观看| 精品一区二区三区视频| 91丨九色丨尤物| 欧美精品一区二区三区很污很色的 | 国产成人av电影在线观看| 91久久精品一区二区二区| 6080国产精品一区二区| 亚洲国产岛国毛片在线| 无码av免费一区二区三区试看 | 色妹子一区二区| 日韩欧美一区在线观看| 亚洲视频免费在线| 精品一区二区三区免费| 欧美少妇一区二区| 亚洲欧洲精品成人久久奇米网| 日本91福利区| 欧美伊人久久久久久久久影院 | 高清不卡在线观看av| 精品视频在线免费看| 国产欧美日产一区| 奇米精品一区二区三区四区| 一本色道久久综合亚洲91| 国产视频一区在线播放| 久久er99热精品一区二区| 欧美自拍丝袜亚洲| 中文字幕一区日韩精品欧美| 激情欧美一区二区三区在线观看| 欧美日韩国产首页| 一区二区三区欧美在线观看| caoporen国产精品视频| 国产日产欧美一区二区三区 | 成人av在线一区二区三区| www一区二区| 国产麻豆精品95视频| 精品福利视频一区二区三区| 日日夜夜免费精品| 91精品欧美综合在线观看最新| 一区二区三区国产精品| 色综合久久66| 亚洲一区在线观看免费| 91视频免费看| 亚洲免费观看视频| 91激情五月电影| 亚洲欧美色一区| 91国偷自产一区二区使用方法| 亚洲欧美激情小说另类| 色88888久久久久久影院按摩| 亚洲天堂a在线| 色综合久久久久综合99| 一区二区三区中文字幕电影| 欧美日韩精品一区二区三区四区| 亚洲主播在线观看| 欧美一区二区三区视频免费播放| 蜜桃视频在线一区| 久久久99免费| av一二三不卡影片| 亚洲国产视频在线| 91精品国产91综合久久蜜臀| 另类的小说在线视频另类成人小视频在线| 欧美精品粉嫩高潮一区二区| 久久精品国产99| 国产欧美1区2区3区| 色综合天天综合| 五月婷婷久久丁香| 久久综合久久综合久久| 成人午夜视频福利| 亚洲丰满少妇videoshd| 久久综合久久99| 在线免费精品视频| 久久97超碰色| ●精品国产综合乱码久久久久| 欧美午夜电影在线播放| 精品亚洲porn| 亚洲精品国产一区二区精华液| 91精品国产91久久综合桃花 | 裸体一区二区三区| 国产精品私人自拍| 欧美日韩免费一区二区三区 | 制服丝袜av成人在线看| 粗大黑人巨茎大战欧美成人| 亚洲综合男人的天堂| 欧美精品一区二区蜜臀亚洲| 91小宝寻花一区二区三区| 青青青伊人色综合久久| 综合久久久久久久| 欧美xingq一区二区| 91美女蜜桃在线| 久久99久久久久久久久久久| 亚洲日本乱码在线观看| 久久久无码精品亚洲日韩按摩| 91国内精品野花午夜精品| 国产一区二区三区在线观看免费视频 | 欧美一级精品在线| 99久久综合精品| 国产毛片精品视频| 美女视频一区二区三区| 亚洲午夜久久久久| 国产精品国产自产拍高清av| 久久午夜老司机| 欧美久久婷婷综合色| 99r精品视频| 国产传媒日韩欧美成人| 久久电影网站中文字幕| 日韩精品成人一区二区三区 | 日韩中文字幕一区二区三区| 亚洲图片激情小说| 国产精品久久久久永久免费观看| 久久蜜桃香蕉精品一区二区三区| 欧美日韩国产bt| 欧美日韩一区二区在线视频| 91天堂素人约啪| k8久久久一区二区三区| 丁香亚洲综合激情啪啪综合| 精品系列免费在线观看| 精品一区二区三区香蕉蜜桃| 九九视频精品免费| 狠狠久久亚洲欧美| 韩国v欧美v亚洲v日本v| 精品亚洲porn| 国产一区二区三区四区五区美女| 美女在线观看视频一区二区| 日韩精品亚洲一区| 久久66热偷产精品| 九九精品视频在线看| 国内精品国产成人| 国产高清成人在线| 国产成人av影院| 成人av动漫网站| 色噜噜狠狠色综合欧洲selulu| 91热门视频在线观看| 欧美这里有精品| 欧美日韩一区三区四区| 日韩午夜av电影| 久久亚洲一级片| 中文字幕日韩一区二区| 亚洲激情自拍偷拍| 丝袜美腿高跟呻吟高潮一区| 日韩av一二三| 国产精品1区二区.| 91免费版pro下载短视频| 欧美日韩在线精品一区二区三区激情 | 日韩综合小视频| 国内精品视频一区二区三区八戒| 国产综合久久久久久鬼色| 99久久久久久| 欧美精品一卡二卡| 国产日产欧美精品一区二区三区| 国产精品进线69影院| 亚洲 欧美综合在线网络| 久久成人羞羞网站| 91在线观看免费视频| 欧美一区二区三区人| 国产欧美日韩麻豆91| 亚洲国产精品一区二区久久恐怖片| 人人狠狠综合久久亚洲| av激情亚洲男人天堂| 欧美美女激情18p| 国产午夜精品在线观看| 天天综合网 天天综合色| 国产成a人亚洲| 欧美精品 日韩| 综合久久久久久久| 激情综合色综合久久| 欧美日韩中文字幕一区二区| 久久亚洲免费视频| 日韩精品一卡二卡三卡四卡无卡| caoporn国产一区二区| 精品国一区二区三区| 亚洲一区二区在线免费观看视频|