propsheet.c
来自「一个类似windows」· C语言 代码 · 共 2,269 行 · 第 1/5 页
C
2,269 行
* 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%08lx\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%08lx\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;
}
TRACE("%p %p size 0x%08x\n",p, (WORD*)pTemplate,sizeof(WORD)*(p - (WORD*)pTemplate));
return (p - (WORD*)pTemplate)*sizeof(WORD);
}
/******************************************************************************
* 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;
resSize = GetTemplateSize(pTemplate);
}
else if(ppshpage->dwFlags & PSP_INTERNAL_UNICODE)
{
HRSRC hResource;
HANDLE hTemplate;
hResource = FindResourceW(ppshpage->hInstance,
ppshpage->u.pszTemplate,
(LPWSTR)RT_DIALOG);
if(!hResource)
return FALSE;
resSize = SizeofResource(ppshpage->hInstance, hResource);
hTemplate = LoadResource(ppshpage->hInstance, hResource);
if(!hTemplate)
return FALSE;
pTemplate = (LPDLGTEMPLATEW)LockResource(hTemplate);
/*
* Make a copy of the dialog template to make it writable
*/
}
else
{
HRSRC hResource;
HANDLE hTemplate;
hResource = FindResourceA(ppshpage->hInstance,
(LPSTR)ppshpage->u.pszTemplate,
(LPSTR)RT_DIALOG);
if(!hResource)
return FALSE;
resSize = SizeofResource(ppshpage->hInstance, hResource);
hTemplate = LoadResource(ppshpage->hInstance, hResource);
if(!hTemplate)
return FALSE;
pTemplate = (LPDLGTEMPLATEA)LockResource(hTemplate);
/*
* Make a copy of the dialog template to make it writable
*/
}
temp = Alloc(resSize);
if (!temp)
return FALSE;
TRACE("copying pTemplate %p into temp %p (%ld)\n", pTemplate, temp, resSize);
memcpy(temp, pTemplate, resSize);
pTemplate = temp;
if (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF)
{
((MyDLGTEMPLATEEX*)pTemplate)->style |= WS_CHILD | WS_TABSTOP | DS_CONTROL;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~DS_MODALFRAME;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_CAPTION;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_SYSMENU;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_POPUP;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_DISABLED;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_VISIBLE;
((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_THICKFRAME;
((MyDLGTEMPLATEEX*)pTemplate)->exStyle |= WS_EX_CONTROLPARENT;
}
else
{
pTemplate->style |= WS_CHILD | WS_TABSTOP | DS_CONTROL;
pTemplate->style &= ~DS_MODALFRAME;
pTemplate->style &= ~WS_CAPTION;
pTemplate->style &= ~WS_SYSMENU;
pTemplate->style &= ~WS_POPUP;
pTemplate->style &= ~WS_DISABLED;
pTemplate->style &= ~WS_VISIBLE;
pTemplate->style &= ~WS_THICKFRAME;
pTemplate->dwExtendedStyle |= WS_EX_CONTROLPARENT;
}
if (psInfo->proppage[index].useCallback)
(*(ppshpage->pfnCallback))(0, PSPCB_CREATE,
(LPPROPSHEETPAGEW)ppshpage);
if(ppshpage->dwFlags & PSP_INTERNAL_UNICODE)
hwndPage = CreateDialogIndirectParamW(ppshpage->hInstance,
pTemplate,
hwndParent,
ppshpage->pfnDlgProc,
(LPARAM)ppshpage);
else
hwndPage = CreateDialogIndirectParamA(ppshpage->hInstance,
pTemplate,
hwndParent,
ppshpage->pfnDlgProc,
(LPARAM)ppshpage);
/* Free a no more needed copy */
if(temp)
Free(temp);
psInfo->proppage[index].hwndPage = hwndPage;
/* Subclass exterior wizard pages */
if((psInfo->ppshheader.dwFlags & (PSH_WIZARD97_NEW | PSH_WIZARD97_OLD)) &&
(psInfo->ppshheader.dwFlags & PSH_WATERMARK) &&
(ppshpage->dwFlags & PSP_HIDEHEADER))
{
SetWindowSubclass(hwndPage, PROPSHEET_WizardSubclassProc, 1,
(DWORD_PTR)ppshpage);
}
if (!(psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD))
EnableThemeDialogTexture (hwndPage, ETDT_ENABLETAB);
return TRUE;
}
/******************************************************************************
* PROPSHEET_LoadWizardBitmaps
*
* Loads the watermark and header bitmaps for a wizard.
*/
static VOID PROPSHEET_LoadWizardBitmaps(PropSheetInfo *psInfo)
{
if (psInfo->ppshheader.dwFlags & (PSH_WIZARD97_NEW | PSH_WIZARD97_OLD))
{
/* if PSH_USEHBMWATERMARK is not set, load the resource from pszbmWatermark
and put the HBITMAP in hbmWatermark. Thus all the rest of the code always
considers hbmWatermark as valid. */
if ((psInfo->ppshheader.dwFlags & PSH_WATERMARK) &&
!(psInfo->ppshheader.dwFlags & PSH_USEHBMWATERMARK))
{
((PropSheetInfo *)psInfo)->ppshheader.u4.hbmWatermark =
CreateMappedBitmap(psInfo->ppshheader.hInstance, (INT_PTR)psInfo->ppshheader.u4.pszbmWatermark, 0, NULL, 0);
}
/* Same behavior as for watermarks */
if ((psInfo->ppshheader.dwFlags & PSH_HEADER) &&
!(psInfo->ppshheader.dwFlags & PSH_USEHBMHEADER))
{
((PropSheetInfo *)psInfo)->ppshheader.u5.hbmHeader =
CreateMappedBitmap(psInfo->ppshheader.hInstance, (INT_PTR)psInfo->ppshheader.u5.pszbmHeader, 0, NULL, 0);
}
}
}
/******************************************************************************
* PROPSHEET_ShowPage
*
* Displays or creates the specified page.
*/
static BOOL PROPSHEET_ShowPage(HWND hwndDlg, int index, PropSheetInfo * psInfo)
{
HWND hwndTabCtrl;
HWND hwndLineHeader;
LPCPROPSHEETPAGEW ppshpage;
TRACE("active_page %d, index %d\n", psInfo->active_page, index);
if (index == psInfo->active_page)
{
if (GetTopWindow(hwndDlg) != psInfo->proppage[index].hwndPage)
SetWindowPos(psInfo->proppage[index].hwndPage, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
return TRUE;
}
ppshpage = (LPCPROPSHEETPAGEW)psInfo->proppage[index].hpage;
if (psInfo->proppage[index].hwndPage == 0)
{
PROPSHEET_CreatePage(hwndDlg, index, psInfo, ppshpage);
}
if ((psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD) &&
(ppshpage->dwFlags & PSP_USETITLE))
{
PROPSHEET_SetTitleW(hwndDlg, psInfo->ppshheader.dwFlags,
psInfo->proppage[index].pszText);
}
if (psInfo->active_page != -1)
ShowWindow(psInfo->proppage[psInfo->active_page].hwndPage, SW_HIDE);
ShowWindow(psInfo->proppage[index].hwndPage, SW_SHOW);
/* Synchronize current selection with tab control
* It seems to be needed even in case of PSH_WIZARD (no tab controls there) */
hwndTabCtrl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
SendMessageW(hwndTabCtrl, TCM_SETCURSEL, index, 0);
psInfo->active_page = index;
psInfo->activeValid = TRUE;
if (psInfo->ppshheader.dwFlags & (PSH_WIZARD97_OLD | PSH_WIZARD97_NEW) )
{
hwndLineHeader = GetDlgItem(hwndDlg, IDC_SUNKEN_LINEHEADER);
ppshpage = (LPCPROPSHEETPAGEW)psInfo->proppage[index].hpage;
if ((ppshpage->dwFlags & PSP_HIDEHEADER) || (!(psInfo->ppshheader.dwFlags & PSH_HEADER)) )
ShowWindow(hwndLineHeader, SW_HIDE);
else
ShowWindow(hwndLineHeader, SW_SHOW);
}
return TRUE;
}
/******************************************************************************
* PROPSHEET_Back
*/
static BOOL PROPSHEET_Back(HWND hwndDlg)
{
PSHNOTIFY psn;
HWND hwndPage;
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
LRESULT result;
int idx;
TRACE("active_page %d\n", psInfo->active_page);
if (psInfo->active_page < 0)
return FALSE;
psn.hdr.code = PSN_WIZBACK;
psn.hdr.hwndFrom = hwndDlg;
psn.hdr.idFrom = 0;
psn.lParam = 0;
hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
result = SendMessageW(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn);
if (result == -1)
return FALSE;
else if (result == 0)
idx = psInfo->active_page - 1;
else
idx = PROPSHEET_FindPageByResId(psInfo, result);
if (idx >= 0 && idx < psInfo->nPages)
{
if (PROPSHEET_CanSetCurSel(hwndDlg))
PROPSHEET_SetCurSel(hwndDlg, idx, -1, 0);
}
return TRUE;
}
/******************************************************************************
* PROPSHEET_Next
*/
static BOOL PROPSHEET_Next(HWND hwndDlg)
{
PSHNOTIFY psn;
HWND hwndPage;
LRESULT msgResult = 0;
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
int idx;
TRACE("active_page %d\n", psInfo->active_page);
if (psInfo->active_page < 0)
return FALSE;
psn.hdr.code = PSN_WIZNEXT;
psn.hdr.hwndFrom = hwndDlg;
psn.hdr.idFrom = 0;
psn.lParam = 0;
hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
msgResult = SendMessageW(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn);
if (msgResult == -1)
return FALSE;
else if (msgResult == 0)
idx = psInfo->active_page + 1;
else
idx = PROPSHEET_FindPageByResId(psInfo, msgResult);
if (idx < psInfo->nPages )
{
if (PROPSHEET_CanSetCurSel(hwndDlg) != FALSE)
PROPSHEET_SetCurSel(hwndDlg, idx, 1, 0);
}
return TRUE;
}
/******************************************************************************
* PROPSHEET_Finish
*/
static BOOL PROPSHEET_Finish(HWND hwndDlg)
{
PSHNOTIFY psn;
HWND hwndPage;
LRESULT msgResult = 0;
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
TRACE("active_page %d\n", psInfo->active_page);
if (psInfo->active_page < 0)
return FALSE;
psn.hdr.code = PSN_WIZFINISH;
psn.hdr.hwndFrom = hwndDlg;
psn.hdr.idFrom = 0;
psn.lParam = 0;
hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
msgResult = SendMessageW(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn);
TRACE("msg result %ld\n", msgResult);
if (msgResult != 0)
return FALSE;
if (psInfo->isModeless)
psInfo->activeValid = FALSE;
else
psInfo->ended = TRUE;
return TRUE;
}
/******************************************************************************
* PROPSHEET_Apply
*/
static BOOL PROPSHEET_Apply(HWND hwndDlg, LPARAM lParam)
{
int i;
HWND hwndPage;
PSHNOTIFY psn;
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
TRACE("active_page %d\n", psInfo->active_page);
if (psInfo->active_page < 0)
return FALSE;
psn.hdr.hwndFrom = hwndDlg;
psn.hdr.idFrom = 0;
psn.lParam = 0;
/*
* Send PSN_KILLACTIVE to the current page.
*/
psn.hdr.code = PSN_KILLACTIVE;
hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
if (SendMessageW(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn) != FALSE)
return FALSE;
/*
* Send PSN_APPLY to all pages.
*/
psn.hdr.code = PSN_APPLY;
psn.lParam = lParam;
for (i = 0; i < psInfo->nPages; i++)
{
hwndPage = psInfo->proppage[i].hwndPage;
if (hwndPage)
{
switch (SendMessageW(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn))
{
case PSNRET_INVALID:
PROPSHEET_ShowPage(hwndDlg, i, psInfo);
/* fall through */
case PSNRET_INVALID_NOCHANGEPAGE:
return FALSE;
}
}
}
if(lParam)
{
psInfo->activeValid = FALSE;
}
else if(psInfo->active_page >= 0)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?