📄 tabbarwnd.cpp
字号:
pData->iIndex = iCurrTabIndex;
// do our best to just replace the text (avoid flicker)
do
{
if (m_TabCtrl.GetItem(iCurrTabIndex, &oldTabItem) == FALSE)
{
oldTabItem.lParam = NULL;
break;
}
if (((tabdata_t *)(oldTabItem.lParam))->hWnd == pData->hWnd)
break;
if (m_TabCtrl.GetItemCount() <= cWindows)
{
oldTabItem.lParam = NULL;
break;
}
m_TabCtrl.DeleteItem(iCurrTabIndex);
} while (1);
if ((HWND)oldTabItem.lParam != NULL)
{
m_TabCtrl.SetItem(iCurrTabIndex, &newTabItem);
}
else
{
m_TabCtrl.InsertItem(iCurrTabIndex, &newTabItem);
}
if (pData->hWnd == hWndActive)
{
m_TabCtrl.SetCurSel(iCurrTabIndex);
}
iCurrTabIndex++;
}
while (m_TabCtrl.GetItemCount() > cWindows)
{
m_TabCtrl.DeleteItem(m_TabCtrl.GetItemCount() - 1);
}
m_TabCtrl.SetRedraw(TRUE);
m_TabCtrl.RedrawWindow();
}
// Retrieves the pointer to a DevStudio window that corresponds to a tab,
// by scanning the DevStudio document windows, looking for a window with the
// same title as the tab.
// This method demonstrates enumeration using the enumeration
// function/property.
bool CTabBarsWnd::FindDSWindow(int iSel, CComQIPtr<IGenericWindow, &IID_IGenericWindow>& pWindow)
{
HWND hWnd = GetTabData(iSel)->hWnd;
CComPtr<IDispatch> pDisp;
CComQIPtr<IWindows, &IID_IWindows> pWindows;
m_pApplication->get_Windows(&pDisp);
pWindows = pDisp;
pDisp = NULL;
CComPtr<IUnknown> pUnk;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
if (SUCCEEDED(pWindows->get__NewEnum(&pUnk)) && pUnk != NULL)
{
pNewEnum = pUnk;
VARIANT varWindow;
CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindowItem;
while (pNewEnum->Next(1, &varWindow, NULL) == S_OK)
{
ASSERT (varWindow.vt == VT_DISPATCH);
pWindowItem = varWindow.pdispVal;
VariantClear(&varWindow);
if (GetHWND(pWindowItem) == hWnd)
{
pWindow = pWindowItem;
return TRUE;
}
}
}
return FALSE;
}
BOOL CTabBarsWnd::LoadPopupMenu(int nResourceID, BCMenu& menu,BCMenu *& pPopup)
{
if (menu.LoadMenu(nResourceID))
{
pPopup = (BCMenu *)menu.GetSubMenu(0);
// pPopup->LoadToolbar(IDR_ICONS);
pPopup->LoadToolbar(IDR_TOOLBAR_MEDIUM);
return TRUE;
}
return FALSE;
}
void CTabBarsWnd::CloseDSWindow(CComQIPtr<IGenericWindow, &IID_IGenericWindow>& pWindow)
{
CComPtr<IDispatch> pDisp;
CComBSTR bStr;
VARIANT_BOOL vb;
// bStr <- name of window to close
// (used later to retrieve window handle)
pWindow->get_Caption(&bStr);
// are we closing the active window?
pWindow->get_Active(&vb);
if (vb == VARIANT_FALSE)
{
// not closing the active window, so save the active
// window in pWindow
m_pApplication->get_ActiveWindow(&pDisp);
pWindow = pDisp;
pDisp = NULL;
m_iLockUpdates++;
// force an event:
pWindow->put_Active(VARIANT_FALSE);
}
::SendMessage(GetHWND(bStr), WM_CLOSE, 0, 0);//now close it!
// need to reactivate the previously active window?
if (vb == VARIANT_FALSE)
{
// get HWND of previously active window
HWND hWnd = GetHWND(pWindow);
::PostMessage(::GetParent(hWnd), WM_MDIACTIVATE,(WPARAM)hWnd, 0);
}
}
CTabBarsWnd::tabdata_t * CTabBarsWnd::GetTabData(int iTabIndex)
{
TC_ITEM tab_item;
tab_item.mask = TCIF_PARAM;
m_TabCtrl.GetItem(iTabIndex, &tab_item);
return ((tabdata_t *)tab_item.lParam);
}
void CTabBarsWnd::ActivateTab(int iIndex)
{
CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow;
tabdata_t * pData;
// find the tab to select
for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
{
pData = GetTabData(i);
if (pData->iIndex == iIndex)
{
if (FindDSWindow(i, pWindow))
{
pWindow->put_Active(VARIANT_TRUE);
}
break;
}
}
}
// GetDocumentObject: Retrieves a window's document object.
//
// BUG BUG: DevStudio provides the get_Parent that returns a window's
// document object. But using get_Parent on a non-text window, might
// cause DevStudio to crash (a good example of this is a resource window).
// Since such windows might actually have a document, this function is used
// to get document "the hard way"
bool CTabBarsWnd::GetDocumentObject(
CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow,
CComQIPtr<IGenericDocument, &IID_IGenericDocument>& pDoc)
{
// Matching the document to a window is a two-step process:
// 1. get a document object from the document list
// 2. scan all windows belonging to the document
// All of the documents/document windows are scanned until the
// window is matched.
CComPtr<IUnknown> pUnk;
CComPtr<IDispatch> pDisp;
CComQIPtr<IDocuments, &IID_IDocuments> pDocuments;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
m_pApplication->get_Documents(&pDisp);
pDocuments = pDisp;
pDisp = NULL;
if (SUCCEEDED(pDocuments->get__NewEnum(&pUnk)) && pUnk != NULL)
{
pNewEnum = pUnk;
VARIANT varDoc;
while (pNewEnum->Next(1, &varDoc, NULL) == S_OK)
{
ASSERT (varDoc.vt == VT_DISPATCH);
pDoc = varDoc.pdispVal;
VariantClear(&varDoc);
// iterate the document's windows
CComQIPtr<IWindows, &IID_IWindows> pWindows;
pDoc->get_Windows(&pDisp);
pWindows = pDisp;
pDisp = NULL;
CComPtr<IUnknown> pUnk2;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pEnum2;
if (SUCCEEDED(pWindows->get__NewEnum(&pUnk2)) && pUnk2 != NULL)
{
pEnum2 = pUnk2;
VARIANT varWindow;
CComQIPtr<IGenericWindow, &IID_IGenericWindow> pWindow2;
while (pEnum2->Next(1, &varWindow, NULL) == S_OK)
{
ASSERT (varWindow.vt == VT_DISPATCH);
pWindow2 = varWindow.pdispVal;
VariantClear(&varWindow);
if (pWindow2 == pWindow)
{
return true;
}
}
}
}
}
return false;
}
void CTabBarsWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect r, rcClient;
GetClientRect(rcClient);
CDC memDC;
CBitmap bitmap;
memDC.CreateCompatibleDC(&dc);
bitmap.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
memDC.SetBkMode( TRANSPARENT );
// memDC.FillSolidRect(&rcClient, m_clrBtnFace );
// First let the control do its default drawing.
CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
COLORREF m_clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
COLORREF m_clrBtnHilite = ::GetSysColor(COLOR_BTNHIGHLIGHT);
COLORREF m_clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
memDC.FillSolidRect(&rcClient, m_clrBtnFace );
memDC.Draw3dRect(&rcClient, m_clrBtnHilite, m_clrBtnShadow);
r = m_RectGripper;
r.left++;
r.right = r.left + GRIPPER_SIZE;
r.DeflateRect(0, 1);
memDC.Draw3dRect(r.left, r.top, 3, r.Height(), m_clrBtnHilite, m_clrBtnShadow);
dc.BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &memDC, 0,0, SRCCOPY);
memDC.SelectObject(pOldBitmap);
memDC.DeleteDC();
bitmap.DeleteObject();
}
/*********************************************************************
* Function Name : CTabBarsWnd::SetTabFont
* Explain : set font
* Parameter List:
* CFont *pFont --
* Return:
* void --
* Author : orbit
* Time : 2002-03-12 17:26:12
*********************************************************************/
void CTabBarsWnd::SetTabFont(CFont *pFont)
{
if(m_pFont != NULL)
{
m_pFont->DeleteObject();
delete m_pFont;
}
m_pFont = pFont;
SetFont(m_pFont, FALSE);
m_TabCtrl.SetFont(m_pFont,TRUE);
TEXTMETRIC tm;
CDC cDC;
cDC.CreateCompatibleDC(NULL);
CFont *pOldFont = cDC.SelectObject(m_pFont);
cDC.GetTextMetrics(&tm);
m_iMinHeight = tm.tmHeight + tm.tmExternalLeading;
m_iMinWidth = tm.tmMaxCharWidth;
cDC.SelectObject(pOldFont);
cDC.DeleteDC();
}
// activates and window and restores it's size (i.e. unminimizes it)
// idea and primary implementation: Alexey N. Kirpa (alexeykirpa@mail.ru)
void CTabBarsWnd::ActivateWindow(CComQIPtr<IGenericWindow, &IID_IGenericWindow>& pWindow,BOOL bActive)
{
DsWindowState dsWindowState;
pWindow->get_WindowState(&dsWindowState);
if (dsWindowState == dsWindowStateMinimized)
{
pWindow->put_WindowState(dsWindowStateNormal);
}
pWindow->put_Active(bActive ? VARIANT_TRUE : VARIANT_FALSE);
}
// **************************************************************************
// BUG BUG: MFC's _AFXFindPopupMenuFromID won't find submenu text entries.
// Instead of recompiling the MFC dll's, I've placed the following two
// replacement functions (_FixedAfxFindPopupMenuFromID and OnMeasureItem)
// here. They two functions are basically copies of their respectived MFC
// functions - but with the necessery fixes.
static CMenu* AFXAPI _FixedAfxFindPopupMenuFromID(CMenu* pMenu, UINT nID)
{
ASSERT_VALID(pMenu);
// walk through all items, looking for ID match
UINT nItems = pMenu->GetMenuItemCount();
for (int iItem = 0; iItem < (int)nItems; iItem++)
{
CMenu* pPopup = pMenu->GetSubMenu(iItem);
if (pPopup != NULL)
{
if ((UINT)pPopup->GetSafeHmenu() != nID)
{
// recurse to child popup
pPopup = _FixedAfxFindPopupMenuFromID(pPopup, nID);
}
if (pPopup != NULL)
return pPopup;
}
else if (pMenu->GetMenuItemID(iItem) == nID)
{
// it is a normal item inside our popup
pMenu = CMenu::FromHandlePermanent(pMenu->m_hMenu);
return pMenu;
}
}
// not found
return NULL;
}
// Measure item implementation relies on unique control/menu IDs
void CTabBarsWnd::OnMeasureItem(int /*nIDCtl*/, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if (lpMeasureItemStruct->CtlType == ODT_MENU)
{
ASSERT(lpMeasureItemStruct->CtlID == 0);
CMenu* pMenu;
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_hTrackingWindow == m_hWnd)
{
// start from popup
pMenu = CMenu::FromHandle(pThreadState->m_hTrackingMenu);
}
else
{
// start from menubar
pMenu = GetMenu();
}
pMenu = _FixedAfxFindPopupMenuFromID(pMenu, lpMeasureItemStruct->itemID);
if (pMenu != NULL)
pMenu->MeasureItem(lpMeasureItemStruct);
else
TRACE1("Warning: unknown WM_MEASUREITEM for menu item 0x%04X.\n", lpMeasureItemStruct->itemID);
}
else
{
CWnd* pChild = GetDescendantWindow(lpMeasureItemStruct->CtlID, TRUE);
if (pChild != NULL && pChild->SendChildNotifyLastMsg())
return; // eaten by child
}
// not handled - do default
Default();
}
// *** ends: MFC bug fix ****************************************************
void CTabBarsWnd::OnTimer(UINT nIDEvent)
{
static count = 0;
if(g_bAutoSave)
{
count++;
if(count > g_nSaveTimeSpan * 6)
{
count = 0;
CComBSTR bStr;
bStr = _T("FileSaveAll");
m_pApplication->ExecuteCommand(bStr);
}
}
CWnd::OnTimer(nIDEvent);
}
BOOL CTabBarsWnd::DestroyWindow()
{
if(m_uTimerID != 0)
KillTimer(m_uTimerID);
return CWnd::DestroyWindow();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -