1

ここに同様の質問がありますが、 C++バージョンを探しています。

" " の代わりに文字列を変数として使用するDialogBoxを使用して.rsファイルを作成し、プログラムで変更できるようにしたいと考えています。

例:

DEFPUSHBUTTON   "Hello World", IDOK, 8, 24, 75, 14

これ"Hello World"は変数名になり、プログラムで「定義」または設定できます。

なんで?私は'template' のような DialogBox を作成しようとしていますが、プログラムの周りに異なる Text で同じボタンを持つ多くのインスタンスを作成しようとしています。

私の意味不明なことが理解されることを願っています。

4

2 に答える 2

2

残念ながら、これは不可能です。リソース ファイルは実際にはアプリケーションとは別にコンパイルされ、プログラムのコードの他の場所で定義された変数を認識しないため、コントロールのキャプション テキストは定数文字列である必要があります。

リソース ファイルは文字列テーブルをサポートしていますが、これらでも文字列が定数値である必要があります。利点は、ソース コードの残りの部分にアクセスせずにリソース ファイルを変更できることです。これにより、外部の翻訳者によるローカリゼーションなどが可能になります。

そのため、最初のキャプションをハードコーディングするのに苦労していDEFPUSHBUTTONます 空の文字列または任意の値にすることができます。プレースホルダーが必要なだけです。また、可能なすべてのキャプションを文字列テーブルに入れることはできますが (これをお勧めします)、自動化されたメカニズムを使用して 2 つをリンクすることはできません。

これを行うには、自分でコードを記述する必要があります。確かにリソースを動的に生成することはできますが、それはかなり面倒です。WM_SETTEXTこれを行う最も簡単な方法は、(「テンプレート」リソース ファイルを使用して) ダイアログを作成し、キャプション テキストを変更するコントロールのハンドルを取得し、新しい文字列でメッセージを送信することだと思います。実際、SetDlgItemText関数はまさにこれを行います。

おそらく、いくつかのコードで説明する方が簡単でしょう。すべてのコントロールを含むダイアログ リソースが定義されているとします。変更するすべてのコントロールには、実行時にそれらを区別できるように、それぞれに一意の ID を割り当てる必要があります。リソース ファイルで割り当てる初期値が何であるかは問題ではありません。すぐに変更することになるからです。次のようになります。

IDD_TEMPLATE DIALOG DISCARDABLE  0, 0, xx, xx
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Dialog Template"
FONT 8, "MS Sans Serif"
BEGIN
    CTEXT           "Placeholder text", IDC_MESSAGE, xx, xx, xx, xx
    DEFPUSHBUTTON   "Placeholder",      IDOK,        xx, xx, xx, xx
    PUSHBUTTON      "Cancel",           IDCANCEL,    xx, xx, xx, xx
END

次に、ダイアログ プロシージャ ( DialogProc) で、WM_INITDIALOG次のようにメッセージを処理します。

INT_PTR CALLBACK TemplateDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
    case WM_INITDIALOG:
    {
      // Load the caption strings you want to use from the string table
      // in the resource file, or get them from wherever you want.
      // These are the "variables" you wanted to use in the question.
      TCHAR* pszMessage;
      LoadString(hInstance,   /* instance handle for app or resource DLL */
                 IDS_MESSAGE, /* ID of the string resource to load       */
                 reinterpret_cast<LPTSTR>(&pszMessage),
                 0);
      TCHAR* pszOkBtn;
      LoadString(hInstance, IDS_OKBUTTON, reinterpret_cast<LPTSTR>(&pszOkBtn), 0);
      // ...etc.

      // Set the caption text for each control.
      SetDlgItemText(hwndDlg,     /* handle to the dialog box window */
                     IDC_MESSAGE, /* ID of the control to modify     */
                     pszMessage); /* variable containing text to set */
      SetDlgItemText(hwndDlg, IDOK, pszOkBtn);
      // ...etc.

      // And, if you want to set some other properties, you can do that too.
      // For example, you might set the caption of the dialog itself.
      TCHAR* pszTitle;
      LoadString(hInstance, IDS_DLGCAPTION, reinterpret_cast<LPTSTR>(&pszTitle), 0);
      SetWindowText(hwndDlg, pszTitle);
      // ...etc.

      return TRUE;  // set the default focus
    }
    // ...process other messages as necessary
  }
  return FALSE;  // we did not process the message
}
于 2013-04-22T22:57:29.327 に答える
1

Cody Gray の回答の方が優れていると思いますが、ダイアログ テンプレートをメモリ内に作成し、ダイアログの新しいインスタンスを作成するときにそれを変更するオプションが常にあります。この種のことが楽しいと思わない限り、お勧めしません(私はそのような人の一人です)。私は確かにあなたが求めているものにはお勧めしませんが、技術的にはオプションです...

DialogBoxIndirectDLGTEMPLATEは、ダイアログ ボックス自体を説明するヘッダー ( ) とそれに続く指定された数のコントロール ( )で構成される構造体へのポインターを受け取りますDLGITEMTEMPLATE

上記を効果的に使用して、ボタンに異なるテキストを持つ DialogBox が必要になるたびに、新しいメモリ内ダイアログ テンプレートを作成できます。ただし、本当にやりたいことがテキストを変更することだけである場合、それは少し極端です.Codyが言うように、SetDlgItemText.

本当に興味がある場合は、ここに例を示します。

于 2013-04-23T14:32:40.703 に答える