全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:925
推到 Plurk!
推到 Facebook!

請教如何實現 TListView 的 OnCancelEdit

尚未結案
yl_huang
一般會員


發表:6
回覆:6
積分:2
註冊:2004-11-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-24 01:43:47 IP:211.21.xxx.xxx 未訂閱
小弟企圖以下列程式碼, 實現類似 Windows 檔案管理員處理空檔名輸入的機制, 可惜失敗! 參考過 "TListView元件裡OnEdited相關問題", 也試了很多其它辦法, 還是不成功. 還請先進們不吝指點, 謝謝!!    //--------------------------------------------------------------------------- //新增一 item 並進入 Edit mode 以提示使用者輸入字串  ← 成功 //--------------------------------------------------------------------------- void __fastcall TfmMain::miAddPlaylistClick(TObject *Sender) {    TListItem* item = lvPlaylist->Items->Add();    item->EditCaption(); }    //--------------------------------------------------------------------------- // 當輸入空字串時, 刪除此新增 item  ← 失敗, 程式碼未被執行!! //--------------------------------------------------------------------------- void __fastcall TfmMain::lvPlaylistEdited(TObject *Sender, TListItem *Item, AnsiString &S) { if(S.IsEmpty()){ int idx=lvPlaylist->Items->IndexOf(Item); lvPlaylist->Items->Delete(idx); } }
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-24 09:41:15 IP:61.63.xxx.xxx 未訂閱
引言: 小弟企圖以下列程式碼, 實現類似 Windows 檔案管理員處理空檔名輸入的機制, 可惜失敗! 參考過 "TListView元件裡OnEdited相關問題", 也試了很多其它辦法, 還是不成功. 還請先進們不吝指點, 謝謝!! //--------------------------------------------------------------------------- //新增一 item 並進入 Edit mode 以提示使用者輸入字串 ← 成功 //--------------------------------------------------------------------------- void __fastcall TfmMain::miAddPlaylistClick(TObject *Sender) { TListItem* item = lvPlaylist->Items->Add(); item->EditCaption(); } //--------------------------------------------------------------------------- // 當輸入空字串時, 刪除此新增 item ← 失敗, 程式碼未被執行!! //--------------------------------------------------------------------------- void __fastcall TfmMain::lvPlaylistEdited(TObject *Sender, TListItem *Item, AnsiString &S) { if(S.IsEmpty()){ int idx=lvPlaylist->Items->IndexOf(Item); lvPlaylist->Items->Delete(idx); } }
yl_huang你好< >: 嗯,問題原因如同你查的那篇,就不再解釋了< >! 作法一樣,如下:

//一個button click事件,用以新增一個item
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TListItem* itm=ListView1->Items->Add();     itm->EditCaption();
}
//---------------------------------------------------------------------------    //ListView的OnEdited事件,用以判斷是不是有輸入字串
void __fastcall TForm1::ListView1Edited(TObject *Sender, TListItem *Item,
      AnsiString &S)
{
 if (S=="")
     PostMessage(ListView1->Handle,LVM_DELETEITEM,Item->Index,0);
}
要注意的是當使用者新增一個item後,他並沒有進行任何key in字串的動作,即結束,那麼這樣並不會驅動OnEdited事件,所以即使item的caption=="",但這個Item也不會被delete,因為OnEdited事件根本沒被驅動! 這是唯一特殊的地方,再你查的那篇也有討論到
yl_huang
一般會員


