📄 winfrm.cpp
字号:
pApp->ExitInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
// Support for Shell DDE Execute messages
LRESULT CFrameWnd::OnDDEInitiate(WPARAM wParam, LPARAM lParam)
{
CWinApp* pApp = AfxGetApp();
if (pApp != NULL &&
LOWORD(lParam) != 0 && HIWORD(lParam) != 0 &&
(ATOM)LOWORD(lParam) == pApp->m_atomApp &&
(ATOM)HIWORD(lParam) == pApp->m_atomSystemTopic)
{
// make duplicates of the incoming atoms (really adding a reference)
TCHAR szAtomName[_MAX_PATH];
VERIFY(GlobalGetAtomName(pApp->m_atomApp,
szAtomName, _MAX_PATH - 1) != 0);
VERIFY(GlobalAddAtom(szAtomName) == pApp->m_atomApp);
VERIFY(GlobalGetAtomName(pApp->m_atomSystemTopic,
szAtomName, _MAX_PATH - 1) != 0);
VERIFY(GlobalAddAtom(szAtomName) == pApp->m_atomSystemTopic);
// send the WM_DDE_ACK (caller will delete duplicate atoms)
::SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hWnd,
MAKELPARAM(pApp->m_atomApp, pApp->m_atomSystemTopic));
}
return 0L;
}
// always ACK the execute command - even if we do nothing
LRESULT CFrameWnd::OnDDEExecute(WPARAM wParam, LPARAM lParam)
{
// unpack the DDE message
UINT unused;
HGLOBAL hData;
VERIFY(UnpackDDElParam(WM_DDE_EXECUTE, lParam, &unused, (UINT*)&hData));
// get the command string
TCHAR szCommand[_MAX_PATH * 2];
LPCTSTR lpsz = (LPCTSTR)GlobalLock(hData);
lstrcpyn(szCommand, lpsz, _countof(szCommand));
GlobalUnlock(hData);
// acknowledge now - before attempting to execute
::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hWnd,
ReuseDDElParam(lParam, WM_DDE_EXECUTE, WM_DDE_ACK,
(UINT)0x8000, (UINT)hData));
// don't execute the command when the window is disabled
if (!IsWindowEnabled())
{
TRACE1("Warning: DDE command '%s' ignored because window is disabled.\n",
szCommand);
return 0;
}
// execute the command
if (!AfxGetApp()->OnDDECommand(szCommand))
TRACE1("Error: failed to execute DDE command '%s'.\n", szCommand);
return 0L;
}
LRESULT CFrameWnd::OnDDETerminate(WPARAM wParam, LPARAM lParam)
{
::PostMessage((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)m_hWnd, lParam);
return 0L;
}
/////////////////////////////////////////////////////////////////////////////
// CFrameWnd attributes
CView* CFrameWnd::GetActiveView() const
{
ASSERT(m_pViewActive == NULL ||
m_pViewActive->IsKindOf(RUNTIME_CLASS(CView)));
return m_pViewActive;
}
void CFrameWnd::SetActiveView(CView* pViewNew, BOOL bNotify)
{
#ifdef _DEBUG
if (pViewNew != NULL)
{
ASSERT(IsChild(pViewNew));
ASSERT_KINDOF(CView, pViewNew);
}
#endif //_DEBUG
CView* pViewOld = m_pViewActive;
if (pViewNew == pViewOld)
return; // do not re-activate if SetActiveView called more than once
m_pViewActive = NULL; // no active for the following processing
// deactivate the old one
if (pViewOld != NULL)
pViewOld->OnActivateView(FALSE, pViewNew, pViewOld);
// if the OnActivateView moves the active window,
// that will veto this change
if (m_pViewActive != NULL)
return; // already set
m_pViewActive = pViewNew;
// activate
if (pViewNew != NULL && bNotify)
pViewNew->OnActivateView(TRUE, pViewNew, pViewOld);
}
/////////////////////////////////////////////////////////////////////////////
// Special view swapping/activation
void CFrameWnd::OnSetFocus(CWnd* pOldWnd)
{
if (m_pViewActive != NULL)
m_pViewActive->SetFocus();
else
CWnd::OnSetFocus(pOldWnd);
}
CDocument* CFrameWnd::GetActiveDocument()
{
ASSERT_VALID(this);
CView* pView = GetActiveView();
if (pView != NULL)
return pView->GetDocument();
return NULL;
}
void CFrameWnd::ShowControlBar(CControlBar* pBar, BOOL bShow, BOOL bDelay)
{
ASSERT(pBar != NULL);
CFrameWnd* pParentFrame = pBar->GetDockingFrame();
ASSERT(pParentFrame->GetTopLevelParent() == GetTopLevelParent());
// parent frame of bar must be related
if (bDelay)
{
pBar->DelayShow(bShow);
pParentFrame->DelayRecalcLayout();
}
else
{
pBar->SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
(bShow ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
// call DelayShow to clear any contradictory DelayShow
pBar->DelayShow(bShow);
if (bShow || !pBar->IsFloating())
pParentFrame->RecalcLayout(FALSE);
}
// show or hide the floating frame as appropriate
if (pBar->IsFloating())
{
int nVisCount = pBar->m_pDockBar != NULL ?
pBar->m_pDockBar->GetDockedVisibleCount() : bShow ? 1 : 0;
if (nVisCount == 1 && bShow)
{
pParentFrame->m_nShowDelay = -1;
if (bDelay)
{
pParentFrame->m_nShowDelay = SW_SHOWNA;
pParentFrame->RecalcLayout(FALSE);
}
else
pParentFrame->ShowWindow(SW_SHOWNA);
}
else if (nVisCount == 0)
{
ASSERT(!bShow);
pParentFrame->m_nShowDelay = -1;
if (bDelay)
pParentFrame->m_nShowDelay = SW_HIDE;
else
pParentFrame->ShowWindow(SW_HIDE);
}
else if (!bDelay)
{
pParentFrame->RecalcLayout(FALSE);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Command prompts
void CFrameWnd::OnInitMenu(CMenu* pMenu)
{
#ifndef _AFX_NO_OLE_SUPPORT
// allow hook to consume message
if (m_pNotifyHook != NULL)
{
#ifdef _AFXDLL
ASSERT(m_pModuleState != NULL);
if (m_pModuleState->m_dwVersion >= 0x423)
#endif
m_pNotifyHook->OnInitMenu(pMenu);
#endif
}
Default();
}
void CFrameWnd::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)
{
AfxCancelModes(m_hWnd);
if (bSysMenu)
return; // don't support system menu
#ifndef _AFX_NO_OLE_SUPPORT
// allow hook to consume message
if (m_pNotifyHook != NULL)
{
#ifdef _AFXDLL
ASSERT(m_pModuleState != NULL);
if (m_pModuleState->m_dwVersion >= 0x423)
#endif
if (m_pNotifyHook->OnInitMenuPopup(pMenu, nIndex, bSysMenu))
return;
}
#endif
ASSERT(pMenu != NULL);
// check the enabled state of various menu items
CCmdUI state;
state.m_pMenu = pMenu;
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pParentMenu == NULL);
// determine if menu is popup in top-level menu and set m_pOther to
// it if so (m_pParentMenu == NULL indicates that it is secondary popup)
HMENU hParentMenu;
if (AfxGetThreadState()->m_hTrackingMenu == pMenu->m_hMenu)
state.m_pParentMenu = pMenu; // parent == child for tracking popup
else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
{
CWnd* pParent = GetTopLevelParent();
// child windows don't have menus -- need to go to the top!
if (pParent != NULL &&
(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
{
int nIndexMax = ::GetMenuItemCount(hParentMenu);
for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
{
if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
{
// when popup is found, m_pParentMenu is containing menu
state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
break;
}
}
}
}
state.m_nIndexMax = pMenu->GetMenuItemCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
if (state.m_nID == 0)
continue; // menu separator or invalid cmd - ignore it
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pMenu != NULL);
if (state.m_nID == (UINT)-1)
{
// possibly a popup menu, route to first item of that popup
state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
if (state.m_pSubMenu == NULL ||
(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
state.m_nID == (UINT)-1)
{
continue; // first item of popup can't be routed to
}
state.DoUpdate(this, FALSE); // popups are never auto disabled
}
else
{
// normal menu item
// Auto enable/disable if frame window has 'm_bAutoMenuEnable'
// set and command is _not_ a system command.
state.m_pSubMenu = NULL;
state.DoUpdate(this, m_bAutoMenuEnable && state.m_nID < 0xF000);
}
// adjust for menu deletions and additions
UINT nCount = pMenu->GetMenuItemCount();
if (nCount < state.m_nIndexMax)
{
state.m_nIndex -= (state.m_nIndexMax - nCount);
while (state.m_nIndex < nCount &&
pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
{
state.m_nIndex++;
}
}
state.m_nIndexMax = nCount;
}
}
void CFrameWnd::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
CFrameWnd* pFrameWnd = GetTopLevelFrame();
ASSERT_VALID(pFrameWnd);
#ifndef _AFX_NO_OLE_SUPPORT
// allow hook to consume message
if (m_pNotifyHook != NULL)
{
#ifdef _AFXDLL
ASSERT(m_pModuleState != NULL);
if (m_pModuleState->m_dwVersion >= 0x423)
#endif
if (m_pNotifyHook->OnMenuSelect(nItemID, nFlags, hSysMenu))
return;
}
#endif
// set the tracking state (update on idle)
if (nFlags == 0xFFFF)
{
// cancel menu operation (go back to idle now)
m_nFlags &= ~WF_NOPOPMSG;
if (!pFrameWnd->m_bHelpMode)
m_nIDTracking = AFX_IDS_IDLEMESSAGE;
else
m_nIDTracking = AFX_IDS_HELPMODEMESSAGE;
SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
ASSERT(m_nIDTracking == m_nIDLastMessage);
// update right away
CWnd* pWnd = GetMessageBar();
if (pWnd != NULL)
pWnd->UpdateWindow();
}
else
{
if (nItemID == 0 || nFlags & (MF_SEPARATOR|MF_POPUP))
{
// nothing should be displayed
m_nIDTracking = 0;
}
else if (nItemID >= 0xF000 && nItemID < 0xF1F0) // max of 31 SC_s
{
// special strings table entries for system commands
m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
m_nIDTracking < AFX_IDS_SCFIRST + 31);
}
else if (nItemID >= AFX_IDM_FIRST_MDICHILD)
{
// all MDI Child windows map to the same help id
m_nIDTracking = AFX_IDS_MDICHILD;
}
else
{
// track on idle
m_nIDTracking = nItemID;
}
pFrameWnd->m_nFlags |= WF_NOPOPMSG;
}
// when running in-place, it is necessary to cause a message to
// be pumped through the queue.
if (m_nIDTracking != m_nIDLastMessage && GetParent() != NULL)
PostMessage(WM_KICKIDLE);
}
void CFrameWnd::GetMessageString(UINT nID, CString& rMessage) const
{
// load appropriate string
LPTSTR lpsz = rMessage.GetBuffer(255);
if (AfxLoadString(nID, lpsz) != 0)
{
// first newline terminates actual string
lpsz = _tcschr(lpsz, '\n');
if (lpsz != NULL)
*lpsz = '\0';
}
else
{
// not found
TRACE1("Warning: no message line prompt for ID 0x%04X.\n", nID);
}
rMessage.ReleaseBuffer();
}
LRESULT CFrameWnd::OnPopMessageString(WPARAM wParam, LPARAM lParam)
{
if (m_nFlags & WF_NOPOPMSG)
return 0;
return SendMessage(WM_SETMESSAGESTRING, wParam, lParam);
}
LRESULT CFrameWnd::OnSetMessageString(WPARAM wParam, LPARAM lParam)
{
UINT nIDLast = m_nIDLastMessage;
m_nFlags &= ~WF_NOPOPMSG;
CWnd* pMessageBar = GetMessageBar();
if (pMessageBar != NULL)
{
LPCTSTR lpsz = NULL;
CString strMessage;
// set the message bar text
if (lParam != 0)
{
ASSERT(wParam == 0); // can't have both an ID and a string
lpsz = (LPCTSTR)lParam; // set an explicit string
}
else if (wParam != 0)
{
// map SC_CLOSE to PREVIEW_CLOSE when in print preview mode
if (wParam == AFX_IDS_SCCLOSE && m_lpfnCloseProc != NULL)
wParam = AFX_IDS_PREVIEW_CLOSE;
// get message associated with the ID indicated by wParam
GetMessageString(wParam, strMessage);
lpsz = strMessage;
}
pMessageBar->SetWindowText(lpsz);
// update owner of the bar in terms of last message selected
CFrameWnd* pFrameWnd = pMessageBar->GetParentFrame();
if (pFrameWnd != NULL)
{
pFrameWnd->m_nIDLastMessage = (UINT)wParam;
pFrameWnd->m_nIDTracking = (UINT)wParam;
}
}
m_nIDLastMessage = (UINT)wParam; // new ID (or 0)
m_nIDTracking = (UINT)wParam; // so F1 on toolbar buttons work
return nIDLast;
}
LRESULT CFrameWnd::OnHelpPromptAddr(WPARAM, LPARAM)
{
return (LRESULT)&m_dwPromptContext;
}
CWnd* CFrameWnd::GetMessageBar()
{
return GetDescendantWindow(AFX_IDW_STATUS_BAR, TRUE);
}
void CFrameWnd::OnEnterIdle(UINT nWhy, CWnd* pWho)
{
CWnd::OnEnterIdle(nWhy, pWho);
if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
return;
SetMessageText(m_nIDTracking);
ASSERT(m_nIDTracking == m_nIDLastMessage);
}
void CFrameWnd::SetMessageText(LPCTSTR lpszText)
{
SendMessage(WM_SETMESSAGESTRING, 0, (LPARAM)lpszText);
}
void CFrameWnd::SetMessageText(UINT nID)
{
SendMessage(WM_SETMESSAGESTRING, (WPARAM)nID);
}
/////////////////////////////////////////////////////////////////////////////
// CFrameWnd standard control bar management
void CFrameWnd::DestroyDockBars()
{
// create a list of all the dock bars
// this is necessary because m_listControlBars will change
// as the dock bars and floating frames are destroyed
CPtrList listDockBars;
POSITION pos = m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CDockBar* pDockBar = (CDockBar*)m_listControlBars.GetNext(pos);
ASSERT(pDockBar != NULL);
if (pDockBar->IsDockBar())
listDockBars.AddTail(pDockBar);
}
pos = listDockBars.GetHeadPosition();
while (pos != NULL)
{
CDockBar* pDockBar = (CDockBar*)listDockBars.GetNext(pos);
if (pDockBar->m_bFloating)
{
CFrameWnd* pFrameWnd = pDockBar->GetParentFrame();
ASSERT_VALID(pFrameWnd);
pFrameWnd->DestroyWindow();
}
else
pDockBar->DestroyWindow();
}
}
CControlBar* CFrameWnd::GetControlBar(UINT nID)
{
if (nID == 0)
return NULL;
POSITION pos = m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CControlBar* pBar = (CControlBar*)m_listControlBars.GetNext(pos);
ASSERT(pBar != NULL);
if (_AfxGetDlgCtrlID(pBar->m_hWnd) == nID)
{
ASSERT_KINDOF(CControlBar, pBar);
return pBar;
}
}
return NULL;
}
void CFrameWnd::OnUpdateControlBarMenu(CCmdUI* pCmdUI)
{
ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);
ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);
ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR);
CControlBar* pBar = GetControlBar(pCmdUI->m_nID);
if (pBar != NULL)
{
pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0);
return;
}
pCmdUI->ContinueRouting();
}
BOOL CFrameWnd::OnBarCheck(UINT nID)
{
ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);
ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);
ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -