<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    略談如何從工作線程中彈出對話框

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    工作線程,在一些技術文章被稱為輔助線程,是相對于主線程而言的。在工作線程中使用界面需要一些技巧。我就曾在工程線程中彈出對話框中遇到過莫名奇妙的錯誤。下面就我的經驗談談如何從工作線程中彈出對話框(暫時只講方法,原理還沒徹底弄清楚)。

     

    實際上在工作線程中直接彈出模式對話框中在debug模式下有時出錯(這里的有時的意思是必然會出錯,但是不是每次都出錯),彈出模式對話框的代碼如下:

     

    1. DWORD WINAPI RecvThread(LPVOID lpParam)    // 工作線程函數
    2. {
    3.      CAIDlgProductName dlg;
    4.      if(dlg.DoModal() == IDOK)
    5. {
    6.      ……
    7. }
    8. }

     

     

          

    錯誤截圖:

     

    RFID設備管理軟件 

     

     

    如果跟蹤DoModal函數,我們進入MFC源碼找到出錯的地方:

     

     

    1. #ifdef _DEBUG
    2. void CWnd::AssertValid() const
    3. {
    4.     if (m_hWnd == NULL)
    5.         return;     // null (unattached) windows are valid
    6.     // check for special wnd??? values
    7.     ASSERT(HWND_TOP == NULL);       // same as desktop
    8.     if (m_hWnd == HWND_BOTTOM)
    9.         ASSERT(this == &CWnd::wndBottom);
    10.     else if (m_hWnd == HWND_TOPMOST)
    11.         ASSERT(this == &CWnd::wndTopMost);
    12.     else if (m_hWnd == HWND_NOTOPMOST)
    13.         ASSERT(this == &CWnd::wndNoTopMost);
    14.     else
    15.     {
    16.         // should be a normal window
    17.         ASSERT(::IsWindow(m_hWnd));
    18.         // should also be in the permanent or temporary handle map
    19.         CHandleMap* pMap = afxMapHWND();
    20.         ASSERT(pMap != NULL);
    21.         CObject* p;
    22.         // 在下面一句出錯
    23.         ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
    24.             (p = pMap->LookupTemporary(m_hWnd)) != NULL);
    25.         ASSERT((CWnd*)p == this);   // must be us
    26.         // Note: if either of the above asserts fire and you are
    27.         // writing a multithreaded application, it is likely that
    28.         // you have passed a C++ object from one thread to another
    29.         // and have used that object in a way that was not intended.
    30.         // (only simple inline wrapper functions should be used)
    31.         //
    32.         // In general, CWnd objects should be passed by HWND from
    33.         // one thread to another.  The receiving thread can wrap
    34.         // the HWND with a CWnd object by using CWnd::FromHandle.
    35.         //
    36.         // It is dangerous to pass C++ objects from one thread to
    37.         // another, unless the objects are designed to be used in
    38.         // such a manner.
    39.     }
    40. }

         

    實際上當時給我啟發的是上面那段Note。我用我淺薄的英文功底翻譯一下大意就是:就是上面的asserts發生了同時你正在寫的是一個多線程程序,那么asserts發生的原因很可能是你將一個C++對象從一個線程傳遞給另一個線程同時你無意中使用了那個C++對象(only simple inline wrapper functions should be used(抱歉,這一句不會翻譯)),實際上線程之間傳遞CWnd對象應該傳遞句柄(HWND)。接收線程應該通過CWnd::FromHandle函數通過傳遞過來的句柄獲取CWnd對象(這里準確的來說應該是CWnd對象的指針)。

     

    線程之間傳遞C++對象是危險的,除非那個對象被設計為以那種方式使用。

     

    由上面我想到一種在工作線程中彈出的對話框的辦法:

    1.       轉遞視圖類句柄給線程函數:

     

    1. HWND HView;
    2. …… // 獲取視圖類句柄

    3. CreateThread(NULL,0,RecvThread, HView
    4.                 ,0,&dwThreadId);

     

     

       

    2.       在線程函數中通過句柄獲取視圖類指針,獲取數據給視圖類發送自定義消息:

     

        

    1. DWORD WINAPI RecvThread(LPVOID lpParam)
    2. {
    3.    HWND HView = (HWND)lpParam;
    4.   CWnd* pMyView = CWnd::FromHandle(HView);
    5.   ……
    6.   pMyView ->SendMessage(WM_TASKDLG_MESSAGE,(WPARAM)(&str));
    7.    …….
    8. }

     

     

        

    3.   在視圖類自定義一個消息函數OnTaskDlgMessage專門處理WM_TASKDLG_MESSAGE消息用于創建對話框:

     

    1. LRESULT CInteAView::OnTaskDlgMessage(WPARAM wParam, LPARAM lParam)
    2. {
    3.      CAIDlgProductName dlg;
    4.      if(dlg.DoModal() == IDOK)
    5.      {
    6.             ……
    7.      }
    8.      return 0;
    9. }

     

     

         

    當然上面將視圖類換為框架類也是可以的。上面就我的經驗談了一種從工作線程中彈出對話框的辦法,不當之處還請大家指點。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全