拡張DLLのダイアログへ、特定の状況でメッセージが届きません。

解決


 2010-04-01 16:54:41  No: 71521  IP: [192.*.*.*]

拡張DLLのダイアログへ、特定の状況でメッセージが届きません。

環境 winxp_sp3/vc6

お世話になっております。
リッチエディットコントロールを貼付けたダイアログを表示するDLLを作りました。
DLLをアプリケーション側から呼び出して、エディットへ文字を書込んでいます。
そのDLLを使用するプログラムは下記のような構成になっています。

#pragma comment(lib, "MyDlg.lib")
#include <MyDlgDef.h>
class CSocket2 : public CSocket
{
 *省略*
 CMyDlg m_dlg; // ← DLL
 CSocket2::CSocket2()
 {
  m_dlg.Create(::GetDesktopWindow(), "telnet monitor");
 }
 CSocket2::~CSocket2()
 {
  m_dlg.SendMessage(WM_CLOSE); // ←このメッセージが届かない

  // CMyDlg dlg; // 試しにここで作ってみると
  // dlg.Create(::GetDesktopWindow(), "telnet monitor");
  // dlg.SendMessage(WM_CLOSE); // ←これは届く。
 }
};

class CMyThread : public CWinThread
{
 *省略*
 CSocket2 m_socket;
};

class CMainFrame : public CFrameWnd
{
 *省略*
 CMyThread* m_pMyThread;
};

(試したこと)
*CSocket2コンストラクタとデストラクタでm_dlg変数をウォッチしたところ内容は同一でした。
*CSocket2のデストラクタではなく、CMainFrame::OnClose()で、MyThread経由でWM_CLOSEを送っても届きませんでした。
*プログラム動作中に、MyThread経由でWM_CLOSEを送ると届きました。

長々と書いてしまい申し訳ありません。
よろしくお願いいたします。

編集 削除
 2010-04-02 11:13:47  No: 71522  IP: [192.*.*.*]

お世話になっております。
その後簡単なプロジェクトを作って試していた所、
一応自己解決しましたのでお知らせします。

CMainFrame::OnClose()
{
 m_pMyThread->m_socket.m_dlg.SendMessage(WM_CLOSE); // ←成功
 m_pMyThread->PostThreadMessage(WM_DLG_CLOSE, 0, 0); //←失敗 (受け取り先でm_dlg.SendMessage(WM_CLOSE);)
}

あまり詳しく理解していませんが、
OnCloseでPostThreadMessageを呼んだ時点で
スレッドが内部でメンバのDLLダイアログをクローズしていたのだと思います
(実際はクローズできていない)。
デバッガで追ったところ、SendMessage内部のASSERT(::IsWindow(m_hWnd));で落ちていました。
(ウインドウはまだあるのに)

スレッドのダイアログをDLLの物ではなく、通常のダイアログに変えても同様の結果だったのですが
通常のダイアログはOnClose内部でGetSafeHwnd()が0を返しました。
(DLLダイアログの場合はCreate時と同じ正しい値を返す。)
更に通常のダイアログは特に明示しなくても勝手にクローズしましたので、
そのあたりから推測しました。

解決としますが、この辺りの処理についてご教示頂けるとうれしいです。

編集 削除
 2010-04-02 11:23:52  No: 71523  IP: [192.*.*.*]

>>通常のダイアログはOnClose内部でGetSafeHwnd()が0を返しました。
と書きましたが誤りです。正しくは
CMainFrame::OnClose()
{
 m_pThread->PostThreadMessage(WM_QUIT, 0, 0);
}
の後の、m_socketのデストラクタで、ダイアログのGetSafeHwnd()が0を返しました。

説明が下手で大変冗長になってしまい申し訳ありません。
読んでくれている方はいるんだろうか(^^;)

編集 削除
仲澤@失業者  2010-04-02 13:46:25  No: 71524  IP: [192.*.*.*]

>読んでくれている方はいるんだろうか(^^;)

いますよ。
自分はCSocketは絶対に使わないというポリシーなので
静観していただけです。やや、気になっていたのは、
1.DestroyWindow()ではなくなぜWM_CLOSEやWM_QUITを使うのか
2.コンストラクタとデストラクタでHWNDをどうこうするのは
    やばいよなぁ。
といった些細な問題です。

編集 削除
 2010-04-02 14:25:33  No: 71525  IP: [192.*.*.*]

仲澤@失業者 様
いつも書き込みを参考にさせて頂いております。
CSocketのことについて聞きたいですが、タイトルから話題が逸れてしまうので
ご指摘の件と併せて、自分で調査してみることにします。
ありがとうございました。

編集 削除