不幸的是,这是不可能的。控件的标题文本必须是常量字符串,因为资源文件实际上是与您的应用程序分开编译的,并且不知道程序代码中其他地方定义的变量。
资源文件确实支持字符串表,但即使这些也要求字符串是常量值。优点是您可以修改资源文件而无需访问源代码的其余部分,这使得本地化之类的事情成为可能,即使是外部翻译人员也是如此。
所以你被困在硬编码你的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
}