清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
#ifndef _DBUFF_VEW_H
#define _DBUFF_VEW_H
#include <atlbase.h>
#include <atlstr.h>
#include <atlapp.h>
#include <atlframe.h>
#include <atlctrls.h>
#include <atlgdix.h>
#include <atlcoll.h>
#include <atlcrack.h>
#include <atlctrlw.h>
#define _WTL_NO_CSTRING
#include <atlmisc.h>
#include <iostream>
#include <array>
#include "resource.h"
using namespace std;
extern HINSTANCE g_hInstance;
#define DRG_NONE 0
#define DRG_COL_MOVE 1
#define DRG_COL_SIZE 2
#define SIZE_POINT 3
typedef CWinTraitsOR<WS_HSCROLL|WS_VSCROLL,WS_EX_CLIENTEDGE,CControlWinTraits> DBuffViewTraits;
class CGridView : public CDoubleBufferWindowImpl<CGridView,CWindow,DBuffViewTraits>
{
public:
DECLARE_WND_CLASS_EX(_T("CGridView"),0,COLOR_BTNFACE)
typedef CDoubleBufferWindowImpl<CGridView,CWindow,DBuffViewTraits> _baseClass;
BEGIN_MSG_MAP(CGridView)
MSG_WM_HSCROLL(OnHScroll)
MSG_WM_VSCROLL(OnVScroll)
MSG_WM_CREATE(OnCreate)
MSG_WM_MOUSEMOVE(OnMouseMove)
MSG_WM_MOUSEWHEEL(OnMouseWheel)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_LBUTTONUP(OnLButtonUp)
CHAIN_MSG_MAP(_baseClass)
END_MSG_MAP()
struct COLINFO
{
int Idx;
int Width;
BYTE HorzAlg;
int ColIdx;
};
//
void ColAt(int x, int &Col , int &Start , int &End)
{
int Off = m_IndWidth;
for (int i = m_StartCol ; i < m_Cols.size() ; i++)
{
Off += m_Cols[i].Width;
if ( x <= Off )
{
Start = Off - m_Cols[i].Width;
End = Off;
Col = i;
return;
}
}
}
//
void OnLButtonDown(UINT nFlags, CPoint point)
{
if ( point.x > m_IndWidth && point.y < m_HeaderHeight && ::DragDetect(m_hWnd,point) )
{
ColAt(point.x, m_DragCol, m_DragStart, m_DragEnd);
SetCapture();
if ( point.x > m_DragEnd - SIZE_POINT )
{
SetCursor(LoadCursor(g_hInstance,MAKEINTRESOURCE(WTLDEMO_SIZE)));
m_DragType = DRG_COL_SIZE;
}
else
{
SetCursor(LoadCursor(g_hInstance,MAKEINTRESOURCE(WTLDEMO_DRAG)));
m_DragType = DRG_COL_MOVE;
}
}
}
//
void OnLButtonUp(UINT nFlags, CPoint point)
{
if ( point.x < 0 || point.y < 0 )
goto ret;
if ( m_DragType == DRG_COL_MOVE )
{
int DropCol;
int Dummy;
ColAt(point.x, DropCol, Dummy, Dummy);
COLINFO tmp = m_Cols[m_DragCol];
if ( DropCol == m_DragCol ) goto ret;
if ( DropCol < m_DragCol )
{
for (int i = m_DragCol ; i < m_Cols.size()-1; i++)
m_Cols[i] = m_Cols[i+1];
for (int i = m_Cols.size() -1 ; i > DropCol ; i--)
m_Cols[i] = m_Cols[i-1];
m_Cols[DropCol] = tmp;
}
else
{
for (int i = m_DragCol ; i < DropCol; i++)
m_Cols[i] = m_Cols[i+1];
m_Cols[DropCol] = tmp;
}
}
if ( m_DragType == DRG_COL_SIZE )
{
m_Cols[m_DragCol].Width = max(m_DragRc.right - m_DragRc.left,3);
}
ret:
SetCursor(LoadCursor(NULL,IDC_ARROW));
ReleaseCapture();
m_DragType = DRG_NONE;
Invalidate();
}
//
void OnMouseMove(UINT nFlags, CPoint point)
{
if (m_DragType == DRG_COL_MOVE )
{
int Width = m_Cols[m_DragCol].Width;
m_DragRc.left = point.x-Width/2;
m_DragRc.top = point.y- m_HeaderHeight/2;
m_DragRc.right = point.x+Width/2;
m_DragRc.bottom = point.y+m_HeaderHeight/2;
Invalidate();
return;
}
if ( m_DragType == DRG_COL_SIZE )
{
m_DragRc.left = m_DragStart;
m_DragRc.top = 0;
m_DragRc.right = point.x;
m_DragRc.bottom = m_HeaderHeight;
Invalidate();
return;
}
int Dummy , End;
ColAt(point.x, Dummy, Dummy, End);
if ( point.x > End - SIZE_POINT )
SetCursor(LoadCursor(g_hInstance,MAKEINTRESOURCE(WTLDEMO_SIZE)));
else if ( point.y < m_HeaderHeight )
SetCursor(LoadCursor(g_hInstance,MAKEINTRESOURCE(WTLDEMO_GRAB)));
}
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
if ( zDelta < 0 )
{
if ( nFlags & MK_CONTROL )
PageScroll(false);
else
PageScroll();
}
else
{
if ( nFlags & MK_CONTROL )
PageScroll(false,false);
else
PageScroll(true,false);
}
return TRUE;
}
void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
{
SCROLLINFO sc = { sizeof(SCROLLINFO), SIF_POS };
switch (nSBCode)
{
case SB_PAGERIGHT:
PageScroll(false);
break;
case SB_PAGELEFT:
PageScroll(false,false);
break;
case SB_LINERIGHT:
LineScroll(false);
break;
case SB_LINELEFT:
LineScroll(false,false);
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
m_StartCol = nPos;
sc.nPos = m_StartCol;
SetScrollInfo(SB_HORZ,&sc);
Invalidate();
break;
}
}
void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
{
SCROLLINFO sc = { sizeof(SCROLLINFO), SIF_POS };
switch (nSBCode)
{
case SB_PAGEDOWN:
PageScroll();
break;
case SB_PAGEUP:
PageScroll(true,false);
break;
case SB_LINERIGHT:
LineScroll();
break;
case SB_LINELEFT:
LineScroll(true,false);
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
m_StartRow = nPos;
sc.nPos = m_StartRow;
SetScrollInfo(SB_VERT,&sc);
Invalidate();
break;
}
}
void UpdateScrollBar(bool vertical = true)
{
SCROLLINFO sc = { sizeof(SCROLLINFO), SIF_POS };
if ( vertical )
{
sc.nPos = m_StartRow;
SetScrollInfo(SB_VERT,&sc);
}
else
{
sc.nPos = m_StartCol;
SetScrollInfo(SB_HORZ,&sc);
}
Invalidate();
}
void PageScroll(bool vertical = true , bool down = true)
{
if ( vertical )
{
m_StartRow += down ? m_PageCnt : - m_PageCnt;
m_StartRow = min(max(m_StartRow,0),m_Rows.size()-1);
}
else
{
m_StartCol += down ? m_PageCnt : - m_PageCnt;
m_StartCol = min(max(m_StartCol,0),m_Cols.size()-1);
}
UpdateScrollBar(vertical);
}
void LineScroll(bool vertical = true, bool down = true)
{
if ( vertical )
{
m_StartRow += down ? m_LineCnt : - m_LineCnt;
m_StartRow =min( max(m_StartRow,0),m_Rows.size()-1);
}
else
{
m_StartCol += down ? m_LineCnt : - m_LineCnt;
m_StartCol = min(max(m_StartCol,0),m_Cols.size()-1);
}
UpdateScrollBar(vertical);
}
void DoPaint(CDCHandle dc)
{
HBRUSH OldBrush;
HFONT OldFont;
OldFont = dc.SelectFont(m_GridFont);
OldBrush = dc.SelectBrush(m_Bk);
DrawBackGround(dc);
DrawHLines(dc);
DrawVLines(dc);
DrawIndicators(dc);
DrawColumnHeadders(dc);
DrawCells(dc);
if ( m_DragType == DRG_COL_MOVE || m_DragType == DRG_COL_SIZE )
DrawColumnHeader(dc, m_DragRc, m_Cols[m_DragCol].HorzAlg, m_Cols[m_DragCol].Idx);
dc.SelectFont(OldFont);
dc.SelectBrush(OldBrush);
}
void DrawHLines(CDCHandle dc)
{
RECT rc;
HPEN OldPen;
OldPen = dc.SelectPen(m_GridPen);
dc.SetBkMode(TRANSPARENT);
GetClientRect(&rc);
for (int i = 2 ; i < 100; i++)
{
dc.MoveTo(m_IndWidth, i*m_IndHeight);
dc.LineTo(m_IndWidth + rc.right, i*m_IndHeight);
}
dc.SelectPen(OldPen);
}
void DrawVLines(CDCHandle dc)
{
RECT rc;
HPEN OldPen;
OldPen = dc.SelectPen(m_GridPen);
dc.SetBkMode(TRANSPARENT);
int EndCol;
GetClientRect(&rc);
EndCol = rc.right;
int Off = 0;
for (int i = m_StartCol ; EndCol > 0 && i < m_Cols.size(); i++)
{
dc.MoveTo(m_IndWidth + Off + m_Cols[i].Width, m_HeaderHeight);
dc.LineTo(m_IndWidth + Off + m_Cols[i].Width, rc.bottom);
Off += m_Cols[i].Width;
EndCol -= m_Cols[i].Width;
}
dc.SelectPen(OldPen);
}
void DrawCells(CDCHandle dc)
{
RECT rc;
HPEN OldPen;
OldPen = dc.SelectPen(m_GridPen);
int EndRow , EndCol , Idx = 0;
GetClientRect(&rc);
EndRow = rc.bottom;
EndCol = rc.right;
dc.SetBkMode(TRANSPARENT);
for (int i = m_StartRow ; EndRow > 0 && i < m_Rows.size(); i++)
{
int Off = 0;
int Delta = EndCol;
for ( int j = m_StartCol ; Delta > 0 && j < m_Cols.size() ; j++)
{
rc.left = m_IndWidth + Off;
rc.top = m_HeaderHeight + Idx * m_IndHeight + m_Padding;
rc.right= m_IndWidth + Off + m_Cols[j].Width + m_Padding;
rc.bottom = rc.top + m_IndHeight;
rc.left++;
rc.top++;
rc.right--;
rc.bottom--;
char *Cell = m_Rows[i][m_Cols[j].ColIdx];
//sprintf(Cell,"Cell %d.%d", m_StartRow + i, m_Cols[j].Idx);
dc.DrawText(Cell, strlen(Cell), &rc,
DT_SINGLELINE | DT_VCENTER | m_Cols[j].HorzAlg | DT_END_ELLIPSIS);
Off += m_Cols[j].Width;
Delta -= m_Cols[j].Width;
}
Idx++;
EndRow -= m_IndHeight;
}
dc.SelectPen(OldPen);
}
//
void DrawColumnHeader(CDCHandle dc , RECT &rc , int Alg , int Idx)
{
HPEN OldPen;
TCHAR title[200];
OldPen = dc.SelectPen(m_GridPen);
dc.SetBkMode(TRANSPARENT);
dc.FillRect(&rc,::GetSysColorBrush(COLOR_3DFACE));
dc.Draw3dRect(rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
::GetSysColor(COLOR_3DHILIGHT),
::GetSysColor(COLOR_3DSHADOW));
sprintf(title,"COLUMN %d",Idx);
rc.left++;
rc.top++;
rc.bottom--;
rc.right--;
dc.DrawText(title, strlen(title), &rc,
DT_SINGLELINE | DT_VCENTER | Alg | DT_END_ELLIPSIS);
dc.SelectPen(OldPen);
}
void DrawColumnHeadders(CDCHandle dc)
{
RECT rc;
int Off = 0;
int Idx = 0;
int EndCol;
GetClientRect(&rc);
EndCol = rc.right;
for ( int i=m_StartCol ; EndCol > 0 && i < m_Cols.size(); i++ )
{
rc.left = m_IndWidth + Off;
rc.right = rc.left + m_Cols[i].Width + m_Padding;
rc.top = 0;
rc.bottom = m_HeaderHeight;
DrawColumnHeader(dc,rc,m_Cols[i].HorzAlg, m_Cols[i].Idx);
Off += m_Cols[i].Width;
EndCol -= m_Cols[i].Width;
}
}
void DrawIndicators(CDCHandle dc)
{
RECT rc;
int EndRow;
TCHAR num[100];
GetClientRect(&rc);
EndRow = rc.bottom / m_IndHeight;
for (int i = 0 ; i< EndRow ; i++)
{
RECT rc = { 0,
i* m_IndHeight + m_HeaderHeight + m_Padding,
m_IndWidth,
i* m_IndHeight + m_IndHeight + m_HeaderHeight };
dc.FillRect(&rc,::GetSysColorBrush(COLOR_3DFACE));
dc.Draw3dRect(rc.left,
rc.top,
rc.right-rc.left,
rc.bottom-rc.top,
::GetSysColor(COLOR_3DHILIGHT),
::GetSysColor(COLOR_3DSHADOW));
sprintf(num,"%d",m_StartRow + i);
rc.left++;
rc.top++;
rc.bottom--;
rc.right--;
dc.SetBkMode(TRANSPARENT);
dc.DrawText(num, strlen(num), &rc,
DT_SINGLELINE | DT_VCENTER | DT_RIGHT | DT_END_ELLIPSIS);
}
}
void DrawBackGround(CDCHandle dc)
{
RECT rc;
GetClientRect(&rc);
dc.FillRect(&rc,m_Bk);
}
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
RECT rc;
SCROLLINFO sc = { sizeof(SCROLLINFO), SIF_PAGE |SIF_POS };
GetClientRect(&rc);
SetScrollRange(SB_HORZ,0,m_Width-1);
SetScrollRange(SB_VERT,0,m_Height-1);
//
if ( m_Width <= (rc.right - rc.left) )
ShowScrollBar(SB_HORZ,FALSE);
else
{
}
if ( m_Height <= rc.bottom - rc.top )
ShowScrollBar(SB_VERT,FALSE);
return 0;
}
CGridView() :
m_Width(0),
m_Height(0),
m_IndWidth(50),
m_IndHeight(20),
m_Padding(0),
m_StartRow(0),
m_StartCol(0),
m_HeaderHeight(20),
m_PageCnt(10),
m_LineCnt(1),
m_DragType(DRG_NONE)
{
//
LOGBRUSH Pen = {0};
Pen.lbStyle = BS_SOLID;
Pen.lbColor = RGB(230,230,230);
DWORD PenStyle[2] = {1,1};
m_GridPen.CreatePen(PS_COSMETIC | PS_USERSTYLE,1,&Pen,2,PenStyle);
//
LOGFONT fnt = {0};
fnt.lfHeight = min(m_HeaderHeight,20);
fnt.lfWeight = 2;
sprintf(fnt.lfFaceName,_T("Courier New"));
m_GridFont.CreateFontIndirect(&fnt);
//
m_Bk.CreateSolidBrush(RGB(255,255,255));
//
for (int i = 0; i < 300 ; i++)
{
COLINFO col;
col.Idx = i;
col.Width = 150;
col.ColIdx = i;
col.HorzAlg = i % 4 ? DT_RIGHT : DT_LEFT;
m_Cols[i] = col;
m_Width++;
}
for ( int i = 0 ; i < 500 ; i++)
{
for ( int j = 0 ; j< 300; j++ )
{
char *buf = new char[200];
sprintf(buf,"Cell %d.%d",i,j);
m_Rows[i][j] = buf;
}
m_Height++;
}
}
~CGridView()
{
for ( int i = 0 ; i < 500 ; i++)
{
for ( int j = 0 ; j< 300; j++ )
{
//cout << m_Rows[i][j] << endl;
delete m_Rows[i][j];
}
}
}
virtual void OnFinalMessage(HWND /*hWnd*/)
{
delete this;
}
private:
int m_Width; // Column Count
int m_Height; // Row Count
int m_IndWidth;
int m_IndHeight;
int m_Padding;
int m_StartRow;
int m_StartCol;
int m_PageCnt;
int m_LineCnt;
CPen m_GridPen;
CFont m_GridFont;
CBrush m_Bk;
RECT m_DragRc;
int m_DragCol;
int m_DragStart;
int m_DragEnd;
std::tr1::array<COLINFO,300> m_Cols;
std::tr1::array< std::tr1::array<char*,300>,500> m_Rows;
int m_HeaderHeight;
int m_DragType;
};
#endif