📄 dlgprop.cpp
字号:
}
}
void CPropertySheet::RemovePage(CPropertyPage* pPage)
{
ASSERT_VALID(this);
ASSERT(pPage != NULL);
ASSERT_KINDOF(CPropertyPage, pPage);
int nPage = GetPageIndex(pPage);
ASSERT(nPage >= 0);
RemovePage(nPage);
}
void CPropertySheet::RemovePage(int nPage)
{
ASSERT_VALID(this);
// remove the page externally
if (m_hWnd != NULL)
SendMessage(PSM_REMOVEPAGE, nPage);
// remove the page from internal list
m_pages.RemoveAt(nPage);
}
void CPropertySheet::EndDialog(int nEndID)
{
ASSERT_VALID(this);
CWnd::EndModalLoop(nEndID);
if (m_bModeless)
DestroyWindow();
else
PostMessage(PSM_PRESSBUTTON, PSBTN_CANCEL);
}
void CPropertySheet::OnClose()
{
m_nModalResult = IDCANCEL;
if (m_bModeless)
DestroyWindow();
else
Default();
}
void CPropertySheet::OnSysCommand(UINT nID, LPARAM)
{
m_nModalResult = IDCANCEL;
switch (nID & 0xFFF0)
{
case SC_CLOSE:
if (m_bModeless)
{
SendMessage(WM_CLOSE);
return;
}
}
Default();
}
/////////////////////////////////////////////////////////////////////////////
// CPropertySheet message handlers
AFX_STATIC_DATA int _afxPropSheetButtons[] = { IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP };
BOOL CPropertySheet::OnInitDialog()
{
// change tab style if scrolling tabs desired (stacked tabs are default)
if (!m_bStacked)
{
HWND hWndTab = (HWND)::GetDlgItem(m_hWnd, AFX_IDC_TAB_CONTROL);
if (hWndTab != NULL)
CWnd::ModifyStyle(hWndTab, TCS_MULTILINE, TCS_SINGLELINE, 0);
}
if (!IsWizard())
{
// resize the tab control so the layout is less restrictive
HWND hWnd = (HWND)::GetDlgItem(m_hWnd, AFX_IDC_TAB_CONTROL);
ASSERT(hWnd != NULL);
CRect rectOld;
::GetWindowRect(hWnd, &rectOld);
ScreenToClient(rectOld);
CRect rectNew(0, 0, 0, 32);
::MapDialogRect(m_hWnd, &rectNew);
if (rectNew.bottom < rectOld.bottom)
{
// move tab control
int cyDiff = rectOld.Height() - rectNew.bottom;
::SetWindowPos(hWnd, NULL, 0, 0, rectOld.Width(), rectNew.bottom,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
// move buttons by similar amount
for (int i = 0; i < _countof(_afxPropSheetButtons); i++)
{
hWnd = ::GetDlgItem(m_hWnd, _afxPropSheetButtons[i]);
if (hWnd != NULL)
{
::GetWindowRect(hWnd, &rectOld);
ScreenToClient(&rectOld);
::SetWindowPos(hWnd, NULL,
rectOld.left, rectOld.top - cyDiff,
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
// resize property sheet itself similarly
GetWindowRect(&rectOld);
SetWindowPos(NULL, 0, 0, rectOld.Width(), rectOld.Height() - cyDiff,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
BOOL bResult = (BOOL)Default();
if (m_bModeless && !IsWizard())
{
// layout property sheet so button area is not accounted for
CRect rectWnd;
GetWindowRect(rectWnd);
CRect rectButton;
HWND hWnd = ::GetDlgItem(m_hWnd, IDOK);
ASSERT(hWnd != NULL);
::GetWindowRect(hWnd, rectButton);
SetWindowPos(NULL, 0, 0,
rectWnd.Width(), rectButton.top - rectWnd.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
// remove standard buttons for modeless dialogs
for (int i = 0; i < _countof(_afxPropSheetButtons); i++)
{
HWND hWnd = ::GetDlgItem(m_hWnd, _afxPropSheetButtons[i]);
if (hWnd != NULL)
{
::ShowWindow(hWnd, SW_HIDE);
::EnableWindow(hWnd, FALSE);
}
}
}
// center the property sheet relative to the parent window
if (!(GetStyle() & WS_CHILD))
CenterWindow();
return bResult;
}
BOOL CPropertySheet::OnNcCreate(LPCREATESTRUCT)
{
// By default, MFC does not directly support the new style
// help button in the caption, so it is turned off here.
// It can be added back in and implemented by derived classes
// from CPropertySheet.
ModifyStyleEx(WS_EX_CONTEXTHELP, 0);
return (BOOL)Default();
}
LRESULT CPropertySheet::HandleInitDialog(WPARAM, LPARAM)
{
LRESULT lResult = OnInitDialog();
return lResult;
}
BOOL CPropertySheet::OnCommand(WPARAM wParam, LPARAM lParam)
{
// allow message map override
if (CWnd::OnCommand(wParam, lParam))
return TRUE;
// crack message parameters
UINT nID = LOWORD(wParam);
HWND hWndCtrl = (HWND)lParam;
int nCode = HIWORD(wParam);
// set m_nModalResult to ID of button, whenever button is clicked
if (hWndCtrl != NULL && nCode == BN_CLICKED)
{
if (::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0) &
(DLGC_BUTTON|DLGC_DEFPUSHBUTTON))
{
LONG lStyle = ::GetWindowLong(hWndCtrl, GWL_STYLE) & 0x0F;
if (lStyle == BS_PUSHBUTTON || lStyle == BS_DEFPUSHBUTTON ||
lStyle == BS_USERBUTTON || lStyle == BS_OWNERDRAW)
{
m_nModalResult = nID;
}
}
}
return FALSE;
}
LRESULT CPropertySheet::OnCommandHelp(WPARAM wParam, LPARAM lParam)
{
ASSERT_VALID(this);
CPropertyPage* pPage = GetActivePage();
ASSERT_VALID(pPage);
return AfxCallWndProc(pPage, pPage->m_hWnd, WM_COMMANDHELP, wParam, lParam);
}
HBRUSH CPropertySheet::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
LRESULT lResult;
if (pWnd->SendChildNotifyLastMsg(&lResult))
return (HBRUSH)lResult;
if (afxData.bWin4)
return CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
if (!GrayCtlColor(pDC->m_hDC, pWnd->GetSafeHwnd(), nCtlColor,
afxData.hbrBtnFace, afxData.clrBtnText))
return (HBRUSH)Default();
return afxData.hbrBtnFace;
}
/////////////////////////////////////////////////////////////////////////////
// CPropertySheet Diagnostics
#ifdef _DEBUG
void CPropertySheet::AssertValid() const
{
CWnd::AssertValid();
m_pages.AssertValid();
ASSERT(m_psh.dwSize == sizeof(m_psh));
ASSERT((m_psh.dwFlags & PSH_PROPSHEETPAGE) == PSH_PROPSHEETPAGE);
}
void CPropertySheet::Dump(CDumpContext& dc) const
{
CWnd::Dump(dc);
dc << "m_strCaption = " << m_strCaption << "\n";
dc << "Number of Pages = " << m_pages.GetSize() << "\n";
dc << "Stacked = " << m_bStacked << "\n";
dc << "Modeless = " << m_bModeless << "\n";
}
#endif //_DEBUG
////////////////////////////////////////////////////////////////////////////
// CPropertyPageEx -- one page of a tabbed dialog, extended for IE4 features
CPropertyPageEx::CPropertyPageEx(UINT nIDTemplate, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)
{
ASSERT(nIDTemplate != 0);
CommonConstruct(MAKEINTRESOURCE(nIDTemplate), nIDCaption, nIDHeaderTitle, nIDHeaderSubTitle);
}
CPropertyPageEx::CPropertyPageEx(LPCTSTR lpszTemplateName, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)
{
ASSERT(AfxIsValidString(lpszTemplateName));
CommonConstruct(lpszTemplateName, nIDCaption, nIDHeaderTitle, nIDHeaderSubTitle);
}
void CPropertyPageEx::Construct(UINT nIDTemplate, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)
{
ASSERT(nIDTemplate != 0);
CommonConstruct(MAKEINTRESOURCE(nIDTemplate), nIDCaption, nIDHeaderTitle, nIDHeaderSubTitle);
}
void CPropertyPageEx::Construct(LPCTSTR lpszTemplateName, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)
{
ASSERT(HIWORD(lpszTemplateName) == 0 ||
AfxIsValidString(lpszTemplateName));
CommonConstruct(lpszTemplateName, nIDCaption, nIDHeaderTitle, nIDHeaderSubTitle);
}
CPropertyPageEx::CPropertyPageEx()
{
CommonConstruct(NULL, 0, 0, 0);
}
void CPropertyPageEx::CommonConstruct(LPCTSTR lpszTemplateName, UINT nIDCaption, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle)
{
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 (nIDHeaderTitle != 0)
VERIFY(m_strHeaderTitle.LoadString(nIDHeaderTitle));
if (nIDHeaderSubTitle != 0)
VERIFY(m_strHeaderSubTitle.LoadString(nIDHeaderSubTitle));
if (AfxHelpEnabled())
m_psp.dwFlags |= PSP_HASHELP;
if (HIWORD(lpszTemplateName) == 0)
m_nIDHelp = LOWORD((DWORD)lpszTemplateName);
m_lpszTemplateName = m_psp.pszTemplate;
m_bFirstSetActive = TRUE;
}
#ifdef _DEBUG
void CPropertyPageEx::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 CPropertyPageEx::Dump(CDumpContext& dc) const
{
CDialog::Dump(dc);
dc << "m_strCaption = " << m_strCaption << "\n";
dc << "m_psp.dwFlags = " << m_psp.dwFlags << "\n";
dc << "m_strHeaderTitle = " << m_strHeaderTitle << "\n";
dc << "m_strHeaderSubTitle = " << m_strHeaderSubTitle << "\n";
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPropertySheetEx -- a tabbed "dialog" (really a popup-window), extended
// for IE4
CPropertySheetEx::CPropertySheetEx()
{
CommonConstruct(NULL, 0, NULL, NULL, NULL);
}
CPropertySheetEx::CPropertySheetEx(UINT nIDCaption, CWnd* pParentWnd,
UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,
HBITMAP hbmHeader)
{
ASSERT(nIDCaption != 0);
VERIFY(m_strCaption.LoadString(nIDCaption) != 0);
CommonConstruct(pParentWnd, iSelectPage, hbmWatermark, hpalWatermark, hbmHeader);
}
CPropertySheetEx::CPropertySheetEx(LPCTSTR pszCaption, CWnd* pParentWnd,
UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,
HBITMAP hbmHeader)
{
ASSERT(pszCaption != NULL);
m_strCaption = pszCaption;
CommonConstruct(pParentWnd, iSelectPage, hbmWatermark, hpalWatermark, hbmHeader);
}
void CPropertySheetEx::Construct(UINT nIDCaption, CWnd* pParentWnd,
UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,
HBITMAP hbmHeader)
{
ASSERT(nIDCaption != 0);
VERIFY(m_strCaption.LoadString(nIDCaption) != 0);
CommonConstruct(pParentWnd, iSelectPage, hbmWatermark, hpalWatermark, hbmHeader);
}
void CPropertySheetEx::Construct(LPCTSTR pszCaption, CWnd* pParentWnd,
UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,
HBITMAP hbmHeader)
{
ASSERT(pszCaption != NULL);
m_strCaption = pszCaption;
CommonConstruct(pParentWnd, iSelectPage, hbmWatermark, hpalWatermark, hbmHeader);
}
void CPropertySheetEx::CommonConstruct(CWnd* pParentWnd, UINT iSelectPage,
HBITMAP hbmWatermark, HPALETTE hpalWatermark, HBITMAP hbmHeader)
{
memset(&m_psh, 0, sizeof(m_psh));
m_psh.dwSize = sizeof(m_psh);
m_psh.dwFlags = PSH_PROPSHEETPAGE;
m_psh.pszCaption = m_strCaption;
m_psh.nStartPage = iSelectPage;
m_bStacked = TRUE;
m_bModeless = FALSE;
if (AfxHelpEnabled())
m_psh.dwFlags |= PSH_HASHELP;
if (hbmWatermark != NULL)
{
m_psh.hbmWatermark = hbmWatermark;
m_psh.dwFlags |= (PSH_USEHBMWATERMARK | PSH_WATERMARK);
}
if (hpalWatermark != NULL)
{
m_psh.hplWatermark = hpalWatermark;
m_psh.dwFlags |= PSH_USEHPLWATERMARK;
}
if (hbmHeader != NULL)
{
m_psh.hbmHeader = hbmHeader;
m_psh.dwFlags |= (PSH_USEHBMHEADER | PSH_HEADER);
}
m_pParentWnd = pParentWnd; // m_psh.hwndParent set in DoModal/create
}
void CPropertySheetEx::BuildPropPageArray()
{
// delete existing prop page array
delete[] (PROPSHEETPAGE*)m_psh.ppsp;
m_psh.ppsp = NULL;
// build new prop page array
PROPSHEETPAGE* ppsp = new PROPSHEETPAGE[m_pages.GetSize()];
m_psh.ppsp = (LPPROPSHEETPAGE)ppsp;
BOOL bWizard = (m_psh.dwFlags & (PSH_WIZARD | PSH_WIZARD97));
for (int i = 0; i < m_pages.GetSize(); i++)
{
CPropertyPage* pPage = GetPage(i);
memcpy(&ppsp[i], &pPage->m_psp, sizeof(pPage->m_psp));
ppsp[i].dwSize = sizeof(PROPSHEETPAGE);
if (pPage->IsKindOf(RUNTIME_CLASS(CPropertyPageEx)))
{
CPropertyPageEx* pPageEx = (CPropertyPageEx*)pPage;
if (!pPageEx->m_strHeaderTitle.IsEmpty())
{
ppsp[i].pszHeaderTitle = pPageEx->m_strHeaderTitle;
ppsp[i].dwFlags |= PSP_USEHEADERTITLE;
}
if (!pPageEx->m_strHeaderSubTitle.IsEmpty())
{
ppsp[i].pszHeaderSubTitle = pPageEx->m_strHeaderSubTitle;
ppsp[i].dwFlags |= PSP_USEHEADERSUBTITLE;
}
}
pPage->PreProcessPageTemplate(ppsp[i], bWizard);
}
m_psh.nPages = m_pages.GetSize();
}
CPropertySheetEx::~CPropertySheetEx()
{
delete[] (PROPSHEETPAGE*)m_psh.ppsp;
}
void CPropertySheetEx::AddPage(CPropertyPageEx* pPage)
{
ASSERT_VALID(this);
ASSERT(pPage != NULL);
ASSERT_KINDOF(CPropertyPageEx, pPage);
ASSERT_VALID(pPage);
// add page to internal list
m_pages.Add(pPage);
// add page externally
if (m_hWnd != NULL)
{
// build new prop page array
PROPSHEETPAGE *ppsp = new PROPSHEETPAGE[m_pages.GetSize()];
memcpy(ppsp, m_psh.ppsp, sizeof(PROPSHEETPAGE) * (m_pages.GetSize()-1));
delete[] (PROPSHEETPAGE*)m_psh.ppsp;
m_psh.ppsp = ppsp;
ppsp += m_pages.GetSize()-1;
memcpy(ppsp, &pPage->m_psp, sizeof(pPage->m_psp));
pPage->PreProcessPageTemplate(*ppsp, IsWizard());
if (!pPage->m_strHeaderTitle.IsEmpty())
{
ppsp->pszHeaderTitle = pPage->m_strHeaderTitle;
ppsp->dwFlags |= PSP_USEHEADERTITLE;
}
if (!pPage->m_strHeaderSubTitle.IsEmpty())
{
ppsp->pszHeaderSubTitle = pPage->m_strHeaderSubTitle;
ppsp->dwFlags |= PSP_USEHEADERSUBTITLE;
}
HPROPSHEETPAGE hPSP = CreatePropertySheetPage(ppsp);
if (hPSP == NULL)
AfxThrowMemoryException();
if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP))
{
DestroyPropertySheetPage(hPSP);
AfxThrowMemoryException();
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CPropertySheetEx Diagnostics
#ifdef _DEBUG
void CPropertySheetEx::AssertValid() const
{
CWnd::AssertValid();
m_pages.AssertValid();
ASSERT(m_psh.dwSize == sizeof(m_psh));
ASSERT((m_psh.dwFlags & PSH_PROPSHEETPAGE) == PSH_PROPSHEETPAGE);
}
void CPropertySheetEx::Dump(CDumpContext& dc) const
{
CWnd::Dump(dc);
dc << "m_strCaption = " << m_strCaption << "\n";
dc << "Number of Pages = " << m_pages.GetSize() << "\n";
dc << "Stacked = " << m_bStacked << "\n";
dc << "Modeless = " << m_bModeless << "\n";
}
#endif //_DEBUG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CPropertyPage, CDialog)
IMPLEMENT_DYNAMIC(CPropertySheet, CWnd)
IMPLEMENT_DYNAMIC(CPropertyPageEx, CPropertyPage)
IMPLEMENT_DYNAMIC(CPropertySheetEx, CPropertySheet)
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -