From 863f21995955fb3e9aa471430218967d4e642c27 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期四, 29 五月 2025 16:11:24 +0800
Subject: [PATCH] Merge branch 'liuyang'
---
SourceCode/Bond/Servo/GridControl/NewCellTypes/GridCellCombo.cpp | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 510 insertions(+), 0 deletions(-)
diff --git a/SourceCode/Bond/Servo/GridControl/NewCellTypes/GridCellCombo.cpp b/SourceCode/Bond/Servo/GridControl/NewCellTypes/GridCellCombo.cpp
new file mode 100644
index 0000000..711b933
--- /dev/null
+++ b/SourceCode/Bond/Servo/GridControl/NewCellTypes/GridCellCombo.cpp
@@ -0,0 +1,510 @@
+// 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]);
+}
\ No newline at end of file
--
Gitblit v1.9.3