📄 cgridctrl.cpp
字号:
#include "stdafx.h"
#include "Prog.h"
#include "MemDC.h"
#include "CGridCtrl.h"
#include "math.h"
#include "InPlaceEdit.h"
#include "InPlaceComboBox.h"
#include "zGridDate.h"
#include "zGridDateTime.h"
#include "zGridTime.h"
#include <afxadv.h> // For CSharedFile
#include <afxole.h> // For COleDataSource
#include <afxconv.h> // For LPTSTR -> LPSTR macros
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define SELECTED_CELL_FONT_WEIGHT 600 // wieght of text for selected items
IMPLEMENT_DYNCREATE(CGridCtrl, CWnd)
void AFXAPI DDX_GridControl(CDataExchange* pDX, int nIDC, CGridCtrl& rControl)
{
if (rControl.GetSafeHwnd() == NULL) // not subclassed yet
{
ASSERT(!pDX->m_bSaveAndValidate);
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
if (!rControl.SubclassWindow(hWndCtrl))
{
ASSERT(FALSE);
AfxThrowNotSupportedException();
}
#ifndef _AFX_NO_OCC_SUPPORT
else
{
if (pDX->m_pDlgWnd->GetSafeHwnd() != ::GetParent(rControl.GetSafeHwnd()))
rControl.AttachControlSite(pDX->m_pDlgWnd);
}
#endif //!_AFX_NO_OCC_SUPPORT
}
}
UINT GetMouseScrollLines()
{
int nScrollLines = 3;
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"),
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
TCHAR szData[128];
DWORD dwKeyDataType;
DWORD dwDataBufSize = sizeof(szData);
if (RegQueryValueEx(hKey, _T("WheelScrollLines"), NULL, &dwKeyDataType,
(LPBYTE) &szData, &dwDataBufSize) == ERROR_SUCCESS)
{
nScrollLines = _tcstoul(szData, NULL, 10);
}
RegCloseKey(hKey);
}
return nScrollLines;
}
/////////////////////////////////////////////////////////////////////////////
// CGridCtrl
CGridCtrl::CGridCtrl(int nRows, int nCols, int nFixedRows, int nFixedCols)
{
RegisterWindowClass();
m_bMustUninitOLE = FALSE;
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
m_crGridColour = RGB(0,0,0);
m_nRows = 0;
m_nCols = 0;
m_nFixedRows = 0;
m_nFixedCols = 0;
m_nDefCellHeight = 10; // These will get changed to something meaningful
m_nDefCellHeight = 30; // when the window is created or subclassed
m_nVScrollMax = 0; // Scroll position
m_nHScrollMax = 0;
m_nMargin = 0; // cell padding
m_nRowsPerWheelNotch = GetMouseScrollLines(); // Get the number of lines
// per mouse wheel notch to scroll
m_bFocusCell=FALSE;
m_bScrollGrid=FALSE;
m_MouseMode = MOUSE_NOTHING;
m_nGridLines = GVL_BOTH;
m_bEditable = TRUE;
m_bListMode = FALSE;
m_bAllowDraw = TRUE; // allow draw updates
m_bEnableSelection = TRUE;
m_bAllowRowResize = TRUE;
m_bAllowColumnResize = TRUE;
m_bSortOnClick = TRUE; // Sort on header row click if in list mode
m_bHandleTabKey = TRUE;
m_bDoubleBuffer = TRUE; // Use double buffering to avoid flicker?
m_bAscending = TRUE; // sorting stuff
m_SortColumn = -1;
m_nTimerID = 0; // For drag-selection
m_nTimerInterval = 25; // (in milliseconds)
m_nResizeCaptureRange = 3; // When resizing columns/row, the cursor has to be
bEnterToKeyDown=FALSE; //用来确定回车键是否转换为向下一格
// Initially use the system message font for the GridCtrl font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
memcpy(&m_Logfont, &(ncm.lfMessageFont), sizeof(LOGFONT));
// Set up the initial grid size
SetRowCount(nRows);
SetColumnCount(nCols);
SetFixedRowCount(nFixedRows);
SetFixedColumnCount(nFixedCols);
// Set the colours
SetTextColor(m_crWindowText);
SetTextBkColor(m_crWindowColour);
SetBkColor(m_crShadow);
SetFixedTextColor(m_crWindowText);
SetFixedBkColor(m_cr3DFace);
// set initial selection range (ie. none)
m_SelectedCellMap.RemoveAll();
m_PrevSelectedCellMap.RemoveAll();
::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);
m_lf.lfHeight=-12;
m_PreCell.col=-1;
m_PreCell.row=-1;
pImageArray=NULL;
pImgTemp=NULL;
m_TempCell.col=-1;
m_TempCell.row=-1;
m_CurCell.col=-1;
m_CurCell.row=-1;
m_nRadioCheckImagePos=-1;
pGridRadio=NULL;
m_bDblClkSort=TRUE;
m_bLineType=FALSE;
}
CGridCtrl::~CGridCtrl()
{
DeleteAllItems();
DestroyWindow();
m_Font.DeleteObject();
// Uninitialize OLE support
if (m_bMustUninitOLE)
::OleUninitialize();
}
// Register the window class if it has not already been registered.
BOOL CGridCtrl::RegisterWindowClass()
{
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetResourceHandle();
if (!(::GetClassInfo(hInst, GRIDCTRL_CLASSNAME, &wndcls)))
{
// otherwise we need to register a new class
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = NULL;
wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = GRIDCTRL_CLASSNAME;
if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
return FALSE;
}
}
return TRUE;
}
BOOL CGridCtrl::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwStyle)
{
ASSERT(pParentWnd->GetSafeHwnd());
if (!CWnd::Create(GRIDCTRL_CLASSNAME, NULL, dwStyle, rect, pParentWnd, nID))
{
return FALSE;
}
try
{
m_arRowHeights.SetSize(m_nRows); // initialize row heights
CGridColumn* pCol=NULL;
for(int col=0;col<m_nCols;col++)
{
if(m_ColData.GetSize()<=col)
{
pCol=new CGridColumn;
pCol->m_nWidth=m_nDefCellWidth;
m_ColData.Add(pCol);
}
}
}
catch (CMemoryException *e)
{
e->ReportError();
e->Delete();
return FALSE;
}
for (int i = 0; i < m_nRows; i++)
{
m_arRowHeights[i] = m_nDefCellHeight;
}
ResetScrollBars();
return TRUE;
}
void CGridCtrl::PreSubclassWindow()
{
CWnd::PreSubclassWindow();
Initialise();
HFONT hFont = ::CreateFontIndirect(&m_Logfont);
OnSetFont((LPARAM)hFont, 0);
DeleteObject(hFont);
ResetScrollBars();
}
BOOL CGridCtrl::SubclassWindow(HWND hWnd)
{
if (!CWnd::SubclassWindow(hWnd))
return FALSE;
return TRUE;
}
LRESULT CGridCtrl::SendMessageToParent(int nRow, int nCol, int nMessage)
{
if (!IsWindow(m_hWnd))
return 0;
NM_GRIDVIEW nmgv;
nmgv.iRow = nRow;
nmgv.iColumn = nCol;
nmgv.hdr.hwndFrom = m_hWnd;
nmgv.hdr.idFrom = GetDlgCtrlID();
nmgv.hdr.code = nMessage;
CWnd *pOwner = GetOwner();
if (pOwner && IsWindow(pOwner->m_hWnd))
return pOwner->SendMessage(WM_NOTIFY, nmgv.hdr.idFrom, (LPARAM)&nmgv);
else
return 0;
}
BEGIN_MESSAGE_MAP(CGridCtrl, CWnd)
//{{AFX_MSG_MAP(CGridCtrl)
ON_WM_PAINT()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_SIZE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_SETCURSOR()
ON_WM_SYSCOLORCHANGE()
ON_WM_CAPTURECHANGED()
ON_WM_ERASEBKGND()
ON_WM_CHAR()
//}}AFX_MSG_MAP
ON_WM_MOUSEWHEEL()
ON_WM_SETTINGCHANGE()
ON_MESSAGE(WM_SETFONT, OnSetFont)
ON_MESSAGE(WM_GETFONT, OnGetFont)
END_MESSAGE_MAP()
void CGridCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (m_bDoubleBuffer) // Use a memory DC to remove flicker
{
CMemDC MemDC(&dc);
OnDraw(&MemDC);
}
else
{
OnDraw(&dc);
}
}
void CGridCtrl::EraseBkgnd(CDC* pDC)
{
CRect VisRect, ClipRect, rect;
CBrush FixedBack(GetFixedBkColor()),
TextBack(GetTextBkColor()),
Back(GetBkColor());
if (pDC->GetClipBox(ClipRect) == ERROR)
{
return;
}
GetVisibleNonFixedCellRange(VisRect);
int nFixedColumnWidth = GetFixedColumnWidth();
if (ClipRect.left < nFixedColumnWidth && ClipRect.top < VisRect.bottom)
{
pDC->FillRect(CRect(ClipRect.left, ClipRect.top, nFixedColumnWidth, VisRect.bottom),&FixedBack);
}
int nFixedRowHeight = GetFixedRowHeight();
if (ClipRect.top < nFixedRowHeight && ClipRect.right > nFixedColumnWidth && ClipRect.left < VisRect.right)
{
pDC->FillRect(CRect(nFixedColumnWidth-1, ClipRect.top, VisRect.right, nFixedRowHeight),&FixedBack);
}
if (rect.IntersectRect(VisRect, ClipRect))
{
CRect CellRect(max(nFixedColumnWidth, rect.left), max(nFixedRowHeight, rect.top),rect.right, rect.bottom);
pDC->FillRect(CellRect, &TextBack);
}
if (VisRect.right < ClipRect.right)
{
pDC->FillRect(CRect(VisRect.right, ClipRect.top, ClipRect.right, ClipRect.bottom),&Back);
}
if (VisRect.bottom < ClipRect.bottom && ClipRect.left < VisRect.right)
{
pDC->FillRect(CRect(ClipRect.left, VisRect.bottom, VisRect.right, ClipRect.bottom),&Back);
}
}
void CGridCtrl::OnSize(UINT nType, int cx, int cy)
{
SetFocus();
CWnd::OnSize(nType, cx, cy);
ResetScrollBars();
}
UINT CGridCtrl::OnGetDlgCode()
{
UINT nCode = DLGC_WANTARROWS | DLGC_WANTCHARS;
if (m_bHandleTabKey && !IsCTRLpressed())
nCode |= DLGC_WANTTAB;
return nCode;
}
void CGridCtrl::OnSysColorChange()
{
CWnd::OnSysColorChange();
if (GetTextColor() == m_crWindowText)
SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
if (GetTextBkColor() == m_crWindowColour)
SetTextBkColor(::GetSysColor(COLOR_WINDOW));
if (GetBkColor() == m_crShadow)
SetBkColor(::GetSysColor(COLOR_3DSHADOW));
if (GetFixedTextColor() == m_crWindowText)
SetFixedTextColor(::GetSysColor(COLOR_WINDOWTEXT));
if (GetFixedBkColor() == m_cr3DFace)
SetFixedBkColor(::GetSysColor(COLOR_3DFACE));
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
}
void CGridCtrl::OnCaptureChanged(CWnd *pWnd)
{
if (pWnd->GetSafeHwnd() == GetSafeHwnd())
{
return;
}
if (m_nTimerID != 0)
{
KillTimer(m_nTimerID);
m_nTimerID = 0;
}
if (m_MouseMode == MOUSE_DRAGGING)
{
m_MouseMode = MOUSE_NOTHING;
}
}
void CGridCtrl::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
CWnd::OnSettingChange(uFlags, lpszSection);
if (GetTextColor() == m_crWindowText) // Still using system colours
SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); // set to new system colour
if (GetTextBkColor() == m_crWindowColour)
SetTextBkColor(::GetSysColor(COLOR_WINDOW));
if (GetBkColor() == m_crShadow)
SetBkColor(::GetSysColor(COLOR_3DSHADOW));
if (GetFixedTextColor() == m_crWindowText)
SetFixedTextColor(::GetSysColor(COLOR_WINDOWTEXT));
if (GetFixedBkColor() == m_cr3DFace)
SetFixedBkColor(::GetSysColor(COLOR_3DFACE));
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
m_nRowsPerWheelNotch = GetMouseScrollLines(); // Get the number of lines
}
void CGridCtrl::OnTimer(UINT nIDEvent)
{
ASSERT(nIDEvent == WM_LBUTTONDOWN);
if (nIDEvent != WM_LBUTTONDOWN)
{
return;
}
CPoint pt, origPt;
if (!GetCursorPos(&origPt))
{
return;
}
ScreenToClient(&origPt);
CRect rect;
GetClientRect(rect);
int nFixedRowHeight = GetFixedRowHeight();
int nFixedColWidth = GetFixedColumnWidth();
pt = origPt;
if (pt.y > rect.bottom)
{
SendMessage(WM_KEYDOWN, VK_DOWN, 0);
if (pt.x < rect.left)
{
pt.x = rect.left;
}
if (pt.x > rect.right)
{
pt.x = rect.right;
}
pt.y = rect.bottom;
OnSelecting(GetCellFromPt(pt));
}
else if (pt.y < nFixedRowHeight)
{
SendMessage(WM_KEYDOWN, VK_UP, 0);
if (pt.x < rect.left)
{
pt.x = rect.left;
}
if (pt.x > rect.right)
{
pt.x = rect.right;
}
pt.y = nFixedRowHeight + 1;
OnSelecting(GetCellFromPt(pt));
}
pt = origPt;
if (pt.x > rect.right)
{
SendMessage(WM_KEYDOWN, VK_RIGHT, 0);
if (pt.y < rect.top)
{
pt.y = rect.top;
}
if (pt.y > rect.bottom)
{
pt.y = rect.bottom;
}
pt.x = rect.right;
OnSelecting(GetCellFromPt(pt));
}
else if (pt.x < nFixedColWidth)
{
SendMessage(WM_KEYDOWN, VK_LEFT, 0);
if (pt.y < rect.top)
{
pt.y = rect.top;
}
if (pt.y > rect.bottom)
{
pt.y = rect.bottom;
}
pt.x = nFixedColWidth + 1;
OnSelecting(GetCellFromPt(pt));
}
}
void CGridCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(!IsValid(m_idCurrentCell))
{
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
return;
}
CCellID next = m_idCurrentCell;
BOOL bChangeLine = FALSE;
switch (nChar)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -