I am trying to subclass the WindowProc
of TListView
to detect ESC key press after editing TListView
caption (if user cancels editing). ListViewWndProc is getting called clearly, but the code parameter which is supposed to detect that never gets LVN_ENDLABELEDIT value. Why the commented part never gets called? I cannot see the error, it should be happening.
TWndMethod OldWndProc;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
OldWndProc = ListView1->WindowProc;
ListView1->WindowProc = ListViewWndProc;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListViewWndProc(TMessage &Message)
{
if (Message.Msg == CN_NOTIFY)
{
LPNMHDR pnmh = reinterpret_cast<LPNMHDR>(Message.LParam);
if (pnmh->code == LVN_ENDLABELEDIT) // UPDATE: if LVN_ENDLABELEDIT is replaced with 4294967120 it works
{
// !!! THE FOLLOWING NEVER HAPPENS !!!
// UPDATE: Looks like LVN_ENDLABELEDIT is incorrectly defined in C++ Builder 2010
// if LVN_ENDLABELEDIT is replaced with 4294967120 the code works
LV_DISPINFO *pdi = reinterpret_cast<LV_DISPINFO*>(Message.LParam);
if (pdi->item.pszText == NULL)
{
Edit1->Text = "Cancelled";
return;
}
}
}
OldWndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListView1Editing(TObject *Sender, TListItem *Item, bool &AllowEdit)
{
Edit1->Text = "Editing";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListView1Edited(TObject *Sender, TListItem *Item, UnicodeString &S)
{
Edit1->Text = "Done";
}
In C++, the value of LVN_ENDLABELEDEDIT
depends on the project's TCHAR_Mapping, which can be changed in the Project Settings via the "_TCHAR maps to"
configuration item. By default, _TCHAR
is set to wchar_t
in C++Builder 2009 and later, unless you migrate a project from an earlier version, in which case it is char
by default instead.
LVN_ENDLABELEDIT
is a macro that maps to LVN_ENDLABELEDITA
(4294967190) when _TCHAR
is char
, and to LVN_ENDLABELEDITW
(4294967120) when _TCHAR
is wchar_t
.
Checking for both constants LVN_ENDLABELEDEDITA
and LVN_ENDLABELEDEDITW
, like it is done in the Delphi source code, should be OK.
void __fastcall TForm1::ListViewWndProc(TMessage &Message)
{
if (Message.Msg == CN_NOTIFY)
{
LPNMHDR pnmh = reinterpret_cast<LPNMHDR>(Message.LParam);
if ((pnmh->code == LVN_ENDLABELEDITA) || (pnmh->code == LVN_ENDLABELEDITW))
{
LV_DISPINFO *pdi = reinterpret_cast<LV_DISPINFO*>(Message.LParam);
if (pdi->item.pszText == NULL)
{
Edit1->Text = "Cancelled";
return;
}
}
}
OldWndProc(Message);
}