📄 dlgprop.cpp
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "occimpl.h"
#ifdef AFX_CORE4_SEG
#pragma code_seg(AFX_CORE4_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
////////////////////////////////////////////////////////////////////////////
// CPropertyPage -- one page of a tabbed dialog
UINT CALLBACK
AfxPropPageCallback(HWND, UINT message, LPPROPSHEETPAGE pPropPage)
{
switch (message)
{
case PSPCB_CREATE:
{
ASSERT(AfxIsValidAddress(pPropPage, sizeof(AFX_OLDPROPSHEETPAGE)));
ASSERT(AfxIsValidAddress(pPropPage, pPropPage->dwSize));
CPropertyPage* pPage =
STATIC_DOWNCAST(CPropertyPage, (CObject*)pPropPage->lParam);
ASSERT_VALID(pPage);
TRY
{
AfxHookWindowCreate(pPage);
}
CATCH_ALL(e)
{
// Note: DELETE_EXCEPTION(e) not necessary
return FALSE;
}
END_CATCH_ALL
}
return TRUE;
case PSPCB_RELEASE:
AfxUnhookWindowCreate();
break;
}
return 0;
}
BEGIN_MESSAGE_MAP(CPropertyPage, CDialog)
//{{AFX_MSG_MAP(CPropertyPage)
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
#ifndef _AFX_NO_CTL3D_SUPPORT
ON_MESSAGE(WM_QUERY3DCONTROLS, OnQuery3dControls)
#endif
END_MESSAGE_MAP()
CPropertyPage::CPropertyPage(UINT nIDTemplate, UINT nIDCaption)
{
ASSERT(nIDTemplate != 0);
CommonConstruct(MAKEINTRESOURCE(nIDTemplate), nIDCaption);
}
CPropertyPage::CPropertyPage(LPCTSTR lpszTemplateName, UINT nIDCaption)
{
ASSERT(AfxIsValidString(lpszTemplateName));
CommonConstruct(lpszTemplateName, nIDCaption);
}
void CPropertyPage::Construct(UINT nIDTemplate, UINT nIDCaption)
{
ASSERT(nIDTemplate != 0);
CommonConstruct(MAKEINTRESOURCE(nIDTemplate), nIDCaption);
}
void CPropertyPage::Construct(LPCTSTR lpszTemplateName, UINT nIDCaption)
{
ASSERT(HIWORD(lpszTemplateName) == 0 ||
AfxIsValidString(lpszTemplateName));
CommonConstruct(lpszTemplateName, nIDCaption);
}
CPropertyPage::CPropertyPage()
{
CommonConstruct(NULL, 0);
}
void CPropertyPage::CommonConstruct(LPCTSTR lpszTemplateName, UINT nIDCaption)
{
memset(&m_psp, 0, sizeof(m_psp));
m_psp.dwSize = sizeof(m_psp);
m_psp.dwFlags = PSP_USECALLBACK;
if (lpszTemplateName != NULL)
m_psp.hInstance = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);
m_psp.pszTemplate = lpszTemplateName;
m_psp.pfnDlgProc = AfxDlgProc;
m_psp.lParam = (LPARAM)this;
m_psp.pfnCallback = AfxPropPageCallback;
if (nIDCaption != 0)
{
VERIFY(m_strCaption.LoadString(nIDCaption));
m_psp.pszTitle = m_strCaption;
m_psp.dwFlags |= PSP_USETITLE;
}
if (AfxHelpEnabled())
m_psp.dwFlags |= PSP_HASHELP;
if (HIWORD(lpszTemplateName) == 0)
m_nIDHelp = LOWORD((DWORD)lpszTemplateName);
m_lpszTemplateName = m_psp.pszTemplate;
m_bFirstSetActive = TRUE;
}
CPropertyPage::~CPropertyPage()
{
#ifndef _AFX_NO_OCC_SUPPORT
Cleanup();
#endif
if (m_hDialogTemplate != NULL)
GlobalFree(m_hDialogTemplate);
}
#ifndef _AFX_NO_OCC_SUPPORT
void CPropertyPage::Cleanup()
{
COccManager* pOccManager = afxOccManager;
if ((pOccManager != NULL) && (m_pOccDialogInfo != NULL))
{
pOccManager->PostCreateDialog(m_pOccDialogInfo);
free(m_pOccDialogInfo);
m_pOccDialogInfo = NULL;
}
}
AFX_STATIC DLGTEMPLATE* AFXAPI
_AfxChangePropPageFont(const DLGTEMPLATE* pTemplate, BOOL bWizard)
{
CString strFaceDefault;
WORD wSizeDefault;
if (!AfxGetPropSheetFont(strFaceDefault, wSizeDefault, bWizard))
return NULL;
// set font of property page to same font used by property sheet
CString strFace;
WORD wSize;
if ((!CDialogTemplate::GetFont(pTemplate, strFace, wSize)) ||
(strFace != strFaceDefault) || (wSize != wSizeDefault))
{
CDialogTemplate dlgTemplate(pTemplate);
dlgTemplate.SetFont(strFaceDefault, wSizeDefault);
return (DLGTEMPLATE*)dlgTemplate.Detach();
}
return NULL;
}
const DLGTEMPLATE* CPropertyPage::InitDialogInfo(const DLGTEMPLATE* pTemplate)
{
// cleanup from previous run, if any
Cleanup();
m_pOccDialogInfo = (_AFX_OCC_DIALOG_INFO*)malloc(
sizeof(_AFX_OCC_DIALOG_INFO));
return afxOccManager->PreCreateDialog(m_pOccDialogInfo, pTemplate);
}
#endif
void CPropertyPage::PreProcessPageTemplate(PROPSHEETPAGE& psp, BOOL bWizard)
{
const DLGTEMPLATE* pTemplate;
if (psp.dwFlags & PSP_DLGINDIRECT)
{
pTemplate = psp.pResource;
}
else
{
HRSRC hResource = ::FindResource(psp.hInstance,
psp.pszTemplate, RT_DIALOG);
HGLOBAL hTemplate = LoadResource(psp.hInstance,
hResource);
pTemplate = (LPCDLGTEMPLATE)LockResource(hTemplate);
}
ASSERT(pTemplate != NULL);
#ifdef _DEBUG
// WINBUG: Windows currently does not support DIALOGEX resources!
// Assert that the template is *not* a DIALOGEX template.
// DIALOGEX templates are not supported by the PropertySheet API.
// To change a DIALOGEX template back to a DIALOG template,
// remove the following:
// 1. Extended styles on the dialog
// 2. Help IDs on any control in the dialog
// 3. Control IDs that are DWORDs
// 4. Weight, italic, or charset attributes on the dialog's font
if (((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF)
{
// it's a DIALOGEX -- we'd better check
DWORD dwVersion = ::GetVersion();
if (dwVersion & 0x80000000)
{
// it's Win95 -- versions of COMCTL32.DLL that export
// a function called DllGetVersion are okay
HINSTANCE hInst = LoadLibrary(_T("COMCTL32.DLL"));
ASSERT(hInst != NULL);
if (hInst != NULL)
{
FARPROC proc = GetProcAddress(hInst, "DllGetVersion");
if (proc == NULL)
ASSERT(FALSE);
FreeLibrary(hInst);
}
}
else if (LOBYTE(LOWORD(dwVersion)) == 3)
{
// it's Windows NT 3.x; we have no hope of this working
ASSERT(FALSE);
}
}
#endif // _DEBUG
#ifndef _AFX_NO_OCC_SUPPORT
// if the dialog could contain OLE controls, deal with them now
if (afxOccManager != NULL)
pTemplate = InitDialogInfo(pTemplate);
#endif
// set font of property page to same font used by property sheet
HGLOBAL hTemplate = _AfxChangePropPageFont(pTemplate, bWizard);
if (m_hDialogTemplate != NULL)
{
GlobalFree(m_hDialogTemplate);
m_hDialogTemplate = NULL;
}
if (hTemplate != NULL)
{
pTemplate = (LPCDLGTEMPLATE)hTemplate;
m_hDialogTemplate = hTemplate;
}
psp.pResource = pTemplate;
psp.dwFlags |= PSP_DLGINDIRECT;
}
void CPropertyPage::CancelToClose()
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(GetParent() != NULL);
GetParent()->SendMessage(PSM_CANCELTOCLOSE);
}
void CPropertyPage::SetModified(BOOL bChanged)
{
if (m_hWnd == NULL) // allowed for backward compatibility
return;
ASSERT(::IsWindow(m_hWnd));
ASSERT(GetParent() != NULL);
CWnd* pParentWnd = GetParent();
if (bChanged)
pParentWnd->SendMessage(PSM_CHANGED, (WPARAM)m_hWnd);
else
pParentWnd->SendMessage(PSM_UNCHANGED, (WPARAM)m_hWnd);
}
LRESULT CPropertyPage::QuerySiblings(WPARAM wParam, LPARAM lParam)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(GetParent() != NULL);
return GetParent()->SendMessage(PSM_QUERYSIBLINGS, wParam, lParam);
}
BOOL CPropertyPage::OnApply()
{
ASSERT_VALID(this);
OnOK();
return TRUE;
}
void CPropertyPage::OnReset()
{
ASSERT_VALID(this);
OnCancel();
}
void CPropertyPage::OnOK()
{
ASSERT_VALID(this);
}
void CPropertyPage::OnCancel()
{
ASSERT_VALID(this);
}
BOOL CPropertyPage::OnSetActive()
{
ASSERT_VALID(this);
if (m_bFirstSetActive)
m_bFirstSetActive = FALSE;
else
UpdateData(FALSE);
return TRUE;
}
BOOL CPropertyPage::OnKillActive()
{
ASSERT_VALID(this);
if (!UpdateData())
{
TRACE0("UpdateData failed during page deactivation\n");
return FALSE;
}
return TRUE;
}
BOOL CPropertyPage::OnQueryCancel()
{
return TRUE; // ok to cancel
}
LRESULT CPropertyPage::OnWizardBack()
{
return 0;
}
LRESULT CPropertyPage::OnWizardNext()
{
return 0;
}
BOOL CPropertyPage::OnWizardFinish()
{
return TRUE;
}
LRESULT CPropertyPage::MapWizardResult(LRESULT lToMap)
{
// -1 and 0 are special
if (lToMap == -1 || lToMap == 0)
return lToMap;
// only do special stuff if MFC owns the property sheet
CWnd* pParent = GetParent();
CPropertySheet* pSheet = DYNAMIC_DOWNCAST(CPropertySheet, pParent);
if (pSheet != NULL)
{
// the structures are laid out different for CPropertySheeEx
CPropertySheetEx* pSheetEx = DYNAMIC_DOWNCAST(CPropertySheetEx, pParent);
const PROPSHEETPAGE* ppsp;
if (pSheetEx != NULL)
ppsp = pSheetEx->m_psh.ppsp;
else
ppsp = pSheet->m_psh.ppsp;
// search the pages for a matching ID
for (int i = 0; i < pSheet->m_pages.GetSize(); i++)
{
// check page[i] for a match
CPropertyPage* pPage = pSheet->GetPage(i);
if ((LRESULT)pPage->m_psp.pszTemplate == lToMap)
return (LRESULT)ppsp->pResource;
// jump to next page
(BYTE*&)ppsp += ppsp->dwSize;
}
}
// otherwise, just use the original value
return lToMap;
}
BOOL CPropertyPage::IsButtonEnabled(int iButton)
{
HWND hWnd = ::GetDlgItem(::GetParent(m_hWnd), iButton);
if (hWnd == NULL)
return FALSE;
return ::IsWindowEnabled(hWnd);
}
BOOL CPropertyPage::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
ASSERT(pResult != NULL);
NMHDR* pNMHDR = (NMHDR*)lParam;
// allow message map to override
if (CDialog::OnNotify(wParam, lParam, pResult))
return TRUE;
// don't handle messages not from the page/sheet itself
if (pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
return FALSE;
// handle default
switch (pNMHDR->code)
{
case PSN_SETACTIVE:
{
CPropertySheet* pSheet = DYNAMIC_DOWNCAST(CPropertySheet, GetParent());
if (pSheet != NULL && !(pSheet->m_nFlags & WF_CONTINUEMODAL) && !(pSheet->m_bModeless))
*pResult = -1;
else
*pResult = OnSetActive() ? 0 : -1;
}
break;
case PSN_KILLACTIVE:
*pResult = !OnKillActive();
break;
case PSN_APPLY:
*pResult = OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
break;
case PSN_RESET:
OnReset();
break;
case PSN_QUERYCANCEL:
*pResult = !OnQueryCancel();
break;
case PSN_WIZNEXT:
//WINBUG: Win32 will send a PSN_WIZBACK even if the button is disabled.
if (IsButtonEnabled(ID_WIZNEXT))
*pResult = MapWizardResult(OnWizardNext());
break;
case PSN_WIZBACK:
//WINBUG: Win32 will send a PSN_WIZBACK even if the button is disabled.
if (IsButtonEnabled(ID_WIZBACK))
*pResult = MapWizardResult(OnWizardBack());
break;
case PSN_WIZFINISH:
*pResult = !OnWizardFinish();
break;
case PSN_HELP:
SendMessage(WM_COMMAND, ID_HELP);
break;
default:
return FALSE; // not handled
}
return TRUE; // handled
}
/////////////////////////////////////////////////////////////////////////////
// CPropertyPage message Handlers
BOOL CPropertyPage::PreTranslateMessage(MSG* pMsg)
{
VERIFY(!CWnd::PreTranslateMessage(pMsg));
return FALSE; // handled by CPropertySheet::PreTranslateMessage
}
HBRUSH CPropertyPage::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
LRESULT lResult;
if (pWnd->SendChildNotifyLastMsg(&lResult))
return (HBRUSH)lResult;
if (afxData.bWin4)
return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (!GrayCtlColor(pDC->m_hDC, pWnd->GetSafeHwnd(), nCtlColor,
afxData.hbrBtnFace, afxData.clrBtnText))
return (HBRUSH)Default();
return afxData.hbrBtnFace;
}
/////////////////////////////////////////////////////////////////////////////
// CPropertyPage Diagnostics
#ifdef _DEBUG
void CPropertyPage::AssertValid() const
{
CDialog::AssertValid();
ASSERT(m_psp.dwSize == sizeof(m_psp));
ASSERT(m_psp.dwFlags & PSP_USECALLBACK);
ASSERT(m_psp.pfnDlgProc == AfxDlgProc);
ASSERT(m_psp.lParam == (LPARAM)this);
}
void CPropertyPage::Dump(CDumpContext& dc) const
{
CDialog::Dump(dc);
dc << "m_strCaption = " << m_strCaption << "\n";
dc << "m_psp.dwFlags = " << m_psp.dwFlags << "\n";
}
#endif //_DEBUG
void CPropertyPage::EndDialog(int nID)
{
// Normally you shouldn't call EndDialog from a page. But in case it does
// happen during error situations, call CPropertySheet::EndDialog instead.
CPropertySheet* pParent = DYNAMIC_DOWNCAST(CPropertySheet, GetParent());
if (pParent != NULL)
pParent->EndDialog(nID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -