234 lines
6.5 KiB
C++
234 lines
6.5 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/textconsole.h"
|
|
#include "bagel/mfc/afxwin.h"
|
|
|
|
namespace Bagel {
|
|
namespace MFC {
|
|
|
|
IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
|
|
|
|
const AFX_MSGMAP *CCmdTarget::GetThisMessageMap() {
|
|
return nullptr;
|
|
}
|
|
|
|
void CCmdTarget::DoWaitCursor(int nCode) {
|
|
AfxGetApp()->DoWaitCursor(nCode);
|
|
}
|
|
|
|
void CCmdTarget::BeginWaitCursor() {
|
|
AfxGetApp()->DoWaitCursor(1);
|
|
}
|
|
|
|
void CCmdTarget::EndWaitCursor() {
|
|
AfxGetApp()->DoWaitCursor(-1);
|
|
}
|
|
|
|
void CCmdTarget::RestoreWaitCursor() {
|
|
AfxGetApp()->DoWaitCursor(0);
|
|
}
|
|
|
|
const AFX_MSGMAP_ENTRY *CCmdTarget::LookupMessage(unsigned int message) {
|
|
// Iterate through this class and any ancestors
|
|
for (const AFX_MSGMAP *map = GetMessageMap();
|
|
map; map = map->pfnGetBaseMap()) {
|
|
// Scan the entries to look for the message
|
|
for (const AFX_MSGMAP_ENTRY *entry = map->lpEntries;
|
|
entry->nMessage; ++entry) {
|
|
if (entry->nMessage == message)
|
|
return entry;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool CCmdTarget::OnCmdMsg(unsigned int nID, int nCode, void *pExtra,
|
|
AFX_CMDHANDLERINFO *pHandlerInfo) {
|
|
// Determine the message number and code (packed into nCode)
|
|
const AFX_MSGMAP *pMessageMap;
|
|
const AFX_MSGMAP_ENTRY *lpEntry;
|
|
unsigned int nMsg = 0;
|
|
|
|
if ((uint)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
|
|
for (pMessageMap = GetMessageMap(); pMessageMap != nullptr;
|
|
pMessageMap = (*pMessageMap->pfnGetBaseMap)()) {
|
|
lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID);
|
|
if (lpEntry) {
|
|
// found it
|
|
return _AfxDispatchCmdMsg(this, nID, nCode,
|
|
lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);
|
|
}
|
|
}
|
|
|
|
// Not handled
|
|
return false;
|
|
}
|
|
|
|
const AFX_MSGMAP_ENTRY *CCmdTarget::AfxFindMessageEntry(const AFX_MSGMAP_ENTRY *lpEntry,
|
|
unsigned int nMsg, unsigned int nCode, unsigned int nID) {
|
|
while (lpEntry->nSig != AfxSig_end) {
|
|
if (lpEntry->nMessage == nMsg && lpEntry->nCode == nCode &&
|
|
nID >= lpEntry->nID && nID <= lpEntry->nLastID) {
|
|
return lpEntry;
|
|
}
|
|
|
|
lpEntry++;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool CCmdTarget::_AfxDispatchCmdMsg(CCmdTarget *pTarget, unsigned int nID, int nCode,
|
|
AFX_PMSG pfn, void *pExtra, unsigned int nSig, AFX_CMDHANDLERINFO *pHandlerInfo) {
|
|
union MessageMapFunctions mmf;
|
|
mmf.pfn = pfn;
|
|
bool bResult = true; // default is ok
|
|
|
|
if (pHandlerInfo != nullptr) {
|
|
// just fill in the information, don't do it
|
|
pHandlerInfo->pTarget = pTarget;
|
|
pHandlerInfo->pmf = mmf.pfn;
|
|
return true;
|
|
}
|
|
|
|
switch (nSig) {
|
|
case AfxSig_vv:
|
|
case AfxSigCmd_v:
|
|
// normal command or control notification
|
|
assert(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
|
|
assert(pExtra == nullptr);
|
|
(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 == nullptr);
|
|
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 == nullptr);
|
|
(pTarget->*mmf.pfn_COMMAND_RANGE)(nID);
|
|
break;
|
|
|
|
case AfxSig_bw:
|
|
// extended command (passed ID, returns bContinue)
|
|
assert(pExtra == nullptr);
|
|
bResult = (pTarget->*mmf.pfn_COMMAND_EX)(nID);
|
|
break;
|
|
|
|
case AfxSig_vNMHDRpl: {
|
|
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
|
|
assert(pNotify != nullptr);
|
|
assert(pNotify->pResult != nullptr);
|
|
assert(pNotify->pNMHDR != nullptr);
|
|
(pTarget->*mmf.pfn_NOTIFY)(pNotify->pNMHDR, pNotify->pResult);
|
|
}
|
|
break;
|
|
|
|
case AfxSig_bNMHDRpl: {
|
|
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
|
|
assert(pNotify != nullptr);
|
|
assert(pNotify->pResult != nullptr);
|
|
assert(pNotify->pNMHDR != nullptr);
|
|
bResult = (pTarget->*mmf.pfn_bNOTIFY)(pNotify->pNMHDR, pNotify->pResult);
|
|
}
|
|
break;
|
|
case AfxSig_vwNMHDRpl: {
|
|
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
|
|
assert(pNotify != nullptr);
|
|
assert(pNotify->pResult != nullptr);
|
|
assert(pNotify->pNMHDR != nullptr);
|
|
(pTarget->*mmf.pfn_NOTIFY_RANGE)(nID, pNotify->pNMHDR,
|
|
pNotify->pResult);
|
|
}
|
|
break;
|
|
|
|
case AfxSig_bwNMHDRpl: {
|
|
AFX_NOTIFY *pNotify = (AFX_NOTIFY *)pExtra;
|
|
assert(pNotify != nullptr);
|
|
assert(pNotify->pResult != nullptr);
|
|
assert(pNotify->pNMHDR != nullptr);
|
|
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 == (unsigned int)-1);
|
|
assert((uint)nCode == CN_UPDATE_COMMAND_UI || nCode == 0xFFFF);
|
|
assert(pExtra != nullptr);
|
|
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((uint)nCode == CN_UPDATE_COMMAND_UI);
|
|
assert(pExtra != nullptr);
|
|
CCmdUI *pCmdUI = (CCmdUI *)pExtra;
|
|
assert(pCmdUI->m_nID == (int)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
|
|
error("Invalid sig");
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
} // namespace MFC
|
|
} // namespace Bagel
|