2012-11-11 24 views
2

我使用了一個使用mdi的應用程序,並且腳本可以附加到一個mdi窗口並從中分離以便按需運行/停止;這個腳本加載了我的dll,它可以完成一些工作;它確實如此;然而,當我分離的腳本仍然一切正常,應用程序應該卸載dll(並調用dllmain與適當的thread_attach/detach和process_attach/detach操作)。現在,如果我嘗試將腳本重新附加到winow,或者將其附加到另一個窗口,那麼在dll被使用一次後 - 主應用程序崩潰。我已將問題解決到由dll創建的線程;胎面形成一扇窗戶;所以,我創建線程像這樣:DLL在重用後崩潰了應用程序

if (!hThread) hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); 

,當腳本脫離它關閉線程像這樣(不管是否被註釋掉的行是註釋掉-OUT):

SendMessage(hWnd, WM_DESTROY, 0, 0); 
//TerminateThread(hThread, 0); 
//WaitForSingleObject(hWndThread, INFINITE); 
CloseHandle(hThread); 
hThread = NULL; 

我不知道爲什麼主應用程序崩潰。一個不同的線程(即一個會簡單地睡一秒鐘和循環,不會造成任何傷害)什麼給予?

+0

http://blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx –

+0

@Hans Passant謝謝你看我的問題。 Unfortunatley發送WM_CLOSE或調用DestroyWindow不能解決問題。 – user1816499

+0

好吧,我們知道你做錯了,但我們仍然不知道崩潰的樣子。至少發佈崩潰原因和調用堆棧的內容。也可以在輸出窗口中查看任何第一次機會異常通知。 –

回答

0

好吧,這裏有一些想法: 你說你的線程打開一個窗口。你運行一個消息循環在線程函數中,或者你期望你的窗口被其他消息循環所服務? 如果你正在線程中運行你自己的消息循環,那麼退出循環可能會或可能不會發生,這取決於你如何寫它。如果您使用的是這樣的:

while(GetMessage(&msg, ...) // msg loop in the thread function 
{ 
    .... 
} 
DestroyWindow(hWnd); // see comment below 

那麼這需要一個WM_QUIT,而不是WM_DESTROY退出無論如何,最好是送你的窗口WM_QUIT和退出消息循環,那麼C之後。所有的DestroyWindow()都可以正確銷燬它。 從MSDN引用:

的DestroyWindow功能 銷燬指定窗口。該函數將WM_DESTROY和WM_NCDESTROY消息發送到窗口以停用它並從中移除鍵盤焦點。該功能還破壞了窗口的菜單,刷新線程消息隊列,銷燬定時器,刪除剪貼板的所有權,並打破了剪貼板查看器鏈(如果窗口是在瀏覽器鏈

頂部張貼WM_QUIT消息後。你的窗口,你的主線程應該等待窗口線程退出下面是一些相關的代碼:

SendMessage(hWnd, WM_QUIT, 0, 0); // send your quit message to exit the msg loop 
if (WaitForSingleObject(hThread, 5000) != WAIT_OBJECT_0) // wait up to 5 seconds 
{ 
    TerminateThread(hThread, -1); // bad! try to never end here 
} 

我希望這有助於我在使用一個窗口中顯示日誌信息螺紋日誌查看器使用。

+0

編輯:'摧毀你的窗戶'應該是:'將WM_QUIT消息發佈到你的窗口後。 – DNT

+0

謝謝你的建議。 我確實運行了一個消息循環。但是,通常我手動關閉窗口(通過關閉按鈕),因此窗口會通過postquitmessage接收wm_quit。不過,我用wm_close消息做了一個額外的sendmessage。 我想我已經嘗試了所有的組合,但仍然沒有運氣。 無論如何,它不再是一個緊迫的問題,因爲現在的代碼工作;它只是在調試/設計時才使用的,因爲每次我必須更改代碼時,我還必須重新啓動託管應用程序(它本身必須重新連接到遠程服務器)。 無論如何,再次感謝。 – user1816499