windows编程中创建TabControl的问题
///////////////////////////////////////////
// ProgressDemo.cpp文件
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#define sz_Or_Ord WORD
#define titleLen 100
#define stringLen 100
#define C_PAGES 3
// 链接到comctl32.lib库
#pragma comment(lib,"comctl32.lib")
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;
typedef struct tag_dlghdr {
HWND hwndTab; // tab control
HWND hwndDisplay; // current child dialog box
RECT rcDisplay; // display rectangle for the tab control
DLGTEMPLATEEX *apRes[C_PAGES];
} DLGHDR;
BOOL __stdcall ChildDialogProc(HWND, UINT, WPARAM, LPARAM);
BOOL __stdcall DlgProc(HWND, UINT, WPARAM, LPARAM);
HRESULT OnTabbedDialogInit(HWND hwndDlg);
DLGTEMPLATEEX* DoLockDlgRes(LPCTSTR lpszResName);
VOID OnSelChanged(HWND hwndDlg);
HINSTANCE g_hInst;
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
::InitCommonControls();
g_hInst = hInstance;
::DialogBoxParam(
hInstance, // 实例句柄
(LPCTSTR)IDD_MAIN, // 对话框资源ID号
NULL, // 父窗口句柄
DlgProc, // 消息处理函数
NULL); // 对话框初始化的值,在WM_INITDIALOG消息的lParam参数中取出
return 0;
}
BOOL __stdcall DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
{
OnTabbedDialogInit(hDlg);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
break;
case IDCANCEL:
::EndDialog (hDlg, IDCANCEL);
break;
}
break;
}
return 0;
}
HRESULT OnTabbedDialogInit(HWND hwndDlg)
{
INITCOMMONCONTROLSEX iccex;
DWORD dwDlgBase = GetDialogBaseUnits();
int cxMargin = LOWORD(dwDlgBase) / 4;
int cyMargin = HIWORD(dwDlgBase) / 8;
TCITEM tie;
RECT rcTab;
HWND hwndButton;
RECT rcButton;
int i;
// Initialize common controls.
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&iccex);
// Allocate memory for the DLGHDR structure. Remember to
// free this memory before the dialog box is destroyed.
DLGHDR *pHdr = (DLGHDR *) LocalAlloc(LPTR, sizeof(DLGHDR));
// Save a pointer to the DLGHDR structure in the window
// data of the dialog box.
SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pHdr);
// Create the tab control. Note that g_hInst is a global
// instance handle.
pHdr->hwndTab = CreateWindow(WC_TABCONTROL, "",WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,0,0,100,100,hwndDlg, NULL, g_hInst,NULL);
if (pHdr->hwndTab == NULL)
{
return HRESULT_FROM_WIN32(GetLastError());
}
// Add a tab for each of the three child dialog boxes.
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
tie.pszText = "First";
TabCtrl_InsertItem(pHdr->hwndTab, 0, &tie);
tie.pszText = "Second";
TabCtrl_InsertItem(pHdr->hwndTab, 1, &tie);
tie.pszText = "Third";
TabCtrl_InsertItem(pHdr->hwndTab, 2, &tie);
// Lock the resources for the three child dialog boxes.
pHdr->apRes[0] = DoLockDlgRes(MAKEINTRESOURCE(IDD_FIRSTDLG));
pHdr->apRes[1] = DoLockDlgRes(MAKEINTRESOURCE(IDD_SECONDDLG));
pHdr->apRes[2] = DoLockDlgRes(MAKEINTRESOURCE(IDD_THIRDDLG));
// Determine a bounding rectangle that is large enough to
// contain the largest child dialog box.
SetRectEmpty(&rcTab);
for (i = 0; i < C_PAGES; i++)
{
if (pHdr->apRes[i]->cx > rcTab.right)
rcTab.right = pHdr->apRes[i]->cx;
if (pHdr->apRes[i]->cy > rcTab.bottom)
rcTab.bottom = pHdr->apRes[i]->cy;
}
// Map the rectangle from dialog box units to pixels.
MapDialogRect(hwndDlg, &rcTab);
// Calculate how large to make the tab control, so
// the display area can accommodate all the child dialog boxes.
TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
OffsetRect(&rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top);
// Calculate the display rectangle.
CopyRect(&pHdr->rcDisplay, &rcTab);
TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
// Set the size and position of the tab control, buttons,
// and dialog box.
SetWindowPos(pHdr->hwndTab, NULL, rcTab.left, rcTab.top,
rcTab.right - rcTab.left, rcTab.bottom - rcTab.top,
SWP_NOZORDER);
// Move the first button below the tab control.
hwndButton = GetDlgItem(hwndDlg, IDB_CLOSE);
SetWindowPos(hwndButton, NULL,
rcTab.left, rcTab.bottom + cyMargin, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
// Determine the size of the button.
GetWindowRect(hwndButton, &rcButton);
rcButton.right -= rcButton.left;
rcButton.bottom -= rcButton.top;
// Move the second button to the right of the first.
hwndButton = GetDlgItem(hwndDlg, IDB_TEST);
SetWindowPos(hwndButton, NULL,
rcTab.left + rcButton.right + cxMargin,
rcTab.bottom + cyMargin, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
// Size the dialog box.
SetWindowPos(hwndDlg, NULL, 0, 0,
rcTab.right + cyMargin + (2 * GetSystemMetrics(SM_CXDLGFRAME)),
rcTab.bottom + rcButton.bottom + (2 * cyMargin)
+ (2 * GetSystemMetrics(SM_CYDLGFRAME))
+ GetSystemMetrics(SM_CYCAPTION),
SWP_NOMOVE | SWP_NOZORDER);
// Simulate selection of the first item.
OnSelChanged(hwndDlg);
return S_OK;
}
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);
}
VOID OnSelChanged(HWND hwndDlg)
{
// Get the dialog header data.
DLGHDR *pHdr = (DLGHDR *) GetWindowLong(
hwndDlg, GWL_USERDATA);
// Get the index of the selected tab.
int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
// Destroy the current child dialog box, if any.
if (pHdr->hwndDisplay != NULL)
DestroyWindow(pHdr->hwndDisplay);
// Create the new child dialog box. Note that g_hInst is the
// global instance handle.
pHdr->hwndDisplay = CreateDialogIndirect(g_hInst,
(DLGTEMPLATE *)pHdr->apRes[iSel], hwndDlg, ChildDialogProc);
return;
}
BOOL __stdcall ChildDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
{
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
break;
case IDCANCEL:
::EndDialog (hDlg, IDCANCEL);
break;
}
break;
}
return 0;
}
备注:
编程环境VC6.0
第一个问题:,经过调试发现:
pHdr->apRes[0]->cx=68
pHdr->apRes[1]->cx=68
pHdr->apRes[2]->cx=68
pHdr->apRes[0]->cy=105
pHdr->apRes[1]->cy=105
pHdr->apRes[2]->cy=105
为什么,我的rc文件中的三个对话框的描述都不是这个宽度和高度????
第二个问题:
// Map the rectangle from dialog box units to pixels.
MapDialogRect(hwndDlg, &rcTab);
这个函数到底是干嘛的?经过这个函数调用以后,68变成了136,105变成了210,都变成原先的二倍,不理解。
第三个问题:
TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
这个函数到底是干嘛的?弄的头大。
...全文


