国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
父子窗口分屬不同消息循環(huán)在WinXP和WinCE的差異

//=====================================================================
//TITLE:
//    父子窗口分屬不同消息循環(huán)在WinXP和WinCE的差異
//AUTHOR:
//    norains
//DATE:
//    Monday 19- April-2010
//ENVIRONMENT:
//    WINDOWS CE 5.0
//    WINDOWS XP SP3
//=====================================================================

    老實(shí)說(shuō),這題目起的有點(diǎn)拗口,讀起來(lái)不太滑溜;但更有意思的是,本文所說(shuō)的情況比較特殊,并不一定大家都能碰上。不過(guò),如果碰上了,估計(jì)找起來(lái)還特別費(fèi)勁,特別是對(duì)于代碼是從WinCE遷移到WinXP上的朋友而言。

 

    在開始進(jìn)行本文的討論之前,先確定如下特殊條件:

     1. 主線程創(chuàng)建父窗口。
     2. 創(chuàng)建一個(gè)線程,并在該線程中創(chuàng)建子窗口,且該線程有子窗口的消息循環(huán)。
     3. 進(jìn)入到父窗口的消息循環(huán)。

 

    可能用文字描述有點(diǎn)抽象,我們來(lái)看看具體的代碼:

  1. #include <string>   
  2.   
  3. #ifdef UNICODE   
  4.  #ifndef TSTRING   
  5.   #define TSTRING std::wstring   
  6.  #endif   
  7. #else   
  8.  #ifndef TSTRING   
  9.   #define TSTRING std::string   
  10.  #endif   
  11. #endif //#ifdef UNICODE   
  12.   
  13. HWND g_hWndParent = NULL;  
  14. HANDLE hEventNotify = NULL;  
  15. LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)  
  16. {  
  17.  return DefWindowProc(hWnd,wMsg,wParam,lParam);  
  18. }  
  19. BOOL MyRegisterClass(const TSTRING &strClassName)  
  20. {  
  21.  WNDCLASS wc;  
  22.  wc.style         = 0;  
  23.     wc.lpfnWndProc   = WndProc;  
  24.     wc.cbClsExtra    = 0;  
  25.     wc.cbWndExtra    = 0;  
  26.     wc.hInstance     = GetModuleHandle(NULL);  
  27.     wc.hIcon         = NULL;   
  28.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);   
  29.     wc.lpszMenuName  = NULL;  
  30.  wc.lpszClassName = strClassName.c_str();   
  31.  wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  
  32.  return RegisterClass(&wc);  
  33. }  
  34. HWND MyCreateWindow(const TSTRING &strClassName,const TSTRING &strWndName,HWND hWndParent,DWORD dwStyle,DWORD dwExStyle)  
  35. {  
  36.  RECT rcArea = {0};  
  37.  SystemParametersInfo(SPI_GETWORKAREA, 0, &rcArea, 0);  
  38.     return CreateWindowEx(dwExStyle,  
  39.     strClassName.c_str(),  
  40.     strWndName.c_str(),  
  41.                 dwStyle,  
  42.                 rcArea.left,  
  43.                 rcArea.top,  
  44.                 rcArea.right - rcArea.left,  
  45.                 rcArea.bottom - rcArea.top,  
  46.                 hWndParent,   
  47.                 NULL,   
  48.                 GetModuleHandle(NULL),   
  49.                 0);  
  50.   
  51. }  
  52. DWORD WINAPI ThreadCreateWnd(LPVOID pArg)  
  53. {  
  54.  if(MyRegisterClass(TEXT("CHILD_CLASS")) == FALSE)  
  55.  {  
  56.   return 0x10;  
  57.  }  
  58.  if(MyCreateWindow(TEXT("CHILD_CLASS"),TEXT("CHILD_NAME"),g_hWndParent,WS_CHILD|WS_VISIBLE,0) == NULL)  
  59.  {  
  60.   return 0x20;  
  61.  }  
  62.   
  63.  OutputDebugString(TEXT("Finish Create child window/r/n"));  
  64.  SetEvent(hEventNotify);  
  65.  //The message loop    
  66.  MSG msg;  
  67.  while(GetMessage(&msg,NULL,0,0))  
  68.  {  
  69.   TranslateMessage(&msg);  
  70.   DispatchMessage(&msg);  
  71.  }  
  72.  return 0;  
  73. }  
  74.   
  75.   
  76. #ifdef _WIN32_WCE   
  77.  int WINAPI WinMain( HINSTANCE hInstance,  
  78.       HINSTANCE hPrevInstance,  
  79.       LPTSTR    lpCmdLine,  
  80.       int       nCmdShow)  
  81. #else   
  82.  int APIENTRY _tWinMain(HINSTANCE hInstance,  
  83.                      HINSTANCE hPrevInstance,  
  84.                      LPTSTR    lpCmdLine,  
  85.                      int       nCmdShow)  
  86. #endif //#ifdef _WIN32_WCE   
  87. {    
  88.    
  89.  if(MyRegisterClass(TEXT("PARENT_CLASS")) == FALSE)  
  90.  {  
  91.   return 0x10;  
  92.  }  
  93.  g_hWndParent = MyCreateWindow(TEXT("PARENT_CLASS"),TEXT("PARENT_NAME"),NULL,WS_POPUP|WS_VISIBLE,0);  
  94.  if(g_hWndParent == NULL)  
  95.  {  
  96.   return 0x20;  
  97.  }  
  98.    
  99.  HANDLE hEventNotify = CreateEvent(NULL,FALSE,FALSE,NULL);  
  100.    
  101.  CreateThread(NULL,NULL,ThreadCreateWnd,FALSE,FALSE,NULL);  
  102.  WaitForSingleObject(hEventNotify,INFINITE);  
  103.   
  104.  MSG msg;   
  105.  while(GetMessage(&msg,NULL,0,0))  
  106.  {  
  107.   TranslateMessage(&msg);  
  108.   DispatchMessage(&msg);  
  109.  }  
  110.   
  111.  return 0;  
  112. }  


    我承認(rèn),為了突出文章的主題,這代碼寫得有點(diǎn)崢嶸,實(shí)在不好理解。所以,就以流程圖說(shuō)一下流程:


 
    如果你是WinCE環(huán)境下,剛剛的那段代碼跑的非常順暢,一點(diǎn)問(wèn)題都沒有;但如果是在WinXP,那么一切都會(huì)改變,你會(huì)發(fā)現(xiàn),程序沒有響應(yīng),被卡死了。仔細(xì)追蹤,你會(huì)發(fā)現(xiàn)出問(wèn)題的是在流程圖中的"創(chuàng)建子窗口"這一項(xiàng),具體來(lái)說(shuō),是CreateWindowEx函數(shù)根本沒有返回!

 

    解決方式也非常簡(jiǎn)單,在調(diào)用CreateWindowEx函數(shù)的時(shí)候,傳入一個(gè)WinCE所不具備的WS_EX_NOPARENTNOTIFY即可。當(dāng)你傳入該數(shù)值時(shí),CreateWindowEx就會(huì)如你所愿,順順當(dāng)當(dāng)返回。

 

    由此我們或多或少可以知道WinXP和WinCE在消息處理上的小小差異:如果沒有WS_EX_NOPARENTNOTIFY,那么子窗口創(chuàng)建時(shí),需要等待父窗口的回應(yīng)。而在我們示例的代碼中,父窗口還沒有進(jìn)入消息循環(huán),無(wú)法正常響應(yīng)子窗口的動(dòng)作,于是便造成了死鎖。而WinCE則沒有這方面的問(wèn)題,子窗口根本就不必等待父窗口的回應(yīng),相應(yīng)的創(chuàng)建完畢后,直接返回。從這個(gè)意義上來(lái)說(shuō),我們一刀切地認(rèn)為(可能實(shí)際底層代碼并不一定如此),雖然WinCE不具備WS_EX_NOPARENTNOTIFY這個(gè)數(shù)值,但實(shí)際上卻默認(rèn)具備了該數(shù)值的屬性。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Bezier曲線原理及實(shí)現(xiàn)代碼(c++)
socket WSAAsyncSelect編程模型(非常好的例子)
Win32編程基礎(chǔ)知識(shí)_天空總是藍(lán)色的
用Win32 application建立窗體_入門
【新提醒】快速增長(zhǎng)你的逆向編程能力:學(xué)會(huì)反匯編的角度編寫程序!,Win32匯編語(yǔ)言案例解析,典型案例解析(VIP免費(fèi)),魚C論壇
Windows應(yīng)用程序基礎(chǔ)知識(shí) - 筆記 - 吳錦華 - CSDN學(xué)生大本營(yíng) - Powe...
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服