Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi NM_RETURN - Problem (https://www.delphipraxis.net/22651-nm_return-problem.html)

Assarbad 2. Sep 2004 21:38

Re: NM_RETURN - Problem
 
Nicht von mir, sorry.

Dezipaitor 3. Mai 2007 10:55

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 IsDialogMessage, welche die eingehenden Nachrichten bearbeitet und bestimmte Tasten nicht an die Elemente (Listview) weitergibt. Die Tab-Taste wird dort z.B. verwendet, um zum nächsten Element zu springen.
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:
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);
   }
(Sorry für C++ Code, aber es sollte klar werden.)


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: http://msdn2.microsoft.com/en-us/library/ms645425.aspx
The Old new Thing Blog: http://blogs.msdn.com/oldnewthing/ar.../26/55872.aspx
MSDN sagt dazu: http://support.microsoft.com/kb/83302/de

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

Dirk - nonVCL 14. Mai 2007 11:32

Re: NM_RETURN - Problem
 
Hallo Dezipaitor,

Super Beitrag. Danke.

In Delphi habe ich das subclassing-Problem so gelöst:

Delphi-Quellcode:
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
Mit CallWindowProc muss man sich keine Gedanken um das richtige weiterleiten der Msg machen. Windows erledigt das. In meinen Programmen funktioniert das super.
Verbesserungen sind bestimmt noch möglich.

Viele Grüße

Dirk

Dezipaitor 14. Mai 2007 14:04

Re: NM_RETURN - Problem
 
hast du ausprobiert, ob du die Tab-Taste noch wie gewohnt verwenden kannst?

Dirk - nonVCL 18. Mai 2007 17:35

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.
Seite 4 von 4   « Erste     234   

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