00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00112
00113 #include "stdafx.h"
00114 #include "MemDC.h"
00115 #include "GridCtrl.h"
00116
00117
00118 #include <afxadv.h>
00119 #include <afxconv.h>
00120
00121 #ifdef _DEBUG
00122 #define new DEBUG_NEW
00123 #undef THIS_FILE
00124 static char THIS_FILE[] = __FILE__;
00125 #endif
00126
00127
00128 #ifdef GRIDCONTROL_NO_TITLETIPS
00129 #pragma message(" -- CGridCtrl: No titletips for cells with large data")
00130 #endif
00131 #ifdef GRIDCONTROL_NO_DRAGDROP
00132 #pragma message(" -- CGridCtrl: No OLE drag and drop")
00133 #endif
00134 #ifdef GRIDCONTROL_NO_CLIPBOARD
00135 #pragma message(" -- CGridCtrl: No clipboard support")
00136 #endif
00137 #ifdef GRIDCONTROL_NO_PRINTING
00138 #pragma message(" -- CGridCtrl: No printing support")
00139 #endif
00140
00141
00142 IMPLEMENT_DYNCREATE(CGridCtrl, CWnd)
00143
00144
00145
00146
00147 UINT GetMouseScrollLines()
00148 {
00149 int nScrollLines = 3;
00150
00151 #ifndef _WIN32_WCE
00152
00153 OSVERSIONINFO VersionInfo;
00154 VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00155 if (!GetVersionEx(&VersionInfo) ||
00156 (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && VersionInfo.dwMinorVersion == 0))
00157 {
00158 HKEY hKey;
00159 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"),
00160 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
00161 {
00162 TCHAR szData[128];
00163 DWORD dwKeyDataType;
00164 DWORD dwDataBufSize = sizeof(szData);
00165
00166 if (RegQueryValueEx(hKey, _T("WheelScrollLines"), NULL, &dwKeyDataType,
00167 (LPBYTE) &szData, &dwDataBufSize) == ERROR_SUCCESS)
00168 {
00169 nScrollLines = _tcstoul(szData, NULL, 10);
00170 }
00171 RegCloseKey(hKey);
00172 }
00173 }
00174
00175 else
00176 SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &nScrollLines, 0);
00177 #endif
00178
00179 return nScrollLines;
00180 }
00181
00183
00184
00185 CGridCtrl::CGridCtrl(int nRows, int nCols, int nFixedRows, int nFixedCols)
00186 {
00187 RegisterWindowClass();
00188
00189 #if !defined(GRIDCONTROL_NO_DRAGDROP) || !defined(GRIDCONTROL_NO_CLIPBOARD)
00190 _AFX_THREAD_STATE* pState = AfxGetThreadState();
00191 if (!pState->m_bNeedTerm && !AfxOleInit())
00192 AfxMessageBox(_T("OLE initialization failed. Make sure that the OLE libraries are the correct version"));
00193 #endif
00194
00195
00196
00197
00198
00199
00200 m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
00201 m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
00202 m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
00203 m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
00204 m_crGridLineColour = RGB(192,192,192);
00205
00206 m_nRows = 0;
00207 m_nCols = 0;
00208 m_nFixedRows = 0;
00209 m_nFixedCols = 0;
00210
00211 m_bVirtualMode = FALSE;
00212 m_pfnCallback = NULL;
00213
00214 m_nVScrollMax = 0;
00215 m_nHScrollMax = 0;
00216 m_nRowsPerWheelNotch = GetMouseScrollLines();
00217
00218 m_nBarState = GVL_NONE;
00219 m_MouseMode = MOUSE_NOTHING;
00220 m_nGridLines = GVL_BOTH;
00221 m_bEditable = TRUE;
00222 m_bListMode = FALSE;
00223 m_bSingleRowSelection = FALSE;
00224 m_bSingleColSelection = FALSE;
00225 m_bLMouseButtonDown = FALSE;
00226 m_bRMouseButtonDown = FALSE;
00227 m_bAllowDraw = TRUE;
00228 m_bEnableSelection = TRUE;
00229 m_bFixedColumnSelection = TRUE;
00230 m_bFixedRowSelection = TRUE;
00231 m_bAllowRowResize = TRUE;
00232 m_bAllowColumnResize = TRUE;
00233 m_bSortOnClick = FALSE;
00234 m_bHandleTabKey = TRUE;
00235 #ifdef _WIN32_WCE
00236 m_bDoubleBuffer = FALSE;
00237 #else
00238 m_bDoubleBuffer = TRUE;
00239 #endif
00240 m_bTitleTips = TRUE;
00241
00242 m_bWysiwygPrinting = FALSE;
00243
00244 m_bHiddenColUnhide = TRUE;
00245 m_bHiddenRowUnhide = TRUE;
00246
00247 m_bAllowColHide = TRUE;
00248 m_bAllowRowHide = TRUE;
00249
00250 m_bAscending = TRUE;
00251 m_nSortColumn = -1;
00252 m_pfnCompare = NULL;
00253
00254 m_nAutoSizeColumnStyle = GVS_BOTH;
00255
00256 m_nTimerID = 0;
00257 m_nTimerInterval = 25;
00258 m_nResizeCaptureRange = 3;
00259
00260
00261 m_pImageList = NULL;
00262 m_bAllowDragAndDrop = FALSE;
00263 m_bTrackFocusCell = TRUE;
00264 m_bFrameFocus = TRUE;
00265
00266 m_pRtcDefault = RUNTIME_CLASS(CGridCell);
00267
00268 SetupDefaultCells();
00269 SetGridBkColor(m_crShadow);
00270
00271
00272 SetRowCount(nRows);
00273 SetColumnCount(nCols);
00274 SetFixedRowCount(nFixedRows);
00275 SetFixedColumnCount(nFixedCols);
00276
00277 SetTitleTipTextClr(CLR_DEFAULT);
00278 SetTitleTipBackClr(CLR_DEFAULT);
00279
00280
00281 m_SelectedCellMap.RemoveAll();
00282 m_PrevSelectedCellMap.RemoveAll();
00283
00284 #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
00285
00286
00287 m_bShadedPrintOut = TRUE;
00288 SetPrintMarginInfo(2, 2, 4, 4, 1, 1, 1);
00289 #endif
00290 }
00291
00292 CGridCtrl::~CGridCtrl()
00293 {
00294 DeleteAllItems();
00295
00296 #ifndef GRIDCONTROL_NO_TITLETIPS
00297 if (m_bTitleTips && ::IsWindow(m_TitleTip.GetSafeHwnd()))
00298 m_TitleTip.DestroyWindow();
00299 #endif
00300
00301 DestroyWindow();
00302
00303 #if !defined(GRIDCONTROL_NO_DRAGDROP) || !defined(GRIDCONTROL_NO_CLIPBOARD)
00304
00305 COleDataSource *pSource = COleDataSource::GetClipboardOwner();
00306 if(pSource)
00307 COleDataSource::FlushClipboard();
00308 #endif
00309 }
00310
00311
00312 BOOL CGridCtrl::RegisterWindowClass()
00313 {
00314 WNDCLASS wndcls;
00315 HINSTANCE hInst = AfxGetInstanceHandle();
00316
00317
00318 if (!(::GetClassInfo(hInst, GRIDCTRL_CLASSNAME, &wndcls)))
00319 {
00320
00321 wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
00322 wndcls.lpfnWndProc = ::DefWindowProc;
00323 wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
00324 wndcls.hInstance = hInst;
00325 wndcls.hIcon = NULL;
00326 #ifndef _WIN32_WCE_NO_CURSOR
00327 wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
00328 #else
00329 wndcls.hCursor = 0;
00330 #endif
00331 wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
00332 wndcls.lpszMenuName = NULL;
00333 wndcls.lpszClassName = GRIDCTRL_CLASSNAME;
00334
00335 if (!AfxRegisterClass(&wndcls))
00336 {
00337 AfxThrowResourceException();
00338 return FALSE;
00339 }
00340 }
00341
00342 return TRUE;
00343 }
00344
00345 BOOL CGridCtrl::Initialise()
00346 {
00347
00348 static BOOL bInProcedure = FALSE;
00349 if (bInProcedure)
00350 return FALSE;
00351 bInProcedure = TRUE;
00352
00353 #ifndef GRIDCONTROL_NO_TITLETIPS
00354 m_TitleTip.SetParentWnd(this);
00355 #endif
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 if (::IsWindow(m_hWnd))
00366 ModifyStyleEx(0, WS_EX_CLIENTEDGE);
00367
00368
00369
00370 CRect rect;
00371 GetWindowRect(rect);
00372 CWnd* pParent = GetParent();
00373 if (pParent != NULL)
00374 pParent->ScreenToClient(rect);
00375 rect.InflateRect(1,1); MoveWindow(rect);
00376 rect.DeflateRect(1,1); MoveWindow(rect);
00377
00378 bInProcedure = FALSE;
00379 return TRUE;
00380 }
00381
00382
00383 BOOL CGridCtrl::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwStyle)
00384 {
00385 ASSERT(pParentWnd->GetSafeHwnd());
00386
00387 if (!CWnd::Create(GRIDCTRL_CLASSNAME, NULL, dwStyle, rect, pParentWnd, nID))
00388 return FALSE;
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 TRY
00399 {
00400 m_arRowHeights.SetSize(m_nRows);
00401 m_arColWidths.SetSize(m_nCols);
00402 }
00403 CATCH (CMemoryException, e)
00404 {
00405 e->ReportError();
00406 return FALSE;
00407 }
00408 END_CATCH
00409
00410 int i;
00411 for (i = 0; i < m_nRows; i++)
00412 m_arRowHeights[i] = m_cellDefault.GetHeight();
00413 for (i = 0; i < m_nCols; i++)
00414 m_arColWidths[i] = m_cellDefault.GetWidth();
00415
00416 return TRUE;
00417 }
00418
00419 void CGridCtrl::SetupDefaultCells()
00420 {
00421 m_cellDefault.SetGrid(this);
00422 m_cellFixedColDef.SetGrid(this);
00423 m_cellFixedRowDef.SetGrid(this);
00424 m_cellFixedRowColDef.SetGrid(this);
00425
00426 m_cellDefault.SetTextClr(m_crWindowText);
00427 m_cellDefault.SetBackClr(m_crWindowColour);
00428 m_cellFixedColDef.SetTextClr(m_crWindowText);
00429 m_cellFixedColDef.SetBackClr(m_cr3DFace);
00430 m_cellFixedRowDef.SetTextClr(m_crWindowText);
00431 m_cellFixedRowDef.SetBackClr(m_cr3DFace);
00432 m_cellFixedRowColDef.SetTextClr(m_crWindowText);
00433 m_cellFixedRowColDef.SetBackClr(m_cr3DFace);
00434 }
00435
00436 void CGridCtrl::PreSubclassWindow()
00437 {
00438 CWnd::PreSubclassWindow();
00439
00440
00441
00442
00443
00444 Initialise();
00445 }
00446
00447
00448
00449 LRESULT CGridCtrl::SendMessageToParent(int nRow, int nCol, int nMessage) const
00450 {
00451 if (!IsWindow(m_hWnd))
00452 return 0;
00453
00454 NM_GRIDVIEW nmgv;
00455 nmgv.iRow = nRow;
00456 nmgv.iColumn = nCol;
00457 nmgv.hdr.hwndFrom = m_hWnd;
00458 nmgv.hdr.idFrom = GetDlgCtrlID();
00459 nmgv.hdr.code = nMessage;
00460
00461 CWnd *pOwner = GetOwner();
00462 if (pOwner && IsWindow(pOwner->m_hWnd))
00463 return pOwner->SendMessage(WM_NOTIFY, nmgv.hdr.idFrom, (LPARAM)&nmgv);
00464 else
00465 return 0;
00466 }
00467
00468
00469 LRESULT CGridCtrl::SendDisplayRequestToParent(GV_DISPINFO* pDisplayInfo) const
00470 {
00471 if (!IsWindow(m_hWnd))
00472 return 0;
00473
00474
00475 pDisplayInfo->hdr.hwndFrom = m_hWnd;
00476 pDisplayInfo->hdr.idFrom = GetDlgCtrlID();
00477 pDisplayInfo->hdr.code = GVN_GETDISPINFO;
00478
00479
00480 CWnd *pOwner = GetOwner();
00481 if (pOwner && IsWindow(pOwner->m_hWnd))
00482 return pOwner->SendMessage(WM_NOTIFY, pDisplayInfo->hdr.idFrom, (LPARAM)pDisplayInfo);
00483 else
00484 return 0;
00485 }
00486
00487
00488 LRESULT CGridCtrl::SendCacheHintToParent(const CCellRange& range) const
00489 {
00490 if (!IsWindow(m_hWnd))
00491 return 0;
00492
00493 GV_CACHEHINT CacheHint;
00494
00495
00496 CacheHint.hdr.hwndFrom = m_hWnd;
00497 CacheHint.hdr.idFrom = GetDlgCtrlID();
00498 CacheHint.hdr.code = GVN_ODCACHEHINT;
00499
00500 CacheHint.range = range;
00501
00502
00503 CWnd *pOwner = GetOwner();
00504 if (pOwner && IsWindow(pOwner->m_hWnd))
00505 return pOwner->SendMessage(WM_NOTIFY, CacheHint.hdr.idFrom, (LPARAM)&CacheHint);
00506 else
00507 return 0;
00508 }
00509
00510 BEGIN_MESSAGE_MAP(CGridCtrl, CWnd)
00511
00512
00513 ON_WM_PAINT()
00514 ON_WM_HSCROLL()
00515 ON_WM_VSCROLL()
00516 ON_WM_SIZE()
00517 ON_WM_LBUTTONUP()
00518 ON_WM_LBUTTONDOWN()
00519 ON_WM_MOUSEMOVE()
00520 ON_WM_TIMER()
00521 ON_WM_GETDLGCODE()
00522 ON_WM_KEYDOWN()
00523 ON_WM_CHAR()
00524 ON_WM_LBUTTONDBLCLK()
00525 ON_WM_ERASEBKGND()
00526 ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdateEditSelectAll)
00527 ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
00528 ON_WM_SYSKEYDOWN()
00529
00530 #ifndef _WIN32_WCE_NO_CURSOR
00531 ON_WM_SETCURSOR()
00532 #endif
00533 #ifndef _WIN32_WCE
00534 ON_WM_RBUTTONUP()
00535 ON_WM_SYSCOLORCHANGE()
00536 ON_WM_CAPTURECHANGED()
00537 #endif
00538 #ifndef GRIDCONTROL_NO_CLIPBOARD
00539 ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
00540 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
00541 ON_COMMAND(ID_EDIT_CUT, OnEditCut)
00542 ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
00543 ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
00544 ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
00545 #endif
00546 #if (_WIN32_WCE >= 210)
00547 ON_WM_SETTINGCHANGE()
00548 #endif
00549 #if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
00550 ON_WM_MOUSEWHEEL()
00551 #endif
00552 ON_MESSAGE(WM_SETFONT, OnSetFont)
00553 ON_MESSAGE(WM_GETFONT, OnGetFont)
00554 ON_MESSAGE(WM_IME_CHAR, OnImeChar)
00555 ON_NOTIFY(GVN_ENDLABELEDIT, IDC_INPLACE_CONTROL, OnEndInPlaceEdit)
00556 END_MESSAGE_MAP()
00557
00558
00560
00561
00562 void CGridCtrl::OnPaint()
00563 {
00564 CPaintDC dc(this);
00565
00566 if (m_bDoubleBuffer)
00567 {
00568 CMemDC MemDC(&dc);
00569 OnDraw(&MemDC);
00570 }
00571 else
00572 OnDraw(&dc);
00573 }
00574
00575 BOOL CGridCtrl::OnEraseBkgnd(CDC* )
00576 {
00577 return TRUE;
00578 }
00579
00580
00581
00582
00583
00584 void CGridCtrl::EraseBkgnd(CDC* pDC)
00585 {
00586 CRect VisRect, ClipRect, rect;
00587 CBrush FixedRowColBack(GetDefaultCell(TRUE, TRUE)->GetBackClr()),
00588 FixedRowBack(GetDefaultCell(TRUE, FALSE)->GetBackClr()),
00589 FixedColBack(GetDefaultCell(FALSE, TRUE)->GetBackClr()),
00590 TextBack(GetDefaultCell(FALSE, FALSE)->GetBackClr());
00591 CBrush Back(GetGridBkColor());
00592
00593
00594 if (pDC->GetClipBox(ClipRect) == ERROR)
00595 return;
00596 GetVisibleNonFixedCellRange(VisRect);
00597
00598 int nFixedColumnWidth = GetFixedColumnWidth();
00599 int nFixedRowHeight = GetFixedRowHeight();
00600
00601
00602 if (ClipRect.left < nFixedColumnWidth && ClipRect.top < nFixedRowHeight)
00603 pDC->FillRect(CRect(ClipRect.left, ClipRect.top,
00604 nFixedColumnWidth, nFixedRowHeight),
00605 &FixedRowColBack);
00606
00607
00608 if (ClipRect.left < nFixedColumnWidth && ClipRect.top < VisRect.bottom)
00609 pDC->FillRect(CRect(ClipRect.left, ClipRect.top,
00610 nFixedColumnWidth, VisRect.bottom),
00611 &FixedColBack);
00612
00613
00614 if (ClipRect.top < nFixedRowHeight &&
00615 ClipRect.right > nFixedColumnWidth && ClipRect.left < VisRect.right)
00616 pDC->FillRect(CRect(nFixedColumnWidth-1, ClipRect.top,
00617 VisRect.right, nFixedRowHeight),
00618 &FixedRowBack);
00619
00620
00621 if (rect.IntersectRect(VisRect, ClipRect))
00622 {
00623 CRect CellRect(max(nFixedColumnWidth, rect.left),
00624 max(nFixedRowHeight, rect.top),
00625 rect.right, rect.bottom);
00626 pDC->FillRect(CellRect, &TextBack);
00627 }
00628
00629
00630 if (VisRect.right < ClipRect.right)
00631 pDC->FillRect(CRect(VisRect.right, ClipRect.top,
00632 ClipRect.right, ClipRect.bottom),
00633 &Back);
00634
00635
00636 if (VisRect.bottom < ClipRect.bottom && ClipRect.left < VisRect.right)
00637 pDC->FillRect(CRect(ClipRect.left, VisRect.bottom,
00638 VisRect.right, ClipRect.bottom),
00639 &Back);
00640 }
00641
00642 void CGridCtrl::OnSize(UINT nType, int cx, int cy)
00643 {
00644 static BOOL bAlreadyInsideThisProcedure = FALSE;
00645 if (bAlreadyInsideThisProcedure)
00646 return;
00647
00648 if (!::IsWindow(m_hWnd))
00649 return;
00650
00651
00652 #ifndef GRIDCONTROL_NO_DRAGDROP
00653 m_DropTarget.Register(this);
00654 #endif
00655
00656
00657 bAlreadyInsideThisProcedure = TRUE;
00658
00659 EndEditing();
00660 CWnd::OnSize(nType, cx, cy);
00661 ResetScrollBars();
00662
00663
00664 bAlreadyInsideThisProcedure = FALSE;
00665 }
00666
00667 UINT CGridCtrl::OnGetDlgCode()
00668 {
00669 UINT nCode = DLGC_WANTARROWS | DLGC_WANTCHARS;
00670
00671 if (m_bHandleTabKey && !IsCTRLpressed())
00672 nCode |= DLGC_WANTTAB;
00673
00674 return nCode;
00675 }
00676
00677 #ifndef _WIN32_WCE
00678
00679 void CGridCtrl::OnSysColorChange()
00680 {
00681 CWnd::OnSysColorChange();
00682
00683 if (GetDefaultCell(FALSE, FALSE)->GetTextClr() == m_crWindowText)
00684 GetDefaultCell(FALSE, FALSE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00685 if (GetDefaultCell(FALSE, FALSE)->GetBackClr() == m_crWindowColour)
00686 GetDefaultCell(FALSE, FALSE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00687
00688 if (GetDefaultCell(TRUE, FALSE)->GetTextClr() == m_crWindowText)
00689 GetDefaultCell(TRUE, FALSE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00690 if (GetDefaultCell(TRUE, FALSE)->GetBackClr() == m_crWindowColour)
00691 GetDefaultCell(TRUE, FALSE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00692
00693 if (GetDefaultCell(FALSE, TRUE)->GetTextClr() == m_crWindowText)
00694 GetDefaultCell(FALSE, TRUE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00695 if (GetDefaultCell(FALSE, TRUE)->GetBackClr() == m_crWindowColour)
00696 GetDefaultCell(FALSE, TRUE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00697
00698 if (GetDefaultCell(TRUE, TRUE)->GetTextClr() == m_crWindowText)
00699 GetDefaultCell(TRUE, TRUE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00700 if (GetDefaultCell(TRUE, TRUE)->GetBackClr() == m_crWindowColour)
00701 GetDefaultCell(TRUE, TRUE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00702
00703 if (GetGridBkColor() == m_crShadow)
00704 SetGridBkColor(::GetSysColor(COLOR_3DSHADOW));
00705
00706 m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
00707 m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
00708 m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
00709 m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
00710 }
00711 #endif
00712
00713 #ifndef _WIN32_WCE_NO_CURSOR
00714
00715 void CGridCtrl::OnCaptureChanged(CWnd *pWnd)
00716 {
00717 if (pWnd->GetSafeHwnd() == GetSafeHwnd())
00718 return;
00719
00720
00721 if (m_nTimerID != 0)
00722 {
00723 KillTimer(m_nTimerID);
00724 m_nTimerID = 0;
00725 }
00726
00727 #ifndef GRIDCONTROL_NO_DRAGDROP
00728
00729 if (m_MouseMode == MOUSE_DRAGGING)
00730 m_MouseMode = MOUSE_NOTHING;
00731 #endif
00732 }
00733 #endif
00734
00735 #if (_MFC_VER >= 0x0421) || (_WIN32_WCE >= 210)
00736
00737 void CGridCtrl::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
00738 {
00739 CWnd::OnSettingChange(uFlags, lpszSection);
00740
00741 if (GetDefaultCell(FALSE, FALSE)->GetTextClr() == m_crWindowText)
00742 GetDefaultCell(FALSE, FALSE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00743 if (GetDefaultCell(FALSE, FALSE)->GetBackClr() == m_crWindowColour)
00744 GetDefaultCell(FALSE, FALSE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00745
00746 if (GetDefaultCell(TRUE, FALSE)->GetTextClr() == m_crWindowText)
00747 GetDefaultCell(TRUE, FALSE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00748 if (GetDefaultCell(TRUE, FALSE)->GetBackClr() == m_crWindowColour)
00749 GetDefaultCell(TRUE, FALSE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00750
00751 if (GetDefaultCell(FALSE, TRUE)->GetTextClr() == m_crWindowText)
00752 GetDefaultCell(FALSE, TRUE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00753 if (GetDefaultCell(FALSE, TRUE)->GetBackClr() == m_crWindowColour)
00754 GetDefaultCell(FALSE, TRUE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00755
00756 if (GetDefaultCell(TRUE, TRUE)->GetTextClr() == m_crWindowText)
00757 GetDefaultCell(TRUE, TRUE)->SetTextClr(::GetSysColor(COLOR_WINDOWTEXT));
00758 if (GetDefaultCell(TRUE, TRUE)->GetBackClr() == m_crWindowColour)
00759 GetDefaultCell(TRUE, TRUE)->SetBackClr(::GetSysColor(COLOR_WINDOW));
00760
00761 if (GetGridBkColor() == m_crShadow)
00762 SetGridBkColor(::GetSysColor(COLOR_3DSHADOW));
00763
00764 m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
00765 m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
00766 m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
00767 m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
00768
00769 m_nRowsPerWheelNotch = GetMouseScrollLines();
00770 }
00771 #endif
00772
00773
00774
00775 void CGridCtrl::OnTimer(UINT nIDEvent)
00776 {
00777 ASSERT(nIDEvent == WM_LBUTTONDOWN);
00778 if (nIDEvent != WM_LBUTTONDOWN)
00779 return;
00780
00781 CPoint pt, origPt;
00782
00783 #ifdef _WIN32_WCE
00784 if (m_MouseMode == MOUSE_NOTHING)
00785 return;
00786 origPt = GetMessagePos();
00787 #else
00788 if (!GetCursorPos(&origPt))
00789 return;
00790 #endif
00791
00792 ScreenToClient(&origPt);
00793
00794 CRect rect;
00795 GetClientRect(rect);
00796
00797 int nFixedRowHeight = GetFixedRowHeight();
00798 int nFixedColWidth = GetFixedColumnWidth();
00799
00800 pt = origPt;
00801 if (pt.y > rect.bottom)
00802 {
00803
00804 SendMessage(WM_KEYDOWN, VK_DOWN, 0);
00805
00806 if (pt.x < rect.left)
00807 pt.x = rect.left;
00808 if (pt.x > rect.right)
00809 pt.x = rect.right;
00810 pt.y = rect.bottom;
00811 OnSelecting(GetCellFromPt(pt));
00812 }
00813 else if (pt.y < nFixedRowHeight)
00814 {
00815
00816 SendMessage(WM_KEYDOWN, VK_UP, 0);
00817
00818 if (pt.x < rect.left)
00819 pt.x = rect.left;
00820 if (pt.x > rect.right)
00821 pt.x = rect.right;
00822 pt.y = nFixedRowHeight + 1;
00823 OnSelecting(GetCellFromPt(pt));
00824 }
00825
00826 pt = origPt;
00827 if (pt.x > rect.right)
00828 {
00829
00830 SendMessage(WM_KEYDOWN, VK_RIGHT, 0);
00831
00832 if (pt.y < rect.top)
00833 pt.y = rect.top;
00834 if (pt.y > rect.bottom)
00835 pt.y = rect.bottom;
00836 pt.x = rect.right;
00837 OnSelecting(GetCellFromPt(pt));
00838 }
00839 else if (pt.x < nFixedColWidth)
00840 {
00841
00842 SendMessage(WM_KEYDOWN, VK_LEFT, 0);
00843
00844 if (pt.y < rect.top)
00845 pt.y = rect.top;
00846 if (pt.y > rect.bottom)
00847 pt.y = rect.bottom;
00848 pt.x = nFixedColWidth + 1;
00849 OnSelecting(GetCellFromPt(pt));
00850 }
00851 }
00852
00853
00854 void CGridCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00855 {
00856 if (!IsValid(m_idCurrentCell))
00857 {
00858 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
00859 return;
00860 }
00861
00862 CCellID next = m_idCurrentCell;
00863 BOOL bChangeLine = FALSE;
00864 BOOL bHorzScrollAction = FALSE;
00865 BOOL bVertScrollAction = FALSE;
00866
00867 if (IsCTRLpressed())
00868 {
00869 switch (nChar)
00870 {
00871 case 'A':
00872 OnEditSelectAll();
00873 break;
00874 #ifndef GRIDCONTROL_NO_CLIPBOARD
00875 case 'X':
00876 OnEditCut();
00877 break;
00878 case VK_INSERT:
00879 case 'C':
00880 OnEditCopy();
00881 break;
00882 case 'V':
00883 OnEditPaste();
00884 break;
00885 #endif
00886 }
00887 }
00888
00889 #ifndef GRIDCONTROL_NO_CLIPBOARD
00890 if (IsSHIFTpressed() &&(nChar == VK_INSERT))
00891 OnEditPaste();
00892 #endif
00893
00894 BOOL bFoundVisible;
00895 int iOrig;
00896
00897 if (nChar == VK_DELETE)
00898 {
00899 CutSelectedText();
00900 }
00901 else if (nChar == VK_DOWN)
00902 {
00903
00904 bFoundVisible = FALSE;
00905 iOrig = next.row;
00906 next.row++;
00907 while( next.row < GetRowCount())
00908 {
00909 if( GetRowHeight( next.row) > 0)
00910 {
00911 bFoundVisible = TRUE;
00912 break;
00913 }
00914 next.row++;
00915 }
00916 if( !bFoundVisible)
00917 next.row = iOrig;
00918 }
00919 else if (nChar == VK_UP)
00920 {
00921
00922 bFoundVisible = FALSE;
00923 iOrig = next.row;
00924 next.row--;
00925 while( next.row >= m_nFixedRows)
00926 {
00927 if( GetRowHeight( next.row) > 0)
00928 {
00929 bFoundVisible = TRUE;
00930 break;
00931 }
00932 next.row--;
00933 }
00934 if( !bFoundVisible)
00935 next.row = iOrig;
00936 }
00937 else if (nChar == VK_RIGHT || (nChar == VK_TAB && !IsSHIFTpressed()) )
00938 {
00939
00940 bFoundVisible = FALSE;
00941 iOrig = next.col;
00942 next.col++;
00943
00944 if (nChar == VK_TAB)
00945 {
00946
00947 if (next.col == (GetColumnCount()) && next.row < (GetRowCount() - 1))
00948 {
00949 next.row++;
00950 while( next.row < GetRowCount())
00951 {
00952 if( GetRowHeight(next.row) > 0)
00953 {
00954 bFoundVisible = TRUE;
00955 break;
00956 }
00957 next.row++;
00958 }
00959
00960 next.col = m_nFixedCols;
00961 bChangeLine = TRUE;
00962 }
00963 else
00964 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
00965 }
00966
00967
00968 while( next.col < GetColumnCount())
00969 {
00970 if( GetColumnWidth( next.col) > 0)
00971 {
00972 bFoundVisible = TRUE;
00973 break;
00974 }
00975 next.col++;
00976 }
00977
00978
00979 if( !bFoundVisible)
00980 next.col = iOrig;
00981 }
00982 else if (nChar == VK_LEFT || (nChar == VK_TAB && IsSHIFTpressed()) )
00983 {
00984
00985 bFoundVisible = FALSE;
00986 iOrig = next.col;
00987 next.col--;
00988
00989 if (nChar == VK_TAB)
00990 {
00991 if (next.col == (GetFixedColumnCount()-1) && next.row > GetFixedRowCount())
00992 {
00993 next.row--;
00994 while( next.row > GetFixedRowCount())
00995 {
00996 if( GetRowHeight(next.row) > 0)
00997 {
00998 bFoundVisible = TRUE;
00999 break;
01000 }
01001 next.row--;
01002 }
01003
01004 next.col = GetColumnCount() - 1;
01005 bChangeLine = TRUE;
01006 }
01007 else
01008 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
01009 }
01010
01011 while( next.col >= m_nFixedCols)
01012 {
01013 if( GetColumnWidth( next.col) > 0)
01014 {
01015 bFoundVisible = TRUE;
01016 break;
01017 }
01018 next.col--;
01019 }
01020 if( !bFoundVisible)
01021 next.col = iOrig;
01022 }
01023 else if (nChar == VK_NEXT)
01024 {
01025 CCellID idOldTopLeft = GetTopleftNonFixedCell();
01026 SendMessage(WM_VSCROLL, SB_PAGEDOWN, 0);
01027 bVertScrollAction = TRUE;
01028 CCellID idNewTopLeft = GetTopleftNonFixedCell();
01029
01030 int increment = idNewTopLeft.row - idOldTopLeft.row;
01031 if (increment)
01032 {
01033 next.row += increment;
01034 if (next.row >(GetRowCount() - 1))
01035 next.row = GetRowCount() - 1;
01036 }
01037 else
01038 next.row = GetRowCount() - 1;
01039 }
01040 else if (nChar == VK_PRIOR)
01041 {
01042 CCellID idOldTopLeft = GetTopleftNonFixedCell();
01043 SendMessage(WM_VSCROLL, SB_PAGEUP, 0);
01044 bVertScrollAction = TRUE;
01045 CCellID idNewTopLeft = GetTopleftNonFixedCell();
01046
01047 int increment = idNewTopLeft.row - idOldTopLeft.row;
01048 if (increment)
01049 {
01050 next.row += increment;
01051 if (next.row < m_nFixedRows)
01052 next.row = m_nFixedRows;
01053 }
01054 else
01055 next.row = m_nFixedRows;
01056 }
01057 else if (nChar == VK_HOME)
01058 {
01059
01060
01061 if (IsCTRLpressed())
01062 {
01063 SendMessage(WM_VSCROLL, SB_TOP, 0);
01064 SendMessage(WM_HSCROLL, SB_LEFT, 0);
01065 bVertScrollAction = TRUE;
01066 bHorzScrollAction = TRUE;
01067 next.row = m_nFixedRows;
01068 next.col = m_nFixedCols;
01069 }
01070 else
01071 {
01072 SendMessage(WM_HSCROLL, SB_LEFT, 0);
01073 bHorzScrollAction = TRUE;
01074 next.col = m_nFixedCols;
01075 }
01076
01077 while( next.col < GetColumnCount() - 1)
01078 {
01079 if( GetColumnWidth( next.col) > 0)
01080 break;
01081 next.col++;
01082 }
01083 while( next.row < GetRowCount() - 1)
01084 {
01085 if( GetRowHeight( next.row) > 0)
01086 break;
01087 next.row++;
01088 }
01089 }
01090 else if (nChar == VK_END)
01091 {
01092
01093
01094 if (IsCTRLpressed())
01095 {
01096 SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
01097 SendMessage(WM_HSCROLL, SB_RIGHT, 0);
01098 bHorzScrollAction = TRUE;
01099 bVertScrollAction = TRUE;
01100 next.row = GetRowCount() - 1;
01101 next.col = GetColumnCount() - 1;
01102 }
01103 else
01104 {
01105 SendMessage(WM_HSCROLL, SB_RIGHT, 0);
01106 bHorzScrollAction = TRUE;
01107 next.col = GetColumnCount() - 1;
01108 }
01109
01110 while( next.col > m_nFixedCols + 1)
01111 {
01112 if( GetColumnWidth( next.col) > 0)
01113 break;
01114 next.col--;
01115 }
01116 while( next.row > m_nFixedRows + 1)
01117 {
01118 if( GetRowHeight( next.row) > 0)
01119 break;
01120 next.row--;
01121 }
01122 }
01123 else if (nChar == VK_F2)
01124 {
01125 OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, CPoint( -1, -1), VK_LBUTTON);
01126 }
01127 else
01128 {
01129 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
01130 return;
01131 }
01132
01133 if (next != m_idCurrentCell)
01134 {
01135
01136
01137
01138
01139 if (m_MouseMode == MOUSE_NOTHING)
01140 {
01141 m_PrevSelectedCellMap.RemoveAll();
01142 m_MouseMode = m_bListMode? MOUSE_SELECT_ROW : MOUSE_SELECT_CELLS;
01143 if (!IsSHIFTpressed() || nChar == VK_TAB)
01144 m_SelectionStartCell = next;
01145
01146
01147 SendMessageToParent(next.row, next.col, GVN_SELCHANGING);
01148 OnSelecting(next);
01149 SendMessageToParent(next.row, next.col, GVN_SELCHANGED);
01150
01151 m_MouseMode = MOUSE_NOTHING;
01152 }
01153
01154 SetFocusCell(next);
01155
01156 if (!IsCellVisible(next))
01157 {
01158
01159 switch (nChar)
01160 {
01161 case VK_RIGHT:
01162 SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
01163 bHorzScrollAction = TRUE;
01164 break;
01165
01166 case VK_LEFT:
01167 SendMessage(WM_HSCROLL, SB_LINELEFT, 0);
01168 bHorzScrollAction = TRUE;
01169 break;
01170
01171 case VK_DOWN:
01172 SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
01173 bVertScrollAction = TRUE;
01174 break;
01175
01176 case VK_UP:
01177 SendMessage(WM_VSCROLL, SB_LINEUP, 0);
01178 bVertScrollAction = TRUE;
01179 break;
01180
01181 case VK_TAB:
01182 if (IsSHIFTpressed())
01183 {
01184 if (bChangeLine)
01185 {
01186 SendMessage(WM_VSCROLL, SB_LINEUP, 0);
01187 bVertScrollAction = TRUE;
01188 SetScrollPos32(SB_HORZ, m_nHScrollMax);
01189 break;
01190 }
01191 else
01192 {
01193 SendMessage(WM_HSCROLL, SB_LINELEFT, 0);
01194 bHorzScrollAction = TRUE;
01195 }
01196 }
01197 else
01198 {
01199 if (bChangeLine)
01200 {
01201 SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
01202 bVertScrollAction = TRUE;
01203 SetScrollPos32(SB_HORZ, 0);
01204 break;
01205 }
01206 else
01207 {
01208 SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
01209 bHorzScrollAction = TRUE;
01210 }
01211 }
01212 break;
01213 }
01214 EnsureVisible(next);
01215 Invalidate();
01216 }
01217 EnsureVisible(next);
01218
01219 if (bHorzScrollAction)
01220 SendMessage(WM_HSCROLL, SB_ENDSCROLL, 0);
01221 if (bVertScrollAction)
01222 SendMessage(WM_VSCROLL, SB_ENDSCROLL, 0);
01223 }
01224 }
01225
01226 void CGridCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
01227 {
01228 CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
01229 }
01230
01231 void CGridCtrl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
01232 {
01233 #ifdef GRIDCONTROL_USE_TITLETIPS
01234 m_TitleTip.Hide();
01235 #endif
01236
01237 CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
01238 }
01239
01240
01241 void CGridCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
01242 {
01243
01244 if (!IsCTRLpressed() && m_MouseMode == MOUSE_NOTHING && nChar != VK_ESCAPE)
01245 {
01246 if (!m_bHandleTabKey || (m_bHandleTabKey && nChar != VK_TAB))
01247 OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, CPoint( -1, -1), nChar);
01248 }
01249
01250 CWnd::OnChar(nChar, nRepCnt, nFlags);
01251 }
01252
01253
01254 LRESULT CGridCtrl::OnImeChar(WPARAM wCharCode, LPARAM)
01255 {
01256
01257 if (!IsCTRLpressed() && m_MouseMode == MOUSE_NOTHING && wCharCode != VK_ESCAPE)
01258 OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, CPoint( -1, -1), wCharCode);
01259 return 0;
01260 }
01261
01262
01263
01264
01265 void CGridCtrl::OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult)
01266 {
01267 GV_DISPINFO *pgvDispInfo = (GV_DISPINFO *)pNMHDR;
01268 GV_ITEM *pgvItem = &pgvDispInfo->item;
01269
01270
01271 if (!IsWindow(GetSafeHwnd()))
01272 return;
01273
01274 OnEndEditCell(pgvItem->row, pgvItem->col, pgvItem->strText);
01275
01276
01277 switch (pgvItem->lParam)
01278 {
01279 case VK_TAB:
01280 case VK_DOWN:
01281 case VK_UP:
01282 case VK_RIGHT:
01283 case VK_LEFT:
01284 case VK_NEXT:
01285 case VK_PRIOR:
01286 case VK_HOME:
01287 case VK_END:
01288 OnKeyDown(pgvItem->lParam, 0, 0);
01289 OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, CPoint( -1, -1), pgvItem->lParam);
01290 }
01291
01292 *pResult = 0;
01293 }
01294
01295
01296 void CGridCtrl::OnHScroll(UINT nSBCode, UINT , CScrollBar* )
01297 {
01298 EndEditing();
01299
01300 #ifndef GRIDCONTROL_NO_TITLETIPS
01301 m_TitleTip.Hide();
01302 #endif
01303
01304 int scrollPos = GetScrollPos32(SB_HORZ);
01305
01306 CCellID idTopLeft = GetTopleftNonFixedCell();
01307
01308 CRect rect;
01309 GetClientRect(rect);
01310
01311 switch (nSBCode)
01312 {
01313 case SB_LINERIGHT:
01314 if (scrollPos < m_nHScrollMax)
01315 {
01316
01317 while (idTopLeft.col < (GetColumnCount()-1)
01318 && GetColumnWidth( idTopLeft.col) < 1 )
01319 {
01320 idTopLeft.col++;
01321 }
01322 int xScroll = GetColumnWidth(idTopLeft.col);
01323 SetScrollPos32(SB_HORZ, scrollPos + xScroll);
01324 if (GetScrollPos32(SB_HORZ) == scrollPos)
01325 break;
01326
01327 rect.left = GetFixedColumnWidth();
01328
01329
01330
01331 InvalidateRect(rect);
01332 }
01333 break;
01334
01335 case SB_LINELEFT:
01336 if (scrollPos > 0 && idTopLeft.col > GetFixedColumnCount())
01337 {
01338 int iColToUse = idTopLeft.col-1;
01339
01340 while( iColToUse > GetFixedColumnCount()
01341 && GetColumnWidth( iColToUse) < 1 )
01342 {
01343 iColToUse--;
01344 }
01345
01346 int xScroll = GetColumnWidth(iColToUse);
01347 SetScrollPos32(SB_HORZ, max(0, scrollPos - xScroll));
01348 rect.left = GetFixedColumnWidth();
01349
01350
01351 InvalidateRect(rect);
01352 }
01353 break;
01354
01355 case SB_PAGERIGHT:
01356 if (scrollPos < m_nHScrollMax)
01357 {
01358 rect.left = GetFixedColumnWidth();
01359 int offset = rect.Width();
01360 int pos = min(m_nHScrollMax, scrollPos + offset);
01361 SetScrollPos32(SB_HORZ, pos);
01362 rect.left = GetFixedColumnWidth();
01363 InvalidateRect(rect);
01364 }
01365 break;
01366
01367 case SB_PAGELEFT:
01368 if (scrollPos > 0)
01369 {
01370 rect.left = GetFixedColumnWidth();
01371 int offset = -rect.Width();
01372 int pos = max(0, scrollPos + offset);
01373 SetScrollPos32(SB_HORZ, pos);
01374 rect.left = GetFixedColumnWidth();
01375 InvalidateRect(rect);
01376 }
01377 break;
01378
01379 case SB_THUMBPOSITION:
01380 case SB_THUMBTRACK:
01381 {
01382 SetScrollPos32(SB_HORZ, GetScrollPos32(SB_HORZ, TRUE));
01383 m_idTopLeftCell.row = -1;
01384 CCellID idNewTopLeft = GetTopleftNonFixedCell();
01385 if (idNewTopLeft != idTopLeft)
01386 {
01387 rect.left = GetFixedColumnWidth();
01388 InvalidateRect(rect);
01389 }
01390 }
01391 break;
01392
01393 case SB_LEFT:
01394 if (scrollPos > 0)
01395 {
01396 SetScrollPos32(SB_HORZ, 0);
01397 Invalidate();
01398 }
01399 break;
01400
01401 case SB_RIGHT:
01402 if (scrollPos < m_nHScrollMax)
01403 {
01404 SetScrollPos32(SB_HORZ, m_nHScrollMax);
01405 Invalidate();
01406 }
01407 break;
01408
01409
01410 default:
01411 break;
01412 }
01413 }
01414
01415
01416 void CGridCtrl::OnVScroll(UINT nSBCode, UINT , CScrollBar* )
01417 {
01418 EndEditing();
01419
01420 #ifndef GRIDCONTROL_NO_TITLETIPS
01421 m_TitleTip.Hide();
01422 #endif
01423
01424
01425 int scrollPos = GetScrollPos32(SB_VERT);
01426
01427 CCellID idTopLeft = GetTopleftNonFixedCell();
01428
01429 CRect rect;
01430 GetClientRect(rect);
01431
01432 switch (nSBCode)
01433 {
01434 case SB_LINEDOWN:
01435 if (scrollPos < m_nVScrollMax)
01436 {
01437
01438 while( idTopLeft.row < (GetRowCount()-1)
01439 && GetRowHeight( idTopLeft.row) < 1 )
01440 {
01441 idTopLeft.row++;
01442 }
01443
01444 int yScroll = GetRowHeight(idTopLeft.row);
01445 SetScrollPos32(SB_VERT, scrollPos + yScroll);
01446 if (GetScrollPos32(SB_VERT) == scrollPos)
01447 break;
01448
01449 rect.top = GetFixedRowHeight();
01450
01451
01452
01453 InvalidateRect(rect);
01454 }
01455 break;
01456
01457 case SB_LINEUP:
01458 if (scrollPos > 0 && idTopLeft.row > GetFixedRowCount())
01459 {
01460 int iRowToUse = idTopLeft.row-1;
01461
01462 while( iRowToUse > GetFixedRowCount()
01463 && GetRowHeight( iRowToUse) < 1 )
01464 {
01465 iRowToUse--;
01466 }
01467
01468 int yScroll = GetRowHeight( iRowToUse);
01469 SetScrollPos32(SB_VERT, max(0, scrollPos - yScroll));
01470 rect.top = GetFixedRowHeight();
01471
01472
01473 InvalidateRect(rect);
01474 }
01475 break;
01476
01477 case SB_PAGEDOWN:
01478 if (scrollPos < m_nVScrollMax)
01479 {
01480 rect.top = GetFixedRowHeight();
01481 scrollPos = min(m_nVScrollMax, scrollPos + rect.Height());
01482 SetScrollPos32(SB_VERT, scrollPos);
01483 rect.top = GetFixedRowHeight();
01484 InvalidateRect(rect);
01485 }
01486 break;
01487
01488 case SB_PAGEUP:
01489 if (scrollPos > 0)
01490 {
01491 rect.top = GetFixedRowHeight();
01492 int offset = -rect.Height();
01493 int pos = max(0, scrollPos + offset);
01494 SetScrollPos32(SB_VERT, pos);
01495 rect.top = GetFixedRowHeight();
01496 InvalidateRect(rect);
01497 }
01498 break;
01499
01500 case SB_THUMBPOSITION:
01501 case SB_THUMBTRACK:
01502 {
01503 SetScrollPos32(SB_VERT, GetScrollPos32(SB_VERT, TRUE));
01504 m_idTopLeftCell.row = -1;
01505 CCellID idNewTopLeft = GetTopleftNonFixedCell();
01506 if (idNewTopLeft != idTopLeft)
01507 {
01508 rect.top = GetFixedRowHeight();
01509 InvalidateRect(rect);
01510 }
01511 }
01512 break;
01513
01514 case SB_TOP:
01515 if (scrollPos > 0)
01516 {
01517 SetScrollPos32(SB_VERT, 0);
01518 Invalidate();
01519 }
01520 break;
01521
01522 case SB_BOTTOM:
01523 if (scrollPos < m_nVScrollMax)
01524 {
01525 SetScrollPos32(SB_VERT, m_nVScrollMax);
01526 Invalidate();
01527 }
01528
01529 default:
01530 break;
01531 }
01532 }
01533
01535
01536
01537 void CGridCtrl::OnDraw(CDC* pDC)
01538 {
01539 if (!m_bAllowDraw)
01540 return;
01541
01542 CRect clipRect;
01543 if (pDC->GetClipBox(&clipRect) == ERROR)
01544 return;
01545
01546 EraseBkgnd(pDC);
01547
01548
01549 #ifdef _DEBUG
01550 LARGE_INTEGER iStartCount;
01551 QueryPerformanceCounter(&iStartCount);
01552 #endif
01553
01554 CRect rect;
01555 int row, col;
01556 CGridCellBase* pCell;
01557
01558 int nFixedRowHeight = GetFixedRowHeight();
01559 int nFixedColWidth = GetFixedColumnWidth();
01560
01561 CCellID idTopLeft = GetTopleftNonFixedCell();
01562 int minVisibleRow = idTopLeft.row,
01563 minVisibleCol = idTopLeft.col;
01564
01565 CRect VisRect;
01566 CCellRange VisCellRange = GetVisibleNonFixedCellRange(VisRect);
01567 int maxVisibleRow = VisCellRange.GetMaxRow(),
01568 maxVisibleCol = VisCellRange.GetMaxCol();
01569
01570 if (GetVirtualMode())
01571 SendCacheHintToParent(VisCellRange);
01572
01573
01574 rect.bottom = -1;
01575 for (row = 0; row < m_nFixedRows; row++)
01576 {
01577 if (GetRowHeight(row) <= 0) continue;
01578
01579 rect.top = rect.bottom+1;
01580 rect.bottom = rect.top + GetRowHeight(row)-1;
01581 rect.right = -1;
01582
01583 for (col = 0; col < m_nFixedCols; col++)
01584 {
01585 if (GetColumnWidth(col) <= 0) continue;
01586
01587 rect.left = rect.right+1;
01588 rect.right = rect.left + GetColumnWidth(col)-1;
01589
01590 pCell = GetCell(row, col);
01591 if (pCell)
01592 {
01593 pCell->SetCoords(row,col);
01594 pCell->Draw(pDC, row, col, rect, FALSE);
01595 }
01596 }
01597 }
01598
01599
01600 rect.bottom = nFixedRowHeight-1;
01601 for (row = minVisibleRow; row <= maxVisibleRow; row++)
01602 {
01603 if (GetRowHeight(row) <= 0) continue;
01604
01605 rect.top = rect.bottom+1;
01606 rect.bottom = rect.top + GetRowHeight(row)-1;
01607
01608
01609 if (rect.top > clipRect.bottom)
01610 break;
01611 if (rect.bottom < clipRect.top)
01612 continue;
01613
01614 rect.right = -1;
01615 for (col = 0; col < m_nFixedCols; col++)
01616 {
01617 if (GetColumnWidth(col) <= 0) continue;
01618
01619 rect.left = rect.right+1;
01620 rect.right = rect.left + GetColumnWidth(col)-1;
01621
01622 if (rect.left > clipRect.right)
01623 break;
01624 if (rect.right < clipRect.left)
01625 continue;
01626
01627 pCell = GetCell(row, col);
01628 if (pCell)
01629 {
01630 pCell->SetCoords(row,col);
01631 pCell->Draw(pDC, row, col, rect, FALSE);
01632 }
01633 }
01634 }
01635
01636
01637 rect.bottom = -1;
01638 for (row = 0; row < m_nFixedRows; row++)
01639 {
01640 if (GetRowHeight(row) <= 0) continue;
01641
01642 rect.top = rect.bottom+1;
01643 rect.bottom = rect.top + GetRowHeight(row)-1;
01644
01645
01646 if (rect.top > clipRect.bottom)
01647 break;
01648 if (rect.bottom < clipRect.top)
01649 continue;
01650
01651 rect.right = nFixedColWidth-1;
01652 for (col = minVisibleCol; col <= maxVisibleCol; col++)
01653 {
01654 if (GetColumnWidth(col) <= 0) continue;
01655
01656 rect.left = rect.right+1;
01657 rect.right = rect.left + GetColumnWidth(col)-1;
01658
01659 if (rect.left > clipRect.right)
01660 break;
01661 if (rect.right < clipRect.left)
01662 continue;
01663
01664 pCell = GetCell(row, col);
01665 if (pCell)
01666 {
01667 pCell->SetCoords(row,col);
01668 pCell->Draw(pDC, row, col, rect, FALSE);
01669 }
01670 }
01671 }
01672
01673
01674 rect.bottom = nFixedRowHeight-1;
01675 for (row = minVisibleRow; row <= maxVisibleRow; row++)
01676 {
01677 if (GetRowHeight(row) <= 0) continue;
01678
01679 rect.top = rect.bottom+1;
01680 rect.bottom = rect.top + GetRowHeight(row)-1;
01681
01682
01683 if (rect.top > clipRect.bottom)
01684 break;
01685 if (rect.bottom < clipRect.top)
01686 continue;
01687
01688 rect.right = nFixedColWidth-1;
01689 for (col = minVisibleCol; col <= maxVisibleCol; col++)
01690 {
01691 if (GetColumnWidth(col) <= 0) continue;
01692
01693 rect.left = rect.right+1;
01694 rect.right = rect.left + GetColumnWidth(col)-1;
01695
01696 if (rect.left > clipRect.right)
01697 break;
01698 if (rect.right < clipRect.left)
01699 continue;
01700
01701 pCell = GetCell(row, col);
01702
01703 if (pCell)
01704 {
01705 pCell->SetCoords(row,col);
01706 pCell->Draw(pDC, row, col, rect, FALSE);
01707 }
01708 }
01709 }
01710
01711
01712 CPen pen;
01713 pen.CreatePen(PS_SOLID, 0, m_crGridLineColour);
01714 pDC->SelectObject(&pen);
01715
01716
01717 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
01718 {
01719 int x = nFixedColWidth;
01720 for (col = minVisibleCol; col <= maxVisibleCol; col++)
01721 {
01722 if (GetColumnWidth(col) <= 0) continue;
01723
01724 x += GetColumnWidth(col);
01725 pDC->MoveTo(x-1, nFixedRowHeight);
01726 pDC->LineTo(x-1, VisRect.bottom);
01727 }
01728 }
01729
01730
01731 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
01732 {
01733 int y = nFixedRowHeight;
01734 for (row = minVisibleRow; row <= maxVisibleRow; row++)
01735 {
01736 if (GetRowHeight(row) <= 0) continue;
01737
01738 y += GetRowHeight(row);
01739 pDC->MoveTo(nFixedColWidth, y-1);
01740 pDC->LineTo(VisRect.right, y-1);
01741 }
01742 }
01743
01744 pDC->SelectStockObject(NULL_PEN);
01745
01746
01747 if (GetVirtualMode())
01748 SendCacheHintToParent(CCellRange(-1,-1,-1,-1));
01749
01750 #ifdef _DEBUG
01751 LARGE_INTEGER iEndCount;
01752 QueryPerformanceCounter(&iEndCount);
01753 TRACE1("Draw counter ticks: %d\n", iEndCount.LowPart-iStartCount.LowPart);
01754 #endif
01755
01756 }
01757
01759
01760
01761
01762
01763 BOOL CGridCtrl::IsValid(int nRow, int nCol) const
01764 {
01765 return (nRow >= 0 && nRow < m_nRows && nCol >= 0 && nCol < m_nCols);
01766 }
01767
01768 BOOL CGridCtrl::IsValid(const CCellID& cell) const
01769 {
01770 return IsValid(cell.row, cell.col);
01771 }
01772
01773
01774
01775 BOOL CGridCtrl::IsValid(const CCellRange& range) const
01776 {
01777 return (range.GetMinRow() >= 0 && range.GetMinCol() >= 0 &&
01778 range.GetMaxRow() >= 0 && range.GetMaxCol() >= 0 &&
01779 range.GetMaxRow() < m_nRows && range.GetMaxCol() < m_nCols &&
01780 range.GetMinRow() <= range.GetMaxRow() && range.GetMinCol() <= range.GetMaxCol());
01781 }
01782
01783
01784
01785 void CGridCtrl::SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars )
01786 {
01787
01788
01789
01790 if (bAllowDraw && !m_bAllowDraw)
01791 {
01792 m_bAllowDraw = TRUE;
01793 Refresh();
01794 }
01795
01796 m_bAllowDraw = bAllowDraw;
01797 if (bResetScrollBars)
01798 ResetScrollBars();
01799 }
01800
01801
01802
01803 BOOL CGridCtrl::RedrawCell(const CCellID& cell, CDC* pDC )
01804 {
01805 return RedrawCell(cell.row, cell.col, pDC);
01806 }
01807
01808 BOOL CGridCtrl::RedrawCell(int nRow, int nCol, CDC* pDC )
01809 {
01810 BOOL bResult = TRUE;
01811 BOOL bMustReleaseDC = FALSE;
01812
01813 if (!m_bAllowDraw || !IsCellVisible(nRow, nCol))
01814 return FALSE;
01815
01816 CRect rect;
01817 if (!GetCellRect(nRow, nCol, rect))
01818 return FALSE;
01819
01820 if (!pDC)
01821 {
01822 pDC = GetDC();
01823 if (pDC)
01824 bMustReleaseDC = TRUE;
01825 }
01826
01827 if (pDC)
01828 {
01829
01830 if (nRow < m_nFixedRows || nCol < m_nFixedCols)
01831 {
01832 CGridCellBase* pCell = GetCell(nRow, nCol);
01833 if (pCell)
01834 bResult = pCell->Draw(pDC, nRow, nCol, rect, TRUE);
01835 }
01836 else
01837 {
01838 CGridCellBase* pCell = GetCell(nRow, nCol);
01839 if (pCell)
01840 bResult = pCell->Draw(pDC, nRow, nCol, rect, TRUE);
01841
01842
01843 CPen pen;
01844 pen.CreatePen(PS_SOLID, 0, m_crGridLineColour);
01845
01846 CPen* pOldPen = (CPen*) pDC->SelectObject(&pen);
01847 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
01848 {
01849 pDC->MoveTo(rect.left, rect.bottom);
01850 pDC->LineTo(rect.right + 1, rect.bottom);
01851 }
01852 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
01853 {
01854 pDC->MoveTo(rect.right, rect.top);
01855 pDC->LineTo(rect.right, rect.bottom + 1);
01856 }
01857 pDC->SelectObject(pOldPen);
01858 }
01859 } else
01860 InvalidateRect(rect, TRUE);
01861
01862
01863 if (bMustReleaseDC)
01864 ReleaseDC(pDC);
01865
01866 return bResult;
01867 }
01868
01869
01870 BOOL CGridCtrl::RedrawRow(int row)
01871 {
01872 BOOL bResult = TRUE;
01873
01874 CDC* pDC = GetDC();
01875 for (int col = 0; col < GetColumnCount(); col++)
01876 bResult = RedrawCell(row, col, pDC) && bResult;
01877 if (pDC)
01878 ReleaseDC(pDC);
01879
01880 return bResult;
01881 }
01882
01883
01884 BOOL CGridCtrl::RedrawColumn(int col)
01885 {
01886 BOOL bResult = TRUE;
01887
01888 CDC* pDC = GetDC();
01889 for (int row = 0; row < GetRowCount(); row++)
01890 bResult = RedrawCell(row, col, pDC) && bResult;
01891 if (pDC)
01892 ReleaseDC(pDC);
01893
01894 return bResult;
01895 }
01896
01897
01898
01899 CCellID CGridCtrl::SetFocusCell(int nRow, int nCol)
01900 {
01901 return SetFocusCell(CCellID(nRow, nCol));
01902 }
01903
01904 CCellID CGridCtrl::SetFocusCell(CCellID cell)
01905 {
01906 if (cell == m_idCurrentCell)
01907 return m_idCurrentCell;
01908
01909 CCellID idPrev = m_idCurrentCell;
01910
01911
01912 if (cell.row != -1 && cell.row < GetFixedRowCount())
01913 cell.row = GetFixedRowCount();
01914 if (cell.col != -1 && cell.col < GetFixedColumnCount())
01915 cell.col = GetFixedColumnCount();
01916
01917 m_idCurrentCell = cell;
01918
01919 if (IsValid(idPrev))
01920 {
01921 SetItemState(idPrev.row, idPrev.col,
01922 GetItemState(idPrev.row, idPrev.col) & ~GVIS_FOCUSED);
01923 RedrawCell(idPrev);
01924
01925 if (GetTrackFocusCell() && idPrev.col != m_idCurrentCell.col)
01926 for (int row = 0; row < m_nFixedRows; row++)
01927 RedrawCell(row, idPrev.col);
01928 if (GetTrackFocusCell() && idPrev.row != m_idCurrentCell.row)
01929 for (int col = 0; col < m_nFixedCols; col++)
01930 RedrawCell(idPrev.row, col);
01931 }
01932
01933 if (IsValid(m_idCurrentCell))
01934 {
01935 SetItemState(m_idCurrentCell.row, m_idCurrentCell.col,
01936 GetItemState(m_idCurrentCell.row, m_idCurrentCell.col) | GVIS_FOCUSED);
01937
01938 RedrawCell(m_idCurrentCell);
01939
01940 if (GetTrackFocusCell() && idPrev.col != m_idCurrentCell.col)
01941 for (int row = 0; row < m_nFixedRows; row++)
01942 RedrawCell(row, m_idCurrentCell.col);
01943 if (GetTrackFocusCell() && idPrev.row != m_idCurrentCell.row)
01944 for (int col = 0; col < m_nFixedCols; col++)
01945 RedrawCell(m_idCurrentCell.row, col);
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 }
01962
01963 return idPrev;
01964 }
01965
01966
01967 void CGridCtrl::SetSelectedRange(const CCellRange& Range,
01968 BOOL bForceRepaint , BOOL bSelectCells)
01969 {
01970 SetSelectedRange(Range.GetMinRow(), Range.GetMinCol(),
01971 Range.GetMaxRow(), Range.GetMaxCol(),
01972 bForceRepaint, bSelectCells);
01973 }
01974
01975 void CGridCtrl::SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol,
01976 BOOL bForceRepaint , BOOL bSelectCells)
01977 {
01978 if (!m_bEnableSelection)
01979 return;
01980
01981 CWaitCursor wait;
01982
01983 CDC* pDC = NULL;
01984 if (bForceRepaint)
01985 pDC = GetDC();
01986
01987
01988 CCellRange VisCellRange;
01989 if (IsWindow(GetSafeHwnd()))
01990 VisCellRange = GetVisibleNonFixedCellRange();
01991
01992
01993 if(nMinRow >= 0 && nMinRow < GetFixedRowCount())
01994 nMinRow = GetFixedRowCount();
01995 if(nMaxRow >= 0 && nMaxRow < GetFixedRowCount())
01996 nMaxRow = GetFixedRowCount();
01997 if(nMinCol >= 0 && nMinCol < GetFixedColumnCount())
01998 nMinCol = GetFixedColumnCount();
01999 if(nMaxCol >= 0 && nMaxCol < GetFixedColumnCount())
02000 nMaxCol = GetFixedColumnCount();
02001
02002
02003 if (bSelectCells)
02004 {
02005 POSITION pos;
02006
02007
02008 for (pos = m_SelectedCellMap.GetStartPosition(); pos != NULL; )
02009 {
02010 DWORD key;
02011 CCellID cell;
02012 m_SelectedCellMap.GetNextAssoc(pos, key, (CCellID&)cell);
02013
02014
02015 if (IsValid(cell))
02016 {
02017
02018 SetItemState(cell.row, cell.col,
02019 GetItemState(cell.row, cell.col) & ~GVIS_SELECTED);
02020
02021
02022 if (nMinRow <= cell.row && cell.row <= nMaxRow &&
02023 nMinCol <= cell.col && cell.col <= nMaxCol)
02024 continue;
02025
02026 if ( VisCellRange.IsValid() && VisCellRange.InRange( cell ) )
02027 {
02028 if (bForceRepaint && pDC)
02029 RedrawCell(cell.row, cell.col, pDC);
02030 else
02031 InvalidateCellRect(cell);
02032 }
02033 }
02034 else
02035 {
02036 m_SelectedCellMap.RemoveKey( key);
02037 }
02038 }
02039
02040
02041
02042
02043
02044
02045 if (!GetSingleRowSelection() &&
02046 nMinRow >= 0 && nMinCol >= 0 && nMaxRow >= 0 && nMaxCol >= 0)
02047 {
02048 for (pos = m_PrevSelectedCellMap.GetStartPosition(); pos != NULL; )
02049 {
02050 DWORD key;
02051 CCellID cell;
02052 m_PrevSelectedCellMap.GetNextAssoc(pos, key, (CCellID&)cell);
02053
02054 if (!IsValid(cell))
02055 continue;
02056
02057 int nState = GetItemState(cell.row, cell.col);
02058
02059
02060 SetItemState(cell.row, cell.col, nState | GVIS_SELECTED);
02061
02062 if ( VisCellRange.IsValid() && VisCellRange.InRange( cell ) )
02063 {
02064
02065 if (bForceRepaint && pDC)
02066 RedrawCell(cell.row, cell.col, pDC);
02067 else
02068 InvalidateCellRect(cell);
02069 }
02070 }
02071 }
02072 }
02073
02074
02075
02076
02077 if (nMinRow >= 0 && nMinCol >= 0 && nMaxRow >= 0 && nMaxCol >= 0 &&
02078 nMaxRow < m_nRows && nMaxCol < m_nCols &&
02079 nMinRow <= nMaxRow && nMinCol <= nMaxCol)
02080 {
02081 for (int row = nMinRow; row <= nMaxRow; row++)
02082 for (int col = nMinCol; col <= nMaxCol; col++)
02083 {
02084 BOOL bCellSelected = IsCellSelected(row, col);
02085 if (bSelectCells == bCellSelected)
02086 continue;
02087
02088
02089 if (bSelectCells)
02090 SetItemState(row, col, GetItemState(row, col) | GVIS_SELECTED);
02091 else
02092 SetItemState(row, col, GetItemState(row, col) & ~GVIS_SELECTED);
02093
02094 if ( VisCellRange.IsValid() && VisCellRange.InRange(row, col) )
02095 {
02096
02097 if (bForceRepaint && pDC)
02098 RedrawCell(row, col, pDC);
02099 else
02100 InvalidateCellRect(row, col);
02101 }
02102 }
02103 }
02104
02105
02106 if (pDC != NULL)
02107 ReleaseDC(pDC);
02108 }
02109
02110
02111 void CGridCtrl::SelectAllCells()
02112 {
02113 if (!m_bEnableSelection)
02114 return;
02115
02116 SetSelectedRange(m_nFixedRows, m_nFixedCols, GetRowCount()-1, GetColumnCount()-1);
02117 }
02118
02119
02120 void CGridCtrl::SelectColumns(CCellID currentCell,
02121 BOOL bForceRedraw , BOOL bSelectCells )
02122 {
02123 if (!m_bEnableSelection)
02124 return;
02125
02126
02127 if (currentCell.col < m_nFixedCols)
02128 return;
02129 if (!IsValid(currentCell))
02130 return;
02131
02132 if (GetSingleColSelection())
02133 SetSelectedRange(GetFixedRowCount(), currentCell.col,
02134 GetRowCount()-1, currentCell.col,
02135 bForceRedraw, bSelectCells);
02136 else
02137 SetSelectedRange(GetFixedRowCount(),
02138 min(m_SelectionStartCell.col, currentCell.col),
02139 GetRowCount()-1,
02140 max(m_SelectionStartCell.col, currentCell.col),
02141 bForceRedraw, bSelectCells);
02142 }
02143
02144
02145 void CGridCtrl::SelectRows(CCellID currentCell,
02146 BOOL bForceRedraw , BOOL bSelectCells )
02147 {
02148 if (!m_bEnableSelection)
02149 return;
02150
02151
02152 if (currentCell.row < m_nFixedRows)
02153 return;
02154 if (!IsValid(currentCell))
02155 return;
02156
02157 if (GetSingleRowSelection())
02158 SetSelectedRange(currentCell.row, GetFixedColumnCount(),
02159 currentCell.row, GetColumnCount()-1,
02160 bForceRedraw, bSelectCells);
02161 else
02162 SetSelectedRange(min(m_SelectionStartCell.row, currentCell.row),
02163 GetFixedColumnCount(),
02164 max(m_SelectionStartCell.row, currentCell.row),
02165 GetColumnCount()-1,
02166 bForceRedraw, bSelectCells);
02167 }
02168
02169
02170 void CGridCtrl::SelectCells(CCellID currentCell,
02171 BOOL bForceRedraw , BOOL bSelectCells )
02172 {
02173 if (!m_bEnableSelection)
02174 return;
02175
02176 int row = currentCell.row;
02177 int col = currentCell.col;
02178 if (row < m_nFixedRows || col < m_nFixedCols)
02179 return;
02180 if (!IsValid(currentCell))
02181 return;
02182
02183
02184
02185
02186
02187 SetSelectedRange(min(m_SelectionStartCell.row, row),
02188 min(m_SelectionStartCell.col, col),
02189 max(m_SelectionStartCell.row, row),
02190 max(m_SelectionStartCell.col, col),
02191 bForceRedraw, bSelectCells);
02192 }
02193
02194
02195 void CGridCtrl::OnSelecting(const CCellID& currentCell)
02196 {
02197 if (!m_bEnableSelection)
02198 return;
02199
02200 switch (m_MouseMode)
02201 {
02202 case MOUSE_SELECT_ALL:
02203 SelectAllCells();
02204 break;
02205 case MOUSE_SELECT_COL:
02206 SelectColumns(currentCell, FALSE);
02207 break;
02208 case MOUSE_SELECT_ROW:
02209 SelectRows(currentCell, FALSE);
02210 break;
02211 case MOUSE_SELECT_CELLS:
02212 SelectCells(currentCell, FALSE);
02213 break;
02214 }
02215
02216
02217
02218 }
02219
02220 void CGridCtrl::ValidateAndModifyCellContents(int nRow, int nCol, LPCTSTR strText)
02221 {
02222 if (!IsCellEditable(nRow, nCol))
02223 return;
02224
02225 if (SendMessageToParent(nRow, nCol, GVN_BEGINLABELEDIT) >= 0)
02226 {
02227 CString strCurrentText = GetItemText(nRow, nCol);
02228 if (strCurrentText != strText)
02229 {
02230 SetItemText(nRow, nCol, strText);
02231 if (ValidateEdit(nRow, nCol, strText) &&
02232 SendMessageToParent(nRow, nCol, GVN_ENDLABELEDIT) >= 0)
02233 {
02234 SetModified(TRUE, nRow, nCol);
02235 RedrawCell(nRow, nCol);
02236 }
02237 else
02238 {
02239 SetItemText(nRow, nCol, strCurrentText);
02240 }
02241 }
02242 }
02243 }
02244
02245 void CGridCtrl::ClearCells(CCellRange Selection)
02246 {
02247 for (int row = Selection.GetMinRow(); row <= Selection.GetMaxRow(); row++)
02248 {
02249 for (int col = Selection.GetMinCol(); col <= Selection.GetMaxCol(); col++)
02250 {
02251
02252 if ( m_arRowHeights[row] > 0 && m_arColWidths[col] > 0 )
02253 {
02254 ValidateAndModifyCellContents(row, col, _T(""));
02255 }
02256 }
02257 }
02258 Refresh();
02259 }
02260
02261 #ifndef GRIDCONTROL_NO_CLIPBOARD
02262
02264
02265
02266
02267 void CGridCtrl::CutSelectedText()
02268 {
02269 if (!IsEditable())
02270 return;
02271
02272 for (POSITION pos = m_SelectedCellMap.GetStartPosition(); pos != NULL; )
02273 {
02274 DWORD key;
02275 CCellID cell;
02276 m_SelectedCellMap.GetNextAssoc(pos, key, (CCellID&)cell);
02277 ValidateAndModifyCellContents(cell.row, cell.col, _T(""));
02278 }
02279 }
02280
02281
02282 COleDataSource* CGridCtrl::CopyTextFromGrid()
02283 {
02284 USES_CONVERSION;
02285
02286 CCellRange Selection = GetSelectedCellRange();
02287 if (!IsValid(Selection))
02288 return NULL;
02289
02290 if (GetVirtualMode())
02291 SendCacheHintToParent(Selection);
02292
02293
02294 CSharedFile sf(GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT);
02295
02296
02297 CString str;
02298 CGridCellBase *pCell;
02299 for (int row = Selection.GetMinRow(); row <= Selection.GetMaxRow(); row++)
02300 {
02301
02302 if( m_arRowHeights[row] <= 0 )
02303 continue;
02304
02305 str.Empty();
02306 for (int col = Selection.GetMinCol(); col <= Selection.GetMaxCol(); col++)
02307 {
02308
02309 if( m_arColWidths[col] <= 0 )
02310 continue;
02311
02312 pCell = GetCell(row, col);
02313 if (pCell &&(pCell->GetState() & GVIS_SELECTED))
02314 {
02315
02316
02317
02318 str += pCell->GetText();
02319 }
02320 if (col != Selection.GetMaxCol())
02321 str += _T("\t");
02322 }
02323 if (row != Selection.GetMaxRow())
02324 str += _T("\n");
02325
02326 sf.Write(T2A(str.GetBuffer(1)), str.GetLength());
02327 str.ReleaseBuffer();
02328 }
02329
02330 char c = '\0';
02331 sf.Write(&c, 1);
02332
02333 if (GetVirtualMode())
02334 SendCacheHintToParent(CCellRange(-1,-1,-1,-1));
02335
02336 DWORD dwLen = (DWORD) sf.GetLength();
02337 HGLOBAL hMem = sf.Detach();
02338 if (!hMem)
02339 return NULL;
02340
02341 hMem = ::GlobalReAlloc(hMem, dwLen, GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT);
02342 if (!hMem)
02343 return NULL;
02344
02345
02346 COleDataSource* pSource = new COleDataSource();
02347 pSource->CacheGlobalData(CF_TEXT, hMem);
02348
02349 return pSource;
02350 }
02351
02352
02353 BOOL CGridCtrl::PasteTextToGrid(CCellID cell, COleDataObject* pDataObject,
02354 BOOL bSelectPastedCells )
02355 {
02356 if (!IsValid(cell) || !IsCellEditable(cell) || !pDataObject->IsDataAvailable(CF_TEXT))
02357 return FALSE;
02358
02359
02360 HGLOBAL hmem = pDataObject->GetGlobalData(CF_TEXT);
02361 CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
02362
02363
02364
02365 LPSTR szBuffer = new char[::GlobalSize(hmem)];
02366 if (!szBuffer)
02367 return FALSE;
02368
02369 sf.Read(szBuffer, ::GlobalSize(hmem));
02370 ::GlobalUnlock(hmem);
02371
02372
02373
02374 CString strText = szBuffer;
02375 delete szBuffer;
02376
02377
02378 strText.LockBuffer();
02379 CString strLine = strText;
02380 int nLine = 0;
02381
02382
02383 CCellRange PasteRange(cell.row, cell.col,-1,-1);
02384 int nIndex;
02385 do
02386 {
02387 int nColumn = 0;
02388 nIndex = strLine.Find(_T("\n"));
02389
02390
02391 CString strNext = (nIndex < 0)? _T("") : strLine.Mid(nIndex + 1);
02392
02393
02394 if (nIndex >= 0)
02395 strLine = strLine.Left(nIndex);
02396
02397 int nLineIndex = strLine.FindOneOf(_T("\t,"));
02398 CString strCellText = (nLineIndex >= 0)? strLine.Left(nLineIndex) : strLine;
02399
02400
02401 int iRowVis = cell.row + nLine;
02402 while( iRowVis < GetRowCount())
02403 {
02404 if( GetRowHeight( iRowVis) > 0)
02405 break;
02406 nLine++;
02407 iRowVis++;
02408 }
02409
02410 while (!strLine.IsEmpty())
02411 {
02412
02413 int iColVis = cell.col + nColumn;
02414 while( iColVis < GetColumnCount())
02415 {
02416 if( GetColumnWidth( iColVis) > 0)
02417 break;
02418 nColumn++;
02419 iColVis++;
02420 }
02421
02422 CCellID TargetCell(iRowVis, iColVis);
02423 if (IsValid(TargetCell))
02424 {
02425 strCellText.TrimLeft();
02426 strCellText.TrimRight();
02427
02428 ValidateAndModifyCellContents(TargetCell.row, TargetCell.col, strCellText);
02429
02430
02431 SetItemState(TargetCell.row, TargetCell.col,
02432 GetItemState(TargetCell.row, TargetCell.col) & ~GVIS_SELECTED);
02433
02434 if (iRowVis > PasteRange.GetMaxRow()) PasteRange.SetMaxRow(iRowVis);
02435 if (iColVis > PasteRange.GetMaxCol()) PasteRange.SetMaxCol(iColVis);
02436 }
02437
02438 strLine = (nLineIndex >= 0)? strLine.Mid(nLineIndex + 1) : _T("");
02439 nLineIndex = strLine.FindOneOf(_T("\t,"));
02440 strCellText = (nLineIndex >= 0)? strLine.Left(nLineIndex) : strLine;
02441
02442 nColumn++;
02443 }
02444
02445 strLine = strNext;
02446 nLine++;
02447 } while (nIndex >= 0);
02448
02449 strText.UnlockBuffer();
02450
02451 if (bSelectPastedCells)
02452 SetSelectedRange(PasteRange, TRUE);
02453 else
02454 {
02455 ResetSelectedRange();
02456 Refresh();
02457 }
02458
02459 return TRUE;
02460 }
02461 #endif
02462
02463 #ifndef GRIDCONTROL_NO_DRAGDROP
02464
02465
02466 void CGridCtrl::OnBeginDrag()
02467 {
02468 if (!m_bAllowDragAndDrop)
02469 return;
02470
02471 COleDataSource* pSource = CopyTextFromGrid();
02472 if (pSource)
02473 {
02474 SendMessageToParent(GetSelectedCellRange().GetTopLeft().row,
02475 GetSelectedCellRange().GetTopLeft().col,
02476 GVN_BEGINDRAG);
02477
02478 m_MouseMode = MOUSE_DRAGGING;
02479 m_bLMouseButtonDown = FALSE;
02480
02481 DROPEFFECT dropEffect = pSource->DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE);
02482
02483 if (dropEffect & DROPEFFECT_MOVE)
02484 CutSelectedText();
02485
02486 if (pSource)
02487 delete pSource;
02488 }
02489 }
02490
02491
02492 DROPEFFECT CGridCtrl::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState,
02493 CPoint point)
02494 {
02495
02496 if (!m_bAllowDragAndDrop || !IsEditable() || !pDataObject->IsDataAvailable(CF_TEXT))
02497 return DROPEFFECT_NONE;
02498
02499
02500 CCellID cell = GetCellFromPt(point, FALSE);
02501
02502
02503 if (!IsValid(cell))
02504 {
02505 OnDragLeave();
02506 m_LastDragOverCell = CCellID(-1,-1);
02507 return DROPEFFECT_NONE;
02508 }
02509
02510 if (!IsCellEditable(cell))
02511 return DROPEFFECT_NONE;
02512
02513
02514 if (cell != m_LastDragOverCell)
02515 {
02516
02517 if (IsValid(m_LastDragOverCell))
02518 {
02519 UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
02520 SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
02521 nState & ~GVIS_DROPHILITED);
02522 RedrawCell(m_LastDragOverCell);
02523 }
02524
02525 m_LastDragOverCell = cell;
02526
02527
02528 if (IsValid(m_LastDragOverCell))
02529 {
02530 UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
02531 SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
02532 nState | GVIS_DROPHILITED);
02533 RedrawCell(m_LastDragOverCell);
02534 }
02535 }
02536
02537
02538 if (dwKeyState & MK_CONTROL)
02539 return DROPEFFECT_COPY;
02540 else
02541 return DROPEFFECT_MOVE;
02542 }
02543
02544
02545 DROPEFFECT CGridCtrl::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState,
02546 CPoint point)
02547 {
02548
02549 if (!m_bAllowDragAndDrop || !pDataObject->IsDataAvailable(CF_TEXT))
02550 return DROPEFFECT_NONE;
02551
02552
02553 m_LastDragOverCell = GetCellFromPt(point, FALSE);
02554 if (!IsValid(m_LastDragOverCell))
02555 return DROPEFFECT_NONE;
02556
02557 if (!IsCellEditable(m_LastDragOverCell))
02558 return DROPEFFECT_NONE;
02559
02560 if (IsValid(m_LastDragOverCell))
02561 {
02562 UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
02563 SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
02564 nState | GVIS_DROPHILITED);
02565 RedrawCell(m_LastDragOverCell);
02566 }
02567
02568
02569 if (dwKeyState & MK_CONTROL)
02570 return DROPEFFECT_COPY;
02571 else
02572 return DROPEFFECT_MOVE;
02573 }
02574
02575
02576 void CGridCtrl::OnDragLeave()
02577 {
02578
02579 if (IsValid(m_LastDragOverCell))
02580 {
02581 UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
02582 SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
02583 nState & ~GVIS_DROPHILITED);
02584 RedrawCell(m_LastDragOverCell);
02585 }
02586 }
02587
02588
02589 BOOL CGridCtrl::OnDrop(COleDataObject* pDataObject, DROPEFFECT ,
02590 CPoint )
02591 {
02592 m_MouseMode = MOUSE_NOTHING;
02593
02594 if (!m_bAllowDragAndDrop || !IsCellEditable(m_LastDragOverCell))
02595 return FALSE;
02596
02597 OnDragLeave();
02598
02599 return PasteTextToGrid(m_LastDragOverCell, pDataObject, FALSE);
02600 }
02601 #endif
02602
02603 #ifndef GRIDCONTROL_NO_CLIPBOARD
02604 void CGridCtrl::OnEditCut()
02605 {
02606 if (!IsEditable())
02607 return;
02608
02609 COleDataSource* pSource = CopyTextFromGrid();
02610 if (!pSource)
02611 return;
02612
02613 pSource->SetClipboard();
02614 CutSelectedText();
02615 }
02616
02617 void CGridCtrl::OnEditCopy()
02618 {
02619 COleDataSource* pSource = CopyTextFromGrid();
02620 if (!pSource)
02621 return;
02622
02623 pSource->SetClipboard();
02624 }
02625
02626 void CGridCtrl::OnEditPaste()
02627 {
02628 if (!IsEditable())
02629 return;
02630
02631 CCellRange cellRange = GetSelectedCellRange();
02632
02633
02634 CCellID cell;
02635 if (cellRange.IsValid())
02636 {
02637 cell.row = cellRange.GetMinRow();
02638 cell.col = cellRange.GetMinCol();
02639 }
02640 else
02641 {
02642 cell = GetFocusCell();
02643 if (!IsValid(cell))
02644 cell = GetTopleftNonFixedCell();
02645 if (!IsValid(cell))
02646 return;
02647 }
02648
02649
02650 if ( IsItemEditing(cell.row, cell.col) )
02651 {
02652 CGridCellBase* pCell = GetCell(cell.row, cell.col);
02653 ASSERT(pCell);
02654 if (!pCell) return;
02655
02656 CWnd* pEditWnd = pCell->GetEditWnd();
02657 if ( pEditWnd && pEditWnd->IsKindOf(RUNTIME_CLASS(CEdit)) )
02658 {
02659 ((CEdit*)pEditWnd)->Paste();
02660 return;
02661 }
02662 }
02663
02664
02665 COleDataObject obj;
02666 if (obj.AttachClipboard())
02667 PasteTextToGrid(cell, &obj);
02668 }
02669 #endif
02670
02671 void CGridCtrl::OnEditSelectAll()
02672 {
02673 SendMessageToParent(m_LeftClickDownCell.row, m_LeftClickDownCell.col, GVN_SELCHANGING);
02674 SelectAllCells();
02675 SendMessageToParent(m_idCurrentCell.row, m_idCurrentCell.col, GVN_SELCHANGED);
02676 }
02677
02678 #ifndef GRIDCONTROL_NO_CLIPBOARD
02679 void CGridCtrl::OnUpdateEditCopy(CCmdUI* pCmdUI)
02680 {
02681 pCmdUI->Enable(GetSelectedCount() > 0);
02682
02683
02684 }
02685
02686 void CGridCtrl::OnUpdateEditCut(CCmdUI* pCmdUI)
02687 {
02688 pCmdUI->Enable(IsEditable() && GetSelectedCount() > 0);
02689
02690
02691 }
02692
02693 void CGridCtrl::OnUpdateEditPaste(CCmdUI* pCmdUI)
02694 {
02695 CCellID cell = GetFocusCell();
02696
02697 BOOL bCanPaste = IsValid(cell) && IsCellEditable(cell) &&
02698 ::IsClipboardFormatAvailable(CF_TEXT);
02699
02700 pCmdUI->Enable(bCanPaste);
02701 }
02702 #endif
02703
02704 void CGridCtrl::OnUpdateEditSelectAll(CCmdUI* pCmdUI)
02705 {
02706 pCmdUI->Enable(m_bEnableSelection);
02707 }
02708
02710
02711
02712
02713 BOOL CGridCtrl::MouseOverRowResizeArea(CPoint& point)
02714 {
02715 if (point.x >= GetFixedColumnWidth())
02716 return FALSE;
02717
02718 CCellID idCurrentCell = GetCellFromPt(point);
02719 CPoint start;
02720 if (!GetCellOrigin(idCurrentCell, &start))
02721 return FALSE;
02722
02723 int endy = start.y + GetRowHeight(idCurrentCell.row);
02724
02725 if ((point.y - start.y < m_nResizeCaptureRange && idCurrentCell.row != 0) ||
02726 endy - point.y < m_nResizeCaptureRange)
02727 {
02728 return TRUE;
02729 }
02730 else
02731 return FALSE;
02732 }
02733
02734
02735 BOOL CGridCtrl::MouseOverColumnResizeArea(CPoint& point)
02736 {
02737 if (point.y >= GetFixedRowHeight())
02738 return FALSE;
02739
02740 CCellID idCurrentCell = GetCellFromPt(point);
02741 CPoint start;
02742 if (!GetCellOrigin(idCurrentCell, &start))
02743 return FALSE;
02744
02745 int endx = start.x + GetColumnWidth(idCurrentCell.col);
02746
02747 if ((point.x - start.x < m_nResizeCaptureRange && idCurrentCell.col != 0) ||
02748 endx - point.x < m_nResizeCaptureRange)
02749 {
02750 return TRUE;
02751 }
02752 else
02753 return FALSE;
02754 }
02755
02756
02757
02758
02759 CCellID CGridCtrl::GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck )
02760 {
02761 CCellID cellID;
02762
02763 CCellID idTopLeft = GetTopleftNonFixedCell();
02764 if (!bAllowFixedCellCheck && !IsValid(idTopLeft))
02765 return cellID;
02766
02767
02768 int fixedColWidth = GetFixedColumnWidth();
02769
02770 if (point.x < 0 || (!bAllowFixedCellCheck && point.x < fixedColWidth))
02771 cellID.col = -1;
02772 else if (point.x < fixedColWidth)
02773 {
02774 int xpos = 0;
02775 int col = 0;
02776 while (col < m_nFixedCols)
02777 {
02778 xpos += GetColumnWidth(col);
02779 if (xpos > point.x)
02780 break;
02781 col++;
02782 }
02783 cellID.col = col;
02784 }
02785 else
02786 {
02787 int xpos = fixedColWidth;
02788 int col = idTopLeft.col;
02789 while ( col < GetColumnCount())
02790 {
02791 xpos += GetColumnWidth(col);
02792 if (xpos > point.x)
02793 break;
02794 col++;
02795 }
02796
02797 if (col >= GetColumnCount())
02798 cellID.col = -1;
02799 else
02800 cellID.col = col;
02801 }
02802
02803
02804 int fixedRowHeight = GetFixedRowHeight();
02805 if (point.y < 0 || (!bAllowFixedCellCheck && point.y < fixedRowHeight))
02806 cellID.row = -1;
02807 else if (point.y < fixedRowHeight)
02808 {
02809 int ypos = 0;
02810 int row = 0;
02811 while (row < m_nFixedRows)
02812 {
02813 ypos += GetRowHeight(row);
02814 if (ypos > point.y)
02815 break;
02816 row++;
02817 }
02818 cellID.row = row;
02819 }
02820 else
02821 {
02822 int ypos = fixedRowHeight;
02823 int row = idTopLeft.row;
02824 while ( row < GetRowCount() )
02825 {
02826 ypos += GetRowHeight(row);
02827 if (ypos > point.y)
02828 break;
02829 row++;
02830 }
02831
02832 if (row >= GetRowCount())
02833 cellID.row = -1;
02834 else
02835 cellID.row = row;
02836 }
02837
02838 return cellID;
02839 }
02840
02842
02843
02844
02845 CCellID CGridCtrl::GetTopleftNonFixedCell(BOOL bForceRecalculation )
02846 {
02847
02848 if (m_idTopLeftCell.IsValid() && !bForceRecalculation)
02849 return m_idTopLeftCell;
02850
02851 int nVertScroll = GetScrollPos(SB_VERT),
02852 nHorzScroll = GetScrollPos(SB_HORZ);
02853
02854 m_idTopLeftCell.col = m_nFixedCols;
02855 int nRight = 0;
02856 while (nRight < nHorzScroll && m_idTopLeftCell.col < (GetColumnCount()-1))
02857 nRight += GetColumnWidth(m_idTopLeftCell.col++);
02858
02859 m_idTopLeftCell.row = m_nFixedRows;
02860 int nTop = 0;
02861 while (nTop < nVertScroll && m_idTopLeftCell.row < (GetRowCount()-1))
02862 nTop += GetRowHeight(m_idTopLeftCell.row++);
02863
02864
02865 return m_idTopLeftCell;
02866 }
02867
02868
02869 CCellRange CGridCtrl::GetVisibleNonFixedCellRange(LPRECT pRect ,
02870 BOOL bForceRecalculation )
02871 {
02872 CRect rect;
02873 GetClientRect(rect);
02874
02875 CCellID idTopLeft = GetTopleftNonFixedCell(bForceRecalculation);
02876
02877
02878 int bottom = GetFixedRowHeight();
02879 int i;
02880 for (i = idTopLeft.row; i < GetRowCount(); i++)
02881 {
02882 bottom += GetRowHeight(i);
02883 if (bottom >= rect.bottom)
02884 {
02885 bottom = rect.bottom;
02886 break;
02887 }
02888 }
02889 int maxVisibleRow = min(i, GetRowCount() - 1);
02890
02891
02892 int right = GetFixedColumnWidth();
02893 for (i = idTopLeft.col; i < GetColumnCount(); i++)
02894 {
02895 right += GetColumnWidth(i);
02896 if (right >= rect.right)
02897 {
02898 right = rect.right;
02899 break;
02900 }
02901 }
02902 int maxVisibleCol = min(i, GetColumnCount() - 1);
02903 if (pRect)
02904 {
02905 pRect->left = pRect->top = 0;
02906 pRect->right = right;
02907 pRect->bottom = bottom;
02908 }
02909
02910 return CCellRange(idTopLeft.row, idTopLeft.col, maxVisibleRow, maxVisibleCol);
02911 }
02912
02913
02914 CCellRange CGridCtrl::GetUnobstructedNonFixedCellRange(BOOL bForceRecalculation )
02915 {
02916 CRect rect;
02917 GetClientRect(rect);
02918
02919 CCellID idTopLeft = GetTopleftNonFixedCell(bForceRecalculation);
02920
02921
02922 int bottom = GetFixedRowHeight();
02923 int i;
02924 for (i = idTopLeft.row; i < GetRowCount(); i++)
02925 {
02926 bottom += GetRowHeight(i);
02927 if (bottom >= rect.bottom)
02928 break;
02929 }
02930 int maxVisibleRow = min(i, GetRowCount() - 1);
02931 if (maxVisibleRow > 0 && bottom > rect.bottom)
02932 maxVisibleRow--;
02933
02934
02935 int right = GetFixedColumnWidth();
02936 for (i = idTopLeft.col; i < GetColumnCount(); i++)
02937 {
02938 right += GetColumnWidth(i);
02939 if (right >= rect.right)
02940 break;
02941 }
02942 int maxVisibleCol = min(i, GetColumnCount() - 1);
02943 if (maxVisibleCol > 0 && right > rect.right)
02944 maxVisibleCol--;
02945
02946
02947 return CCellRange(idTopLeft.row, idTopLeft.col, maxVisibleRow, maxVisibleCol);
02948 }
02949
02950
02951
02952 CCellRange CGridCtrl::GetSelectedCellRange() const
02953 {
02954 CCellRange Selection(GetRowCount(), GetColumnCount(), -1,-1);
02955
02956 for (POSITION pos = m_SelectedCellMap.GetStartPosition(); pos != NULL; )
02957 {
02958 DWORD key;
02959 CCellID cell;
02960 m_SelectedCellMap.GetNextAssoc(pos, key, (CCellID&)cell);
02961
02962 Selection.SetMinRow( min(Selection.GetMinRow(), cell.row) );
02963 Selection.SetMinCol( min(Selection.GetMinCol(), cell.col) );
02964 Selection.SetMaxRow( max(Selection.GetMaxRow(), cell.row) );
02965 Selection.SetMaxCol( max(Selection.GetMaxCol(), cell.col) );
02966 }
02967
02968 return Selection;
02969 }
02970
02971
02972 CCellRange CGridCtrl::GetCellRange() const
02973 {
02974 return CCellRange(0, 0, GetRowCount() - 1, GetColumnCount() - 1);
02975 }
02976
02977
02978 void CGridCtrl::ResetSelectedRange()
02979 {
02980 m_PrevSelectedCellMap.RemoveAll();
02981 SetSelectedRange(-1,-1,-1,-1);
02982 SetFocusCell(-1,-1);
02983 }
02984
02985
02986 int CGridCtrl::GetScrollPos32(int nBar, BOOL bGetTrackPos )
02987 {
02988 SCROLLINFO si;
02989 si.cbSize = sizeof(SCROLLINFO);
02990
02991 if (bGetTrackPos)
02992 {
02993 if (GetScrollInfo(nBar, &si, SIF_TRACKPOS))
02994 return si.nTrackPos;
02995 }
02996 else
02997 {
02998 if (GetScrollInfo(nBar, &si, SIF_POS))
02999 return si.nPos;
03000 }
03001
03002 return 0;
03003 }
03004
03005 BOOL CGridCtrl::SetScrollPos32(int nBar, int nPos, BOOL bRedraw )
03006 {
03007 m_idTopLeftCell.row = -1;
03008
03009 SCROLLINFO si;
03010 si.cbSize = sizeof(SCROLLINFO);
03011 si.fMask = SIF_POS;
03012 si.nPos = nPos;
03013 return SetScrollInfo(nBar, &si, bRedraw);
03014 }
03015
03016 void CGridCtrl::EnableScrollBars(int nBar, BOOL bEnable )
03017 {
03018 if (bEnable)
03019 {
03020 if (!IsVisibleHScroll() && (nBar == SB_HORZ || nBar == SB_BOTH))
03021 {
03022 m_nBarState |= GVL_HORZ;
03023 CWnd::EnableScrollBarCtrl(SB_HORZ, bEnable);
03024 }
03025
03026 if (!IsVisibleVScroll() && (nBar == SB_VERT || nBar == SB_BOTH))
03027 {
03028 m_nBarState |= GVL_VERT;
03029 CWnd::EnableScrollBarCtrl(SB_VERT, bEnable);
03030 }
03031 }
03032 else
03033 {
03034 if ( IsVisibleHScroll() && (nBar == SB_HORZ || nBar == SB_BOTH))
03035 {
03036 m_nBarState &= ~GVL_HORZ;
03037 CWnd::EnableScrollBarCtrl(SB_HORZ, bEnable);
03038 }
03039
03040 if ( IsVisibleVScroll() && (nBar == SB_VERT || nBar == SB_BOTH))
03041 {
03042 m_nBarState &= ~GVL_VERT;
03043 CWnd::EnableScrollBarCtrl(SB_VERT, bEnable);
03044 }
03045 }
03046 }
03047
03048
03049 void CGridCtrl::ResetScrollBars()
03050 {
03051
03052 m_idTopLeftCell.row = -1;
03053
03054 if (!m_bAllowDraw || !::IsWindow(GetSafeHwnd()))
03055 return;
03056
03057 CRect rect;
03058
03059
03060
03061
03062 GetClientRect(rect);
03063
03064 if (rect.left == rect.right || rect.top == rect.bottom)
03065 return;
03066
03067 if (IsVisibleVScroll())
03068 rect.right += GetSystemMetrics(SM_CXVSCROLL) + GetSystemMetrics(SM_CXBORDER);
03069
03070 if (IsVisibleHScroll())
03071 rect.bottom += GetSystemMetrics(SM_CYHSCROLL) + GetSystemMetrics(SM_CYBORDER);
03072
03073 rect.left += GetFixedColumnWidth();
03074 rect.top += GetFixedRowHeight();
03075
03076
03077 if (rect.left >= rect.right || rect.top >= rect.bottom)
03078 {
03079 EnableScrollBarCtrl(SB_BOTH, FALSE);
03080 return;
03081 }
03082
03083 CRect VisibleRect(GetFixedColumnWidth(), GetFixedRowHeight(),
03084 rect.right, rect.bottom);
03085 CRect VirtualRect(GetFixedColumnWidth(), GetFixedRowHeight(),
03086 GetVirtualWidth(), GetVirtualHeight());
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098 if (VisibleRect.Height() < VirtualRect.Height())
03099 VisibleRect.right -= ::GetSystemMetrics(SM_CXVSCROLL);
03100
03101 if (VisibleRect.Width() < VirtualRect.Width())
03102 VisibleRect.bottom -= ::GetSystemMetrics(SM_CYHSCROLL);
03103
03104
03105
03106
03107
03108 if (VisibleRect.Height() < VirtualRect.Height())
03109 {
03110 EnableScrollBars(SB_VERT, TRUE);
03111 m_nVScrollMax = VirtualRect.Height() - 1;
03112 }
03113 else
03114 {
03115 EnableScrollBars(SB_VERT, FALSE);
03116 m_nVScrollMax = 0;
03117 }
03118
03119 if (VisibleRect.Width() < VirtualRect.Width())
03120 {
03121 EnableScrollBars(SB_HORZ, TRUE);
03122 m_nHScrollMax = VirtualRect.Width() - 1;
03123 }
03124 else
03125 {
03126 EnableScrollBars(SB_HORZ, FALSE);
03127 m_nHScrollMax = 0;
03128 }
03129
03130 ASSERT(m_nVScrollMax < INT_MAX && m_nHScrollMax < INT_MAX);
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146 SCROLLINFO si;
03147 si.cbSize = sizeof(SCROLLINFO);
03148 si.fMask = SIF_PAGE | SIF_RANGE;
03149 si.nPage = (m_nHScrollMax>0)? VisibleRect.Width() : 0;
03150 si.nMin = 0;
03151 si.nMax = m_nHScrollMax;
03152 SetScrollInfo(SB_HORZ, &si, TRUE);
03153
03154 si.fMask |= SIF_DISABLENOSCROLL;
03155 si.nPage = (m_nVScrollMax>0)? VisibleRect.Height() : 0;
03156 si.nMin = 0;
03157 si.nMax = m_nVScrollMax;
03158 SetScrollInfo(SB_VERT, &si, TRUE);
03159 }
03160
03162
03163
03164
03165 BOOL CGridCtrl::GetCellOrigin(int nRow, int nCol, LPPOINT p)
03166 {
03167 int i;
03168
03169 if (!IsValid(nRow, nCol))
03170 return FALSE;
03171
03172 CCellID idTopLeft;
03173 if (nCol >= m_nFixedCols || nRow >= m_nFixedRows)
03174 idTopLeft = GetTopleftNonFixedCell();
03175
03176 if ((nRow >= m_nFixedRows && nRow < idTopLeft.row) ||
03177 (nCol>= m_nFixedCols && nCol < idTopLeft.col))
03178 return FALSE;
03179
03180 p->x = 0;
03181 if (nCol < m_nFixedCols)
03182 for (i = 0; i < nCol; i++)
03183 p->x += GetColumnWidth(i);
03184 else
03185 {
03186 for (i = 0; i < m_nFixedCols; i++)
03187 p->x += GetColumnWidth(i);
03188 for (i = idTopLeft.col; i < nCol; i++)
03189 p->x += GetColumnWidth(i);
03190 }
03191
03192 p->y = 0;
03193 if (nRow < m_nFixedRows)
03194 for (i = 0; i < nRow; i++)
03195 p->y += GetRowHeight(i);
03196 else
03197 {
03198 for (i = 0; i < m_nFixedRows; i++)
03199 p->y += GetRowHeight(i);
03200 for (i = idTopLeft.row; i < nRow; i++)
03201 p->y += GetRowHeight(i);
03202 }
03203
03204 return TRUE;
03205 }
03206
03207 BOOL CGridCtrl::GetCellOrigin(const CCellID& cell, LPPOINT p)
03208 {
03209 return GetCellOrigin(cell.row, cell.col, p);
03210 }
03211
03212
03213 BOOL CGridCtrl::GetCellRect(const CCellID& cell, LPRECT pRect)
03214 {
03215 return GetCellRect(cell.row, cell.col, pRect);
03216 }
03217
03218 BOOL CGridCtrl::GetCellRect(int nRow, int nCol, LPRECT pRect)
03219 {
03220 CPoint CellOrigin;
03221 if (!GetCellOrigin(nRow, nCol, &CellOrigin))
03222 return FALSE;
03223
03224 pRect->left = CellOrigin.x;
03225 pRect->top = CellOrigin.y;
03226 pRect->right = CellOrigin.x + GetColumnWidth(nCol)-1;
03227 pRect->bottom = CellOrigin.y + GetRowHeight(nRow)-1;
03228
03229
03230
03231
03232
03233 return TRUE;
03234 }
03235
03236 BOOL CGridCtrl::GetTextRect(const CCellID& cell, LPRECT pRect)
03237 {
03238 return GetTextRect(cell.row, cell.col, pRect);
03239 }
03240
03241 BOOL CGridCtrl::GetTextRect(int nRow, int nCol, LPRECT pRect)
03242 {
03243 CGridCellBase* pCell = GetCell( nRow, nCol);
03244 if( pCell == NULL)
03245 return FALSE;
03246
03247 if( !GetCellRect( nRow, nCol, pRect) )
03248 return FALSE;
03249
03250 return pCell->GetTextRect( pRect);
03251 }
03252
03253
03254 BOOL CGridCtrl::GetCellRangeRect(const CCellRange& cellRange, LPRECT lpRect)
03255 {
03256 CPoint MinOrigin,MaxOrigin;
03257
03258 if (!GetCellOrigin(cellRange.GetMinRow(), cellRange.GetMinCol(), &MinOrigin))
03259 return FALSE;
03260 if (!GetCellOrigin(cellRange.GetMaxRow(), cellRange.GetMaxCol(), &MaxOrigin))
03261 return FALSE;
03262
03263 lpRect->left = MinOrigin.x;
03264 lpRect->top = MinOrigin.y;
03265 lpRect->right = MaxOrigin.x + GetColumnWidth(cellRange.GetMaxCol()) - 1;
03266 lpRect->bottom = MaxOrigin.y + GetRowHeight(cellRange.GetMaxRow()) - 1;
03267
03268 return TRUE;
03269 }
03270
03272
03273
03274 LRESULT CGridCtrl::OnSetFont(WPARAM hFont, LPARAM )
03275 {
03276 LRESULT result = Default();
03277
03278
03279 LOGFONT lf;
03280 if (!GetObject((HFONT) hFont, sizeof(LOGFONT), &lf))
03281 return result;
03282
03283 m_cellDefault.SetFont(&lf);
03284 m_cellFixedColDef.SetFont(&lf);
03285 m_cellFixedRowDef.SetFont(&lf);
03286 m_cellFixedRowColDef.SetFont(&lf);
03287
03288 Refresh();
03289
03290 return result;
03291 }
03292
03293 LRESULT CGridCtrl::OnGetFont(WPARAM , LPARAM )
03294 {
03295
03296
03297
03298 return (LRESULT) m_cellDefault.GetFontObject()->GetSafeHandle();
03299 }
03300
03301 #ifndef _WIN32_WCE_NO_CURSOR
03302 BOOL CGridCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
03303 {
03304 if (nHitTest == HTCLIENT)
03305 {
03306 switch (m_MouseMode)
03307 {
03308 case MOUSE_OVER_COL_DIVIDE:
03309 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
03310 break;
03311 case MOUSE_OVER_ROW_DIVIDE:
03312 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
03313 break;
03314 #ifndef GRIDCONTROL_NO_DRAGDROP
03315 case MOUSE_DRAGGING:
03316 break;
03317 #endif
03318 default:
03319 if (!GetVirtualMode())
03320 {
03321 CPoint pt(GetMessagePos());
03322 ScreenToClient(&pt);
03323 CCellID cell = GetCellFromPt(pt);
03324 if (IsValid(cell))
03325 {
03326 CGridCellBase* pCell = GetCell(cell.row, cell.col);
03327 if (pCell)
03328 return pCell->OnSetCursor();
03329 }
03330 }
03331
03332 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
03333 }
03334 return TRUE;
03335 }
03336
03337 return CWnd::OnSetCursor(pWnd, nHitTest, message);
03338 }
03339 #endif
03340
03342
03343
03344 BOOL CGridCtrl::SetFixedRowCount(int nFixedRows)
03345 {
03346 if (m_nFixedRows == nFixedRows)
03347 return TRUE;
03348
03349 ASSERT(nFixedRows >= 0);
03350
03351 ResetSelectedRange();
03352
03353
03354 m_idTopLeftCell.col = -1;
03355
03356 if (nFixedRows > GetRowCount())
03357 if (!SetRowCount(nFixedRows))
03358 return FALSE;
03359
03360 if (m_idCurrentCell.row < nFixedRows)
03361 SetFocusCell(-1, - 1);
03362
03363 if (!GetVirtualMode())
03364 {
03365 if (nFixedRows > m_nFixedRows)
03366 {
03367 for (int i = m_nFixedRows; i < nFixedRows; i++)
03368 for (int j = 0; j < GetColumnCount(); j++)
03369 {
03370 SetItemState(i, j, GetItemState(i, j) | GVIS_FIXED | GVIS_FIXEDROW);
03371 SetItemBkColour(i, j, CLR_DEFAULT );
03372 SetItemFgColour(i, j, CLR_DEFAULT );
03373 }
03374 }
03375 else
03376 {
03377 for (int i = nFixedRows; i < m_nFixedRows; i++)
03378 {
03379 int j;
03380 for (j = 0; j < GetFixedColumnCount(); j++)
03381 SetItemState(i, j, GetItemState(i, j) & ~GVIS_FIXEDROW );
03382
03383 for (j = GetFixedColumnCount(); j < GetColumnCount(); j++)
03384 {
03385 SetItemState(i, j, GetItemState(i, j) & ~(GVIS_FIXED | GVIS_FIXEDROW) );
03386 SetItemBkColour(i, j, CLR_DEFAULT );
03387 SetItemFgColour(i, j, CLR_DEFAULT );
03388 }
03389 }
03390 }
03391 }
03392
03393 m_nFixedRows = nFixedRows;
03394
03395 Refresh();
03396
03397 return TRUE;
03398 }
03399
03400 BOOL CGridCtrl::SetFixedColumnCount(int nFixedCols)
03401 {
03402 if (m_nFixedCols == nFixedCols)
03403 return TRUE;
03404
03405 ASSERT(nFixedCols >= 0);
03406
03407 if (nFixedCols > GetColumnCount())
03408 if (!SetColumnCount(nFixedCols))
03409 return FALSE;
03410
03411 if (m_idCurrentCell.col < nFixedCols)
03412 SetFocusCell(-1, - 1);
03413
03414 ResetSelectedRange();
03415
03416
03417 m_idTopLeftCell.col = -1;
03418
03419 if (!GetVirtualMode())
03420 {
03421 if (nFixedCols > m_nFixedCols)
03422 {
03423 for (int i = 0; i < GetRowCount(); i++)
03424 for (int j = m_nFixedCols; j < nFixedCols; j++)
03425 {
03426 SetItemState(i, j, GetItemState(i, j) | GVIS_FIXED | GVIS_FIXEDCOL);
03427 SetItemBkColour(i, j, CLR_DEFAULT );
03428 SetItemFgColour(i, j, CLR_DEFAULT );
03429 }
03430 }
03431 else
03432 {
03433 {
03434 for (int i = 0; i < GetFixedRowCount(); i++)
03435 for (int j = nFixedCols; j < m_nFixedCols; j++)
03436 SetItemState(i, j, GetItemState(i, j) & ~GVIS_FIXEDCOL );
03437 }
03438 {
03439 for (int i = GetFixedRowCount(); i < GetRowCount(); i++)
03440 for (int j = nFixedCols; j < m_nFixedCols; j++)
03441 {
03442 SetItemState(i, j, GetItemState(i, j) & ~(GVIS_FIXED | GVIS_FIXEDCOL) );
03443 SetItemBkColour(i, j, CLR_DEFAULT );
03444 SetItemFgColour(i, j, CLR_DEFAULT );
03445 }
03446 }
03447 }
03448 }
03449
03450 m_nFixedCols = nFixedCols;
03451
03452 Refresh();
03453
03454 return TRUE;
03455 }
03456
03457 BOOL CGridCtrl::SetRowCount(int nRows)
03458 {
03459 BOOL bResult = TRUE;
03460
03461 ASSERT(nRows >= 0);
03462 if (nRows == GetRowCount())
03463 return bResult;
03464
03465
03466 m_idTopLeftCell.col = -1;
03467
03468 if (nRows < m_nFixedRows)
03469 m_nFixedRows = nRows;
03470
03471 if (m_idCurrentCell.row >= nRows)
03472 SetFocusCell(-1, - 1);
03473
03474 int addedRows = nRows - GetRowCount();
03475
03476
03477
03478 if (addedRows < 0)
03479 {
03480 if (!GetVirtualMode())
03481 {
03482 for (int row = nRows; row < m_nRows; row++)
03483 {
03484
03485 for (int col = 0; col < m_nCols; col++)
03486 DestroyCell(row, col);
03487
03488
03489 GRID_ROW* pRow = m_RowData[row];
03490 if (pRow)
03491 delete pRow;
03492 }
03493 }
03494 m_nRows = nRows;
03495 }
03496
03497 TRY
03498 {
03499 m_arRowHeights.SetSize(nRows);
03500
03501 if (GetVirtualMode())
03502 {
03503 m_nRows = nRows;
03504 if (addedRows > 0)
03505 {
03506 int startRow = nRows - addedRows;
03507 for (int row = startRow; row < nRows; row++)
03508 m_arRowHeights[row] = m_cellDefault.GetHeight();
03509 }
03510 }
03511 else
03512 {
03513
03514 m_RowData.SetSize(nRows);
03515
03516
03517
03518 if (addedRows > 0)
03519 {
03520
03521 int startRow = nRows - addedRows;
03522 for (int row = startRow; row < nRows; row++)
03523 {
03524 m_arRowHeights[row] = m_cellDefault.GetHeight();
03525
03526 m_RowData[row] = new GRID_ROW;
03527 m_RowData[row]->SetSize(m_nCols);
03528 for (int col = 0; col < m_nCols; col++)
03529 {
03530 GRID_ROW* pRow = m_RowData[row];
03531 if (pRow && !GetVirtualMode())
03532 pRow->SetAt(col, CreateCell(row, col));
03533 }
03534 m_nRows++;
03535 }
03536 }
03537 }
03538 }
03539 CATCH (CMemoryException, e)
03540 {
03541 e->ReportError();
03542 bResult = FALSE;
03543 }
03544 END_CATCH
03545
03546 SetModified();
03547 ResetScrollBars();
03548 Refresh();
03549
03550 return bResult;
03551 }
03552
03553 BOOL CGridCtrl::SetColumnCount(int nCols)
03554 {
03555 BOOL bResult = TRUE;
03556
03557 ASSERT(nCols >= 0);
03558
03559 if (nCols == GetColumnCount())
03560 return bResult;
03561
03562
03563 m_idTopLeftCell.col = -1;
03564
03565 if (nCols < m_nFixedCols)
03566 m_nFixedCols = nCols;
03567
03568 if (m_idCurrentCell.col >= nCols)
03569 SetFocusCell(-1, - 1);
03570
03571 int addedCols = nCols - GetColumnCount();
03572
03573
03574
03575 if (addedCols < 0 && !GetVirtualMode())
03576 {
03577 for (int row = 0; row < m_nRows; row++)
03578 for (int col = nCols; col < GetColumnCount(); col++)
03579 DestroyCell(row, col);
03580 }
03581
03582 TRY
03583 {
03584
03585 m_arColWidths.SetSize(nCols);
03586
03587
03588 if (!GetVirtualMode())
03589 for (int i = 0; i < m_nRows; i++)
03590 if (m_RowData[i])
03591 m_RowData[i]->SetSize(nCols);
03592
03593
03594
03595 if (addedCols > 0)
03596 {
03597
03598 int startCol = nCols - addedCols;
03599 int col;
03600 for (col = startCol; col < nCols; col++)
03601 m_arColWidths[col] = m_cellFixedColDef.GetWidth();
03602
03603
03604 if (!GetVirtualMode())
03605 {
03606 for (int row = 0; row < m_nRows; row++)
03607 for (col = startCol; col < nCols; col++)
03608 {
03609 GRID_ROW* pRow = m_RowData[row];
03610 if (pRow)
03611 pRow->SetAt(col, CreateCell(row, col));
03612 }
03613 }
03614 }
03615
03616
03617 }
03618 CATCH (CMemoryException, e)
03619 {
03620 e->ReportError();
03621 bResult = FALSE;
03622 }
03623 END_CATCH
03624
03625 m_nCols = nCols;
03626
03627 SetModified();
03628 ResetScrollBars();
03629 Refresh();
03630
03631 return bResult;
03632 }
03633
03634
03635 int CGridCtrl::InsertColumn(LPCTSTR strHeading,
03636 UINT nFormat ,
03637 int nColumn )
03638 {
03639 if (nColumn >= 0 && nColumn < m_nFixedCols)
03640 {
03641
03642
03643 ASSERT(FALSE);
03644 return -1;
03645 }
03646
03647
03648 if (nColumn >= 0 && nColumn > GetColumnCount())
03649 return -1;
03650
03651
03652 m_idTopLeftCell.col = -1;
03653
03654 ResetSelectedRange();
03655
03656
03657 if (m_nRows < 1)
03658 SetRowCount(1);
03659
03660
03661
03662
03663 if (nColumn == GetColumnCount())
03664 nColumn = -1;
03665
03666 TRY
03667 {
03668 if (nColumn < 0)
03669 {
03670 nColumn = m_nCols;
03671 m_arColWidths.Add(0);
03672 if (!GetVirtualMode())
03673 {
03674 for (int row = 0; row < m_nRows; row++)
03675 {
03676 GRID_ROW* pRow = m_RowData[row];
03677 if (!pRow)
03678 return -1;
03679 pRow->Add(CreateCell(row, nColumn));
03680 }
03681 }
03682 }
03683 else
03684 {
03685 m_arColWidths.InsertAt(nColumn, (UINT)0);
03686 if (!GetVirtualMode())
03687 {
03688 for (int row = 0; row < m_nRows; row++)
03689 {
03690 GRID_ROW* pRow = m_RowData[row];
03691 if (!pRow)
03692 return -1;
03693 pRow->InsertAt(nColumn, CreateCell(row, nColumn));
03694 }
03695 }
03696 }
03697 }
03698 CATCH (CMemoryException, e)
03699 {
03700 e->ReportError();
03701 return FALSE;
03702 }
03703 END_CATCH
03704
03705 m_nCols++;
03706
03707
03708 SetItemText(0, nColumn, strHeading);
03709 for (int row = 0; row < m_nRows; row++)
03710 SetItemFormat(row, nColumn, nFormat);
03711
03712
03713 m_arColWidths[nColumn] = GetTextExtent(0, nColumn, strHeading).cx;
03714
03715 if (m_idCurrentCell.col != -1 && nColumn < m_idCurrentCell.col)
03716 m_idCurrentCell.col++;
03717
03718 ResetScrollBars();
03719
03720 SetModified();
03721
03722 return nColumn;
03723 }
03724
03725
03726 int CGridCtrl::InsertRow(LPCTSTR strHeading, int nRow )
03727 {
03728 if (nRow >= 0 && nRow < m_nFixedRows)
03729 {
03730
03731 ASSERT(FALSE);
03732 return -1;
03733 }
03734
03735
03736 if (nRow >= 0 && nRow >= GetRowCount())
03737 return -1;
03738
03739
03740 m_idTopLeftCell.col = -1;
03741
03742 ResetSelectedRange();
03743
03744
03745 if (m_nCols < 1)
03746 SetColumnCount(1);
03747
03748 TRY
03749 {
03750
03751 if (nRow < 0)
03752 {
03753 nRow = m_nRows;
03754 m_arRowHeights.Add(0);
03755 if (!GetVirtualMode())
03756 m_RowData.Add(new GRID_ROW);
03757 }
03758 else
03759 {
03760 m_arRowHeights.InsertAt(nRow, (UINT)0);
03761 if (!GetVirtualMode())
03762 m_RowData.InsertAt(nRow, new GRID_ROW);
03763 }
03764
03765 if (!GetVirtualMode())
03766 m_RowData[nRow]->SetSize(m_nCols);
03767 }
03768 CATCH (CMemoryException, e)
03769 {
03770 e->ReportError();
03771 return FALSE;
03772 }
03773 END_CATCH
03774
03775 m_nRows++;
03776
03777
03778 if (!GetVirtualMode())
03779 {
03780 for (int col = 0; col < m_nCols; col++)
03781 {
03782 GRID_ROW* pRow = m_RowData[nRow];
03783 if (!pRow)
03784 return -1;
03785 pRow->SetAt(col, CreateCell(nRow, col));
03786 }
03787 }
03788
03789
03790 SetItemText(nRow, 0, strHeading);
03791
03792
03793 if (strHeading && strHeading[0])
03794 m_arRowHeights[nRow] = GetTextExtent(nRow, 0, strHeading).cy;
03795 else
03796 m_arRowHeights[nRow] = m_cellFixedRowDef.GetHeight();
03797
03798 if (m_idCurrentCell.row != -1 && nRow < m_idCurrentCell.row)
03799 m_idCurrentCell.row++;
03800
03801 ResetScrollBars();
03802
03803 SetModified();
03804
03805 return nRow;
03806 }
03807
03809
03810
03811 BOOL CGridCtrl::SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass)
03812 {
03813 if (GetVirtualMode())
03814 return FALSE;
03815
03816 ASSERT(IsValid(nRow, nCol));
03817 if (!IsValid(nRow, nCol))
03818 return FALSE;
03819
03820 if (!pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(CGridCellBase)))
03821 {
03822 ASSERT( FALSE);
03823 return FALSE;
03824 }
03825
03826 CGridCellBase* pNewCell = (CGridCellBase*) pRuntimeClass->CreateObject();
03827
03828 CGridCellBase* pCurrCell = GetCell(nRow, nCol);
03829 if (pCurrCell)
03830 *pNewCell = *pCurrCell;
03831
03832 SetCell(nRow, nCol, pNewCell);
03833 delete pCurrCell;
03834
03835 return TRUE;
03836 }
03837
03838 BOOL CGridCtrl::SetDefaultCellType( CRuntimeClass* pRuntimeClass)
03839 {
03840 ASSERT( pRuntimeClass != NULL );
03841 if (!pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(CGridCellBase)))
03842 {
03843 ASSERT( FALSE);
03844 return FALSE;
03845 }
03846 m_pRtcDefault = pRuntimeClass;
03847 return TRUE;
03848 }
03849
03850
03851 CGridCellBase* CGridCtrl::CreateCell(int nRow, int nCol)
03852 {
03853 ASSERT(!GetVirtualMode());
03854
03855 if (!m_pRtcDefault || !m_pRtcDefault->IsDerivedFrom(RUNTIME_CLASS(CGridCellBase)))
03856 {
03857 ASSERT( FALSE);
03858 return NULL;
03859 }
03860 CGridCellBase* pCell = (CGridCellBase*) m_pRtcDefault->CreateObject();
03861 if (!pCell)
03862 return NULL;
03863
03864 pCell->SetGrid(this);
03865 pCell->SetCoords(nRow, nCol);
03866
03867 if (nCol < m_nFixedCols)
03868 pCell->SetState(pCell->GetState() | GVIS_FIXED | GVIS_FIXEDCOL);
03869 if (nRow < m_nFixedRows)
03870 pCell->SetState(pCell->GetState() | GVIS_FIXED | GVIS_FIXEDROW);
03871
03872 pCell->SetFormat(pCell->GetDefaultCell()->GetFormat());
03873
03874 return pCell;
03875 }
03876
03877
03878 void CGridCtrl::DestroyCell(int nRow, int nCol)
03879 {
03880
03881 ASSERT(!GetVirtualMode());
03882
03883
03884
03885 SetItemState(nRow, nCol, 0);
03886
03887 delete GetCell(nRow, nCol);
03888 }
03889
03890 BOOL CGridCtrl::DeleteColumn(int nColumn)
03891 {
03892 if (nColumn < 0 || nColumn >= GetColumnCount())
03893 return FALSE;
03894
03895 ResetSelectedRange();
03896
03897 if (!GetVirtualMode())
03898 {
03899 for (int row = 0; row < GetRowCount(); row++)
03900 {
03901 GRID_ROW* pRow = m_RowData[row];
03902 if (!pRow)
03903 return FALSE;
03904
03905 DestroyCell(row, nColumn);
03906
03907 pRow->RemoveAt(nColumn);
03908 }
03909 }
03910 m_arColWidths.RemoveAt(nColumn);
03911 m_nCols--;
03912 if (nColumn < m_nFixedCols)
03913 m_nFixedCols--;
03914
03915 if (nColumn == m_idCurrentCell.col)
03916 m_idCurrentCell.row = m_idCurrentCell.col = -1;
03917 else if (nColumn < m_idCurrentCell.col)
03918 m_idCurrentCell.col--;
03919
03920 ResetScrollBars();
03921
03922 SetModified();
03923
03924 return TRUE;
03925 }
03926
03927 BOOL CGridCtrl::DeleteRow(int nRow)
03928 {
03929 if (nRow < 0 || nRow >= GetRowCount())
03930 return FALSE;
03931
03932 ResetSelectedRange();
03933
03934 if (!GetVirtualMode())
03935 {
03936 GRID_ROW* pRow = m_RowData[nRow];
03937 if (!pRow)
03938 return FALSE;
03939
03940 for (int col = 0; col < GetColumnCount(); col++)
03941 DestroyCell(nRow, col);
03942
03943 delete pRow;
03944 m_RowData.RemoveAt(nRow);
03945 }
03946
03947 m_arRowHeights.RemoveAt(nRow);
03948
03949 m_nRows--;
03950 if (nRow < m_nFixedRows)
03951 m_nFixedRows--;
03952
03953 if (nRow == m_idCurrentCell.row)
03954 m_idCurrentCell.row = m_idCurrentCell.col = -1;
03955 else if (nRow < m_idCurrentCell.row)
03956 m_idCurrentCell.row--;
03957
03958 ResetScrollBars();
03959
03960 SetModified();
03961
03962 return TRUE;
03963 }
03964
03965
03966 BOOL CGridCtrl::DeleteNonFixedRows()
03967 {
03968 ResetSelectedRange();
03969
03970 int nFixed = GetFixedRowCount();
03971 int nCount = GetRowCount();
03972
03973
03974 for (int nRow = nCount; nRow >= nFixed; nRow--)
03975 DeleteRow(nRow);
03976
03977 return TRUE;
03978 }
03979
03980
03981 BOOL CGridCtrl::DeleteAllItems()
03982 {
03983 ResetSelectedRange();
03984
03985 m_arColWidths.RemoveAll();
03986 m_arRowHeights.RemoveAll();
03987
03988
03989 if (!GetVirtualMode())
03990 {
03991 for (int row = 0; row < m_nRows; row++)
03992 {
03993 for (int col = 0; col < m_nCols; col++)
03994 DestroyCell(row, col);
03995
03996 GRID_ROW* pRow = m_RowData[row];
03997 delete pRow;
03998 }
03999
04000
04001 m_RowData.RemoveAll();
04002 }
04003
04004 m_idCurrentCell.row = m_idCurrentCell.col = -1;
04005 m_nRows = m_nFixedRows = m_nCols = m_nFixedCols = 0;
04006
04007 ResetScrollBars();
04008
04009 SetModified();
04010
04011 return TRUE;
04012 }
04013
04014 void CGridCtrl::AutoFill()
04015 {
04016 if (!::IsWindow(m_hWnd))
04017 return;
04018
04019 CRect rect;
04020 GetClientRect(rect);
04021
04022 SetColumnCount(rect.Width() / m_cellDefault.GetWidth() + 1);
04023 SetRowCount(rect.Height() / m_cellDefault.GetHeight() + 1);
04024 SetFixedRowCount(1);
04025 SetFixedColumnCount(1);
04026 ExpandToFit();
04027 }
04028
04030
04031
04032
04033 CCellID CGridCtrl::GetNextItem(CCellID& cell, int nFlags) const
04034 {
04035 if ((nFlags & GVNI_ALL) == GVNI_ALL)
04036 {
04037
04038
04039 int row = cell.row , col = cell.col + 1;
04040 if (row <= 0)
04041 row = GetFixedRowCount();
04042 for (; row < GetRowCount(); row++)
04043 {
04044 if (col <= 0)
04045 col = GetFixedColumnCount();
04046 for (; col < GetColumnCount(); col++)
04047 {
04048 int nState = GetItemState(row, col);
04049 if ((nFlags & GVNI_DROPHILITED && nState & GVIS_DROPHILITED) ||
04050 (nFlags & GVNI_FOCUSED && nState & GVIS_FOCUSED) ||
04051 (nFlags & GVNI_SELECTED && nState & GVIS_SELECTED) ||
04052 (nFlags & GVNI_READONLY && nState & GVIS_READONLY) ||
04053 (nFlags & GVNI_FIXED && nState & GVIS_FIXED) ||
04054 (nFlags & GVNI_MODIFIED && nState & GVIS_MODIFIED))
04055 return CCellID(row, col);
04056 }
04057
04058 col = GetFixedColumnCount();
04059 }
04060 }
04061 else if ((nFlags & GVNI_BELOW) == GVNI_BELOW &&
04062 (nFlags & GVNI_TORIGHT) == GVNI_TORIGHT)
04063 {
04064
04065
04066 int row = cell.row;
04067 if (row <= 0)
04068 row = GetFixedRowCount();
04069 for (; row < GetRowCount(); row++)
04070 {
04071 int col = cell.col + 1;
04072 if (col <= 0)
04073 col = GetFixedColumnCount();
04074 for (; col < GetColumnCount(); col++)
04075 {
04076 int nState = GetItemState(row, col);
04077 if ((nFlags & GVNI_DROPHILITED && nState & GVIS_DROPHILITED) ||
04078 (nFlags & GVNI_FOCUSED && nState & GVIS_FOCUSED) ||
04079 (nFlags & GVNI_SELECTED && nState & GVIS_SELECTED) ||
04080 (nFlags & GVNI_READONLY && nState & GVIS_READONLY) ||
04081 (nFlags & GVNI_FIXED && nState & GVIS_FIXED) ||
04082 (nFlags & GVNI_MODIFIED && nState & GVIS_MODIFIED))
04083 return CCellID(row, col);
04084 }
04085 }
04086 }
04087 else if ((nFlags & GVNI_ABOVE) == GVNI_ABOVE)
04088 {
04089 for (int row = cell.row - 1; row >= GetFixedRowCount(); row--)
04090 {
04091 int nState = GetItemState(row, cell.col);
04092 if ((nFlags & GVNI_DROPHILITED && nState & GVIS_DROPHILITED) ||
04093 (nFlags & GVNI_FOCUSED && nState & GVIS_FOCUSED) ||
04094 (nFlags & GVNI_SELECTED && nState & GVIS_SELECTED) ||
04095 (nFlags & GVNI_READONLY && nState & GVIS_READONLY) ||
04096 (nFlags & GVNI_FIXED && nState & GVIS_FIXED) ||
04097 (nFlags & GVNI_MODIFIED && nState & GVIS_MODIFIED))
04098 return CCellID(row, cell.col);
04099 }
04100 }
04101 else if ((nFlags & GVNI_BELOW) == GVNI_BELOW)
04102 {
04103 for (int row = cell.row + 1; row < GetRowCount(); row++)
04104 {
04105 int nState = GetItemState(row, cell.col);
04106 if ((nFlags & GVNI_DROPHILITED && nState & GVIS_DROPHILITED) ||
04107 (nFlags & GVNI_FOCUSED && nState & GVIS_FOCUSED) ||
04108 (nFlags & GVNI_SELECTED && nState & GVIS_SELECTED) ||
04109 (nFlags & GVNI_READONLY && nState & GVIS_READONLY) ||
04110 (nFlags & GVNI_FIXED && nState & GVIS_FIXED) ||
04111 (nFlags & GVNI_MODIFIED && nState & GVIS_MODIFIED))
04112 return CCellID(row, cell.col);
04113 }
04114 }
04115 else if ((nFlags & GVNI_TOLEFT) == GVNI_TOLEFT)
04116 {
04117 for (int col = cell.col - 1; col >= GetFixedColumnCount(); col--)
04118 {
04119 int nState = GetItemState(cell.row, col);
04120 if ((nFlags & GVNI_DROPHILITED && nState & GVIS_DROPHILITED) ||
04121 (nFlags & GVNI_FOCUSED && nState & GVIS_FOCUSED) ||
04122 (nFlags & GVNI_SELECTED && nState & GVIS_SELECTED) ||
04123 (nFlags & GVNI_READONLY && nState & GVIS_READONLY) ||
04124 (nFlags & GVNI_FIXED && nState & GVIS_FIXED) ||
04125 (nFlags & GVNI_MODIFIED && nState & GVIS_MODIFIED))
04126 return CCellID(cell.row, col);
04127 }
04128 }
04129 else if ((nFlags & GVNI_TORIGHT) == GVNI_TORIGHT)
04130 {
04131 for (int col = cell.col + 1; col < GetColumnCount(); col++)
04132 {
04133 int nState = GetItemState(cell.row, col);
04134 if ((nFlags & GVNI_DROPHILITED && nState & GVIS_DROPHILITED) ||
04135 (nFlags & GVNI_FOCUSED && nState & GVIS_FOCUSED) ||
04136 (nFlags & GVNI_SELECTED && nState & GVIS_SELECTED) ||
04137 (nFlags & GVNI_READONLY && nState & GVIS_READONLY) ||
04138 (nFlags & GVNI_FIXED && nState & GVIS_FIXED) ||
04139 (nFlags & GVNI_MODIFIED && nState & GVIS_MODIFIED))
04140 return CCellID(cell.row, col);
04141 }
04142 }
04143
04144 return CCellID(-1, -1);
04145 }
04146
04147
04148 BOOL CGridCtrl::SortTextItems(int nCol, BOOL bAscending, LPARAM data )
04149 {
04150 SetSortColumn(nCol);
04151 SetSortAscending(bAscending);
04152 ResetSelectedRange();
04153 SetFocusCell(-1, - 1);
04154 return CGridCtrl::SortItems(pfnCellTextCompare, nCol, bAscending, data);
04155 }
04156
04157 void CGridCtrl::SetCompareFunction(PFNLVCOMPARE pfnCompare)
04158 {
04159 m_pfnCompare = pfnCompare;
04160 }
04161
04162
04163
04164 BOOL CGridCtrl::SortItems(int nCol, BOOL bAscending, LPARAM data )
04165 {
04166 SetSortColumn(nCol);
04167 SetSortAscending(bAscending);
04168 ResetSelectedRange();
04169 SetFocusCell(-1, - 1);
04170
04171 if (m_pfnCompare == NULL)
04172 return CGridCtrl::SortItems(pfnCellTextCompare, nCol, bAscending, data);
04173 else
04174 return CGridCtrl::SortItems(m_pfnCompare, nCol, bAscending, data);
04175 }
04176
04177
04178 BOOL CGridCtrl::SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending,
04179 LPARAM data )
04180 {
04181 SetSortColumn(nCol);
04182 SetSortAscending(bAscending);
04183 ResetSelectedRange();
04184 SetFocusCell(-1, -1);
04185 return SortItems(pfnCompare, nCol, bAscending, data, GetFixedRowCount(), -1);
04186 }
04187
04188 int CALLBACK CGridCtrl::pfnCellTextCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
04189 {
04190 UNUSED_ALWAYS(lParamSort);
04191
04192 CGridCellBase* pCell1 = (CGridCellBase*) lParam1;
04193 CGridCellBase* pCell2 = (CGridCellBase*) lParam2;
04194 if (!pCell1 || !pCell2) return 0;
04195
04196 return _tcscmp(pCell1->GetText(), pCell2->GetText());
04197 }
04198
04199 int CALLBACK CGridCtrl::pfnCellNumericCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
04200 {
04201 UNUSED_ALWAYS(lParamSort);
04202
04203 CGridCellBase* pCell1 = (CGridCellBase*) lParam1;
04204 CGridCellBase* pCell2 = (CGridCellBase*) lParam2;
04205 if (!pCell1 || !pCell2) return 0;
04206
04207 int nValue1 = _ttol(pCell1->GetText());
04208 int nValue2 = _ttol(pCell2->GetText());
04209
04210 if (nValue1 < nValue2)
04211 return -1;
04212 else if (nValue1 == nValue2)
04213 return 0;
04214 else
04215 return 1;
04216 }
04217
04218
04219 BOOL CGridCtrl::SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data,
04220 int low, int high)
04221 {
04222 if (nCol >= GetColumnCount())
04223 return FALSE;
04224
04225 if (high == -1)
04226 high = GetRowCount() - 1;
04227
04228 int lo = low;
04229 int hi = high;
04230
04231 if (hi <= lo)
04232 return FALSE;
04233
04234
04235 LPARAM pMidCell = (LPARAM) GetCell((lo + hi)/2, nCol);
04236
04237
04238 while (lo <= hi)
04239 {
04240
04241
04242 if (bAscending)
04243 while (lo < high && pfnCompare( (LPARAM)GetCell(lo, nCol), (LPARAM) pMidCell, data) < 0)
04244 ++lo;
04245 else
04246 while (lo < high && pfnCompare((LPARAM)GetCell(lo, nCol), pMidCell, data) > 0)
04247 ++lo;
04248
04249
04250
04251 if (bAscending)
04252 while (hi > low && pfnCompare((LPARAM)GetCell(hi, nCol), pMidCell, data) > 0)
04253 --hi;
04254 else
04255 while (hi > low && pfnCompare((LPARAM)GetCell(hi, nCol), pMidCell, data) < 0)
04256 --hi;
04257
04258
04259 if (lo <= hi)
04260 {
04261
04262 if (pfnCompare((LPARAM)GetCell(lo, nCol), (LPARAM)GetCell(hi, nCol), data) != 0)
04263 {
04264 for (int col = 0; col < GetColumnCount(); col++)
04265 {
04266 CGridCellBase *pCell = GetCell(lo, col);
04267 SetCell(lo, col, GetCell(hi, col));
04268 SetCell(hi, col, pCell);
04269 }
04270 UINT nRowHeight = m_arRowHeights[lo];
04271 m_arRowHeights[lo] = m_arRowHeights[hi];
04272 m_arRowHeights[hi] = nRowHeight;
04273 }
04274
04275 ++lo;
04276 --hi;
04277 }
04278 }
04279
04280
04281
04282 if (low < hi)
04283 SortItems(pfnCompare, nCol, bAscending, data, low, hi);
04284
04285
04286
04287 if (lo < high)
04288 SortItems(pfnCompare, nCol, bAscending, data, lo, high);
04289
04290 return TRUE;
04291 }
04292
04294
04295
04296 BOOL CGridCtrl::SetItem(const GV_ITEM* pItem)
04297 {
04298 if (!pItem || GetVirtualMode())
04299 return FALSE;
04300
04301 CGridCellBase* pCell = GetCell(pItem->row, pItem->col);
04302 if (!pCell)
04303 return FALSE;
04304
04305 SetModified(TRUE, pItem->row, pItem->col);
04306
04307 if (pItem->mask & GVIF_TEXT)
04308 pCell->SetText(pItem->strText);
04309 if (pItem->mask & GVIF_PARAM)
04310 pCell->SetData(pItem->lParam);
04311 if (pItem->mask & GVIF_IMAGE)
04312 pCell->SetImage(pItem->iImage);
04313 if (pItem->mask & GVIF_STATE)
04314 SetItemState(pItem->row, pItem->col, pItem->nState);
04315 if (pItem->mask & GVIF_FORMAT)
04316 pCell->SetFormat(pItem->nFormat);
04317 if (pItem->mask & GVIF_BKCLR)
04318 pCell->SetBackClr(pItem->crBkClr);
04319 if (pItem->mask & GVIF_FGCLR)
04320 pCell->SetTextClr(pItem->crFgClr);
04321 if (pItem->mask & GVIF_FONT)
04322 pCell->SetFont(&(pItem->lfFont));
04323 if( pItem->mask & GVIF_MARGIN)
04324 pCell->SetMargin( pItem->nMargin);
04325
04326 return TRUE;
04327 }
04328
04329 BOOL CGridCtrl::GetItem(GV_ITEM* pItem)
04330 {
04331 if (!pItem)
04332 return FALSE;
04333 CGridCellBase* pCell = GetCell(pItem->row, pItem->col);
04334 if (!pCell)
04335 return FALSE;
04336
04337 if (pItem->mask & GVIF_TEXT)
04338 pItem->strText = GetItemText(pItem->row, pItem->col);
04339 if (pItem->mask & GVIF_PARAM)
04340 pItem->lParam = pCell->GetData();;
04341 if (pItem->mask & GVIF_IMAGE)
04342 pItem->iImage = pCell->GetImage();
04343 if (pItem->mask & GVIF_STATE)
04344 pItem->nState = pCell->GetState();
04345 if (pItem->mask & GVIF_FORMAT)
04346 pItem->nFormat = pCell->GetFormat();
04347 if (pItem->mask & GVIF_BKCLR)
04348 pItem->crBkClr = pCell->GetBackClr();
04349 if (pItem->mask & GVIF_FGCLR)
04350 pItem->crFgClr = pCell->GetTextClr();
04351 if (pItem->mask & GVIF_FONT)
04352 memcpy(&(pItem->lfFont), pCell->GetFont(), sizeof(LOGFONT));
04353 if( pItem->mask & GVIF_MARGIN)
04354 pItem->nMargin = pCell->GetMargin();
04355
04356 return TRUE;
04357 }
04358
04359 BOOL CGridCtrl::SetItemText(int nRow, int nCol, LPCTSTR str)
04360 {
04361 if (GetVirtualMode())
04362 return FALSE;
04363
04364 CGridCellBase* pCell = GetCell(nRow, nCol);
04365 if (!pCell)
04366 return FALSE;
04367
04368 pCell->SetText(str);
04369
04370 SetModified(TRUE, nRow, nCol);
04371 return TRUE;
04372 }
04373
04374 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 210)
04375
04376 BOOL CGridCtrl::SetItemTextFmt(int nRow, int nCol, LPCTSTR szFmt, ...)
04377 {
04378 if (GetVirtualMode())
04379 return FALSE;
04380
04381 CString strText;
04382
04383 va_list argptr;
04384
04385 CGridCellBase* pCell = GetCell(nRow, nCol);
04386 if (!pCell)
04387 return FALSE;
04388
04389
04390 va_start(argptr, szFmt);
04391 strText.FormatV(szFmt, argptr);
04392 va_end(argptr);
04393
04394 pCell->SetText(strText);
04395
04396 SetModified(TRUE, nRow, nCol);
04397 return TRUE;
04398 }
04399
04400
04401
04402 BOOL CGridCtrl::SetItemTextFmtID(int nRow, int nCol, UINT nID, ...)
04403 {
04404 if (GetVirtualMode())
04405 return FALSE;
04406
04407 CString strFmt, strText;
04408 va_list argptr;
04409
04410 CGridCellBase* pCell = GetCell(nRow, nCol);
04411 if (!pCell)
04412 return FALSE;
04413
04414
04415 va_start(argptr, nID);
04416 VERIFY(strFmt.LoadString(nID));
04417 strText.FormatV(strFmt, argptr);
04418 va_end(argptr);
04419
04420 pCell->SetText(strText);
04421
04422 SetModified(TRUE, nRow, nCol);
04423 return TRUE;
04424 }
04425 #endif
04426
04427 BOOL CGridCtrl::SetItemData(int nRow, int nCol, LPARAM lParam)
04428 {
04429 if (GetVirtualMode())
04430 return FALSE;
04431
04432 CGridCellBase* pCell = GetCell(nRow, nCol);
04433 if (!pCell)
04434 return FALSE;
04435
04436 pCell->SetData(lParam);
04437 SetModified(TRUE, nRow, nCol);
04438 return TRUE;
04439 }
04440
04441 LPARAM CGridCtrl::GetItemData(int nRow, int nCol) const
04442 {
04443 CGridCellBase* pCell = GetCell(nRow, nCol);
04444 if (!pCell)
04445 return (LPARAM) 0;
04446
04447 return pCell->GetData();
04448 }
04449
04450 BOOL CGridCtrl::SetItemImage(int nRow, int nCol, int iImage)
04451 {
04452 if (GetVirtualMode())
04453 return FALSE;
04454
04455 CGridCellBase* pCell = GetCell(nRow, nCol);
04456 if (!pCell)
04457 return FALSE;
04458
04459 pCell->SetImage(iImage);
04460 SetModified(TRUE, nRow, nCol);
04461 return TRUE;
04462 }
04463
04464 int CGridCtrl::GetItemImage(int nRow, int nCol) const
04465 {
04466 CGridCellBase* pCell = GetCell(nRow, nCol);
04467 ASSERT(pCell);
04468 if (!pCell)
04469 return -1;
04470
04471 return pCell->GetImage();
04472 }
04473
04474 BOOL CGridCtrl::SetItemState(int nRow, int nCol, UINT state)
04475 {
04476 BOOL bSelected = IsCellSelected(nRow, nCol);
04477
04478
04479 if (bSelected && !(state & GVIS_SELECTED))
04480 {
04481 CCellID cell;
04482 DWORD key = MAKELONG(nRow, nCol);
04483
04484 if (m_SelectedCellMap.Lookup(key, (CCellID&)cell))
04485 m_SelectedCellMap.RemoveKey(key);
04486 }
04487
04488
04489 else if (!bSelected && (state & GVIS_SELECTED))
04490 {
04491 CCellID cell(nRow, nCol);
04492 m_SelectedCellMap.SetAt(MAKELONG(nRow, nCol), cell);
04493 }
04494
04495 if (GetVirtualMode())
04496 return FALSE;
04497
04498 CGridCellBase* pCell = GetCell(nRow, nCol);
04499 ASSERT(pCell);
04500 if (!pCell)
04501 return FALSE;
04502
04503
04504 pCell->SetState(state);
04505
04506 return TRUE;
04507 }
04508
04509 UINT CGridCtrl::GetItemState(int nRow, int nCol) const
04510 {
04511 CGridCellBase* pCell = GetCell(nRow, nCol);
04512 ASSERT(pCell);
04513 if (!pCell)
04514 return 0;
04515
04516 return pCell->GetState();
04517 }
04518
04519 BOOL CGridCtrl::SetItemFormat(int nRow, int nCol, UINT nFormat)
04520 {
04521 if (GetVirtualMode())
04522 return FALSE;
04523
04524 CGridCellBase* pCell = GetCell(nRow, nCol);
04525 ASSERT(pCell);
04526 if (!pCell)
04527 return FALSE;
04528
04529 pCell->SetFormat(nFormat);
04530 return TRUE;
04531 }
04532
04533 UINT CGridCtrl::GetItemFormat(int nRow, int nCol) const
04534 {
04535 CGridCellBase* pCell = GetCell(nRow, nCol);
04536 ASSERT(pCell);
04537 if (!pCell)
04538 return 0;
04539
04540 return pCell->GetFormat();
04541 }
04542
04543 BOOL CGridCtrl::SetItemBkColour(int nRow, int nCol, COLORREF cr )
04544 {
04545 if (GetVirtualMode())
04546 return FALSE;
04547
04548 CGridCellBase* pCell = GetCell(nRow, nCol);
04549 ASSERT(pCell);
04550 if (!pCell)
04551 return FALSE;
04552
04553 pCell->SetBackClr(cr);
04554 return TRUE;
04555 }
04556
04557 COLORREF CGridCtrl::GetItemBkColour(int nRow, int nCol) const
04558 {
04559 CGridCellBase* pCell = GetCell(nRow, nCol);
04560 ASSERT(pCell);
04561 if (!pCell)
04562 return 0;
04563
04564 return pCell->GetBackClr();
04565 }
04566
04567 BOOL CGridCtrl::SetItemFgColour(int nRow, int nCol, COLORREF cr )
04568 {
04569 if (GetVirtualMode())
04570 return FALSE;
04571
04572 CGridCellBase* pCell = GetCell(nRow, nCol);
04573 ASSERT(pCell);
04574 if (!pCell)
04575 return FALSE;
04576
04577 pCell->SetTextClr(cr);
04578 return TRUE;
04579 }
04580
04581 COLORREF CGridCtrl::GetItemFgColour(int nRow, int nCol) const
04582 {
04583 CGridCellBase* pCell = GetCell(nRow, nCol);
04584 ASSERT(pCell);
04585 if (!pCell)
04586 return 0;
04587
04588 return pCell->GetTextClr();
04589 }
04590
04591 BOOL CGridCtrl::SetItemFont(int nRow, int nCol, const LOGFONT* plf)
04592 {
04593 if (GetVirtualMode())
04594 return FALSE;
04595
04596 CGridCellBase* pCell = GetCell(nRow, nCol);
04597 ASSERT(pCell);
04598 if (!pCell)
04599 return FALSE;
04600
04601 pCell->SetFont(plf);
04602
04603 return TRUE;
04604 }
04605
04606 const LOGFONT* CGridCtrl::GetItemFont(int nRow, int nCol)
04607 {
04608 CGridCellBase* pCell = GetCell(nRow, nCol);
04609 ASSERT(pCell);
04610 if (!pCell)
04611 return GetDefaultCell(nRow < GetFixedRowCount(), nCol < GetFixedColumnCount())->GetFont();
04612
04613 return pCell->GetFont();
04614 }
04615
04616 BOOL CGridCtrl::IsItemEditing(int nRow, int nCol)
04617 {
04618 CGridCellBase* pCell = GetCell(nRow, nCol);
04619 ASSERT(pCell);
04620 if (!pCell)
04621 return FALSE;
04622
04623 return pCell->IsEditing();
04624 }
04625
04627
04628
04629 long CGridCtrl::GetVirtualWidth() const
04630 {
04631 long lVirtualWidth = 0;
04632 int iColCount = GetColumnCount();
04633 for (int i = 0; i < iColCount; i++)
04634 lVirtualWidth += m_arColWidths[i];
04635
04636 return lVirtualWidth;
04637 }
04638
04639 long CGridCtrl::GetVirtualHeight() const
04640 {
04641 long lVirtualHeight = 0;
04642 int iRowCount = GetRowCount();
04643 for (int i = 0; i < iRowCount; i++)
04644 lVirtualHeight += m_arRowHeights[i];
04645
04646 return lVirtualHeight;
04647 }
04648
04649 int CGridCtrl::GetRowHeight(int nRow) const
04650 {
04651 ASSERT(nRow >= 0 && nRow < m_nRows);
04652 if (nRow < 0 || nRow >= m_nRows)
04653 return -1;
04654
04655 return m_arRowHeights[nRow];
04656 }
04657
04658 int CGridCtrl::GetColumnWidth(int nCol) const
04659 {
04660 ASSERT(nCol >= 0 && nCol < m_nCols);
04661 if (nCol < 0 || nCol >= m_nCols)
04662 return -1;
04663
04664 return m_arColWidths[nCol];
04665 }
04666
04667 BOOL CGridCtrl::SetRowHeight(int nRow, int height)
04668 {
04669 ASSERT(nRow >= 0 && nRow < m_nRows && height >= 0);
04670 if (nRow < 0 || nRow >= m_nRows || height < 0)
04671 return FALSE;
04672
04673 m_arRowHeights[nRow] = height;
04674 ResetScrollBars();
04675
04676 return TRUE;
04677 }
04678
04679 BOOL CGridCtrl::SetColumnWidth(int nCol, int width)
04680 {
04681 ASSERT(nCol >= 0 && nCol < m_nCols && width >= 0);
04682 if (nCol < 0 || nCol >= m_nCols || width < 0)
04683 return FALSE;
04684
04685 m_arColWidths[nCol] = width;
04686 ResetScrollBars();
04687
04688 return TRUE;
04689 }
04690
04691 int CGridCtrl::GetFixedRowHeight() const
04692 {
04693 int nHeight = 0;
04694 for (int i = 0; i < m_nFixedRows; i++)
04695 nHeight += GetRowHeight(i);
04696
04697 return nHeight;
04698 }
04699
04700 int CGridCtrl::GetFixedColumnWidth() const
04701 {
04702 int nWidth = 0;
04703 for (int i = 0; i < m_nFixedCols; i++)
04704 nWidth += GetColumnWidth(i);
04705
04706 return nWidth;
04707 }
04708
04709 BOOL CGridCtrl::AutoSizeColumn(int nCol, UINT nAutoSizeStyle ,
04710 BOOL bResetScroll )
04711 {
04712 ASSERT(nCol >= 0 && nCol < m_nCols);
04713 if (nCol < 0 || nCol >= m_nCols)
04714 return FALSE;
04715
04716
04717 if( GetColumnWidth( nCol) <=0 )
04718 return FALSE;
04719
04720 CSize size;
04721 CDC* pDC = GetDC();
04722 if (!pDC)
04723 return FALSE;
04724
04725 int nWidth = 0;
04726
04727 ASSERT(GVS_DEFAULT <= nAutoSizeStyle && nAutoSizeStyle <= GVS_BOTH);
04728 if (nAutoSizeStyle == GVS_DEFAULT)
04729 nAutoSizeStyle = GetAutoSizeStyle();
04730
04731 int nStartRow = (nAutoSizeStyle & GVS_HEADER)? 0 : GetFixedRowCount();
04732 int nEndRow = (nAutoSizeStyle & GVS_DATA)? GetRowCount()-1 : GetFixedRowCount()-1;
04733
04734 if (GetVirtualMode())
04735 SendCacheHintToParent(CCellRange(nStartRow, nCol, nEndRow, nCol));
04736
04737 for (int nRow = nStartRow; nRow <= nEndRow; nRow++)
04738 {
04739 CGridCellBase* pCell = GetCell(nRow, nCol);
04740 if (pCell)
04741 size = pCell->GetCellExtent(pDC);
04742 if (size.cx > nWidth)
04743 nWidth = size.cx;
04744 }
04745
04746 if (GetVirtualMode())
04747 SendCacheHintToParent(CCellRange(-1,-1,-1,-1));
04748
04749 m_arColWidths[nCol] = nWidth;
04750
04751 ReleaseDC(pDC);
04752 if (bResetScroll)
04753 ResetScrollBars();
04754
04755 return TRUE;
04756 }
04757
04758 BOOL CGridCtrl::AutoSizeRow(int nRow, BOOL bResetScroll )
04759 {
04760 ASSERT(nRow >= 0 && nRow < m_nRows);
04761 if (nRow < 0 || nRow >= m_nRows)
04762 return FALSE;
04763
04764
04765 if( GetRowHeight( nRow) <=0 )
04766 return FALSE;
04767
04768 CSize size;
04769 CDC* pDC = GetDC();
04770 if (!pDC)
04771 return FALSE;
04772
04773 int nHeight = 0;
04774 int nNumColumns = GetColumnCount();
04775
04776 if (GetVirtualMode())
04777 SendCacheHintToParent(CCellRange(nRow, 0, nRow, nNumColumns));
04778
04779 for (int nCol = 0; nCol < nNumColumns; nCol++)
04780 {
04781 CGridCellBase* pCell = GetCell(nRow, nCol);
04782 if (pCell)
04783 size = pCell->GetCellExtent(pDC);
04784 if (size.cy > nHeight)
04785 nHeight = size.cy;
04786 }
04787 m_arRowHeights[nRow] = nHeight;
04788
04789 if (GetVirtualMode())
04790 SendCacheHintToParent(CCellRange(-1,-1,-1,-1));
04791
04792 ReleaseDC(pDC);
04793 if (bResetScroll)
04794 ResetScrollBars();
04795
04796 return TRUE;
04797 }
04798
04799 void CGridCtrl::AutoSizeColumns(UINT nAutoSizeStyle )
04800 {
04801 int nNumColumns = GetColumnCount();
04802 for (int nCol = 0; nCol < nNumColumns; nCol++)
04803 {
04804
04805 if( GetColumnWidth( nCol) > 0 )
04806 AutoSizeColumn(nCol, nAutoSizeStyle, FALSE);
04807 }
04808 ResetScrollBars();
04809 }
04810
04811 void CGridCtrl::AutoSizeRows()
04812 {
04813 int nNumRows = GetRowCount();
04814 for (int nRow = 0; nRow < nNumRows; nRow++)
04815 {
04816
04817 if( GetRowHeight( nRow) > 0 )
04818 AutoSizeRow(nRow, FALSE);
04819 }
04820 ResetScrollBars();
04821 }
04822
04823
04824
04825 void CGridCtrl::AutoSize(UINT nAutoSizeStyle )
04826 {
04827 CDC* pDC = GetDC();
04828 if (!pDC)
04829 return;
04830
04831 int nNumColumns = GetColumnCount();
04832
04833 int nCol, nRow;
04834
04835 ASSERT(GVS_DEFAULT <= nAutoSizeStyle && nAutoSizeStyle <= GVS_BOTH);
04836 if (nAutoSizeStyle == GVS_DEFAULT)
04837 nAutoSizeStyle = GetAutoSizeStyle();
04838
04839 int nStartRow = (nAutoSizeStyle & GVS_HEADER)? 0 : GetFixedRowCount();
04840 int nEndRow = (nAutoSizeStyle & GVS_DATA)? GetRowCount()-1 : GetFixedRowCount()-1;
04841
04842 if (GetVirtualMode())
04843 SendCacheHintToParent(CCellRange(nStartRow, 0, nEndRow, nNumColumns));
04844
04845
04846 for (nRow = nStartRow; nRow <= nEndRow; nRow++)
04847 {
04848 if( GetRowHeight( nRow) > 0 )
04849 m_arRowHeights[nRow] = 1;
04850 }
04851
04852 CSize size;
04853 for (nCol = 0; nCol < nNumColumns; nCol++)
04854 {
04855
04856 if( GetColumnWidth( nCol) > 0 )
04857 {
04858
04859 m_arColWidths[nCol] = 0;
04860 for (nRow = nStartRow; nRow <= nEndRow; nRow++)
04861 {
04862 if( GetRowHeight( nRow) > 0 )
04863 {
04864 CGridCellBase* pCell = GetCell(nRow, nCol);
04865 if (pCell)
04866 size = pCell->GetCellExtent(pDC);
04867 if (size.cx >(int) m_arColWidths[nCol])
04868 m_arColWidths[nCol] = size.cx;
04869 if (size.cy >(int) m_arRowHeights[nRow])
04870 m_arRowHeights[nRow] = size.cy;
04871 }
04872 }
04873 }
04874 }
04875
04876 if (GetVirtualMode())
04877 SendCacheHintToParent(CCellRange(-1,-1,-1,-1));
04878
04879 ReleaseDC(pDC);
04880
04881 ResetScrollBars();
04882 Refresh();
04883 }
04884
04885
04886
04887 void CGridCtrl::ExpandColumnsToFit(BOOL bExpandFixed )
04888 {
04889 if (bExpandFixed)
04890 {
04891 if (GetColumnCount() <= 0) return;
04892 }
04893 else
04894 {
04895 if (GetColumnCount() <= GetFixedColumnCount()) return;
04896 }
04897
04898 EnableScrollBars(SB_HORZ, FALSE);
04899
04900 CRect rect;
04901 GetClientRect(rect);
04902
04903 int nFirstColumn = (bExpandFixed)? 0 : GetFixedColumnCount();
04904
04905 int nNumColumnsAffected = 0;
04906 int col;
04907 for (col = nFirstColumn; col < GetColumnCount(); col++)
04908 {
04909 if (m_arColWidths[col] > 0)
04910 nNumColumnsAffected++;
04911 }
04912
04913 if (nNumColumnsAffected <= 0)
04914 return;
04915
04916 long virtualWidth = GetVirtualWidth();
04917 int nDifference = rect.Width() -(int) virtualWidth;
04918 int nColumnAdjustment = nDifference / nNumColumnsAffected;
04919
04920 for (col = nFirstColumn; col < GetColumnCount(); col++)
04921 {
04922 if (m_arColWidths[col] > 0)
04923 m_arColWidths[col] += nColumnAdjustment;
04924 }
04925
04926 if (nDifference > 0)
04927 {
04928 int leftOver = nDifference % nNumColumnsAffected;
04929 for (int nCount = 0, col = nFirstColumn;
04930 (col < GetColumnCount()) && (nCount < leftOver); col++, nCount++)
04931 {
04932 if (m_arColWidths[col] > 0)
04933 m_arColWidths[col] += 1;
04934 }
04935 }
04936 else
04937 {
04938 int leftOver = (-nDifference) % nNumColumnsAffected;
04939 for (int nCount = 0, col = nFirstColumn;
04940 (col < GetColumnCount()) && (nCount < leftOver); col++, nCount++)
04941 {
04942 if (m_arColWidths[col] > 0)
04943 m_arColWidths[col] -= 1;
04944 }
04945 }
04946
04947 Refresh();
04948
04949 ResetScrollBars();
04950 }
04951
04952 void CGridCtrl::ExpandLastColumn()
04953 {
04954 if (GetColumnCount() <= 0)
04955 return;
04956
04957
04958 int nLastColumn = GetColumnCount()-1;
04959 while (m_arColWidths[nLastColumn] <= 0)
04960 nLastColumn--;
04961
04962 if (nLastColumn <= 0)
04963 return;
04964
04965 EnableScrollBars(SB_HORZ, FALSE);
04966
04967 CRect rect;
04968 GetClientRect(rect);
04969
04970 long virtualWidth = GetVirtualWidth();
04971 int nDifference = rect.Width() -(int) virtualWidth;
04972
04973 if (nDifference > 0)
04974 {
04975
04976
04977
04978 m_arColWidths[ nLastColumn ] += nDifference;
04979 Refresh();
04980 }
04981
04982 ResetScrollBars();
04983 }
04984
04985
04986
04987 void CGridCtrl::ExpandRowsToFit(BOOL bExpandFixed )
04988 {
04989 if (bExpandFixed)
04990 {
04991 if (GetRowCount() <= 0) return;
04992 }
04993 else
04994 {
04995 if (GetRowCount() <= GetFixedRowCount()) return;
04996 }
04997
04998 EnableScrollBars(SB_VERT, FALSE);
04999
05000 CRect rect;
05001 GetClientRect(rect);
05002
05003 int nFirstRow = (bExpandFixed)? 0 : GetFixedRowCount();
05004
05005 int nNumRowsAffected = 0;
05006 int row;
05007 for (row = nFirstRow; row < GetRowCount(); row++)
05008 {
05009 if (m_arRowHeights[row] > 0)
05010 nNumRowsAffected++;
05011 }
05012
05013 if (nNumRowsAffected <= 0)
05014 return;
05015
05016 long virtualHeight = GetVirtualHeight();
05017 int nDifference = rect.Height() -(int) virtualHeight;
05018 int nRowAdjustment = nDifference / nNumRowsAffected;
05019
05020 for (row = nFirstRow; row < GetRowCount(); row++)
05021 {
05022 if (m_arRowHeights[row] > 0)
05023 m_arRowHeights[row] += nRowAdjustment;
05024 }
05025
05026 if (nDifference > 0)
05027 {
05028 int leftOver = nDifference % nNumRowsAffected;
05029 for (int nCount = 0, row = nFirstRow;
05030 (row < GetRowCount()) && (nCount < leftOver); row++, nCount++)
05031 {
05032 if (m_arRowHeights[row] > 0)
05033 m_arRowHeights[row] += 1;
05034 }
05035 }
05036 else
05037 {
05038 int leftOver = (-nDifference) % nNumRowsAffected;
05039 for (int nCount = 0, row = nFirstRow;
05040 (row < GetRowCount()) && (nCount < leftOver); row++, nCount++)
05041 {
05042 if (m_arRowHeights[row] > 0)
05043 m_arRowHeights[row] -= 1;
05044 }
05045 }
05046
05047 Refresh();
05048
05049 ResetScrollBars();
05050 }
05051
05052
05053
05054 void CGridCtrl::ExpandToFit(BOOL bExpandFixed )
05055 {
05056 ExpandColumnsToFit(bExpandFixed);
05057 ExpandRowsToFit(bExpandFixed);
05058 ExpandColumnsToFit(bExpandFixed);
05059
05060 Refresh();
05061 }
05062
05064
05065
05066 void CGridCtrl::SetVirtualMode(BOOL bVirtual)
05067 {
05068 DeleteAllItems();
05069 m_bVirtualMode = bVirtual;
05070
05071
05072 if (m_bVirtualMode)
05073 {
05074 SetEditable(FALSE);
05075 SetHeaderSort(FALSE);
05076 SetAutoSizeStyle(GVS_HEADER);
05077 SetFixedColumnSelection(FALSE);
05078 SetFixedRowSelection(FALSE);
05079 }
05080 }
05081
05082 void CGridCtrl::SetGridLines(int nWhichLines )
05083 {
05084 m_nGridLines = nWhichLines;
05085 Refresh();
05086 }
05087
05088 void CGridCtrl::SetListMode(BOOL bEnableListMode )
05089 {
05090 ResetSelectedRange();
05091 SetSortColumn(-1);
05092 m_bListMode = bEnableListMode;
05093 SetFixedRowSelection(FALSE);
05094 Refresh();
05095 }
05096
05097 void CGridCtrl::SetSortColumn(int nCol)
05098 {
05099 if (m_nSortColumn >= 0)
05100 InvalidateCellRect(0, m_nSortColumn);
05101 m_nSortColumn = nCol;
05102 if (nCol >= 0)
05103 InvalidateCellRect(0, nCol);
05104 }
05105
05106 BOOL CGridCtrl::IsCellFixed(int nRow, int nCol)
05107 {
05108 return (nRow < GetFixedRowCount() || nCol < GetFixedColumnCount());
05109 }
05110
05111 void CGridCtrl::SetModified(BOOL bModified , int nRow , int nCol )
05112 {
05113
05114 if (nCol < 0 || nCol == GetSortColumn())
05115 SetSortColumn(-1);
05116
05117 if (nRow >= 0 && nCol >= 0)
05118 {
05119 if (bModified)
05120 {
05121 SetItemState(nRow, nCol, GetItemState(nRow, nCol) | GVIS_MODIFIED);
05122 m_bModified = TRUE;
05123 }
05124 else
05125 SetItemState(nRow, nCol, GetItemState(nRow, nCol) & ~GVIS_MODIFIED);
05126 }
05127 else
05128 m_bModified = bModified;
05129
05130 if (!m_bModified)
05131 {
05132 for (int row = 0; row < GetRowCount(); row++)
05133 for (int col = 0; col < GetColumnCount(); col++)
05134 SetItemState(row, col, GetItemState(row, col) & ~GVIS_MODIFIED);
05135 }
05136 }
05137
05138 BOOL CGridCtrl::GetModified(int nRow , int nCol )
05139 {
05140 if (nRow >= 0 && nCol >= 0)
05141 return ( (GetItemState(nRow, nCol) & GVIS_MODIFIED) == GVIS_MODIFIED );
05142 else
05143 return m_bModified;
05144 }
05145
05147
05148
05149 void CGridCtrl::Refresh()
05150 {
05151 if (GetSafeHwnd() && m_bAllowDraw)
05152 Invalidate();
05153 }
05154
05155
05156 void CGridCtrl::EnsureVisible(int nRow, int nCol)
05157 {
05158 if (!m_bAllowDraw)
05159 return;
05160
05161 CRect rectWindow;
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186 CWnd* pFocusWnd = GetFocus();
05187
05188 CCellRange VisibleCells = GetVisibleNonFixedCellRange();
05189
05190 int right = nCol - VisibleCells.GetMaxCol();
05191 int left = VisibleCells.GetMinCol() - nCol;
05192 int down = nRow - VisibleCells.GetMaxRow();
05193 int up = VisibleCells.GetMinRow() - nRow;
05194
05195 int iColumnStart;
05196 int iRowStart;
05197
05198 iColumnStart = VisibleCells.GetMaxCol() + 1;
05199 while( right > 0 )
05200 {
05201 if( GetColumnWidth( iColumnStart ) > 0 )
05202 SendMessage( WM_HSCROLL, SB_LINERIGHT, 0 );
05203
05204 right--;
05205 iColumnStart++;
05206 }
05207
05208 iColumnStart = VisibleCells.GetMinCol() - 1;
05209 while( left > 0 )
05210 {
05211 if( GetColumnWidth( iColumnStart ) > 0 )
05212 SendMessage( WM_HSCROLL, SB_LINELEFT, 0 );
05213 left--;
05214 iColumnStart--;
05215 }
05216
05217 iRowStart = VisibleCells.GetMaxRow() + 1;
05218 while( down > 0 )
05219 {
05220 if( GetRowHeight( iRowStart ) > 0 )
05221 SendMessage( WM_VSCROLL, SB_LINEDOWN, 0 );
05222 down--;
05223 iRowStart++;
05224 }
05225
05226 iRowStart = VisibleCells.GetMinRow() - 1;
05227 while( up > 0 )
05228 {
05229 if( GetRowHeight( iRowStart ) > 0 )
05230 SendMessage( WM_VSCROLL, SB_LINEUP, 0 );
05231 up--;
05232 iRowStart--;
05233 }
05234
05235
05236 CRect rectCell;
05237 if (!GetCellRect(nRow, nCol, rectCell))
05238 {
05239 if (pFocusWnd && ::IsWindow(pFocusWnd->GetSafeHwnd()))
05240 pFocusWnd->SetFocus();
05241 return;
05242 }
05243
05244 GetClientRect(rectWindow);
05245
05246
05247 while (rectCell.right > rectWindow.right
05248 && rectCell.left > GetFixedColumnWidth())
05249 {
05250 SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
05251 if (!GetCellRect(nRow, nCol, rectCell))
05252 {
05253 if (pFocusWnd && ::IsWindow(pFocusWnd->GetSafeHwnd()))
05254 pFocusWnd->SetFocus();
05255 return;
05256 }
05257 }
05258
05259 while (rectCell.bottom > rectWindow.bottom
05260 && rectCell.top > GetFixedRowHeight())
05261 {
05262 SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
05263 if (!GetCellRect(nRow, nCol, rectCell))
05264 {
05265 if (pFocusWnd && ::IsWindow(pFocusWnd->GetSafeHwnd()))
05266 pFocusWnd->SetFocus();
05267 return;
05268 }
05269 }
05270
05271
05272 if (pFocusWnd && ::IsWindow(pFocusWnd->GetSafeHwnd()))
05273 pFocusWnd->SetFocus();
05274 }
05275
05276 BOOL CGridCtrl::IsCellEditable(CCellID &cell) const
05277 {
05278 return IsCellEditable(cell.row, cell.col);
05279 }
05280
05281 BOOL CGridCtrl::IsCellEditable(int nRow, int nCol) const
05282 {
05283 return IsEditable() && ((GetItemState(nRow, nCol) & GVIS_READONLY) != GVIS_READONLY);
05284 }
05285
05286 BOOL CGridCtrl::IsCellSelected(CCellID &cell) const
05287 {
05288 return IsCellSelected(cell.row, cell.col);
05289 }
05290
05291 BOOL CGridCtrl::IsCellSelected(int nRow, int nCol) const
05292 {
05293 if (GetVirtualMode())
05294 {
05295 if (!IsSelectable())
05296 return FALSE;
05297
05298 CCellID cell;
05299 DWORD key = MAKELONG(nRow, nCol);
05300
05301 return (m_SelectedCellMap.Lookup(key, (CCellID&)cell));
05302 }
05303 else
05304 return IsSelectable() && ((GetItemState(nRow, nCol) & GVIS_SELECTED) == GVIS_SELECTED);
05305 }
05306
05307 BOOL CGridCtrl::IsCellVisible(CCellID cell)
05308 {
05309 return IsCellVisible(cell.row, cell.col);
05310 }
05311
05312 BOOL CGridCtrl::IsCellVisible(int nRow, int nCol)
05313 {
05314 if (!IsWindow(m_hWnd))
05315 return FALSE;
05316
05317 int x, y;
05318
05319 CCellID TopLeft;
05320 if (nCol >= GetFixedColumnCount() || nRow >= GetFixedRowCount())
05321 {
05322 TopLeft = GetTopleftNonFixedCell();
05323 if (nCol >= GetFixedColumnCount() && nCol < TopLeft.col)
05324 return FALSE;
05325 if (nRow >= GetFixedRowCount() && nRow < TopLeft.row)
05326 return FALSE;
05327 }
05328
05329 CRect rect;
05330 GetClientRect(rect);
05331 if (nCol < GetFixedColumnCount())
05332 {
05333 x = 0;
05334 for (int i = 0; i <= nCol; i++)
05335 {
05336 if (x >= rect.right)
05337 return FALSE;
05338 x += GetColumnWidth(i);
05339 }
05340 }
05341 else
05342 {
05343 x = GetFixedColumnWidth();
05344 for (int i = TopLeft.col; i <= nCol; i++)
05345 {
05346 if (x >= rect.right)
05347 return FALSE;
05348 x += GetColumnWidth(i);
05349 }
05350 }
05351
05352 if (nRow < GetFixedRowCount())
05353 {
05354 y = 0;
05355 for (int i = 0; i <= nRow; i++)
05356 {
05357 if (y >= rect.bottom)
05358 return FALSE;
05359 y += GetRowHeight(i);
05360 }
05361 }
05362 else
05363 {
05364 if (nRow < TopLeft.row)
05365 return FALSE;
05366 y = GetFixedRowHeight();
05367 for (int i = TopLeft.row; i <= nRow; i++)
05368 {
05369 if (y >= rect.bottom)
05370 return FALSE;
05371 y += GetRowHeight(i);
05372 }
05373 }
05374
05375 return TRUE;
05376 }
05377
05378 BOOL CGridCtrl::InvalidateCellRect(const CCellID& cell)
05379 {
05380 return InvalidateCellRect(cell.row, cell.col);
05381 }
05382
05383 BOOL CGridCtrl::InvalidateCellRect(const int row, const int col)
05384 {
05385 if (!::IsWindow(GetSafeHwnd()) || !m_bAllowDraw)
05386 return FALSE;
05387
05388 if (!IsValid(row, col))
05389 return FALSE;
05390
05391 if (!IsCellVisible(row, col))
05392 return FALSE;
05393
05394 CRect rect;
05395 if (!GetCellRect(row, col, rect))
05396 return FALSE;
05397 rect.right++;
05398 rect.bottom++;
05399 InvalidateRect(rect, TRUE);
05400
05401 return TRUE;
05402 }
05403
05404 BOOL CGridCtrl::InvalidateCellRect(const CCellRange& cellRange)
05405 {
05406 ASSERT(IsValid(cellRange));
05407 if (!::IsWindow(GetSafeHwnd()) || !m_bAllowDraw)
05408 return FALSE;
05409
05410 CCellRange visibleCellRange = GetVisibleNonFixedCellRange().Intersect(cellRange);
05411
05412 CRect rect;
05413 if (!GetCellRangeRect(visibleCellRange, rect))
05414 return FALSE;
05415
05416 rect.right++;
05417 rect.bottom++;
05418 InvalidateRect(rect, TRUE);
05419
05420 return TRUE;
05421 }
05422
05424
05425
05426
05427
05428 #if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
05429 BOOL CGridCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
05430 {
05431
05432
05433 if (m_nRowsPerWheelNotch == -1)
05434 {
05435 int nPagesScrolled = zDelta / 120;
05436
05437 if (nPagesScrolled > 0)
05438 {
05439 for (int i = 0; i < nPagesScrolled; i++)
05440 {
05441 PostMessage(WM_VSCROLL, SB_PAGEUP, 0);
05442 }
05443 }
05444 else
05445 {
05446 for (int i = 0; i > nPagesScrolled; i--)
05447 {
05448 PostMessage(WM_VSCROLL, SB_PAGEDOWN, 0);
05449 }
05450 }
05451 }
05452 else
05453 {
05454 int nRowsScrolled = m_nRowsPerWheelNotch * zDelta / 120;
05455
05456 if (nRowsScrolled > 0)
05457 {
05458 for (int i = 0; i < nRowsScrolled; i++)
05459 {
05460 PostMessage(WM_VSCROLL, SB_LINEUP, 0);
05461 }
05462 }
05463 else
05464 {
05465 for (int i = 0; i > nRowsScrolled; i--)
05466 {
05467 PostMessage(WM_VSCROLL, SB_LINEDOWN, 0);
05468 }
05469 }
05470 }
05471
05472 return CWnd::OnMouseWheel(nFlags, zDelta, pt);
05473 }
05474 #endif // !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
05475
05476 void CGridCtrl::OnMouseMove(UINT , CPoint point)
05477 {
05478 CRect rect;
05479 GetClientRect(rect);
05480
05481 #ifndef GRIDCONTROL_NO_DRAGDROP
05482
05483 if (m_MouseMode != MOUSE_DRAGGING && !rect.PtInRect(point))
05484 return;
05485 #endif
05486
05487
05488
05489
05490
05491
05492
05493
05494 if (!m_bLMouseButtonDown ||
05495 (m_bLMouseButtonDown && m_MouseMode == MOUSE_NOTHING))
05496 {
05497 if (m_bAllowColumnResize && MouseOverColumnResizeArea(point))
05498 {
05499 if (m_MouseMode != MOUSE_OVER_COL_DIVIDE)
05500 {
05501 #ifndef _WIN32_WCE_NO_CURSOR
05502 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
05503 #endif
05504 m_MouseMode = MOUSE_OVER_COL_DIVIDE;
05505 }
05506 }
05507 else if (m_bAllowRowResize && MouseOverRowResizeArea(point))
05508 {
05509 if (m_MouseMode != MOUSE_OVER_ROW_DIVIDE)
05510 {
05511 #ifndef _WIN32_WCE_NO_CURSOR
05512 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
05513 #endif
05514 m_MouseMode = MOUSE_OVER_ROW_DIVIDE;
05515 }
05516 }
05517 else if (m_MouseMode != MOUSE_NOTHING)
05518 {
05519 #ifndef _WIN32_WCE_NO_CURSOR
05520 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
05521 #endif
05522 m_MouseMode = MOUSE_NOTHING;
05523 }
05524
05525 if (m_MouseMode == MOUSE_NOTHING)
05526 {
05527 CGridCellBase* pCell = NULL;
05528 CCellID idCurrentCell;
05529 if (!GetVirtualMode() || m_bTitleTips)
05530 {
05531
05532
05533 idCurrentCell = GetCellFromPt(point);
05534 pCell = GetCell(idCurrentCell.row, idCurrentCell.col);
05535 if (pCell)
05536 pCell->OnMouseOver();
05537 }
05538
05539 #ifndef GRIDCONTROL_NO_TITLETIPS
05540
05541 if (m_bTitleTips)
05542 {
05543 CRect TextRect, CellRect;
05544 if (pCell)
05545 {
05546 LPCTSTR szTipText = pCell->GetTipText();
05547 if (!m_bRMouseButtonDown
05548 && szTipText && szTipText[0]
05549 && !pCell->IsEditing()
05550 && GetCellRect( idCurrentCell.row, idCurrentCell.col, &TextRect)
05551 && pCell->GetTipTextRect( &TextRect)
05552 && GetCellRect(idCurrentCell.row, idCurrentCell.col, CellRect) )
05553 {
05554 TRACE0("Showing TitleTip\n");
05555 m_TitleTip.Show(TextRect, pCell->GetTipText(), 0, CellRect,
05556 pCell->GetFont(), GetTitleTipTextClr(), GetTitleTipBackClr());
05557 }
05558 }
05559 }
05560 #endif
05561 }
05562
05563 m_LastMousePoint = point;
05564 return;
05565 }
05566
05567 if (!IsValid(m_LeftClickDownCell))
05568 {
05569 m_LastMousePoint = point;
05570 return;
05571 }
05572
05573
05574 if (m_bLMouseButtonDown)
05575 {
05576 switch (m_MouseMode)
05577 {
05578 case MOUSE_SELECT_ALL:
05579 break;
05580
05581 case MOUSE_SELECT_COL:
05582 case MOUSE_SELECT_ROW:
05583 case MOUSE_SELECT_CELLS:
05584 {
05585 CCellID idCurrentCell = GetCellFromPt(point);
05586 if (!IsValid(idCurrentCell))
05587 return;
05588
05589 if (idCurrentCell != GetFocusCell())
05590 {
05591 OnSelecting(idCurrentCell);
05592
05593
05594
05595
05596 if((idCurrentCell.row >= m_nFixedRows &&
05597 idCurrentCell.col >= m_nFixedCols) ||
05598 m_MouseMode==MOUSE_SELECT_COL ||
05599 m_MouseMode==MOUSE_SELECT_ROW)
05600 {
05601 SetFocusCell(idCurrentCell);
05602 }
05603 }
05604 break;
05605 }
05606
05607 case MOUSE_SIZING_COL:
05608 {
05609 CDC* pDC = GetDC();
05610 if (!pDC)
05611 break;
05612
05613 CRect oldInvertedRect(m_LastMousePoint.x, rect.top,
05614 m_LastMousePoint.x + 2, rect.bottom);
05615 pDC->InvertRect(&oldInvertedRect);
05616 CRect newInvertedRect(point.x, rect.top,
05617 point.x + 2, rect.bottom);
05618 pDC->InvertRect(&newInvertedRect);
05619 ReleaseDC(pDC);
05620 }
05621 break;
05622
05623 case MOUSE_SIZING_ROW:
05624 {
05625 CDC* pDC = GetDC();
05626 if (!pDC)
05627 break;
05628
05629 CRect oldInvertedRect(rect.left, m_LastMousePoint.y,
05630 rect.right, m_LastMousePoint.y + 2);
05631 pDC->InvertRect(&oldInvertedRect);
05632 CRect newInvertedRect(rect.left, point.y,
05633 rect.right, point.y + 2);
05634 pDC->InvertRect(&newInvertedRect);
05635 ReleaseDC(pDC);
05636 }
05637 break;
05638
05639 #ifndef GRIDCONTROL_NO_DRAGDROP
05640 case MOUSE_PREPARE_EDIT:
05641 case MOUSE_PREPARE_DRAG:
05642 m_MouseMode = MOUSE_PREPARE_DRAG;
05643 OnBeginDrag();
05644 break;
05645 #endif
05646 }
05647 }
05648
05649 m_LastMousePoint = point;
05650 }
05651
05652
05653 CPoint CGridCtrl::GetPointClicked(int nRow, int nCol, const CPoint& point)
05654 {
05655 CPoint PointCellOrigin;
05656 if( !GetCellOrigin( nRow, nCol, &PointCellOrigin) )
05657 return CPoint( 0, 0);
05658
05659 CPoint PointClickedCellRelative( point);
05660 PointClickedCellRelative -= PointCellOrigin;
05661 return PointClickedCellRelative;
05662 }
05663
05664 void CGridCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
05665 {
05666 TRACE0("CGridCtrl::OnLButtonDblClk\n");
05667
05668 CCellID cell = GetCellFromPt(point);
05669 if( !IsValid( cell) )
05670 {
05671
05672 return;
05673 }
05674
05675 #ifdef _WIN32_WCE
05676 if (MouseOverColumnResizeArea(point))
05677 #else
05678 if (m_MouseMode == MOUSE_OVER_COL_DIVIDE)
05679 #endif
05680 {
05681 CPoint start;
05682 if (!GetCellOrigin(0, cell.col, &start))
05683 return;
05684
05685 if (point.x - start.x < m_nResizeCaptureRange)
05686 cell.col--;
05687
05688
05689 BOOL bFoundVisible = FALSE;
05690 while( cell.col >= 0)
05691 {
05692 if( GetColumnWidth( cell.col) > 0)
05693 {
05694 bFoundVisible = TRUE;
05695 break;
05696 }
05697 cell.col--;
05698 }
05699 if( !bFoundVisible)
05700 return;
05701
05702 AutoSizeColumn(cell.col, GetAutoSizeStyle());
05703 Invalidate();
05704 }
05705 #ifdef _WIN32_WCE
05706 else if (MouseOverRowResizeArea(point))
05707 #else
05708 else if (m_MouseMode == MOUSE_OVER_ROW_DIVIDE)
05709 #endif
05710 {
05711 CPoint start;
05712 if (!GetCellOrigin(0, cell.col, &start))
05713 return;
05714
05715 if (point.y - start.y < m_nResizeCaptureRange)
05716 cell.row--;
05717
05718
05719 BOOL bFoundVisible = FALSE;
05720 while( cell.row >= 0)
05721 {
05722 if( GetRowHeight( cell.row) > 0)
05723 {
05724 bFoundVisible = TRUE;
05725 break;
05726 }
05727 cell.row--;
05728 }
05729 if( !bFoundVisible)
05730 return;
05731
05732 AutoSizeRow(cell.row);
05733 Invalidate();
05734 }
05735 else if (m_MouseMode == MOUSE_NOTHING)
05736 {
05737 CPoint pointClickedRel;
05738 pointClickedRel = GetPointClicked( cell.row, cell.col, point);
05739
05740 CGridCellBase* pCell = NULL;
05741 if (IsValid(cell))
05742 pCell = GetCell(cell.row, cell.col);
05743
05744
05745 BOOL bInTextArea = FALSE;
05746 if (pCell)
05747 {
05748 CRect rectCell;
05749 if (GetCellRect(cell.row, cell.col, rectCell) && pCell->GetTextRect(rectCell))
05750 bInTextArea = rectCell.PtInRect(point);
05751 }
05752
05753 if (cell.row >= m_nFixedRows && IsValid(m_LeftClickDownCell) &&
05754 cell.col >= m_nFixedCols && bInTextArea)
05755 {
05756 OnEditCell(cell.row, cell.col, pointClickedRel, VK_LBUTTON);
05757 }
05758 else if (m_bListMode)
05759 {
05760 if (!IsValid(cell))
05761 return;
05762 if (cell.row >= m_nFixedRows && cell.col >= m_nFixedCols && bInTextArea)
05763 OnEditCell(cell.row, cell.col, pointClickedRel, VK_LBUTTON);
05764 }
05765
05766 if (IsValid(cell))
05767 {
05768 CGridCellBase* pCell = GetCell(cell.row, cell.col);
05769 if (pCell)
05770 pCell->OnDblClick(pointClickedRel);
05771 SendMessageToParent(cell.row, cell.col, NM_DBLCLK);
05772 }
05773 }
05774
05775 CWnd::OnLButtonDblClk(nFlags, point);
05776 }
05777
05778 void CGridCtrl::OnLButtonDown(UINT nFlags, CPoint point)
05779 {
05780 #ifdef GRIDCONTROL_USE_TITLETIPS
05781
05782 m_TitleTip.Hide();
05783 #endif
05784
05785
05786
05787
05788 SetFocus();
05789
05790 m_bLMouseButtonDown = TRUE;
05791 m_LeftClickDownPoint = point;
05792 m_LeftClickDownCell = GetCellFromPt(point);
05793 if (!IsValid(m_LeftClickDownCell))
05794 return;
05795
05796
05797
05798
05799
05800 if ((nFlags & MK_SHIFT) != MK_SHIFT)
05801 m_SelectionStartCell = m_LeftClickDownCell;
05802 else
05803 {
05804 if (!IsValid(m_SelectionStartCell))
05805 m_SelectionStartCell = m_idCurrentCell;
05806 }
05807
05808 EndEditing();
05809
05810
05811 CGridCellBase* pCell = GetCell(m_LeftClickDownCell.row, m_LeftClickDownCell.col);
05812 if (pCell)
05813 pCell->OnClickDown(GetPointClicked( m_LeftClickDownCell.row, m_LeftClickDownCell.col, point));
05814
05815
05816 BOOL bInTextArea = FALSE;
05817 if (pCell)
05818 {
05819 CRect rectCell;
05820 if (GetCellRect(m_LeftClickDownCell.row, m_LeftClickDownCell.col, rectCell) &&
05821 pCell->GetTextRect(rectCell))
05822 {
05823 bInTextArea = rectCell.PtInRect(point);
05824 }
05825 }
05826
05827
05828
05829 if (m_LeftClickDownCell == m_idCurrentCell &&
05830 !(nFlags & MK_CONTROL) && bInTextArea &&
05831 IsCellEditable(m_LeftClickDownCell))
05832 {
05833 m_MouseMode = MOUSE_PREPARE_EDIT;
05834 return;
05835 }
05836
05837
05838 else if (IsCellSelected(m_LeftClickDownCell))
05839 {
05840
05841 if (nFlags & MK_CONTROL)
05842 {
05843 SetFocusCell(m_LeftClickDownCell);
05844 if (GetListMode())
05845 SelectRows(m_LeftClickDownCell, TRUE, FALSE);
05846 else
05847 SelectCells(m_LeftClickDownCell, TRUE, FALSE);
05848 return;
05849 }
05850 #ifndef GRIDCONTROL_NO_DRAGDROP
05851 else if (m_bAllowDragAndDrop)
05852 m_MouseMode = MOUSE_PREPARE_DRAG;
05853 #endif
05854 }
05855 else if (m_MouseMode != MOUSE_OVER_COL_DIVIDE &&
05856 m_MouseMode != MOUSE_OVER_ROW_DIVIDE)
05857 {
05858 if (m_LeftClickDownCell.row >= GetFixedRowCount() &&
05859 m_LeftClickDownCell.col >= GetFixedColumnCount())
05860 {
05861 SetFocusCell(m_LeftClickDownCell.row, m_LeftClickDownCell.col);
05862 }
05863 else
05864 SetFocusCell(-1, -1);
05865
05866
05867
05868
05869
05870
05871 }
05872
05873 SetCapture();
05874
05875 if (m_MouseMode == MOUSE_NOTHING)
05876 {
05877 if (m_bAllowColumnResize && MouseOverColumnResizeArea(point))
05878 {
05879 if (m_MouseMode != MOUSE_OVER_COL_DIVIDE)
05880 {
05881 #ifndef _WIN32_WCE_NO_CURSOR
05882 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
05883 #endif
05884 m_MouseMode = MOUSE_OVER_COL_DIVIDE;
05885 }
05886 }
05887 else if (m_bAllowRowResize && MouseOverRowResizeArea(point))
05888 {
05889 if (m_MouseMode != MOUSE_OVER_ROW_DIVIDE)
05890 {
05891 #ifndef _WIN32_WCE_NO_CURSOR
05892 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
05893 #endif
05894 m_MouseMode = MOUSE_OVER_ROW_DIVIDE;
05895 }
05896 }
05897
05898
05899
05900
05901
05902 }
05903
05904 if (m_MouseMode == MOUSE_OVER_COL_DIVIDE)
05905 {
05906 m_MouseMode = MOUSE_SIZING_COL;
05907
05908
05909 if (GetColumnWidth(GetColumnCount()-1) < m_nResizeCaptureRange)
05910 {
05911 CRect VisRect;
05912 GetVisibleNonFixedCellRange(VisRect);
05913 if (abs(point.x - VisRect.right) < m_nResizeCaptureRange)
05914 m_LeftClickDownCell.col = GetColumnCount()-1;
05915 }
05916
05917 CPoint start;
05918 if (!GetCellOrigin(0, m_LeftClickDownCell.col, &start))
05919 return;
05920
05921 if( !m_bHiddenColUnhide)
05922 {
05923
05924 BOOL bLookForVisible = TRUE;
05925 BOOL bIsCellRightBorder = point.x - start.x >= m_nResizeCaptureRange;
05926
05927 if( bIsCellRightBorder
05928 && m_LeftClickDownCell.col + 1 >= GetColumnCount() )
05929 {
05930
05931
05932
05933 if( m_LeftClickDownCell.col >= 0)
05934 bLookForVisible = FALSE;
05935 }
05936
05937 if( bLookForVisible)
05938 {
05939
05940 BOOL bFoundVisible = FALSE;
05941 int iOffset = 1;
05942
05943 if( bIsCellRightBorder)
05944 iOffset = 0;
05945
05946 while( m_LeftClickDownCell.col - iOffset >= 0)
05947 {
05948 if( GetColumnWidth( m_LeftClickDownCell.col - iOffset) > 0)
05949 {
05950 bFoundVisible = TRUE;
05951 break;
05952 }
05953 m_LeftClickDownCell.col--;
05954 }
05955 if( !bFoundVisible)
05956 return;
05957 }
05958 }
05959
05960
05961 CRect rect;
05962 GetClientRect(rect);
05963 CRect invertedRect(point.x, rect.top, point.x + 2, rect.bottom);
05964
05965 CDC* pDC = GetDC();
05966 if (pDC)
05967 {
05968 pDC->InvertRect(&invertedRect);
05969 ReleaseDC(pDC);
05970 }
05971
05972
05973
05974
05975 if (point.x - start.x < m_nResizeCaptureRange)
05976 {
05977 if (m_LeftClickDownCell.col < GetColumnCount()-1 ||
05978 GetColumnWidth(GetColumnCount()-1) >= m_nResizeCaptureRange)
05979 {
05980 if (!GetCellOrigin(0, --m_LeftClickDownCell.col, &start))
05981 return;
05982 }
05983 }
05984
05985
05986
05987 int nMaxCellWidth = rect.Width()-GetFixedColumnWidth();
05988 rect.left = start.x + 1;
05989 rect.right = rect.left + nMaxCellWidth;
05990
05991 ClientToScreen(rect);
05992 #ifndef _WIN32_WCE_NO_CURSOR
05993 ClipCursor(rect);
05994 #endif
05995 }
05996 else if (m_MouseMode == MOUSE_OVER_ROW_DIVIDE)
05997 {
05998 m_MouseMode = MOUSE_SIZING_ROW;
05999
06000
06001 if (GetRowHeight(GetRowCount()-1) < m_nResizeCaptureRange)
06002 {
06003 CRect VisRect;
06004 GetVisibleNonFixedCellRange(VisRect);
06005 if (abs(point.y - VisRect.bottom) < m_nResizeCaptureRange)
06006 m_LeftClickDownCell.row = GetRowCount()-1;
06007 }
06008
06009 CPoint start;
06010 if (!GetCellOrigin(m_LeftClickDownCell, &start))
06011 return;
06012
06013 if( !m_bHiddenRowUnhide)
06014 {
06015
06016 BOOL bLookForVisible = TRUE;
06017 BOOL bIsCellBottomBorder = point.y - start.y >= m_nResizeCaptureRange;
06018
06019 if( bIsCellBottomBorder
06020 && m_LeftClickDownCell.row + 1 >= GetRowCount() )
06021 {
06022
06023
06024
06025 if( m_LeftClickDownCell.row >= 0)
06026 bLookForVisible = FALSE;
06027 }
06028
06029 if( bLookForVisible)
06030 {
06031
06032 BOOL bFoundVisible = FALSE;
06033 int iOffset = 1;
06034
06035 if( bIsCellBottomBorder)
06036 iOffset = 0;
06037
06038 while( m_LeftClickDownCell.row - iOffset >= 0)
06039 {
06040 if( GetRowHeight( m_LeftClickDownCell.row - iOffset) > 0)
06041 {
06042 bFoundVisible = TRUE;
06043 break;
06044 }
06045 m_LeftClickDownCell.row--;
06046 }
06047 if( !bFoundVisible)
06048 return;
06049 }
06050 }
06051
06052 CRect rect;
06053 GetClientRect(rect);
06054 CRect invertedRect(rect.left, point.y, rect.right, point.y + 2);
06055
06056 CDC* pDC = GetDC();
06057 if (pDC)
06058 {
06059 pDC->InvertRect(&invertedRect);
06060 ReleaseDC(pDC);
06061 }
06062
06063
06064
06065
06066 if (point.y - start.y < m_nResizeCaptureRange)
06067 {
06068 if (m_LeftClickDownCell.row < GetRowCount()-1 ||
06069 GetRowHeight(GetRowCount()-1) >= m_nResizeCaptureRange)
06070 {
06071 if (!GetCellOrigin(--m_LeftClickDownCell.row, 0, &start))
06072 return;
06073 }
06074 }
06075
06076 int nMaxCellHeight = rect.Height()-GetFixedRowHeight();
06077 rect.top = start.y + 1;
06078 rect.bottom = rect.top + nMaxCellHeight;
06079
06080 ClientToScreen(rect);
06081
06082 #ifndef _WIN32_WCE_NO_CURSOR
06083 ClipCursor(rect);
06084 #endif
06085 }
06086 else
06087 #ifndef GRIDCONTROL_NO_DRAGDROP
06088 if (m_MouseMode != MOUSE_PREPARE_DRAG)
06089 #endif
06090 {
06091 SendMessageToParent(m_LeftClickDownCell.row, m_LeftClickDownCell.col, GVN_SELCHANGING);
06092
06093
06094
06095 m_PrevSelectedCellMap.RemoveAll();
06096 if (nFlags & MK_CONTROL)
06097 {
06098 for (POSITION pos = m_SelectedCellMap.GetStartPosition(); pos != NULL; )
06099 {
06100 DWORD key;
06101 CCellID cell;
06102 m_SelectedCellMap.GetNextAssoc(pos, key, (CCellID&)cell);
06103 m_PrevSelectedCellMap.SetAt(key, cell);
06104 }
06105 }
06106
06107 if (m_LeftClickDownCell.row < GetFixedRowCount())
06108 OnFixedRowClick(m_LeftClickDownCell);
06109 else if (m_LeftClickDownCell.col < GetFixedColumnCount())
06110 OnFixedColumnClick(m_LeftClickDownCell);
06111 else
06112 {
06113 m_MouseMode = m_bListMode? MOUSE_SELECT_ROW : MOUSE_SELECT_CELLS;
06114 OnSelecting(m_LeftClickDownCell);
06115
06116 m_nTimerID = SetTimer(WM_LBUTTONDOWN, m_nTimerInterval, 0);
06117 }
06118 }
06119 m_LastMousePoint = point;
06120 }
06121
06122 void CGridCtrl::OnLButtonUp(UINT nFlags, CPoint point)
06123 {
06124
06125
06126 CWnd::OnLButtonUp(nFlags, point);
06127
06128 m_bLMouseButtonDown = FALSE;
06129
06130 #ifndef _WIN32_WCE_NO_CURSOR
06131 ClipCursor(NULL);
06132 #endif
06133
06134 if (GetCapture()->GetSafeHwnd() == GetSafeHwnd())
06135 {
06136 ReleaseCapture();
06137 KillTimer(m_nTimerID);
06138 m_nTimerID = 0;
06139 }
06140
06141 CPoint pointClickedRel;
06142 pointClickedRel = GetPointClicked( m_idCurrentCell.row, m_idCurrentCell.col, point);
06143
06144
06145
06146 if (m_MouseMode == MOUSE_PREPARE_EDIT)
06147 {
06148 OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, pointClickedRel, VK_LBUTTON);
06149 }
06150 #ifndef GRIDCONTROL_NO_DRAGDROP
06151
06152
06153 else if (m_MouseMode == MOUSE_PREPARE_DRAG)
06154 {
06155 CGridCellBase* pCell = GetCell(m_idCurrentCell.row, m_idCurrentCell.col);
06156 if (pCell)
06157 pCell->OnClick( GetPointClicked( m_idCurrentCell.row, m_idCurrentCell.col, point) );
06158 SendMessageToParent(m_LeftClickDownCell.row, m_LeftClickDownCell.col, NM_CLICK);
06159 SendMessageToParent(m_LeftClickDownCell.row, m_LeftClickDownCell.col, GVN_SELCHANGING);
06160 ResetSelectedRange();
06161 SendMessageToParent(m_idCurrentCell.row, m_idCurrentCell.col, GVN_SELCHANGED);
06162 }
06163 #endif
06164 else if (m_MouseMode == MOUSE_SIZING_COL)
06165 {
06166 CRect rect;
06167 GetClientRect(rect);
06168 CRect invertedRect(m_LastMousePoint.x, rect.top, m_LastMousePoint.x + 2, rect.bottom);
06169
06170 CDC* pDC = GetDC();
06171 if (pDC)
06172 {
06173 pDC->InvertRect(&invertedRect);
06174 ReleaseDC(pDC);
06175 }
06176
06177 if (m_LeftClickDownPoint != point && (point.x != 0 || point.y != 0))
06178 {
06179 CPoint start;
06180 if (!GetCellOrigin(m_LeftClickDownCell, &start))
06181 return;
06182
06183 int nColumnWidth = max(point.x - start.x, m_bAllowColHide? 0 : 1);
06184
06185 SetColumnWidth(m_LeftClickDownCell.col, nColumnWidth);
06186 ResetScrollBars();
06187 Invalidate();
06188 }
06189 }
06190 else if (m_MouseMode == MOUSE_SIZING_ROW)
06191 {
06192 CRect rect;
06193 GetClientRect(rect);
06194 CRect invertedRect(rect.left, m_LastMousePoint.y, rect.right, m_LastMousePoint.y + 2);
06195
06196 CDC* pDC = GetDC();
06197 if (pDC)
06198 {
06199 pDC->InvertRect(&invertedRect);
06200 ReleaseDC(pDC);
06201 }
06202
06203 if (m_LeftClickDownPoint != point && (point.x != 0 || point.y != 0))
06204 {
06205 CPoint start;
06206 if (!GetCellOrigin(m_LeftClickDownCell, &start))
06207 return;
06208
06209 int nRowHeight = max(point.y - start.y, m_bAllowRowHide? 0 : 1);
06210
06211 SetRowHeight(m_LeftClickDownCell.row, nRowHeight);
06212 ResetScrollBars();
06213 Invalidate();
06214 }
06215 }
06216 else
06217 {
06218 SendMessageToParent(m_idCurrentCell.row, m_idCurrentCell.col, GVN_SELCHANGED);
06219
06220 CGridCellBase* pCell = GetCell(m_idCurrentCell.row, m_idCurrentCell.col);
06221 if (pCell)
06222 pCell->OnClick( GetPointClicked( m_idCurrentCell.row, m_idCurrentCell.col, point) );
06223 SendMessageToParent(m_LeftClickDownCell.row, m_LeftClickDownCell.col, NM_CLICK);
06224 }
06225
06226 m_MouseMode = MOUSE_NOTHING;
06227
06228 #ifndef _WIN32_WCE_NO_CURSOR
06229 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
06230 #endif
06231
06232 if (!IsValid(m_LeftClickDownCell))
06233 return;
06234
06235 CWnd *pOwner = GetOwner();
06236 if (pOwner && IsWindow(pOwner->m_hWnd))
06237 pOwner->PostMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_CLICKED),
06238 (LPARAM) GetSafeHwnd());
06239 }
06240
06241 #ifndef _WIN32_WCE
06242 void CGridCtrl::OnRButtonDown(UINT nFlags, CPoint point)
06243 {
06244 CWnd::OnRButtonDown(nFlags, point);
06245 m_bRMouseButtonDown = TRUE;
06246
06247 #ifdef GRIDCONTROL_USE_TITLETIPS
06248 TRACE0("Hiding TitleTip\n");
06249 m_TitleTip.Hide();
06250 #endif
06251 }
06252
06253
06254
06255 void CGridCtrl::OnRButtonUp(UINT nFlags, CPoint point)
06256 {
06257 CWnd::OnRButtonUp(nFlags, point);
06258
06259 m_bRMouseButtonDown = FALSE;
06260
06261 CCellID FocusCell;
06262 FocusCell = GetCellFromPt(point);
06263
06264 EndEditing();
06265
06266
06267 if(!IsValid(FocusCell))
06268 SendMessageToParent(-1, -1, NM_RCLICK);
06269 else
06270 {
06271 SetFocusCell(-1,-1);
06272 SetFocusCell(max(FocusCell.row, m_nFixedRows),
06273 max(FocusCell.col, m_nFixedCols));
06274
06275
06276 CGridCellBase* pCell = GetCell(FocusCell.row, FocusCell.col);
06277 if (pCell)
06278 pCell->OnRClick( GetPointClicked( FocusCell.row, FocusCell.col, point) );
06279
06280 SendMessageToParent(FocusCell.row, FocusCell.col, NM_RCLICK);
06281 }
06282 }
06283 #endif
06284
06285 #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
06286
06287
06288
06289
06290 void CGridCtrl::SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight,
06291 int nLeftMargin, int nRightMargin, int nTopMargin,
06292 int nBottomMargin, int nGap)
06293 {
06294
06295 if(nHeaderHeight > -1)
06296 m_nHeaderHeight = nHeaderHeight;
06297 if(nFooterHeight > -1)
06298 m_nFooterHeight = nFooterHeight;
06299 if(nLeftMargin > -1)
06300 m_nLeftMargin = nLeftMargin;
06301 if(nRightMargin > -1)
06302 m_nRightMargin = nRightMargin;
06303 if(nTopMargin > -1)
06304 m_nTopMargin = nTopMargin;
06305 if(nBottomMargin > -1)
06306 m_nBottomMargin = nBottomMargin;
06307 if(nGap > -1)
06308 m_nGap = nGap;
06309 }
06310
06311 void CGridCtrl::GetPrintMarginInfo(int &nHeaderHeight, int &nFooterHeight,
06312 int &nLeftMargin, int &nRightMargin, int &nTopMargin,
06313 int &nBottomMargin, int &nGap)
06314 {
06315 nHeaderHeight = m_nHeaderHeight;
06316 nFooterHeight = m_nFooterHeight;
06317 nLeftMargin = m_nLeftMargin;
06318 nRightMargin = m_nRightMargin;
06319 nTopMargin = m_nTopMargin;
06320 nBottomMargin = m_nBottomMargin;
06321 nGap = m_nGap;
06322 }
06323
06324 void CGridCtrl::Print(CPrintDialog* pPrntDialog )
06325 {
06326 CDC dc;
06327
06328 if (pPrntDialog == NULL)
06329 {
06330 CPrintDialog printDlg(FALSE);
06331 if (printDlg.DoModal() != IDOK)
06332 return;
06333
06334 dc.Attach(printDlg.GetPrinterDC());
06335 }
06336 else
06337 dc.Attach(pPrntDialog->GetPrinterDC());
06338
06339 dc.m_bPrinting = TRUE;
06340
06341 CString strTitle;
06342 strTitle.LoadString(AFX_IDS_APP_TITLE);
06343
06344 if( strTitle.IsEmpty() )
06345 {
06346 CWnd *pParentWnd = GetParent();
06347 while (pParentWnd)
06348 {
06349 pParentWnd->GetWindowText(strTitle);
06350 if (strTitle.GetLength())
06351 break;
06352 pParentWnd = pParentWnd->GetParent();
06353 }
06354 }
06355
06356 DOCINFO di;
06357 memset(&di, 0, sizeof (DOCINFO));
06358 di.cbSize = sizeof (DOCINFO);
06359 di.lpszDocName = strTitle;
06360
06361 BOOL bPrintingOK = dc.StartDoc(&di);
06362
06363 CPrintInfo Info;
06364 Info.m_rectDraw.SetRect(0,0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES));
06365
06366 OnBeginPrinting(&dc, &Info);
06367 for (UINT page = Info.GetMinPage(); page <= Info.GetMaxPage() && bPrintingOK; page++)
06368 {
06369 dc.StartPage();
06370 Info.m_nCurPage = page;
06371 OnPrint(&dc, &Info);
06372 bPrintingOK = (dc.EndPage() > 0);
06373 }
06374 OnEndPrinting(&dc, &Info);
06375
06376 if (bPrintingOK)
06377 dc.EndDoc();
06378 else
06379 dc.AbortDoc();
06380
06381 dc.Detach();
06382 }
06383
06385
06386
06387
06388
06389 void CGridCtrl::OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo)
06390 {
06391
06392
06393
06394
06395
06396
06397
06398
06399
06400 ASSERT(pDC && pInfo);
06401 if (!pDC || !pInfo) return;
06402
06403
06404 CDC *pCurrentDC = GetDC();
06405 if (!pCurrentDC) return;
06406
06407 CSize PaperPixelsPerInch(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY));
06408 CSize ScreenPixelsPerInch(pCurrentDC->GetDeviceCaps(LOGPIXELSX), pCurrentDC->GetDeviceCaps(LOGPIXELSY));
06409
06410
06411 int nFontSize = -10;
06412 CString strFontName = "Arial";
06413 m_PrinterFont.CreateFont(nFontSize, 0,0,0, FW_NORMAL, 0,0,0, DEFAULT_CHARSET,
06414 OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
06415 DEFAULT_PITCH | FF_DONTCARE, strFontName);
06416
06417 CFont *pOldFont = pDC->SelectObject(&m_PrinterFont);
06418
06419
06420 m_CharSize = pDC->GetTextExtent(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSATUVWXYZ"),52);
06421 m_CharSize.cx /= 52;
06422 int nMargins = (m_nLeftMargin+m_nRightMargin)*m_CharSize.cx;
06423
06424
06425 m_PaperSize = CSize(pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
06426
06427 if( m_bWysiwygPrinting)
06428 {
06429 m_LogicalPageSize.cx = ScreenPixelsPerInch.cx * m_PaperSize.cx / PaperPixelsPerInch.cx * 3 / 4;
06430 m_LogicalPageSize.cy = ScreenPixelsPerInch.cy * m_PaperSize.cy / PaperPixelsPerInch.cy * 3 / 4;
06431 }
06432 else
06433 {
06434 m_PaperSize = CSize(pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
06435
06436 m_LogicalPageSize.cx = GetVirtualWidth()+nMargins;
06437 #ifdef _WIN32_WCE
06438 m_LogicalPageSize.cy = (m_LogicalPageSize.cx * m_PaperSize.cy) / m_PaperSize.cx;
06439 #else
06440 m_LogicalPageSize.cy = MulDiv(m_LogicalPageSize.cx, m_PaperSize.cy, m_PaperSize.cx);
06441 #endif
06442 }
06443
06444 m_nPageHeight = m_LogicalPageSize.cy - GetFixedRowHeight()
06445 - (m_nHeaderHeight+m_nFooterHeight + 2*m_nGap)*m_CharSize.cy;
06446
06447
06448 int nTotalRowHeight = 0;
06449 m_nNumPages = 1;
06450 for (int row = GetFixedRowCount(); row < GetRowCount(); row++)
06451 {
06452 nTotalRowHeight += GetRowHeight(row);
06453 if (nTotalRowHeight > m_nPageHeight) {
06454 m_nNumPages++;
06455 nTotalRowHeight = GetRowHeight(row);
06456 }
06457 }
06458
06459
06460
06461 int iColumnOffset = 0;
06462 int i1;
06463 for( i1=0; i1 < GetFixedColumnCount(); i1++)
06464 {
06465 iColumnOffset += GetColumnWidth( i1);
06466 }
06467 m_nPageWidth = m_LogicalPageSize.cx - iColumnOffset
06468 - nMargins;
06469 m_nPageMultiplier = 1;
06470
06471 if( m_bWysiwygPrinting)
06472 {
06473 int iTotalRowWidth = 0;
06474 for( i1 = GetFixedColumnCount(); i1 < GetColumnCount(); i1++)
06475 {
06476 iTotalRowWidth += GetColumnWidth( i1);
06477 if( iTotalRowWidth > m_nPageWidth)
06478 {
06479 m_nPageMultiplier++;
06480 iTotalRowWidth = GetColumnWidth( i1);
06481 }
06482 }
06483 m_nNumPages *= m_nPageMultiplier;
06484 }
06485
06486
06487 pInfo->SetMaxPage(m_nNumPages);
06488 pInfo->m_nCurPage = 1;
06489
06490 ReleaseDC(pCurrentDC);
06491 pDC->SelectObject(pOldFont);
06492 }
06493
06494 void CGridCtrl::OnPrint(CDC *pDC, CPrintInfo *pInfo)
06495 {
06496 if (!pDC || !pInfo)
06497 return;
06498
06499
06500 CFont *pOldFont = pDC->SelectObject(&m_PrinterFont);
06501
06502
06503 pDC->SetMapMode(MM_ANISOTROPIC);
06504 pDC->SetWindowExt(m_LogicalPageSize);
06505 pDC->SetViewportExt(m_PaperSize);
06506 pDC->SetWindowOrg(-m_nLeftMargin * m_CharSize.cx, 0);
06507
06508
06509 pInfo->m_rectDraw.top = 0;
06510 pInfo->m_rectDraw.left = 0;
06511 pInfo->m_rectDraw.right = m_LogicalPageSize.cx - (m_nLeftMargin + m_nRightMargin) * m_CharSize.cx;
06512 pInfo->m_rectDraw.bottom = m_nHeaderHeight * m_CharSize.cy;
06513 PrintHeader(pDC, pInfo);
06514 pDC->OffsetWindowOrg(0, -m_nHeaderHeight * m_CharSize.cy);
06515
06516
06517 pDC->OffsetWindowOrg(0, -m_nGap * m_CharSize.cy);
06518
06519 pDC->OffsetWindowOrg(0, -GetFixedRowHeight());
06520
06521
06522 int nTotalRowHeight = 0;
06523 UINT nNumPages = 1;
06524 m_nCurrPrintRow = GetFixedRowCount();
06525
06526
06527
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538 int iPageIfIgnoredWideCols = pInfo->m_nCurPage / m_nPageMultiplier;
06539 int iWideColPageOffset = pInfo->m_nCurPage - ( iPageIfIgnoredWideCols * m_nPageMultiplier);
06540 if( iWideColPageOffset > 0)
06541 iPageIfIgnoredWideCols++;
06542
06543 if( iWideColPageOffset == 0)
06544 iWideColPageOffset = m_nPageMultiplier;
06545 iWideColPageOffset--;
06546
06547
06548 while( m_nCurrPrintRow < GetRowCount()
06549 && (int)nNumPages < iPageIfIgnoredWideCols)
06550 {
06551 nTotalRowHeight += GetRowHeight(m_nCurrPrintRow);
06552 if (nTotalRowHeight > m_nPageHeight) {
06553 nNumPages++;
06554 if ((int)nNumPages == iPageIfIgnoredWideCols) break;
06555 nTotalRowHeight = GetRowHeight(m_nCurrPrintRow);
06556 }
06557 m_nCurrPrintRow++;
06558 }
06559
06560 m_nPrintColumn = GetFixedColumnCount();
06561 int iTotalRowWidth = 0;
06562 int i1, i2;
06563
06564
06565 for( i1 = 0; i1 < iWideColPageOffset; i1++)
06566 {
06567 for( i2 = m_nPrintColumn; i2 < GetColumnCount(); i2++)
06568 {
06569 iTotalRowWidth += GetColumnWidth( i2);
06570 if( iTotalRowWidth > m_nPageWidth)
06571 {
06572 m_nPrintColumn = i2;
06573 iTotalRowWidth = 0;
06574 break;
06575 }
06576 }
06577 }
06578
06579
06580 PrintRowButtons( pDC, pInfo);
06581 int iColumnOffset = 0;
06582 for( i1=0; i1 < GetFixedColumnCount(); i1++)
06583 {
06584 iColumnOffset += GetColumnWidth( i1);
06585 }
06586
06587
06588 pInfo->m_rectDraw.bottom = GetFixedRowHeight();
06589
06590 if( m_nPrintColumn == GetFixedColumnCount())
06591 {
06592
06593
06594 pDC->OffsetWindowOrg( 0, +GetFixedRowHeight());
06595
06596 m_nPageWidth += iColumnOffset;
06597 m_nPrintColumn = 0;
06598 PrintColumnHeadings(pDC, pInfo);
06599 m_nPageWidth -= iColumnOffset;
06600 m_nPrintColumn = GetFixedColumnCount();
06601
06602 pDC->OffsetWindowOrg( -iColumnOffset, -GetFixedRowHeight());
06603 }
06604 else
06605 {
06606
06607 pDC->OffsetWindowOrg( 0, +GetFixedRowHeight());
06608
06609 m_nPageWidth += iColumnOffset;
06610
06611
06612 PrintColumnHeadings(pDC, pInfo);
06613
06614 m_nPageWidth -= iColumnOffset;
06615
06616 pDC->OffsetWindowOrg( -iColumnOffset, -GetFixedRowHeight());
06617 }
06618
06619
06620 if (m_nCurrPrintRow >= GetRowCount()) return;
06621
06622
06623
06624
06625
06626
06627 BOOL bFirstPrintedRow = TRUE;
06628 CRect rect;
06629 rect.bottom = -1;
06630 while (m_nCurrPrintRow < GetRowCount())
06631 {
06632 rect.top = rect.bottom+1;
06633 rect.bottom = rect.top + GetRowHeight(m_nCurrPrintRow) - 1;
06634
06635 if (rect.bottom > m_nPageHeight) break;
06636
06637 rect.right = -1;
06638
06639
06640 for (int col = m_nPrintColumn; col < GetColumnCount(); col++)
06641 {
06642 rect.left = rect.right+1;
06643 rect.right = rect.left
06644 + GetColumnWidth( col)
06645 - 1;
06646
06647 if( rect.right > m_nPageWidth)
06648 break;
06649
06650 CGridCellBase* pCell = GetCell(m_nCurrPrintRow, col);
06651 if (pCell)
06652 pCell->PrintCell(pDC, m_nCurrPrintRow, col, rect);
06653
06654 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
06655 {
06656 int Overlap = (col == 0)? 0:1;
06657 pDC->MoveTo(rect.left-Overlap, rect.bottom);
06658 pDC->LineTo(rect.right, rect.bottom);
06659 if (m_nCurrPrintRow == 0) {
06660 pDC->MoveTo(rect.left-Overlap, rect.top);
06661 pDC->LineTo(rect.right, rect.top);
06662 }
06663 }
06664 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
06665 {
06666 int Overlap = (bFirstPrintedRow)? 0:1;
06667 pDC->MoveTo(rect.right, rect.top-Overlap);
06668 pDC->LineTo(rect.right, rect.bottom);
06669 if (col == 0) {
06670 pDC->MoveTo(rect.left, rect.top-Overlap);
06671 pDC->LineTo(rect.left, rect.bottom);
06672 }
06673 }
06674
06675 }
06676 m_nCurrPrintRow++;
06677 bFirstPrintedRow = FALSE;
06678 }
06679
06680
06681
06682 pInfo->m_rectDraw.bottom = m_nFooterHeight * m_CharSize.cy;
06683 pDC->SetWindowOrg( -m_nLeftMargin * m_CharSize.cx,
06684 -m_LogicalPageSize.cy + m_nFooterHeight * m_CharSize.cy);
06685 PrintFooter(pDC, pInfo);
06686
06687
06688 pDC->SetWindowOrg(0,0);
06689
06690 pDC->SelectObject(pOldFont);
06691 }
06692
06693
06694
06695 void CGridCtrl::PrintFixedRowCells(int nStartColumn, int nStopColumn, int& row, CRect& rect,
06696 CDC *pDC, BOOL& bFirst)
06697 {
06698
06699 for (int col =nStartColumn; col < nStopColumn; col++)
06700 {
06701 rect.left = rect.right+1;
06702 rect.right = rect.left + GetColumnWidth( col) - 1;
06703
06704 if( rect.right > m_nPageWidth)
06705 break;
06706
06707 CGridCellBase* pCell = GetCell(row, col);
06708 if (pCell)
06709 pCell->PrintCell(pDC, row, col, rect);
06710
06711 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
06712 {
06713 int Overlap = (col == 0)? 0:1;
06714
06715 pDC->MoveTo(rect.left-Overlap, rect.bottom);
06716 pDC->LineTo(rect.right, rect.bottom);
06717
06718 if (row == 0)
06719 {
06720 pDC->MoveTo(rect.left-Overlap, rect.top);
06721 pDC->LineTo(rect.right, rect.top);
06722 }
06723 }
06724
06725 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
06726 {
06727 int Overlap = (row == 0)? 0:1;
06728
06729 pDC->MoveTo(rect.right, rect.top-Overlap);
06730 pDC->LineTo(rect.right, rect.bottom);
06731
06732 if( bFirst)
06733 {
06734 pDC->MoveTo(rect.left-1, rect.top-Overlap);
06735 pDC->LineTo(rect.left-1, rect.bottom);
06736 bFirst = FALSE;
06737 }
06738
06739 }
06740
06741 }
06742
06743
06744 }
06745
06746 void CGridCtrl::PrintColumnHeadings(CDC *pDC, CPrintInfo* )
06747 {
06748 CFont *pOldFont = pDC->SelectObject(&m_PrinterFont);
06749
06750 CRect rect;
06751 rect.bottom = -1;
06752
06753 BOOL bFirst = TRUE;
06754 BOOL bOriginal;
06755
06756
06757
06758 for (int row = 0; row < GetFixedRowCount(); row++)
06759 {
06760 rect.top = rect.bottom+1;
06761 rect.bottom = rect.top + GetRowHeight(row) - 1;
06762
06763 rect.right = -1;
06764
06765
06766
06767
06768 if(m_nPrintColumn>= GetFixedColumnCount())
06769 {
06770 bOriginal=bFirst;
06771
06772 PrintFixedRowCells(0,GetFixedColumnCount(), row, rect, pDC, bFirst);
06773 bFirst=bOriginal;
06774 }
06775
06776
06777 PrintFixedRowCells(m_nPrintColumn, GetColumnCount(), row, rect, pDC, bFirst);
06778
06779 }
06780
06781 pDC->SelectObject(pOldFont);
06782 }
06783
06784
06785
06786
06787
06788
06789
06790
06791 void CGridCtrl::PrintRowButtons(CDC *pDC, CPrintInfo* )
06792 {
06793 CFont *pOldFont = pDC->SelectObject(&m_PrinterFont);
06794
06795 CRect rect;
06796 rect.right = -1;
06797
06798 BOOL bFirst = TRUE;
06799 for( int iCol = 0; iCol < GetFixedColumnCount(); iCol++)
06800 {
06801 rect.left = rect.right+1;
06802 rect.right = rect.left
06803 + GetColumnWidth( iCol)
06804 - 1;
06805
06806 rect.bottom = -1;
06807 for( int iRow = m_nCurrPrintRow; iRow < GetRowCount(); iRow++)
06808 {
06809 rect.top = rect.bottom+1;
06810 rect.bottom = rect.top + GetRowHeight( iRow) - 1;
06811
06812 if( rect.bottom > m_nPageHeight)
06813 break;
06814
06815 CGridCellBase* pCell = GetCell(iRow, iCol);
06816 if (pCell)
06817 pCell->PrintCell(pDC, iRow, iCol, rect);
06818
06819 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
06820 {
06821 int Overlap = (iCol == 0)? 0:1;
06822 pDC->MoveTo(rect.left-Overlap, rect.bottom);
06823 pDC->LineTo(rect.right, rect.bottom);
06824 if( bFirst) {
06825 pDC->MoveTo(rect.left-Overlap, rect.top-1);
06826 pDC->LineTo(rect.right, rect.top-1);
06827 bFirst = FALSE;
06828 }
06829 }
06830 if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
06831 {
06832 int Overlap = (iRow == 0)? 0:1;
06833 pDC->MoveTo(rect.right, rect.top-Overlap);
06834 pDC->LineTo(rect.right, rect.bottom);
06835 if (iCol == 0) {
06836 pDC->MoveTo(rect.left, rect.top-Overlap);
06837 pDC->LineTo(rect.left, rect.bottom);
06838 }
06839 }
06840
06841 }
06842 }
06843 pDC->SelectObject(pOldFont);
06844 }
06845
06846 void CGridCtrl::PrintHeader(CDC *pDC, CPrintInfo *pInfo)
06847 {
06848
06849 CString strRight;
06850 strRight.LoadString(AFX_IDS_APP_TITLE);
06851
06852
06853 CString strCenter;
06854 CWnd *pParentWnd = GetParent();
06855 while (pParentWnd)
06856 {
06857 pParentWnd->GetWindowText(strCenter);
06858 if (strCenter.GetLength())
06859 break;
06860 pParentWnd = pParentWnd->GetParent();
06861 }
06862
06863 CFont BoldFont;
06864 LOGFONT lf;
06865
06866
06867 VERIFY(m_PrinterFont.GetLogFont(&lf));
06868 lf.lfWeight = FW_BOLD;
06869 VERIFY(BoldFont.CreateFontIndirect(&lf));
06870
06871 CFont *pNormalFont = pDC->SelectObject(&BoldFont);
06872 int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
06873
06874 CRect rc(pInfo->m_rectDraw);
06875 if( !strCenter.IsEmpty() )
06876 pDC->DrawText( strCenter, &rc, DT_CENTER | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER);
06877 if( !strRight.IsEmpty() )
06878 pDC->DrawText( strRight, &rc, DT_RIGHT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER);
06879
06880 pDC->SetBkMode(nPrevBkMode);
06881 pDC->SelectObject(pNormalFont);
06882 BoldFont.DeleteObject();
06883
06884
06885 pDC->SelectStockObject(BLACK_PEN);
06886 pDC->MoveTo(rc.left, rc.bottom);
06887 pDC->LineTo(rc.right, rc.bottom);
06888 }
06889
06890
06891 void CGridCtrl::PrintFooter(CDC *pDC, CPrintInfo *pInfo)
06892 {
06893
06894 CString strLeft;
06895 strLeft.Format(_T("Page %d of %d"), pInfo->m_nCurPage, pInfo->GetMaxPage() );
06896
06897
06898 CString strRight;
06899 COleDateTime t = COleDateTime::GetCurrentTime();
06900 strRight = t.Format(_T("%c"));
06901
06902 CRect rc(pInfo->m_rectDraw);
06903
06904
06905 pDC->SelectStockObject(BLACK_PEN);
06906 pDC->MoveTo(rc.left, rc.top);
06907 pDC->LineTo(rc.right, rc.top);
06908
06909 CFont BoldFont;
06910 LOGFONT lf;
06911
06912
06913 m_PrinterFont.GetLogFont(&lf);
06914 lf.lfWeight = FW_BOLD;
06915 BoldFont.CreateFontIndirect(&lf);
06916
06917 CFont *pNormalFont = pDC->SelectObject(&BoldFont);
06918 int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
06919
06920
06921
06922 pDC->SetTextColor(RGB(0, 0, 0));
06923
06924 if( !strLeft.IsEmpty() )
06925 pDC->DrawText( strLeft, &rc, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER);
06926 if( !strRight.IsEmpty() )
06927 pDC->DrawText( strRight, &rc, DT_RIGHT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER);
06928
06929 pDC->SetBkMode(nPrevBkMode);
06930 pDC->SelectObject(pNormalFont);
06931 BoldFont.DeleteObject();
06932 }
06933
06934 void CGridCtrl::OnEndPrinting(CDC* , CPrintInfo* )
06935 {
06936 m_PrinterFont.DeleteObject();
06937 }
06938
06939 #endif // !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
06940
06941
06942 #ifndef _WIN32_WCE
06943
06944
06945
06946 BOOL CGridCtrl::Save(LPCTSTR filename, TCHAR chSeparator)
06947 {
06948 CStdioFile File;
06949 CFileException ex;
06950 CString strSeparator(chSeparator);
06951
06952 if (!File.Open(filename, CFile::modeWrite | CFile::modeCreate| CFile::typeText, &ex))
06953 {
06954 ex.ReportError();
06955 return FALSE;
06956 }
06957
06958 TRY
06959 {
06960 int nNumColumns = GetColumnCount();
06961 for (int i = 0; i < GetRowCount(); i++)
06962 {
06963 for (int j = 0; j < nNumColumns; j++)
06964 {
06965 File.WriteString(GetItemText(i,j));
06966 File.WriteString((j==(nNumColumns-1))? _T("\n"): strSeparator);
06967 }
06968 }
06969
06970 File.Close();
06971 }
06972
06973 CATCH (CFileException, e)
06974 {
06975 AfxMessageBox(_T("Unable to save grid list"));
06976 return FALSE;
06977 }
06978 END_CATCH
06979
06980 return TRUE;
06981 }
06982
06983 BOOL CGridCtrl::Load(LPCTSTR filename, TCHAR chSeparator)
06984 {
06985 if (GetVirtualMode())
06986 return FALSE;
06987
06988 TCHAR *token, *end;
06989 TCHAR buffer[1024];
06990 CStdioFile File;
06991 CFileException ex;
06992
06993 if (!File.Open(filename, CFile::modeRead | CFile::typeText))
06994 {
06995 ex.ReportError();
06996 return FALSE;
06997 }
06998
06999 DeleteAllItems();
07000
07001 TRY
07002 {
07003
07004 File.ReadString(buffer, 1024);
07005
07006
07007 for (token=buffer, end=buffer;
07008 *end && (*end != chSeparator) && (*end != _T('\n'));
07009 end++)
07010 ;
07011
07012 if ((*end == _T('\0')) && (token == end))
07013 token = NULL;
07014
07015 *end = _T('\0');
07016
07017 while (token)
07018 {
07019 InsertColumn(token);
07020
07021
07022 for (token=++end; *end && (*end != chSeparator) && (*end != _T('\n'));
07023 end++)
07024 ;
07025
07026 if ((*end == _T('\0')) && (token == end))
07027 token = NULL;
07028
07029 *end = _T('\0');
07030 }
07031
07032
07033 int nItem = 0;
07034 while (File.ReadString(buffer, 1024))
07035 {
07036
07037 for (token=buffer, end=buffer;
07038 *end && (*end != chSeparator) && (*end != _T('\n')); end++)
07039 ;
07040
07041 if ((*end == _T('\0')) && (token == end))
07042 token = NULL;
07043
07044 *end = _T('\0');
07045
07046 int nSubItem = 0;
07047 while (token)
07048 {
07049 if (!nSubItem)
07050 InsertRow(token);
07051 else
07052 SetItemText(nItem, nSubItem, token);
07053
07054
07055 for (token=++end; *end && (*end != chSeparator) && (*end != _T('\n'));
07056 end++)
07057 ;
07058
07059 if ((*end == _T('\0')) && (token == end))
07060 token = NULL;
07061
07062 *end = _T('\0');
07063
07064 nSubItem++;
07065 }
07066 nItem++;
07067 }
07068
07069 AutoSizeColumns(GetAutoSizeStyle());
07070 File.Close();
07071 }
07072
07073 CATCH (CFileException, e)
07074 {
07075 AfxMessageBox(_T("Unable to load grid data"));
07076 return FALSE;
07077 }
07078 END_CATCH
07079
07080 return TRUE;
07081 }
07082 #endif
07083
07085
07086
07087 #ifndef GRIDCONTROL_NO_DRAGDROP
07088
07089
07090 CImageList* CGridCtrl::CreateDragImage(CPoint *pHotSpot)
07091 {
07092 CDC* pDC = GetDC();
07093 if (!pDC)
07094 return NULL;
07095
07096 CRect rect;
07097 CCellID cell = GetFocusCell();
07098 if (!GetCellRect(cell.row, cell.col, rect))
07099 return NULL;
07100
07101
07102 rect.BottomRight() = CPoint(rect.Width(), rect.Height());
07103 rect.TopLeft() = CPoint(0, 0);
07104 *pHotSpot = rect.BottomRight();
07105
07106
07107
07108 CImageList* pList = new CImageList;
07109 if (!pList || !pList->Create(rect.Width(), rect.Height(), ILC_MASK, 1, 1))
07110 {
07111 if (pList)
07112 delete pList;
07113 return NULL;
07114 }
07115
07116
07117 CDC MemDC;
07118 CBitmap bm;
07119 MemDC.CreateCompatibleDC(pDC);
07120 bm.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
07121 CBitmap* pOldBitmap = MemDC.SelectObject(&bm);
07122 MemDC.SetWindowOrg(0, 0);
07123
07124
07125 CGridCellBase* pCell = GetCell(cell.row, cell.col);
07126 if (pCell)
07127 pCell->Draw(&MemDC, cell.row, cell.col, rect, FALSE);
07128
07129
07130 MemDC.SelectObject(pOldBitmap);
07131 ReleaseDC(pDC);
07132
07133
07134 pList->Add(&bm, GetDefaultCell(FALSE, FALSE)->GetBackClr());
07135 bm.DeleteObject();
07136
07137 return pList;
07138 }
07139 #endif
07140
07141 void CGridCtrl::OnFixedRowClick(CCellID& cell)
07142 {
07143 if (!IsValid(cell))
07144 return;
07145
07146 if (GetHeaderSort())
07147 {
07148 CWaitCursor waiter;
07149 if (cell.col == GetSortColumn())
07150 SortItems(cell.col, !GetSortAscending());
07151 else
07152 SortItems(cell.col, TRUE);
07153 Invalidate();
07154 }
07155
07156
07157
07158 if (GetFixedColumnSelection())
07159 {
07160 if (cell.col < GetFixedColumnCount())
07161 {
07162 m_MouseMode = MOUSE_SELECT_ALL;
07163 OnSelecting(cell);
07164 }
07165 else
07166 {
07167 m_MouseMode = MOUSE_SELECT_COL;
07168 OnSelecting(cell);
07169 }
07170 }
07171 }
07172
07173 void CGridCtrl::OnFixedColumnClick(CCellID& cell)
07174 {
07175 if (!IsValid(cell))
07176 return;
07177
07178
07179
07180
07181
07182
07183
07184
07185
07186 if (GetFixedRowSelection())
07187 {
07188 if (cell.row < GetFixedRowCount())
07189 {
07190 m_MouseMode = MOUSE_SELECT_ALL;
07191 OnSelecting(cell);
07192 }
07193 else
07194 {
07195 m_MouseMode = MOUSE_SELECT_ROW;
07196 OnSelecting(cell);
07197 }
07198 }
07199 }
07200
07201
07202
07203 CSize CGridCtrl::GetTextExtent(int nRow, int nCol, LPCTSTR str)
07204 {
07205 CGridCellBase* pCell = GetCell(nRow, nCol);
07206 if (!pCell)
07207 return CSize(0, 0);
07208 else
07209 return pCell->GetTextExtent(str);
07210 }
07211
07212
07213 void CGridCtrl::OnEditCell(int nRow, int nCol, CPoint point, UINT nChar)
07214 {
07215 #ifndef GRIDCONTROL_NO_TITLETIPS
07216 m_TitleTip.Hide();
07217 #endif
07218
07219
07220 CCellID cell(nRow, nCol);
07221 if (!IsValid(cell) || !IsCellEditable(nRow, nCol))
07222 return;
07223
07224
07225 EnsureVisible(nRow, nCol);
07226 if (!IsCellVisible(nRow, nCol))
07227 return;
07228
07229
07230 CRect rect;
07231 if (!GetCellRect(cell, rect))
07232 return;
07233
07234
07235 if (SendMessageToParent(nRow, nCol, GVN_BEGINLABELEDIT) >= 0)
07236 {
07237
07238 CGridCellBase* pCell = GetCell(nRow, nCol);
07239 if (pCell)
07240 pCell->Edit(nRow, nCol, rect, point, IDC_INPLACE_CONTROL, nChar);
07241 }
07242 }
07243
07244
07245 void CGridCtrl::EndEditing()
07246 {
07247 CCellID cell = GetFocusCell();
07248 if (!IsValid(cell)) return;
07249 CGridCellBase *pCell = GetCell(cell.row, cell.col);
07250 if (pCell)
07251 pCell->EndEdit();
07252 }
07253
07254
07255 void CGridCtrl::OnEndEditCell(int nRow, int nCol, CString str)
07256 {
07257 CString strCurrentText = GetItemText(nRow, nCol);
07258 if (strCurrentText != str)
07259 {
07260 SetItemText(nRow, nCol, str);
07261 if (ValidateEdit(nRow, nCol, str) &&
07262 SendMessageToParent(nRow, nCol, GVN_ENDLABELEDIT) >= 0)
07263 {
07264 SetModified(TRUE, nRow, nCol);
07265 RedrawCell(nRow, nCol);
07266 }
07267 else
07268 {
07269 SetItemText(nRow, nCol, strCurrentText);
07270 }
07271 }
07272
07273 CGridCellBase* pCell = GetCell(nRow, nCol);
07274 if (pCell)
07275 pCell->OnEndEdit();
07276 }
07277
07278
07279
07280 BOOL CGridCtrl::ValidateEdit(int nRow, int nCol, LPCTSTR str)
07281 {
07282 CGridCellBase* pCell = GetCell(nRow, nCol);
07283 ASSERT(pCell);
07284 if (!pCell)
07285 return TRUE;
07286
07287 return pCell->ValidateEdit(str);
07288 }
07289
07290
07291 CString CGridCtrl::GetItemText(int nRow, int nCol) const
07292 {
07293 if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols)
07294 return _T("");
07295
07296 CGridCellBase* pCell = GetCell(nRow, nCol);
07297 ASSERT(pCell);
07298 if (!pCell)
07299 return _T("");
07300
07301 return pCell->GetText();
07302 }