1

这里有一个类似的问题,但我正在寻找C++版本。

我想创建一个带有DialogBox的.rs文件,该文件使用字符串作为变量而不是“”,以便我可以在程序中更改它。

例如:在

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

"Hello World"成为一个变量名,我可以在程序中“定义”设置

为什么?我正在尝试制作一个 DialogBox,例如'template',并在程序周围制作许多实例,其中包含不同的 Text 但其中的按钮相同。

希望我的胡言乱语能被理解。

4

2 回答 2

2

不幸的是,这是不可能的。控件的标题文本必须是常量字符串,因为资源文件实际上是与您的应用程序分开编译的,并且不知道程序代码中其他地方定义的变量。

资源文件确实支持字符串表,但即使这些也要求字符串是常量值。优点是您可以修改资源文件而无需访问源代码的其余部分,这使得本地化之类的事情成为可能,即使是外部翻译人员也是如此。

所以你被困在硬编码你的DEFPUSHBUTTON. 它可以是空字符串或您想要的任何值;你只需要一个占位符。您可以将所有可能的标题放在一个字符串表中(我建议这样做),但您不能使用任何自动机制将两者联系起来。

您需要自己编写代码来执行此操作。您当然可以动态生成资源,但这有点麻烦。我认为最简单的方法就是创建对话框(使用您的“模板”资源文件),检索要更改其标题文本的控件的句柄,并向它们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 的答案更好,但始终可以选择在内存中创建对话框模板,并在创建对话框的新实例时对其进行修改。除非你觉得这种事情很有趣,否则我不会推荐它(我就是其中之一)。我当然不会根据您的要求推荐它,但从技术上讲,它是一种选择...

DialogBoxIndirect接受一个指向结构的指针,该结构由DLGTEMPLATE描述对话框本身的标题 ( ) 和指定数量的控件 ( DLGITEMTEMPLATE) 组成。

每次您想要一个在按钮上具有不同文本的 DialogBox 时,您都可以有效地使用上述方法构建一个新的内存中对话框模板。但是,如果您真正想做的只是更改一些文本,这有点极端,正如 Cody 所说,您可以使用SetDlgItemText.

如果你真的很好奇,这里有一个例子

于 2013-04-23T14:32:40.703 回答