none
MFCを使わずにダイアログを表示する方法 RRS feed

  • 質問

  • Visual Studio 2005 VC++で開発中です。

    MFCを使わないDLLで、キーボード入力のイベントによりダイアログを表示して値を設定するということをしたいと思っています。

    とりあえず、画面表示ができるようにしようとおもい、以下のような処理を追加しました。

    キーイベントのところで以下のような処理を行っています。
      case vrWindow::KEY_H:
      case vrWindow::KEY_h:
            /* ダイアログを作成する */
            g_hdlgWnd = CreateDialog(hInst,
                                                    MAKEINTRESOURCE(IDD_DIALOG1),
                                                    0,
                                                    (DLGPROC)DialogProc);
            if( g_hdlgWnd == NULL ){
              int error = GetLastError();
              char msg[33];
              itoa(error, msg, 10);
              string strmsg("ダイアログ作成エラー error:"); ※エラーメッセージがでる
              strmsg.append(msg);
                MessageBox(hWnd, strmsg.c_str(),"エラー", MB_OK);
            }else{
                    ShowWindow(g_hdlgWnd, SW_SHOW);
                    UpdateWindow(g_hdlgWnd);
            }
        break;

    ダイアログのコールバックでは次のような処理を追加しています。
    LRESULT CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
    {
            switch (msg){
                    case WM_COMMAND:
                            switch (LOWORD(wParam)){
                                    case IDOK:
                                            MessageBox(hwndDlg, "OKボタン","確認", MB_OK);
                                            return TRUE;
                                    case IDCANCEL:
                                            MessageBox(hwndDlg, "キャンセルボタン","確認", MB_OK);
                                            return TRUE;
                            }
                    case WM_CLOSE:
                            DestroyWindow(hwndDlg);
                            g_hdlgWnd = NULL;
                            return TRUE;
            }
            return 0;
    }

    ところが、キーを押したところで、ダイアログのCreateDialogで失敗し、
    エラーメッセージのコードには1813が表示されています。

    色々調べて見ましたが、良く分かりませんでした。
    ご教授の程よろしくお願い致します。
    2009年11月4日 1:26

回答

  • 度々申し訳ありません。

    ダイアログは表示できたのですが、ボタンのクリックなどをしようとおもっても反応しません。
    やはり、まだどこかおかしいようです。


    メッセージ ループの中に、ダイアログ宛にメッセージを送ってやる処理が必要なのではないかと。
    CreateDialog を使っているということは、モードレス ダイアログだと思うので、このあたりが参考になるかもしれません。

     Using Dialog Boxes (Creating a Modeless Dialog Box)
     http://msdn.microsoft.com/en-us/library/ms644996(VS.85).aspx#modeless_box

    あるいは、「CreateDialog IsDialogMessage」あたりで検索してみると、参考になる情報がいくつかヒットするのではないでしょうか。
     
    • 回答としてマーク rieko kume 2009年11月4日 8:09
    2009年11月4日 4:59

すべての返信

  • Visual Studio 2005 のツール、エラー ルックアップによると 1813 は 「指定されたリソースの種類がイメージ ファイルに見つかりません。」との事です。

    IDD_DIALOG1 がリソース内にありますか?
    2009年11月4日 1:56
  • Visual Studio 2005 には「エラールックアップ」というツールがあります。
    それによると、エラーコード 1813 は「指定されたリソースの種類がイメージ ファイルに見つかりません。 」です。

    IDD_DIALOG1というダイアログリソースがないか、hInstの値がおかしいか、などが原因でしょう。
    2009年11月4日 1:58
  • ミッヒーさん、Atushi777さん、

    ご回答ありがとうございます。

    現在、このDLLは、あるexe経由で DLL の export 関数として呼び出しています。
    この場合、アプリケーションの HINSTANCE 値と、 DLL 自身の HMODULE 値が同一で無いケースとありました。
    それが原因しているのでしょうか。

    DLLは以下のような感じで指定してあります。
    extern "C" int runModule( int argc, TCHAR* argv[] )



    DLL 自身の HMODULE 値を取得する方法が良く分かりません。
    現在DLLでは、以下の方法で取得を試みています。
    hInst = (HINSTANCE)GetModuleHandle(NULL);

    勉強不足で大変申し訳ありませんが、よろしくお願い致します。

    2009年11月4日 2:56
  • 自己レスです。

    GetModuleHandleの引数にdll名を入れたら画面を表示できました。

    ご教授ありがとうございました。

    • 回答としてマーク rieko kume 2009年11月4日 4:28
    • 回答としてマークされていない rieko kume 2009年11月4日 8:09
    2009年11月4日 4:27
  • 度々申し訳ありません。

    ダイアログは表示できたのですが、ボタンのクリックなどをしようとおもっても反応しません。
    やはり、まだどこかおかしいようです。

    2009年11月4日 4:31
  • GetModuleHandle のリファレンスは読んでみたでしょうか?

    引数にNULLを渡した場合のことも記載されています。VS上で、GetModuleHandle と入力されている個所でF1キーを押せばリファレンスが参照できると思いますよ(日本語じゃない場合は、MSDNライブラリでキーワードから入力し直す必要がありますが)。

    で、こちらですが、EXEのハンドルが取得されるため、DLLのリソースは使えません。

    DLLのリソースを参照する場合は、DllMain(もしくは相当する同様の関数)で、HMODULE が渡されますのでそれをどこかに保持しておきます。

    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    2009年11月4日 4:35
  • CreateDialog の第一引数には、ダイアログ ボックスのリソースを含むモジュールのハンドルを指定するので、
    DLL の中にダイアログ リソースが入っているのなら、 DLL のモジュール ハンドルを指定してあげないといけません。
    DLL 自身の HMODULE 値を取得する方法が良く分かりません。
    現在DLLでは、以下の方法で取得を試みています。
    hInst = (HINSTANCE)GetModuleHandle(NULL);

    DllMain の第一引数をどこかに持っておくのが単純ではないかと思います。
    2009年11月4日 4:38
  • 度々申し訳ありません。

    ダイアログは表示できたのですが、ボタンのクリックなどをしようとおもっても反応しません。
    やはり、まだどこかおかしいようです。


    メッセージ ループの中に、ダイアログ宛にメッセージを送ってやる処理が必要なのではないかと。
    CreateDialog を使っているということは、モードレス ダイアログだと思うので、このあたりが参考になるかもしれません。

     Using Dialog Boxes (Creating a Modeless Dialog Box)
     http://msdn.microsoft.com/en-us/library/ms644996(VS.85).aspx#modeless_box

    あるいは、「CreateDialog IsDialogMessage」あたりで検索してみると、参考になる情報がいくつかヒットするのではないでしょうか。
     
    • 回答としてマーク rieko kume 2009年11月4日 8:09
    2009年11月4日 4:59

  • 教えていただいたページ内容を参考にDLLループ処理でメッセージの取得と送信を行ったところ、
    ボタンの押下等のイベントを取得してそこで個別処理ができるようになりました。

    ご教授ありがとうございました。
    2009年11月4日 8:09