| | |
| | | // eq cim mode change |
| | | CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep(); |
| | | pStep->setName(STEP_CIM_MODE_CHANGE); |
| | | pStep->setWriteSignalDev(0x70); |
| | | pStep->setWriteSignalDev(0x60); |
| | | pStep->setCimModeDev(0x15); |
| | | if (addStep(STEP_ID_CIMMODE_CHANGED_CMD_REPLY, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | // eq cim message |
| | | CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep(); |
| | | pStep->setName(STEP_CIM_MESSAGE_CMD); |
| | | pStep->setWriteSignalDev(0x71); |
| | | pStep->setWriteSignalDev(0x61); |
| | | pStep->setCimMessageDev(0x0); |
| | | if (addStep(STEP_ID_CIM_MSG_SET_CMD_REPLY, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | // CIM Message Confirm |
| | | CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, 0x5f80); |
| | | pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM); |
| | | pStep->setWriteSignalDev(0x59); |
| | | pStep->setWriteSignalDev(0x49); |
| | | if (addStep(STEP_ID_CIM_MSG_CONFIRM_REPORT, pStep) != 0) { |
| | | delete pStep; |
| | | } |
| | |
| | | // eq cim message clear |
| | | CEqCimMessageClearStep* pStep = new CEqCimMessageClearStep(); |
| | | pStep->setName(STEP_CIM_MESSAGE_CLEAR); |
| | | pStep->setWriteSignalDev(0x72); |
| | | pStep->setWriteSignalDev(0x62); |
| | | pStep->setClearCimMessageDev(0x13); |
| | | if (addStep(STEP_ID_CIM_MSG_CLEAR_CMD_REPLY, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | // datetime set cmd |
| | | CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep(); |
| | | pStep->setName(STEP_DATETIME_SET_CMD); |
| | | pStep->setWriteSignalDev(0x73); |
| | | pStep->setWriteSignalDev(0x63); |
| | | pStep->setDateTimeDev(0x16); |
| | | if (addStep(STEP_ID_DATETIME_SET_CMD_REPLY, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | // vcr enable |
| | | CEqVCREnableStep* pStep = new CEqVCREnableStep(); |
| | | pStep->setName(STEP_EQ_VCR_ENABLE); |
| | | pStep->setWriteSignalDev(0x74); |
| | | pStep->setWriteSignalDev(0x64); |
| | | pStep->setEqVCRModeDev(0x1F); |
| | | if (addStep(STEP_ID_VCR_ENABLE_CMD_REPLY, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | // eq mode change |
| | | CEqModeChangeStep* pStep = new CEqModeChangeStep(); |
| | | pStep->setName(STEP_EQ_MODE_CHANGE); |
| | | pStep->setWriteSignalDev(0x75); |
| | | pStep->setWriteSignalDev(0x65); |
| | | pStep->setEqModeDev(0x1E); |
| | | if (addStep(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | BOOL bAlive = pEquipment->isAlive(); |
| | | if (EQ_ID_EFEM == nID) { |
| | | DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE; |
| | | UpdateDeviceStatus(INDICATE_FLIPER, status); |
| | | UpdateDeviceStatus(INDICATE_ALIGNER, status); |
| | | UpdateDeviceStatus(INDICATE_LPORT1, status); |
| | | UpdateDeviceStatus(INDICATE_LPORT2, status); |
| | | UpdateDeviceStatus(INDICATE_LPORT3, status); |
| | | UpdateDeviceStatus(INDICATE_LPORT4, status); |
| | | UpdateDeviceStatus(INDICATE_ROBOT_ARM1, status); |
| | | UpdateDeviceStatus(INDICATE_ROBOT_ARM2, status); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /////////////////////////////////////////////////////////////////////// |
| | | // CellRange.h: header file |
| | | // |
| | | // MFC Grid Control - interface for the CCellRange class. |
| | | // |
| | | // Written by Chris Maunder <cmaunder@mail.com> |
| | | // 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:chinajoe@aol.com |
| | | // http://users.aol.com/chinajoe |
| | | |
| | | #ifndef max |
| | | #define max(a,b) (((a) > (b)) ? (a) : (b)) |
| | | #endif |
| | | |
| | | #ifndef min |
| | | #define min(a,b) (((a) < (b)) ? (a) : (b)) |
| | | #endif |
| | | |
| | | 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 |
| | | // <kenbertelson@hotmail.com> |
| | | // C Maunder - 17 Jun 2000 - Font handling optimsed, Added CGridDefaultCell |
| | | // |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| | | #include "stdafx.h" |
| | | #include "GridCell.h" |
| | | #include "GridCtrl.h" |
| | | #include "GridInPlaceEdit.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #undef THIS_FILE |
| | | static const char* THIS_FILE = __FILE__; |
| | | #endif |
| | | |
| | | IMPLEMENT_DYNCREATE(CGridCell, CGridCellBase) |
| | | IMPLEMENT_DYNCREATE(CGridDefaultCell, CGridCell) |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // GridCell |
| | | |
| | | CGridCell::CGridCell() |
| | | { |
| | | m_plfFont = NULL; |
| | | CGridCell::Reset(); |
| | | } |
| | | |
| | | CGridCell::~CGridCell() |
| | | { |
| | | if (m_plfFont) |
| | | { |
| | | delete m_plfFont; |
| | | m_plfFont = NULL; |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // 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 |
| | | |
| | | if (m_plfFont) |
| | | { |
| | | delete m_plfFont; |
| | | m_plfFont = NULL; |
| | | } |
| | | m_plfFont = NULL; // Cell font |
| | | } |
| | | |
| | | void CGridCell::SetFont(const LOGFONT* plf) |
| | | { |
| | | if (plf == NULL) |
| | | { |
| | | if (m_plfFont) |
| | | { |
| | | 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 CGridInPlaceEdit(pGrid, rect, dwStyle, nID, nRow, nCol, GetText(), nChar); |
| | | } |
| | | return TRUE; |
| | | } |
| | | |
| | | void CGridCell::EndEdit() |
| | | { |
| | | if (m_pEditWnd) |
| | | ((CGridInPlaceEdit*)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_CENTER|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; |
| | | memset(&ncm,0,sizeof(NONCLIENTMETRICS)); |
| | | ncm.cbSize = sizeof(NONCLIENTMETRICS); |
| | | //VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)); |
| | | 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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // GridCell.h : header file |
| | | // |
| | | // MFC Grid Control - Grid cell class header file |
| | | // |
| | | // Written by Chris Maunder <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 itemæ¯ 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 const 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, (int)_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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // GridCellBase.h : header file |
| | | // |
| | | // MFC Grid Control - Grid cell base class header file |
| | | // |
| | | // Written by Chris Maunder <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 itemæ¯ 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 */) { 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "GridCell.h" |
| | | #include "GridCtrl.h" |
| | | #include "GridCellButton.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #undef THIS_FILE |
| | | static const char* THIS_FILE = __FILE__; |
| | | #endif |
| | | |
| | | IMPLEMENT_DYNCREATE(CGridCellButton, CGridCell) |
| | | CGridCellButton::CGridCellButton(void) |
| | | { |
| | | m_bPushing = FALSE; |
| | | } |
| | | |
| | | CGridCellButton::~CGridCellButton(void) |
| | | { |
| | | } |
| | | |
| | | BOOL CGridCellButton::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /* = TRUE */) |
| | | { |
| | | m_rect = rect; |
| | | pDC->SetBkMode(TRANSPARENT); |
| | | rect.DeflateRect(GetMargin(), 0); |
| | | CFont* pOldFont = pDC->SelectObject(GetFontObject()); |
| | | pDC->DrawFrameControl(rect, DFC_BUTTON, m_bPushing ? DFCS_BUTTONPUSH | DFCS_PUSHED : DFCS_BUTTONPUSH); |
| | | COLORREF ColorCurrent = pDC->GetTextColor(); |
| | | pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); |
| | | pDC->DrawText(GetText(), -1, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | pDC->SetTextColor(ColorCurrent); |
| | | return TRUE; |
| | | } |
| | | |
| | | void CGridCellButton::OnClick(CPoint PointCellRelative) |
| | | { |
| | | m_bPushing = !m_bPushing; |
| | | GetGrid()->InvalidateRect(m_rect); |
| | | } |
| | | |
| | | void CGridCellButton::OnMouseLeave() |
| | | { |
| | | m_bPushing = FALSE; |
| | | GetGrid()->InvalidateRect(m_rect); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef __GRID_CELL_BUTTON__ |
| | | #define __GRID_CELL_BUTTON__ |
| | | |
| | | #include "GridCell.h" |
| | | |
| | | class CGridCellButton : public CGridCell |
| | | { |
| | | friend class CGridCtrl; |
| | | DECLARE_DYNCREATE(CGridCellButton) |
| | | |
| | | public: |
| | | CGridCellButton(void); |
| | | virtual ~CGridCellButton(void); |
| | | |
| | | void SetPushing(BOOL bPush) {m_bPushing = bPush;} |
| | | |
| | | public: |
| | | virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE); |
| | | |
| | | protected: |
| | | virtual void OnClick(CPoint PointCellRelative); |
| | | virtual void OnMouseLeave(); |
| | | |
| | | protected: |
| | | CRect m_rect; |
| | | BOOL m_bPushing; |
| | | }; |
| | | #endif |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // GridCtrl.h : header file |
| | | // |
| | | // MFC Grid Control - main header |
| | | // |
| | | // Written by Chris Maunder <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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+ |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | // FEATURES BY Mukit, Ataul (2007-11-17): |
| | | // 1. Merge Cell |
| | | // 2. Ability to do XL Style Freeze Pane |
| | | // 3. The Horizontal Gray Area Removed |
| | | |
| | | // FINDINGS: |
| | | // 1. A cell cannot be edited if a tooltip is shown.. |
| | | // 2. The InplaceEditCtrl is not multiline even if a cell can contain Multiline Text.. |
| | | // 3. If a cell is too small, the InplaceEditCtrl is almost invisible.. |
| | | |
| | | #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> |
| | | #include <vector> |
| | | using namespace std; |
| | | |
| | | |
| | | struct CELL_ENABLE |
| | | { |
| | | CELL_ENABLE() |
| | | { |
| | | nEnable = -1; |
| | | } |
| | | void SetEnable(BOOL bValue) |
| | | { |
| | | nEnable = bValue; |
| | | } |
| | | BOOL isEnable() |
| | | { |
| | | if (nEnable > 0) |
| | | { |
| | | return TRUE; |
| | | } |
| | | else |
| | | { |
| | | return FALSE; |
| | | } |
| | | } |
| | | BOOL isActivated() |
| | | { |
| | | if (nEnable < 0) |
| | | { |
| | | return FALSE; |
| | | } |
| | | else |
| | | { |
| | | return TRUE; |
| | | } |
| | | } |
| | | int nEnable; |
| | | }; |
| | | |
| | | /////////////////////////////////////////////////////////////////////////////////// |
| | | // 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 |
| | | // LUC |
| | | #define GVNI_FREEZED 0x0040 |
| | | |
| | | #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_COMBOSELCHANGE LVN_FIRST-10 |
| | | |
| | | class CGridCtrl; |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // CGridCtrl window |
| | | |
| | | typedef bool (*PVIRTUALCOMPARE)(int, int); |
| | | |
| | | 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: |
| | | |
| | | ///// LUC /////////////////////////////////////////////////////////////////////// |
| | | |
| | | //// LUC : MergeCell//////// |
| | | |
| | | INT_PTR MergeCells(CCellRange& mergedCellRange); |
| | | void SplitCells(INT_PTR nMergeID); |
| | | |
| | | BOOL IsMergedCell(int row, int col, CCellRange& mergedCellRange); |
| | | BOOL GetMergedCellRect(int row, int col, CRect& rect); |
| | | BOOL GetMergedCellRect(CCellRange& mergedCell, CRect& rect); |
| | | BOOL GetTopLeftMergedCell(int& row, int& col, CRect& mergeRect); |
| | | BOOL GetBottomRightMergedCell(int& row, int& col, CRect& mergeRect); |
| | | virtual BOOL IsFocused(CGridCellBase& cell, int nRow, int nCol); |
| | | virtual BOOL IsSelected(CGridCellBase& cell, int nRow, int nCol); |
| | | |
| | | BOOL m_bDrawingMergedCell; |
| | | INT_PTR m_nCurrentMergeID; |
| | | |
| | | static CRect rectNull; |
| | | static CCellID cellNull; |
| | | |
| | | // LUC : Freeze Rows |
| | | |
| | | BOOL SetFreezedRowCount(int nFreezedRows) |
| | | { |
| | | BOOL bRet = FALSE; |
| | | if( (nFreezedRows >= 0) && ((nFreezedRows + m_nFixedRows) <= m_nRows) ) |
| | | { |
| | | m_nFreezedRows = nFreezedRows; |
| | | ResetScrollBars(); |
| | | Refresh(); |
| | | bRet = TRUE; |
| | | } |
| | | |
| | | return bRet; |
| | | |
| | | } |
| | | |
| | | BOOL SetFreezedColumnCount(int nFreezedCols) |
| | | { |
| | | BOOL bRet = FALSE; |
| | | if( (nFreezedCols >= 0) && ((nFreezedCols + m_nFixedCols) <= m_nCols) ) |
| | | { |
| | | m_nFreezedCols = nFreezedCols; |
| | | ResetScrollBars(); |
| | | Refresh(); |
| | | bRet = TRUE; |
| | | } |
| | | |
| | | return bRet; |
| | | } |
| | | |
| | | // To avoid calling ResetScrollBars twice you can use SetFreezedFrame |
| | | BOOL SetFreezedFrame(int nFreezedRows, int nFreezedCols) |
| | | { |
| | | BOOL bRet = FALSE; |
| | | if( (nFreezedRows >= 0) && ((nFreezedRows + m_nFixedRows) <= m_nRows) ) |
| | | { |
| | | m_nFreezedRows = nFreezedRows; |
| | | bRet = TRUE; |
| | | } |
| | | if( (nFreezedCols >= 0) && ((nFreezedCols + m_nFixedCols) <= m_nCols) ) |
| | | { |
| | | m_nFreezedCols = nFreezedCols; |
| | | bRet = TRUE; |
| | | } |
| | | else |
| | | { |
| | | bRet = FALSE; |
| | | } |
| | | |
| | | ResetScrollBars(); |
| | | |
| | | return bRet; |
| | | } |
| | | |
| | | int GetFreezedRowCount() const { return m_nFreezedRows; } |
| | | int GetFreezedColumnCount() const { return m_nFreezedCols; } |
| | | |
| | | void ShowHorzNonGridArea(BOOL bShow) |
| | | { |
| | | m_bShowHorzNonGridArea = bShow; |
| | | } |
| | | |
| | | BOOL IsShowingHorzNonGridArea() |
| | | { |
| | | return m_bShowHorzNonGridArea; |
| | | } |
| | | |
| | | /////////////////////////////////////////////////////////////////////////////////////// |
| | | |
| | | int GetRowCount() const { return m_nRows; } |
| | | int GetColumnCount() const { return m_nCols; } |
| | | int GetFixedRowCount(BOOL bIncludeFreezedRows = FALSE) const |
| | | { |
| | | return (bIncludeFreezedRows) ? (m_nFixedRows + m_nFreezedRows) : m_nFixedRows; |
| | | } |
| | | int GetFixedColumnCount(BOOL bIncludeFreezedCols = FALSE) const |
| | | { |
| | | return (bIncludeFreezedCols) ? (m_nFixedCols + m_nFreezedCols) : m_nFixedCols; |
| | | } |
| | | |
| | | BOOL SetRowCount(int nRows = 10); |
| | | BOOL SetColumnCount(int nCols = 10); |
| | | |
| | | BOOL UpdateCellEditableMask(); |
| | | |
| | | BOOL SetFixedRowCount(int nFixedRows = 1); |
| | | BOOL SetFixedColumnCount(int nFixedCols = 1); |
| | | |
| | | public: |
| | | 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); |
| | | |
| | | BOOL SetCellMaskEditable(int nRow, int nCol, BOOL bEditable); |
| | | BOOL isCellMaskEditable(int nRow, int nCol); |
| | | BOOL isCellMaskActivated(int nRow, int nCol); |
| | | |
| | | // LUC |
| | | // Change for MergeCell |
| | | CCellID GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck = TRUE, CCellID& cellOriginal = cellNull); |
| | | |
| | | // LUC |
| | | //int GetFixedRowHeight() const; |
| | | //int GetFixedColumnWidth() const; |
| | | int GetFixedRowHeight(BOOL bIncludeFreezedRows = FALSE) const; |
| | | int GetFixedColumnWidth(BOOL bIncludeFreezedCols = FALSE) 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; |
| | | |
| | | 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); |
| | | // LUC |
| | | CCellRange GetVisibleNonFixedCellRange(LPRECT pRect = NULL, BOOL bForceRecalculation = FALSE); |
| | | CCellRange GetVisibleFixedCellRange(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 enable |
| | | vector<vector<CELL_ENABLE>> m_pCellEnable; |
| | | |
| | | // Cell size details |
| | | int m_nRows, m_nFixedRows, m_nCols, m_nFixedCols; |
| | | // LUC |
| | | int m_nFreezedRows, m_nFreezedCols; |
| | | BOOL m_bExcludeFreezedRowsFromSelection; |
| | | BOOL m_bExcludeFreezedColsFromSelection; |
| | | |
| | | // LUC |
| | | CArray<CCellRange, CCellRange&> m_arMergedCells; |
| | | // LUC |
| | | BOOL m_bShowHorzNonGridArea; |
| | | |
| | | 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_PTR 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_PTR 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 void OnComboSelChange(NMHDR* pNMHDR, LRESULT* pResult); |
| | | 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 |
| | | }; |
| | | // for sort in virtual mode, and column order, save and load layer |
| | | public: |
| | | typedef std::vector<int> intlist; |
| | | void Reorder(int From, int To); |
| | | void SetVirtualCompare(PVIRTUALCOMPARE VirtualCompare) { m_pfnVirtualCompare = VirtualCompare;} |
| | | int m_CurCol; |
| | | void AllowReorderColumn(bool b=true) { m_AllowReorderColumn = b;} |
| | | void EnableDragRowMode(bool b=true) { m_bDragRowMode = b; if(b) EnableDragAndDrop(); } // to change row order |
| | | int GetLayer(int** pLayer); // gives back the number of ints of the area (do not forget to delete *pLayer) |
| | | void SetLayer(int* pLayer); // coming from a previous GetLayer (ignored if not same number of column, or the same revision number) |
| | | void ForceQuitFocusOnTab(bool b=true) { m_QuitFocusOnTab = b;} // use only if GetParent() is a CDialog |
| | | void AllowSelectRowInFixedCol(bool b=true) { m_AllowSelectRowInFixedCol = b;} // |
| | | // allow acces? |
| | | intlist m_arRowOrder, m_arColOrder; |
| | | static CGridCtrl* m_This; |
| | | protected: |
| | | virtual void AddSubVirtualRow(int Num, int Nb); |
| | | bool m_bDragRowMode; |
| | | int m_CurRow; |
| | | private: |
| | | void ResetVirtualOrder(); |
| | | PVIRTUALCOMPARE m_pfnVirtualCompare; |
| | | static bool NotVirtualCompare(int c1, int c2); |
| | | bool m_InDestructor; |
| | | bool m_AllowReorderColumn; |
| | | bool m_QuitFocusOnTab; |
| | | bool m_AllowSelectRowInFixedCol; |
| | | |
| | | }; |
| | | |
| | | // 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_InDestructor) |
| | | { |
| | | gvdi.item.row = m_arRowOrder[nRow]; |
| | | gvdi.item.col = m_arColOrder[nCol]; |
| | | |
| | | if (m_pfnCallback) |
| | | m_pfnCallback(&gvdi, m_lParam); |
| | | else |
| | | SendDisplayRequestToParent(&gvdi); |
| | | gvdi.item.row = nRow; |
| | | gvdi.item.col = nCol; |
| | | } |
| | | 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; |
| | | if(pRow->GetData() == NULL) |
| | | return NULL; |
| | | return pRow->GetAt(m_arColOrder[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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 const 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 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | // GridDropTarget.h : header file |
| | | // |
| | | // MFC Grid Control - Drag/Drop target implementation |
| | | // |
| | | // Written by Chris Maunder <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // InPlaceEdit.cpp : implementation file |
| | | // |
| | | // Adapted by Chris Maunder <cmaunder@mail.com> |
| | | // Copyright (c) 1998-2002. All Rights Reserved. |
| | | // |
| | | // The code contained in this file is based on the original |
| | | // CGridInPlaceEdit 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 "GridCtrl.h" |
| | | #include "GridInPlaceEdit.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #undef THIS_FILE |
| | | static const char* THIS_FILE = __FILE__; |
| | | #endif |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // CGridInPlaceEdit |
| | | |
| | | CGridInPlaceEdit::CGridInPlaceEdit(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); |
| | | } |
| | | |
| | | CGridInPlaceEdit::~CGridInPlaceEdit() |
| | | { |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CGridInPlaceEdit, CEdit) |
| | | //{{AFX_MSG_MAP(CGridInPlaceEdit) |
| | | ON_WM_KILLFOCUS() |
| | | ON_WM_CHAR() |
| | | ON_WM_KEYDOWN() |
| | | ON_WM_GETDLGCODE() |
| | | ON_WM_CREATE() |
| | | //}}AFX_MSG_MAP |
| | | END_MESSAGE_MAP() |
| | | |
| | | //////////////////////////////////////////////////////////////////////////// |
| | | // CGridInPlaceEdit 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 CGridInPlaceEdit::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 CGridInPlaceEdit::OnKillFocus(CWnd* pNewWnd) |
| | | { |
| | | CEdit::OnKillFocus(pNewWnd); |
| | | EndEdit(); |
| | | } |
| | | |
| | | void CGridInPlaceEdit::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 CGridInPlaceEdit::OnGetDlgCode() |
| | | { |
| | | return DLGC_WANTALLKEYS; |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////////////////////////// |
| | | // CGridInPlaceEdit overrides |
| | | |
| | | // Stoopid win95 accelerator key problem workaround - Matt Weagle. |
| | | BOOL CGridInPlaceEdit::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 CGridInPlaceEdit::PostNcDestroy() |
| | | { |
| | | CEdit::PostNcDestroy(); |
| | | |
| | | delete this; |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////////////////////////// |
| | | // CGridInPlaceEdit implementation |
| | | |
| | | void CGridInPlaceEdit::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; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | // InPlaceEdit.h : header file |
| | | // |
| | | // MFC Grid Control - inplace editing class |
| | | // |
| | | // Written by Chris Maunder <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 CGridInPlaceEdit : public CEdit |
| | | { |
| | | // Construction |
| | | public: |
| | | CGridInPlaceEdit(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(CGridInPlaceEdit) |
| | | public: |
| | | virtual BOOL PreTranslateMessage(MSG* pMsg); |
| | | protected: |
| | | virtual void PostNcDestroy(); |
| | | //}}AFX_VIRTUAL |
| | | |
| | | // Implementation |
| | | public: |
| | | virtual ~CGridInPlaceEdit(); |
| | | |
| | | // Generated message map functions |
| | | protected: |
| | | //{{AFX_MSG(CGridInPlaceEdit) |
| | | 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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 |
| | | // |
| | | |
| | | ////////////////////////////////////////////////// |
| | | // CGridMemDC - memory DC |
| | | // |
| | | // Author: Keith Rule |
| | | // Email: keithr@europa.com |
| | | // 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 CGridMemDC : public CDC |
| | | { |
| | | public: |
| | | |
| | | // constructor sets up the memory DC |
| | | CGridMemDC(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 |
| | | ~CGridMemDC() |
| | | { |
| | | 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 |
| | | CGridMemDC* operator->() {return this;} |
| | | |
| | | // Allow usage as a pointer |
| | | operator CGridMemDC*() {return this;} |
| | | |
| | | private: |
| | | CBitmap m_bitmap; // Offscreen bitmap |
| | | CBitmap* m_pOldBitmap; // bitmap originally found in CGridMemDC |
| | | 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 |
| | | // 13 Mar 2004 - GetCellExtent and GetCheckPlacement fixed by Yogurt |
| | | // - Read-only now honoured - Yogurt |
| | | // |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| | | #include "stdafx.h" |
| | | #include "GridCell.h" |
| | | #include "GridCtrl.h" |
| | | #include "GridCellCheck.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #undef THIS_FILE |
| | | static const 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(); |
| | | 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(); |
| | | |
| | | // Bail if cell is read-only |
| | | CCellID cell = GetGrid()->GetCellFromPt(PointCellRelative); |
| | | if (GetGrid()->isCellMaskActivated(cell.row, cell.col)) |
| | | { |
| | | if (!GetGrid()->isCellMaskEditable(cell.row, cell.col)) |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | 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; |
| | | } |
| | | */ |
| | | |
| | | if (m_Rect.Height() < nWidth + 2 * static_cast<int> (GetMargin())) |
| | | { |
| | | place.top = m_Rect.top + (m_Rect.Height() - nWidth) / 2; |
| | | place.bottom = place.top + nWidth; |
| | | } |
| | | |
| | | return place; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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 <rdw@inn.nl>. Added nID to |
| | | // the constructor param list. |
| | | // 29 Nov 1998 - bug fix in onkeydown (Markus Irtenkauf) |
| | | // 13 Mar 2004 - GetCellExtent fixed by Yogurt |
| | | // |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| | | #include "stdafx.h" |
| | | #include "GridCell.h" |
| | | #include "GridCtrl.h" |
| | | #include "GridCellCombo.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #undef THIS_FILE |
| | | static const 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 (raybie@Exabyte.COM) |
| | | 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::OnDropdown() |
| | | { |
| | | SetDroppedWidth(GetCorrectDropWidth()); |
| | | } |
| | | |
| | | void CInPlaceList::OnSelChange() |
| | | { |
| | | CString str; |
| | | GetLBText(GetCurSel(), str); |
| | | |
| | | // Send Notification to parent |
| | | GV_DISPINFO dispinfo; |
| | | |
| | | dispinfo.hdr.hwndFrom = GetSafeHwnd(); |
| | | dispinfo.hdr.idFrom = GetDlgCtrlID(); |
| | | dispinfo.hdr.code = GVN_COMBOSELCHANGE; |
| | | |
| | | 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); |
| | | } |
| | | |
| | | 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)); |
| | | 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]); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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 <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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; |
| | | }; |
| | | |
| | | |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // 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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /////////////////////////////////////////////////////////////////////////// |
| | | // |
| | | // 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 "GridCellDateTime.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #undef THIS_FILE |
| | | static const char* THIS_FILE=__FILE__; |
| | | #define new DEBUG_NEW |
| | | #endif |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | // CGridCellDateTime |
| | | |
| | | IMPLEMENT_DYNCREATE(CGridCellDateTime, CGridCell) |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | // Construction/Destruction |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | CGridCellDateTime::CGridCellDateTime() : CGridCell() |
| | | { |
| | | m_dwStyle = 0; |
| | | m_cTime = CTime::GetCurrentTime(); |
| | | } |
| | | |
| | | CGridCellDateTime::CGridCellDateTime(DWORD dwStyle) : CGridCell() |
| | | { |
| | | Init(dwStyle); |
| | | } |
| | | |
| | | CGridCellDateTime::~CGridCellDateTime() |
| | | { |
| | | } |
| | | |
| | | 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 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("%H:%M:%S"))); |
| | | SetText(m_cTime.Format(_T("%X"))); |
| | | #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(("%d/%m/%Y"))); |
| | | SetText(m_cTime.Format(("%x"))); |
| | | #endif |
| | | } |
| | | } |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // 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() |
| | | //}}AFX_MSG_MAP |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // CInPlaceDateTime message handlers |
| | | |
| | | void CInPlaceDateTime::OnKillFocus(CWnd* pNewWnd) |
| | | { |
| | | 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); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 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(); |
| | | virtual CSize GetCellExtent(CDC* pDC); |
| | | |
| | | // 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(); |
| | | |
| | | |
| | | 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 |
| | | //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; |
| | | }; |
| | | |
| | | #endif // !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // GridCellNumeric.cpp: implementation of the CGridCellNumeric class. |
| | | // |
| | | // Written by Andrew Truckle [ajtruckle@wsatkins.co.uk] |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | #include "stdafx.h" |
| | | #include "GridCtrl.h" |
| | | #include "GridCellNumeric.h" |
| | | #include "Gridinplaceedit.h" |
| | | |
| | | IMPLEMENT_DYNCREATE(CGridCellNumeric, CGridCell) |
| | | |
| | | #ifdef _DEBUG |
| | | #undef THIS_FILE |
| | | static const 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; |
| | | |
| | | // CGridInPlaceEdit auto-deletes itself |
| | | m_pEditWnd = new CGridInPlaceEdit(GetGrid(), rect, /*GetStyle() |*/ ES_NUMBER, nID, nRow, nCol, |
| | | GetText(), nChar); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | // Cancel the editing. |
| | | void CGridCellNumeric::EndEdit() |
| | | { |
| | | if (m_pEditWnd) |
| | | ((CGridInPlaceEdit*)m_pEditWnd)->EndEdit(); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // GridCellNumeric.h: interface for the CGridCellNumeric class. |
| | | // |
| | | // Written by Andrew Truckle [ajtruckle@wsatkins.co.uk] |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | #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_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // GridURLCell.cpp: implementation of the CGridURLCell class. |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | #include "stdafx.h" |
| | | #include "GridCtrl.h" |
| | | #include "GridURLCell.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #undef THIS_FILE |
| | | static const char* THIS_FILE = __FILE__; |
| | | #endif |
| | | |
| | | IMPLEMENT_DYNCREATE(CGridURLCell, CGridCell) |
| | | |
| | | #ifndef _WIN32_WCE |
| | | HCURSOR CGridURLCell::g_hLinkCursor = NULL; |
| | | #endif |
| | | |
| | | // Possible prefixes that indicate a hyperlink |
| | | URLStruct CGridURLCell::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 |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | CGridURLCell::CGridURLCell() |
| | | { |
| | | #ifndef _WIN32_WCE |
| | | g_hLinkCursor = GetHandCursor(); |
| | | #endif |
| | | m_bLaunchUrl = TRUE; |
| | | m_clrUrl = GetSysColor(COLOR_HIGHLIGHT); |
| | | } |
| | | |
| | | CGridURLCell::~CGridURLCell() |
| | | { |
| | | } |
| | | |
| | | BOOL CGridURLCell::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd) |
| | | { |
| | | // If url is present then change text color |
| | | if (HasUrl(GetText())) |
| | | SetTextClr(m_clrUrl); |
| | | |
| | | // Good a place as any to store the bounds of the rect |
| | | m_Rect = rect; |
| | | |
| | | return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd); |
| | | } |
| | | |
| | | #pragma warning(disable:4100) |
| | | BOOL CGridURLCell::Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar) |
| | | { |
| | | return FALSE; |
| | | } |
| | | #pragma warning(default:4100) |
| | | |
| | | void CGridURLCell::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 CGridURLCell::OnSetCursor() |
| | | { |
| | | #ifndef _WIN32_WCE |
| | | CString strURL; |
| | | CPoint pt(GetMessagePos()); |
| | | GetGrid()->ScreenToClient(&pt); |
| | | pt = pt - m_Rect.TopLeft(); |
| | | |
| | | if (OverURL(pt, strURL)) |
| | | { |
| | | SetCursor(g_hLinkCursor); |
| | | return TRUE; |
| | | } |
| | | else |
| | | #endif |
| | | return CGridCell::OnSetCursor(); |
| | | } |
| | | |
| | | #ifndef _WIN32_WCE |
| | | HCURSOR CGridURLCell::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 CGridURLCell::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 CGridURLCell::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); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // GridURLCell.h: interface for the CGridURLCell class. |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | #if !defined(AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_) |
| | | #define AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_ |
| | | |
| | | #if _MSC_VER > 1000 |
| | | #pragma once |
| | | #endif // _MSC_VER > 1000 |
| | | |
| | | #include "GridCell.h" |
| | | |
| | | typedef struct { |
| | | LPCTSTR szURLPrefix; |
| | | size_t nLength; |
| | | } URLStruct; |
| | | |
| | | |
| | | |
| | | class CGridURLCell : public CGridCell |
| | | { |
| | | DECLARE_DYNCREATE(CGridURLCell) |
| | | |
| | | public: |
| | | CGridURLCell(); |
| | | virtual ~CGridURLCell(); |
| | | |
| | | 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; } |
| | | |
| | | 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; |
| | | BOOL m_bLaunchUrl; |
| | | CRect m_Rect; |
| | | }; |
| | | |
| | | #endif // !defined(AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | //////////////////////////////////////////////////////////////////////////// |
| | | // TitleTip.cpp : implementation file |
| | | // |
| | | // Based on code by Zafir Anjum |
| | | // |
| | | // Adapted by Chris Maunder <cmaunder@mail.com> |
| | | // 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 const 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 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // Titletip.h : header file |
| | | // |
| | | // MFC Grid Control - cell titletips |
| | | // |
| | | // Written by Chris Maunder <chris@codeproject.com> |
| | | // Copyright (c) 1998-2005. 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_) |
| | |
| | | // CPageRobotCmd å¯¹è¯æ¡ |
| | | |
| | | std::map<CString, int> g_deviceSlotCount = { |
| | | {_T("PORT 1"), 1}, |
| | | {_T("PORT 2"), 1}, |
| | | {_T("PORT 3"), 1}, |
| | | {_T("PORT 4"), 1}, |
| | | {_T("PORT 1"), 8}, |
| | | {_T("PORT 2"), 8}, |
| | | {_T("PORT 3"), 8}, |
| | | {_T("PORT 4"), 8}, |
| | | {_T("RB1"), 1}, |
| | | {_T("RB2"), 1}, |
| | | {_T("ALIGN"), 1}, |
| | | {_T("FLIP"), 1}, |
| | | {_T("VAC BAKE"), 2}, |
| | | {_T("VAC BAKE"), 4}, |
| | | {_T("BONDER1"), 2}, |
| | | {_T("BONDER2"), 2}, |
| | | {_T("POST BAKE(COOLING)"), 4}, |
| | | {_T("POST BAKE(COOLING)"), 2}, |
| | | {_T("MEASUREMENT"), 1} |
| | | }; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // PortConfigurationDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "afxdialogex.h" |
| | | #include "PortConfigurationDlg.h" |
| | | #include "NewCellTypes/GridCellCheck.h" |
| | | #include "NewCellTypes/GridCellCombo.h" |
| | | #include "NewCellTypes/GridCellNumeric.h" |
| | | |
| | | |
| | | // CPortConfigurationDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CPortConfigurationDlg, CDialogEx) |
| | | |
| | | CPortConfigurationDlg::CPortConfigurationDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_PORT_CONFIGURATION, pParent) |
| | | { |
| | | |
| | | } |
| | | |
| | | CPortConfigurationDlg::~CPortConfigurationDlg() |
| | | { |
| | | } |
| | | |
| | | void CPortConfigurationDlg::InitGrid() |
| | | { |
| | | if (m_wndGrid.GetSafeHwnd() == NULL) { |
| | | return; |
| | | } |
| | | |
| | | const int nCols = 3; |
| | | const int nFixRows = 1; |
| | | const int nRows = 9; |
| | | |
| | | int nColIdx = 0; |
| | | m_wndGrid.DeleteAllItems(); |
| | | m_wndGrid.SetVirtualMode(FALSE); |
| | | |
| | | // è®¾ç½®æ ·å¼é¢è² |
| | | m_wndGrid.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); |
| | | m_wndGrid.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); |
| | | m_wndGrid.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor); |
| | | m_wndGrid.SetFixedTextColor(g_nGridFixFontColor); |
| | | |
| | | // è¡åæ°é |
| | | m_wndGrid.SetRowCount(nRows); |
| | | m_wndGrid.SetColumnCount(nCols); |
| | | m_wndGrid.SetFixedRowCount(nFixRows); |
| | | m_wndGrid.SetFixedColumnCount(0); |
| | | |
| | | // 设置å宽 |
| | | m_wndGrid.SetColumnWidth(nColIdx, 50); |
| | | m_wndGrid.SetItemText(0, nColIdx++, _T("Slot ID")); |
| | | m_wndGrid.SetColumnWidth(nColIdx, 150); |
| | | m_wndGrid.SetItemText(0, nColIdx++, _T("EQ Recipe")); |
| | | m_wndGrid.SetColumnWidth(nColIdx, 150); |
| | | m_wndGrid.SetItemText(0, nColIdx++, _T("Panel ID")); |
| | | m_wndGrid.SetColumnWidth(nColIdx, 60); |
| | | m_wndGrid.SetItemText(0, nColIdx++, _T("å¯ç¨")); |
| | | |
| | | // 设置è¡ä¸ºæ ·å¼ |
| | | m_wndGrid.SetFixedRowSelection(FALSE); |
| | | m_wndGrid.SetFixedColumnSelection(FALSE); |
| | | m_wndGrid.SetEditable(TRUE); |
| | | m_wndGrid.SetRowResize(FALSE); |
| | | m_wndGrid.SetColumnResize(TRUE); |
| | | m_wndGrid.SetListMode(TRUE); |
| | | m_wndGrid.EnableSelection(TRUE); |
| | | m_wndGrid.SetSingleRowSelection(TRUE); |
| | | m_wndGrid.ExpandColumnsToFit(TRUE); |
| | | m_wndGrid.ExpandLastColumn(); |
| | | |
| | | // èªå¨è®¡ç®å¹¶è®¾ç½®æ¯è¡é«åº¦ |
| | | CRect rcClient; |
| | | m_wndGrid.GetClientRect(&rcClient); |
| | | int nAvailableHeight = rcClient.Height(); |
| | | int nEachRowHeight = max(24, nAvailableHeight / nRows); |
| | | |
| | | for (int i = 0; i < nRows; ++i) { |
| | | m_wndGrid.SetRowHeight(i, nEachRowHeight); |
| | | } |
| | | |
| | | FillGrid(); |
| | | } |
| | | |
| | | void CPortConfigurationDlg::FillGrid() |
| | | { |
| | | //CStringArray recipeOptions; |
| | | //recipeOptions.Add(_T("Recipe A")); |
| | | //recipeOptions.Add(_T("Recipe B")); |
| | | //recipeOptions.Add(_T("Recipe C")); |
| | | |
| | | for (int i = 1; i < 9; ++i) { |
| | | CString strIndex; |
| | | strIndex.Format(_T("%d"), i); |
| | | m_wndGrid.SetItemText(i, 0, strIndex); |
| | | m_wndGrid.SetItemState(i, 0, GVIS_READONLY); |
| | | |
| | | // EQ Recipe - ComboBox |
| | | //if (m_wndGrid.SetCellType(i, 1, RUNTIME_CLASS(CGridCellCombo))) { |
| | | // CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_wndGrid.GetCell(i, 1)); |
| | | // pCell->SetOptions(recipeOptions); |
| | | // pCell->SetStyle(CBS_DROPDOWNLIST); |
| | | //} |
| | | //m_wndGrid.SetItemText(i, 1, recipeOptions[0]); |
| | | |
| | | // Panel ID - å¯ç¼è¾ |
| | | m_wndGrid.SetItemText(i, 1, _T("")); |
| | | |
| | | // Checkbox |
| | | m_wndGrid.SetCellType(i, 2, RUNTIME_CLASS(CGridCellCheck)); |
| | | CGridCellCheck* pCheck = static_cast<CGridCellCheck*>(m_wndGrid.GetCell(i, 2)); |
| | | if (pCheck) { |
| | | pCheck->SetCheck(FALSE); |
| | | } |
| | | } |
| | | |
| | | m_wndGrid.Invalidate(); |
| | | m_wndGrid.UpdateWindow(); |
| | | } |
| | | |
| | | void CPortConfigurationDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | DDX_Control(pDX, IDC_GRID_PANEL_RECIPE, m_wndGrid); |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPortConfigurationDlg, CDialogEx) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CPortConfigurationDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | BOOL CPortConfigurationDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | InitGrid(); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | #include "GridCtrl.h" |
| | | |
| | | // CPortConfigurationDlg å¯¹è¯æ¡ |
| | | |
| | | class CPortConfigurationDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPortConfigurationDlg) |
| | | |
| | | public: |
| | | CPortConfigurationDlg(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPortConfigurationDlg(); |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_PORT_CONFIGURATION }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | virtual BOOL OnInitDialog(); |
| | | DECLARE_MESSAGE_MAP() |
| | | |
| | | private: |
| | | CGridCtrl m_wndGrid; |
| | | |
| | | void InitGrid(); |
| | | void FillGrid(); |
| | | }; |
| | |
| | | #include "ServoGraph.h" |
| | | #include "AlarmManager.h" |
| | | #include "SECSRuntimeManager.h" |
| | | #include "ProductionLogManager.h" |
| | | #include "TransferManager.h" |
| | | #include "VerticalLine.h" |
| | | #include "EqsGraphWnd.h" |
| | | #include "MapPosWnd.h" |
| | |
| | | } |
| | | AlarmManager::getInstance().insertMockData(); |
| | | |
| | | |
| | | // åå§åç产履å管çå¨ |
| | | //try { |
| | | // if (!ProductionLogManager::getInstance().initProductionTable()) { |
| | | // AfxMessageBox("åå§åç产履å管çå¨å¤±è´¥ï¼"); |
| | | // return FALSE; |
| | | // } |
| | | //} |
| | | //catch (const std::exception& ex) { |
| | | // CString errorMsg; |
| | | // errorMsg.Format(_T("åå§åç产履å管çå¨å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | // AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | // return FALSE; |
| | | //} |
| | | |
| | | |
| | | // åå§åSECSè¿è¡è®¾ç½®ç®¡çåº |
| | | try { |
| | | if (!SECSRuntimeManager::getInstance().initRuntimeSetting()) { |
| | |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åSECSè¿è¡è®¾ç½®å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | // åå§åæ¬è¿è®°å½ç®¡çåº |
| | | try { |
| | | if (!TransferManager::getInstance().initTransferTable()) { |
| | | AfxMessageBox("åå§åæ¬è¿è®°å½ç®¡çåºè®¾ç½®å¤±è´¥ï¼"); |
| | | return FALSE; |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åæ¬è¿è®°å½ç®¡çåºè®¾ç½®å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | |
| | | // 鿝æ¥è¦è¡¨ |
| | | AlarmManager::getInstance().termAlarmTable(); |
| | | |
| | | // 鿝ç产表 |
| | | ProductionLogManager::getInstance().termProductionTable(); |
| | | |
| | | // 鿝SECSè¿è¡è®¾ç½®ç®¡çåº |
| | | SECSRuntimeManager::getInstance().termRuntimeSetting(); |
| | | |
| | | // 鿝æ¬è¿è®°å½ç®¡çåº |
| | | TransferManager::getInstance().termTransferTable(); |
| | | |
| | | return CWinApp::ExitInstance(); |
| | | } |
| | | |
| | |
| | | <Optimization>Disabled</Optimization> |
| | | <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <SDLCheck>true</SDLCheck> |
| | | <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;..\MELSECSDK\include;.\CCLinkPerformance;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
| | | <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;..\MELSECSDK\include;.\CCLinkPerformance;.\GridControl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
| | | </ClCompile> |
| | | <Link> |
| | | <SubSystem>Windows</SubSystem> |
| | |
| | | <ClInclude Include="CRobotCmdTestDlg.h" /> |
| | | <ClInclude Include="CPagePortStatus.h" /> |
| | | <ClInclude Include="CPortStatusReport.h" /> |
| | | <ClInclude Include="GridControl\CellRange.h" /> |
| | | <ClInclude Include="GridControl\GridCell.h" /> |
| | | <ClInclude Include="GridControl\GridCellBase.h" /> |
| | | <ClInclude Include="GridControl\GridCellButton.h" /> |
| | | <ClInclude Include="GridControl\GridCtrl.h" /> |
| | | <ClInclude Include="GridControl\GridDropTarget.h" /> |
| | | <ClInclude Include="GridControl\GridInPlaceEdit.h" /> |
| | | <ClInclude Include="GridControl\GridMemDC.h" /> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellCheck.h" /> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellCombo.h" /> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellDateTime.h" /> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellNumeric.h" /> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridURLCell.h" /> |
| | | <ClInclude Include="GridControl\TitleTip.h" /> |
| | | <ClInclude Include="JobSlotGrid.h" /> |
| | | <ClInclude Include="MsgDlg.h" /> |
| | | <ClInclude Include="PageRecipe.h" /> |
| | |
| | | <ClInclude Include="MapPosWnd.h" /> |
| | | <ClInclude Include="Model.h" /> |
| | | <ClInclude Include="PageRobotCmd.h" /> |
| | | <ClInclude Include="PortConfigurationDlg.h" /> |
| | | <ClInclude Include="ProductionLogManager.h" /> |
| | | <ClInclude Include="Resource.h" /> |
| | | <ClInclude Include="SECSRuntimeManager.h" /> |
| | |
| | | <ClInclude Include="targetver.h" /> |
| | | <ClInclude Include="TerminalDisplayDlg.h" /> |
| | | <ClInclude Include="ToolUnits.h" /> |
| | | <ClInclude Include="TransferManager.h" /> |
| | | <ClInclude Include="VerticalLine.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | |
| | | <ClCompile Include="CRobotCmdTestDlg.cpp" /> |
| | | <ClCompile Include="CPagePortStatus.cpp" /> |
| | | <ClCompile Include="CPortStatusReport.cpp" /> |
| | | <ClCompile Include="GridControl\GridCell.cpp" /> |
| | | <ClCompile Include="GridControl\GridCellBase.cpp" /> |
| | | <ClCompile Include="GridControl\GridCellButton.cpp" /> |
| | | <ClCompile Include="GridControl\GridCtrl.cpp" /> |
| | | <ClCompile Include="GridControl\GridDropTarget.cpp" /> |
| | | <ClCompile Include="GridControl\GridInPlaceEdit.cpp" /> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellCheck.cpp" /> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellCombo.cpp" /> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellDateTime.cpp" /> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellNumeric.cpp" /> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridURLCell.cpp" /> |
| | | <ClCompile Include="GridControl\TitleTip.cpp" /> |
| | | <ClCompile Include="JobSlotGrid.cpp" /> |
| | | <ClCompile Include="MsgDlg.cpp" /> |
| | | <ClCompile Include="PageRecipe.cpp" /> |
| | |
| | | <ClCompile Include="MapPosWnd.cpp" /> |
| | | <ClCompile Include="Model.cpp" /> |
| | | <ClCompile Include="PageRobotCmd.cpp" /> |
| | | <ClCompile Include="PortConfigurationDlg.cpp" /> |
| | | <ClCompile Include="ProductionLogManager.cpp" /> |
| | | <ClCompile Include="SECSRuntimeManager.cpp" /> |
| | | <ClCompile Include="SecsTestDlg.cpp" /> |
| | |
| | | </ClCompile> |
| | | <ClCompile Include="TerminalDisplayDlg.cpp" /> |
| | | <ClCompile Include="ToolUnits.cpp" /> |
| | | <ClCompile Include="TransferManager.cpp" /> |
| | | <ClCompile Include="VerticalLine.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | |
| | | <ClCompile Include="MsgDlg.cpp" /> |
| | | <ClCompile Include="CPagePortStatus.cpp" /> |
| | | <ClCompile Include="JobSlotGrid.cpp" /> |
| | | <ClCompile Include="GridControl\GridCell.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\GridCellBase.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\GridCellButton.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\GridCtrl.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\GridDropTarget.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\GridInPlaceEdit.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\TitleTip.cpp"> |
| | | <Filter>GridControl</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellCheck.cpp"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellCombo.cpp"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellDateTime.cpp"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridCellNumeric.cpp"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="GridControl\NewCellTypes\GridURLCell.cpp"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="PortConfigurationDlg.cpp" /> |
| | | <ClCompile Include="TransferManager.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | |
| | | <ClInclude Include="CPagePortStatus.h" /> |
| | | <ClInclude Include="ServoCommo.h" /> |
| | | <ClInclude Include="JobSlotGrid.h" /> |
| | | <ClInclude Include="GridControl\CellRange.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridCell.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridCellBase.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridCellButton.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridCtrl.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridDropTarget.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridInPlaceEdit.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\GridMemDC.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\TitleTip.h"> |
| | | <Filter>GridControl</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellCheck.h"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellCombo.h"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellDateTime.h"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridCellNumeric.h"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="GridControl\NewCellTypes\GridURLCell.h"> |
| | | <Filter>GridControl\NewCellTypes</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="PortConfigurationDlg.h" /> |
| | | <ClInclude Include="TransferManager.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |
| | |
| | | <Filter Include="CCLinkPerformance"> |
| | | <UniqueIdentifier>{77338295-9841-4706-8816-a958b1b5c465}</UniqueIdentifier> |
| | | </Filter> |
| | | <Filter Include="GridControl"> |
| | | <UniqueIdentifier>{1206b229-6054-40f2-8d8a-5848582a3896}</UniqueIdentifier> |
| | | </Filter> |
| | | <Filter Include="GridControl\NewCellTypes"> |
| | | <UniqueIdentifier>{52ebd40d-fb71-4a53-93ab-5b93670c706d}</UniqueIdentifier> |
| | | </Filter> |
| | | </ItemGroup> |
| | | </Project> |
| | |
| | | <RESOURCE_FILE>Servo.rc</RESOURCE_FILE> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
| | | <RemoteDebuggerCommand>D:\Servo\Debug\Servo.exe</RemoteDebuggerCommand> |
| | | <RemoteDebuggerWorkingDirectory>D:\Servo\Debug\</RemoteDebuggerWorkingDirectory> |
| | | <RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\Servo\Debug\Servo.exe</RemoteDebuggerCommand> |
| | | <RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\Servo\Debug\</RemoteDebuggerWorkingDirectory> |
| | | <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName> |
| | | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| | | </PropertyGroup> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "TransferManager.h" |
| | | #include <iostream> |
| | | #include <sstream> |
| | | #include <fstream> |
| | | #include <iomanip> |
| | | #include <ctime> |
| | | #include <stdexcept> |
| | | |
| | | // éæäºæ¥éåå§å |
| | | std::mutex TransferManager::m_mutex; |
| | | |
| | | // è·å TransferManager åä¾ |
| | | TransferManager& TransferManager::getInstance() { |
| | | static TransferManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | TransferManager::TransferManager() { |
| | | m_pDB = new BL::SQLiteDatabase(); |
| | | } |
| | | |
| | | // ææå½æ° |
| | | TransferManager::~TransferManager() { |
| | | if (m_pDB) { |
| | | delete m_pDB; |
| | | m_pDB = nullptr; |
| | | } |
| | | } |
| | | |
| | | // ä»»å¡ç¶æè½¬æ¢æ int ç±»å |
| | | int TransferManager::statusToInt(TransferStatus status) { |
| | | return static_cast<int>(status); |
| | | } |
| | | |
| | | // int ç±»åè½¬æ¢æä»»å¡ç¶æ |
| | | TransferStatus TransferManager::intToStatus(int value) { |
| | | switch (value) { |
| | | case 0: return TransferStatus::Ready; |
| | | case 1: return TransferStatus::Running; |
| | | case 2: return TransferStatus::Error; |
| | | case 3: return TransferStatus::Abort; |
| | | case 4: return TransferStatus::Completed; |
| | | default: return TransferStatus::Error; |
| | | } |
| | | } |
| | | |
| | | // ä»»å¡ç¶æè½¬æ¢æå符串 |
| | | std::string TransferManager::statusToString(TransferStatus status) { |
| | | switch (status) { |
| | | case TransferStatus::Ready: return "Ready"; |
| | | case TransferStatus::Running: return "Running"; |
| | | case TransferStatus::Error: return "Error"; |
| | | case TransferStatus::Abort: return "Abort"; |
| | | case TransferStatus::Completed: return "Completed"; |
| | | default: return "Unknown"; |
| | | } |
| | | } |
| | | |
| | | // åç¬¦ä¸²è½¬æ¢æä»»å¡ç¶æ |
| | | TransferStatus TransferManager::stringToStatus(const std::string& str) { |
| | | if (str == "Ready") return TransferStatus::Ready; |
| | | if (str == "Running") return TransferStatus::Running; |
| | | if (str == "Error") return TransferStatus::Error; |
| | | if (str == "Abort") return TransferStatus::Abort; |
| | | if (str == "Completed") return TransferStatus::Completed; |
| | | return TransferStatus::Error; |
| | | } |
| | | |
| | | // æ¬å°ç¼ç 转为 UTF-8 |
| | | std::string TransferManager::ansiToUtf8(const std::string& ansiStr) { |
| | | // 1. ANSI â UTF-16 |
| | | int wideLen = MultiByteToWideChar(CP_ACP, 0, ansiStr.c_str(), -1, nullptr, 0); |
| | | std::wstring wideStr(wideLen, 0); |
| | | MultiByteToWideChar(CP_ACP, 0, ansiStr.c_str(), -1, &wideStr[0], wideLen); |
| | | |
| | | // 2. UTF-16 â UTF-8 |
| | | int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, nullptr, 0, nullptr, nullptr); |
| | | std::string utf8Str(utf8Len, 0); |
| | | WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, &utf8Str[0], utf8Len, nullptr, nullptr); |
| | | |
| | | utf8Str.pop_back(); // 廿æåç '\0' |
| | | return utf8Str; |
| | | } |
| | | |
| | | // UTF-8 转为æ¬å°ç¼ç |
| | | std::string TransferManager::utf8ToAnsi(const std::string& utf8Str) { |
| | | // 1. UTF-8 â UTF-16 |
| | | int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0); |
| | | std::wstring wideStr(wideLen, 0); |
| | | MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wideStr[0], wideLen); |
| | | |
| | | // 2. UTF-16 â ANSI |
| | | int ansiLen = WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, NULL, 0, NULL, NULL); |
| | | std::string ansiStr(ansiLen, 0); |
| | | WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, &ansiStr[0], ansiLen, NULL, NULL); |
| | | |
| | | ansiStr.pop_back(); // 廿æåç '\0' |
| | | return ansiStr; |
| | | } |
| | | |
| | | // åå§åæ¬è¿è®°å½è¡¨ |
| | | bool TransferManager::initTransferTable() { |
| | | char szPath[MAX_PATH]; |
| | | GetModuleFileName(NULL, szPath, MAX_PATH); |
| | | std::string exePath(szPath); |
| | | std::string dbDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB"; |
| | | |
| | | if (!CreateDirectory(dbDir.c_str(), NULL) && GetLastError() != ERROR_ALREADY_EXISTS) { |
| | | throw std::runtime_error("åå»ºæ°æ®åºç®å½å¤±è´¥"); |
| | | } |
| | | |
| | | std::string dbPath = dbDir + "\\TransferManager.db"; |
| | | |
| | | if (!m_pDB->connect(dbPath, true)) { |
| | | throw std::runtime_error("è¿æ¥æ°æ®åºå¤±è´¥"); |
| | | } |
| | | |
| | | const std::string createTableSQL = R"( |
| | | CREATE TABLE IF NOT EXISTS transfers ( |
| | | record_id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | class_id TEXT NOT NULL, |
| | | status TEXT NOT NULL, |
| | | create_time TEXT, |
| | | pick_time TEXT, |
| | | place_time TEXT, |
| | | end_time TEXT, |
| | | description TEXT |
| | | ); |
| | | )"; |
| | | |
| | | return m_pDB->executeQuery(createTableSQL); |
| | | } |
| | | |
| | | // æå
¥æµè¯æ¬è¿è®°å½ |
| | | void TransferManager::insertTestTransferRecord() { |
| | | TransferData data; |
| | | data.strClassID = "Task-20240529-001"; |
| | | data.strStatus = "Running"; |
| | | data.strCreateTime = "2024-05-29 10:30:00"; |
| | | data.strPickTime = "2024-05-29 10:31:00"; |
| | | data.strPlaceTime = "2024-05-29 10:32:00"; |
| | | data.strEndTime = "2024-05-29 10:33:00"; |
| | | data.strDescription = "æ¬è¿å¨ä½ï¼ä» Port1 åç â Port2 æ¾ç"; |
| | | |
| | | int nRecordId = -1; |
| | | if (TransferManager::getInstance().addTransferRecord(data, nRecordId)) { |
| | | std::cout << "æå
¥æåï¼è®°å½ ID = " << nRecordId << std::endl; |
| | | } |
| | | else { |
| | | std::cerr << "æå
¥å¤±è´¥ï¼" << std::endl; |
| | | } |
| | | } |
| | | |
| | | // æå¼æ°æ®åºè¿æ¥ |
| | | void TransferManager::termTransferTable() { |
| | | if (m_pDB) { |
| | | m_pDB->disconnect(); |
| | | } |
| | | } |
| | | |
| | | // å 餿¬è¿è®°å½è¡¨ |
| | | bool TransferManager::destroyTransferTable() { |
| | | if (!m_pDB) return false; |
| | | |
| | | const std::string dropTableSQL = "DROP TABLE IF EXISTS transfers;"; |
| | | return m_pDB->executeQuery(dropTableSQL); |
| | | } |
| | | |
| | | // æå
¥æ¬è¿è®°å½ |
| | | bool TransferManager::addTransferRecord(const TransferData& data, int& outRecordId) { |
| | | if (!m_pDB) { |
| | | return false; |
| | | } |
| | | |
| | | std::ostringstream oss; |
| | | oss << "INSERT INTO transfers (class_id, status, create_time, pick_time, place_time, end_time, description) " |
| | | << "VALUES ('" |
| | | << ansiToUtf8(data.strClassID) << "', '" |
| | | << ansiToUtf8(data.strStatus) << "', '" |
| | | << data.strCreateTime << "', '" |
| | | << data.strPickTime << "', '" |
| | | << data.strPlaceTime << "', '" |
| | | << data.strEndTime << "', '" |
| | | << ansiToUtf8(data.strDescription) << "') RETURNING record_id;"; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | |
| | | auto results = m_pDB->fetchResults(oss.str()); |
| | | if (!results.empty() && !results[0].empty()) { |
| | | try { |
| | | outRecordId = std::stoi(results[0][0]); |
| | | return true; |
| | | } |
| | | catch (const std::exception& e) { |
| | | std::cerr << "è§£æ record_id åºé: " << e.what() << std::endl; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | // æ¥è¯¢æææ¬è¿è®°å½ |
| | | std::vector<TransferData> TransferManager::getAllTransfers() { |
| | | std::vector<TransferData> records; |
| | | |
| | | if (!m_pDB) { |
| | | return records; |
| | | } |
| | | |
| | | const std::string query = R"( |
| | | SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description |
| | | FROM transfers |
| | | ORDER BY record_id DESC |
| | | )"; |
| | | |
| | | auto results = m_pDB->fetchResults(query); |
| | | for (const auto& row : results) { |
| | | if (row.size() != 8) continue; |
| | | |
| | | TransferData data; |
| | | data.nRecordId = std::stoi(row[0]); |
| | | data.strClassID = row[1]; |
| | | data.strStatus = row[2]; |
| | | data.strCreateTime = row[3]; |
| | | data.strPickTime = row[4]; |
| | | data.strPlaceTime = row[5]; |
| | | data.strEndTime = row[6]; |
| | | data.strDescription = row[7]; |
| | | |
| | | records.push_back(data); |
| | | } |
| | | |
| | | return records; |
| | | } |
| | | |
| | | // æ ¹æ® ID æ¥è¯¢æ¬è¿è®°å½ |
| | | TransferData TransferManager::getTransferById(int id) { |
| | | TransferData data; |
| | | if (!m_pDB) { |
| | | return data; |
| | | } |
| | | std::ostringstream oss; |
| | | oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " |
| | | << "FROM transfers WHERE record_id = " << id; |
| | | auto results = m_pDB->fetchResults(oss.str()); |
| | | if (!results.empty() && results[0].size() == 8) { |
| | | data.nRecordId = std::stoi(results[0][0]); |
| | | data.strClassID = results[0][1]; |
| | | data.strStatus = results[0][2]; |
| | | data.strCreateTime = results[0][3]; |
| | | data.strPickTime = results[0][4]; |
| | | data.strPlaceTime = results[0][5]; |
| | | data.strEndTime = results[0][6]; |
| | | data.strDescription = results[0][7]; |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | // æ ¹æ®æ¶é´èå´æ¥è¯¢æ¬è¿è®°å½ |
| | | std::vector<TransferData> TransferManager::getTransfersByTimeRange(const std::string& startTime, const std::string& endTime) { |
| | | std::vector<TransferData> records; |
| | | if (!m_pDB) { |
| | | return records; |
| | | } |
| | | std::ostringstream oss; |
| | | oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " |
| | | << "FROM transfers WHERE 1=1"; |
| | | if (!startTime.empty()) { |
| | | oss << " AND create_time >= '" << startTime << "'"; |
| | | } |
| | | if (!endTime.empty()) { |
| | | oss << " AND end_time <= '" << endTime << "'"; |
| | | } |
| | | auto results = m_pDB->fetchResults(oss.str()); |
| | | for (const auto& row : results) { |
| | | if (row.size() != 8) continue; |
| | | TransferData data; |
| | | data.nRecordId = std::stoi(row[0]); |
| | | data.strClassID = row[1]; |
| | | data.strStatus = row[2]; |
| | | data.strCreateTime = row[3]; |
| | | data.strPickTime = row[4]; |
| | | data.strPlaceTime = row[5]; |
| | | data.strEndTime = row[6]; |
| | | data.strDescription = row[7]; |
| | | records.push_back(data); |
| | | } |
| | | return records; |
| | | } |
| | | |
| | | // æ¥è¯¢æå®ç¶æçæ¬è¿è®°å½ |
| | | std::vector<TransferData> TransferManager::getTransfersByStatus(const std::string& status) { |
| | | std::vector<TransferData> records; |
| | | if (!m_pDB) { |
| | | return records; |
| | | } |
| | | |
| | | std::ostringstream oss; |
| | | oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " |
| | | << "FROM transfers WHERE status = '" << status << "' " |
| | | << "ORDER BY create_time DESC"; |
| | | |
| | | auto results = m_pDB->fetchResults(oss.str()); |
| | | for (const auto& row : results) { |
| | | if (row.size() != 8) continue; |
| | | |
| | | TransferData data; |
| | | data.nRecordId = std::stoi(row[0]); |
| | | data.strClassID = row[1]; |
| | | data.strStatus = row[2]; |
| | | data.strCreateTime = row[3]; |
| | | data.strPickTime = row[4]; |
| | | data.strPlaceTime = row[5]; |
| | | data.strEndTime = row[6]; |
| | | data.strDescription = row[7]; |
| | | |
| | | records.push_back(data); |
| | | } |
| | | |
| | | return records; |
| | | } |
| | | |
| | | // å页è·åæ¬è¿è®°å½ |
| | | //std::vector<TransferData> TransferManager::getTransfers(int startPosition, int count) { |
| | | // std::vector<TransferData> records; |
| | | // if (!m_pDB) { |
| | | // return records; |
| | | // } |
| | | // std::ostringstream oss; |
| | | // oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " |
| | | // << "FROM transfers ORDER BY create_time DESC LIMIT " << count << " OFFSET " << startPosition; |
| | | // auto results = m_pDB->fetchResults(oss.str()); |
| | | // for (const auto& row : results) { |
| | | // if (row.size() != 8) continue; |
| | | // TransferData data; |
| | | // data.nRecordId = std::stoi(row[0]); |
| | | // data.strClassID = row[1]; |
| | | // data.strStatus = row[2]; |
| | | // data.strCreateTime = row[3]; |
| | | // data.strPickTime = row[4]; |
| | | // data.strPlaceTime = row[5]; |
| | | // data.strEndTime = row[6]; |
| | | // data.strDescription = row[7]; |
| | | // records.push_back(data); |
| | | // } |
| | | // return records; |
| | | //} |
| | | |
| | | // è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° |
| | | int TransferManager::getTotalTransferCount() { |
| | | if (!m_pDB) { |
| | | return 0; |
| | | } |
| | | |
| | | const std::string query = "SELECT COUNT(*) FROM transfers;"; |
| | | auto results = m_pDB->fetchResults(query); |
| | | |
| | | if (!results.empty() && !results[0].empty()) { |
| | | try { |
| | | return std::stoi(results[0][0]); |
| | | } |
| | | catch (const std::exception& e) { |
| | | std::cerr << "Error parsing total count: " << e.what() << std::endl; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° |
| | | int TransferManager::getTotalTransferCount(const TransferData& filter) { |
| | | if (!m_pDB) { |
| | | return 0; |
| | | } |
| | | |
| | | std::ostringstream oss; |
| | | oss << "SELECT COUNT(*) FROM transfers WHERE 1=1"; |
| | | |
| | | // ç¶æçéï¼å®å
¨å¹é
ï¼ |
| | | if (!filter.strStatus.empty()) { |
| | | oss << " AND status = '" << filter.strStatus << "'"; |
| | | } |
| | | |
| | | // æè¿°å
³é®å模ç³å¹é
|
| | | if (!filter.strDescription.empty()) { |
| | | oss << " AND description LIKE '%" << filter.strDescription << "%'"; |
| | | } |
| | | |
| | | // æ¶é´èå´çé |
| | | if (!filter.strCreateTime.empty()) { |
| | | oss << " AND create_time >= '" << filter.strCreateTime << "'"; |
| | | } |
| | | if (!filter.strEndTime.empty()) { |
| | | oss << " AND end_time <= '" << filter.strEndTime << "'"; |
| | | } |
| | | |
| | | auto results = m_pDB->fetchResults(oss.str()); |
| | | if (!results.empty() && !results[0].empty()) { |
| | | try { |
| | | return std::stoi(results[0][0]); |
| | | } |
| | | catch (const std::exception& e) { |
| | | std::cerr << "Error parsing total count: " << e.what() << std::endl; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<TransferData> TransferManager::getTransfers(const TransferData& filter, int pageNum, int pageSize) { |
| | | std::vector<TransferData> records; |
| | | |
| | | if (!m_pDB) { |
| | | return records; |
| | | } |
| | | |
| | | std::ostringstream oss; |
| | | oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " |
| | | << "FROM transfers WHERE 1=1"; |
| | | |
| | | // æ¡ä»¶æ¼æ¥ï¼ä¸ getTotalTransferCount ä¿æä¸è´ï¼ |
| | | if (!filter.strStatus.empty()) { |
| | | oss << " AND status = '" << filter.strStatus << "'"; |
| | | } |
| | | if (!filter.strDescription.empty()) { |
| | | oss << " AND description LIKE '%" << filter.strDescription << "%'"; |
| | | } |
| | | if (!filter.strCreateTime.empty()) { |
| | | oss << " AND create_time >= '" << filter.strCreateTime << "'"; |
| | | } |
| | | if (!filter.strEndTime.empty()) { |
| | | oss << " AND end_time <= '" << filter.strEndTime << "'"; |
| | | } |
| | | |
| | | // å页æ§å¶ |
| | | int offset = (pageNum - 1) * pageSize; |
| | | oss << " ORDER BY create_time DESC"; |
| | | oss << " LIMIT " << pageSize << " OFFSET " << offset; |
| | | |
| | | // æ¥è¯¢ |
| | | auto results = m_pDB->fetchResults(oss.str()); |
| | | for (const auto& row : results) { |
| | | if (row.size() != 8) continue; |
| | | |
| | | TransferData data; |
| | | data.nRecordId = std::stoi(row[0]); |
| | | data.strClassID = row[1]; |
| | | data.strStatus = row[2]; |
| | | data.strCreateTime = row[3]; |
| | | data.strPickTime = row[4]; |
| | | data.strPlaceTime = row[5]; |
| | | data.strEndTime = row[6]; |
| | | data.strDescription = row[7]; |
| | | |
| | | records.push_back(data); |
| | | } |
| | | |
| | | return records; |
| | | } |
| | | |
| | | // æ¸
çæ©äºæä¸æ¶é´çæ¬è¿è®°å½ |
| | | void TransferManager::cleanOldTransfers(int daysToKeep) { |
| | | if (!m_pDB) { |
| | | return; |
| | | } |
| | | std::ostringstream oss; |
| | | oss << "DELETE FROM transfers WHERE create_time < datetime('now', '-" << daysToKeep << " days')"; |
| | | |
| | | m_pDB->executeQuery(oss.str()); |
| | | } |
| | | |
| | | // è¯»åæ¬è¿è®°å½ CSV æä»¶ |
| | | bool TransferManager::readTransferFile(const std::string& filename) { |
| | | std::ifstream file(filename); |
| | | if (!file.is_open()) { |
| | | std::cerr << "æ æ³æå¼æä»¶: " << filename << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | std::string line; |
| | | bool firstLine = true; |
| | | int insertedCount = 0; |
| | | |
| | | while (std::getline(file, line)) { |
| | | if (firstLine) { |
| | | firstLine = false; |
| | | continue; |
| | | } |
| | | |
| | | std::stringstream ss(line); |
| | | std::string cell; |
| | | TransferData data; |
| | | |
| | | try { |
| | | std::getline(ss, cell, ','); |
| | | data.nRecordId = std::stoi(cell); |
| | | |
| | | std::getline(ss, data.strClassID, ','); |
| | | std::getline(ss, data.strStatus, ','); |
| | | std::getline(ss, data.strCreateTime, ','); |
| | | std::getline(ss, data.strPickTime, ','); |
| | | std::getline(ss, data.strPlaceTime, ','); |
| | | std::getline(ss, data.strEndTime, ','); |
| | | std::getline(ss, data.strDescription, ','); |
| | | |
| | | int newId = -1; |
| | | if (addTransferRecord(data, newId)) { |
| | | ++insertedCount; |
| | | } |
| | | } |
| | | catch (const std::exception& e) { |
| | | std::cerr << "读åé误è¡: " << line << "ï¼é误: " << e.what() << std::endl; |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | file.close(); |
| | | std::cout << "æå导å
¥è®°å½æ°: " << insertedCount << std::endl; |
| | | return true; |
| | | } |
| | | |
| | | // ä¿åæ¬è¿è®°å½å° CSV æä»¶ |
| | | bool TransferManager::saveTransferFile(const std::string& filename) { |
| | | std::ofstream file(filename); |
| | | if (!file.is_open()) { |
| | | std::cerr << "æ æ³åå
¥æä»¶: " << filename << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | // åå
¥æ é¢ |
| | | file << "RecordID,ClassID,Status,CreateTime,PickTime,PlaceTime,EndTime,Description\n"; |
| | | |
| | | auto records = getAllTransfers(); |
| | | for (const auto& data : records) { |
| | | file << data.nRecordId << "," |
| | | << data.strClassID << "," |
| | | << data.strStatus << "," |
| | | << data.strCreateTime << "," |
| | | << data.strPickTime << "," |
| | | << data.strPlaceTime << "," |
| | | << data.strEndTime << "," |
| | | << data.strDescription << "\n"; |
| | | } |
| | | |
| | | file.close(); |
| | | std::cout << "å·²å¯¼åº " << records.size() << " æ¡è®°å½å°: " << filename << std::endl; |
| | | return true; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef TRANSFER_MANAGER_H |
| | | #define TRANSFER_MANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <mutex> |
| | | #include <unordered_map> |
| | | #include "Database.h" |
| | | |
| | | /** |
| | | * ä»»å¡ç¶ææä¸¾ç±»å |
| | | */ |
| | | enum class TransferStatus { |
| | | Ready = 0, |
| | | Running, |
| | | Error, |
| | | Abort, |
| | | Completed |
| | | }; |
| | | |
| | | /** |
| | | * æ¬è¿è®°å½ç»æä½ |
| | | */ |
| | | struct TransferData { |
| | | int nRecordId; // ä¸»é® |
| | | std::string strClassID; // æ¬è¿ä»»å¡ ClassID |
| | | std::string strStatus; // ä»»å¡ç¶æï¼å符串ï¼ReadyãRunning...ï¼ |
| | | std::string strCreateTime; // å建æ¶é´ |
| | | std::string strPickTime; // åçæ¶é´ |
| | | std::string strPlaceTime; // æ¾çæ¶é´ |
| | | std::string strEndTime; // ç»ææ¶é´ |
| | | std::string strDescription; // ä»»å¡è¯´æ |
| | | }; |
| | | |
| | | using TransferDataMap = std::unordered_map<int, TransferData>; |
| | | |
| | | class TransferManager { |
| | | public: |
| | | /** |
| | | * è·å TransferManager åä¾ |
| | | * @return TransferManager å®ä¾ |
| | | */ |
| | | static TransferManager& getInstance(); |
| | | |
| | | /** |
| | | * åå§åæ¬è¿è®°å½è¡¨ |
| | | * @return æåè¿å trueï¼å¤±è´¥è¿å false |
| | | */ |
| | | bool initTransferTable(); |
| | | |
| | | /** |
| | | * æå
¥æµè¯æ¬è¿è®°å½ |
| | | */ |
| | | void insertTestTransferRecord(); |
| | | |
| | | /** |
| | | * ç»æ¢æ°æ®åºè¿æ¥ |
| | | */ |
| | | void termTransferTable(); |
| | | |
| | | /** |
| | | * å 餿¬è¿è®°å½è¡¨ |
| | | * @return æåè¿å trueï¼å¤±è´¥è¿å false |
| | | */ |
| | | bool destroyTransferTable(); |
| | | |
| | | /** |
| | | * æå
¥æ¬è¿è®°å½ |
| | | * @param data æ¬è¿è®°å½ç»æä½ |
| | | * @param outRecordId æå
¥åçè®°å½ä¸»é® ID |
| | | * @return æåè¿å trueï¼å¤±è´¥è¿å false |
| | | */ |
| | | bool addTransferRecord(const TransferData& data, int& outRecordId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æææ¬è¿è®°å½ |
| | | * @return ææè®°å½æ°æ® |
| | | */ |
| | | std::vector<TransferData> getAllTransfers(); |
| | | |
| | | /** |
| | | * æ ¹æ®è®°å½ ID æ¥è¯¢æ¬è¿è®°å½ |
| | | * @param id è®°å½ä¸»é® ID |
| | | * @return æ¬è¿è®°å½æ°æ® |
| | | */ |
| | | TransferData getTransferById(int id); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¶é´èå´æ¥è¯¢æ¬è¿è®°å½ |
| | | * @param startTime èµ·å§æ¶é´ |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return æ¬è¿è®°å½æ°æ® |
| | | */ |
| | | std::vector<TransferData> getTransfersByTimeRange(const std::string& startTime, const std::string& endTime); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¶ææ¥è¯¢æ¬è¿è®°å½ |
| | | * @param status ä»»å¡ç¶æ |
| | | * @return æ¬è¿è®°å½æ°æ® |
| | | */ |
| | | std::vector<TransferData> TransferManager::getTransfersByStatus(const std::string& status); |
| | | |
| | | /** |
| | | * å页è·åæ¬è¿è®°å½ |
| | | * @param startPosition èµ·å§è®°å½ä½ç½® |
| | | * @param count è·åçè®°å½æ°é |
| | | * @return æ¬è¿è®°å½æ°æ® |
| | | */ |
| | | //std::vector<TransferData> getTransfers(int startPosition, int count); |
| | | |
| | | /** |
| | | * è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° |
| | | */ |
| | | int getTotalTransferCount(); |
| | | |
| | | /** |
| | | * å页è·åç¬¦åæ¡ä»¶çæ¬è¿è®°å½ |
| | | * @param filter è¿æ»¤æ¡ä»¶ |
| | | * @param pageNum 页ç |
| | | * @param pageSize æ¯é¡µè®°å½æ° |
| | | */ |
| | | std::vector<TransferData> getTransfers(const TransferData& filter, int pageNum, int pageSize); |
| | | |
| | | /** |
| | | * è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° |
| | | * @param filter è¿æ»¤æ¡ä»¶ |
| | | * @return ç¬¦åæ¡ä»¶çè®°å½æ»æ° |
| | | */ |
| | | int getTotalTransferCount(const TransferData& filter);; |
| | | |
| | | /** |
| | | * æ¸
çæ©äºæä¸æ¶é´çæ¬è¿è®°å½ |
| | | * @param daysToKeep ä¿ççå¤©æ° |
| | | */ |
| | | void cleanOldTransfers(int daysToKeep = 30); |
| | | |
| | | /** |
| | | * è¯»åæ¬è¿è®°å½ CSV æä»¶ |
| | | * @param filename æä»¶å |
| | | * @return æåè¿å trueï¼å¤±è´¥è¿å false |
| | | */ |
| | | bool readTransferFile(const std::string& filename); |
| | | |
| | | /** |
| | | * ä¿åæ¬è¿è®°å½å° CSV æä»¶ |
| | | * @param filename æä»¶å |
| | | * @return æåè¿å trueï¼å¤±è´¥è¿å false |
| | | */ |
| | | bool saveTransferFile(const std::string& filename); |
| | | |
| | | private: |
| | | TransferManager(); |
| | | ~TransferManager(); |
| | | |
| | | // ç¦æ¢æ·è´åèµå¼ |
| | | TransferManager(const TransferManager&) = delete; |
| | | TransferManager& operator=(const TransferManager&) = delete; |
| | | |
| | | // å
è彿° |
| | | inline int statusToInt(TransferStatus status); |
| | | inline TransferStatus intToStatus(int value); |
| | | inline std::string statusToString(TransferStatus status); |
| | | inline TransferStatus stringToStatus(const std::string& str); |
| | | inline std::string ansiToUtf8(const std::string& ansiStr); |
| | | inline std::string utf8ToAnsi(const std::string& utf8Str); |
| | | |
| | | BL::Database* m_pDB; |
| | | static std::mutex m_mutex; |
| | | }; |
| | | |
| | | #endif // TRANSFER_MANAGER_H |
| | |
| | | #include <afxcontrolbars.h> // åè½åºåæ§ä»¶æ¡ç MFC æ¯æ |
| | | |
| | | |
| | | // æ§ä»¶æ ·å¼ |
| | | static UINT g_nGridFixCellColor = RGB(144, 200, 246); |
| | | static UINT g_nGridFixFontColor = RGB(0, 0, 0); |
| | | static UINT g_nGridCellColor = RGB(255, 255, 224); |
| | | static UINT g_nGridCellColor_NonSelect = RGB(150, 150, 150); |
| | | static UINT g_nGridCellReadyColor = RGB(255, 255, 0); |
| | | static UINT g_nGridCellOnColor = RGB(255, 69, 0); |
| | | static UINT g_nGridCellOffColor = RGB(128, 191, 255); |
| | | static UINT g_nPropertyGridFixCellColor = RGB(150, 150, 150); |
| | | static UINT g_nPropertyGridFixFontColor = RGB(0, 0, 0); |
| | | |
| | | // GDI+ |
| | | #include <gdiplus.h> |
| | | using namespace Gdiplus; |