我的任务是对特定程序的用户界面进行一些修改。其中一部分是我向特定对话框添加更多信息。为了让它看起来更好,我认为有一个选项卡式界面会更好。目前该程序中的所有布局都是在资源(.rc)文件中完成的。
我一直在阅读带有选项卡的对话框,我相信这是通过为每个选项卡创建对话框布局(没有边框和“子”样式),然后根据选择的选项卡显示布局来完成的。我的问题是我一直无法找到任何关于如何实际执行此操作的好的文档/示例。
一些代码:
//create the main dialog from WndProc - no problem here
DialogBox(hInst, (char*)IDD_DIALOG_MAIN, hWnd, MainDlgProc);
对话框代码:
HWND hTab;
BOOL CALLBACK MainDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
{
TCITEM titem;
switch (Message) {
case WM_INITDIALOG:
//create tab control
//I didn't use a tabcontrol in the resource file because I could not figure out how to get a handle for it
hTab = CreateWindow(WC_TABCONTROL, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
30, 30, 400, 550, hDlg,(HMENU) ID_TABCTRL, hInst, NULL);
//add a couple of tabs
titem.mask = TCIF_TEXT;
titem.pszText = "Tab1";
TabCtrl_InsertItem(hTab, 0, &titem);
titem.pszText = "Tab2";
TabCtrl_InsertItem(hTab, 1, &titem);
//add content to tabs using dialog resource IDs???
//Obviously this doesn't work. It doesn't even point to which tab the content should be on
//CreateDialog(hInst,IDD_DIALOG_MAIN_TAB1, hTab, Tab1DlgProc);
//CreateDialog(hInst,IDD_DIALOG_MAIN_TAB2, hTab, Tab2DlgProc);
//EDIT: See my answer below for how I placed the dialogs in the tabs
//etc....
任何关于我可以在哪里阅读更多此类内容的建议将不胜感激。另外,如果我的方法中的任何内容看起来完全错误,请随时告诉我原因。
我最终找到了这个页面:如何创建选项卡式对话框。
从此我学会了使用类似于以下的代码加载每个选项卡的对话框资源:
DLGTEMPLATEEX *apRes[N_TABS];
apRes[0] = DoLockDlgRes(MAKEINTRESOURCE(IDD_FIRSTDLG));
apRes[1] = DoLockDlgRes(MAKEINTRESOURCE(IDD_SECONDDLG));
与
DLGTEMPLATEEX* DoLockDlgRes(LPCTSTR lpszResName)
{
HRSRC hrsrc = FindResource(NULL, lpszResName, RT_DIALOG);
// Note that g_hInst is the global instance handle
HGLOBAL hglb = LoadResource(g_hInst, hrsrc);
return (DLGTEMPLATEEX *) LockResource(hglb);
}
然后使用
加载对话框int currentSlectedTabIndex = 0;
HWND hSelectedTab;
VOID OnSelChanged(HWND hDlg)
{
//get tab control
HWND hTab = GetDlgItem(hDlg, IDC_TAB1);
// Get the index of the selected tab.
currentTabIndex = TabCtrl_GetCurSel(hTab);
// Destroy the current child dialog box, if any.
if (hSelectedTab != NULL)
DestroyWindow(hSelectedTab);
// Create the new child dialog box
hSelectedTab = CreateDialogIndirect(hInst, apRes[currentTabIndex], hDlg, TabDlgProc);
return;
}
TabDlgProc
负责调整选项卡中对话框的大小和位置。
要检查选项卡是否已切换,我使用 TCN_SELCHANGE 检查 WM_NOTIFY 消息
case WM_NOTIFY:
switch ( ((LPNMHDR)lParam)->code ) {
case TCN_SELCHANGE:
OnSelChanged(hDlg); //change tab
break;
}
break;
您走在正确的道路上。创建子对话框后,您必须调整它们在选项卡控件上的大小和位置。您可以使用 MoveWindow 来实现这一点。
顺便说一句,如果选项卡控件放置在资源文件中,您可以使用 GetDlgItem(ID) 获取其句柄。
这是 DLGTEMPLATEEX 结构
#define sz_Or_Ord WORD
#define titleLen 30
#define stringLen 30
typedef struct {
WORD dlgVer;
WORD signature;
DWORD helpID;
DWORD exStyle;
DWORD style;
WORD cDlgItems;
short x;
short y;
short cx;
short cy;
sz_Or_Ord menu;
sz_Or_Ord windowClass;
WCHAR title[titleLen];
WORD pointsize;
WORD weight;
BYTE italic;
BYTE charset;
WCHAR typeface[stringLen];
} DLGTEMPLATEEX;