You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You can end a combo box edit by clicking away to loose focus on the
control. This ends up setting a new value for the cell, even if the user
never selected or typed in anything.
What steps will reproduce the problem?
1. Put a break point in CGridListCtrlEx::OnEndLabelEdit
2. Select a cell in the State column so that the combo box shows
3. Click somewhere else in the control so the edit looses focus
4. Notice the breakpoint in OnEndLabelEdit gets hit, even though you didn't
type in anything
What is the expected output? What do you see instead?
The problem is that CGridEditorComboBoxEdit sends the WM_KEYUP message with
VK_RETURN, even if the value was not modified. The solution is to send
VK_ESCAPE if the value was not modified.
I've copied the changes to the code below. I've just added a new member to
CGridEditorComboBoxEdit and use this to track if the value has actually
been changed.
*******************CGridColumnTraitCombo.h**********************:
class CGridEditorComboBox : public CComboBox
{
public:
CGridEditorComboBox(int nRow, int nCol, int nMaxWidth);
virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
UINT nID);
virtual void EndEdit(bool bSuccess);
protected:
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnNcDestroy();
afx_msg void OnDestroy();
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
afx_msg void OnDropDown();
afx_msg void OnCloseUp();
afx_msg void OnEditChange();
afx_msg void OnChangeSelection();
DECLARE_MESSAGE_MAP();
CGridEditorComboBoxEdit m_Edit; //!< Subclassed edit control inside the
CComboBox
bool m_Completed; //!< Ensure the editor only reacts to a single close event
int m_Row; //!< The index of the row being edited
int m_Col; //!< The index of the column being edited
int m_MaxWidth; //!< Max width (in pixels) of the CComboBox when doing
dropdown
bool m_Modified; //!< If the value has been modified (should process
EndEdit(true))
};
*******************CGridColumnTraitCombo.cpp**********************:
BEGIN_MESSAGE_MAP(CGridEditorComboBox, CComboBox)
//{{AFX_MSG_MAP(CGridEditorComboBox)
ON_WM_KILLFOCUS()
ON_WM_GETDLGCODE()
ON_WM_DESTROY()
ON_WM_KEYUP()
ON_WM_NCDESTROY()
ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseUp)
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropDown)
ON_CONTROL_REFLECT(CBN_EDITCHANGE, OnEditChange)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnChangeSelection)
ON_CONTROL_REFLECT(CBN_SELENDOK, OnChangeSelection)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//------------------------------------------------------------------------
//! CGridEditorComboBox - Constructor
//------------------------------------------------------------------------
CGridEditorComboBox::CGridEditorComboBox(int nRow, int nCol, int nMaxWidth)
:m_Row(nRow)
,m_Col(nCol)
,m_Completed(false)
,m_MaxWidth(nMaxWidth)
,m_Modified(false)
{}
//------------------------------------------------------------------------
//! The cell value editor was closed and the entered should be saved.
//!
//! @param bSuccess Should the entered cell value be saved
//------------------------------------------------------------------------
void CGridEditorComboBox::EndEdit(bool bSuccess)
{
// Avoid two messages if key-press is followed by kill-focus
if (m_Completed)
return;
m_Completed = true;
// Send Notification to parent of ListView ctrl
CString str;
GetWindowText(str);
LV_DISPINFO dispinfo = {0};
dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
dispinfo.hdr.idFrom = GetDlgCtrlID();
dispinfo.hdr.code = LVN_ENDLABELEDIT;
dispinfo.item.iItem = m_Row;
dispinfo.item.iSubItem = m_Col;
if (bSuccess && m_Modified)
{
dispinfo.item.mask = LVIF_TEXT | LVIF_PARAM;
dispinfo.item.pszText = str.GetBuffer(0);
dispinfo.item.cchTextMax = str.GetLength();
dispinfo.item.lParam = GetItemData(GetCurSel());
}
ShowWindow(SW_HIDE);
GetParent()->GetParent()->SendMessage( WM_NOTIFY,
GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo );
PostMessage(WM_CLOSE);
}
//------------------------------------------------------------------------
//! CBN_EDITCHANGE message handler called when the edit control for the
CComboBox control
//! has been modified.
//------------------------------------------------------------------------
void CGridEditorComboBox::OnEditChange()
{
m_Modified = true;
}
//------------------------------------------------------------------------
//! CBN_SELCHANGE, CBN_SELENDOK message handler called when the selection
in the CComboBox control
//! has been modified.
//------------------------------------------------------------------------
void CGridEditorComboBox::OnChangeSelection()
{
m_Modified = true;
}
Original issue reported on code.google.com by garretf...@gmail.com on 30 Sep 2009 at 1:22
The text was updated successfully, but these errors were encountered:
Oops. I accidentally described my initial solution which had a problem. The
solution
is to detect in CGridEditorComboBox whether the value has been modified, and
only do
the set the text in the LV_DISPINFO if the value was modified.
I added a member to CGridEditorComboBox, not to CGridEditorComboBoxEdit.
Original comment by garretf...@gmail.com on 30 Sep 2009 at 1:27
Just tested the LVS_EDITLABELS in a vanilla CListCtrl, and yes you are correct
that
if no changes are made, then a LVN_ENDLABELEDIT notification is sent with NULL
string.
I will update the different editable column-traits, so the behavior is the same.
Original comment by sweaty1 on 30 Sep 2009 at 7:54
I have now implemented check for modifications in the CEdit, CComboBox and
CDateTimeCtrl editor. When the editor closes and no modifications was detected,
then
the parent will see it as the editing was cancelled.
Original comment by sweaty1 on 30 Sep 2009 at 9:37
Original issue reported on code.google.com by
garretf...@gmail.com
on 30 Sep 2009 at 1:22The text was updated successfully, but these errors were encountered: