2016-04-04 32 views
0

Visual Studio 2015 (Topluluk Sürümü) & MFC C++ projesini kullanarak gönderin. Bir işçi iş parçacığım var, bu ileti, bu iş parçacığından ana UI iş parçacığına (CDialog'umun bulunduğu yer) henüz aynı sınıfta veri göndermek için PostMessage() işlevini kullanmak istiyorum, bu iletiyi almak istiyorum . MyComm.h dosyasında mfc C++ Çalışan bir iş parçacığından ana kullanıcı arabirimine bir postmessage özel kullanıcı iletisini

, şu var: Benim MyComm.cpp dosyasında

#define WM_USERRESPONSE WM_APP + 2000 

class MyComm: public CDialog 
{ 
    ... 
    CWnd* m_pParent; 
    static BOOL m_bThreadKill; 
    static CWinThread* pThread; 
    static CEvent* pEvent; 
    static CEvent m_ThreadKillEvent; 
    ... 
    static UINT MyThreadProc(LPVOID pParam); 
    ... 
    afx_msg LRESULT OnResponse(WPARAM wParam, LPARAM lParam); 
    ... 
}; 

, şu var:

MyComm::MyComm(CWnd* pParent /*=NULL*/) 
    : CDialog(IDD_PPAGE_COMMAND, pParent) 
{ 
    m_pParent = pParent; 

    pEvent = new CEvent(FALSE, FALSE); 

    if ((pThread = AfxBeginThread(MyThreadProc, this)) == NULL) 
    AfxMessageBox("Could not Create Read Thread!"); 

    pThread->m_bAutoDelete = FALSE; 
    m_ThreadKillEvent.ResetEvent(); 
    m_ReadThreadDead.ResetEvent(); 
    running = 1; 
} 

UINT MyComm::MyThreadProc(LPVOID pParam) 
{ 
    MyComm *pMyHndl = ((MyComm*)pParam); 
    string s = "I would like this string posted"; 
    BOOL b = false; 

    b = ::PostMessage(pMyHndl->GetSafeHwnd(), WM_USBRDRESPONSE, 0, 
     (LPARAM)&s); 
} 

BEGIN_MESSAGE_MAP(MyComm, CDialog) 
    ON_MESSAGE(WM_USERRESPONSE, &MyComm::OnResponse) 
END_MESSAGE_MAP() 

afx_msg LRESULT MyComm::OnResponse(WPARAM wParam, LPARAM lParam) 
{ 
    MyStruct* p = (MyStruct*)lParam; 
    ... 
} 

Not kalmak için bu bazı kısaltılmış Konu üzerine.

Hata ayıklamada (bundan çok daha fazla kod var), iş parçacığının başladığını doğrularım, bu true değerini döndüren bu PostMessage() işlevini çalıştırıyorum. asla alıcı olması amaçlanan OnResponse() işlevine ulaşamıyorum. Emin değilim neden .. (??) ..

Bazı düşünceler. MyComm sınıfının aynı sınıfta olduğu doğrudur, ancak iletişim iş parçacığı için değil, bunun tarafından oluşturulur ve CDialog'dan türetilmiştir. Bu yeterli olmayabilir? Kabul ediyorum, hala MFC programlama paradigması ile konulara yeni bir yeni. Herhangi bir yardım takdir edilir.

Maddog

+0

teslimat soruna neden olmasa da, dize 's' hala var olacak? MyThreadProc() geri döndüğünde RAII'd olmaz mı? –

+0

Üzgünüm, gerçek kodda, iş parçacığı asla döndürmez (yani (1) ...) veya ölene kadar. –

+0

Benim durumumda, bu dize, iş parçacığı oluşturulduğunda oluşturulan bir arabellektir. –

cevap

0
  • değişken string s iplik bittikten sonra mevcut olmayacaktır. Gösterdiğiniz iş parçacığı işlevi çok küçük ve yakında çıkıyor.
  • Oluşturucuda, OnInitDialog'dan yeni bir iş parçacığı başlatmalısınız. İleti döngüsü oluşturucuda oluşturulmamış, ancak OnInitDialog'da.
  • İleti kodunun doğru olduğunu kontrol edin. Kodunuzun her ikisi de: WM_USBRDRESPONSE ve WM_USBRDRESPONSE
+0

Daha önce de söylediğim gibi kodumdaki iş parçacığı hiçbir zaman ölene kadar tamamlanmaz. SendMessage() öğesinin de almadığını buldum. İkincisi, devam etmeden önce mesajın yayınlanmasını beklemek zorundayım. Burada başka bir soruda bulduğum bir şey [link] (http://stackoverflow.com/questions/18271229/mfc-send-message-to-main-thread-rather-than-a-window) PostMessage'ımın() Mesajını bir pencereye gönder. Şu anki sınıfım, diyalog sınıfında ortaya çıkmaktansa penceresizdir. –

+0

Bu nedenle, MyComm sınıfının neden OnInitDialog() yöntemini yürütmediğini açıklar. Bu yüzden aslında burada gizli bir pencere oluşturmam gerekebilir. Sinyalin kendisinden özür dilerim. Kodumda mesaj WM_USBRDRESPONSE. WM_RESPONSE adını sadece basitleştirme için yeniden adlandırdım. Bütün kodu buraya koymak istemedim çünkü 100'den fazla sayfa var ve Entellektüel Mülkiyet sorunları var. –

+0

İletişim kutusu nasıl gösterilir? DoModal, ShowWindow? – Ajay

0

Bugün, bu sorunun cevabını buldum.

Bu, iş parçacığının başlatıldığı sınıfın, bir pencere ile henüz oluşturulmamış bir penceresine bağlı bir sınıf olmadığı içindir. Dolayısıyla, pMyHndl 'da ince bir nüans gerekli. POSTMESSAGE()'da, bunun yerine pMyHndl->m_pParent kullanın, bunun yerine Ana sınıfına m_pParent noktaları (pencere içeren bir tane) kullanın. Bu kod, mesajını alacak kodun buraya taşındığını bildiren bir mesaj aldı. Herkese yardım için teşekkürler.

maddog ileti teslim edildiğinde