2011-08-25 37 views
1

從工作線程訪問MFC控件的最佳方式是什麼?如何從工作線程訪問MFC控件?

什麼是訪問控件的MFC習慣用法?

我讀到這裏http://www.flounder.com/workerthreads.htm下面的辦法,但我不很喜歡的CStringnew,我怎麼可以肯定的CString會妥善deleted

typedef struct tagTP 
{ 
    HWND hwnd; 
    int n; 
} TP; 

BEGIN_MESSAGE_MAP(CMyDlg, CDialog) 
    // ... 
    ON_MESSAGE(UWM_UPDATE_RESULTS, OnUpdateResults) 
END_MESSAGE_MAP() 

void CMyDlg::OnBnClickedDoWork() 
{ 
    TP* tp = new TP; 
    tp->hwnd = m_hWnd; 
    tp->n = 42; 

    AfxBeginThread(doWork, tp); 
} 

UINT CMyDlg::doWork(LPVOID p) 
{ 
    TP* tp = reinterpret_cast< TP* >(p); 
    CWnd* dlg = FromHandle(tp->hwnd); 

    if (tp->n == 42) { 
     CString* s = new CString("Is the Answer to the Ultimate Question of Life, the Universe, and Everything"); 
     dlg->PostMessage(UWM_UPDATE_STATUS, 0, reinterpret_cast<LPARAM>(s)); 
    } 

    return 0; 
} 

LRESULT CMyDlg::OnUpdateResults(WPARAM,LPARAM lParam) 
{ 
    CString* s = reinterpret_cast<CString *>(lParam); 
    m_result.AddString(*s);// m_result is a CListBox 
    delete s; 
    UpdateData(FALSE); 
    return 0; 
} 
+1

您應該將CString指針存儲在OnUpdateResults()中的智能指針中,以確保在處理過程中出現異常時它會被銷燬。 – tinman

回答

0

使用PostMessage(..)是正確的。考慮使用SendMessage(..) - 哪個阻塞直到完成。 傳遞指向新對象的指針很常見 - 檢查PostMessage(..)的返回值以檢查它是否已發佈。

我該如何確定CString將被正確刪除?

如前所述,檢查PostMessage(..)的返回值並在退出消息循環時處理整個消息隊列。

0

作爲一般規則,MFC控件只能從創建它們的線程訪問。這就是爲什麼您找到的樣本需要通過傳遞消息的額外步驟。該消息由創建該控件的線程接收並處理。

CString在OnUpdateResults()中正確刪除。

0

除了@ Simon的回答,如果你有更復雜的情況,很難找出誰應該刪除CString(或任何類型),請考慮std :: tr1 :: shared_ptr。它會照顧刪除。

+1

您可以在發佈(然後釋放指針)之前以及在消息處理程序中接收它之後(使用智能指針進行分配)完成此操作。這只是關於異常安全。您不能直接發佈智能指針。 – Simon

+0

在這種情況下'shared_ptr'會做什麼?它是一個C++對象,不能以'sizeof(void *)'字節傳遞。它必須分配然後釋放。根本沒有幫助。 – Ajay

+0

@dgnorton謝謝,我不熟悉shared_ptr,我該如何使用它? –