Beim drücken der Entertaste ertönt ein Warnsound (Subclassing)



  • Ich seh mir gerade die Definition an, damit kann ich aber wirklich nichts anfangnen. Kannst du mir mal erläutern wie das Funktionieren soll, ich finde nichts in der MSDN



  • Ist gaaaanz easy:

    1. Windowsx.h öffnen und nach der gewünschten WM-Message suchen, ich nehme mal als Beispiel WM_CREATE, gibt man WM_CREATE in der Suche ein kommt das hier:

    /* BOOL Cls_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) */
    #define HANDLE_WM_CREATE(hwnd, wParam, lParam, fn) \
        ((fn)((hwnd), (LPCREATESTRUCT)(lParam)) ? 0L : (LRESULT)-1L)
    #define FORWARD_WM_CREATE(hwnd, lpCreateStruct, fn) \
        (BOOL)(DWORD)(fn)((hwnd), WM_CREATE, 0L, (LPARAM)(LPCREATESTRUCT)(lpCreateStruct))
    

    In dem Kommentar steht die Definition der Funktion:

    BOOL Cls_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
    

    2. Die Funktion für WM_CREATE kann man z.B. so schreiben, nach den Parameterrichtlinien:

    // Handling der WM_CREATE-Message
    bool create (::HWND__* hwnd, CREATESTRUCT* createStruct)
    {
        return (true);
    }
    

    Darin kann man nun alles machen was man will für die WM_CREATE-Message.

    3. In die WndProc einbinden geht auch sehr einfach:

    // Die Fensterprozedur für das Editorfeld
    long __stdcall WndProc (::HWND__* hwnd, unsigned int message, unsigned int wParam, long lParam)
    {
            // Welche Message wird angefordert?
        switch(message)
        {
        HANDLE_MSG (hwnd, WM_CREATE,  create);
        HANDLE_MSG (hwnd, WM_DESTROY, destroy);
        }
    
            // Windows-Standardverarbeitung
        return (static_cast<long>(::DefWindowProc (hwnd, message, wParam, lParam)));    
    }
    

    Ich habe hier noch die WM_DESTROY message mit eingebunden, die hat nur HWND als Parameter, aber ich glaube die Spezifikationen dafür findest Du schon selber raus 😉

    So bekommt halt alles seine Ordnung 🙂

    Achja: HANDLE_MSG und WindowsX.h standen bis vor paar Jahren noch in der MSDN, aber seit ca. 2001 schaue ich nur noch in die WindowsX.h für die Spezifikationen der einzelnen Funktionen. Kann sein das es aus der MSDN nach dem "großen Umbau" rausgeflogen ist wie der alte DOS-Scheiß. Die WindowsX.h ist ja noch aus WinNT1.0 da 😉



  • Das Konzept hat MS unter Garantie von GTK geklaut. Die machen das genauso. Ne ich bleibe bei meinem alten Konzept, aber gut auch noch ne andere Möglichkeit zu kennen, thk



  • flammenvogel schrieb:

    Das Konzept hat MS unter Garantie von GTK geklaut.

    Und wenn? Es klaut doch jeder von jedem. Die Linuxfritzen klauen von Microsoft Research, die Microsoftfritzen von MacOS, die wieder von anderen.

    Also: Wayne? kein schwein.



  • [...] schrieb:

    flammenvogel schrieb:

    Das Konzept hat MS unter Garantie von GTK geklaut.

    Und wenn? Es klaut doch jeder von jedem. Die Linuxfritzen klauen von Microsoft Research, die Microsoftfritzen von MacOS, die wieder von anderen.

    Also: Wayne? kein schwein.

    Hab ich was anderes gesagt? Ich finde nur die Möglichkeit alles in eine Funktion zu packen übersichtlicher weil ich sonst zu viele Funktionsdefinition im Header stehen habe



  • Kann mir dann jemand wenigstens nocheinmal ein gutes Tutorial zum Subclassing empfehlen. Dann vergleiche ich den Code ...



  • Da ja anscheinend keiner in der Lage ist die Aufgabe zu lösen musste ich es nun irgendwie selber schaffen. Nach ein paar Stunden MSDN Recherche bin ich zu folgendem funktionierendem Ergebnis gekommen:

    LRESULT CALLBACK WndEditProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch(message)
    	{
    		//case WM_GETDLGCODE:
    		//	return DLGC_WANTALLKEYS;
    		//	break;
    		case WM_GETDLGCODE:
    			if(lParam != NULL)
    			{
    				if(((MSG*) lParam)->message == WM_KEYDOWN && ((MSG*) lParam)->wParam == VK_RETURN)	
    	   			{		
    					return DLGC_WANTMESSAGE;
    				}
    			}
    			break;
    		case WM_KEYDOWN:
    			return 0;
    		case WM_CHAR:
    			if(wParam == VK_RETURN)
    			{
    				SendMessage((HWND) GetWindowLong(hwnd, GWL_HWNDPARENT), WM_COMMAND, MAKEWPARAM(BU_WEITER, 0),0);
    				return 0;
    			}
    			else
    				return CallWindowProc((WNDPROC)oldeditproc, hwnd, message, wParam, lParam);
    		case WM_SYSCHAR:
    		case WM_SYSKEYDOWN:
    		case WM_SYSCOMMAND:
    			return 0;
    			break;
    		default:			
    			return CallWindowProc((WNDPROC)oldeditproc, hwnd, message, wParam, lParam);
    	}
    	return CallWindowProc((WNDPROC)oldeditproc, hwnd, message, wParam, lParam);
    }
    

    Die Rolle der WM_GETDLGCODE verstehe ich immer noch nicht so ganz, aber es sieht so aus als müsste man Messages mit VK_RETURN extra anfordern. Das muss man komischerweise für Texteingaben (Buchstaben, Zahlen) nicht machen. Dann alle Nachrichten mit VK_RETURN (dazu gehören auch WM_SYS* Messages) selber bearbeiten und kaputt machen (retun 0), so das sie nicht mehr weiterverarbeitet werden. Die WM_KEYDOWN Nachricht mach ich kaputt, da WM_KEYDOWN und WM_CHAR gesendet wird (vorausgesetzt in der while-Schleife gibt es TranslateMessage()). Würde ich beide verarbeiten, würde ich zweimal einen Tastendruck auf VK_RETURN registrieren. (Einmal von der Keydown Message und der Char Message). In dem Code oben stehen zwei Varianten von WM_GETDLGCODE. Die Auskommentierte hat den Nachteil das dann auch andere Systemkeys im Edit Feld nicht gehen (Bsp: Der Wechsel mit Tab zwischen den Feldern). Bei der Variante oben funktioniert aber alles perfekt und auch der TAB-Wechsel geht. 😉

    Eine Bitte an einen/die Moderatoren hier. Ich habe lange gebraucht das Problem zu lösen. Und da ich mir vorstellen kann, das einige andere auch mal ein Edit Feld "sauber" subclassen wollen, wär das doch mal was für die FAQ.



  • Nachtrag: Man kann meinen Code oben noch optimieren, z.B könnte man den default Zweig löschen ...



  • Ich habe sowas noch nie gemacht, aber hast du mal DLGC_WANTCHARS ausprobiert?
    BTW: IN der WinUser.h sind DLGC_WANTALLKEYS und DLGC_WANTMESSAGE beide als 0x0004 definiert (also synonym)



  • @Flenders: Stimmt beide sind als 4 definiert. Keine Ahnung warum Microsoft das so gemacht hat.

    Zu dem DLGC_WANTCHARS:

    Mir persönlich gefällt diese Variante besser, da ich dann nur den Kram beim Enter drücken bekomme, außerdem habe ich keine ob bei DLGC_WANTCHARS auch die Tastenanschläge von VK_RETURN bekomme.

    Ich brauche diese kommische Message ja nur wenn ich in meiner while Schleife ein IsDialogMessage() drin habe

    MSDN:

    IsDialogMessage sends WM_GETDLGCODE messages to the dialog box procedure to determine which keys should be processed.

    Deswegen halte ich es für keine gute Idee für alle Tasten in WM_CHARS die Dialog Standardaktionen zu sperren.


Anmelden zum Antworten