none
スレッドからPostMessageによる関数の呼び出し RRS feed

  • 質問

  • スレッド内でPostMessageにて関数を呼び出そうとしていますが、呼出しのPostMessageは実行しているのですが、関数が呼び出されません。

    メッセージマップは下記のように宣言しています。

    #define WM_READ_END WM_USER + 5

    BEGIN_MESSAGE_MAP(CSerialCommView, CFormView)
     ON_MESSAGE(WM_READ_END, OnEndRead)
     ON_WM_DESTROY()
     ON_WM_CTLCOLOR()
     ON_WM_PAINT()
     ON_WM_TIMER()
     ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, &CSerialCommView::OnTcnSelchangeTab)
     ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CSerialCommView::OnBnClickedButtonConnect)
     ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, &CSerialCommView::OnBnClickedButtonDisconnect)
     ON_BN_CLICKED(IDC_BUTTON_SEND, &CSerialCommView::OnBnClickedButtonSend)
     ON_BN_CLICKED(IDC_BUTTON_RECEIVE, &CSerialCommView::OnBnClickedButtonReceive)
     ON_STN_DBLCLK(IDC_PIC_LAMP4, &CSerialCommView::OnStnDblclickPicLamp4)
     ON_STN_DBLCLK(IDC_PIC_LAMP5, &CSerialCommView::OnStnDblclickPicLamp5)
     ON_STN_DBLCLK(IDC_PIC_LAMP6, &CSerialCommView::OnStnDblclickPicLamp6)
    END_MESSAGE_MAP()

    また、PostMessageは

    ::PostMessage(m_vhWnd, WM_READ_END, 0, 0);

    としています。

    どのようにすれば、関数が呼出せるかお教えください。

    2012年8月26日 0:55

すべての返信

  • >::PostMessage(m_vhWnd, WM_READ_END, 0, 0);

    その時点で m_vhWnd に格納されているウィンドウハンドルは有効ですか?

    また、m_vhWnd はメッセージを処理するはずのウィンドウを間違いなく指し示しているでしょうか?


    2012年8月26日 2:39
  • m_vhWndはスレッド処理開始時に m_vhWnd = GetSafeHwnd();としてウィンドウハンドルを渡しています。

    2012年8月26日 7:03
  • いくつか可能性を書いてみます。

    1. GetSafeHwnd 関数の呼び出し方がおかしい。
    2. m_vhWnd の代入先、あるいは参照方法がおかしい。
    3. メインスレッドとワーカースレッド(AfxBeginThread)間でパラメーターを渡す方法がおかしい。

    現状の書き込み内容では何が問題か当てられません。

    以下、推測で困る事柄:
    スレッド処理開始時」という「AfxBeginThread を呼ぶ側のコード」なのか、「AfxBeginThread で指定した関数の冒頭コード」なのか?
    m_vhWnd とは何変数?クラスのメンバー変数?static?グローバル変数?
    このウィンドウは複数表示される、ワーカースレッドが複数同時実行されることはない?
    AfxBeginThread 自体は何を渡しているのか?

    2012年8月26日 9:16
    モデレータ
  • #define WM_READ_END WM_USER + 5
    詳しくないので見当はずれかもしれませんが、 WM_USER+5 ではなく WM_APP+5 だとうまくいきますか?
    2012年8月26日 23:58
  • Azuleanさんの質問に追加する感じになりますが

    スレッドを生成・開始する前にGetSafeHwnd()していた場合、
    スレッドを生成した場所(クラス・関数)は、どこで行っているのでしょうか?

    2012年8月27日 4:08
  • スレッドの生成・開始は、COMポートをオープンするためのOnBnClickedButtonConnect()から呼出したCommPortOpen関数内で下記のように行っています。

     m_pThread = AfxBeginThread(ReadThread, 0, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
                   // 受信スレッド     生成
     m_pThread->m_bAutoDelete = FALSE;      // スレッド自動削除 禁止
     m_vhWnd = GetSafeHwnd();        // ウィンドウハンドル   取得
     m_pThread->ResumeThread();        // スレッド実行開始

    2012年8月27日 10:44
  • いろいろと答えていない項目があるようなので、再度見直してください。
    2012年8月27日 13:38
    モデレータ
  • 1.
    CommPortOpen関数も、CSerialCommViewのメンバ関数ですか?

    2.
    m_vhWnd = GetSafeHwnd();
    ここについて疑問が…

    m_pThread->m_vhWnd = GetSafeHwnd();
    の書き間違えでしょうか?
    もしくはさらにスレッド側に引き渡すところがあるのでしょうか?
    それとも、m_vhWndがグローバルとか?

    もし、提示されたものだけが実際に使用されているソースであれば
    スレッド側にウィンドウハンドルが渡せてないのではないでしょうか?

    2012年8月28日 3:47
  • m_vhWndはグローバル変数です。

    皆様のご回答で、どうにか呼び出しができるようになりました。

    2012年8月30日 10:49
  • 何が悪かったのかを残しておきませんか。
    似たような症状で困った後進の人々へのヒントになると思いますので。
    2012年8月30日 13:26
    モデレータ
  • こんにちは、B_Wolf さん
    フォーラムオペレータの佐伯 玲 です。

    B_Wolf さん、問題は解決されたようですがAzulean さんも仰る通り
    原因や実際に行われた対策を記載頂けると今後同じ現象で困った方達にも大きな助けとなります。

    是非一度その後の詳細をこちらへご返信下さいませ。

    今後ともMSDNフォーラムを宜しくお願い致します。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレーター 佐伯 玲

    2012年9月3日 5:39
  • 色々と変更してみて動くようになったので、原因が特定できていませんが、多分

    ::PostMessage(m_vhWnd, WM_READ_END, 0, 0);

    としていたのを、

    ::PostMessageW(m_vhWnd, WM_READ_END, 0, 0);

    に変更後、呼出されるようになりました。

    2012年9月12日 11:06