發表:6
回覆:6
積分:2
註冊:2004-11-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-24 13:24:19 IP:211.21.xxx.xxx 未訂閱
m8815010您好, 您說的原因小弟在" > 請教該如何正確攔截 class="code"> __fastcall TfmMain::TfmMain(TComponent* Owner): TForm(Owner) { OldWindowProc=WindowProc; WindowProc=NewWindowProc; } //--------------------------------------------------------------------------- void __fastcall TfmMain::NewWindowProc(TMessage &Message) { if(Message.Msg==WM_NOTIFY){ NMHDR* pnmh=(NMHDR*)(Message.LParam); if(pnmh->code==LVN_ENDLABELEDIT) ShowMessage("Time to Delete Invalid Items"); } OldWindowProc(Message); }
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-24 14:13:03 IP:61.63.xxx.xxx 未訂閱
引言: m8815010您好, 您說的原因小弟在" > 請教該如何正確攔截 class="code"> __fastcall TfmMain::TfmMain(TComponent* Owner): TForm(Owner) { OldWindowProc=WindowProc; WindowProc=NewWindowProc; } //--------------------------------------------------------------------------- void __fastcall TfmMain::NewWindowProc(TMessage &Message) { if(Message.Msg==WM_NOTIFY){ NMHDR* pnmh=(NMHDR*)(Message.LParam); if(pnmh->code==LVN_ENDLABELEDIT) ShowMessage("Time to Delete Invalid Items"); } OldWindowProc(Message); }
yl_huang你好: 不好意思哦,想請問你一下,既然已經用用 class="code"> __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OldFormWndProc=this->WindowProc; this->WindowProc=FormWndProc; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormWndProc(TMessage& Message) { OldFormWndProc(Message); if (Message.Msg==WM_NOTIFY) { LPNMHDR lpnmhdr=(LPNMHDR)Message.LParam; if (lpnmhdr->code==LVN_ENDLABELEDIT) { LV_DISPINFO* pdi; pdi=(LV_DISPINFO*)Message.LParam; this->Caption=pdi->item.pszText; } } } 注意: 1.是要去ListView元件的parent去攔這訊息,不是去listview本身攔,本例parent是Form1 2.本範把最終結束edit後其item的caption show在form1的caption上 All,!
yl_huang
一般會員


發表:6
回覆:6
積分:2
註冊:2004-11-24

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-24 15:41:25 IP:211.21.xxx.xxx 未訂閱
m8815010您好,    1. 小弟只是〈了解〉您於"TListView元件裡OnEdited相關問題"的說明,     小弟的問題仍無法於 OnEdited 中解決.    2. 小弟的問題在於新增 item 後進入 Edit mode,     【若使用者直接按 ENTER 或 ESC (空字串), 根本攔截不到 OnEdited, 也就無法 delete 此 item 】. 3. 小弟在 BCB6 中 try 了您攔 LVN_ENDLABELEDIT 的 code , 還是失敗.
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-24 16:55:09 IP:61.63.xxx.xxx 未訂閱
    yl_huang你好< >: 呵呵,好像兩人在雞同鴨講< >,不過我現在大概體會了! 你說的: 【若使用者直接按 ENTER 或 ESC (空字串), 根本攔截不到 OnEdited, 也就無法 delete 此 item 】. 這正是TListView的OnEdited事件沒辦法達到的地方,但應該是說使用者直接按enter等等等這些操作手法是無法觸發OnEdited事件的! OnEdited事件觸發只有在使用者有key in 一些字串時,而我們先前的範例在這事件內判斷Item的Caption是否為NULL,只適用使用者先key了一些字串後,再把字串全部刪除(這時caption又是NULL了),當然不適合你說的那種操作手法< >! 不過這我在注意事項有特別提及的< >! 嗯,結論是要一起concern你說的那種操作方式的話,攔訊息是正確的作法,我改了一下code,改成可直接把item刪除,並貼上完整的source,請測試! < class="code"> .h中 ~~ private: // User declarations TWndMethod OldFormWndProc; //add this line void __fastcall FormWndProc(TMessage& Message); //add this line public: // User declarations __fastcall TForm1(TComponent* Owner); //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; }; .ccp中 ~~ __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OldFormWndProc=this->WindowProc; //procedure assign this->WindowProc=FormWndProc; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) //新增一個item,並開啟edit mode { TListItem* itm=ListView1->Items->Add(); itm->EditCaption(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormWndProc(TMessage& Message) { OldFormWndProc(Message); if (Message.Msg==WM_NOTIFY) { LPNMHDR lpnmhdr=(LPNMHDR)Message.LParam; if (lpnmhdr->code==LVN_ENDLABELEDIT) { LV_DISPINFO* pdi; pdi=(LV_DISPINFO*)Message.LParam; if (AnsiString(pdi->item.pszText)=="") //判斷是空caption則刪除 PostMessage(ListView1->Handle,LVM_DELETEITEM,pdi->item.iItem,0); } } } 嗯,目前測試還成功!
yl_huang
一般會員


發表:6
回覆:6
積分:2
註冊:2004-11-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-11-25 10:57:17 IP:211.21.xxx.xxx 未訂閱
搞定了, 您的方法的確可以正確攔截 LVN_ENDLABELEDIT, 小弟把 ListView 擺在一個 PageContrl 下的某個 TabSheet, 只要把 code hook 到 TabSheet 的 WinProc 即可達到想要的效果. 真是耍寶哩~~~
系統時間:2024-03-29 13:39:32
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!