📄 winfrm.cpp
字号:
CControlBar* pBar = GetControlBar(nID);
if (pBar != NULL)
{
ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE);
return TRUE;
}
return FALSE;
}
BOOL CFrameWnd::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
{
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
// need to handle both ANSI and UNICODE versions of the message
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
TCHAR szFullText[256];
CString strTipText;
UINT nID = pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
// idFrom is actually the HWND of the tool
nID = _AfxGetDlgCtrlID((HWND)nID);
}
if (nID != 0) // will be zero on a separator
{
// don't handle the message if no string resource found
if (AfxLoadString(nID, szFullText) == 0)
return FALSE;
// this is the command id, not the button index
AfxExtractSubString(strTipText, szFullText, 1, '\n');
}
#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
lstrcpyn(pTTTA->szText, strTipText, _countof(pTTTA->szText));
else
_mbstowcsz(pTTTW->szText, strTipText, _countof(pTTTW->szText));
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
_wcstombsz(pTTTA->szText, strTipText, _countof(pTTTA->szText));
else
lstrcpyn(pTTTW->szText, strTipText, _countof(pTTTW->szText));
#endif
*pResult = 0;
// bring the tooltip window above other popup windows
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
return TRUE; // message was handled
}
/////////////////////////////////////////////////////////////////////////////
// Support for standard status bar
void CFrameWnd::OnUpdateKeyIndicator(CCmdUI* pCmdUI)
{
UINT nVK;
UINT flag = 0x0001;
switch (pCmdUI->m_nID)
{
case ID_INDICATOR_CAPS:
nVK = VK_CAPITAL;
break;
case ID_INDICATOR_NUM:
nVK = VK_NUMLOCK;
break;
case ID_INDICATOR_SCRL:
nVK = VK_SCROLL;
break;
case ID_INDICATOR_KANA:
nVK = VK_KANA;
// WINBUG: Special case for Windows 3.x. The wrong bit was toggled
// in those systems so this must be special cased. This is fixed
// on systems whose version is 4.x or greater.
if (!afxData.bWin4)
flag = 0x8000;
break;
default:
TRACE1("Warning: OnUpdateKeyIndicator - unknown indicator 0x%04X.\n",
pCmdUI->m_nID);
pCmdUI->ContinueRouting();
return; // not for us
}
pCmdUI->Enable(::GetKeyState(nVK) & flag);
// enable static text based on toggled key state
ASSERT(pCmdUI->m_bEnableChanged);
}
void CFrameWnd::OnUpdateContextHelp(CCmdUI* pCmdUI)
{
if (AfxGetMainWnd() == this)
pCmdUI->SetCheck(!!m_bHelpMode);
else
pCmdUI->ContinueRouting();
}
/////////////////////////////////////////////////////////////////////////////
// Setting title of frame window - UISG standard
void CFrameWnd::OnUpdateFrameTitle(BOOL bAddToTitle)
{
if ((GetStyle() & FWS_ADDTOTITLE) == 0)
return; // leave it alone!
#ifndef _AFX_NO_OLE_SUPPORT
// allow hook to set the title (used for OLE support)
if (m_pNotifyHook != NULL && m_pNotifyHook->OnUpdateFrameTitle())
return;
#endif
CDocument* pDocument = GetActiveDocument();
if (bAddToTitle && pDocument != NULL)
UpdateFrameTitleForDocument(pDocument->GetTitle());
else
UpdateFrameTitleForDocument(NULL);
}
void CFrameWnd::UpdateFrameTitleForDocument(LPCTSTR lpszDocName)
{
// copy first part of title loaded at time of frame creation
TCHAR szText[256+_MAX_PATH];
if (GetStyle() & FWS_PREFIXTITLE)
{
szText[0] = '\0'; // start with nothing
// get name of currently active view
if (lpszDocName != NULL)
{
lstrcpy(szText, lpszDocName);
// add current window # if needed
if (m_nWindow > 0)
wsprintf(szText + lstrlen(szText), _T(":%d"), m_nWindow);
lstrcat(szText, _T(" - "));
}
lstrcat(szText, m_strTitle);
}
else
{
// get name of currently active view
lstrcpy(szText, m_strTitle);
if (lpszDocName != NULL)
{
lstrcat(szText, _T(" - "));
lstrcat(szText, lpszDocName);
// add current window # if needed
if (m_nWindow > 0)
wsprintf(szText + lstrlen(szText), _T(":%d"), m_nWindow);
}
}
// set title if changed, but don't remove completely
// Note: will be excessive for MDI Frame with maximized child
AfxSetWindowText(m_hWnd, szText);
}
/////////////////////////////////////////////////////////////////////////////
void CFrameWnd::OnSetPreviewMode(BOOL bPreview, CPrintPreviewState* pState)
{
// default implementation changes control bars, menu and main pane window
#ifndef _AFX_NO_OLE_SUPPORT
CFrameWnd* pActiveFrame = GetActiveFrame();
ASSERT_VALID(pActiveFrame);
if (bPreview && pActiveFrame->m_pNotifyHook != NULL)
pActiveFrame->m_pNotifyHook->OnDocActivate(FALSE);
#endif
// Set visibility of standard ControlBars (only the first 32)
DWORD dwOldStates = 0;
POSITION pos = m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CControlBar* pBar = (CControlBar*)m_listControlBars.GetNext(pos);
ASSERT_VALID(pBar);
UINT nID = _AfxGetDlgCtrlID(pBar->m_hWnd);
if (nID >= AFX_IDW_CONTROLBAR_FIRST && nID <= AFX_IDW_CONTROLBAR_FIRST+31)
{
DWORD dwMask = 1L << (nID - AFX_IDW_CONTROLBAR_FIRST);
if (pBar->IsVisible())
dwOldStates |= dwMask; // save if previously visible
if (!pBar->IsDockBar() || nID != AFX_IDW_DOCKBAR_FLOAT)
ShowControlBar(pBar, (pState->dwStates & dwMask), TRUE);
}
}
pState->dwStates = dwOldStates; // save for restore
if (bPreview)
{
// Entering Print Preview
ASSERT(m_lpfnCloseProc == NULL); // no chaining
m_lpfnCloseProc = pState->lpfnCloseProc;
// show any modeless dialogs, popup windows, float tools, etc
ShowOwnedWindows(FALSE);
// Hide the main pane
HWND hWnd = ::GetDlgItem(m_hWnd, pState->nIDMainPane);
ASSERT(hWnd != NULL); // must be one that we are hiding!
::ShowWindow(hWnd, SW_HIDE);
// Get rid of the menu first (will resize the window)
pState->hMenu = ::GetMenu(m_hWnd);
if (pState->hMenu != NULL)
{
// Invalidate before SetMenu since we are going to replace
// the frame's client area anyway
Invalidate();
SetMenu(NULL);
m_nIdleFlags &= ~idleMenu; // avoid any idle menu processing
}
// Save the accelerator table and remove it.
pState->hAccelTable = m_hAccelTable;
m_hAccelTable = NULL;
LoadAccelTable(MAKEINTRESOURCE(AFX_IDR_PREVIEW_ACCEL));
// Make room for the PreviewView by changing AFX_IDW_PANE_FIRST's ID
// to AFX_IDW_PREVIEW_FIRST
if (pState->nIDMainPane != AFX_IDW_PANE_FIRST)
hWnd = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_FIRST);
if (hWnd != NULL)
_AfxSetDlgCtrlID(hWnd, AFX_IDW_PANE_SAVE);
#ifdef _DEBUG
if ((::GetWindowLong(m_hWnd, GWL_STYLE) & (WS_HSCROLL|WS_VSCROLL)) != 0)
TRACE0("Warning: scroll bars in frame windows may cause unusual behaviour.\n");
#endif
}
else
{
// Leaving Preview
m_lpfnCloseProc = NULL;
// shift original AFX_IDW_PANE_FIRST back to its rightful ID
HWND hWnd = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_SAVE);
if (hWnd != NULL)
{
HWND hWndTemp = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_FIRST);
if (hWndTemp != NULL)
_AfxSetDlgCtrlID(hWndTemp, AFX_IDW_PANE_SAVE);
_AfxSetDlgCtrlID(hWnd, AFX_IDW_PANE_FIRST);
}
// put the menu back in place if it was removed before
if (pState->hMenu != NULL)
{
// Invalidate before SetMenu since we are going to replace
// the frame's client area anyway
Invalidate();
::SetMenu(m_hWnd, pState->hMenu);
}
// recalc layout now, before showing the main pane
#ifndef _AFX_NO_OLE_SUPPORT
if (pActiveFrame->m_pNotifyHook != NULL)
pActiveFrame->m_pNotifyHook->OnDocActivate(TRUE);
#endif
RecalcLayout();
// now show main pane that was hidden
if (pState->nIDMainPane != AFX_IDW_PANE_FIRST)
hWnd = ::GetDlgItem(m_hWnd, pState->nIDMainPane);
ASSERT(hWnd != NULL);
::ShowWindow(hWnd, SW_SHOW);
// Restore the Accelerator table
m_hAccelTable = pState->hAccelTable;
// show any modeless dialogs, popup windows, float tools, etc
ShowOwnedWindows(TRUE);
}
}
void CFrameWnd::DelayUpdateFrameMenu(HMENU hMenuAlt)
{
m_hMenuAlt = hMenuAlt;
m_nIdleFlags |= idleMenu;
}
void CFrameWnd::OnIdleUpdateCmdUI()
{
// update menu if necessary
if (m_nIdleFlags & idleMenu)
OnUpdateFrameMenu(m_hMenuAlt);
// update title if necessary
if (m_nIdleFlags & idleTitle)
OnUpdateFrameTitle(TRUE);
// recalc layout if necessary
if (m_nIdleFlags & idleLayout)
{
RecalcLayout(m_nIdleFlags & idleNotify);
UpdateWindow();
}
// set the current message string if necessary
if (m_nIDTracking != m_nIDLastMessage)
{
SetMessageText(m_nIDTracking);
ASSERT(m_nIDTracking == m_nIDLastMessage);
}
m_nIdleFlags = 0;
}
CFrameWnd* CFrameWnd::GetActiveFrame()
{
// by default, the active frame is the frame itself (MDI is different)
return this;
}
void CFrameWnd::RecalcLayout(BOOL bNotify)
{
if (m_bInRecalcLayout)
return;
m_bInRecalcLayout = TRUE;
// clear idle flags for recalc layout if called elsewhere
if (m_nIdleFlags & idleNotify)
bNotify = TRUE;
m_nIdleFlags &= ~(idleLayout|idleNotify);
#ifndef _AFX_NO_OLE_SUPPORT
// call the layout hook -- OLE support uses this hook
if (bNotify && m_pNotifyHook != NULL)
m_pNotifyHook->OnRecalcLayout();
#endif
// reposition all the child windows (regardless of ID)
if (GetStyle() & FWS_SNAPTOBARS)
{
CRect rect(0, 0, 32767, 32767);
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,
&rect, &rect, FALSE);
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra,
&m_rectBorder, &rect, TRUE);
CalcWindowRect(&rect);
SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
}
else
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra, &m_rectBorder);
m_bInRecalcLayout = FALSE;
}
// CFrameWnd implementation of OLE border space negotiation
BOOL CFrameWnd::NegotiateBorderSpace(UINT nBorderCmd, LPRECT lpRectBorder)
{
CRect border, request;
switch (nBorderCmd)
{
case borderGet:
ASSERT(lpRectBorder != NULL);
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,
lpRectBorder);
break;
case borderRequest:
return TRUE;
case borderSet:
if (lpRectBorder == NULL)
{
if (!m_rectBorder.IsRectNull())
{
// releasing all border space -- recalc needed
m_rectBorder.SetRectEmpty();
return TRUE;
}
// original rect is empty & lpRectBorder is NULL, no recalc needed
return FALSE;
}
if (!::EqualRect(m_rectBorder, lpRectBorder))
{
// the rects are different -- recalc needed
m_rectBorder.CopyRect(lpRectBorder);
return TRUE;
}
return FALSE; // no recalc needed
default:
ASSERT(FALSE); // invalid CFrameWnd::BorderCmd
}
return TRUE;
}
void CFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy); // important for MDI Children
if (nType != SIZE_MINIMIZED)
RecalcLayout();
}
BOOL CFrameWnd::OnEraseBkgnd(CDC* pDC)
{
if (m_pViewActive != NULL)
return TRUE; // active view will erase/paint itself
// for view-less frame just use the default background fill
return CWnd::OnEraseBkgnd(pDC);
}
LRESULT CFrameWnd::OnRegisteredMouseWheel(WPARAM wParam, LPARAM lParam)
{
// convert from MSH_MOUSEWHEEL to WM_MOUSEWHEEL
WORD keyState = 0;
keyState |= (::GetKeyState(VK_CONTROL) < 0) ? MK_CONTROL : 0;
keyState |= (::GetKeyState(VK_SHIFT) < 0) ? MK_SHIFT : 0;
LRESULT lResult;
HWND hwFocus = ::GetFocus();
const HWND hwDesktop = ::GetDesktopWindow();
if (hwFocus == NULL)
lResult = SendMessage(WM_MOUSEWHEEL, (wParam << 16) | keyState, lParam);
else
{
do {
lResult = ::SendMessage(hwFocus, WM_MOUSEWHEEL,
(wParam << 16) | keyState, lParam);
hwFocus = ::GetParent(hwFocus);
}
while (lResult == 0 && hwFocus != NULL && hwFocus != hwDesktop);
}
return lResult;
}
void CFrameWnd::ActivateFrame(int nCmdShow)
// nCmdShow is the normal show mode this frame should be in
{
// translate default nCmdShow (-1)
if (nCmdShow == -1)
{
if (!IsWindowVisible())
nCmdShow = SW_SHOWNORMAL;
else if (IsIconic())
nCmdShow = SW_RESTORE;
}
// bring to top before showing
BringToTop(nCmdShow);
if (nCmdShow != -1)
{
// show the window as specified
ShowWindow(nCmdShow);
// and finally, bring to top after showing
BringToTop(nCmdShow);
}
}
void CFrameWnd::BringToTop(int nCmdShow)
{
// place the window on top except for certain nCmdShow
if (nCmdShow != SW_HIDE &&
nCmdShow != SW_MINIMIZE && nCmdShow != SW_SHOWMINNOACTIVE &&
nCmdShow != SW_SHOWNA && nCmdShow != SW_SHOWNOACTIVATE)
{
// if no last active popup, it will return m_hWnd
HWND hWndLastPop = ::GetLastActivePopup(m_hWnd);
::BringWindowToTop(hWndLastPop);
}
}
/////////////////////////////////////////////////////////////////////////////
// CFrameWnd Diagnostics
#ifdef _DEBUG
void CFrameWnd::AssertValid() const
{
CWnd::AssertValid();
if (m_pViewActive != NULL)
ASSERT_VALID(m_pViewActive);
}
void CFrameWnd::Dump(CDumpContext& dc) const
{
CWnd::Dump(dc);
dc << "m_hAccelTable = " << (UINT)m_hAccelTable;
dc << "\nm_nWindow = " << m_nWindow;
dc << "\nm_nIDHelp = " << m_nIDHelp;
dc << "\nm_nIDTracking = " << m_nIDTracking;
dc << "\nm_nIDLastMessage = " << m_nIDLastMessage;
if (m_pViewActive != NULL)
dc << "\nwith active view: " << m_pViewActive;
else
dc << "\nno active view";
dc << "\n";
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CControlBar segmentation
CFrameWnd* CControlBar::GetDockingFrame() const
{
CFrameWnd* pFrameWnd = GetParentFrame();
if (pFrameWnd == NULL)
pFrameWnd = m_pDockSite;
ASSERT(pFrameWnd != NULL);
ASSERT_KINDOF(CFrameWnd, pFrameWnd);
return pFrameWnd;
}
BOOL CControlBar::IsFloating() const
{
if (IsDockBar())
return ((CDockBar*)this)->m_bFloating;
else
return m_pDockBar != NULL && m_pDockBar->m_bFloating;
}
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
// in this file for IsKindOf library granularity (IsKindOf references these)
IMPLEMENT_DYNCREATE(CFrameWnd, CWnd)
IMPLEMENT_DYNAMIC(CView, CWnd)
IMPLEMENT_DYNAMIC(CControlBar, CWnd)
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -