AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

NM_RETURN - Problem

Ein Thema von silentAMD · begonnen am 20. Mai 2004 · letzter Beitrag vom 18. Mai 2007
Antwort Antwort
Seite 4 von 4   « Erste     234   
Assarbad
(Gast)

n/a Beiträge
 
#31

Re: NM_RETURN - Problem

  Alt 2. Sep 2004, 22:38
Nicht von mir, sorry.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#32

Re: NM_RETURN - Problem

  Alt 3. Mai 2007, 11:55
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
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Dirk - nonVCL

Registriert seit: 14. Mai 2007
Ort: Islamabad
2 Beiträge
 
Delphi 2005 Personal
 
#33

Re: NM_RETURN - Problem

  Alt 14. Mai 2007, 12:32
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
Dirk
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#34

Re: NM_RETURN - Problem

  Alt 14. Mai 2007, 15:04
hast du ausprobiert, ob du die Tab-Taste noch wie gewohnt verwenden kannst?
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Dirk - nonVCL

Registriert seit: 14. Mai 2007
Ort: Islamabad
2 Beiträge
 
Delphi 2005 Personal
 
#35

Re: NM_RETURN - Problem

  Alt 18. Mai 2007, 18:35
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.
Dirk
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 4   « Erste     234   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz