⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xptabctrl.cpp

📁 一个详细的学籍管理系统源码,支持数据查找、排序、导入、导出
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"
#include "XPTabCtrl.h"

#include "..\StudentRecords.h"
#include "..\IndexSet.h"
#include "..\InputData.h"
#include "..\QueryData.h"
#include "..\PaiTxtData.h"
#include "..\About.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;

	m_tabPages[0]=new CIndexSet;
	m_tabPages[1]=new CInputData;
	m_tabPages[2]=new CQueryData;
	m_tabPages[3]=new CPaiTxtData;
	m_tabPages[4]=new CAboutDlg;

	m_nNumberOfPages=5;
}

CXPTabCtrl::~CXPTabCtrl()
{
	for(int nCount=0; nCount < m_nNumberOfPages; nCount++)
	{
		delete m_tabPages[nCount];
	}
}
//----------------------------------------------------------------------------------------------------------
// 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
	ON_WM_LBUTTONDOWN()
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 HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
	if(bBody && bVertic)					// when it is right oriented body -> flip twice, first flip border shadows, than flip shaded inside body again
	{	nStart=2; nLenSub=4; bihOut.biHeight=szBmp.cy;
	GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
	bihOut.biHeight=-szBmp.cy;			// to mirror bitmap is eough to use negative height between Get/SetDIBits
	SetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
	}	}	}
	// 5th if it is bottom or right oriented tab, draw after mirroring background (do GetDIBits again)
	if(!bBody && ixItem>=0)							// 
	{	if(bSel) rcMem.bottom--;
	DrawTabItem(&dcMem, ixItem, rcMem, uiFlag);
	if(bVertic)											// if it is right tab, do GetDIBits again
	{	bihOut.biHeight=-szBmp.cy;
	GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS);
	}	}
	// 6th: do rotate now, finaly
	if(bVertic)							// force rotating bitmap as RGB -> good for any resolution
	{	SwapVars(szBmp.cx,szBmp.cy);

	int nBmpWdtPD=DWordAlign(szBmp.cx*3);
	int nPadD=nBmpWdtPD-szBmp.cx*3;
	int nSzBuffPD=((nBmpWdtPD*szBmp.cy)/8+2)*8;
	LPBYTE pcImgRotate=new BYTE[nSzBuffPD]; ASSERT(pcImgRotate);
	int nWidth,nHeight=szBmp.cy,nHeight1=nHeight-1;
	//====================================
	//------------------------------------
	// here is the example how to speed up lengthy repeatetive processing by using inline assembler
#define __USE_MASM__		// the same processing is in C and in asm. To use C -> comment the beginning of this line
	// Do the actual whole RGB bitmap rotating in C or assembler
#ifndef __USE_MASM__
	LPBYTE pcImgS=pcImg;
	LPBYTE pcImgD=pcImgRotate;
	int ixHeight=0;
	BOOL bLast=FALSE;
	while(ixHeight<nHeight)					// for all destination height lines
	{	nWidth=szBmp.cx;
	if(ixHeight==nHeight1) { bLast=TRUE; nWidth--; }

	while(nWidth--)
	{	*(PDWORD)pcImgD=*(PDWORD)pcImgS; // do all Rgb triplets read/write qicker as DWORD
	pcImgS+=nBmpWdtPS;	// increment source in padded source lines
	pcImgD+=3;			// increment destination in rgb triplets
	}
	if(bLast)				// when the last line, the last pixel - colud be a problem if bitmap DWORD alligned 
		for(int c=3;c;c--) *pcImgD++=*pcImgS++;		// (only last three bytes available->could not read/write DWORD)!!
	else
	{	ixHeight++;
	pcImgD+=nPadD;				// destination bitmap horizontal padding to DWORD
	pcImgS=pcImg+(ixHeight*3);	// reset the source to the begining of the next vertical line
	}	}
#else	// __USE_MASM__
	nBmpWdtPS-=4;					// adjust esi increment (due to esi self-incrementing by movsd)
	nWidth=szBmp.cx;
	__asm
	{		mov		esi, pcImg			// source index
	mov		edi, pcImgRotate	// destination index
	xor		ebx, ebx			// vertical counter
loop_height:
	mov		ecx, nWidth			// horizontal counter
		cmp		ebx, nHeight1		// check is it the last line
		jne		loop_width
		dec		ecx					// if it is decremnt for the last pixel

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -