📄 ctlppg.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"
#ifdef AFXCTL_PAGE_SEG
#pragma code_seg(AFXCTL_PAGE_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#define MAX_CLASS_NAME 100
struct NotifyInfo
{
LPCTSTR szClassName; // Name of control's class
WORD wNotifyCode; // Notification code
};
#define MAX_TEXT 1024
BEGIN_INTERFACE_MAP(COlePropertyPage, CDialog)
INTERFACE_PART(COlePropertyPage, IID_IPropertyPage2, PropertyPage)
INTERFACE_PART(COlePropertyPage, IID_IPropertyPage, PropertyPage)
END_INTERFACE_MAP()
BEGIN_MESSAGE_MAP(COlePropertyPage, CDialog)
//{{AFX_MSG_MAP(COlePropertyPage)
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
#ifndef _AFX_NO_CTL3D_SUPPORT
ON_MESSAGE(WM_QUERY3DCONTROLS, OnQuery3dControls)
#endif
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// AFX_DDPDATA
struct AFX_DDPDATA : public CObject
{
AFX_DDPDATA(LPVOID lpHandler, int nCtrlId, BOOL bEditCtrl, LPVOID lpMember,
UINT nType, LPCTSTR lpszOleName);
LPVOID m_lpHandler;
int m_nCtrlId;
BOOL m_bEditCtrl;
LPVOID m_lpMember;
UINT m_nType;
LPCTSTR m_lpszOleName;
};
AFX_DDPDATA::AFX_DDPDATA(LPVOID lpHandler, int nCtrlId, BOOL bEditCtrl,
LPVOID lpMember, UINT nType, LPCTSTR lpszOleName) :
m_lpHandler(lpHandler),
m_nCtrlId(nCtrlId),
m_bEditCtrl(bEditCtrl),
m_lpMember(lpMember),
m_nType(nType),
m_lpszOleName(lpszOleName)
{
}
/////////////////////////////////////////////////////////////////////////////
// cleanup helper function
AFX_STATIC void AFXAPI _AfxCleanupDDPs(CPtrArray& arrayDDP)
{
int cDDP = arrayDDP.GetSize();
for (int i = 0; i < cDDP; i++)
{
ASSERT(arrayDDP[i] != NULL);
delete (AFX_DDPDATA*)(arrayDDP[i]);
}
arrayDDP.RemoveAll();
}
/////////////////////////////////////////////////////////////////////////////
// page validation helper function (debug only)
#ifdef _DEBUG
void _ValidatePageDialog(CDialogTemplate& dt, CString& strPage,
COlePropertyPage* pPage)
{
if (GetSystemMetrics(SM_DBCSENABLED))
return;
// Only display the message boxes the first time a page is shown.
#ifdef _DEBUG
BOOL bEnable = AfxEnableMemoryTracking(FALSE);
#endif
static CPtrList _classList;
BOOL bMessageBox = FALSE;
CRuntimeClass* pClass = pPage->GetRuntimeClass();
if (_classList.Find(pClass) == NULL)
{
bMessageBox = TRUE;
_classList.AddHead(pClass);
}
#ifdef _DEBUG
AfxEnableMemoryTracking(bEnable);
#endif
SIZE sizeDLU;
CString strFontName;
WORD wFontSize;
LPTSTR pszTmp;
dt.GetSizeInDialogUnits(&sizeDLU);
dt.GetFont(strFontName, wFontSize);
if ((sizeDLU.cx != 250) || ((sizeDLU.cy != 62) && (sizeDLU.cy != 110)))
{
pszTmp = new TCHAR[strPage.GetLength() + 128];
wsprintf(pszTmp, _T("Property page '%s' has nonstandard dimensions."),
(LPCTSTR)strPage);
TRACE1("Warning: %s\n", pszTmp);
if (bMessageBox)
{
lstrcat(pszTmp,
_T(" Dimensions should be 250x62 or 250x110 dialog units."));
pPage->MessageBox(pszTmp, _T("Property page warning"),
MB_ICONEXCLAMATION);
}
delete [] pszTmp;
}
if ((wFontSize != 8) ||
(strFontName != _T("MS Sans Serif") && strFontName != _T("Helv") &&
strFontName != _T("MS Shell Dlg")))
{
pszTmp = new TCHAR[strPage.GetLength() + 128];
wsprintf(pszTmp, _T("Property page '%s' uses a nonstandard font."),
(LPCTSTR)strPage);
TRACE1("Warning: %s\n", pszTmp);
if (bMessageBox)
{
lstrcat(pszTmp, _T(" Font should be MS Sans Serif 8."));
pPage->MessageBox(pszTmp, _T("Property page warning"),
MB_ICONEXCLAMATION);
}
delete [] pszTmp;
}
}
#endif // _DEBUG
/////////////////////////////////////////////////////////////////////////////
// COlePropertyPage::COlePropertyPage
COlePropertyPage::COlePropertyPage(UINT idDlg, UINT idCaption) :
#ifdef _DEBUG
m_bNonStandardSize(FALSE),
#endif
m_bDirty(FALSE),
m_idCaption(idCaption),
m_idDlg(idDlg),
m_pPageSite(NULL),
m_ppDisp(NULL),
m_pAdvisors(NULL),
m_bPropsChanged(FALSE),
m_nObjects(0),
m_bInitializing(TRUE),
m_nControls(0),
m_pStatus(NULL),
m_hDialog(NULL),
m_dwHelpContext(0)
{
// m_lpDialogTemplate is needed later by CWnd::ExecuteDlgInit
m_lpszTemplateName = MAKEINTRESOURCE(m_idDlg);
// Keep this DLL loaded at least until this object is deleted.
AfxOleLockApp();
}
void COlePropertyPage::OnSetPageSite()
{
// Load the caption from resources
CString strCaption;
if (!strCaption.LoadString(m_idCaption))
strCaption.LoadString(AFX_IDS_PROPPAGE_UNKNOWN);
SetPageName(strCaption);
// Try to load the dialog resource template into memory and get its size
m_sizePage.cx = 0;
m_sizePage.cy = 0;
CDialogTemplate dt;
dt.Load(MAKEINTRESOURCE(m_idDlg));
#ifdef _DEBUG
if (!m_bNonStandardSize)
_ValidatePageDialog(dt, strCaption, this);
#endif
// If no font specified, set the system font.
BOOL bSetSysFont = !dt.HasFont();
CString strFace;
WORD wSize;
// On DBCS systems, also change "MS Sans Serif" or "Helv" to system font.
if ((!bSetSysFont) && GetSystemMetrics(SM_DBCSENABLED))
{
CString strFace;
dt.GetFont(strFace, wSize);
bSetSysFont = (strFace == _T("MS Shell Dlg") ||
strFace == _T("MS Sans Serif") || strFace == _T("Helv"));
}
// Here is where we actually set the font.
if (bSetSysFont && AfxGetPropSheetFont(strFace, wSize, FALSE))
dt.SetFont(strFace, wSize);
dt.GetSizeInPixels(&m_sizePage);
m_hDialog = dt.Detach();
}
BOOL COlePropertyPage::OnInitDialog()
{
CDialog::OnInitDialog();
return 0;
}
BOOL COlePropertyPage::PreTranslateMessage(LPMSG lpMsg)
{
// Don't let CDialog process the Return key or Escape key.
if ((lpMsg->message == WM_KEYDOWN) &&
((lpMsg->wParam == VK_RETURN) || (lpMsg->wParam == VK_ESCAPE)))
{
// Special case: if control with focus is an edit control with
// ES_WANTRETURN style, let it handle the Return key.
TCHAR szClass[10];
CWnd* pWndFocus = GetFocus();
if ((lpMsg->wParam == VK_RETURN) &&
((pWndFocus = GetFocus()) != NULL) &&
IsChild(pWndFocus) &&
(pWndFocus->GetStyle() & ES_WANTRETURN) &&
GetClassName(pWndFocus->m_hWnd, szClass, 10) &&
(lstrcmpi(szClass, _T("EDIT")) == 0))
{
pWndFocus->SendMessage(WM_CHAR, lpMsg->wParam, lpMsg->lParam);
return TRUE;
}
return FALSE;
}
// If it's a WM_SYSKEYDOWN, temporarily replace the hwnd in the
// message with the hwnd of our first control, and try to handle
// the message for ourselves.
BOOL bHandled;
if ((lpMsg->message == WM_SYSKEYDOWN) && !::IsChild(m_hWnd, lpMsg->hwnd))
{
HWND hWndSave = lpMsg->hwnd;
lpMsg->hwnd = ::GetWindow(m_hWnd, GW_CHILD);
bHandled = CDialog::PreTranslateMessage(lpMsg);
lpMsg->hwnd = hWndSave;
}
else
{
bHandled = CDialog::PreTranslateMessage(lpMsg);
}
return bHandled;
}
void COlePropertyPage::CleanupObjectArray()
{
if (m_pAdvisors)
{
for (ULONG nObject = 0; nObject < m_nObjects; nObject++)
AfxConnectionUnadvise(m_ppDisp[nObject], IID_IPropertyNotifySink,
&m_xPropNotifySink, FALSE, m_pAdvisors[nObject]);
delete [] m_pAdvisors;
m_pAdvisors = NULL;
}
if (m_ppDisp)
{
for (ULONG nObject = 0; nObject < m_nObjects; nObject++)
RELEASE(m_ppDisp[nObject]);
delete [] m_ppDisp;
m_ppDisp = NULL;
}
}
COlePropertyPage::~COlePropertyPage()
{
// Remember to free the resource we loaded!
if (m_hDialog != NULL)
GlobalFree(m_hDialog);
if (m_pStatus != NULL)
{
delete [] m_pStatus;
m_pStatus = NULL;
}
// Clean out any leftovers in the DDP map.
_AfxCleanupDDPs(m_arrayDDP);
RELEASE(m_pPageSite);
CleanupObjectArray();
AfxOleUnlockApp();
}
void COlePropertyPage::OnFinalRelease()
{
if (m_hWnd != NULL)
DestroyWindow();
delete this;
}
LRESULT COlePropertyPage::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE(m_pModuleState);
// Forward WM_SYSCOMMAND messages to the frame for translation
if (msg == WM_SYSCOMMAND && (wParam & 0xFFF0) != SC_KEYMENU && m_pPageSite != NULL)
{
if (m_pPageSite->TranslateAccelerator((LPMSG)GetCurrentMessage())
== S_OK)
{
return 0;
}
}
return CDialog::WindowProc(msg, wParam, lParam);
}
HBRUSH COlePropertyPage::OnCtlColor(CDC*, CWnd* pWnd, UINT)
{
// allow the control itself first crack at the color
LRESULT lResult;
if (pWnd->SendChildNotifyLastMsg(&lResult))
return (HBRUSH)lResult;
// allow the parent window to determine the color
HWND hParent = ::GetParent(m_hWnd);
const MSG* pMsg = GetCurrentMessage();
HBRUSH hResult = (HBRUSH)::SendMessage(hParent,
pMsg->message, pMsg->wParam, pMsg->lParam);
// use default if parent returns NULL
if (hResult == NULL)
hResult = (HBRUSH)Default();
return hResult;
}
BOOL COlePropertyPage::OnHelp(LPCTSTR)
{
// May be overridden by subclass.
return FALSE;
}
BOOL COlePropertyPage::OnEditProperty(DISPID)
{
// May be overridden by subclass.
return FALSE;
}
void COlePropertyPage::OnObjectsChanged()
{
// May be overridden by subclass.
}
LPDISPATCH* COlePropertyPage::GetObjectArray(ULONG* pnObjects)
{
ASSERT_POINTER(pnObjects, ULONG);
if (pnObjects != NULL)
*pnObjects = m_nObjects;
return m_ppDisp;
}
void COlePropertyPage::SetModifiedFlag(BOOL bModified)
{
if (!bModified)
m_bPropsChanged = FALSE;
if ((m_bDirty && !bModified) || (!m_bDirty && bModified))
{
m_bDirty = bModified;
if (m_pPageSite != NULL)
{
DWORD flags = 0;
if (bModified)
flags |= PROPPAGESTATUS_DIRTY;
m_pPageSite->OnStatusChange(flags);
}
}
}
BOOL COlePropertyPage::IsModified()
{
return m_bDirty;
}
void COlePropertyPage::SetPageName(LPCTSTR lpszPageName)
{
ASSERT(AfxIsValidString(lpszPageName));
m_strPageName = lpszPageName;
}
void COlePropertyPage::SetDialogResource(HGLOBAL hDialog)
{
if (m_hDialog != NULL)
{
GlobalFree(m_hDialog);
m_hDialog = NULL;
}
CDialogTemplate dt(hDialog);
#ifdef _DEBUG
_ValidatePageDialog(dt, m_strPageName, this);
#endif
dt.GetSizeInPixels(&m_sizePage);
m_hDialog = dt.Detach();
}
void COlePropertyPage::SetHelpInfo(LPCTSTR lpszDocString,
LPCTSTR lpszHelpFile, DWORD dwHelpContext)
{
ASSERT((lpszDocString == NULL) || AfxIsValidString(lpszDocString));
ASSERT((lpszHelpFile == NULL) || AfxIsValidString(lpszHelpFile));
m_strDocString = lpszDocString;
m_strHelpFile = lpszHelpFile;
m_dwHelpContext = dwHelpContext;
}
LPPROPERTYPAGESITE COlePropertyPage::GetPageSite()
{
return m_pPageSite;
}
int COlePropertyPage::MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption,
UINT nType)
{
// use caption of page by default
if (lpszCaption == NULL)
lpszCaption = m_strPageName;
// start message box on safe owner of the page
return ::MessageBox(GetSafeOwner_(m_hWnd, NULL), lpszText, lpszCaption, nType);
}
/////////////////////////////////////////////////////////////////////////////
// COlePropertyPage::XPropertyPage
STDMETHODIMP_(ULONG) COlePropertyPage::XPropertyPage::AddRef()
{
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COlePropertyPage::XPropertyPage::Release()
{
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP COlePropertyPage::XPropertyPage::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -