與在編輯模式下 TListView 的背景關系選單中的阻止操作有關,我在讀取事件中的值時遇到plvdi->item.pszText問題CNNotify()。nil如果取消編輯,該值應該是。我嘗試了一些轉換,但沒有運氣。我一定做錯了什么。請參閱下面的代碼。
一切正常,除了比較pszText價值。
.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "TCustomListView.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TCustomListView1 *)
{
new TCustomListView1(NULL);
}
//---------------------------------------------------------------------------
__fastcall TCustomListView1::TCustomListView1(TComponent* Owner)
: TListView(Owner)
{
cancel = false;
}
//---------------------------------------------------------------------------
void __fastcall TCustomListView1::WMGetDlgCode(TMessage &msg)
{
TCustomListView::Dispatch(&msg);
msg.Result |= WM_CHAR;
//To Do
}
//---------------------------------------------------------------------------
void __fastcall TCustomListView1::CNNotify(Winapi::Messages::TWMNotify &Message)
{
TListView::Dispatch(&Message);
Message.Result |= LVN_ENDLABELEDIT;
NMLVDISPINFO* plvdi = (NMLVDISPINFO*)Message.NMHdr;
if(plvdi->item.pszText == NULL ) ----->> ??? what am i doing wrong here
{
if(FOnEditCancel && IsEditing())
{
cancel = true;
FOnEditCancel(this, this->Selected, cancel);
cancel = false;
}
}
}
//---------------------------------------------------------------------------
namespace Tcustomlistview
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TCustomListView1)};
RegisterComponents(L"Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
。H
//---------------------------------------------------------------------------
#ifndef TCustomListViewH
#define TCustomListViewH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Controls.hpp>
//---------------------------------------------------------------------------
typedef void __fastcall (__closure *TOnEditCancel)(TObject* Sender, TListItem* item, bool cancelled);
class PACKAGE TCustomListView1 : public TListView
{
private:
TOnEditCancel FOnEditCancel;
bool cancel;
MESSAGE void __fastcall WMGetDlgCode(TMessage &msg);
MESSAGE void __fastcall CNNotify(Winapi::Messages::TWMNotify &Message);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_GETDLGCODE, TMessage, WMGetDlgCode)
VCL_MESSAGE_HANDLER(WM_NOTIFY, TWMNotify, CNNotify);
END_MESSAGE_MAP(inherited);
protected:
public:
__fastcall TCustomListView1(TComponent* Owner);
__published:
__property TOnEditCancel OnEditCancel = {read = FOnEditCancel, write = FOnEditCancel};
};
//---------------------------------------------------------------------------
#endif
uj5u.com熱心網友回復:
你的代碼有很多問題。
TCustomListView1對您的組件來說不是一個好名字。使用更有意義的東西。您的組件根本不需要該
cancel成員,因此請擺脫它。您可以改為硬編碼事件的cancelled引數。OnEditCancel但是,該事件確實不應該有一個cancelled引數開始。在這種情況下,洗掉該引數后,您可以使用與其余引數匹配的現有 ListView 事件型別之一,例如TLVNotifyEvent.WM_CHAR是視窗訊息識別符號,它不是可以添加到WM_GETDLGCODE訊息回傳值的有效標志。您打算改用該DLGC_WANTCHARS標志,這將使您的控制元件能夠接收WM_CHAR訊息。LVN_ENDLABELEDIT是視窗訊息識別符號,它不是可以添加到CN_NOTIFY訊息回傳值的有效標志。您需要檢查該Message.NMHdr->code欄位是否匹配LVN_ENDLABELEDIT,然后Message.NMHdr相應地處理該欄位。您正在處理
MESSAGE_MAP. 您正在捕獲WM_NOTIFY從 ListView 的標頭控制元件發送到 ListView 的訊息。您需要捕獲CN_NOTIFY訊息,這些WM_NOTIFY訊息是 ListView 發送到其父視窗的訊息,然后以CN_NOTIFY. VCL 進行這種反射以允許組件自包含并處理它們自己的通知。
話雖如此,請嘗試更像這樣的東西:
TMyListViewEx.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MyListViewEx.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TMyListViewEx *)
{
new TMyListViewEx(NULL);
}
//---------------------------------------------------------------------------
__fastcall TMyListViewEx::TMyListViewEx(TComponent* Owner)
: TListView(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMyListViewEx::WMGetDlgCode(TMessage &msg)
{
TListView::Dispatch(&msg);
msg.Result |= DLGC_WANTCHARS; // TODO
}
//---------------------------------------------------------------------------
void __fastcall TMyListViewEx::CNNotify(Winapi::Messages::TWMNotify &Message)
{
TListView::Dispatch(&Message);
if (Message.NMHdr->code == LVN_ENDLABELEDITA ||
Message.NMHdr->code == LVN_ENDLABELEDITW)
{
NMLVDISPINFO *plvdi = reinterpret_cast<NMLVDISPINFO*>(Message.NMHdr);
if ((plvdi->item.pszText == NULL) &&
(plvdi->item.iItem != -1) &&
(FOnCancelEdit != NULL))
{
// ideally, you should be using TCustomListView::GetItem(LVITEM)
// to determine the TListItem affected, but that method is private
// and not accessible to descendants, which is all the more reason
// why Embarcadero needs to fix this in the native TListView instead...
TListItem *item;
if (plvdi->item.mask & LVIF_PARAM)
item = reinterpret_cast<TListItem*>(plvdi->item.lParam);
else // TODO: handle OwnerData=true ...
item = this->Items->Item[plvdi->item.iItem];
FOnCancelEdit(this, item);
}
}
}
//---------------------------------------------------------------------------
namespace Tmylistviewex
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TMyListViewEx)};
RegisterComponents(L"Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
TMyListViewEx.h
//---------------------------------------------------------------------------
#ifndef TMyListViewExH
#define TMyListViewExH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Controls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TMyListViewEx : public TListView
{
private:
TLVNotifyEvent FOnCancelEdit;
MESSAGE void __fastcall WMGetDlgCode(TMessage &msg);
MESSAGE void __fastcall CNNotify(Winapi::Messages::TWMNotify &Message);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_GETDLGCODE, TMessage, WMGetDlgCode)
VCL_MESSAGE_HANDLER(CN_NOTIFY, TWMNotify, CNNotify)
END_MESSAGE_MAP(TListView);
protected:
public:
__fastcall TMyListViewEx(TComponent* Owner);
__published:
__property TLVNotifyEvent OnCancelEdit = {read = FOnCancelEdit, write = FOnCancelEdit};
};
//---------------------------------------------------------------------------
#endif
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/508534.html
