我正在使用 C Builder XE6 撰寫一個 VCL 應用程式,其中包含一個TListView帶有關聯TPopupMenu背景關系選單的。
TListView有ViewStyle=vsReport和ReadOnly= false。_ 關聯的背景關系選單包含一個帶有ShortCut=的“洗掉”選單項Del。
“洗掉”選單項具有以下OnClick事件處理程式:
void __fastcall TForm1::Delete1Click (TObject *Sender)
{
ListView1->DeleteSelected();
}
“洗掉”選單項OnPopup在背景關系選單的事件處理程式中啟用/禁用:
void __fastcall TForm1::PopupMenu1Popup (TObject *Sender)
{
Delete1->Enabled = (ListView1->SelCount > 0);
}
當我在串列視圖中選擇一個專案并按下Del鍵盤上的鍵時,將Delete1Click()呼叫事件處理程式并洗掉該專案,正如預期的那樣。
但是,如果串列視圖專案處于編輯模式并且我按下了Del鍵,則Delete1Click()事件處理程式也會被呼叫,從而洗掉該專案。按鍵不會發送到串列視圖中的編輯框。
我試圖通過修改OnPopup背景關系選單的事件處理程式來解決這個問題,如下所示:
void __fastcall TForm1::PopupMenu1Popup (TObject *Sender)
{
Delete1->Enabled = (ListView1->SelCount > 0 && !ListView1->IsEditing());
}
這可以防止洗掉串列視圖項,但按鍵仍然沒有發送到串列視圖中的編輯框。
當串列視圖項處于編輯模式時,Del按鍵應該由串列視圖的編輯框處理,而不是呼叫Delete1Click()事件處理程式。
我如何實作這一目標?
我不想將“洗掉”選單項的快捷方式更改為Ctrl 之類的東西Del。
uj5u.com熱心網友回復:
要解決您的問題,您需要在編輯串列項時清除選單項的快捷方式,OnEditing方法是OnEdited向TListView.
void __fastcall TForm3::ListView1Editing(TObject *Sender, TListItem *Item, bool &AllowEdit)
{
if(Delete1->ShortCut != NULL) //added
{
shortCut = Delete1->ShortCut; //added
Delete1->ShortCut = NULL;
}
}
在編輯時按下鍵盤Del鍵將正常作業,完成編輯后,您可以像這樣恢復快捷方式:
void __fastcall TForm3::ListView1Edited(TObject *Sender, TListItem *Item, UnicodeString &S)
{
// omit -> Delete1->ShortCut = TextToShortCut("Del") ;
// replace with
Delete1->ShortCut = shortCut;
}
添加這兩個事件處理程式在 XE7 中可以正常作業,因此您對 XE6 應該沒有問題。
您還可以在使用時將選單項的快捷方式存盤在 a 中TShortCut,然后使用您遇到問題的快捷方式從該快捷方式中恢復每個選單項。
編輯:作為 ESC 問題的解決方法,如果從 Delete1 中洗掉了快捷方式,則可以使用添加 OnContextPopup 來恢復快捷方式
更新答案以反映變化
將 TShortCut 快捷方式變數添加到您的表單中。
void __fastcall TForm3::ListView1ContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled)
{
if(shortCut != 0)
{
Delete1->ShortCut = shortCut;
shortCut = NULL;
}
}
uj5u.com熱心網友回復:
以下代碼在兩種情況下都處理 Del 按鍵,而不洗掉選單項快捷方式。當串列視圖不處于編輯模式時,DeleteSelected()呼叫洗掉串列視圖中的選定專案。當串列視圖處于編輯模式時(即正在編輯一個專案),代碼模擬Del串列視圖的編輯框中的按鍵,使用SendMessage().
void __fastcall TForm1::Delete1Click (TObject *Sender)
{
if (ListView1->IsEditing()) // Check if list view item is being edited.
{
HWND Edit = ListView_GetEditControl(ListView1->Handle); // Get handle to edit window.
if (Edit)
{
UINT Scan = MapVirtualKey(VK_DELETE, MAPVK_VK_TO_VSC); // Get scan code of Del key.
SendMessage(Edit, WM_KEYDOWN, VK_DELETE, 0x00000001 | Scan << 16); // Simulate Del keypress in edit window.
SendMessage(Edit, WM_KEYUP, VK_DELETE, 0xC0000001 | Scan << 16);
}
}
else
ListView1->DeleteSelected(); // Delete selected items in list view.
}
void __fastcall TForm1::PopupMenu1Popup (TObject *Sender)
{
Delete1->Enabled = (ListView1->SelCount > 0);
}
有關引數中使用的位的描述WM_KEYDOWN和說明,請參見檔案。WM_KEYUPlparam
uj5u.com熱心網友回復:
只是一個想法,當您選擇 ListView1 專案并使用該標志跳過 ListView1->DeleteSelected(); 時,您應該能夠設定一個標志 'is_editing = true';有類似的東西
void __fastcall TForm1::Delete1Click (TObject *Sender)
{
if(!ListView1->Selected->Focused ) //revised
{
ListView1->DeleteSelected();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/506368.html
