![]() |
Re: NM_RETURN - Problem
Nicht von mir, sorry.
|
Re: NM_RETURN - Problem
hi
es scheint, dass das NM_RETURN Problem noch keiner gelöst hat? Hier das Problem: Das Problem ist, dass die Enter Taste, oder allgemein alle Tasten, im Dialog von einem ListView (oder anderen Elementen) nicht über die Nachricht WM_NOTIFY empfangen werden kann. Dasselbe funktioniert jedoch, wenn man das ListView NICHT in einem Dialog hat. Hier die Lösung : Es liegt an ![]() Die Enter-Taste ist in Dialogen eine besondere Taste (genauso wie ESC), welche ein ID_OK repräsentiert. Also ein Klicken auf den OK-Button. Daher empfängt kein anderes Steuerelement diese Tasten. Es gibt drei Lösungen: Wer IsDialogMessage selbst aufruft, der kann vorher einfach die Nachricht vorher schon abfangen, und die Nachricht an das eigene Fenster schicken.
Delphi-Quellcode:
(Sorry für C++ Code, aber es sollte klar werden.)
BOOL PreTranslateMessage(MSG* pMsg)
{ switch (pMsg->message) { case WM_KEYDOWN: { switch (pMsg->wParam) { case VK_RETURN: case VK_F5: SendMessage(myWindowHandle, pMsg->message,pMsg->wParam,pMsg->lParam); return FALSE; } } } return ::IsDialogMessage(m_hWnd, pMsg); } Die zweite Lösung ist, dass man von der Listview Klasse eine eigene Ableitung erstellt (Subclassing) und dort die WindowProc überschreibt. Es geht jedoch auch einfach so, dass man CreateWindow verwendet und in der Struktur, die WndProc auf eine eigene Version setzt. Das Ziel ist es dabei, die Nachricht WM_GETDLGCODE, die von IsDialogMessage an jedes einzelne Steuerelement gesendet wird, abzufangen und einen besonderen Rückgabewert zu erzeugen: GetDlgCode: ![]() The Old new Thing Blog: ![]() MSDN sagt dazu: ![]()
Delphi-Quellcode:
LRESULT CALLBACK ListViewControlWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ switch (message) { case WM_GETDLGCODE: switch (wParam) { case VK_F5: case VK_RETURN: return DLGC_WANTALLKEYS | DLGC_WANTMESSAGE; } } return ::DefWindowProc(hwnd, message, wParam, lParam); } Die dritte Lösung ist, die WindowProc eines existierenden ListViews zu verbiegen:
Delphi-Quellcode:
//Die Listview WindowProc verbiegen, damit man die Enter-Taste abfragen können,
//weil diese von IsDialogMessage verbogen wird LPARAM wndProc = GetWindowLong(mListViewHandle GWL_WNDPROC); SetWindowLong(mListViewHandle,GWLP_USERDATA,(LPARAM)wndProc); SetWindowLong(mListViewHandle, GWL_WNDPROC,(LPARAM)&ListViewControlWndProc);
Delphi-Quellcode:
LRESULT CALLBACK ListViewControlWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ switch (message) { case WM_GETDLGCODE: switch (wParam) { case VK_F5: case VK_RETURN: return DLGC_WANTALLKEYS | DLGC_WANTMESSAGE; } } LPARAM l = ::GetWindowLong(hwnd,GWL_USERDATA); WNDPROC wndProc = (WNDPROC)l; if (wndProc) return wndProc(hwnd,message,wParam,lParam); } Wer Lust hat von den Mods kann den C++ Code nach Delphi portieren. Sorry aber ich hab grad kaum Zeit :D |
Re: NM_RETURN - Problem
Hallo Dezipaitor,
Super Beitrag. Danke. In Delphi habe ich das subclassing-Problem so gelöst:
Delphi-Quellcode:
Mit CallWindowProc muss man sich keine Gedanken um das richtige weiterleiten der Msg machen. Windows erledigt das. In meinen Programmen funktioniert das super.
type
{Since Delphi does not distinguish between capital and non-capital letters, TWPARAM & TLPARAM should be declared.} TWPARAM = WPARAM; TLPARAM = LPARAM; var WndProcLV : Integer; hListView : HWND; //*************** LVWndProc *************** function LVWndProc(handle : HWND; Msg : Cardinal; wParam1 : TWPARAM; lParam1 : TLPARAM) : Integer; stdcall; begin // LVWndProc // if "Return" was pressed, then process it in the list view if (Msg = WM_GETDLGCODE) and (wParam1 = VK_RETURN) then Result:= DLGC_WANTALLKEYS or DLGC_WANTMESSAGE // otherwise give the control back to the calling procedure else Result:= CallWindowProc(Pointer(WndProcLV), handle, Msg, wParam1, lParam1); end; // LVWndProc //*************** LVWndProc *************** //begin main dialog function //... hListView := GetDlgItem(hwndDlg, FolderList); // handle to the ListView hHeader := SendMessage(hListView, LVM_GETHEADER, 0, 0); // LV header {Create a subclass for the list view, to catch the VK_RETURN for the list view} WndProcLV:= GetWindowLong(hListView, GWL_WNDPROC); SetWindowLong(hListView, GWL_USERDATA, WndProcLV); SetWindowLong(hListView, GWL_WNDPROC, Integer(@LVWndProc)); //... // end main dialog function Verbesserungen sind bestimmt noch möglich. Viele Grüße Dirk |
Re: NM_RETURN - Problem
hast du ausprobiert, ob du die Tab-Taste noch wie gewohnt verwenden kannst?
|
Re: NM_RETURN - Problem
Ja, kein Problem. Alle Tasten funktionieren wie sie sollen, inkl. TAB im Dialog (auch mit Return Taste).
Die Return-Taste wird nur abgefangen, wenn der der List View den Focus hat. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz