📄 propsheet.c
字号:
p++; /* dlgVer */
p++; /* signature */
p += 2; /* help ID */
p += 2; /* ext style */
p += 2; /* style */
}
else
{
/* DLGTEMPLATE */
p += 2; /* style */
p += 2; /* ext style */
}
p++; /* nb items */
p++; /* x */
p++; /* y */
width = (WORD)*p; p++;
height = (WORD)*p; p++;
/* Special calculation for interior wizard pages so the largest page is
* calculated correctly. We need to add all the padding and space occupied
* by the header so the width and height sums up to the whole wizard client
* area. */
if ((psInfo->ppshheader.dwFlags & (PSH_WIZARD97_OLD | PSH_WIZARD97_NEW)) &&
(psInfo->ppshheader.dwFlags & PSH_HEADER) &&
!(dwFlags & PSP_HIDEHEADER))
{
height += 2 * WIZARD_PADDING + WIZARD_HEADER_HEIGHT;
width += 2 * WIZARD_PADDING;
}
if (psInfo->ppshheader.dwFlags & PSH_WIZARD)
{
height += 2 * WIZARD_PADDING;
width += 2 * WIZARD_PADDING;
}
/* remember the largest width and height */
if (width > psInfo->width)
psInfo->width = width;
if (height > psInfo->height)
psInfo->height = height;
/* menu */
switch ((WORD)*p)
{
case 0x0000:
p++;
break;
case 0xffff:
p += 2;
break;
default:
p += lstrlenW( (LPCWSTR)p ) + 1;
break;
}
/* class */
switch ((WORD)*p)
{
case 0x0000:
p++;
break;
case 0xffff:
p += 2;
break;
default:
p += lstrlenW( (LPCWSTR)p ) + 1;
break;
}
/* Extract the caption */
psInfo->proppage[index].pszText = (LPCWSTR)p;
TRACE("Tab %d %s\n",index,debugstr_w((LPCWSTR)p));
p += lstrlenW((LPCWSTR)p) + 1;
if (dwFlags & PSP_USETITLE)
{
WCHAR szTitle[256];
const WCHAR *pTitle;
static const WCHAR pszNull[] = { '(','n','u','l','l',')',0 };
int len;
if ( !HIWORD( lppsp->pszTitle ) )
{
if (!LoadStringW( lppsp->hInstance, (DWORD_PTR)lppsp->pszTitle,szTitle,sizeof(szTitle) ))
{
pTitle = pszNull;
FIXME("Could not load resource #%04x?\n",LOWORD(lppsp->pszTitle));
}
else
pTitle = szTitle;
}
else
pTitle = lppsp->pszTitle;
len = strlenW(pTitle);
psInfo->proppage[index].pszText = Alloc( (len+1)*sizeof (WCHAR) );
strcpyW( (LPWSTR)psInfo->proppage[index].pszText,pTitle);
}
/*
* Build the image list for icons
*/
if ((dwFlags & PSP_USEHICON) || (dwFlags & PSP_USEICONID))
{
HICON hIcon;
int icon_cx = GetSystemMetrics(SM_CXSMICON);
int icon_cy = GetSystemMetrics(SM_CYSMICON);
if (dwFlags & PSP_USEICONID)
hIcon = LoadImageW(lppsp->hInstance, lppsp->u2.pszIcon, IMAGE_ICON,
icon_cx, icon_cy, LR_DEFAULTCOLOR);
else
hIcon = lppsp->u2.hIcon;
if ( hIcon )
{
if (psInfo->hImageList == 0 )
psInfo->hImageList = ImageList_Create(icon_cx, icon_cy, ILC_COLOR, 1, 1);
ImageList_AddIcon(psInfo->hImageList, hIcon);
}
}
return TRUE;
}
/******************************************************************************
* PROPSHEET_CreateDialog
*
* Creates the actual property sheet.
*/
static INT_PTR PROPSHEET_CreateDialog(PropSheetInfo* psInfo)
{
LRESULT ret;
LPCVOID template;
LPVOID temp = 0;
HRSRC hRes;
DWORD resSize;
WORD resID = IDD_PROPSHEET;
TRACE("\n");
if (psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD)
resID = IDD_WIZARD;
if( psInfo->unicode )
{
if(!(hRes = FindResourceW(COMCTL32_hModule,
MAKEINTRESOURCEW(resID),
(LPWSTR)RT_DIALOG)))
return -1;
}
else
{
if(!(hRes = FindResourceA(COMCTL32_hModule,
MAKEINTRESOURCEA(resID),
(LPSTR)RT_DIALOG)))
return -1;
}
if(!(template = (LPVOID)LoadResource(COMCTL32_hModule, hRes)))
return -1;
/*
* Make a copy of the dialog template.
*/
resSize = SizeofResource(COMCTL32_hModule, hRes);
temp = Alloc(resSize);
if (!temp)
return -1;
memcpy(temp, template, resSize);
if (psInfo->ppshheader.dwFlags & PSH_NOCONTEXTHELP)
{
if (((MyDLGTEMPLATEEX*)temp)->signature == 0xFFFF)
((MyDLGTEMPLATEEX*)temp)->style &= ~DS_CONTEXTHELP;
else
((DLGTEMPLATE*)temp)->style &= ~DS_CONTEXTHELP;
}
if ((psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD) &&
(psInfo->ppshheader.dwFlags & PSH_WIZARDCONTEXTHELP))
{
if (((MyDLGTEMPLATEEX*)temp)->signature == 0xFFFF)
((MyDLGTEMPLATEEX*)temp)->style |= DS_CONTEXTHELP;
else
((DLGTEMPLATE*)temp)->style |= DS_CONTEXTHELP;
}
if (psInfo->useCallback)
(*(psInfo->ppshheader.pfnCallback))(0, PSCB_PRECREATE, (LPARAM)temp);
/* NOTE: MSDN states "Returns a positive value if successful, or -1
* otherwise for modal property sheets.", but this is wrong. The
* actual return value is either TRUE (success), FALSE (cancel) or
* -1 (error). */
if( psInfo->unicode )
{
ret = (INT_PTR)CreateDialogIndirectParamW(psInfo->ppshheader.hInstance,
(LPDLGTEMPLATEW) temp,
psInfo->ppshheader.hwndParent,
PROPSHEET_DialogProc,
(LPARAM)psInfo);
if ( !ret ) ret = -1;
}
else
{
ret = (INT_PTR)CreateDialogIndirectParamA(psInfo->ppshheader.hInstance,
(LPDLGTEMPLATEA) temp,
psInfo->ppshheader.hwndParent,
PROPSHEET_DialogProc,
(LPARAM)psInfo);
if ( !ret ) ret = -1;
}
Free(temp);
return ret;
}
/******************************************************************************
* PROPSHEET_SizeMismatch
*
* Verify that the tab control and the "largest" property sheet page dlg. template
* match in size.
*/
static BOOL PROPSHEET_SizeMismatch(HWND hwndDlg, PropSheetInfo* psInfo)
{
HWND hwndTabCtrl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
RECT rcOrigTab, rcPage;
/*
* Original tab size.
*/
GetClientRect(hwndTabCtrl, &rcOrigTab);
TRACE("orig tab %d %d %d %d\n", rcOrigTab.left, rcOrigTab.top,
rcOrigTab.right, rcOrigTab.bottom);
/*
* Biggest page size.
*/
rcPage.left = 0;
rcPage.top = 0;
rcPage.right = psInfo->width;
rcPage.bottom = psInfo->height;
MapDialogRect(hwndDlg, &rcPage);
TRACE("biggest page %d %d %d %d\n", rcPage.left, rcPage.top,
rcPage.right, rcPage.bottom);
if ( (rcPage.right - rcPage.left) != (rcOrigTab.right - rcOrigTab.left) )
return TRUE;
if ( (rcPage.bottom - rcPage.top) != (rcOrigTab.bottom - rcOrigTab.top) )
return TRUE;
return FALSE;
}
/******************************************************************************
* PROPSHEET_AdjustSize
*
* Resizes the property sheet and the tab control to fit the largest page.
*/
static BOOL PROPSHEET_AdjustSize(HWND hwndDlg, PropSheetInfo* psInfo)
{
HWND hwndTabCtrl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
HWND hwndButton = GetDlgItem(hwndDlg, IDOK);
RECT rc,tabRect;
int tabOffsetX, tabOffsetY, buttonHeight;
PADDING_INFO padding = PROPSHEET_GetPaddingInfo(hwndDlg);
RECT units;
/* Get the height of buttons */
GetClientRect(hwndButton, &rc);
buttonHeight = rc.bottom;
/*
* Biggest page size.
*/
rc.left = 0;
rc.top = 0;
rc.right = psInfo->width;
rc.bottom = psInfo->height;
MapDialogRect(hwndDlg, &rc);
/* retrieve the dialog units */
units.left = units.right = 4;
units.top = units.bottom = 8;
MapDialogRect(hwndDlg, &units);
/*
* Resize the tab control.
*/
GetClientRect(hwndTabCtrl,&tabRect);
SendMessageW(hwndTabCtrl, TCM_ADJUSTRECT, FALSE, (LPARAM)&tabRect);
if ((rc.bottom - rc.top) < (tabRect.bottom - tabRect.top))
{
rc.bottom = rc.top + tabRect.bottom - tabRect.top;
psInfo->height = MulDiv((rc.bottom - rc.top),8,units.top);
}
if ((rc.right - rc.left) < (tabRect.right - tabRect.left))
{
rc.right = rc.left + tabRect.right - tabRect.left;
psInfo->width = MulDiv((rc.right - rc.left),4,units.left);
}
SendMessageW(hwndTabCtrl, TCM_ADJUSTRECT, TRUE, (LPARAM)&rc);
tabOffsetX = -(rc.left);
tabOffsetY = -(rc.top);
rc.right -= rc.left;
rc.bottom -= rc.top;
TRACE("setting tab %p, rc (0,0)-(%d,%d)\n",
hwndTabCtrl, rc.right, rc.bottom);
SetWindowPos(hwndTabCtrl, 0, 0, 0, rc.right, rc.bottom,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
GetClientRect(hwndTabCtrl, &rc);
TRACE("tab client rc %d %d %d %d\n",
rc.left, rc.top, rc.right, rc.bottom);
rc.right += ((padding.x * 2) + tabOffsetX);
rc.bottom += (buttonHeight + (3 * padding.y) + tabOffsetY);
/*
* Resize the property sheet.
*/
TRACE("setting dialog %p, rc (0,0)-(%d,%d)\n",
hwndDlg, rc.right, rc.bottom);
SetWindowPos(hwndDlg, 0, 0, 0, rc.right, rc.bottom,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
return TRUE;
}
/******************************************************************************
* PROPSHEET_AdjustSizeWizard
*
* Resizes the property sheet to fit the largest page.
*/
static BOOL PROPSHEET_AdjustSizeWizard(HWND hwndDlg, PropSheetInfo* psInfo)
{
HWND hwndLine = GetDlgItem(hwndDlg, IDC_SUNKEN_LINE);
RECT rc, lineRect, dialogRect;
/* Biggest page size */
rc.left = 0;
rc.top = 0;
rc.right = psInfo->width;
rc.bottom = psInfo->height;
MapDialogRect(hwndDlg, &rc);
TRACE("Biggest page %d %d %d %d\n", rc.left, rc.top, rc.right, rc.bottom);
/* Add space for the buttons row */
GetWindowRect(hwndLine, &lineRect);
MapWindowPoints(NULL, hwndDlg, (LPPOINT)&lineRect, 2);
GetClientRect(hwndDlg, &dialogRect);
rc.bottom += dialogRect.bottom - lineRect.top - 1;
/* Convert the client coordinates to window coordinates */
AdjustWindowRect(&rc, GetWindowLongW(hwndDlg, GWL_STYLE), FALSE);
/* Resize the property sheet */
TRACE("setting dialog %p, rc (0,0)-(%d,%d)\n",
hwndDlg, rc.right, rc.bottom);
SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
return TRUE;
}
/******************************************************************************
* PROPSHEET_AdjustButtons
*
* Adjusts the buttons' positions.
*/
static BOOL PROPSHEET_AdjustButtons(HWND hwndParent, PropSheetInfo* psInfo)
{
HWND hwndButton = GetDlgItem(hwndParent, IDOK);
RECT rcSheet;
int x, y;
int num_buttons = 2;
int buttonWidth, buttonHeight;
PADDING_INFO padding = PROPSHEET_GetPaddingInfo(hwndParent);
if (psInfo->hasApply)
num_buttons++;
if (psInfo->hasHelp)
num_buttons++;
/*
* Obtain the size of the buttons.
*/
GetClientRect(hwndButton, &rcSheet);
buttonWidth = rcSheet.right;
buttonHeight = rcSheet.bottom;
/*
* Get the size of the property sheet.
*/
GetClientRect(hwndParent, &rcSheet);
/*
* All buttons will be at this y coordinate.
*/
y = rcSheet.bottom - (padding.y + buttonHeight);
/*
* Position OK button and make it default.
*/
hwndButton = GetDlgItem(hwndParent, IDOK);
x = rcSheet.right - ((padding.x + buttonWidth) * num_buttons);
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
SendMessageW(hwndParent, DM_SETDEFID, IDOK, 0);
/*
* Position Cancel button.
*/
hwndButton = GetDlgItem(hwndParent, IDCANCEL);
x = rcSheet.right - ((padding.x + buttonWidth) * (num_buttons - 1));
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
/*
* Position Apply button.
*/
hwndButton = GetDlgItem(hwndParent, IDC_APPLY_BUTTON);
if (psInfo->hasApply)
{
if (psInfo->hasHelp)
x = rcSheet.right - ((padding.x + buttonWidth) * 2);
else
x = rcSheet.right - (padding.x + buttonWidth);
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
EnableWindow(hwndButton, FALSE);
}
else
ShowWindow(hwndButton, SW_HIDE);
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -