📄 propsheet.c
字号:
* Position Help button.
*/
hwndButton = GetDlgItem(hwndParent, IDHELP);
if (psInfo->hasHelp)
{
x = rcSheet.right - (padding.x + buttonWidth);
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
else
ShowWindow(hwndButton, SW_HIDE);
return TRUE;
}
/******************************************************************************
* PROPSHEET_AdjustButtonsWizard
*
* Adjusts the buttons' positions.
*/
static BOOL PROPSHEET_AdjustButtonsWizard(HWND hwndParent,
PropSheetInfo* psInfo)
{
HWND hwndButton = GetDlgItem(hwndParent, IDCANCEL);
HWND hwndLine = GetDlgItem(hwndParent, IDC_SUNKEN_LINE);
HWND hwndLineHeader = GetDlgItem(hwndParent, IDC_SUNKEN_LINEHEADER);
RECT rcSheet;
int x, y;
int num_buttons = 3;
int buttonWidth, buttonHeight, lineHeight, lineWidth;
PADDING_INFO padding = PROPSHEET_GetPaddingInfoWizard(hwndParent, psInfo);
if (psInfo->hasHelp)
num_buttons++;
if (psInfo->hasFinish)
num_buttons++;
/*
* Obtain the size of the buttons.
*/
GetClientRect(hwndButton, &rcSheet);
buttonWidth = rcSheet.right;
buttonHeight = rcSheet.bottom;
GetClientRect(hwndLine, &rcSheet);
lineHeight = 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 the Back button.
*/
hwndButton = GetDlgItem(hwndParent, IDC_BACK_BUTTON);
x = rcSheet.right - ((padding.x + buttonWidth) * (num_buttons - 1)) - buttonWidth;
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
/*
* Position the Next button.
*/
hwndButton = GetDlgItem(hwndParent, IDC_NEXT_BUTTON);
x += buttonWidth;
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
/*
* Position the Finish button.
*/
hwndButton = GetDlgItem(hwndParent, IDC_FINISH_BUTTON);
if (psInfo->hasFinish)
x += padding.x + buttonWidth;
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
if (!psInfo->hasFinish)
ShowWindow(hwndButton, SW_HIDE);
/*
* Position the Cancel button.
*/
hwndButton = GetDlgItem(hwndParent, IDCANCEL);
x += padding.x + buttonWidth;
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
/*
* Position Help button.
*/
hwndButton = GetDlgItem(hwndParent, IDHELP);
if (psInfo->hasHelp)
{
x += padding.x + buttonWidth;
SetWindowPos(hwndButton, 0, x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
else
ShowWindow(hwndButton, SW_HIDE);
if (psInfo->ppshheader.dwFlags &
(PSH_WIZARD97_OLD | PSH_WIZARD97_NEW | PSH_WIZARD_LITE))
padding.x = 0;
/*
* Position and resize the sunken line.
*/
x = padding.x;
y = rcSheet.bottom - ((padding.y * 2) + buttonHeight + lineHeight);
lineWidth = rcSheet.right - (padding.x * 2);
SetWindowPos(hwndLine, 0, x, y, lineWidth, 2,
SWP_NOZORDER | SWP_NOACTIVATE);
/*
* Position and resize the header sunken line.
*/
SetWindowPos(hwndLineHeader, 0, 0, 0, rcSheet.right, 2,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
if (!(psInfo->ppshheader.dwFlags & (PSH_WIZARD97_OLD | PSH_WIZARD97_NEW)))
ShowWindow(hwndLineHeader, SW_HIDE);
return TRUE;
}
/******************************************************************************
* PROPSHEET_GetPaddingInfo
*
* Returns the layout information.
*/
static PADDING_INFO PROPSHEET_GetPaddingInfo(HWND hwndDlg)
{
HWND hwndTab = GetDlgItem(hwndDlg, IDC_TABCONTROL);
RECT rcTab;
POINT tl;
PADDING_INFO padding;
GetWindowRect(hwndTab, &rcTab);
tl.x = rcTab.left;
tl.y = rcTab.top;
ScreenToClient(hwndDlg, &tl);
padding.x = tl.x;
padding.y = tl.y;
return padding;
}
/******************************************************************************
* PROPSHEET_GetPaddingInfoWizard
*
* Returns the layout information.
* Vertical spacing is the distance between the line and the buttons.
* Do NOT use the Help button to gather padding information when it isn't mapped
* (PSH_HASHELP), as app writers aren't forced to supply correct coordinates
* for it in this case !
* FIXME: I'm not sure about any other coordinate problems with these evil
* buttons. Fix it in case additional problems appear or maybe calculate
* a padding in a completely different way, as this is somewhat messy.
*/
static PADDING_INFO PROPSHEET_GetPaddingInfoWizard(HWND hwndDlg, const PropSheetInfo*
psInfo)
{
PADDING_INFO padding;
RECT rc;
HWND hwndControl;
INT idButton;
POINT ptButton, ptLine;
TRACE("\n");
if (psInfo->hasHelp)
{
idButton = IDHELP;
}
else
{
if (psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD)
{
idButton = IDC_NEXT_BUTTON;
}
else
{
/* hopefully this is ok */
idButton = IDCANCEL;
}
}
hwndControl = GetDlgItem(hwndDlg, idButton);
GetWindowRect(hwndControl, &rc);
ptButton.x = rc.left;
ptButton.y = rc.top;
ScreenToClient(hwndDlg, &ptButton);
/* Line */
hwndControl = GetDlgItem(hwndDlg, IDC_SUNKEN_LINE);
GetWindowRect(hwndControl, &rc);
ptLine.x = rc.left;
ptLine.y = rc.bottom;
ScreenToClient(hwndDlg, &ptLine);
padding.y = ptButton.y - ptLine.y;
if (padding.y < 0)
ERR("padding negative ! Please report this !\n");
/* this is most probably not correct, but the best we have now */
padding.x = padding.y;
return padding;
}
/******************************************************************************
* PROPSHEET_CreateTabControl
*
* Insert the tabs in the tab control.
*/
static BOOL PROPSHEET_CreateTabControl(HWND hwndParent,
PropSheetInfo * psInfo)
{
HWND hwndTabCtrl = GetDlgItem(hwndParent, IDC_TABCONTROL);
TCITEMW item;
int i, nTabs;
int iImage = 0;
TRACE("\n");
item.mask = TCIF_TEXT;
item.cchTextMax = MAX_TABTEXT_LENGTH;
nTabs = psInfo->nPages;
/*
* Set the image list for icons.
*/
if (psInfo->hImageList)
{
SendMessageW(hwndTabCtrl, TCM_SETIMAGELIST, 0, (LPARAM)psInfo->hImageList);
}
SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 0, 0);
for (i = 0; i < nTabs; i++)
{
if ( psInfo->proppage[i].hasIcon )
{
item.mask |= TCIF_IMAGE;
item.iImage = iImage++;
}
else
{
item.mask &= ~TCIF_IMAGE;
}
item.pszText = (LPWSTR) psInfo->proppage[i].pszText;
SendMessageW(hwndTabCtrl, TCM_INSERTITEMW, (WPARAM)i, (LPARAM)&item);
}
SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 1, 0);
return TRUE;
}
/******************************************************************************
* PROPSHEET_WizardSubclassProc
*
* Subclassing window procedure for wizard extrior pages to prevent drawing
* background and so drawing above the watermark.
*/
static LRESULT CALLBACK
PROPSHEET_WizardSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uID, DWORD_PTR dwRef)
{
switch (uMsg)
{
case WM_ERASEBKGND:
return TRUE;
case WM_CTLCOLORSTATIC:
SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
/*
* Get the size of an in-memory Template
*
*( Based on the code of PROPSHEET_CollectPageInfo)
* See also dialog.c/DIALOG_ParseTemplate32().
*/
static UINT GetTemplateSize(DLGTEMPLATE* pTemplate)
{
const WORD* p = (const WORD *)pTemplate;
BOOL istemplateex = (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF);
WORD nrofitems;
UINT ret;
if (istemplateex)
{
/* DLGTEMPLATEEX (not defined in any std. header file) */
TRACE("is DLGTEMPLATEEX\n");
p++; /* dlgVer */
p++; /* signature */
p += 2; /* help ID */
p += 2; /* ext style */
p += 2; /* style */
}
else
{
/* DLGTEMPLATE */
TRACE("is DLGTEMPLATE\n");
p += 2; /* style */
p += 2; /* ext style */
}
nrofitems = (WORD)*p; p++; /* nb items */
p++; /* x */
p++; /* y */
p++; /* width */
p++; /* height */
/* menu */
switch ((WORD)*p)
{
case 0x0000:
p++;
break;
case 0xffff:
p += 2;
break;
default:
TRACE("menu %s\n",debugstr_w((LPCWSTR)p));
p += lstrlenW( (LPCWSTR)p ) + 1;
break;
}
/* class */
switch ((WORD)*p)
{
case 0x0000:
p++;
break;
case 0xffff:
p += 2; /* 0xffff plus predefined window class ordinal value */
break;
default:
TRACE("class %s\n",debugstr_w((LPCWSTR)p));
p += lstrlenW( (LPCWSTR)p ) + 1;
break;
}
/* title */
TRACE("title %s\n",debugstr_w((LPCWSTR)p));
p += lstrlenW((LPCWSTR)p) + 1;
/* font, if DS_SETFONT set */
if ((DS_SETFONT & ((istemplateex)? ((MyDLGTEMPLATEEX*)pTemplate)->style :
pTemplate->style)))
{
p+=(istemplateex)?3:1;
TRACE("font %s\n",debugstr_w((LPCWSTR)p));
p += lstrlenW( (LPCWSTR)p ) + 1; /* the font name */
}
/* now process the DLGITEMTEMPLATE(EX) structs (plus custom data)
* that are following the DLGTEMPLATE(EX) data */
TRACE("%d items\n",nrofitems);
while (nrofitems > 0)
{
p = (WORD*)(((DWORD_PTR)p + 3) & ~3); /* DWORD align */
/* skip header */
p += (istemplateex ? sizeof(MyDLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE))/sizeof(WORD);
/* check class */
switch ((WORD)*p)
{
case 0x0000:
p++;
break;
case 0xffff:
TRACE("class ordinal 0x%08x\n",*(DWORD*)p);
p += 2;
break;
default:
TRACE("class %s\n",debugstr_w((LPCWSTR)p));
p += lstrlenW( (LPCWSTR)p ) + 1;
break;
}
/* check title text */
switch ((WORD)*p)
{
case 0x0000:
p++;
break;
case 0xffff:
TRACE("text ordinal 0x%08x\n",*(DWORD*)p);
p += 2;
break;
default:
TRACE("text %s\n",debugstr_w((LPCWSTR)p));
p += lstrlenW( (LPCWSTR)p ) + 1;
break;
}
p += *p / sizeof(WORD) + 1; /* Skip extra data */
--nrofitems;
}
ret = (p - (WORD*)pTemplate) * sizeof(WORD);
TRACE("%p %p size 0x%08x\n", p, pTemplate, ret);
return ret;
}
/******************************************************************************
* PROPSHEET_CreatePage
*
* Creates a page.
*/
static BOOL PROPSHEET_CreatePage(HWND hwndParent,
int index,
const PropSheetInfo * psInfo,
LPCPROPSHEETPAGEW ppshpage)
{
DLGTEMPLATE* pTemplate;
HWND hwndPage;
DWORD resSize;
LPVOID temp = NULL;
TRACE("index %d\n", index);
if (ppshpage == NULL)
{
return FALSE;
}
if (ppshpage->dwFlags & PSP_DLGINDIRECT)
{
pTemplate = (DLGTEMPLATE*)ppshpage->u.pResource;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -