📄 ctlppg.cpp
字号:
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP COlePropertyPage::XPropertyPage::SetPageSite(
LPPROPERTYPAGESITE pPageSite)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
ASSERT_NULL_OR_POINTER(pPageSite, IPropertyPageSite);
RELEASE(pThis->m_pPageSite); // release the old one
pThis->m_pPageSite = pPageSite;
if (pPageSite != NULL)
{
pThis->m_pPageSite->AddRef(); // Bump the reference count
pThis->OnSetPageSite();
}
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::Activate(HWND hWndParent,
LPCRECT pRect, BOOL)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
ASSERT_NULL_OR_POINTER(pRect, RECT);
BOOL bSuccess = FALSE; // Did we successfully create the dialog box
if (pThis->m_hDialog != NULL)
{
// We've already loaded the dialog template into memory so just
// create it!
void* lpDialogTemplate = LockResource(pThis->m_hDialog);
if (lpDialogTemplate != NULL)
{
bSuccess = pThis->CreateIndirect(lpDialogTemplate, CWnd::FromHandle(hWndParent));
UnlockResource(pThis->m_hDialog);
}
else
bSuccess = pThis->Create(pThis->m_idDlg, CWnd::FromHandle(hWndParent));
}
else
bSuccess = pThis->Create(pThis->m_idDlg, CWnd::FromHandle(hWndParent));
// Were we successful in creating the dialog box!
if (bSuccess)
{
pThis->MoveWindow(pRect); // Force page to fill area given by frame *
pThis->m_bInitializing = TRUE;
pThis->UpdateData(FALSE);
pThis->SetModifiedFlag(FALSE);
pThis->m_bInitializing = FALSE;
if (pThis->m_pStatus != NULL)
{
delete [] pThis->m_pStatus;
pThis->m_pStatus = NULL;
}
pThis->m_nControls = 0;
::EnumChildWindows(pThis->GetSafeHwnd(), (WNDENUMPROC) COlePropertyPage::EnumChildProc, (LPARAM) pThis);
if (pThis->m_nControls > 0)
pThis->m_pStatus = new AFX_PPFIELDSTATUS [UINT(pThis->m_nControls)];
pThis->m_nControls = 0;
EnumChildWindows(pThis->GetSafeHwnd(), (WNDENUMPROC) COlePropertyPage::EnumControls, (LPARAM) pThis);
return S_OK;
}
return E_FAIL;
}
BOOL CALLBACK COlePropertyPage::EnumChildProc(HWND, LPARAM lParam)
{
COlePropertyPage* pDlg = (COlePropertyPage*) lParam;
ASSERT_POINTER(pDlg, COlePropertyPage);
pDlg->m_nControls++;
return TRUE;
}
BOOL CALLBACK COlePropertyPage::EnumControls(HWND hWnd, LPARAM lParam)
{
COlePropertyPage* pDlg = (COlePropertyPage*) lParam;
ASSERT_POINTER(pDlg, COlePropertyPage);
ASSERT(pDlg->m_pStatus != NULL);
pDlg->m_pStatus[pDlg->m_nControls].nID = (UINT)::GetDlgCtrlID(hWnd);
pDlg->m_pStatus[pDlg->m_nControls].bDirty = FALSE;
pDlg->m_nControls++;
return TRUE;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::Deactivate()
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
pThis->DestroyWindow();
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::GetPageInfo(
LPPROPPAGEINFO pPageInfo)
{
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
ASSERT_POINTER(pPageInfo, PROPPAGEINFO);
pPageInfo->pszTitle = AfxAllocTaskOleString(pThis->m_strPageName);
pPageInfo->size = pThis->m_sizePage;
pPageInfo->pszDocString = AfxAllocTaskOleString(pThis->m_strDocString);
pPageInfo->pszHelpFile = AfxAllocTaskOleString(pThis->m_strHelpFile);
pPageInfo->dwHelpContext = pThis->m_dwHelpContext;
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::SetObjects(
ULONG cObjects, LPUNKNOWN* ppUnk)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
pThis->CleanupObjectArray();
if (cObjects != 0)
{
ASSERT(AfxIsValidAddress(ppUnk, sizeof(LPUNKNOWN) * (int)cObjects, FALSE));
pThis->m_ppDisp = new LPDISPATCH [(UINT)cObjects];
pThis->m_pAdvisors = new DWORD [(UINT)cObjects];
for (ULONG nObject = 0; nObject < cObjects; nObject++)
{
HRESULT hr = ppUnk[nObject]->QueryInterface(IID_IDispatch,
(VOID**)&(pThis->m_ppDisp[nObject]));
if (SUCCEEDED(hr))
{
AfxConnectionAdvise(ppUnk[nObject], IID_IPropertyNotifySink,
&pThis->m_xPropNotifySink, FALSE,
&pThis->m_pAdvisors[nObject]);
}
else
{
return hr;
}
}
}
pThis->m_nObjects = cObjects;
// No painting during the data update.
BOOL bLock = (pThis->m_hWnd != NULL) && pThis->IsWindowVisible();
if (bLock)
::LockWindowUpdate(pThis->m_hWnd);
pThis->OnObjectsChanged();
// If window exists, update the data in its fields.
if (cObjects != 0 && pThis->m_hWnd != NULL)
{
pThis->UpdateData(FALSE);
pThis->SetModifiedFlag(FALSE);
}
if (bLock)
::LockWindowUpdate(NULL);
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::Show(UINT nCmdShow)
{
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
pThis->ShowWindow(nCmdShow);
if (nCmdShow == SW_SHOWNORMAL)
pThis->SetFocus();
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::Move(LPCRECT pRect)
{
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
ASSERT_POINTER(pRect, RECT);
pThis->MoveWindow(pRect);
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::IsPageDirty()
{
METHOD_PROLOGUE_EX_(COlePropertyPage, PropertyPage)
return pThis->m_bDirty ? S_OK : S_FALSE;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::Apply()
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
HRESULT hr = S_OK;
BOOL bClean = FALSE;
if (pThis->m_bDirty)
{
if (pThis->UpdateData(TRUE))
{
pThis->m_bDirty = FALSE;
bClean = TRUE;
}
else
hr = E_FAIL;
if (pThis->m_bPropsChanged)
{
pThis->UpdateData(FALSE);
pThis->m_bPropsChanged = FALSE;
bClean = TRUE;
}
if (bClean)
{
// Set the dirty status of all the controls on this page to FALSE.
if (pThis->m_pStatus != NULL)
{
for (int nControl = 0; nControl < pThis->m_nControls; nControl++)
pThis->m_pStatus[nControl].bDirty = FALSE;
}
}
}
else
ASSERT(!pThis->m_bPropsChanged);
return hr;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::Help(LPCOLESTR lpszHelpDir)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
ASSERT((lpszHelpDir == NULL) || AfxIsValidString(lpszHelpDir));
USES_CONVERSION;
if (!pThis->OnHelp(OLE2CT(lpszHelpDir)))
return S_FALSE;
else
return S_OK;
}
BOOL AFXAPI _AfxAtEndOfTabList(CDialog* pDlg, UINT nCmd)
{
if ((pDlg->SendMessage(WM_GETDLGCODE) &
(DLGC_WANTALLKEYS | DLGC_WANTMESSAGE | DLGC_WANTTAB)) == 0)
{
CWnd* pCtl = CWnd::GetFocus();
if (pDlg->IsChild(pCtl))
{
// Get top level child for controls with children, like combo.
while (pCtl->GetParent() != pDlg)
{
pCtl = pCtl->GetParent();
ASSERT_VALID(pCtl);
}
do
{
if ((pCtl = pCtl->GetWindow(nCmd)) == NULL)
return TRUE;
}
while ((pCtl->GetStyle() & (WS_DISABLED | WS_TABSTOP)) != WS_TABSTOP);
}
}
return FALSE;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::TranslateAccelerator(LPMSG lpMsg)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
ASSERT_POINTER(lpMsg, MSG);
BOOL bHandled = FALSE;
if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_TAB &&
GetKeyState(VK_CONTROL) >= 0)
{
if (pThis->IsChild(CWnd::GetFocus()))
{
// We already have the focus. Let's determine whether we should
// pass focus up to the frame.
if (_AfxAtEndOfTabList(pThis, GetKeyState(VK_SHIFT) < 0 ?
GW_HWNDPREV : GW_HWNDNEXT))
{
// fix for default button border
DWORD dwDefID = pThis->GetDefID();
if (HIWORD(dwDefID) == DC_HASDEFID)
{
CWnd *pDefBtn = pThis->GetDlgItem(LOWORD(dwDefID));
if (pDefBtn != NULL && pDefBtn->IsWindowEnabled())
pThis->GotoDlgCtrl(pDefBtn);
}
// Pass focus to the frame by letting the page site handle
// this message.
if (pThis->m_pPageSite != NULL)
bHandled =
pThis->m_pPageSite->TranslateAccelerator(lpMsg) ==
S_OK;
}
}
else
{
// We don't already have the focus. The frame is passing the
// focus to us.
CWnd* pWnd = pThis->GetTopWindow();
if (pWnd != NULL)
{
UINT gwInit;
UINT gwMove;
if (GetKeyState(VK_SHIFT) >= 0)
{
// Set the focus to the first tabstop in the page.
gwInit = GW_HWNDFIRST;
gwMove = GW_HWNDNEXT;
}
else
{
// Set the focus to the last tabstop in the page.
gwInit = GW_HWNDLAST;
gwMove = GW_HWNDPREV;
}
pWnd = pWnd->GetWindow(gwInit);
while (pWnd != NULL)
{
if ((pWnd->GetStyle() & (WS_DISABLED | WS_TABSTOP)) ==
WS_TABSTOP)
{
pThis->GotoDlgCtrl(pWnd);
bHandled = TRUE;
break;
}
pWnd = pWnd->GetWindow(gwMove);
}
}
}
}
// If message was not handled here, call PreTranslateMessage
return (bHandled || pThis->PreTranslateMessage(lpMsg)) ?
S_OK : S_FALSE;
}
STDMETHODIMP COlePropertyPage::XPropertyPage::EditProperty(DISPID dispid)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropertyPage)
ASSERT_VALID(pThis);
return pThis->OnEditProperty(dispid) ? S_OK : E_NOTIMPL;
}
/////////////////////////////////////////////////////////////////////////////
// COlePropertyPage::XPropNotifySink
STDMETHODIMP_(ULONG) COlePropertyPage::XPropNotifySink::AddRef()
{
return 1;
}
STDMETHODIMP_(ULONG) COlePropertyPage::XPropNotifySink::Release()
{
return 0;
}
STDMETHODIMP COlePropertyPage::XPropNotifySink::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
if (IsEqualIID(iid, IID_IPropertyNotifySink) ||
IsEqualIID(iid, IID_IUnknown))
{
*ppvObj = this;
return S_OK;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
}
STDMETHODIMP COlePropertyPage::XPropNotifySink::OnRequestEdit(DISPID)
{
return S_OK;
}
STDMETHODIMP COlePropertyPage::XPropNotifySink::OnChanged(DISPID)
{
METHOD_PROLOGUE_EX(COlePropertyPage, PropNotifySink)
// If we're not currently in the middle of an UpdateData, call it now.
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThis->m_hWnd != NULL &&
pThreadState->m_hLockoutNotifyWindow != pThis->m_hWnd)
{
pThis->UpdateData(FALSE);
}
else
{
pThis->m_bPropsChanged = TRUE;
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// Handle control notifications
AFX_STATIC_DATA const NotifyInfo _afxNotifyList[] = {
{ _T("edit"), EN_CHANGE },
{ _T("button"), BN_CLICKED },
{ _T("button"), BN_DOUBLECLICKED },
{ _T("combobox"), CBN_EDITCHANGE },
{ _T("combobox"), CBN_SELCHANGE },
{ _T("listbox"), LBN_SELCHANGE },
};
AFX_STATIC_DATA const NotifyInfo _afxUpdateList[] = {
{ _T("edit"), EN_KILLFOCUS },
{ _T("button"), BN_CLICKED },
{ _T("button"), BN_DOUBLECLICKED },
{ _T("combobox"), CBN_SELCHANGE },
{ _T("combobox"), CBN_KILLFOCUS },
{ _T("listbox"), LBN_SELCHANGE },
};
BOOL AFXAPI _AfxIsRadioButton(HWND hWnd)
{
DWORD dwButtonStyle = GetWindowLong(hWnd, GWL_STYLE) & 0x0000000FL;
return ((dwButtonStyle == BS_RADIOBUTTON) ||
(dwButtonStyle == BS_AUTORADIOBUTTON));
}
BOOL COlePropertyPage::OnCommand(WPARAM wParam, LPARAM lParam)
{
// Let the base class process the message first
BOOL bSuccess = CDialog::OnCommand(wParam, lParam);
// Are we just initializing the dialog box, or do we have no objects?
if (m_bInitializing || m_ppDisp == NULL)
return bSuccess;
UINT nID = (UINT)LOWORD(wParam);
HWND hWndCtl = (HWND)lParam;
WORD wNotifyCode = HIWORD(wParam);
DWORD flags = 0;
if (hWndCtl != NULL)
{
BOOL bIgnoreControl = FALSE;
for (int count = 0; count < m_IDArray.GetSize(); count++)
{
UINT nNotID = m_IDArray.GetAt(count);
if (nID == nNotID)
bIgnoreControl = TRUE;
}
if ( !bIgnoreControl )
{
TCHAR szClassName[MAX_CLASS_NAME];
// We have a control message - check type of control and message
::GetClassName(hWndCtl, (LPTSTR)szClassName, MAX_CLASS_NAME);
for (int iNotify = 0; iNotify < _countof(_afxNotifyList); iNotify++)
{
if (lstrcmpi(_afxNotifyList[iNotify].szClassName, szClassName) == 0
&& _afxNotifyList[iNotify].wNotifyCode == wNotifyCode )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -