/***********************************************************************************************************/
// XPTabCtrl.cpp : implementation file
/////////////////////////////////////////////////////////////////////////////
// Compiler: Visual C++, Service Pack 5, Windows NT
// Tested on: Windows NT, Windows XP
//
// Created: 25/February/2004
// Updated:
//
// Author: Adi DEDIC
// e-mail: [email protected]
// www: http://web.onetel.net.uk/~adidedic/
//
// Disclaimer
// ----------
// THIS SOFTWARE AND THE ACCOMPANYING FILES ARE DISTRIBUTED "AS IS" AND WITHOUT
// ANY WARRANTIES WHETHER EXPRESSED OR IMPLIED. NO REPONSIBILITIES FOR POSSIBLE
// DAMAGES OR EVEN FUNCTIONALITY CAN BE TAKEN. THE USER MUST ASSUME THE ENTIRE
// RISK OF USING THIS SOFTWARE.
//
// Terms of use
// ------------
// THIS SOFTWARE IS FREE FOR PERSONAL USE OR FREEWARE APPLICATIONS.
// IF YOU USE THIS SOFTWARE IN COMMERCIAL OR SHAREWARE APPLICATIONS YOU
// ARE GENTLY ASKED TO DONATE �1 (ONE GB PUND) TO THE AUTHOR
/***********************************************************************************************************/
#include "StdAfx.h"
#include "XPTabCtrl.h"
//#define USE_DEFAULT_XP_TOPTAB // XP top tab is drawn only for test purpose. To use default, uncoment this line
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/***********************************************************************************************************/
// constant string definitions here (or you can put it into resource string table)
#define IDS_UTIL_TAB "TAB"
#define IDS_UTIL_UXTHEME "UxTheme.dll"
#define IDS_UTIL_THEMEACT "IsThemeActive"
#define IDS_UTIL_THEMEOPN "OpenThemeData"
#define IDS_UTIL_THEMEBCKG "DrawThemeBackground"
/***********************************************************************************************************/
// CXPTabCtrl
/***********************************************************************************************************/
CXPTabCtrl::CXPTabCtrl()
{
m_bTabExtended=TRUE; // default is to use extended tab (if it is Themes XP)
m_eTabOrientation=e_tabBottom; // default initial orientation is: bottom
m_ixSelOld=-1;
}
//----------------------------------------------------------------------------------------------------------
// nBitmapID Resource IDs of the bitmap to be associated with the image list.
void CXPTabCtrl::InitImageList(UINT nBitmapID)
{
if(!::IsWindow(GetSafeHwnd()) || m_ilTabs.operator HIMAGELIST())
{ ASSERT(FALSE); return; } // tab control has to be created first and image list can be created only once
if(m_ilTabs.Create(nBitmapID, 16, 1, RGB(0xFF,0,0xFF))) // add an images list with appropriate background (transparent) color
SetImageList(&m_ilTabs);
}
//----------------------------------------------------------------------------------------------------------
// only three messages used
BEGIN_MESSAGE_MAP(CXPTabCtrl, CTabCtrl)
//{{AFX_MSG_MAP(CXPTabCtrl)
ON_WM_PAINT()
ON_NOTIFY_REFLECT(TCN_SELCHANGING,OnTabSelChanging)
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnTabSelChanged)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//----------------------------------------------------------------------------------------------------------
void CXPTabCtrl::OnPaint()
{
if(!IsExtendedTabTheamedXP()) // if it is not XP or it is not Themes, behave as default
{ Default(); return; }
CPaintDC dc(this); // device context for painting
CRect rcClip; rcClip.SetRectEmpty();
dc.GetClipBox(rcClip);
// 1st paint the tab body
CRect rcPage,rcItem,rcClient;
GetClientRect(&rcPage);
rcClient=rcPage;
AdjustRect(FALSE,rcPage);
switch(m_eTabOrientation)
{ case e_tabTop: rcClient.top =rcPage.top -2; break;
case e_tabBottom: rcClient.bottom=rcPage.bottom+3; break;
case e_tabLeft: rcClient.left =rcPage.left -1; break;
case e_tabRight: rcClient.right =rcPage.right +3; break;
default: ASSERT(FALSE); return;
}
UINT uiVertBottm;
uiVertBottm =(m_eTabOrientation&1)? 8:0; // 8=bottom
uiVertBottm|=(m_eTabOrientation&2)?16:0; // 16=vertical
UINT uiFlags=1|uiVertBottm; // 1=body
DrawThemesXpTabItem(&dc, -1, rcClient,uiFlags); // TABP_PANE=9,0,'TAB'
int nTab=GetItemCount(); // paint the tabs first and then the borders
if(!nTab) return; // no tab pages added
// 2nd paint the inactive tabs
CRect ;
TCHITTESTINFO hti; hti.flags=0;
::GetCursorPos(&hti.pt); ScreenToClient(&hti.pt);
int ixHot=HitTest(&hti);
int ixSel=GetCurSel();
for(int ixTab=0; ixTab<nTab; ixTab++)
{ if(ixTab==ixSel)
continue;
VERIFY(GetItemRect(ixTab, &rcItem));
if(m_eTabOrientation==e_tabLeft) rcItem.right++;
uiFlags=uiVertBottm|(ixTab==ixHot?4:0); // 4= hot
DrawThemesXpTabItem(&dc,ixTab,rcItem,uiFlags);
}
// 3rd paint the active selected tab
VERIFY(GetItemRect(ixSel, &rcItem)); // now selected tab
rcItem.InflateRect(2,2);
if(m_eTabOrientation==e_tabTop) rcItem.bottom--;
uiFlags=uiVertBottm|2; // 2= selected
DrawThemesXpTabItem(&dc, ixSel, rcItem,uiFlags);
}
//----------------------------------------------------------------------------------------------------------
// This function draws Themes Tab control parts: a) Tab-Body and b) Tab-tabs
void CXPTabCtrl::DrawThemesXpTabItem(CDC* pDC, int ixItem, const CRect& rcItem, UINT uiFlag)
{ // uiFlag(1/0):1=Type(body/tab);2=Sel(y/n);4=Hot(y/n);8=bBottom(y/n);16=rotate(y/n)
BOOL bBody =(uiFlag& 1)?TRUE:FALSE;
BOOL bSel =(uiFlag& 2)?TRUE:FALSE;
BOOL bHot =(uiFlag& 4)?TRUE:FALSE;
BOOL bBottom=(uiFlag& 8)?TRUE:FALSE; // mirror
BOOL bVertic=(uiFlag&16)?TRUE:FALSE; // rotate
BOOL bLeftTab=!bBottom && bVertic && !bBody;
CSize szBmp=rcItem.Size();
if(bVertic) SwapVars(szBmp.cx,szBmp.cy);
// 1st draw background
CDC dcMem; dcMem .CreateCompatibleDC(pDC);
CBitmap bmpMem; bmpMem.CreateCompatibleBitmap(pDC,szBmp.cx,szBmp.cy);
CBitmap* pBmpOld=dcMem.SelectObject(&bmpMem);
CRect rcMem(CPoint(0,0),szBmp); if(bSel) rcMem.bottom++;
if(bBody)
DrawThemesPart(dcMem.GetSafeHdc(), 9, 0, (LPCSTR)IDS_UTIL_TAB, &rcMem); // TABP_PANE=9, 0, 'TAB'
else DrawThemesPart(dcMem.GetSafeHdc(), 1, bSel?3:(bHot?2:1), (LPCSTR)IDS_UTIL_TAB, &rcMem);
// TABP_TABITEM=1, TIS_SELECTED=3:TIS_HOT=2:TIS_NORMAL=1, 'TAB'
// 2nd init some extra parameters
BITMAPINFO biOut; ZeroMemory(&biOut,sizeof(BITMAPINFO)); // Fill local pixel arrays
BITMAPINFOHEADER& bihOut=biOut.bmiHeader;
bihOut.biSize =sizeof (BITMAPINFOHEADER);
bihOut.biCompression=BI_RGB;
bihOut.biPlanes=1; bihOut.biBitCount=24; // force as RGB: 3 bytes,24 bits -> good for rotating bitmap in any resolution
bihOut.biWidth =szBmp.cx; bihOut.biHeight=szBmp.cy;
int nBmpWdtPS=DWordAlign(szBmp.cx*3);
int nSzBuffPS=((nBmpWdtPS*szBmp.cy)/8+2)*8;
LPBYTE pcImg=NULL;
if(bBottom || bVertic) { pcImg=new BYTE[nSzBuffPS]; ASSERT(pcImg); }
int nStart=0,nLenSub=0;
if(bBody && bBottom && !bVertic) nStart=3,nLenSub=4; // if bottom oriented flip the body contest only (no shadows were flipped)
// 3rd if it is left oriented tab, draw tab context before mirroring or rotating (before GetDIBits)
if(bVertic)
{ if(bBody || !bBottom) bihOut.biHeight=-szBmp.cy;
if(!bBottom && !bBody && ixItem>=0) //
{ if(bSel) rcMem.bottom--;
DrawTabItem(&dcMem, ixItem, rcMem, uiFlag); ixItem=-1;
} } // rotate or mirror
// 4th get bits (for rotate) and mirror: body=(all except top) tab=(all except top)
if(bVertic || bBottom) // get bits:
{ GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
if(bBottom) // mirror: body=(bottom and right) tab=(bottom and right)
{ bihOut.biHeight=-szBmp.cy; // to mirror bitmap is eough to use negative height between Get/SetDIBits
SetDIBits(*pDC, bmpMem.operator
XP-class.zip_class XP
版权申诉
132 浏览量
2022-09-21
07:48:33
上传
评论
收藏 20KB ZIP 举报
JonSco
- 粉丝: 72
- 资源: 1万+
最新资源
- 下载安装这个软件.apk
- 【数据集详细解释及案例分析】数据集详细解释及案例分析
- 基于SHT71温湿度传感器、STM32F103C8T6、LCD1602温湿度采集显示系统proteus仿真设计
- 基于TH02温湿度传感器、STM32F103C8T6、LCD1602、FREERTOS的温湿度采集系统proteus仿真设计
- 【TCP-IP协议详细解释及案例分析】TCP-IP协议详细解释及案例分析
- 一文搞懂 LSTM(长短期记忆网络).rar
- 【autosar简介及基本案例解析】autosar简介及基本案例解析
- java模拟斗地主洗牌发牌
- springboot+vue登录系统 vue部分
- 常用常见 SQL语句语法
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