/****************************************************************************\
Datei : MDITabs.h
Projekt: MDITabs, a tabcontrol for switching between MDI-views
Inhalt : CMDITabs implementation
Datum : 03.10.2001
Autor : Christian Rodemeyer
Hinweis: � 2001 by Christian Rodemeyer
\****************************************************************************/
#include "stdafx.h"
#include "MDITabs.h"
#include <AFXPRIV.H>
#include <algorithm>
#include <vector>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMDITabs
CMDITabs::CMDITabs()
{
m_mdiClient = NULL;
m_minViews = 0;
m_bImages = false;
m_bTop = false;
}
BEGIN_MESSAGE_MAP(CMDITabs, CTabCtrl)
//{{AFX_MSG_MAP(CMDITabs)
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelChange)
ON_WM_PAINT()
ON_WM_NCPAINT()
ON_WM_CONTEXTMENU()
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMDITabs message handlers
afx_msg LRESULT CMDITabs::OnSizeParent(WPARAM, LPARAM lParam)
{
if (GetItemCount() < m_minViews)
{
ShowWindow(SW_HIDE);
}
else
{
AFX_SIZEPARENTPARAMS* pParams = reinterpret_cast<AFX_SIZEPARENTPARAMS*>(lParam);
const int height = 26 + (m_bImages ? 1 : 0);
const int offset = 2;
m_height = height + offset;
m_width = pParams->rect.right - pParams->rect.left;
if (m_bTop)
{
pParams->rect.top += height;
MoveWindow(pParams->rect.left, pParams->rect.top - height, m_width, m_height, true);
}
else
{
pParams->rect.bottom -= height;
MoveWindow(pParams->rect.left, pParams->rect.bottom - offset, m_width, m_height, true);
}
ShowWindow(SW_NORMAL);
}
return 0;
}
void CMDITabs::OnSelChange(NMHDR* pNMHDR, LRESULT* pResult)
{
TCITEM item;
item.mask = TCIF_PARAM;
GetItem(GetCurSel(), &item);
::BringWindowToTop(HWND(item.lParam));
*pResult = 0;
}
void CMDITabs::Update()
{
SetRedraw(false);
HWND active = ::GetTopWindow(m_mdiClient); // get active view window (actually the frame of the view)
typedef std::vector<HWND> TWndVec;
typedef TWndVec::iterator TWndIter;
TWndVec vChild; // put all child windows in a list (actually a vector)
for (HWND child = active; child; child = ::GetNextWindow(child, GW_HWNDNEXT))
{
vChild.push_back(child);
}
TCITEM item;
char text[256];
item.pszText = text;
for (int i = GetItemCount(); i--;) // for each tab
{
item.mask = TCIF_PARAM;
GetItem(i, &item);
TWndIter it = std::find(vChild.begin(), vChild.end(), HWND(item.lParam));
if (it == vChild.end()) // associatete view does no longer exist, so delete the tab
{
DeleteItem(i);
if (m_bImages) RemoveImage(i);
}
else // update the tab's text, image and selection state
{
item.mask = TCIF_TEXT;
::GetWindowText(*it, text, 256);
if (m_bImages) m_images.Replace(i, (HICON)::GetClassLong(*it, GCL_HICONSM));
SetItem(i, &item);
if (*it == active) SetCurSel(i); // associated view is active => make it the current selection
vChild.erase(it); // remove view from list
}
}
// all remaining views in vChild have to be added as new tabs
i = GetItemCount();
for (TWndIter it = vChild.begin(), end = vChild.end(); it != end; ++it)
{
item.mask = TCIF_TEXT|TCIF_PARAM|TCIF_IMAGE;
::GetWindowText(*it, text, 256);
if (m_bImages) m_images.Add((HICON)::GetClassLong(*it, GCL_HICONSM));
item.iImage = i;
item.lParam = LPARAM(*it);
InsertItem(i, &item);
if (*it == active) SetCurSel(i);
++i;
}
// this removes the control when there are no tabs and shows it when there is at least one tab
bool bShow = GetItemCount() >= m_minViews;
if ((!bShow && IsWindowVisible()) || (bShow && !IsWindowVisible()))
{
static_cast<CMDIFrameWnd*>(FromHandlePermanent(::GetParent(m_mdiClient)))->RecalcLayout();
}
RedrawWindow(NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
SetRedraw(true);
}
void CMDITabs::OnPaint()
{
CPaintDC dc(this);
if (GetItemCount() == 0) return; // do nothing
// cache some system colors
DWORD shadow = ::GetSysColor(COLOR_3DSHADOW);
DWORD dark = ::GetSysColor(COLOR_3DDKSHADOW);
DWORD hilight = ::GetSysColor(COLOR_3DHILIGHT);
DWORD light = ::GetSysColor(COLOR_3DLIGHT);
// Special preparations for spin-buttons (in case there are more tabs than fit into the window)
// extend borders and prevent system from overdrawing our new pixels
if (m_bTop)
{
::SetPixel(dc, m_width - 5, m_height - 8, hilight);
::SetPixel(dc, m_width - 5, m_height - 7, light);
::SetPixel(dc, m_width - 6, m_height - 8, hilight);
::SetPixel(dc, m_width - 6, m_height - 7, light);
::ExcludeClipRect(dc, 0, m_height - 6, m_width, m_height - 2);
::ExcludeClipRect(dc, m_width - 6, m_height - 8, m_width - 2, m_height - 6);
}
else
{
::SetPixel(dc, m_width - 5, 2, shadow);
::SetPixel(dc, m_width - 5, 3, dark);
::SetPixel(dc, m_width - 6, 2, shadow);
::SetPixel(dc, m_width - 6, 3, dark);
::ExcludeClipRect(dc, 0, 0, m_width, 2);
::ExcludeClipRect(dc, m_width - 6, 2, m_width - 2, 4);
}
// windows should draw the control as usual
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
pThreadState->m_lastSentMsg.wParam = WPARAM(HDC(dc));
Default();
// extend the horizontal border to the left margin
if (m_bTop)
{
::SetPixel(dc, 0, m_height - 8, hilight);
::SetPixel(dc, 0, m_height - 7, light);
}
else
{
::SetPixel(dc, 0, 2, shadow);
}
// special drawing if the leftmost tab is selected
CRect rect;
GetItemRect(GetCurSel(), rect);
if (rect.left == 2) // is at the leftmost position a tab selected?
{
// if yes, remove the leftmost white line and extend the bottom border of the tab
int j = m_bImages ? 1 : 0;
HPEN pen = ::CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DFACE));
HGDIOBJ old = ::SelectObject(dc, pen);
::MoveToEx(dc, 0, 2, NULL);
::LineTo(dc, 0, 22 + j);
::MoveToEx(dc, 1, 2, NULL);
::LineTo(dc, 1, 22 + j);
::SelectObject(dc, old);
::DeleteObject(pen);
if (m_bTop)
{
::SetPixel(dc, 0, 0, hilight); ::SetPixel(dc, 1, 0, hilight);
::SetPixel(dc, 0, 1, light); ::SetPixel(dc, 1, 1, light);
}
else
{
::SetPixel(dc, 0, 22 + j, shadow); ::SetPixel(dc, 1, 22 + j, shadow);
::SetPixel(dc, 0, 23 + j, dark); ::SetPixel(dc, 1, 23 + j, dark);
}
}
}
void CMDITabs::OnNcPaint()
{
HDC hdc = ::GetWindowDC(m_hWnd);
CRect rect;
rect.left = 0;
rect.top = m_bTop ? 0 : -2;
rect.right = m_width;
rect.bottom = m_height;
HPEN pen = ::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DFACE));
HGDIOBJ old = ::SelectObject(hdc, pen);
if (m_bTop)
{
DrawEdge(hdc, rect, EDGE_SUNKEN, BF_LEFT|BF_RIGHT|BF_TOP);
::MoveToEx(hdc, 2, m_height - 1, NULL);
::LineTo(hdc, m_width - 2, m_height - 1);
::MoveToEx(hdc, 2, m_height - 2, NULL);
::LineTo(hdc, m_width - 2, m_height - 2);
}
else
{
DrawEdge(hdc, rect, EDGE_SUNKEN, BF_LEFT|BF_RIGHT|BF_BOTTOM);
::MoveToEx(hdc, 2, 0, NULL);
::LineTo(hdc, m_width - 2, 0);
::MoveToEx(hdc, 2, 1, NULL);
::LineTo(hdc, m_width - 2, 1);
}
::SelectObject(hdc, old);
::DeleteObject(pen);
::ReleaseDC(m_hWnd, hdc);
}
void CMDITabs::Create(CFrameWnd* pMainFrame, DWORD dwStyle)
{
m_bTop = (dwStyle & MT_TOP);
m_minViews = (dwStyle & MT_HIDEWLT2VIEWS) ? 2 : 1;
CTabCtrl::Create(WS_CHILD|WS_VISIBLE|(m_bTop?0:T
基于MDI的CTabCtrl实例
5星 · 超过95%的资源 需积分: 18 17 浏览量
2011-01-14
12:28:26
上传
评论 1
收藏 32KB ZIP 举报
joromeh
- 粉丝: 4
- 资源: 29
最新资源
- 安卓11.0以上版本支持 手指单个手指双手指操作
- 电子密码锁使用说明(1).doc
- 上位机开发罗克韦尔abcip通信协议详解
- 基于去中心化联邦学习的货运速度预测时空模型-A decentralized federated learning-based s
- 适合新手的 OpenAI Sora 详细使用教程
- 驱动总裁离线安装包01
- NT98336 SDK 114版本
- torch-1.8.1+cu111-cp38-cp38-linux-x86-64.whl +torchvision
- 智能提取字幕-intel
- 计算机设计 - VB+ACCESS网络计时管理系统设计(源代码+系统),保证可靠运行,毕业生可参考,免费资源下载
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
前往页