From 508b6523350b4b1c4b2518b6c8c69e5d161f26c5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 30 May 2008 00:26:07 +0000 Subject: [PATCH] ensure that GetEditControl() returns something even if label editing was started by the user and not the program (closes #1325) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53831 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/listctrl.h | 3 +++ samples/listctrl/listtest.cpp | 10 +++++++ src/msw/listctrl.cpp | 63 +++++++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index 635a0af..8be82a4 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -446,6 +446,9 @@ private: // UpdateStyle()), only should be called if InReportView() void MSWSetExListStyles(); + // initialize the (already created) m_textCtrl with the associated HWND + void InitEditControl(WXHWND hWnd); + // destroy m_textCtrl if it's currently valid and reset it to NULL void DeleteEditControl(); diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index 23ee183..b969e64 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -830,6 +830,16 @@ void MyListCtrl::OnBeginRDrag(wxListEvent& event) void MyListCtrl::OnBeginLabelEdit(wxListEvent& event) { wxLogMessage( wxT("OnBeginLabelEdit: %s"), event.m_item.m_text.c_str()); + + wxTextCtrl * const text = GetEditControl(); + if ( !text ) + { + wxLogMessage("BUG: started to edit but no edit control"); + } + else + { + wxLogMessage("Edit control value: \"%s\"", text->GetValue()); + } } void MyListCtrl::OnEndLabelEdit(wxListEvent& event) diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 16cf30a..239b9b2 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -766,6 +766,25 @@ int wxListCtrl::GetCountPerPage() const // Gets the edit control for editing labels. wxTextCtrl* wxListCtrl::GetEditControl() const { + // first check corresponds to the case when the label editing was started + // by user and hence m_textCtrl wasn't created by EditLabel() at all, while + // the second case corresponds to us being called from inside EditLabel() + // (e.g. from a user wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT handler): in this + // case EditLabel() did create the control but it didn't have an HWND to + // initialize it with yet + if ( !m_textCtrl || !m_textCtrl->GetHWND() ) + { + HWND hwndEdit = ListView_GetEditControl(GetHwnd()); + if ( hwndEdit ) + { + wxListCtrl * const self = wx_const_cast(wxListCtrl *, this); + + if ( !m_textCtrl ) + self->m_textCtrl = new wxTextCtrl; + self->InitEditControl((WXHWND)hwndEdit); + } + } + return m_textCtrl; } @@ -1455,33 +1474,49 @@ void wxListCtrl::ClearAll() DeleteAllColumns(); } +void wxListCtrl::InitEditControl(WXHWND hWnd) +{ + m_textCtrl->SetHWND(hWnd); + m_textCtrl->SubclassWin(hWnd); + m_textCtrl->SetParent(this); + + // we must disallow TABbing away from the control while the edit contol is + // shown because this leaves it in some strange state (just try removing + // this line and then pressing TAB while editing an item in listctrl + // inside a panel) + m_textCtrl->SetWindowStyle(m_textCtrl->GetWindowStyle() | wxTE_PROCESS_TAB); +} + wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass) { - wxASSERT( (textControlClass->IsKindOf(CLASSINFO(wxTextCtrl))) ); + wxCHECK_MSG( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)), NULL, + "control used for label editing must be a wxTextCtrl" ); // ListView_EditLabel requires that the list has focus. SetFocus(); + // create m_textCtrl here before calling ListView_EditLabel() because it + // generates wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT event from inside it and + // the user handler for it can call GetEditControl() resulting in an on + // demand creation of a stock wxTextCtrl instead of the control of a + // (possibly) custom wxClassInfo + DeleteEditControl(); + m_textCtrl = (wxTextCtrl *)textControlClass->CreateObject(); + WXHWND hWnd = (WXHWND) ListView_EditLabel(GetHwnd(), item); if ( !hWnd ) { // failed to start editing + delete m_textCtrl; + m_textCtrl = NULL; + return NULL; } - // [re]create the text control wrapping the HWND we got - DeleteEditControl(); - - m_textCtrl = (wxTextCtrl *)textControlClass->CreateObject(); - m_textCtrl->SetHWND(hWnd); - m_textCtrl->SubclassWin(hWnd); - m_textCtrl->SetParent(this); - - // we must disallow TABbing away from the control while the edit contol is - // shown because this leaves it in some strange state (just try removing - // this line and then pressing TAB while editing an item in listctrl - // inside a panel) - m_textCtrl->SetWindowStyle(m_textCtrl->GetWindowStyle() | wxTE_PROCESS_TAB); + // if GetEditControl() hasn't been called, we need to initialize the edit + // control ourselves + if ( !m_textCtrl->GetHWND() ) + InitEditControl(hWnd); return m_textCtrl; } -- 2.7.4