Update of /cvsroot/perl-win32-gui/Win32-GUI-Grid/MFCGrid
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15861/MFCGrid
Added Files:
CellRange.h GridCell.cpp GridCell.h GridCellBase.cpp
GridCellBase.h GridCellCheck.cpp GridCellCheck.h
GridCellCombo.cpp GridCellCombo.h GridCellDateTime.cpp
GridCellDateTime.h GridCellNumeric.cpp GridCellNumeric.h
GridCellURL.cpp GridCellURL.h GridCtrl.cpp GridCtrl.h
GridDropTarget.cpp GridDropTarget.h InPlaceEdit.cpp
InPlaceEdit.h Makefile MemDC.h StdAfx.cpp StdAfx.h
TitleTip.cpp TitleTip.h
Log Message:
Added to repository
--- NEW FILE: InPlaceEdit.h ---
//////////////////////////////////////////////////////////////////////
// InPlaceEdit.h : header file
//
// MFC Grid Control - inplace editing class
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
#define AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class CInPlaceEdit : public CEdit
{
// Construction
public:
CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
int nRow, int nColumn, CString sInitText, UINT nFirstChar);
// Attributes
public:
// Operations
public:
void EndEdit();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CInPlaceEdit();
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceEdit)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
int m_nRow;
int m_nColumn;
CString m_sInitText;
UINT m_nLastChar;
BOOL m_bExitOnArrows;
CRect m_Rect;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
--- NEW FILE: GridCellCheck.cpp ---
// GridCellCheck.cpp : implementation file
//
// MFC Grid Control - Main grid cell class
//
// Provides the implementation for a combobox cell type of the
// grid control.
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// Parts of the code contained in this file are based on the original
// CInPlaceList from http://www.codeguru.com/listview
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.22+
//
// History:
// 23 Jul 2001 - Complete rewrite
//
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "GridCell.h"
#include "GridCtrl.h"
#include "GridCellCheck.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CGridCellCheck, CGridCell)
CGridCellCheck::CGridCellCheck() : CGridCell()
{
m_bChecked = FALSE;
//m_Rect.IsRectNull();
}
CSize CGridCellCheck::GetCellExtent(CDC* pDC)
{
// Using SM_CXHSCROLL as a guide to the size of the checkbox
int nWidth = GetSystemMetrics(SM_CXHSCROLL) + 2*GetMargin(); // Yogurt
$$LR$$
CSize cellSize = CGridCell::GetCellExtent(pDC);
cellSize.cx += nWidth;
cellSize.cy = max (cellSize.cy, nWidth);
return cellSize;
}
// i/o: i=dims of cell rect; o=dims of text rect
BOOL CGridCellCheck::GetTextRect( LPRECT pRect)
{
BOOL bResult = CGridCell::GetTextRect(pRect);
if (bResult)
{
int nWidth = GetSystemMetrics(SM_CXHSCROLL) + 2*GetMargin();
pRect->left += nWidth;
if (pRect->left > pRect->right)
pRect->left = pRect->right;
}
return bResult;
}
// Override draw so that when the cell is selected, a drop arrow is shown in
the RHS.
BOOL CGridCellCheck::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd /*=TRUE*/)
{
BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
#ifndef _WIN32_WCE
// Store the cell's dimensions for later
m_Rect = rect;
CRect CheckRect = GetCheckPlacement();
rect.left = CheckRect.right;
// enough room to draw?
// if (CheckRect.Width() < rect.Width() && CheckRect.Height() <
rect.Height()) {
// Do the draw
pDC->DrawFrameControl(GetCheckPlacement(), DFC_BUTTON,
(m_bChecked)? DFCS_BUTTONCHECK | DFCS_CHECKED : DFCS_BUTTONCHECK);
// }
#endif
return bResult;
}
void CGridCellCheck::OnClick(CPoint PointCellRelative)
{
// PointCellRelative is relative to the topleft of the cell. Convert to
client coords
PointCellRelative += m_Rect.TopLeft();
CCellID cell = GetGrid()->GetCellFromPt (PointCellRelative);
if (!GetGrid()->IsCellEditable (cell))
return;
// GetCheckPlacement returns the checkbox dimensions in client coords. Only
check/
// uncheck if the user clicked in the box
if (GetCheckPlacement().PtInRect(PointCellRelative))
{
m_bChecked = !m_bChecked;
GetGrid()->InvalidateRect(m_Rect);
}
}
//////////////////////////////////////////////////////////////////////
// Operations
//////////////////////////////////////////////////////////////////////
BOOL CGridCellCheck::SetCheck(BOOL bChecked /*=TRUE*/)
{
BOOL bTemp = m_bChecked;
m_bChecked = bChecked;
if (!m_Rect.IsRectEmpty())
GetGrid()->InvalidateRect(m_Rect);
return bTemp;
}
BOOL CGridCellCheck::GetCheck()
{
return m_bChecked;
}
//////////////////////////////////////////////////////////////////////
// Protected implementation
//////////////////////////////////////////////////////////////////////
// Returns the dimensions and placement of the checkbox in client coords.
CRect CGridCellCheck::GetCheckPlacement()
{
int nWidth = GetSystemMetrics(SM_CXHSCROLL);
CRect place = m_Rect + CSize(GetMargin(), GetMargin());
place.right = place.left + nWidth;
place.bottom = place.top + nWidth;
/* for centering
int nDiff = (place.Width() - nWidth)/2;
if (nDiff > 0)
{
place.left += nDiff;
place.right = place.left + nWidth;
}
nDiff = (place.Height() - nWidth)/2;
if (nDiff > 0)
{
place.top += nDiff;
place.bottom = place.top + nWidth;
}
*/
// Yogurt $$LR$$
if (m_Rect.Height() < nWidth + 2 * (int)GetMargin() )
{
place.top = m_Rect.top + (m_Rect.Height() - nWidth) / 2;
place.bottom = place.top + nWidth;
}
return place;
}
--- NEW FILE: GridCell.cpp ---
// GridCell.cpp : implementation file
//
// MFC Grid Control - Main grid cell class
//
// Provides the implementation for the "default" cell type of the
// grid control. Adds in cell editing.
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.20+
//
// History:
// Eric Woodruff - 20 Feb 2000 - Added PrintCell() plus other minor changes
// Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and
CGridCellBase
// <[EMAIL PROTECTED]>
// C Maunder - 17 Jun 2000 - Font handling optimsed, Added CGridDefaultCell
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GridCell.h"
#include "InPlaceEdit.h"
#include "GridCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CGridCell, CGridCellBase)
IMPLEMENT_DYNCREATE(CGridDefaultCell, CGridCell)
/////////////////////////////////////////////////////////////////////////////
// GridCell
CGridCell::CGridCell()
{
m_plfFont = NULL;
CGridCell::Reset();
}
CGridCell::~CGridCell()
{
delete m_plfFont;
}
/////////////////////////////////////////////////////////////////////////////
// GridCell Attributes
void CGridCell::operator=(const CGridCell& cell)
{
if (this != &cell) CGridCellBase::operator=(cell);
}
void CGridCell::Reset()
{
CGridCellBase::Reset();
m_strText.Empty();
m_nImage = -1;
m_lParam = NULL; // BUG FIX J. Bloggs 20/10/03
m_pGrid = NULL;
m_bEditing = FALSE;
m_pEditWnd = NULL;
m_nFormat = (DWORD)-1; // Use default from CGridDefaultCell
m_crBkClr = CLR_DEFAULT; // Background colour (or CLR_DEFAULT)
m_crFgClr = CLR_DEFAULT; // Forground colour (or CLR_DEFAULT)
m_nMargin = (UINT)-1; // Use default from CGridDefaultCell
delete m_plfFont;
m_plfFont = NULL; // Cell font
}
void CGridCell::SetFont(const LOGFONT* plf)
{
if (plf == NULL)
{
delete m_plfFont;
m_plfFont = NULL;
}
else
{
if (!m_plfFont)
m_plfFont = new LOGFONT;
if (m_plfFont)
memcpy(m_plfFont, plf, sizeof(LOGFONT));
}
}
LOGFONT* CGridCell::GetFont() const
{
if (m_plfFont == NULL)
{
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
if (!pDefaultCell)
return NULL;
return pDefaultCell->GetFont();
}
return m_plfFont;
}
CFont* CGridCell::GetFontObject() const
{
// If the default font is specified, use the default cell implementation
if (m_plfFont == NULL)
{
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
if (!pDefaultCell)
return NULL;
return pDefaultCell->GetFontObject();
}
else
{
static CFont Font;
Font.DeleteObject();
Font.CreateFontIndirect(m_plfFont);
return &Font;
}
}
DWORD CGridCell::GetFormat() const
{
if (m_nFormat == (DWORD)-1)
{
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
if (!pDefaultCell)
return 0;
return pDefaultCell->GetFormat();
}
return m_nFormat;
}
UINT CGridCell::GetMargin() const
{
if (m_nMargin == (UINT)-1)
{
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
if (!pDefaultCell)
return 0;
return pDefaultCell->GetMargin();
}
return m_nMargin;
}
/////////////////////////////////////////////////////////////////////////////
// GridCell Operations
BOOL CGridCell::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT
nID, UINT nChar)
{
if ( m_bEditing )
{
if (m_pEditWnd)
m_pEditWnd->SendMessage ( WM_CHAR, nChar );
}
else
{
DWORD dwStyle = ES_LEFT;
if (GetFormat() & DT_RIGHT)
dwStyle = ES_RIGHT;
else if (GetFormat() & DT_CENTER)
dwStyle = ES_CENTER;
m_bEditing = TRUE;
// InPlaceEdit auto-deletes itself
CGridCtrl* pGrid = GetGrid();
m_pEditWnd = new CInPlaceEdit(pGrid, rect, dwStyle, nID, nRow,
nCol, GetText(), nChar);
}
return TRUE;
}
void CGridCell::EndEdit()
{
if (m_pEditWnd)
((CInPlaceEdit*)m_pEditWnd)->EndEdit();
}
void CGridCell::OnEndEdit()
{
m_bEditing = FALSE;
m_pEditWnd = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CGridDefaultCell
CGridDefaultCell::CGridDefaultCell()
{
#ifdef _WIN32_WCE
m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX;
#else
m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX | DT_END_ELLIPSIS;
#endif
m_crFgClr = CLR_DEFAULT;
m_crBkClr = CLR_DEFAULT;
m_Size = CSize(30,10);
m_dwStyle = 0;
#ifdef _WIN32_WCE
LOGFONT lf;
GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf);
SetFont(&lf);
#else // not CE
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS), &ncm, 0));
SetFont(&(ncm.lfMessageFont));
#endif
}
CGridDefaultCell::~CGridDefaultCell()
{
m_Font.DeleteObject();
}
void CGridDefaultCell::SetFont(const LOGFONT* plf)
{
ASSERT(plf);
if (!plf) return;
m_Font.DeleteObject();
m_Font.CreateFontIndirect(plf);
CGridCell::SetFont(plf);
// Get the font size and hence the default cell size
CDC* pDC = CDC::FromHandle(::GetDC(NULL));
if (pDC)
{
CFont* pOldFont = pDC->SelectObject(&m_Font);
SetMargin(pDC->GetTextExtent(_T(" "), 1).cx);
m_Size = pDC->GetTextExtent(_T(" XXXXXXXXXXXX "), 14);
m_Size.cy = (m_Size.cy * 3) / 2;
pDC->SelectObject(pOldFont);
ReleaseDC(NULL, pDC->GetSafeHdc());
}
else
{
SetMargin(3);
m_Size = CSize(40,16);
}
}
LOGFONT* CGridDefaultCell::GetFont() const
{
ASSERT(m_plfFont); // This is the default - it CAN'T be NULL!
return m_plfFont;
}
CFont* CGridDefaultCell::GetFontObject() const
{
ASSERT(m_Font.GetSafeHandle());
return (CFont*) &m_Font;
}
--- NEW FILE: Makefile ---
# Microsoft Developer Studio Generated NMAKE File, Based on MFCGrid.dsp
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
CPP=cl.exe
RSC=rc.exe
OUTDIR=.\Lib
INTDIR=.\Build
# Begin Custom Macros
OutDir=.\Lib
# End Custom Macros
ALL : "$(OUTDIR)\MFCGrid.lib"
CLEAN :
[EMAIL PROTECTED] "$(INTDIR)\GridCellUrl.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCellNumeric.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCellDateTime.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCellCheck.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCellCombo.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCell.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCellBase.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridCtrl.obj"
[EMAIL PROTECTED] "$(INTDIR)\GridDropTarget.obj"
[EMAIL PROTECTED] "$(INTDIR)\InPlaceEdit.obj"
[EMAIL PROTECTED] "$(INTDIR)\StdAfx.obj"
[EMAIL PROTECTED] "$(INTDIR)\TitleTip.obj"
[EMAIL PROTECTED] "$(INTDIR)\vc60.idb"
[EMAIL PROTECTED] "$(INTDIR)\MFCGrid.pch"
[EMAIL PROTECTED] "$(OUTDIR)\MFCGrid.lib"
"$(OUTDIR)" :
mkdir "$(OUTDIR)"
"$(INTDIR)" :
mkdir "$(INTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D
"_MBCS" /D"_WINDLL" /D"_USRDLL" /D "_AFXDLL" /D "_AFX_NOFORCE_LIBS"
/Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\MFCGrid.bsc"
BSC32_SBRS= \
LIB32=link.exe -lib
LIB32_FLAGS=/nologo /out:"$(OUTDIR)\MFCGrid.lib"
LIB32_OBJS= \
"$(INTDIR)\TitleTip.obj" \
"$(INTDIR)\InPlaceEdit.obj" \
"$(INTDIR)\GridDropTarget.obj" \
"$(INTDIR)\GridCtrl.obj" \
"$(INTDIR)\GridCellBase.obj" \
"$(INTDIR)\GridCell.obj" \
"$(INTDIR)\GridCellNumeric.obj" \
"$(INTDIR)\GridCellUrl.obj" \
"$(INTDIR)\GridCellDateTime.obj" \
"$(INTDIR)\GridCellCheck.obj" \
"$(INTDIR)\GridCellCombo.obj" \
"$(INTDIR)\StdAfx.obj"
"$(OUTDIR)\MFCGrid.lib" : "$(OUTDIR)" "$(INTDIR)" $(DEF_FILE) $(LIB32_OBJS)
$(LIB32) @<<
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
<<
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
GridCell.cpp : \
"CellRange.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"GridDropTarget.h"\
"InPlaceEdit.h"\
"StdAfx.h"\
"TitleTip.h"
GridCellBase.cpp : \
"CellRange.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"GridDropTarget.h"\
"StdAfx.h"\
"TitleTip.h"
GridCtrl.cpp : \
"CellRange.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"GridDropTarget.h"\
"MemDC.h"\
"StdAfx.h"\
"TitleTip.h"
GridDropTarget.cpp : \
"CellRange.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"GridDropTarget.h"\
"StdAfx.h"\
"TitleTip.h"
InPlaceEdit.cpp : \
"CellRange.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"GridDropTarget.h"\
"InPlaceEdit.h"\
"StdAfx.h"\
"TitleTip.h"
StdAfx.cpp : \
"StdAfx.h"
TitleTip.cpp : \
"CellRange.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"GridDropTarget.h"\
"StdAfx.h"\
"TitleTip.h"
GridCellNumeric.cpp : \
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"InPlaceEdit.h"\
"StdAfx.h"
GridCellDateTime.cpp : \
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"StdAfx.h"
GridCellCheck.cpp : \
"GridCellCheck.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"StdAfx.h"
GridCellCombo.cpp : \
"GridCellCombo.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"StdAfx.h"
GridCellUrl.cpp : \
"GridCellUrl.h"\
"GridCell.h"\
"GridCellBase.h"\
"GridCtrl.h"\
"StdAfx.h"
SOURCE=GridCell.cpp
"$(INTDIR)\GridCell.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCellBase.cpp
"$(INTDIR)\GridCellBase.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCtrl.cpp
"$(INTDIR)\GridCtrl.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridDropTarget.cpp
"$(INTDIR)\GridDropTarget.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=InPlaceEdit.cpp
"$(INTDIR)\InPlaceEdit.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=StdAfx.cpp
"$(INTDIR)\StdAfx.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=TitleTip.cpp
"$(INTDIR)\TitleTip.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCellNumeric.cpp
"$(INTDIR)\GridCellNumeric.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCellDateTime.cpp
"$(INTDIR)\GridCellDateTime.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCellCheck.cpp
"$(INTDIR)\GridCellCheck.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCellCombo.cpp
"$(INTDIR)\GridCellCombo.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=GridCellUrl.cpp
"$(INTDIR)\GridCellUrl.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
--- NEW FILE: GridCellCombo.h ---
#if
!defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
#define AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
/////////////////////////////////////////////////////////////////////////////
// GridCellCombo.h : header file
//
// MFC Grid Control - Grid combo cell class header file
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10
//
//////////////////////////////////////////////////////////////////////
#include "GridCell.h"
class CGridCellCombo : public CGridCell
{
friend class CGridCtrl;
DECLARE_DYNCREATE(CGridCellCombo)
public:
CGridCellCombo();
// editing cells
public:
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID,
UINT nChar);
virtual CWnd* GetEditWnd() const;
virtual void EndEdit();
// Operations
public:
virtual CSize GetCellExtent(CDC* pDC);
// CGridCellCombo specific calls
public:
void SetOptions(const CStringArray& ar);
void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle; }
DWORD GetStyle() { return m_dwStyle; }
protected:
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd = TRUE);
CStringArray m_Strings;
DWORD m_dwStyle;
};
class CGridCellList : public CGridCellCombo
{
DECLARE_DYNCREATE(CGridCellList)
public:
CGridCellList();
};
/////////////////////////////////////////////////////////////////////////////
// CComboEdit window
#define IDC_COMBOEDIT 1001
class CComboEdit : public CEdit
{
// Construction
public:
CComboEdit();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CComboEdit)
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CComboEdit();
// Generated message map functions
protected:
//{{AFX_MSG(CComboEdit)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CInPlaceList window
class CInPlaceList : public CComboBox
{
friend class CComboEdit;
// Construction
public:
CInPlaceList(CWnd* pParent, // parent
CRect& rect, // dimensions & location
DWORD dwStyle, // window/combobox style
UINT nID, // control ID
int nRow, int nColumn, // row and column
COLORREF crFore, COLORREF crBack, // Foreground, background
colour
CStringArray& Items, // Items in list
CString sInitText, // initial selection
UINT nFirstChar); // first character to
pass to control
// Attributes
public:
CComboEdit m_edit; // subclassed edit control
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceList)
protected:
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CInPlaceList();
void EndEdit();
protected:
int GetCorrectDropWidth();
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceList)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnDropdown();
afx_msg void OnSelChange();
afx_msg UINT OnGetDlgCode();
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
//}}AFX_MSG
//afx_msg void OnSelendOK();
DECLARE_MESSAGE_MAP()
private:
int m_nNumLines;
CString m_sInitText;
int m_nRow;
int m_nCol;
UINT m_nLastChar;
BOOL m_bExitOnArrows;
COLORREF m_crForeClr, m_crBackClr;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
--- NEW FILE: GridCellURL.h ---
// GridCellURL.h: interface for the CGridCellURL class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GridCellURL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_)
#define AFX_GridCellURL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "GridCell.h"
typedef struct {
LPCTSTR szURLPrefix;
int nLength;
} URLStruct;
class CGridCellURL : public CGridCell
{
DECLARE_DYNCREATE(CGridCellURL)
public:
CGridCellURL();
virtual ~CGridCellURL();
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd = TRUE);
// virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT
nID, UINT nChar);
virtual LPCTSTR GetTipText() { return NULL; }
void SetAutoLaunchUrl(BOOL bLaunch = TRUE) { m_bLaunchUrl = bLaunch;
}
BOOL GetAutoLaunchUrl() { return m_bLaunchUrl && !m_bEditing; }
protected:
virtual BOOL OnSetCursor();
virtual void OnClick(CPoint PointCellRelative);
BOOL HasUrl(CString str);
BOOL OverURL(CPoint& pt, CString& strURL);
protected:
#ifndef _WIN32_WCE
static HCURSOR g_hLinkCursor; // Hyperlink mouse cursor
HCURSOR GetHandCursor();
#endif
static URLStruct g_szURIprefixes[];
protected:
COLORREF m_clrUrl;
COLORREF m_clrOld;
BOOL m_bLaunchUrl;
CRect m_Rect;
};
#endif //
!defined(AFX_GridCellURL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_)
--- NEW FILE: GridCellDateTime.h ---
// GridCellDateTime.h: interface for the CGridCellDateTime class.
//
// Provides the implementation for a datetime picker cell type of the
// grid control.
//
// For use with CGridCtrl v2.22+
//
//////////////////////////////////////////////////////////////////////
#if
!defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_)
#define AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "GridCell.h"
#include "afxdtctl.h" // for CDateTimeCtrl
class CGridCellDateTime : public CGridCell
{
friend class CGridCtrl;
DECLARE_DYNCREATE(CGridCellDateTime)
CTime m_cTime;
DWORD m_dwStyle;
public:
CGridCellDateTime();
CGridCellDateTime(DWORD dwStyle);
virtual ~CGridCellDateTime();
// editing cells
public:
void Init(DWORD dwStyle);
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT
nID, UINT nChar);
virtual CWnd* GetEditWnd() const;
virtual void EndEdit();
virtual CSize GetCellExtent(CDC* pDC);
CTime* GetTime() {return &m_cTime;};
void SetTime(CTime time);
};
class CInPlaceDateTime : public CDateTimeCtrl
{
// Construction
public:
CInPlaceDateTime(CWnd* pParent, // parent
CRect& rect, // dimensions & location
DWORD dwStyle, // window/combobox style
UINT nID, // control ID
int nRow, int nColumn, // row and column
COLORREF crFore, COLORREF crBack, // Foreground, background colour
CTime* pcTime,
UINT nFirstChar); // first character to pass to control
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceList)
protected:
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CInPlaceDateTime();
void EndEdit();
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceList)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
afx_msg void OnCloseUp ( NMHDR * pNotifyStruct, LRESULT* result );
//}}AFX_MSG
//afx_msg void OnSelendOK();
DECLARE_MESSAGE_MAP()
private:
CTime* m_pcTime;
int m_nRow;
int m_nCol;
UINT m_nLastChar;
BOOL m_bExitOnArrows;
COLORREF m_crForeClr, m_crBackClr;
};
class CGridCellTime : public CGridCellDateTime
{
CGridCellTime():CGridCellDateTime(DTS_TIMEFORMAT) {}
DECLARE_DYNCREATE(CGridCellTime)
};
class CGridCellDateCal : public CGridCellDateTime
{
CGridCellDateCal():CGridCellDateTime() {}
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT
nID, UINT nChar);
DECLARE_DYNCREATE(CGridCellDateCal)
};
#endif //
!defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_)
--- NEW FILE: GridCell.h ---
/////////////////////////////////////////////////////////////////////////////
// GridCell.h : header file
//
// MFC Grid Control - Grid cell class header file
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.20+
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class CGridCtrl;
#include "GridCellBase.h"
// Each cell contains one of these. Fields "row" and "column" are not stored
since we
// will usually have acces to them in other ways, and they are an extra 8 bytes
per
// cell that is probably unnecessary.
class CGridCell : public CGridCellBase
{
friend class CGridCtrl;
DECLARE_DYNCREATE(CGridCell)
// Construction/Destruction
public:
CGridCell();
virtual ~CGridCell();
// Attributes
public:
void operator=(const CGridCell& cell);
virtual void SetText(LPCTSTR szText) { m_strText = szText; }
virtual void SetImage(int nImage) { m_nImage = nImage; }
virtual void SetData(LPARAM lParam) { m_lParam = lParam; }
virtual void SetGrid(CGridCtrl* pGrid) { m_pGrid = pGrid; }
// virtual void SetState(const DWORD nState); - use base class version
virtual void SetFormat(DWORD nFormat) { m_nFormat = nFormat; }
virtual void SetTextClr(COLORREF clr) { m_crFgClr = clr; }
virtual void SetBackClr(COLORREF clr) { m_crBkClr = clr; }
virtual void SetFont(const LOGFONT* plf);
virtual void SetMargin(UINT nMargin) { m_nMargin = nMargin; }
virtual CWnd* GetEditWnd() const { return m_pEditWnd; }
virtual void SetCoords(int /*nRow*/, int /*nCol*/) {} // don't need to
know the row and
// column for base
implementation
virtual LPCTSTR GetText() const { return
(m_strText.IsEmpty())? _T("") : LPCTSTR(m_strText); }
virtual int GetImage() const { return m_nImage; }
virtual LPARAM GetData() const { return m_lParam; }
virtual CGridCtrl* GetGrid() const { return m_pGrid; }
// virtual DWORD GetState() const - use base class
virtual DWORD GetFormat() const;
virtual COLORREF GetTextClr() const { return m_crFgClr; } //
TODO: change to use default cell
virtual COLORREF GetBackClr() const { return m_crBkClr; }
virtual LOGFONT* GetFont() const;
virtual CFont* GetFontObject() const;
virtual UINT GetMargin() const;
virtual BOOL IsEditing() const { return m_bEditing; }
virtual BOOL IsDefaultFont() const { return (m_plfFont ==
NULL); }
virtual void Reset();
// editing cells
public:
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID,
UINT nChar);
virtual void EndEdit();
protected:
virtual void OnEndEdit();
protected:
CString m_strText; // Cell text (or binary data if you wish...)
LPARAM m_lParam; // 32-bit value to associate with item
int m_nImage; // Index of the list view items icon
DWORD m_nFormat;
COLORREF m_crFgClr;
COLORREF m_crBkClr;
LOGFONT* m_plfFont;
UINT m_nMargin;
BOOL m_bEditing; // Cell being edited?
CGridCtrl* m_pGrid; // Parent grid control
CWnd* m_pEditWnd;
};
// This class is for storing grid default values. It's a little heavy weight, so
// don't use it in bulk
class CGridDefaultCell : public CGridCell
{
DECLARE_DYNCREATE(CGridDefaultCell)
// Construction/Destruction
public:
CGridDefaultCell();
virtual ~CGridDefaultCell();
public:
virtual DWORD GetStyle() const { return m_dwStyle;
}
virtual void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle;
}
virtual int GetWidth() const { return m_Size.cx;
}
virtual int GetHeight() const { return m_Size.cy;
}
virtual void SetWidth(int nWidth) { m_Size.cx = nWidth;
}
virtual void SetHeight(int nHeight) { m_Size.cy = nHeight;
}
// Disable these properties
virtual void SetData(LPARAM /*lParam*/) { ASSERT(FALSE);
}
virtual void SetState(DWORD /*nState*/) { ASSERT(FALSE);
}
virtual DWORD GetState() const { return
CGridCell::GetState()|GVIS_READONLY; }
virtual void SetCoords( int /*row*/, int /*col*/) { ASSERT(FALSE);
}
virtual void SetFont(const LOGFONT* /*plf*/);
virtual LOGFONT* GetFont() const;
virtual CFont* GetFontObject() const;
protected:
CSize m_Size; // Default Size
CFont m_Font; // Cached font
DWORD m_dwStyle; // Cell Style - unused
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
--- NEW FILE: GridCellNumeric.h ---
// GridCellNumeric.h: interface for the CGridCellNumeric class.
//
// Written by Andrew Truckle [EMAIL PROTECTED]
//
//////////////////////////////////////////////////////////////////////
#if
!defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_)
#define AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "GridCell.h"
class CGridCellNumeric : public CGridCell
{
DECLARE_DYNCREATE(CGridCellNumeric)
public:
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID,
UINT nChar);
virtual void EndEdit();
};
#endif //
!defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_)
--- NEW FILE: CellRange.h ---
///////////////////////////////////////////////////////////////////////
// CellRange.h: header file
//
// MFC Grid Control - interface for the CCellRange class.
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.20+
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// The code contained in this file is based on the original
// WorldCom Grid control written by Joe Willcoxson,
// mailto:[EMAIL PROTECTED]
// http://users.aol.com/chinajoe
class CCellID
{
// Attributes
public:
int row, col;
// Operations
public:
explicit CCellID(int nRow = -1, int nCol = -1) : row(nRow), col(nCol) {}
int IsValid() const { return (row >= 0 && col >= 0); }
int operator==(const CCellID& rhs) const { return (row == rhs.row && col ==
rhs.col); }
int operator!=(const CCellID& rhs) const { return !operator==(rhs); }
};
class CCellRange
{
public:
CCellRange(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int
nMaxCol = -1)
{
Set(nMinRow, nMinCol, nMaxRow, nMaxCol);
}
void Set(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol
= -1);
int IsValid() const;
int InRange(int row, int col) const;
int InRange(const CCellID& cellID) const;
int Count() { return (m_nMaxRow - m_nMinRow + 1) * (m_nMaxCol - m_nMinCol
+ 1); }
CCellID GetTopLeft() const;
CCellRange Intersect(const CCellRange& rhs) const;
int GetMinRow() const {return m_nMinRow;}
void SetMinRow(int minRow) {m_nMinRow = minRow;}
int GetMinCol() const {return m_nMinCol;}
void SetMinCol(int minCol) {m_nMinCol = minCol;}
int GetMaxRow() const {return m_nMaxRow;}
void SetMaxRow(int maxRow) {m_nMaxRow = maxRow;}
int GetMaxCol() const {return m_nMaxCol;}
void SetMaxCol(int maxCol) {m_nMaxCol = maxCol;}
int GetRowSpan() const {return m_nMaxRow - m_nMinRow + 1;}
int GetColSpan() const {return m_nMaxCol - m_nMinCol + 1;}
void operator=(const CCellRange& rhs);
int operator==(const CCellRange& rhs);
int operator!=(const CCellRange& rhs);
protected:
int m_nMinRow;
int m_nMinCol;
int m_nMaxRow;
int m_nMaxCol;
};
inline void CCellRange::Set(int minRow, int minCol, int maxRow, int maxCol)
{
m_nMinRow = minRow;
m_nMinCol = minCol;
m_nMaxRow = maxRow;
m_nMaxCol = maxCol;
}
inline void CCellRange::operator=(const CCellRange& rhs)
{
if (this != &rhs) Set(rhs.m_nMinRow, rhs.m_nMinCol, rhs.m_nMaxRow,
rhs.m_nMaxCol);
}
inline int CCellRange::operator==(const CCellRange& rhs)
{
return ((m_nMinRow == rhs.m_nMinRow) && (m_nMinCol == rhs.m_nMinCol) &&
(m_nMaxRow == rhs.m_nMaxRow) && (m_nMaxCol == rhs.m_nMaxCol));
}
inline int CCellRange::operator!=(const CCellRange& rhs)
{
return !operator==(rhs);
}
inline int CCellRange::IsValid() const
{
return (m_nMinRow >= 0 && m_nMinCol >= 0 && m_nMaxRow >= 0 && m_nMaxCol >=
0 &&
m_nMinRow <= m_nMaxRow && m_nMinCol <= m_nMaxCol);
}
inline int CCellRange::InRange(int row, int col) const
{
return (row >= m_nMinRow && row <= m_nMaxRow && col >= m_nMinCol && col <=
m_nMaxCol);
}
inline int CCellRange::InRange(const CCellID& cellID) const
{
return InRange(cellID.row, cellID.col);
}
inline CCellID CCellRange::GetTopLeft() const
{
return CCellID(m_nMinRow, m_nMinCol);
}
inline CCellRange CCellRange::Intersect(const CCellRange& rhs) const
{
return CCellRange(max(m_nMinRow,rhs.m_nMinRow),
max(m_nMinCol,rhs.m_nMinCol),
min(m_nMaxRow,rhs.m_nMaxRow),
min(m_nMaxCol,rhs.m_nMaxCol));
}
#endif //
!defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_)
--- NEW FILE: GridCellBase.cpp ---
// GridCellBase.cpp : implementation file
//
// MFC Grid Control - Main grid cell base class
//
// Provides the implementation for the base cell type of the
// grid control. No data is stored (except for state) but default
// implementations of drawing, printingetc provided. MUST be derived
// from to be used.
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.22+
//
// History:
// Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and
CGridCellBase
// C Maunder - 19 May 2000 - Fixed sort arrow drawing (Ivan Ilinov)
// C Maunder - 29 Aug 2000 - operator= checks for NULL font before setting
(Martin Richter)
// C Maunder - 15 Oct 2000 - GetTextExtent fixed (Martin Richter)
// C Maunder - 1 Jan 2001 - Added ValidateEdit
// Yogurt - 13 Mar 2004 - GetCellExtent fixed
//
// NOTES: Each grid cell should take care of it's own drawing, though the Draw()
// method takes an "erase background" paramter that is called if the grid
// decides to draw the entire grid background in on hit. Certain ambient
// properties such as the default font to use, and hints on how to draw
// fixed cells should be fetched from the parent grid. The grid trusts
the
// cells will behave in a certain way, and the cells trust the grid will
// supply accurate information.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GridCtrl.h"
#include "GridCellBase.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(CGridCellBase, CObject)
/////////////////////////////////////////////////////////////////////////////
// GridCellBase
CGridCellBase::CGridCellBase()
{
Reset();
}
CGridCellBase::~CGridCellBase()
{
}
/////////////////////////////////////////////////////////////////////////////
// GridCellBase Operations
void CGridCellBase::Reset()
{
m_nState = 0;
}
void CGridCellBase::operator=(const CGridCellBase& cell)
{
if (this == &cell) return;
SetGrid(cell.GetGrid()); // do first in case of dependencies
SetText(cell.GetText());
SetImage(cell.GetImage());
SetData(cell.GetData());
SetState(cell.GetState());
SetFormat(cell.GetFormat());
SetTextClr(cell.GetTextClr());
SetBackClr(cell.GetBackClr());
SetFont(cell.IsDefaultFont()? NULL : cell.GetFont());
SetMargin(cell.GetMargin());
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellBase Attributes
// Returns a pointer to a cell that holds default values for this particular
type of cell
CGridCellBase* CGridCellBase::GetDefaultCell() const
{
if (GetGrid())
return GetGrid()->GetDefaultCell(IsFixedRow(), IsFixedCol());
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellBase Operations
// EFW - Various changes to make it draw cells better when using alternate
// color schemes. Also removed printing references as that's now done
// by PrintCell() and fixed the sort marker so that it doesn't draw out
// of bounds.
BOOL CGridCellBase::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd /*=TRUE*/)
{
// Note - all through this function we totally brutalise 'rect'. Do not
// depend on it's value being that which was passed in.
CGridCtrl* pGrid = GetGrid();
ASSERT(pGrid);
if (!pGrid || !pDC)
return FALSE;
if( rect.Width() <= 0 || rect.Height() <= 0) // prevents imagelist item
from drawing even
return FALSE; // though cell is hidden
//TRACE3("Drawing %scell %d, %d\n", IsFixed()? _T("Fixed ") : _T(""), nRow,
nCol);
int nSavedDC = pDC->SaveDC();
pDC->SetBkMode(TRANSPARENT);
// Get the default cell implementation for this kind of cell. We use it if
this cell
// has anything marked as "default"
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
if (!pDefaultCell)
return FALSE;
// Set up text and background colours
COLORREF TextClr, TextBkClr;
TextClr = (GetTextClr() == CLR_DEFAULT)? pDefaultCell->GetTextClr() :
GetTextClr();
if (GetBackClr() == CLR_DEFAULT)
TextBkClr = pDefaultCell->GetBackClr();
else
{
bEraseBkgnd = TRUE;
TextBkClr = GetBackClr();
}
// Draw cell background and highlighting (if necessary)
if ( IsFocused() || IsDropHighlighted() )
{
// Always draw even in list mode so that we can tell where the
// cursor is at. Use the highlight colors though.
if(GetState() & GVIS_SELECTED)
{
TextBkClr = ::GetSysColor(COLOR_HIGHLIGHT);
TextClr = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
bEraseBkgnd = TRUE;
}
rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
if (bEraseBkgnd)
{
TRY
{
CBrush brush(TextBkClr);
pDC->FillRect(rect, &brush);
}
CATCH(CResourceException, e)
{
//e->ReportError();
}
END_CATCH
}
// Don't adjust frame rect if no grid lines so that the
// whole cell is enclosed.
if(pGrid->GetGridLines() != GVL_NONE)
{
rect.right--;
rect.bottom--;
}
if (pGrid->GetFrameFocusCell())
{
// Use same color as text to outline the cell so that it shows
// up if the background is black.
TRY
{
CBrush brush(TextClr);
pDC->FrameRect(rect, &brush);
}
CATCH(CResourceException, e)
{
//e->ReportError();
}
END_CATCH
}
pDC->SetTextColor(TextClr);
// Adjust rect after frame draw if no grid lines
if(pGrid->GetGridLines() == GVL_NONE)
{
rect.right--;
rect.bottom--;
}
//rect.DeflateRect(0,1,1,1); - Removed by Yogurt
}
else if ((GetState() & GVIS_SELECTED))
{
rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
pDC->FillSolidRect(rect, ::GetSysColor(COLOR_HIGHLIGHT));
rect.right--; rect.bottom--;
pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
}
else
{
if (bEraseBkgnd)
{
rect.right++; rect.bottom++; // FillRect doesn't draw RHS or
bottom
CBrush brush(TextBkClr);
pDC->FillRect(rect, &brush);
rect.right--; rect.bottom--;
}
pDC->SetTextColor(TextClr);
}
// Draw lines only when wanted
if (IsFixed() && pGrid->GetGridLines() != GVL_NONE)
{
CCellID FocusCell = pGrid->GetFocusCell();
// As above, always show current location even in list mode so
// that we know where the cursor is at.
BOOL bHiliteFixed = pGrid->GetTrackFocusCell() &&
pGrid->IsValid(FocusCell) &&
(FocusCell.row == nRow || FocusCell.col == nCol);
// If this fixed cell is on the same row/col as the focus cell,
// highlight it.
if (bHiliteFixed)
{
rect.right++; rect.bottom++;
pDC->DrawEdge(rect, BDR_SUNKENINNER /*EDGE_RAISED*/, BF_RECT);
rect.DeflateRect(1,1);
}
else
{
CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)),
darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)),
*pOldPen = pDC->GetCurrentPen();
pDC->SelectObject(&lightpen);
pDC->MoveTo(rect.right, rect.top);
pDC->LineTo(rect.left, rect.top);
pDC->LineTo(rect.left, rect.bottom);
pDC->SelectObject(&darkpen);
pDC->MoveTo(rect.right, rect.top);
pDC->LineTo(rect.right, rect.bottom);
pDC->LineTo(rect.left, rect.bottom);
pDC->SelectObject(pOldPen);
rect.DeflateRect(1,1);
}
}
// Draw Text and image
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
if (!pDC->m_bPrinting)
#endif
{
CFont *pFont = GetFontObject();
ASSERT(pFont);
if (pFont)
pDC->SelectObject(pFont);
}
//rect.DeflateRect(GetMargin(), 0); - changed by Yogurt
rect.DeflateRect(GetMargin(), GetMargin());
rect.right++;
rect.bottom++;
if (pGrid->GetImageList() && GetImage() >= 0)
{
IMAGEINFO Info;
if (pGrid->GetImageList()->GetImageInfo(GetImage(), &Info))
{
// would like to use a clipping region but seems to have issue
// working with CMemDC directly. Instead, don't display image
// if any part of it cut-off
//
// CRgn rgn;
// rgn.CreateRectRgnIndirect(rect);
// pDC->SelectClipRgn(&rgn);
// rgn.DeleteObject();
/*
// removed by Yogurt
int nImageWidth = Info.rcImage.right-Info.rcImage.left+1;
int nImageHeight = Info.rcImage.bottom-Info.rcImage.top+1;
if( nImageWidth + rect.left <= rect.right + (int)(2*GetMargin())
&& nImageHeight + rect.top <= rect.bottom +
(int)(2*GetMargin()) )
{
pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(),
ILD_NORMAL);
}
*/
// Added by Yogurt
int nImageWidth = Info.rcImage.right-Info.rcImage.left;
int nImageHeight = Info.rcImage.bottom-Info.rcImage.top;
if ((nImageWidth + rect.left <= rect.right) && (nImageHeight +
rect.top <= rect.bottom))
pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(),
ILD_NORMAL);
//rect.left += nImageWidth+GetMargin();
}
}
// Draw sort arrow
if (pGrid->GetSortColumn() == nCol && nRow == 0)
{
CSize size = pDC->GetTextExtent(_T("M"));
int nOffset = 2;
// Base the size of the triangle on the smaller of the column
// height or text height with a slight offset top and bottom.
// Otherwise, it can get drawn outside the bounds of the cell.
size.cy -= (nOffset * 2);
if (size.cy >= rect.Height())
size.cy = rect.Height() - (nOffset * 2);
size.cx = size.cy; // Make the dimensions square
// Kludge for vertical text
BOOL bVertical = (GetFont()->lfEscapement == 900);
// Only draw if it'll fit!
//if (size.cx + rect.left < rect.right + (int)(2*GetMargin())) -
changed / Yogurt
if (size.cx + rect.left < rect.right)
{
int nTriangleBase = rect.bottom - nOffset - size.cy; // Triangle
bottom right
//int nTriangleBase = (rect.top + rect.bottom - size.cy)/2; //
Triangle middle right
//int nTriangleBase = rect.top + nOffset; //
Triangle top right
//int nTriangleLeft = rect.right - size.cx; //
Triangle RHS
//int nTriangleLeft = (rect.right + rect.left - size.cx)/2; //
Triangle middle
//int nTriangleLeft = rect.left; //
Triangle LHS
int nTriangleLeft;
if (bVertical)
nTriangleLeft = (rect.right + rect.left - size.cx)/2; //
Triangle middle
else
nTriangleLeft = rect.right - size.cx; // Triangle
RHS
CPen penShadow(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW));
CPen penLight(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT));
if (pGrid->GetSortAscending())
{
// Draw triangle pointing upwards
CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight);
pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1);
pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase +
1 );
pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase +
size.cy + 1);
pDC->LineTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1);
pDC->SelectObject(&penShadow);
pDC->MoveTo( nTriangleLeft, nTriangleBase + size.cy );
pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase );
pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase + size.cy );
pDC->LineTo( nTriangleLeft, nTriangleBase + size.cy );
pDC->SelectObject(pOldPen);
}
else
{
// Draw triangle pointing downwards
CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight);
pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + 1 );
pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase +
size.cy + 1 );
pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + 1 );
pDC->LineTo( nTriangleLeft + 1, nTriangleBase + 1 );
pDC->SelectObject(&penShadow);
pDC->MoveTo( nTriangleLeft, nTriangleBase );
pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase +
size.cy );
pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase );
pDC->LineTo( nTriangleLeft, nTriangleBase );
pDC->SelectObject(pOldPen);
}
if (!bVertical)
rect.right -= size.cy;
}
}
// We want to see '&' characters so use DT_NOPREFIX
GetTextRect(rect);
rect.right++;
rect.bottom++;
DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | DT_NOPREFIX);
pDC->RestoreDC(nSavedDC);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellBase Mouse and Cursor events
// Not yet implemented
void CGridCellBase::OnMouseEnter()
{
TRACE0("Mouse entered cell\n");
}
void CGridCellBase::OnMouseOver()
{
//TRACE0("Mouse over cell\n");
}
// Not Yet Implemented
void CGridCellBase::OnMouseLeave()
{
TRACE0("Mouse left cell\n");
}
void CGridCellBase::OnClick( CPoint PointCellRelative)
{
UNUSED_ALWAYS(PointCellRelative);
TRACE2("Mouse Left btn up in cell at x=%i y=%i\n", PointCellRelative.x,
PointCellRelative.y);
}
void CGridCellBase::OnClickDown( CPoint PointCellRelative)
{
UNUSED_ALWAYS(PointCellRelative);
TRACE2("Mouse Left btn down in cell at x=%i y=%i\n", PointCellRelative.x,
PointCellRelative.y);
}
void CGridCellBase::OnRClick( CPoint PointCellRelative)
{
UNUSED_ALWAYS(PointCellRelative);
TRACE2("Mouse right-clicked in cell at x=%i y=%i\n", PointCellRelative.x,
PointCellRelative.y);
}
void CGridCellBase::OnDblClick( CPoint PointCellRelative)
{
UNUSED_ALWAYS(PointCellRelative);
TRACE2("Mouse double-clicked in cell at x=%i y=%i\n", PointCellRelative.x,
PointCellRelative.y);
}
// Return TRUE if you set the cursor
BOOL CGridCellBase::OnSetCursor()
{
#ifndef _WIN32_WCE_NO_CURSOR
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
#endif
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellBase editing
void CGridCellBase::OnEndEdit()
{
ASSERT( FALSE);
}
BOOL CGridCellBase::ValidateEdit(LPCTSTR str)
{
UNUSED_ALWAYS(str);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellBase Sizing
BOOL CGridCellBase::GetTextRect( LPRECT pRect) // i/o: i=dims of cell rect;
o=dims of text rect
{
if (GetImage() >= 0)
{
IMAGEINFO Info;
CGridCtrl* pGrid = GetGrid();
CImageList* pImageList = pGrid->GetImageList();
if (pImageList && pImageList->GetImageInfo( GetImage(), &Info))
{
int nImageWidth = Info.rcImage.right-Info.rcImage.left; //+1;
pRect->left += nImageWidth + GetMargin();
}
}
return TRUE;
}
// By default this uses the selected font (which is a bigger font)
CSize CGridCellBase::GetTextExtent(LPCTSTR szText, CDC* pDC /*= NULL*/)
{
CGridCtrl* pGrid = GetGrid();
ASSERT(pGrid);
BOOL bReleaseDC = FALSE;
if (pDC == NULL || szText == NULL)
{
if (szText)
pDC = pGrid->GetDC();
if (pDC == NULL || szText == NULL)
{
CGridDefaultCell* pDefCell = (CGridDefaultCell*) GetDefaultCell();
ASSERT(pDefCell);
return CSize(pDefCell->GetWidth(), pDefCell->GetHeight());
}
bReleaseDC = TRUE;
}
CFont *pOldFont = NULL,
*pFont = GetFontObject();
if (pFont)
pOldFont = pDC->SelectObject(pFont);
CSize size;
int nFormat = GetFormat();
// If the cell is a multiline cell, then use the width of the cell
// to get the height
if ((nFormat & DT_WORDBREAK) && !(nFormat & DT_SINGLELINE))
{
CString str = szText;
int nMaxWidth = 0;
while (TRUE)
{
int nPos = str.Find(_T('\n'));
CString TempStr = (nPos < 0)? str : str.Left(nPos);
int nTempWidth = pDC->GetTextExtent(TempStr).cx;
if (nTempWidth > nMaxWidth)
nMaxWidth = nTempWidth;
if (nPos < 0)
break;
str = str.Mid(nPos + 1); // Bug fix by Thomas Steinborn
}
CRect rect;
rect.SetRect(0,0, nMaxWidth+1, 0);
pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT);
size = rect.Size();
}
else
size = pDC->GetTextExtent(szText, _tcslen(szText));
// Removed by Yogurt
//TEXTMETRIC tm;
//pDC->GetTextMetrics(&tm);
//size.cx += (tm.tmOverhang);
if (pOldFont)
pDC->SelectObject(pOldFont);
size += CSize(2*GetMargin(), 2*GetMargin());
// Kludge for vertical text
LOGFONT *pLF = GetFont();
if (pLF->lfEscapement == 900 || pLF->lfEscapement == -900)
{
int nTemp = size.cx;
size.cx = size.cy;
size.cy = nTemp;
size += CSize(0, 4*GetMargin());
}
if (bReleaseDC)
pGrid->ReleaseDC(pDC);
return size;
}
CSize CGridCellBase::GetCellExtent(CDC* pDC)
{
CSize size = GetTextExtent(GetText(), pDC);
CSize ImageSize(0,0);
int nImage = GetImage();
if (nImage >= 0)
{
CGridCtrl* pGrid = GetGrid();
ASSERT(pGrid);
IMAGEINFO Info;
if (pGrid->GetImageList() &&
pGrid->GetImageList()->GetImageInfo(nImage, &Info))
{
ImageSize = CSize(Info.rcImage.right-Info.rcImage.left,
Info.rcImage.bottom-Info.rcImage.top);
if (size.cx > 2*(int)GetMargin ())
ImageSize.cx += GetMargin();
ImageSize.cy += 2*(int)GetMargin ();
}
}
size.cx += ImageSize.cx + 1;
size.cy = max(size.cy, ImageSize.cy) + 1;
if (IsFixed())
{
size.cx++;
size.cy++;
}
return size;
}
// EFW - Added to print cells so that grids that use different colors are
// printed correctly.
BOOL CGridCellBase::PrintCell(CDC* pDC, int /*nRow*/, int /*nCol*/, CRect rect)
{
#if defined(_WIN32_WCE_NO_PRINTING) || defined(GRIDCONTROL_NO_PRINTING)
return FALSE;
#else
COLORREF crFG, crBG;
GV_ITEM Item;
CGridCtrl* pGrid = GetGrid();
if (!pGrid || !pDC)
return FALSE;
if( rect.Width() <= 0
|| rect.Height() <= 0) // prevents imagelist item from drawing even
return FALSE; // though cell is hidden
int nSavedDC = pDC->SaveDC();
pDC->SetBkMode(TRANSPARENT);
if (pGrid->GetShadedPrintOut())
{
// Get the default cell implementation for this kind of cell. We use it
if this cell
// has anything marked as "default"
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
if (!pDefaultCell)
return FALSE;
// Use custom color if it doesn't match the default color and the
// default grid background color. If not, leave it alone.
if(IsFixed())
crBG = (GetBackClr() != CLR_DEFAULT) ? GetBackClr() :
pDefaultCell->GetBackClr();
else
crBG = (GetBackClr() != CLR_DEFAULT && GetBackClr() !=
pDefaultCell->GetBackClr()) ?
GetBackClr() : CLR_DEFAULT;
// Use custom color if the background is different or if it doesn't
// match the default color and the default grid text color.
if(IsFixed())
crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() :
pDefaultCell->GetTextClr();
else
crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() :
pDefaultCell->GetTextClr();
// If not printing on a color printer, adjust the foreground color
// to a gray scale if the background color isn't used so that all
// colors will be visible. If not, some colors turn to solid black
// or white when printed and may not show up. This may be caused by
// coarse dithering by the printer driver too (see image note below).
if(pDC->GetDeviceCaps(NUMCOLORS) == 2 && crBG == CLR_DEFAULT)
crFG = RGB(GetRValue(crFG) * 0.30, GetGValue(crFG) * 0.59,
GetBValue(crFG) * 0.11);
// Only erase the background if the color is not the default
// grid background color.
if(crBG != CLR_DEFAULT)
{
CBrush brush(crBG);
rect.right++; rect.bottom++;
pDC->FillRect(rect, &brush);
rect.right--; rect.bottom--;
}
}
else
{
crBG = CLR_DEFAULT;
crFG = RGB(0, 0, 0);
}
pDC->SetTextColor(crFG);
CFont *pFont = GetFontObject();
if (pFont)
pDC->SelectObject(pFont);
/*
// ***************************************************
// Disabled - if you need this functionality then you'll need to rewrite.
// Create the appropriate font and select into DC.
CFont Font;
// Bold the fixed cells if not shading the print out. Use italic
// font it it is enabled.
const LOGFONT* plfFont = GetFont();
if(IsFixed() && !pGrid->GetShadedPrintOut())
{
Font.CreateFont(plfFont->lfHeight, 0, 0, 0, FW_BOLD, plfFont->lfItalic,
0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
#ifndef _WIN32_WCE
PROOF_QUALITY,
#else
DEFAULT_QUALITY,
#endif
VARIABLE_PITCH | FF_SWISS, plfFont->lfFaceName);
}
else
Font.CreateFontIndirect(plfFont);
pDC->SelectObject(&Font);
// ***************************************************
*/
// Draw lines only when wanted on fixed cells. Normal cell grid lines
// are handled in OnPrint.
if(pGrid->GetGridLines() != GVL_NONE && IsFixed())
{
CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)),
darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)),
*pOldPen = pDC->GetCurrentPen();
pDC->SelectObject(&lightpen);
pDC->MoveTo(rect.right, rect.top);
pDC->LineTo(rect.left, rect.top);
pDC->LineTo(rect.left, rect.bottom);
pDC->SelectObject(&darkpen);
pDC->MoveTo(rect.right, rect.top);
pDC->LineTo(rect.right, rect.bottom);
pDC->LineTo(rect.left, rect.bottom);
rect.DeflateRect(1,1);
pDC->SelectObject(pOldPen);
}
rect.DeflateRect(GetMargin(), 0);
if(pGrid->GetImageList() && GetImage() >= 0)
{
// NOTE: If your printed images look like fuzzy garbage, check the
// settings on your printer driver. If it's using coarse
// dithering and/or vector graphics, they may print wrong.
// Changing to fine dithering and raster graphics makes them
// print properly. My HP 4L had that problem.
IMAGEINFO Info;
if(pGrid->GetImageList()->GetImageInfo(GetImage(), &Info))
{
int nImageWidth = Info.rcImage.right-Info.rcImage.left;
pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(),
ILD_NORMAL);
rect.left += nImageWidth+GetMargin();
}
}
// Draw without clipping so as not to lose text when printed for real
// DT_NOCLIP removed 01.01.01. Slower, but who cares - we are printing!
DrawText(pDC->m_hDC, GetText(), -1, rect,
GetFormat() | /*DT_NOCLIP | */ DT_NOPREFIX);
pDC->RestoreDC(nSavedDC);
return TRUE;
#endif
}
/*****************************************************************************
Callable by derived classes, only
*****************************************************************************/
LRESULT CGridCellBase::SendMessageToParent(int nRow, int nCol, int nMessage)
{
CGridCtrl* pGrid = GetGrid();
if( pGrid)
return pGrid->SendMessageToParent(nRow, nCol, nMessage);
else
return 0;
}
--- NEW FILE: GridCellCheck.h ---
#if
!defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
#define AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
/////////////////////////////////////////////////////////////////////////////
// GridCellCheck.h : header file
//
// MFC Grid Control - Grid combo cell class header file
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.22+
//
//////////////////////////////////////////////////////////////////////
#include "GridCell.h"
class CGridCellCheck : public CGridCell
{
friend class CGridCtrl;
DECLARE_DYNCREATE(CGridCellCheck)
public:
CGridCellCheck();
public:
BOOL SetCheck(BOOL bChecked = TRUE);
BOOL GetCheck();
// Operations
virtual CSize GetCellExtent(CDC* pDC);
virtual void OnClick( CPoint PointCellRelative);
virtual BOOL GetTextRect( LPRECT pRect);
protected:
CRect GetCheckPlacement();
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd = TRUE);
protected:
BOOL m_bChecked;
CRect m_Rect;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
--- NEW FILE: GridCellURL.cpp ---
// GridCellURL.cpp: implementation of the CGridCellURL class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GridCellURL.h"
#include "GridCtrl.h"
IMPLEMENT_DYNCREATE(CGridCellURL, CGridCell)
#ifndef _WIN32_WCE
HCURSOR CGridCellURL::g_hLinkCursor = NULL;
#endif
// Possible prefixes that indicate a hyperlink
URLStruct CGridCellURL::g_szURIprefixes[] = {
{ _T("www."), _tcslen(_T("www.")) },
{ _T("http:"), _tcslen(_T("http:")) },
{ _T("mailto:"), _tcslen(_T("mailto:")) },
{ _T("ftp:"), _tcslen(_T("ftp:")) },
{ _T("https:"), _tcslen(_T("https:")) },
{ _T("news:"), _tcslen(_T("news:")) },
{ _T("gopher:"), _tcslen(_T("gopher:")) },
{ _T("telnet:"), _tcslen(_T("telnet:")) },
{ _T("url:"), _tcslen(_T("url:")) },
{ _T("file:"), _tcslen(_T("file:")) },
{ _T("ftp."), _tcslen(_T("ftp.")) }
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGridCellURL::CGridCellURL()
{
#ifndef _WIN32_WCE
g_hLinkCursor = GetHandCursor();
#endif
m_bLaunchUrl = TRUE;
m_clrUrl = GetSysColor(COLOR_HIGHLIGHT);
m_clrOld = CLR_NONE;
}
CGridCellURL::~CGridCellURL()
{
}
BOOL CGridCellURL::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd)
{
// If url is present then change text color
if (HasUrl(GetText()))
{
if (m_clrOld == CLR_NONE)
{
LOGFONT lf;
GetFontObject()->GetLogFont(&lf);
lf.lfUnderline = TRUE;
SetFont(&lf);
m_clrOld = GetTextClr();
SetTextClr(m_clrUrl);
}
}
else if (m_clrOld != CLR_NONE)
{
LOGFONT lf;
GetFontObject()->GetLogFont(&lf);
lf.lfUnderline = FALSE;
SetFont(&lf);
SetTextClr(m_clrOld);
m_clrOld = CLR_NONE;
}
// Good a place as any to store the bounds of the rect
m_Rect = rect;
return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
}
void CGridCellURL::OnClick(CPoint PointCellRelative)
{
#ifndef _WIN32_WCE
CString strURL;
if (GetAutoLaunchUrl() && OverURL(PointCellRelative, strURL))
ShellExecute(NULL, _T("open"), strURL, NULL,NULL, SW_SHOW);
#endif
}
// Return TRUE if you set the cursor
BOOL CGridCellURL::OnSetCursor()
{
#ifndef _WIN32_WCE
CString strURL;
CPoint pt(GetMessagePos());
GetGrid()->ScreenToClient(&pt);
pt = pt - m_Rect.TopLeft();
if (!m_bEditing && OverURL(pt, strURL))
{
SetCursor(g_hLinkCursor);
return TRUE;
}
else
#endif
return CGridCell::OnSetCursor();
}
#ifndef _WIN32_WCE
HCURSOR CGridCellURL::GetHandCursor()
{
if (g_hLinkCursor == NULL) // No cursor handle - load our
own
{
// Get the windows directory
CString strWndDir;
GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
strWndDir.ReleaseBuffer();
strWndDir += _T("\\winhlp32.exe");
// This retrieves cursor #106 from winhlp32.exe, which is a
hand pointer
HMODULE hModule = LoadLibrary(strWndDir);
if( hModule )
{
HCURSOR hHandCursor = ::LoadCursor(hModule,
MAKEINTRESOURCE(106));
if( hHandCursor )
{
g_hLinkCursor = CopyCursor(hHandCursor);
}
}
FreeLibrary(hModule);
}
return g_hLinkCursor;
}
#endif
////////////////////////////////////////////////////////////////////////////////////////////
// Helper functions
BOOL CGridCellURL::HasUrl(CString str)
{
int nNumPrefixes = sizeof(g_szURIprefixes) / sizeof(g_szURIprefixes[0]);
for (int i = 0; i < nNumPrefixes; i++)
//if (str.Left(g_szURIprefixes[i].nLength) ==
g_szURIprefixes[i].szURLPrefix)
if (str.Find(g_szURIprefixes[i].szURLPrefix) >= 0)
return TRUE;
return FALSE;
}
// here we figure out if we are over a URL or not
BOOL CGridCellURL::OverURL(CPoint& pt, CString& strURL)
{
//TRACE2("Checking point %d,%d\n",pt.x,pt.y);
BOOL bOverURL = FALSE;
CSize size = GetTextExtent(GetText());
// Add left of cell so we know if we clicked on text or not
pt.x += m_Rect.left;
CPoint center = m_Rect.CenterPoint();
if ((m_nFormat & DT_RIGHT) && pt.x >= (m_Rect.right - size.cx))
{
bOverURL = TRUE;
}
else if ((m_nFormat & DT_CENTER) &&
((center.x - (size.cx/2)) <= pt.x) && (pt.x <= (center.x +
(size.cx/2))) )
{
bOverURL = TRUE;
}
else if (pt.x <= (size.cx + m_Rect.left))
{
bOverURL = TRUE;
}
if (!bOverURL)
return FALSE;
// We are over text - but are we over a URL?
bOverURL = FALSE;
strURL = GetText();
// Use float, otherwise we get an incorrect letter from the point
float width = (float)size.cx/(float)strURL.GetLength();
// remove left of cell so we have original point again
pt.x -= m_Rect.left;
if (m_nFormat & DT_RIGHT)
{
int wide = m_Rect.Width() - size.cx;
pt.x -= wide;
if (pt.x <= 0)
return FALSE;
}
if (m_nFormat & DT_CENTER)
{
int wide = m_Rect.Width() - size.cx;
pt.x -= (wide/2);
if (pt.x <= 0 || pt.x > (size.cx + (wide/2)))
return FALSE;
}
// Turn point into a letter
int ltrs = (int)((float)pt.x/width);
#if !defined(_WIN32_WCE) || (_WIN32_WCE > 210)
// Find spaces before and after letter, process text between
int endSpace = strURL.Find(_T(' '), ltrs);
if (endSpace != -1)
strURL.Delete(endSpace, strURL.GetLength()-endSpace);
int beginSpace = strURL.ReverseFind(_T(' '));
if (beginSpace != -1)
strURL.Delete(0, ++beginSpace);
#endif
// Does text have url
return HasUrl(strURL);
}
--- NEW FILE: GridCellNumeric.cpp ---
// GridCellNumeric.cpp: implementation of the CGridCellNumeric class.
//
// Written by Andrew Truckle [EMAIL PROTECTED]
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "GridCellNumeric.h"
#include "InPlaceEdit.h"
#include "GridCtrl.h"
IMPLEMENT_DYNCREATE(CGridCellNumeric, CGridCell)
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// Create a control to do the editing
BOOL CGridCellNumeric::Edit(int nRow, int nCol, CRect rect, CPoint /* point */,
UINT nID, UINT nChar)
{
m_bEditing = TRUE;
// CInPlaceEdit auto-deletes itself
m_pEditWnd = new CInPlaceEdit(GetGrid(), rect, /*GetStyle() |*/ ES_NUMBER,
nID, nRow, nCol,
GetText(), nChar);
return TRUE;
}
// Cancel the editing.
void CGridCellNumeric::EndEdit()
{
if (m_pEditWnd)
((CInPlaceEdit*)m_pEditWnd)->EndEdit();
}
--- NEW FILE: GridCtrl.cpp ---
// GridCtrl.cpp : implementation file
//
// MFC Grid Control v2.25
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// The code contained in this file was based on the original
// WorldCom Grid control written by Joe Willcoxson,
// mailto:[EMAIL PROTECTED]
// http://users.aol.com/chinajoe
// (These addresses may be out of date) The code has gone through
// so many modifications that I'm not sure if there is even a single
// original line of code. In any case Joe's code was a great
// framework on which to build.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
[...7269 lines suppressed...]
ASSERT(pCell);
if (!pCell)
return TRUE;
return pCell->ValidateEdit(str);
}
// virtual
CString CGridCtrl::GetItemText(int nRow, int nCol) const
{
if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols)
return _T("");
CGridCellBase* pCell = GetCell(nRow, nCol);
ASSERT(pCell);
if (!pCell)
return _T("");
return pCell->GetText();
}
--- NEW FILE: InPlaceEdit.cpp ---
// InPlaceEdit.cpp : implementation file
//
// Adapted by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// The code contained in this file is based on the original
// CInPlaceEdit from http://www.codeguru.com/listview/edit_subitems.shtml
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
// History:
// 10 May 1998 Uses GVN_ notifications instead of LVN_,
// Sends notification messages to the parent,
// instead of the parent's parent.
// 15 May 1998 There was a problem when editing with the in-place
editor,
// there arises a general protection fault in user.exe,
with a
// few qualifications:
// (1) This only happens with owner-drawn buttons;
// (2) This only happens in Win95
// (3) This only happens if the handler for the button
does not
// create a new window (even an AfxMessageBox will
avoid the
// crash)
// (4) This will not happen if Spy++ is running.
// PreTranslateMessage was added to route messages
correctly.
// (Matt Weagle found and fixed this problem)
// 26 Jul 1998 Removed the ES_MULTILINE style - that fixed a few probs!
// 6 Aug 1998 Added nID to the constructor param list
// 6 Sep 1998 Space no longer clears selection when starting edit
(Franco Bez)
// 10 Apr 1999 Enter, Tab and Esc key prob fixed (Koay Kah Hoe)
// Workaround for bizzare "shrinking window" problem in CE
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TCHAR.h"
#include "InPlaceEdit.h"
#include "GridCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CInPlaceEdit
CInPlaceEdit::CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
int nRow, int nColumn, CString sInitText,
UINT nFirstChar)
{
m_sInitText = sInitText;
m_nRow = nRow;
m_nColumn = nColumn;
m_nLastChar = 0;
m_bExitOnArrows = (nFirstChar != VK_LBUTTON); // If mouse click brought
us here,
// then no exit on arrows
m_Rect = rect; // For bizarre CE bug.
DWORD dwEditStyle = WS_BORDER|WS_CHILD|WS_VISIBLE| ES_AUTOHSCROLL
//|ES_MULTILINE
| dwStyle;
if (!Create(dwEditStyle, rect, pParent, nID)) return;
SetFont(pParent->GetFont());
SetWindowText(sInitText);
SetFocus();
switch (nFirstChar){
case VK_LBUTTON:
case VK_RETURN: SetSel((int)_tcslen(m_sInitText), -1); return;
case VK_BACK: SetSel((int)_tcslen(m_sInitText), -1); break;
case VK_TAB:
case VK_DOWN:
case VK_UP:
case VK_RIGHT:
case VK_LEFT:
case VK_NEXT:
case VK_PRIOR:
case VK_HOME:
case VK_SPACE:
case VK_END: SetSel(0,-1); return;
default: SetSel(0,-1);
}
// Added by KiteFly. When entering DBCS chars into cells the first char was
being lost
// SenMessage changed to PostMessage (John Lagerquist)
if( nFirstChar < 0x80)
PostMessage(WM_CHAR, nFirstChar);
else
PostMessage(WM_IME_CHAR, nFirstChar);
}
CInPlaceEdit::~CInPlaceEdit()
{
}
BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
//{{AFX_MSG_MAP(CInPlaceEdit)
ON_WM_KILLFOCUS()
ON_WM_CHAR()
ON_WM_KEYDOWN()
ON_WM_GETDLGCODE()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////
// CInPlaceEdit message handlers
// If an arrow key (or associated) is pressed, then exit if
// a) The Ctrl key was down, or
// b) m_bExitOnArrows == TRUE
void CInPlaceEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
nChar == VK_DOWN || nChar == VK_UP ||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
{
m_nLastChar = nChar;
GetParent()->SetFocus();
return;
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
// As soon as this edit loses focus, kill it.
void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
EndEdit();
}
void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_TAB || nChar == VK_RETURN)
{
m_nLastChar = nChar;
GetParent()->SetFocus(); // This will destroy this window
return;
}
if (nChar == VK_ESCAPE)
{
SetWindowText(m_sInitText); // restore previous text
m_nLastChar = nChar;
GetParent()->SetFocus();
return;
}
CEdit::OnChar(nChar, nRepCnt, nFlags);
// Resize edit control if needed
// Get text extent
CString str;
GetWindowText( str );
// add some extra buffer
str += _T(" ");
CWindowDC dc(this);
CFont *pFontDC = dc.SelectObject(GetFont());
CSize size = dc.GetTextExtent( str );
dc.SelectObject( pFontDC );
// Get client rect
CRect ParentRect;
GetParent()->GetClientRect( &ParentRect );
// Check whether control needs to be resized
// and whether there is space to grow
if (size.cx > m_Rect.Width())
{
if( size.cx + m_Rect.left < ParentRect.right )
m_Rect.right = m_Rect.left + size.cx;
else
m_Rect.right = ParentRect.right;
MoveWindow( &m_Rect );
}
}
UINT CInPlaceEdit::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
////////////////////////////////////////////////////////////////////////////
// CInPlaceEdit overrides
// Stoopid win95 accelerator key problem workaround - Matt Weagle.
BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
{
// Catch the Alt key so we don't choke if focus is going to an owner drawn
button
if (pMsg->message == WM_SYSCHAR)
return TRUE;
return CWnd::PreTranslateMessage(pMsg);
}
// Auto delete
void CInPlaceEdit::PostNcDestroy()
{
CEdit::PostNcDestroy();
delete this;
}
////////////////////////////////////////////////////////////////////////////
// CInPlaceEdit implementation
void CInPlaceEdit::EndEdit()
{
CString str;
// EFW - BUG FIX - Clicking on a grid scroll bar in a derived class
// that validates input can cause this to get called multiple times
// causing assertions because the edit control goes away the first time.
static BOOL bAlreadyEnding = FALSE;
if(bAlreadyEnding)
return;
bAlreadyEnding = TRUE;
GetWindowText(str);
// Send Notification to parent
GV_DISPINFO dispinfo;
dispinfo.hdr.hwndFrom = GetSafeHwnd();
dispinfo.hdr.idFrom = GetDlgCtrlID();
dispinfo.hdr.code = GVN_ENDLABELEDIT;
dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
dispinfo.item.row = m_nRow;
dispinfo.item.col = m_nColumn;
dispinfo.item.strText = str;
dispinfo.item.lParam = (LPARAM) m_nLastChar;
CWnd* pOwner = GetOwner();
if (pOwner)
pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
// Close this window (PostNcDestroy will delete this)
if (IsWindow(GetSafeHwnd()))
SendMessage(WM_CLOSE, 0, 0);
bAlreadyEnding = FALSE;
}
--- NEW FILE: GridDropTarget.h ---
//////////////////////////////////////////////////////////////////////
// GridDropTarget.h : header file
//
// MFC Grid Control - Drag/Drop target implementation
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
//////////////////////////////////////////////////////////////////////
#if
!defined(AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_)
#define AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include <afxole.h>
class CGridCtrl;
/////////////////////////////////////////////////////////////////////////////
// CGridDropTarget command target
class CGridDropTarget : public COleDropTarget
{
public:
CGridDropTarget();
virtual ~CGridDropTarget();
// Attributes
public:
CGridCtrl* m_pGridCtrl;
BOOL m_bRegistered;
// Operations
public:
BOOL Register(CGridCtrl *pGridCtrl);
virtual void Revoke();
BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT
dropEffect, CPoint point);
DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD
dwKeyState, CPoint point);
void OnDragLeave(CWnd* pWnd);
DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD
dwKeyState, CPoint point);
DROPEFFECT OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGridDropTarget)
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CGridDropTarget)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_)
--- NEW FILE: GridCellBase.h ---
/////////////////////////////////////////////////////////////////////////////
// GridCellBase.h : header file
//
// MFC Grid Control - Grid cell base class header file
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.22+
//
//////////////////////////////////////////////////////////////////////
#if
!defined(AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class CGridCtrl;
// Cell states
#define GVIS_FOCUSED 0x0001
#define GVIS_SELECTED 0x0002
#define GVIS_DROPHILITED 0x0004
#define GVIS_READONLY 0x0008
#define GVIS_FIXED 0x0010
#define GVIS_FIXEDROW 0x0020
#define GVIS_FIXEDCOL 0x0040
#define GVIS_MODIFIED 0x0080
// Cell data mask
#define GVIF_TEXT LVIF_TEXT
#define GVIF_IMAGE LVIF_IMAGE
#define GVIF_PARAM LVIF_PARAM
#define GVIF_STATE LVIF_STATE
#define GVIF_BKCLR (GVIF_STATE<<1)
#define GVIF_FGCLR (GVIF_STATE<<2)
#define GVIF_FORMAT (GVIF_STATE<<3)
#define GVIF_FONT (GVIF_STATE<<4)
#define GVIF_MARGIN (GVIF_STATE<<5)
#define GVIF_ALL
(GVIF_TEXT|GVIF_IMAGE|GVIF_PARAM|GVIF_STATE|GVIF_BKCLR|GVIF_FGCLR| \
GVIF_FORMAT|GVIF_FONT|GVIF_MARGIN)
// Used for Get/SetItem calls.
typedef struct _GV_ITEM {
int row,col; // Row and Column of item
UINT mask; // Mask for use in getting/setting cell data
UINT nState; // cell state (focus/hilighted etc)
DWORD nFormat; // Format of cell
int iImage; // index of the list view items icon
COLORREF crBkClr; // Background colour (or CLR_DEFAULT)
COLORREF crFgClr; // Forground colour (or CLR_DEFAULT)
LPARAM lParam; // 32-bit value to associate with item
LOGFONT lfFont; // Cell font
UINT nMargin; // Internal cell margin
CString strText; // Text in cell
} GV_ITEM;
// Each cell contains one of these. Fields "row" and "column" are not stored
since we
// will usually have acces to them in other ways, and they are an extra 8 bytes
per
// cell that is probably unnecessary.
class CGridCellBase : public CObject
{
friend class CGridCtrl;
DECLARE_DYNAMIC(CGridCellBase)
// Construction/Destruction
public:
CGridCellBase();
virtual ~CGridCellBase();
// Attributes
public:
virtual void SetText(LPCTSTR /* szText */) = 0 ;
virtual void SetImage(int /* nImage */) = 0 ;
virtual void SetData(LPARAM /* lParam */) = 0 ;
virtual void SetState(DWORD nState) { m_nState =
nState; }
virtual void SetFormat(DWORD /* nFormat */) = 0 ;
virtual void SetTextClr(COLORREF /* clr */) = 0 ;
virtual void SetBackClr(COLORREF /* clr */) = 0 ;
virtual void SetFont(const LOGFONT* /* plf */) = 0 ;
virtual void SetMargin( UINT /* nMargin */) = 0 ;
virtual void SetGrid(CGridCtrl* /* pGrid */) = 0 ;
virtual void SetCoords( int /* nRow */, int /* nCol */) = 0 ;
virtual LPCTSTR GetText() const = 0 ;
virtual LPCTSTR GetTipText() const { return GetText();
} // may override TitleTip return
virtual int GetImage() const = 0 ;
virtual LPARAM GetData() const = 0 ;
virtual DWORD GetState() const { return m_nState;
}
virtual DWORD GetFormat() const = 0 ;
virtual COLORREF GetTextClr() const = 0 ;
virtual COLORREF GetBackClr() const = 0 ;
virtual LOGFONT * GetFont() const = 0 ;
virtual CFont * GetFontObject() const = 0 ;
virtual CGridCtrl* GetGrid() const = 0 ;
virtual CWnd * GetEditWnd() const = 0 ;
virtual UINT GetMargin() const = 0 ;
virtual CGridCellBase* GetDefaultCell() const;
virtual BOOL IsDefaultFont() const = 0 ;
virtual BOOL IsEditing() const = 0 ;
virtual BOOL IsFocused() const { return (m_nState
& GVIS_FOCUSED); }
virtual BOOL IsFixed() const { return (m_nState
& GVIS_FIXED); }
virtual BOOL IsFixedCol() const { return (m_nState
& GVIS_FIXEDCOL); }
virtual BOOL IsFixedRow() const { return (m_nState
& GVIS_FIXEDROW); }
virtual BOOL IsSelected() const { return (m_nState
& GVIS_SELECTED); }
virtual BOOL IsReadOnly() const { return (m_nState
& GVIS_READONLY); }
virtual BOOL IsModified() const { return (m_nState
& GVIS_MODIFIED); }
virtual BOOL IsDropHighlighted() const { return (m_nState
& GVIS_DROPHILITED); }
// Operators
public:
virtual void operator=(const CGridCellBase& cell);
// Operations
public:
virtual void Reset();
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd = TRUE);
virtual BOOL GetTextRect( LPRECT pRect); // i/o: i=dims of cell rect;
o=dims of text rect
virtual BOOL GetTipTextRect( LPRECT pRect) { return GetTextRect( pRect); }
// may override for btns, etc.
virtual CSize GetTextExtent(LPCTSTR str, CDC* pDC = NULL);
virtual CSize GetCellExtent(CDC* pDC);
// Editing
virtual BOOL Edit( int /* nRow */, int /* nCol */, CRect /* rect */, CPoint
/* point */,
UINT /* nID */, UINT /* nChar */) { ASSERT( FALSE);
return FALSE;}
virtual BOOL ValidateEdit(LPCTSTR str);
virtual void EndEdit() {}
// EFW - Added to print cells properly
virtual BOOL PrintCell(CDC* pDC, int nRow, int nCol, CRect rect);
// add additional protected grid members required of cells
LRESULT SendMessageToParent(int nRow, int nCol, int nMessage);
protected:
virtual void OnEndEdit();
virtual void OnMouseEnter();
virtual void OnMouseOver();
virtual void OnMouseLeave();
virtual void OnClick( CPoint PointCellRelative);
virtual void OnClickDown( CPoint PointCellRelative);
virtual void OnRClick( CPoint PointCellRelative);
virtual void OnDblClick( CPoint PointCellRelative);
virtual BOOL OnSetCursor();
protected:
DWORD m_nState; // Cell state (selected/focus etc)
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
--- NEW FILE: StdAfx.h ---
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__19E18FB7_DFF6_11D1_8CE7_000000000000__INCLUDED_)
#define AFX_STDAFX_H__19E18FB7_DFF6_11D1_8CE7_000000000000__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows
headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC OLE automation classes
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common
Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_STDAFX_H__19E18FB7_DFF6_11D1_8CE7_000000000000__INCLUDED_)
--- NEW FILE: StdAfx.cpp ---
// stdafx.cpp : source file that includes just the standard includes
// GridViewDemo.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
--- NEW FILE: TitleTip.h ---
/////////////////////////////////////////////////////////////////////////////
// Titletip.h : header file
//
// MFC Grid Control - cell titletips
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2001. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_)
#define AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#define TITLETIP_CLASSNAME _T("ZTitleTip")
/////////////////////////////////////////////////////////////////////////////
// CTitleTip window
class CTitleTip : public CWnd
{
// Construction
public:
CTitleTip();
virtual ~CTitleTip();
virtual BOOL Create( CWnd *pParentWnd);
// Attributes
public:
void SetParentWnd(CWnd* pParentWnd) { m_pParentWnd = pParentWnd; }
CWnd* GetParentWnd() { return m_pParentWnd; }
// Operations
public:
void Show(CRect rectTitle, LPCTSTR lpszTitleText,
int xoffset = 0, LPRECT lpHoverRect = NULL,
const LOGFONT* lpLogFont = NULL,
COLORREF crTextClr = CLR_DEFAULT, COLORREF crBackClr =
CLR_DEFAULT);
void Hide();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTitleTip)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL DestroyWindow();
//}}AFX_VIRTUAL
// Implementation
protected:
CWnd *m_pParentWnd;
CRect m_rectTitle;
CRect m_rectHover;
DWORD m_dwLastLButtonDown;
DWORD m_dwDblClickMsecs;
BOOL m_bCreated;
// Generated message map functions
protected:
//{{AFX_MSG(CTitleTip)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_)
--- NEW FILE: GridDropTarget.cpp ---
// GridDropTarget.cpp : implementation file
//
// MFC Grid Control - Drag/Drop target implementation
//
// CGridDropTarget is an OLE drop target for CGridCtrl. All it does
// is handle the drag and drop windows messages and pass them
// directly onto the grid control.
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.10+
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GridCtrl.h"
#ifndef GRIDCONTROL_NO_DRAGDROP
#include "GridDropTarget.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CGridDropTarget
CGridDropTarget::CGridDropTarget()
{
m_pGridCtrl = NULL;
m_bRegistered = FALSE;
}
CGridDropTarget::~CGridDropTarget()
{
}
// Overloaded Register() function performs the normal COleDropTarget::Register
// but also serves to connect this COleDropTarget with the parent grid control,
// where all drop messages will ultimately be forwarded.
BOOL CGridDropTarget::Register(CGridCtrl *pGridCtrl)
{
if (m_bRegistered)
return FALSE;
// Stop re-entry problems
static BOOL bInProcedure = FALSE;
if (bInProcedure)
return FALSE;
bInProcedure = TRUE;
ASSERT(pGridCtrl->IsKindOf(RUNTIME_CLASS(CGridCtrl)));
ASSERT(pGridCtrl);
if (!pGridCtrl || !pGridCtrl->IsKindOf(RUNTIME_CLASS(CGridCtrl)))
{
bInProcedure = FALSE;
return FALSE;
}
m_pGridCtrl = pGridCtrl;
m_bRegistered = COleDropTarget::Register(pGridCtrl);
bInProcedure = FALSE;
return m_bRegistered;
}
void CGridDropTarget::Revoke()
{
m_bRegistered = FALSE;
COleDropTarget::Revoke();
}
BEGIN_MESSAGE_MAP(CGridDropTarget, COleDropTarget)
//{{AFX_MSG_MAP(CGridDropTarget)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGridDropTarget message handlers
DROPEFFECT CGridDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint
/*point*/)
{
// TRACE("In CGridDropTarget::OnDragScroll\n");
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
{
if (dwKeyState & MK_CONTROL)
return DROPEFFECT_COPY;
else
return DROPEFFECT_MOVE;
} else
return DROPEFFECT_NONE;
}
DROPEFFECT CGridDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject*
pDataObject,
DWORD dwKeyState, CPoint point)
{
TRACE(_T("In CGridDropTarget::OnDragEnter\n"));
ASSERT(m_pGridCtrl);
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
return m_pGridCtrl->OnDragEnter(pDataObject, dwKeyState, point);
else
return DROPEFFECT_NONE;
}
void CGridDropTarget::OnDragLeave(CWnd* pWnd)
{
TRACE(_T("In CGridDropTarget::OnDragLeave\n"));
ASSERT(m_pGridCtrl);
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
m_pGridCtrl->OnDragLeave();
}
DROPEFFECT CGridDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
// TRACE("In CGridDropTarget::OnDragOver\n");
ASSERT(m_pGridCtrl);
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
return m_pGridCtrl->OnDragOver(pDataObject, dwKeyState, point);
else
return DROPEFFECT_NONE;
}
BOOL CGridDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point)
{
TRACE(_T("In CGridDropTarget::OnDrop\n"));
ASSERT(m_pGridCtrl);
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
return m_pGridCtrl->OnDrop(pDataObject, dropEffect, point);
else
return FALSE;
}
#endif // GRIDCONTROL_NO_DRAGDROP
--- NEW FILE: GridCtrl.h ---
/////////////////////////////////////////////////////////////////////////////
// GridCtrl.h : header file
//
// MFC Grid Control - main header
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2004. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.20+
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "CellRange.h"
#include "GridCell.h"
#include <afxtempl.h>
///////////////////////////////////////////////////////////////////////////////////
// Defines - these determine the features (and the final size) of the final code
///////////////////////////////////////////////////////////////////////////////////
//#define GRIDCONTROL_NO_TITLETIPS // Do not use titletips for cells with
large data
//#define GRIDCONTROL_NO_DRAGDROP // Do not use OLE drag and drop
//#define GRIDCONTROL_NO_CLIPBOARD // Do not use clipboard routines
#ifdef _WIN32_WCE
# define GRIDCONTROL_NO_TITLETIPS // Do not use titletips for cells with
large data
# define GRIDCONTROL_NO_DRAGDROP // Do not use OLE drag and drop
# define GRIDCONTROL_NO_CLIPBOARD // Do not use clipboard routines
# define GRIDCONTROL_NO_PRINTING // Do not use printing routines
# ifdef WCE_NO_PRINTING // Older versions of CE had
different #def's
# define _WIN32_WCE_NO_PRINTING
# endif
# ifdef WCE_NO_CURSOR
# define _WIN32_WCE_NO_CURSOR
# endif
#endif // _WIN32_WCE
// Use this as the classname when inserting this control as a custom control
// in the MSVC++ dialog editor
#define GRIDCTRL_CLASSNAME _T("MFCGridCtrl") // Window class name
#define IDC_INPLACE_CONTROL 8 // ID of inplace edit controls
///////////////////////////////////////////////////////////////////////////////////
// Conditional includes
///////////////////////////////////////////////////////////////////////////////////
#ifndef GRIDCONTROL_NO_TITLETIPS
# include "TitleTip.h"
#endif
#ifndef GRIDCONTROL_NO_DRAGDROP
# include "GridDropTarget.h"
# undef GRIDCONTROL_NO_CLIPBOARD // Force clipboard functions on
#endif
#ifndef GRIDCONTROL_NO_CLIPBOARD
# include <afxole.h>
#endif
///////////////////////////////////////////////////////////////////////////////////
// Helper functions
///////////////////////////////////////////////////////////////////////////////////
// Handy functions
#define IsSHIFTpressed() ( (GetKeyState(VK_SHIFT) & (1 << (sizeof(SHORT)*8-1)))
!= 0 )
#define IsCTRLpressed() ( (GetKeyState(VK_CONTROL) & (1 <<
(sizeof(SHORT)*8-1))) != 0 )
// Backwards compatibility for pre 2.20 grid versions
#define DDX_GridControl(pDX, nIDC, rControl) DDX_Control(pDX, nIDC, rControl)
///////////////////////////////////////////////////////////////////////////////////
// Structures
///////////////////////////////////////////////////////////////////////////////////
// This structure sent to Grid's parent in a WM_NOTIFY message
typedef struct tagNM_GRIDVIEW {
NMHDR hdr;
int iRow;
int iColumn;
} NM_GRIDVIEW;
// This is sent to the Grid from child in-place edit controls
typedef struct tagGV_DISPINFO {
NMHDR hdr;
GV_ITEM item;
} GV_DISPINFO;
// This is sent to the Grid from child in-place edit controls
typedef struct tagGV_CACHEHINT {
NMHDR hdr;
CCellRange range;
} GV_CACHEHINT;
// storage typedef for each row in the grid
typedef CTypedPtrArray<CObArray, CGridCellBase*> GRID_ROW;
// For virtual mode callback
typedef BOOL (CALLBACK* GRIDCALLBACK)(GV_DISPINFO *, LPARAM);
///////////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////////
// Grid line/scrollbar selection
#define GVL_NONE 0L // Neither
#define GVL_HORZ 1L // Horizontal line or scrollbar
#define GVL_VERT 2L // Vertical line or scrollbar
#define GVL_BOTH 3L // Both
// Autosizing option
#define GVS_DEFAULT 0
#define GVS_HEADER 1 // Size using column fixed cells data
only
#define GVS_DATA 2 // Size using column non-fixed cells
data only
#define GVS_BOTH 3 // Size using column fixed and non-fixed
// Cell Searching options
#define GVNI_FOCUSED 0x0001
#define GVNI_SELECTED 0x0002
#define GVNI_DROPHILITED 0x0004
#define GVNI_READONLY 0x0008
#define GVNI_FIXED 0x0010
#define GVNI_MODIFIED 0x0020
#define GVNI_ABOVE LVNI_ABOVE
#define GVNI_BELOW LVNI_BELOW
#define GVNI_TOLEFT LVNI_TOLEFT
#define GVNI_TORIGHT LVNI_TORIGHT
#define GVNI_ALL (LVNI_BELOW|LVNI_TORIGHT|LVNI_TOLEFT)
#define GVNI_AREA (LVNI_BELOW|LVNI_TORIGHT)
// Hit test values (not yet implemented)
#define GVHT_DATA 0x0000
#define GVHT_TOPLEFT 0x0001
#define GVHT_COLHDR 0x0002
#define GVHT_ROWHDR 0x0004
#define GVHT_COLSIZER 0x0008
#define GVHT_ROWSIZER 0x0010
#define GVHT_LEFT 0x0020
#define GVHT_RIGHT 0x0040
#define GVHT_ABOVE 0x0080
#define GVHT_BELOW 0x0100
// Messages sent to the grid's parent (More will be added in future)
#define GVN_BEGINDRAG LVN_BEGINDRAG // LVN_FIRST-9
#define GVN_BEGINLABELEDIT LVN_BEGINLABELEDIT // LVN_FIRST-5
#define GVN_BEGINRDRAG LVN_BEGINRDRAG
#define GVN_COLUMNCLICK LVN_COLUMNCLICK
#define GVN_DELETEITEM LVN_DELETEITEM
#define GVN_ENDLABELEDIT LVN_ENDLABELEDIT // LVN_FIRST-6
#define GVN_SELCHANGING LVN_ITEMCHANGING
#define GVN_SELCHANGED LVN_ITEMCHANGED
#define GVN_GETDISPINFO LVN_GETDISPINFO
#define GVN_ODCACHEHINT LVN_ODCACHEHINT
#define GVN_CHANGEDLABELEDIT (LVN_FIRST+1)
class CGridCtrl;
/////////////////////////////////////////////////////////////////////////////
// CGridCtrl window
class CGridCtrl : public CWnd
{
DECLARE_DYNCREATE(CGridCtrl)
friend class CGridCell;
friend class CGridCellBase;
// Construction
public:
CGridCtrl(int nRows = 0, int nCols = 0, int nFixedRows = 0, int nFixedCols
= 0);
BOOL Create(const RECT& rect, CWnd* parent, UINT nID,
DWORD dwStyle = WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE);
///////////////////////////////////////////////////////////////////////////////////
// Attributes
///////////////////////////////////////////////////////////////////////////////////
public:
int GetRowCount() const { return m_nRows; }
int GetColumnCount() const { return m_nCols; }
int GetFixedRowCount() const { return m_nFixedRows; }
int GetFixedColumnCount() const { return m_nFixedCols; }
BOOL SetRowCount(int nRows = 10);
BOOL SetColumnCount(int nCols = 10);
BOOL SetFixedRowCount(int nFixedRows = 1);
BOOL SetFixedColumnCount(int nFixedCols = 1);
int GetRowHeight(int nRow) const;
BOOL SetRowHeight(int row, int height);
int GetColumnWidth(int nCol) const;
BOOL SetColumnWidth(int col, int width);
BOOL GetCellOrigin(int nRow, int nCol, LPPOINT p);
BOOL GetCellOrigin(const CCellID& cell, LPPOINT p);
BOOL GetCellRect(int nRow, int nCol, LPRECT pRect);
BOOL GetCellRect(const CCellID& cell, LPRECT pRect);
BOOL GetTextRect(const CCellID& cell, LPRECT pRect);
BOOL GetTextRect(int nRow, int nCol, LPRECT pRect);
CCellID GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck = TRUE);
int GetFixedRowHeight() const;
int GetFixedColumnWidth() const;
long GetVirtualWidth() const;
long GetVirtualHeight() const;
CSize GetTextExtent(int nRow, int nCol, LPCTSTR str);
// EFW - Get extent of current text in cell
inline CSize GetCellTextExtent(int nRow, int nCol) { return
GetTextExtent(nRow, nCol, GetItemText(nRow,nCol)); }
void SetGridBkColor(COLORREF clr) { m_crGridBkColour = clr;
}
COLORREF GetGridBkColor() const { return m_crGridBkColour;
}
void SetGridLineColor(COLORREF clr) { m_crGridLineColour = clr;
}
COLORREF GetGridLineColor() const { return m_crGridLineColour;
}
void SetTitleTipBackClr(COLORREF clr = CLR_DEFAULT) {
m_crTTipBackClr = clr; }
COLORREF GetTitleTipBackClr() { return
m_crTTipBackClr; }
void SetTitleTipTextClr(COLORREF clr = CLR_DEFAULT) {
m_crTTipTextClr = clr; }
COLORREF GetTitleTipTextClr() { return
m_crTTipTextClr; }
//
***************************************************************************** //
// These have been deprecated. Use GetDefaultCell and then set the colors
void SetTextColor(COLORREF clr) { m_cellDefault.SetTextClr(clr);
}
COLORREF GetTextColor() { return
m_cellDefault.GetTextClr(); }
void SetTextBkColor(COLORREF clr) { m_cellDefault.SetBackClr(clr);
}
COLORREF GetTextBkColor() { return
m_cellDefault.GetBackClr(); }
void SetFixedTextColor(COLORREF clr) {
m_cellFixedRowDef.SetTextClr(clr);
m_cellFixedColDef.SetTextClr(clr);
m_cellFixedRowColDef.SetTextClr(clr); }
COLORREF GetFixedTextColor() const { return
m_cellFixedRowDef.GetTextClr(); }
void SetFixedBkColor(COLORREF clr) {
m_cellFixedRowDef.SetBackClr(clr);
m_cellFixedColDef.SetBackClr(clr);
m_cellFixedRowColDef.SetBackClr(clr); }
COLORREF GetFixedBkColor() const { return
m_cellFixedRowDef.GetBackClr(); }
void SetGridColor(COLORREF clr) { SetGridLineColor(clr);
}
COLORREF GetGridColor() { return GetGridLineColor();
}
void SetBkColor(COLORREF clr) { SetGridBkColor(clr);
}
COLORREF GetBkColor() { return GetGridBkColor();
}
void SetDefCellMargin( int nMargin) { m_cellDefault.SetMargin(nMargin);
m_cellFixedRowDef.SetMargin(nMargin);
m_cellFixedColDef.SetMargin(nMargin);
m_cellFixedRowColDef.SetMargin(nMargin); }
int GetDefCellMargin() const { return
m_cellDefault.GetMargin(); }
int GetDefCellHeight() const { return
m_cellDefault.GetHeight(); }
void SetDefCellHeight(int nHeight) { m_cellDefault.SetHeight(nHeight);
m_cellFixedRowDef.SetHeight(nHeight);
m_cellFixedColDef.SetHeight(nHeight);
m_cellFixedRowColDef.SetHeight(nHeight); }
int GetDefCellWidth() const { return m_cellDefault.GetWidth();
}
void SetDefCellWidth(int nWidth) { m_cellDefault.SetWidth(nWidth);
m_cellFixedRowDef.SetWidth(nWidth);
m_cellFixedColDef.SetWidth(nWidth);
m_cellFixedRowColDef.SetWidth(nWidth); }
//
***************************************************************************** //
int GetSelectedCount() const { return
(int)m_SelectedCellMap.GetCount(); }
CCellID SetFocusCell(CCellID cell);
CCellID SetFocusCell(int nRow, int nCol);
CCellID GetFocusCell() const { return m_idCurrentCell;
}
void SetVirtualMode(BOOL bVirtual);
BOOL GetVirtualMode() const { return m_bVirtualMode;
}
void SetCallbackFunc(GRIDCALLBACK pCallback,
LPARAM lParam) { m_pfnCallback = pCallback;
m_lParam = lParam; }
GRIDCALLBACK GetCallbackFunc() { return m_pfnCallback;
}
void SetImageList(CImageList* pList) { m_pImageList = pList;
}
CImageList* GetImageList() const { return m_pImageList;
}
void SetGridLines(int nWhichLines = GVL_BOTH);
int GetGridLines() const { return m_nGridLines;
}
void SetEditable(BOOL bEditable = TRUE) { m_bEditable = bEditable;
}
BOOL IsEditable() const { return m_bEditable;
}
void SetListMode(BOOL bEnableListMode = TRUE);
BOOL GetListMode() const { return m_bListMode;
}
void SetSingleRowSelection(BOOL bSing = TRUE) { m_bSingleRowSelection =
bSing; }
BOOL GetSingleRowSelection() { return
m_bSingleRowSelection & m_bListMode; }
void SetSingleColSelection(BOOL bSing = TRUE) { m_bSingleColSelection =
bSing; }
BOOL GetSingleColSelection() { return
m_bSingleColSelection; }
void EnableSelection(BOOL bEnable = TRUE) { ResetSelectedRange();
m_bEnableSelection = bEnable; ResetSelectedRange(); }
BOOL IsSelectable() const { return m_bEnableSelection;
}
void SetFixedColumnSelection(BOOL bSelect) { m_bFixedColumnSelection =
bSelect;}
BOOL GetFixedColumnSelection() { return
m_bFixedColumnSelection; }
void SetFixedRowSelection(BOOL bSelect) { m_bFixedRowSelection =
bSelect; }
BOOL GetFixedRowSelection() { return
m_bFixedRowSelection; }
void EnableDragAndDrop(BOOL bAllow = TRUE) { m_bAllowDragAndDrop =
bAllow; }
BOOL GetDragAndDrop() const { return m_bAllowDragAndDrop;
}
void SetRowResize(BOOL bResize = TRUE) { m_bAllowRowResize =
bResize; }
BOOL GetRowResize() const { return m_bAllowRowResize;
}
void SetColumnResize(BOOL bResize = TRUE) { m_bAllowColumnResize =
bResize; }
BOOL GetColumnResize() const { return
m_bAllowColumnResize; }
void SetHeaderSort(BOOL bSortOnClick = TRUE) { m_bSortOnClick =
bSortOnClick; }
BOOL GetHeaderSort() const { return m_bSortOnClick;
}
void SetHandleTabKey(BOOL bHandleTab = TRUE) { m_bHandleTabKey =
bHandleTab; }
BOOL GetHandleTabKey() const { return m_bHandleTabKey;
}
void SetDoubleBuffering(BOOL bBuffer = TRUE) { m_bDoubleBuffer = bBuffer;
}
BOOL GetDoubleBuffering() const { return m_bDoubleBuffer;
}
void EnableTitleTips(BOOL bEnable = TRUE) { m_bTitleTips = bEnable;
}
BOOL GetTitleTips() { return m_bTitleTips;
}
void SetSortColumn(int nCol);
int GetSortColumn() const { return m_nSortColumn;
}
void SetSortAscending(BOOL bAscending) { m_bAscending = bAscending;
}
BOOL GetSortAscending() const { return m_bAscending;
}
void SetTrackFocusCell(BOOL bTrack) { m_bTrackFocusCell = bTrack;
}
BOOL GetTrackFocusCell() { return m_bTrackFocusCell;
}
void SetFrameFocusCell(BOOL bFrame) { m_bFrameFocus = bFrame;
}
BOOL GetFrameFocusCell() { return m_bFrameFocus;
}
void SetAutoSizeStyle(int nStyle = GVS_BOTH) { m_nAutoSizeColumnStyle =
nStyle; }
int GetAutoSizeStyle() { return
m_nAutoSizeColumnStyle; }
void EnableHiddenColUnhide(BOOL bEnable = TRUE){ m_bHiddenColUnhide =
bEnable; }
BOOL GetHiddenColUnhide() { return m_bHiddenColUnhide;
}
void EnableHiddenRowUnhide(BOOL bEnable = TRUE){ m_bHiddenRowUnhide =
bEnable; }
BOOL GetHiddenRowUnhide() { return m_bHiddenRowUnhide;
}
void EnableColumnHide(BOOL bEnable = TRUE) { m_bAllowColHide = bEnable;
}
BOOL GetColumnHide() { return m_bAllowColHide;
}
void EnableRowHide(BOOL bEnable = TRUE) { m_bAllowRowHide = bEnable;
}
BOOL GetRowHide() { return m_bAllowRowHide;
}
///////////////////////////////////////////////////////////////////////////////////
// default Grid cells. Use these for setting default values such as colors and
fonts
///////////////////////////////////////////////////////////////////////////////////
public:
CGridCellBase* GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const;
///////////////////////////////////////////////////////////////////////////////////
// Grid cell Attributes
///////////////////////////////////////////////////////////////////////////////////
public:
CGridCellBase* GetCell(int nRow, int nCol) const; // Get the actual cell!
void SetModified(BOOL bModified = TRUE, int nRow = -1, int nCol = -1);
BOOL GetModified(int nRow = -1, int nCol = -1);
BOOL IsCellFixed(int nRow, int nCol);
BOOL SetItem(const GV_ITEM* pItem);
BOOL GetItem(GV_ITEM* pItem);
BOOL SetItemText(int nRow, int nCol, LPCTSTR str);
// The following was virtual. If you want to override, use
// CGridCellBase-derived class's GetText() to accomplish same thing
CString GetItemText(int nRow, int nCol) const;
// EFW - 06/13/99 - Added to support printf-style formatting codes.
// Also supports use with a string resource ID
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 210)
BOOL SetItemTextFmt(int nRow, int nCol, LPCTSTR szFmt, ...);
BOOL SetItemTextFmtID(int nRow, int nCol, UINT nID, ...);
#endif
BOOL SetItemData(int nRow, int nCol, LPARAM lParam);
LPARAM GetItemData(int nRow, int nCol) const;
BOOL SetItemImage(int nRow, int nCol, int iImage);
int GetItemImage(int nRow, int nCol) const;
BOOL SetItemState(int nRow, int nCol, UINT state);
UINT GetItemState(int nRow, int nCol) const;
BOOL SetItemFormat(int nRow, int nCol, UINT nFormat);
UINT GetItemFormat(int nRow, int nCol) const;
BOOL SetItemBkColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
COLORREF GetItemBkColour(int nRow, int nCol) const;
BOOL SetItemFgColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
COLORREF GetItemFgColour(int nRow, int nCol) const;
BOOL SetItemFont(int nRow, int nCol, const LOGFONT* lf);
const LOGFONT* GetItemFont(int nRow, int nCol);
BOOL IsItemEditing(int nRow, int nCol);
BOOL SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass);
BOOL SetDefaultCellType( CRuntimeClass* pRuntimeClass);
///////////////////////////////////////////////////////////////////////////////////
// Operations
///////////////////////////////////////////////////////////////////////////////////
public:
int InsertColumn(LPCTSTR strHeading, UINT nFormat =
DT_CENTER|DT_VCENTER|DT_SINGLELINE,
int nColumn = -1);
int InsertRow(LPCTSTR strHeading, int nRow = -1);
BOOL DeleteColumn(int nColumn);
BOOL DeleteRow(int nRow);
BOOL DeleteNonFixedRows();
BOOL DeleteAllItems();
void ClearCells(CCellRange Selection);
BOOL AutoSizeRow(int nRow, BOOL bResetScroll = TRUE);
BOOL AutoSizeColumn(int nCol, UINT nAutoSizeStyle = GVS_DEFAULT, BOOL
bResetScroll = TRUE);
void AutoSizeRows();
void AutoSizeColumns(UINT nAutoSizeStyle = GVS_DEFAULT);
void AutoSize(UINT nAutoSizeStyle = GVS_DEFAULT);
void ExpandColumnsToFit(BOOL bExpandFixed = TRUE);
void ExpandLastColumn();
void ExpandRowsToFit(BOOL bExpandFixed = TRUE);
void ExpandToFit(BOOL bExpandFixed = TRUE);
void Refresh();
void AutoFill(); // Fill grid with blank cells
void EnsureVisible(CCellID &cell) { EnsureVisible(cell.row,
cell.col); }
void EnsureVisible(int nRow, int nCol);
BOOL IsCellVisible(int nRow, int nCol);
BOOL IsCellVisible(CCellID cell);
BOOL IsCellEditable(int nRow, int nCol) const;
BOOL IsCellEditable(CCellID &cell) const;
BOOL IsCellSelected(int nRow, int nCol) const;
BOOL IsCellSelected(CCellID &cell) const;
// SetRedraw stops/starts redraws on things like changing the # rows/columns
// and autosizing, but not for user-intervention such as resizes
void SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars = FALSE);
BOOL RedrawCell(int nRow, int nCol, CDC* pDC = NULL);
BOOL RedrawCell(const CCellID& cell, CDC* pDC = NULL);
BOOL RedrawRow(int row);
BOOL RedrawColumn(int col);
#ifndef _WIN32_WCE
BOOL Save(LPCTSTR filename, TCHAR chSeparator = _T(','));
BOOL Load(LPCTSTR filename, TCHAR chSeparator = _T(','));
#endif
///////////////////////////////////////////////////////////////////////////////////
// Cell Ranges
///////////////////////////////////////////////////////////////////////////////////
public:
CCellRange GetCellRange() const;
CCellRange GetSelectedCellRange() const;
void SetSelectedRange(const CCellRange& Range, BOOL bForceRepaint = FALSE,
BOOL bSelectCells = TRUE);
void SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol,
BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
BOOL IsValid(int nRow, int nCol) const;
BOOL IsValid(const CCellID& cell) const;
BOOL IsValid(const CCellRange& range) const;
///////////////////////////////////////////////////////////////////////////////////
// Clipboard, drag and drop, and cut n' paste operations
///////////////////////////////////////////////////////////////////////////////////
#ifndef GRIDCONTROL_NO_CLIPBOARD
virtual void CutSelectedText();
virtual COleDataSource* CopyTextFromGrid();
virtual BOOL PasteTextToGrid(CCellID cell, COleDataObject* pDataObject,
BOOL bSelectPastedCells=TRUE);
#endif
#ifndef GRIDCONTROL_NO_DRAGDROP
public:
virtual void OnBeginDrag();
virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject, DWORD
dwKeyState, CPoint point);
virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD
dwKeyState, CPoint point);
virtual void OnDragLeave();
virtual BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect,
CPoint point);
#endif
#ifndef GRIDCONTROL_NO_CLIPBOARD
virtual void OnEditCut();
virtual void OnEditCopy();
virtual void OnEditPaste();
#endif
virtual void OnEditSelectAll();
///////////////////////////////////////////////////////////////////////////////////
// Misc.
///////////////////////////////////////////////////////////////////////////////////
public:
CCellID GetNextItem(CCellID& cell, int nFlags) const;
/* $$LR$$ : Force virtual */
virtual BOOL SortItems(int nCol, BOOL bAscending, LPARAM data = 0);
BOOL SortTextItems(int nCol, BOOL bAscending, LPARAM data = 0);
BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM
data = 0);
void SetCompareFunction(PFNLVCOMPARE pfnCompare);
// in-built sort functions
static int CALLBACK pfnCellTextCompare(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort);
static int CALLBACK pfnCellNumericCompare(LPARAM lParam1, LPARAM
lParam2, LPARAM lParamSort);
///////////////////////////////////////////////////////////////////////////////////
// Printing
///////////////////////////////////////////////////////////////////////////////////
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
public:
void Print(CPrintDialog* pPrntDialog = NULL);
// EFW - New printing support functions
void EnableWysiwygPrinting(BOOL bEnable = TRUE) { m_bWysiwygPrinting =
bEnable; }
BOOL GetWysiwygPrinting() { return
m_bWysiwygPrinting; }
void SetShadedPrintOut(BOOL bEnable = TRUE) { m_bShadedPrintOut =
bEnable; }
BOOL GetShadedPrintOut(void) { return
m_bShadedPrintOut; }
// Use -1 to have it keep the existing value
void SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight,
int nLeftMargin, int nRightMargin, int nTopMargin,
int nBottomMargin, int nGap);
void GetPrintMarginInfo(int &nHeaderHeight, int &nFooterHeight,
int &nLeftMargin, int &nRightMargin, int &nTopMargin,
int &nBottomMargin, int &nGap);
///////////////////////////////////////////////////////////////////////////////////
// Printing overrides for derived classes
///////////////////////////////////////////////////////////////////////////////////
public:
virtual void OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo);
virtual void OnPrint(CDC *pDC, CPrintInfo *pInfo);
virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo);
#endif // #if !defined(_WIN32_WCE_NO_PRINTING) &&
!defined(GRIDCONTROL_NO_PRINTING)
// Implementation
public:
virtual ~CGridCtrl();
protected:
BOOL RegisterWindowClass();
BOOL Initialise();
void SetupDefaultCells();
LRESULT SendMessageToParent(int nRow, int nCol, int nMessage) const;
LRESULT SendDisplayRequestToParent(GV_DISPINFO* pDisplayInfo) const;
LRESULT SendCacheHintToParent(const CCellRange& range) const;
BOOL InvalidateCellRect(const int row, const int col);
BOOL InvalidateCellRect(const CCellID& cell);
BOOL InvalidateCellRect(const CCellRange& cellRange);
void EraseBkgnd(CDC* pDC);
BOOL GetCellRangeRect(const CCellRange& cellRange, LPRECT lpRect);
BOOL SetCell(int nRow, int nCol, CGridCellBase* pCell);
int SetMouseMode(int nMode) { int nOldMode = m_MouseMode; m_MouseMode =
nMode; return nOldMode; }
int GetMouseMode() const { return m_MouseMode; }
BOOL MouseOverRowResizeArea(CPoint& point);
BOOL MouseOverColumnResizeArea(CPoint& point);
CCellID GetTopleftNonFixedCell(BOOL bForceRecalculation = FALSE);
CCellRange GetUnobstructedNonFixedCellRange(BOOL bForceRecalculation =
FALSE);
CCellRange GetVisibleNonFixedCellRange(LPRECT pRect = NULL, BOOL
bForceRecalculation = FALSE);
BOOL IsVisibleVScroll() { return ( (m_nBarState & GVL_VERT) > 0); }
BOOL IsVisibleHScroll() { return ( (m_nBarState & GVL_HORZ) > 0); }
void ResetSelectedRange();
void ResetScrollBars();
void EnableScrollBars(int nBar, BOOL bEnable = TRUE);
int GetScrollPos32(int nBar, BOOL bGetTrackPos = FALSE);
BOOL SetScrollPos32(int nBar, int nPos, BOOL bRedraw = TRUE);
BOOL SortTextItems(int nCol, BOOL bAscending, int low, int high);
BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM
data,
int low, int high);
CPoint GetPointClicked(int nRow, int nCol, const CPoint& point);
void ValidateAndModifyCellContents(int nRow, int nCol, LPCTSTR strText);
// Overrrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGridCtrl)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
protected:
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
// Printing
virtual void PrintFixedRowCells(int nStartColumn, int nStopColumn, int&
row, CRect& rect,
CDC *pDC, BOOL& bFirst);
virtual void PrintColumnHeadings(CDC *pDC, CPrintInfo *pInfo);
virtual void PrintHeader(CDC *pDC, CPrintInfo *pInfo);
virtual void PrintFooter(CDC *pDC, CPrintInfo *pInfo);
virtual void PrintRowButtons(CDC *pDC, CPrintInfo* /*pInfo*/);
#endif
#ifndef GRIDCONTROL_NO_DRAGDROP
// Drag n' drop
virtual CImageList* CreateDragImage(CPoint *pHotSpot); // no longer
necessary
#endif
// Mouse Clicks
virtual void OnFixedColumnClick(CCellID& cell);
virtual void OnFixedRowClick(CCellID& cell);
// Editing
virtual void OnEditCell(int nRow, int nCol, CPoint point, UINT nChar);
virtual void OnEndEditCell(int nRow, int nCol, CString str);
virtual BOOL ValidateEdit(int nRow, int nCol, LPCTSTR str);
virtual void EndEditing();
// Drawing
virtual void OnDraw(CDC* pDC);
// CGridCellBase Creation and Cleanup
virtual CGridCellBase* CreateCell(int nRow, int nCol);
virtual void DestroyCell(int nRow, int nCol);
// Attributes
protected:
// General attributes
COLORREF m_crFixedTextColour, m_crFixedBkColour;
COLORREF m_crGridBkColour, m_crGridLineColour;
COLORREF m_crWindowText, m_crWindowColour, m_cr3DFace, // System
colours
m_crShadow;
COLORREF m_crTTipBackClr, m_crTTipTextClr; // Titletip
colours - FNA
BOOL m_bVirtualMode;
LPARAM m_lParam; // lParam
for callback
GRIDCALLBACK m_pfnCallback; // The
callback function
int m_nGridLines;
BOOL m_bEditable;
BOOL m_bModified;
BOOL m_bAllowDragAndDrop;
BOOL m_bListMode;
BOOL m_bSingleRowSelection;
BOOL m_bSingleColSelection;
BOOL m_bAllowDraw;
BOOL m_bEnableSelection;
BOOL m_bFixedRowSelection, m_bFixedColumnSelection;
BOOL m_bSortOnClick;
BOOL m_bHandleTabKey;
BOOL m_bDoubleBuffer;
BOOL m_bTitleTips;
int m_nBarState;
BOOL m_bWysiwygPrinting;
BOOL m_bHiddenColUnhide, m_bHiddenRowUnhide;
BOOL m_bAllowColHide, m_bAllowRowHide;
BOOL m_bAutoSizeSkipColHdr;
BOOL m_bTrackFocusCell;
BOOL m_bFrameFocus;
UINT m_nAutoSizeColumnStyle;
// Cell size details
int m_nRows, m_nFixedRows, m_nCols, m_nFixedCols;
CUIntArray m_arRowHeights, m_arColWidths;
int m_nVScrollMax, m_nHScrollMax;
// Fonts and images
CRuntimeClass* m_pRtcDefault; // determines kind of Grid Cell created by
default
CGridDefaultCell m_cellDefault; // "default" cell. Contains default
colours, font etc.
CGridDefaultCell m_cellFixedColDef, m_cellFixedRowDef, m_cellFixedRowColDef;
CFont m_PrinterFont; // for the printer
CImageList* m_pImageList;
// Cell data
CTypedPtrArray<CObArray, GRID_ROW*> m_RowData;
// Mouse operations such as cell selection
int m_MouseMode;
BOOL m_bLMouseButtonDown, m_bRMouseButtonDown;
CPoint m_LeftClickDownPoint, m_LastMousePoint;
CCellID m_LeftClickDownCell, m_SelectionStartCell;
CCellID m_idCurrentCell, m_idTopLeftCell;
int m_nTimerID;
int m_nTimerInterval;
int m_nResizeCaptureRange;
BOOL m_bAllowRowResize, m_bAllowColumnResize;
int m_nRowsPerWheelNotch;
CMap<DWORD,DWORD, CCellID, CCellID&> m_SelectedCellMap,
m_PrevSelectedCellMap;
#ifndef GRIDCONTROL_NO_TITLETIPS
CTitleTip m_TitleTip; // Title tips for cells
#endif
// Drag and drop
CCellID m_LastDragOverCell;
#ifndef GRIDCONTROL_NO_DRAGDROP
CGridDropTarget m_DropTarget; // OLE Drop target for the grid
#endif
// Printing information
CSize m_CharSize;
int m_nPageHeight;
CSize m_LogicalPageSize, // Page size in gridctrl units.
m_PaperSize; // Page size in device units.
// additional properties to support Wysiwyg printing
int m_nPageWidth;
int m_nPrintColumn;
int m_nCurrPrintRow;
int m_nNumPages;
int m_nPageMultiplier;
// sorting
int m_bAscending;
int m_nSortColumn;
PFNLVCOMPARE m_pfnCompare;
// EFW - Added to support shaded/unshaded printout. If true, colored
// cells will print as-is. If false, all text prints as black on white.
BOOL m_bShadedPrintOut;
// EFW - Added support for user-definable margins. Top and bottom are in
// lines. Left, right, and gap are in characters (avg width is used).
int m_nHeaderHeight, m_nFooterHeight, m_nLeftMargin,
m_nRightMargin, m_nTopMargin, m_nBottomMargin, m_nGap;
protected:
void SelectAllCells();
void SelectColumns(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL
bSelectCells=TRUE);
void SelectRows(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL
bSelectCells=TRUE);
void SelectCells(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL
bSelectCells=TRUE);
void OnSelecting(const CCellID& currentCell);
// Generated message map functions
//{{AFX_MSG(CGridCtrl)
afx_msg void OnPaint();
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg UINT OnGetDlgCode();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnUpdateEditSelectAll(CCmdUI* pCmdUI);
//}}AFX_MSG
#ifndef _WIN32_WCE_NO_CURSOR
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
#endif
#ifndef _WIN32_WCE
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point); // EFW - Added
afx_msg void OnSysColorChange();
#endif
#ifndef _WIN32_WCE_NO_CURSOR
afx_msg void OnCaptureChanged(CWnd *pWnd);
#endif
#ifndef GRIDCONTROL_NO_CLIPBOARD
afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
#endif
#if (_MFC_VER >= 0x0421) || (_WIN32_WCE >= 210)
afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
#endif
#if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
#endif
afx_msg LRESULT OnSetFont(WPARAM hFont, LPARAM lParam);
afx_msg LRESULT OnGetFont(WPARAM hFont, LPARAM lParam);
afx_msg LRESULT OnImeChar(WPARAM wCharCode, LPARAM lParam);
afx_msg void OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg LRESULT OnCustomPrint(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
enum eMouseModes { MOUSE_NOTHING, MOUSE_SELECT_ALL, MOUSE_SELECT_COL,
MOUSE_SELECT_ROW,
MOUSE_SELECT_CELLS, MOUSE_SCROLLING_CELLS,
MOUSE_OVER_ROW_DIVIDE, MOUSE_SIZING_ROW,
MOUSE_OVER_COL_DIVIDE, MOUSE_SIZING_COL,
MOUSE_PREPARE_EDIT,
#ifndef GRIDCONTROL_NO_DRAGDROP
MOUSE_PREPARE_DRAG, MOUSE_DRAGGING
#endif
};
};
// Returns the default cell implementation for the given grid region
inline CGridCellBase* CGridCtrl::GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol)
const
{
if (bFixedRow && bFixedCol) return (CGridCellBase*) &m_cellFixedRowColDef;
if (bFixedRow) return (CGridCellBase*) &m_cellFixedRowDef;
if (bFixedCol) return (CGridCellBase*) &m_cellFixedColDef;
return (CGridCellBase*) &m_cellDefault;
}
inline CGridCellBase* CGridCtrl::GetCell(int nRow, int nCol) const
{
if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols)
return NULL;
if (GetVirtualMode())
{
CGridCellBase* pCell = GetDefaultCell(nRow < m_nFixedRows, nCol <
m_nFixedCols);
static GV_DISPINFO gvdi;
gvdi.item.row = nRow;
gvdi.item.col = nCol;
gvdi.item.mask = 0xFFFFFFFF;
gvdi.item.nState = 0;
gvdi.item.nFormat = pCell->GetFormat();
gvdi.item.iImage = pCell->GetImage();
gvdi.item.crBkClr = pCell->GetBackClr();
gvdi.item.crFgClr = pCell->GetTextClr();
gvdi.item.lParam = pCell->GetData();
memcpy(&gvdi.item.lfFont, pCell->GetFont(), sizeof(LOGFONT));
gvdi.item.nMargin = pCell->GetMargin();
gvdi.item.strText.Empty();
// Fix the state bits
if (IsCellSelected(nRow, nCol)) gvdi.item.nState |= GVIS_SELECTED;
if (nRow < GetFixedRowCount()) gvdi.item.nState |= (GVIS_FIXED |
GVIS_FIXEDROW);
if (nCol < GetFixedColumnCount()) gvdi.item.nState |= (GVIS_FIXED |
GVIS_FIXEDCOL);
if (GetFocusCell() == CCellID(nRow, nCol)) gvdi.item.nState |=
GVIS_FOCUSED;
if (m_pfnCallback)
m_pfnCallback(&gvdi, m_lParam);
else
SendDisplayRequestToParent(&gvdi);
static CGridCell cell;
cell.SetState(gvdi.item.nState);
cell.SetFormat(gvdi.item.nFormat);
cell.SetImage(gvdi.item.iImage);
cell.SetBackClr(gvdi.item.crBkClr);
cell.SetTextClr(gvdi.item.crFgClr);
cell.SetData(gvdi.item.lParam);
cell.SetFont(&(gvdi.item.lfFont));
cell.SetMargin(gvdi.item.nMargin);
cell.SetText(gvdi.item.strText);
cell.SetGrid((CGridCtrl*)this);
return (CGridCellBase*) &cell;
}
GRID_ROW* pRow = m_RowData[nRow];
if (!pRow) return NULL;
return pRow->GetAt(nCol);
}
inline BOOL CGridCtrl::SetCell(int nRow, int nCol, CGridCellBase* pCell)
{
if (GetVirtualMode())
return FALSE;
if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols)
return FALSE;
GRID_ROW* pRow = m_RowData[nRow];
if (!pRow) return FALSE;
pCell->SetCoords( nRow, nCol);
pRow->SetAt(nCol, pCell);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif //
!defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
--- NEW FILE: GridCellDateTime.cpp ---
///////////////////////////////////////////////////////////////////////////
//
// GridCellDateTime.cpp: implementation of the CGridCellDateTime class.
//
// Provides the implementation for a datetime picker cell type of the
// grid control.
//
// Written by Podsypalnikov Eugen 15 Mar 2001
// Modified:
// 31 May 2001 Fixed m_cTime bug (Chris Maunder)
//
// For use with CGridCtrl v2.22+
//
///////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "GridCtrl.h"
#include "GridCell.h"
#include "GridCellDateTime.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// CGridCellDateTime
IMPLEMENT_DYNCREATE(CGridCellDateTime, CGridCell)
IMPLEMENT_DYNCREATE(CGridCellTime, CGridCellDateTime)
IMPLEMENT_DYNCREATE(CGridCellDateCal, CGridCellDateTime)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGridCellDateTime::CGridCellDateTime() : CGridCell()
{
m_dwStyle = 0;
m_cTime = CTime::GetCurrentTime();
}
CGridCellDateTime::CGridCellDateTime(DWORD dwStyle) : CGridCell()
{
Init(dwStyle);
}
CGridCellDateTime::~CGridCellDateTime()
{
}
BOOL CGridCellDateTime::Edit(int nRow, int nCol, CRect rect, CPoint /* point */,
UINT nID, UINT nChar)
{
m_bEditing = TRUE;
// CInPlaceDateTime auto-deletes itself
m_pEditWnd = new CInPlaceDateTime(GetGrid(), rect,
m_dwStyle|DTS_UPDOWN, nID, nRow, nCol,
GetTextClr(), GetBackClr(), GetTime(), nChar);
return TRUE;
}
CWnd* CGridCellDateTime::GetEditWnd() const
{
return m_pEditWnd;
}
void CGridCellDateTime::EndEdit()
{
if (m_pEditWnd) ((CInPlaceDateTime*)m_pEditWnd)->EndEdit();
}
void CGridCellDateTime::Init(DWORD dwStyle)
{
m_dwStyle = dwStyle;
SetTime(CTime::GetCurrentTime());
SetFormat(DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX
#ifndef _WIN32_WCE
|DT_END_ELLIPSIS
#endif
);
}
// Should be changed to use locale settings
void CGridCellDateTime::SetTime(CTime time)
{
m_cTime = time;
if (DTS_TIMEFORMAT == m_dwStyle)
{
#ifdef _WIN32_WCE
CString strTemp;
strTemp.Format(_T("%02d:%02d:%02d"),
m_cTime.GetHour(), m_cTime.GetMinute(), m_cTime.GetSecond());
SetText(strTemp);
#else
SetText(m_cTime.Format(_T("%X"))); // Yogurt $$LR$$ (_T("%H:%M:%S")));
#endif
}
else if (DTS_SHORTDATEFORMAT == m_dwStyle)
{
#ifdef _WIN32_WCE
CString strTemp;
strTemp.Format(_T("%02d/%02d/%02d"),
m_cTime.GetMonth(), m_cTime.GetDay(), m_cTime.GetYear());
SetText(strTemp);
#else
SetText(m_cTime.Format(_T("%x"))); // Yogurt $$LR$$ (("%d/%m/%Y")));
#endif
}
}
// Yogurt $$LR$$
CSize CGridCellDateTime::GetCellExtent(CDC* pDC)
{
CSize sizeScroll (GetSystemMetrics(SM_CXVSCROLL),
GetSystemMetrics(SM_CYHSCROLL));
CSize sizeCell (CGridCell::GetCellExtent(pDC));
sizeCell.cx += sizeScroll.cx;
sizeCell.cy = max(sizeCell.cy,sizeScroll.cy);
return sizeCell;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
BOOL CGridCellDateCal::Edit(int nRow, int nCol, CRect rect, CPoint /* point */,
UINT nID, UINT nChar)
{
m_bEditing = TRUE;
// CInPlaceDateTime auto-deletes itself
m_pEditWnd = new CInPlaceDateTime(GetGrid(), rect,
m_dwStyle, nID, nRow, nCol,
GetTextClr(), GetBackClr(), GetTime(), nChar);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CInPlaceDateTime
CInPlaceDateTime::CInPlaceDateTime(CWnd* pParent, CRect& rect, DWORD dwStyle,
UINT nID,
int nRow, int nColumn,
COLORREF crFore, COLORREF crBack,
CTime* pcTime,
UINT nFirstChar)
{
m_crForeClr = crFore;
m_crBackClr = crBack;
m_nRow = nRow;
m_nCol = nColumn;
m_nLastChar = 0;
m_bExitOnArrows = FALSE;
m_pcTime = pcTime;
DWORD dwStl = WS_BORDER|WS_VISIBLE|WS_CHILD|dwStyle;
if (!Create(dwStl, rect, pParent, nID)) {
return;
}
SetTime(m_pcTime);
SetFont(pParent->GetFont());
SetFocus();
switch (nFirstChar)
{
case VK_LBUTTON:
case VK_RETURN: return;
case VK_BACK: break;
case VK_DOWN:
case VK_UP:
case VK_RIGHT:
case VK_LEFT:
case VK_NEXT:
case VK_PRIOR:
case VK_HOME:
case VK_END: return;
default: break;
}
SendMessage(WM_CHAR, nFirstChar);
}
CInPlaceDateTime::~CInPlaceDateTime()
{
}
void CInPlaceDateTime::EndEdit()
{
CString str;
if (::IsWindow(m_hWnd))
{
GetWindowText(str);
GetTime(*m_pcTime);
}
// Send Notification to parent
GV_DISPINFO dispinfo;
dispinfo.hdr.hwndFrom = GetSafeHwnd();
dispinfo.hdr.idFrom = GetDlgCtrlID();
dispinfo.hdr.code = GVN_ENDLABELEDIT;
dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
dispinfo.item.row = m_nRow;
dispinfo.item.col = m_nCol;
dispinfo.item.strText = str;
dispinfo.item.lParam = (LPARAM) m_nLastChar;
CWnd* pOwner = GetOwner();
if (IsWindow(pOwner->GetSafeHwnd())) {
pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
}
// Close this window (PostNcDestroy will delete this)
if (::IsWindow(m_hWnd)) {
PostMessage(WM_CLOSE, 0, 0);
}
}
void CInPlaceDateTime::PostNcDestroy()
{
CDateTimeCtrl::PostNcDestroy();
delete this;
}
BEGIN_MESSAGE_MAP(CInPlaceDateTime, CDateTimeCtrl)
//{{AFX_MSG_MAP(CInPlaceDateTime)
ON_WM_KILLFOCUS()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_GETDLGCODE()
ON_NOTIFY_REFLECT(DTN_CLOSEUP, OnCloseUp)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceDateTime message handlers
void CInPlaceDateTime::OnCloseUp (NMHDR * pNotifyStruct, LRESULT* result)
{
EndEdit();
*result = 0;
}
void CInPlaceDateTime::OnKillFocus(CWnd* pNewWnd)
{
HWND pCalWnd;
// if focus goes to CMonthCalCtrl from inside ...
// just ignore it
pCalWnd = (HWND)SendMessage( DTM_GETMONTHCAL );
if( pNewWnd->GetSafeHwnd() == pCalWnd )
return;
CDateTimeCtrl::OnKillFocus(pNewWnd);
if (GetSafeHwnd() == pNewWnd->GetSafeHwnd())
return;
EndEdit();
}
UINT CInPlaceDateTime::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
void CInPlaceDateTime::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (( nChar == VK_PRIOR || nChar == VK_NEXT ||
nChar == VK_DOWN || nChar == VK_UP ||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
{
m_nLastChar = nChar;
GetParent()->SetFocus();
return;
}
CDateTimeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CInPlaceDateTime::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
{
m_nLastChar = nChar;
GetParent()->SetFocus(); // This will destroy this window
return;
}
CDateTimeCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
}
--- NEW FILE: MemDC.h ---
#if !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// MemDC.h : header file
//
//////////////////////////////////////////////////
// CMemDC - memory DC
//
// Author: Keith Rule
// Email: [EMAIL PROTECTED]
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// History - 10/3/97 Fixed scrolling bug.
// Added print support.
// 25 feb 98 - fixed minor assertion bug
//
// This class implements a memory Device Context
class CMemDC : public CDC
{
public:
// constructor sets up the memory DC
CMemDC(CDC* pDC) : CDC()
{
ASSERT(pDC != NULL);
m_pDC = pDC;
m_pOldBitmap = NULL;
#ifndef _WIN32_WCE_NO_PRINTING
m_bMemDC = !pDC->IsPrinting();
#else
m_bMemDC = FALSE;
#endif
if (m_bMemDC) // Create a Memory DC
{
pDC->GetClipBox(&m_rect);
CreateCompatibleDC(pDC);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(),
m_rect.Height());
m_pOldBitmap = SelectObject(&m_bitmap);
#ifndef _WIN32_WCE
SetWindowOrg(m_rect.left, m_rect.top);
#endif
// EFW - Bug fix - Fill background in case the user has overridden
// WM_ERASEBKGND. We end up with garbage otherwise.
// CJM - moved to fix a bug in the fix.
FillSolidRect(m_rect, pDC->GetBkColor());
}
else // Make a copy of the relevent parts of the current DC for
printing
{
#if !defined(_WIN32_WCE) || ((_WIN32_WCE > 201) &&
!defined(_WIN32_WCE_NO_PRINTING))
m_bPrinting = pDC->m_bPrinting;
#endif
m_hDC = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
}
}
// Destructor copies the contents of the mem DC to the original DC
~CMemDC()
{
if (m_bMemDC)
{
// Copy the offscreen bitmap onto the screen.
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(),
m_rect.Height(),
this, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
SelectObject(m_pOldBitmap);
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated
with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
}
// Allow usage as a pointer
CMemDC* operator->() {return this;}
// Allow usage as a pointer
operator CMemDC*() {return this;}
private:
CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_pOldBitmap; // bitmap originally found in CMemDC
CDC* m_pDC; // Saves CDC passed in constructor
CRect m_rect; // Rectangle of drawing area.
BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately
before the previous line.
#endif // !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
--- NEW FILE: TitleTip.cpp ---
////////////////////////////////////////////////////////////////////////////
// TitleTip.cpp : implementation file
//
// Based on code by Zafir Anjum
//
// Adapted by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2002. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.20+
//
// History
// 10 Apr 1999 Now accepts a LOGFONT pointer and
// a tracking rect in Show(...) (Chris Maunder)
// 18 Apr 1999 Resource leak in Show fixed by Daniel Gehriger
// 8 Mar 2000 Added double-click fix found on codeguru
// web site but forgot / can't find who contributed it
// 28 Mar 2000 Aqiruse (marked with //FNA)
// Titletips now use cell color
// 18 Jun 2000 Delayed window creation added
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "gridctrl.h"
#ifndef GRIDCONTROL_NO_TITLETIPS
#include "TitleTip.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTitleTip
CTitleTip::CTitleTip()
{
// Register the window class if it has not already been registered.
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
if(!(::GetClassInfo(hInst, TITLETIP_CLASSNAME, &wndcls)))
{
// otherwise we need to register a new class
wndcls.style = CS_SAVEBITS;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = LoadCursor( hInst, IDC_ARROW
);
wndcls.hbrBackground = (HBRUSH)(COLOR_INFOBK +1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = TITLETIP_CLASSNAME;
if (!AfxRegisterClass(&wndcls))
AfxThrowResourceException();
}
m_dwLastLButtonDown = ULONG_MAX;
m_dwDblClickMsecs = GetDoubleClickTime();
m_bCreated = FALSE;
m_pParentWnd = NULL;
}
CTitleTip::~CTitleTip()
{
}
BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
//{{AFX_MSG_MAP(CTitleTip)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTitleTip message handlers
BOOL CTitleTip::Create(CWnd * pParentWnd)
{
ASSERT_VALID(pParentWnd);
// Already created?
if (m_bCreated)
return TRUE;
DWORD dwStyle = WS_BORDER | WS_POPUP;
DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
m_pParentWnd = pParentWnd;
m_bCreated = CreateEx(dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL, NULL );
return m_bCreated;
}
BOOL CTitleTip::DestroyWindow()
{
m_bCreated = FALSE;
return CWnd::DestroyWindow();
}
// Show - Show the titletip if needed
// rectTitle - The rectangle within which the original
// title is constrained - in client coordinates
// lpszTitleText - The text to be displayed
// xoffset - Number of pixel that the text is offset from
// left border of the cell
void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset /*=0*/,
LPRECT lpHoverRect /*=NULL*/,
const LOGFONT* lpLogFont /*=NULL*/,
COLORREF crTextClr /* CLR_DEFAULT */,
COLORREF crBackClr /* CLR_DEFAULT */)
{
if (!IsWindow(m_hWnd))
Create(m_pParentWnd);
ASSERT( ::IsWindow( GetSafeHwnd() ) );
if (rectTitle.IsRectEmpty())
return;
// If titletip is already displayed, don't do anything.
if( IsWindowVisible() )
return;
m_rectHover = (lpHoverRect != NULL)? lpHoverRect : rectTitle;
m_rectHover.right++; m_rectHover.bottom++;
m_pParentWnd->ClientToScreen( m_rectHover );
ScreenToClient( m_rectHover );
// Do not display the titletip is app does not have focus
if( GetFocus() == NULL )
return;
// Define the rectangle outside which the titletip will be hidden.
// We add a buffer of one pixel around the rectangle
m_rectTitle.top = -1;
m_rectTitle.left = -xoffset-1;
m_rectTitle.right = rectTitle.Width()-xoffset;
m_rectTitle.bottom = rectTitle.Height()+1;
// Determine the width of the text
m_pParentWnd->ClientToScreen( rectTitle );
CClientDC dc(this);
CString strTitle = _T("");
strTitle += _T(" ");
strTitle += lpszTitleText;
strTitle += _T(" ");
CFont font, *pOldFont = NULL;
if (lpLogFont)
{
font.CreateFontIndirect(lpLogFont);
pOldFont = dc.SelectObject( &font );
}
else
{
// use same font as ctrl
pOldFont = dc.SelectObject( m_pParentWnd->GetFont() );
}
CSize size = dc.GetTextExtent( strTitle );
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
size.cx += tm.tmOverhang;
CRect rectDisplay = rectTitle;
rectDisplay.left += xoffset;
rectDisplay.right = rectDisplay.left + size.cx + xoffset;
// Do not display if the text fits within available space
if ( rectDisplay.right > rectTitle.right-xoffset )
{
// Show the titletip
SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top,
rectDisplay.Width(), rectDisplay.Height(),
SWP_SHOWWINDOW|SWP_NOACTIVATE );
// FNA - handle colors correctly
if (crBackClr != CLR_DEFAULT)
{
CBrush backBrush(crBackClr);
CBrush* pOldBrush = dc.SelectObject(&backBrush);
CRect rect;
dc.GetClipBox(&rect); // Erase the area needed
dc.PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
PATCOPY);
dc.SelectObject(pOldBrush);
}
// Set color
if (crTextClr != CLR_DEFAULT)//FNA
dc.SetTextColor(crTextClr);//FA
dc.SetBkMode( TRANSPARENT );
dc.TextOut( 0, 0, strTitle );
SetCapture();
}
dc.SelectObject( pOldFont );
}
void CTitleTip::Hide()
{
if (!::IsWindow(GetSafeHwnd()))
return;
if (GetCapture()->GetSafeHwnd() == GetSafeHwnd())
ReleaseCapture();
ShowWindow( SW_HIDE );
}
void CTitleTip::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_rectHover.PtInRect(point))
{
Hide();
// Forward the message
ClientToScreen( &point );
CWnd *pWnd = WindowFromPoint( point );
if ( pWnd == this )
pWnd = m_pParentWnd;
int hittest =
(int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
if (hittest == HTCLIENT) {
pWnd->ScreenToClient( &point );
pWnd->PostMessage( WM_MOUSEMOVE, nFlags, MAKELONG(point.x,point.y)
);
} else {
pWnd->PostMessage( WM_NCMOUSEMOVE, hittest,
MAKELONG(point.x,point.y) );
}
}
}
BOOL CTitleTip::PreTranslateMessage(MSG* pMsg)
{
// Used to qualify WM_LBUTTONDOWN messages as double-clicks
DWORD dwTick=0;
BOOL bDoubleClick=FALSE;
CWnd *pWnd;
int hittest;
switch (pMsg->message)
{
case WM_LBUTTONDOWN:
// Get tick count since last LButtonDown
dwTick = GetTickCount();
bDoubleClick = ((dwTick - m_dwLastLButtonDown) <= m_dwDblClickMsecs);
m_dwLastLButtonDown = dwTick;
// NOTE: DO NOT ADD break; STATEMENT HERE! Let code fall through
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
{
POINTS pts = MAKEPOINTS( pMsg->lParam );
POINT point;
point.x = pts.x;
point.y = pts.y;
ClientToScreen( &point );
Hide();
pWnd = WindowFromPoint( point );
if (!pWnd)
return CWnd::PreTranslateMessage(pMsg);
if( pWnd->GetSafeHwnd() == GetSafeHwnd())
pWnd = m_pParentWnd;
hittest =
(int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
if (hittest == HTCLIENT)
{
pWnd->ScreenToClient( &point );
pMsg->lParam = MAKELONG(point.x,point.y);
}
else
{
switch (pMsg->message) {
case WM_LBUTTONDOWN:
pMsg->message = WM_NCLBUTTONDOWN;
break;
case WM_RBUTTONDOWN:
pMsg->message = WM_NCRBUTTONDOWN;
break;
case WM_MBUTTONDOWN:
pMsg->message = WM_NCMBUTTONDOWN;
break;
}
pMsg->wParam = hittest;
pMsg->lParam = MAKELONG(point.x,point.y);
}
// If this is the 2nd WM_LBUTTONDOWN in x milliseconds,
// post a WM_LBUTTONDBLCLK message instead of a single click.
pWnd->PostMessage( bDoubleClick ? WM_LBUTTONDBLCLK : pMsg->message,
pMsg->wParam,
pMsg->lParam);
return TRUE;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
Hide();
m_pParentWnd->PostMessage( pMsg->message, pMsg->wParam,
pMsg->lParam );
return TRUE;
}
if( GetFocus() == NULL )
{
Hide();
return TRUE;
}
return CWnd::PreTranslateMessage(pMsg);
}
#endif // GRIDCONTROL_NO_TITLETIPS
--- NEW FILE: GridCellCombo.cpp ---
// GridCellCombo.cpp : implementation file
//
// MFC Grid Control - Main grid cell class
//
// Provides the implementation for a combobox cell type of the
// grid control.
//
// Written by Chris Maunder <[EMAIL PROTECTED]>
// Copyright (c) 1998-2001. All Rights Reserved.
//
// Parts of the code contained in this file are based on the original
// CInPlaceList from http://www.codeguru.com/listview
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.22+
//
// History:
// 6 Aug 1998 - Added CComboEdit to subclass the edit control - code
// provided by Roelf Werkman <[EMAIL PROTECTED]>. Added nID to
// the constructor param list.
// 29 Nov 1998 - bug fix in onkeydown (Markus Irtenkauf)
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GridCell.h"
#include "GridCtrl.h"
#include "GridCellCombo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CComboEdit
CComboEdit::CComboEdit()
{
}
CComboEdit::~CComboEdit()
{
}
// Stoopid win95 accelerator key problem workaround - Matt Weagle.
BOOL CComboEdit::PreTranslateMessage(MSG* pMsg)
{
// Make sure that the keystrokes continue to the appropriate handlers
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
{
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE;
}
// Catch the Alt key so we don't choke if focus is going to an owner
drawn button
if (pMsg->message == WM_SYSCHAR)
return TRUE;
return CEdit::PreTranslateMessage(pMsg);
}
BEGIN_MESSAGE_MAP(CComboEdit, CEdit)
//{{AFX_MSG_MAP(CComboEdit)
ON_WM_KILLFOCUS()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComboEdit message handlers
void CComboEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
CInPlaceList* pOwner = (CInPlaceList*) GetOwner(); // This MUST be a
CInPlaceList
if (pOwner)
pOwner->EndEdit();
}
void CComboEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
nChar == VK_DOWN || nChar == VK_UP ||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
(GetKeyState(VK_CONTROL) < 0 && GetDlgCtrlID() ==
IDC_COMBOEDIT))
{
CWnd* pOwner = GetOwner();
if (pOwner)
pOwner->SendMessage(WM_KEYDOWN, nChar, nRepCnt+
(((DWORD)nFlags)<<16));
return;
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CComboEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE)
{
CWnd* pOwner = GetOwner();
if (pOwner)
pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt +
(((DWORD)nFlags)<<16));
return;
}
if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
{
CWnd* pOwner = GetOwner();
if (pOwner)
pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt +
(((DWORD)nFlags)<<16));
return;
}
CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
}
/////////////////////////////////////////////////////////////////////////////
// CInPlaceList
CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
int nRow, int nColumn,
COLORREF crFore, COLORREF crBack,
CStringArray& Items, CString
sInitText,
UINT nFirstChar)
{
m_crForeClr = crFore;
m_crBackClr = crBack;
m_nNumLines = 4;
m_sInitText = sInitText;
m_nRow = nRow;
m_nCol = nColumn;
m_nLastChar = 0;
m_bExitOnArrows = FALSE; //(nFirstChar != VK_LBUTTON); // If mouse
click brought us here,
// Create the combobox
DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL|
CBS_AUTOHSCROLL | dwStyle;
int nHeight = rect.Height();
rect.bottom = rect.bottom + m_nNumLines*nHeight +
::GetSystemMetrics(SM_CYHSCROLL);
if (!Create(dwComboStyle, rect, pParent, nID)) return;
// Add the strings
for (int i = 0; i < Items.GetSize(); i++)
AddString(Items[i]);
SetFont(pParent->GetFont());
SetItemHeight(-1, nHeight);
int nMaxLength = GetCorrectDropWidth();
/*
if (nMaxLength > rect.Width())
rect.right = rect.left + nMaxLength;
// Resize the edit window and the drop down window
MoveWindow(rect);
*/
SetDroppedWidth(nMaxLength);
SetHorizontalExtent(0); // no horz scrolling
// Set the initial text to m_sInitText
if (::IsWindow(m_hWnd) && SelectString(-1, m_sInitText) == CB_ERR)
SetWindowText(m_sInitText); // No text selected, so
restore what was there before
ShowDropDown();
// Subclass the combobox edit control if style includes CBS_DROPDOWN
if ((dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST)
{
m_edit.SubclassDlgItem(IDC_COMBOEDIT, this);
SetFocus();
switch (nFirstChar)
{
case VK_LBUTTON:
case VK_RETURN: m_edit.SetSel((int)_tcslen(m_sInitText), -1);
return;
case VK_BACK: m_edit.SetSel((int)_tcslen(m_sInitText), -1);
break;
case VK_DOWN:
case VK_UP:
case VK_RIGHT:
case VK_LEFT:
case VK_NEXT:
case VK_PRIOR:
case VK_HOME:
case VK_END: m_edit.SetSel(0,-1); return;
default: m_edit.SetSel(0,-1);
}
SendMessage(WM_CHAR, nFirstChar);
}
else
SetFocus();
}
CInPlaceList::~CInPlaceList()
{
}
void CInPlaceList::EndEdit()
{
CString str;
if (::IsWindow(m_hWnd))
GetWindowText(str);
// Send Notification to parent
GV_DISPINFO dispinfo;
dispinfo.hdr.hwndFrom = GetSafeHwnd();
dispinfo.hdr.idFrom = GetDlgCtrlID();
dispinfo.hdr.code = GVN_ENDLABELEDIT;
dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
dispinfo.item.row = m_nRow;
dispinfo.item.col = m_nCol;
dispinfo.item.strText = str;
dispinfo.item.lParam = (LPARAM) m_nLastChar;
CWnd* pOwner = GetOwner();
if (IsWindow(pOwner->GetSafeHwnd()))
pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
// Close this window (PostNcDestroy will delete this)
if (::IsWindow(m_hWnd))
PostMessage(WM_CLOSE, 0, 0);
}
int CInPlaceList::GetCorrectDropWidth()
{
const int nMaxWidth = 200; // don't let the box be bigger than this
// Reset the dropped width
int nNumEntries = GetCount();
int nWidth = 0;
CString str;
CClientDC dc(this);
int nSave = dc.SaveDC();
dc.SelectObject(GetFont());
int nScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);
for (int i = 0; i < nNumEntries; i++)
{
GetLBText(i, str);
int nLength = dc.GetTextExtent(str).cx + nScrollWidth;
nWidth = max(nWidth, nLength);
}
// Add margin space to the calculations
nWidth += dc.GetTextExtent(_T("0")).cx;
dc.RestoreDC(nSave);
nWidth = min(nWidth, nMaxWidth);
return nWidth;
//SetDroppedWidth(nWidth);
}
/*
// Fix by Ray ([EMAIL PROTECTED])
void CInPlaceList::OnSelendOK()
{
int iIndex = GetCurSel();
if( iIndex != CB_ERR)
{
CString strLbText;
GetLBText( iIndex, strLbText);
if (!((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST))
m_edit.SetWindowText( strLbText);
}
GetParent()->SetFocus();
}
*/
void CInPlaceList::PostNcDestroy()
{
CComboBox::PostNcDestroy();
delete this;
}
BEGIN_MESSAGE_MAP(CInPlaceList, CComboBox)
//{{AFX_MSG_MAP(CInPlaceList)
ON_WM_KILLFOCUS()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelChange)
ON_WM_GETDLGCODE()
ON_WM_CTLCOLOR_REFLECT()
//}}AFX_MSG_MAP
//ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelendOK)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceList message handlers
UINT CInPlaceList::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
void CInPlaceList::OnSelChange()
{
CString csTexte;
if (::IsWindow(m_hWnd))
{
int isel = GetCurSel();
if (isel != CB_ERR)
{
GetLBText (isel, csTexte);
// Notification du changement
// Send Notification to parent owner (grid Owner)
GV_DISPINFO dispinfo;
CWnd* pParent = GetParent();
dispinfo.hdr.hwndFrom = pParent->GetSafeHwnd();
dispinfo.hdr.idFrom = pParent->GetDlgCtrlID();
dispinfo.hdr.code = GVN_CHANGEDLABELEDIT;
dispinfo.item.mask = LVIF_TEXT;
dispinfo.item.row = m_nRow;
dispinfo.item.col = m_nCol;
dispinfo.item.strText = csTexte;
CWnd* pOwner = pParent->GetOwner();
if (IsWindow(pOwner->GetSafeHwnd()))
pOwner->SendMessage(WM_NOTIFY,
dispinfo.hdr.idFrom, (LPARAM)&dispinfo);
}
}
}
void CInPlaceList::OnDropdown()
{
SetDroppedWidth(GetCorrectDropWidth());
}
void CInPlaceList::OnKillFocus(CWnd* pNewWnd)
{
CComboBox::OnKillFocus(pNewWnd);
if (GetSafeHwnd() == pNewWnd->GetSafeHwnd())
return;
// Only end editing on change of focus if we're using the CBS_DROPDOWNLIST
style
if ((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
EndEdit();
}
// If an arrow key (or associated) is pressed, then exit if
// a) The Ctrl key was down, or
// b) m_bExitOnArrows == TRUE
void CInPlaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
nChar == VK_DOWN || nChar == VK_UP ||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
{
m_nLastChar = nChar;
GetParent()->SetFocus();
return;
}
CComboBox::OnKeyDown(nChar, nRepCnt, nFlags);
}
// Need to keep a lookout for Tabs, Esc and Returns.
void CInPlaceList::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE)
SetWindowText(m_sInitText); // restore previous text
if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
{
m_nLastChar = nChar;
GetParent()->SetFocus(); // This will destroy this window
return;
}
CComboBox::OnKeyUp(nChar, nRepCnt, nFlags);
}
HBRUSH CInPlaceList::CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/)
{
/*
static CBrush brush(m_crBackClr);
pDC->SetTextColor(m_crForeClr);
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH) brush.GetSafeHandle();
*/
// TODO: Return a non-NULL brush if the parent's handler should not be
called
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellCombo
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CGridCellCombo, CGridCell)
CGridCellCombo::CGridCellCombo() : CGridCell()
{
SetStyle(CBS_DROPDOWN); // CBS_DROPDOWN, CBS_DROPDOWNLIST, CBS_SIMPLE,
CBS_SORT
}
// Create a control to do the editing
BOOL CGridCellCombo::Edit(int nRow, int nCol, CRect rect, CPoint /* point */,
UINT nID, UINT nChar)
{
m_bEditing = TRUE;
// CInPlaceList auto-deletes itself
m_pEditWnd = new CInPlaceList(GetGrid(), rect, GetStyle(), nID, nRow, nCol,
GetTextClr(), GetBackClr(), m_Strings,
GetText(), nChar);
return TRUE;
}
CWnd* CGridCellCombo::GetEditWnd() const
{
if (m_pEditWnd && (m_pEditWnd->GetStyle() & CBS_DROPDOWNLIST) !=
CBS_DROPDOWNLIST )
return &(((CInPlaceList*)m_pEditWnd)->m_edit);
return NULL;
}
CSize CGridCellCombo::GetCellExtent(CDC* pDC)
{
CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL),
GetSystemMetrics(SM_CYHSCROLL)); //Yogurt $$LR$$
CSize sizeCell (CGridCell::GetCellExtent(pDC));
sizeCell.cx += sizeScroll.cx;
sizeCell.cy = max(sizeCell.cy,sizeScroll.cy);
return sizeCell;
}
// Cancel the editing.
void CGridCellCombo::EndEdit()
{
if (m_pEditWnd)
((CInPlaceList*)m_pEditWnd)->EndEdit();
}
// Override draw so that when the cell is selected, a drop arrow is shown in
the RHS.
BOOL CGridCellCombo::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL
bEraseBkgnd /*=TRUE*/)
{
#ifdef _WIN32_WCE
return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
#else
// Cell selected?
//if ( !IsFixed() && IsFocused())
if (GetGrid()->IsCellEditable(nRow, nCol) && !IsEditing())
{
// Get the size of the scroll box
CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL),
GetSystemMetrics(SM_CYHSCROLL));
// enough room to draw?
if (sizeScroll.cy < rect.Width() && sizeScroll.cy < rect.Height())
{
// Draw control at RHS of cell
CRect ScrollRect = rect;
ScrollRect.left = rect.right - sizeScroll.cx;
ScrollRect.bottom = rect.top + sizeScroll.cy;
// Do the draw
pDC->DrawFrameControl(ScrollRect, DFC_SCROLL, DFCS_SCROLLDOWN);
// Adjust the remaining space in the cell
rect.right = ScrollRect.left;
}
}
CString strTempText = GetText();
if (IsEditing())
SetText(_T(""));
// drop through and complete the cell drawing using the base class' method
BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
if (IsEditing())
SetText(strTempText);
return bResult;
#endif
}
// For setting the strings that will be displayed in the drop list
void CGridCellCombo::SetOptions(const CStringArray& ar)
{
m_Strings.RemoveAll();
for (int i = 0; i < ar.GetSize(); i++)
m_Strings.Add(ar[i]);
}
/////////////////////////////////////////////////////////////////////////////
// CGridCellList
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CGridCellList, CGridCellCombo)
CGridCellList::CGridCellList() : CGridCellCombo()
{
SetStyle(CBS_DROPDOWNLIST); // CBS_DROPDOWN, CBS_DROPDOWNLIST, CBS_SIMPLE,
CBS_SORT
}