📄 cmdtarg.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_CORE1_SEG
#pragma code_seg(AFX_CORE1_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// CCmdTarget construction/destruction
CCmdTarget::CCmdTarget()
{
// capture module state where object was constructed
#ifdef _AFXDLL
m_pModuleState = AfxGetModuleState();
ASSERT(m_pModuleState != NULL);
#endif
// initialize state
#ifndef _AFX_NO_OLE_SUPPORT
m_dwRef = 1;
m_pOuterUnknown = NULL;
m_xInnerUnknown = 0;
m_xDispatch.m_vtbl = 0;
m_bResultExpected = TRUE;
m_xConnPtContainer.m_vtbl = 0;
#endif
}
CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
if (m_xDispatch.m_vtbl != 0)
((COleDispatchImpl*)&m_xDispatch)->Disconnect();
ASSERT(m_dwRef <= 1);
#endif
#ifdef _AFXDLL
m_pModuleState = NULL;
#endif
}
/////////////////////////////////////////////////////////////////////////////
// CCmdTarget windows message dispatching
AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,
AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo)
// return TRUE to stop routing
{
ASSERT_VALID(pTarget);
UNUSED(nCode); // unused in release builds
union MessageMapFunctions mmf;
mmf.pfn = pfn;
BOOL bResult = TRUE; // default is ok
if (pHandlerInfo != NULL)
{
// just fill in the information, don't do it
pHandlerInfo->pTarget = pTarget;
pHandlerInfo->pmf = mmf.pfn;
return TRUE;
}
switch (nSig)
{
case AfxSig_vv:
// normal command or control notification
ASSERT(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
ASSERT(pExtra == NULL);
(pTarget->*mmf.pfn_COMMAND)();
break;
case AfxSig_bv:
// normal command or control notification
ASSERT(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
ASSERT(pExtra == NULL);
bResult = (pTarget->*mmf.pfn_bCOMMAND)();
break;
case AfxSig_vw:
// normal command or control notification in a range
ASSERT(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
ASSERT(pExtra == NULL);
(pTarget->*mmf.pfn_COMMAND_RANGE)(nID);
break;
case AfxSig_bw:
// extended command (passed ID, returns bContinue)
ASSERT(pExtra == NULL);
bResult = (pTarget->*mmf.pfn_COMMAND_EX)(nID);
break;
case AfxSig_vNMHDRpl:
{
AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
ASSERT(pNotify != NULL);
ASSERT(pNotify->pResult != NULL);
ASSERT(pNotify->pNMHDR != NULL);
(pTarget->*mmf.pfn_NOTIFY)(pNotify->pNMHDR, pNotify->pResult);
}
break;
case AfxSig_bNMHDRpl:
{
AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
ASSERT(pNotify != NULL);
ASSERT(pNotify->pResult != NULL);
ASSERT(pNotify->pNMHDR != NULL);
bResult = (pTarget->*mmf.pfn_bNOTIFY)(pNotify->pNMHDR, pNotify->pResult);
}
break;
case AfxSig_vwNMHDRpl:
{
AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
ASSERT(pNotify != NULL);
ASSERT(pNotify->pResult != NULL);
ASSERT(pNotify->pNMHDR != NULL);
(pTarget->*mmf.pfn_NOTIFY_RANGE)(nID, pNotify->pNMHDR,
pNotify->pResult);
}
break;
case AfxSig_bwNMHDRpl:
{
AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
ASSERT(pNotify != NULL);
ASSERT(pNotify->pResult != NULL);
ASSERT(pNotify->pNMHDR != NULL);
bResult = (pTarget->*mmf.pfn_NOTIFY_EX)(nID, pNotify->pNMHDR,
pNotify->pResult);
}
break;
case AfxSig_cmdui:
{
// ON_UPDATE_COMMAND_UI or ON_UPDATE_COMMAND_UI_REFLECT case
ASSERT(CN_UPDATE_COMMAND_UI == (UINT)-1);
ASSERT(nCode == CN_UPDATE_COMMAND_UI || nCode == 0xFFFF);
ASSERT(pExtra != NULL);
CCmdUI* pCmdUI = (CCmdUI*)pExtra;
ASSERT(!pCmdUI->m_bContinueRouting); // idle - not set
(pTarget->*mmf.pfn_UPDATE_COMMAND_UI)(pCmdUI);
bResult = !pCmdUI->m_bContinueRouting;
pCmdUI->m_bContinueRouting = FALSE; // go back to idle
}
break;
case AfxSig_cmduiw:
{
// ON_UPDATE_COMMAND_UI case
ASSERT(nCode == CN_UPDATE_COMMAND_UI);
ASSERT(pExtra != NULL);
CCmdUI* pCmdUI = (CCmdUI*)pExtra;
ASSERT(pCmdUI->m_nID == nID); // sanity assert
ASSERT(!pCmdUI->m_bContinueRouting); // idle - not set
(pTarget->*mmf.pfn_UPDATE_COMMAND_UI_RANGE)(pCmdUI, nID);
bResult = !pCmdUI->m_bContinueRouting;
pCmdUI->m_bContinueRouting = FALSE; // go back to idle
}
break;
// general extensibility hooks
case AfxSig_vpv:
(pTarget->*mmf.pfn_OTHER)(pExtra);
break;
case AfxSig_bpv:
bResult = (pTarget->*mmf.pfn_OTHER_EX)(pExtra);
break;
default: // illegal
ASSERT(FALSE);
return 0;
}
return bResult;
}
// compare two pointers to GUIDs -- TRUE if both pointers are NULL
// or both pointers point to same GUID; FALSE otherwise
#define IsEqualNULLGuid(pGuid1, pGuid2) \
(((pGuid1) == NULL && (pGuid2) == NULL) || \
((pGuid1) != NULL && (pGuid2) != NULL && \
IsEqualGUID(*(pGuid1), *(pGuid2))))
BOOL CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
#ifndef _AFX_NO_OCC_SUPPORT
// OLE control events are a special case
if (nCode == CN_EVENT)
{
ASSERT(afxOccManager != NULL);
return afxOccManager->OnEvent(this, nID, (AFX_EVENT*)pExtra, pHandlerInfo);
}
#endif // !_AFX_NO_OCC_SUPPORT
// determine the message number and code (packed into nCode)
const AFX_MSGMAP* pMessageMap;
const AFX_MSGMAP_ENTRY* lpEntry;
UINT nMsg = 0;
#ifndef _AFX_NO_DOCOBJECT_SUPPORT
if (nCode == CN_OLECOMMAND)
{
BOOL bResult = FALSE;
const AFX_OLECMDMAP* pOleCommandMap;
const AFX_OLECMDMAP_ENTRY* pEntry;
COleCmdUI* pUI = (COleCmdUI*) pExtra;
const GUID* pguidCmdGroup = pUI->m_pguidCmdGroup;
#ifdef _AFXDLL
for (pOleCommandMap = GetCommandMap(); pOleCommandMap != NULL && !bResult;
pOleCommandMap = pOleCommandMap->pfnGetBaseMap())
#else
for (pOleCommandMap = GetCommandMap(); pOleCommandMap != NULL && !bResult;
pOleCommandMap = pOleCommandMap->pBaseMap)
#endif
{
for (pEntry = pOleCommandMap->lpEntries;
pEntry->cmdID != 0 && pEntry->nID != 0 && !bResult;
pEntry++)
{
if (nID == pEntry->cmdID &&
IsEqualNULLGuid(pguidCmdGroup, pEntry->pguid))
{
pUI->m_nID = pEntry->nID;
bResult = TRUE;
}
}
}
return bResult;
}
#endif
if (nCode != CN_UPDATE_COMMAND_UI)
{
nMsg = HIWORD(nCode);
nCode = LOWORD(nCode);
}
// for backward compatibility HIWORD(nCode)==0 is WM_COMMAND
if (nMsg == 0)
nMsg = WM_COMMAND;
// look through message map to see if it applies to us
#ifdef _AFXDLL
for (pMessageMap = GetMessageMap(); pMessageMap != NULL;
pMessageMap = (*pMessageMap->pfnGetBaseMap)())
#else
for (pMessageMap = GetMessageMap(); pMessageMap != NULL;
pMessageMap = pMessageMap->pBaseMap)
#endif
{
// Note: catches BEGIN_MESSAGE_MAP(CMyClass, CMyClass)!
#ifdef _AFXDLL
ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
#else
ASSERT(pMessageMap != pMessageMap->pBaseMap);
#endif
lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID);
if (lpEntry != NULL)
{
// found it
#ifdef _DEBUG
if (afxTraceFlags & traceCmdRouting)
{
if (nCode == CN_COMMAND)
{
TRACE2("SENDING command id 0x%04X to %hs target.\n", nID,
GetRuntimeClass()->m_lpszClassName);
}
else if (nCode > CN_COMMAND)
{
if (afxTraceFlags & traceWinMsg)
{
TRACE3("SENDING control notification %d from control id 0x%04X to %hs window.\n",
nCode, nID, GetRuntimeClass()->m_lpszClassName);
}
}
}
#endif //_DEBUG
return _AfxDispatchCmdMsg(this, nID, nCode,
lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);
}
}
return FALSE; // not handled
}
/////////////////////////////////////////////////////////////////////////////
// Hook to disable automation handlers
#ifndef _AFX_NO_OLE_SUPPORT
BOOL CCmdTarget::IsInvokeAllowed(DISPID)
{
return TRUE; // normally, invoke is always allowed
}
#endif // !_AFX_NO_OLE_SUPPORT
/////////////////////////////////////////////////////////////////////////////
// Stubs for OLE type library functions
#ifndef _AFX_NO_OLE_SUPPORT
BOOL CCmdTarget::GetDispatchIID(IID*)
{
// Subclass must implement (typically via COleControl implementation)
return FALSE;
}
UINT CCmdTarget::GetTypeInfoCount()
{
// Subclass must implement (typically via IMPLEMENT_OLETYPELIB macro)
return 0;
}
CTypeLibCache* CCmdTarget::GetTypeLibCache()
{
// Subclass must implement (typically via IMPLEMENT_OLETYPELIB macro)
return NULL;
}
HRESULT CCmdTarget::GetTypeLib(LCID, LPTYPELIB*)
{
// Subclass must implement (typically via IMPLEMENT_OLETYPELIB macro)
return TYPE_E_CANTLOADLIBRARY;
}
#endif // !_AFX_NO_OLE_SUPPORT
/////////////////////////////////////////////////////////////////////////////
// CCmdTarget routines that delegate to the WinApp
void CCmdTarget::BeginWaitCursor()
{ AfxGetApp()->DoWaitCursor(1); }
void CCmdTarget::EndWaitCursor()
{ AfxGetApp()->DoWaitCursor(-1); }
void CCmdTarget::RestoreWaitCursor()
{ AfxGetApp()->DoWaitCursor(0); }
/////////////////////////////////////////////////////////////////////////////
// Root of message maps
const AFX_DATADEF AFX_MSGMAP CCmdTarget::messageMap =
{
#ifdef _AFXDLL
&CCmdTarget::_GetBaseMessageMap,
#else
NULL,
#endif
&CCmdTarget::_messageEntries[0]
};
#ifdef _AFXDLL
const AFX_MSGMAP* CCmdTarget::_GetBaseMessageMap()
{
return NULL;
}
#endif
const AFX_MSGMAP* CCmdTarget::GetMessageMap() const
{
return &CCmdTarget::messageMap;
}
const AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] =
{
{ 0, 0, AfxSig_end, 0 } // nothing here
};
/////////////////////////////////////////////////////////////////////////////
// Root of dispatch maps
#ifndef _AFX_NO_OLE_SUPPORT
UINT CCmdTarget::_dispatchEntryCount = (UINT)-1;
DWORD CCmdTarget::_dwStockPropMask = (DWORD)-1;
const AFX_DISPMAP CCmdTarget::dispatchMap =
{
#ifdef _AFXDLL
&CCmdTarget::_GetBaseDispatchMap,
#else
NULL,
#endif
&CCmdTarget::_dispatchEntries[0],
&CCmdTarget::_dispatchEntryCount,
&CCmdTarget::_dwStockPropMask
};
#ifdef _AFXDLL
const AFX_DISPMAP* CCmdTarget::_GetBaseDispatchMap()
{
return NULL;
}
#endif
const AFX_DISPMAP* CCmdTarget::GetDispatchMap() const
{
return &CCmdTarget::dispatchMap;
}
const AFX_DISPMAP_ENTRY CCmdTarget::_dispatchEntries[] =
{
{ NULL, -1, NULL, 0, (AFX_PMSG)NULL, (AFX_PMSG)NULL, (size_t)-1,
afxDispCustom }
// nothing here
};
#endif //!_AFX_NO_OLE_SUPPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -