Simple frage zur WinAPI



  • Hi,

    nehmen wir mal an ich habe ein Fenster mit einem Button drauf.

    Ich klicke auf den Button, und die WM_COMMAND Message wird ausgeführt und an das Fenster wodrauf der Button ist gesendet.

    JETZT ist die frage: Wird die WM_COMMAND auch an den Button gesendet wenn ich da mit Subclassing drangehe? Oder welche nachricht wird an den Button dann gesendet, wenn WM_COMMAND nicht zum Button gesendet wird? evtl. eine Alternativmessage?

    Vielen dank im voraus!



  • '#' schrieb:

    JETZT ist die frage: Wird die WM_COMMAND auch an den Button gesendet wenn ich da mit Subclassing drangehe?

    Subclassing hat doch mit den Messages nichts zu tun. Das bleibt wie normal. Nur wird eben jetzt *Deine* WndProc ausfgerufen.



  • @Jochen Kalmbach
    Also bekommt der Button auch die Message WM_COMMAND?



  • Nein. Nur der Parent bekommt ein WM_COMMAND



  • @Jochen Kalmbach
    bekommt der Button stattdessen eine andere Message mit der ich so etwas "immitieren" kann?



  • Manche Frameworks senden die Nachricht wieder zum Button zurück, natürlich unter anderer Message-ID, sowas wie WM_COMMAND_REFLECTED.



  • '#' schrieb:

    @Jochen Kalmbach
    bekommt der Button stattdessen eine andere Message mit der ich so etwas "immitieren" kann?

    Was willst Du denn "immitieren"?



  • @Jochen Kalmbach
    ich möchte nicht das das Fenster WM_COMMAND bekommt (okay, ist mir eigentlich egal) sondern das der Button diese nachricht auch bekommt oder ich sie irgendwie immitieren kann in der WndProc des Buttons. Hauptsache das der Button "weiß" das er betätigt wurde und nicht das Fenster wo er drauf gezeichnet ist.



  • kannste nicht WM_LBUTTONDOWN nehmen?



  • @fraage
    ist doch nicht das selbe wie WM_COMMAND!



  • '#' schrieb:

    @Jochen Kalmbach
    ich möchte nicht das das Fenster WM_COMMAND bekommt (okay, ist mir eigentlich egal) sondern das der Button diese nachricht auch bekommt oder ich sie irgendwie immitieren kann in der WndProc des Buttons. Hauptsache das der Button "weiß" das er betätigt wurde und nicht das Fenster wo er drauf gezeichnet ist.

    Das würde bedeuten, daß der Button eine eigene CALLBACK-Funktion bekommt. Wenn Du den Button mit hButton = CreateWindow("button",...) erstellt hast, rechnet Windows nicht mit ner CALLBACK-Funktion. Der bekommt nur eine ID zugewiesen.
    Du müßtest den Button selbst programmieren, dann kannst Du ihm eine CALLBACK-Funktion geben und eine WM_COMMAND schicken.

    http://www.win-api.de/tutorials.php?tutid=14
    Da ist am Ende des Tutorials von so einem Beispiel die Rede. Du kannst den autor anmailen, daß er Dir das Prog schickt.



  • @Elektronix
    d.h. ich muss mit einer Fensterklasse dran gehen, diese Registrieren und anhand dieser Daten das fenster erstellen des Buttons? und DANN würde der Button WM_COMMAND bekommen beim Drücken?

    Oder wäre es auch eine möglichkeit in der WndProc des Hauptfensters bei WM_COMMAND zu schreiben: SendMessage (hwnd, WM_COMMAND usw.) ?



  • du musst das child-fenster vom parent-fenster aus irgendwie benachrichtigen. anders geht es nicht.



  • Oder wäre es auch eine möglichkeit in der WndProc des Hauptfensters bei WM_COMMAND zu schreiben: SendMessage (hwnd, WM_COMMAND usw.) ?
    

    Damit schickst Du ja nur eine Nachricht an Dein Fenster.

    Es reicht nicht, daß der Button eine Nachricht bekommt. Er muß sie auch verarbeiten (wozu bekommt er sie sonst?). Dazu ist die CALLBACK-Funktion da.

    Die CALLBACK-Funktion wird in der Fensterklasse deklariert. Der Button ist eine schon vorregistrierte Fensterklasse und wird mit CreateWindow erstellt. Dabei gibst Du nur als Class-Parameter "button" ein (der erste Parameter in CreateWindow ist lpszClassName). Die Fensterklasse "button" enthält aber keine CALLBACK-Deklaration. Ohne CALLBACK kannst Du keine Nachrichten bearbeiten.
    Folglich: Du mußt eine eigene Fensterklasse entwerfen, die aussieht wie ein Button und eine CALLBACK-Funktion enthält. Laß Dir das Beispiel aus dem Link schicken.



  • @Elektronix
    Wenn ich eine Fensterklasse mit WndProc für den Button registriere bekommt der button dann auch diese Message, wenn ich sie dort verarbeiten kann?

    Oder kann ich mit SubClassing dem Button eine Alternative WndProc geben wo ich nachrichten darauf abfragen kann, womit ich eine WM_COMMAND simulieren kann?

    Ich möchte es so machen wie in VCL: Der Buttonevent verarbeitet, nicht das Fenster.



  • Hab ich doch eigentlich schon beantwortet ;).

    Wenn Du ein Child-Window als Button programmierst, trägst Du in den Fenster-Parametern eine zweite CALLBACK-Funktion ein, die Du selbst implementieren mußt. Dann sendest Du mit der WndProc eine Nachricht an die ChildProc (des Button-Fensters) und kannst die dort auswerten.

    Das ganze Prozedere ist in dem Tutorial beschrieben, das ich Dir schon empfohlen hab. Tu Dir ruhig mal die Mühe an (hab ich auch gemacht, die Antwort kommt eigentlich recht schnell). Es lohnt sich.



  • Du musst Dir nicht zwangsläufig eine eigene Fensterklasse für den Button erstellen, das würde ja beinhalten, dass Du diesen auch selbst zeichnen müsstest, etc. Wäre für das empfangen einer eigenen Klick-Msg viel zu aufwendig.

    Es würde reichen, wenn Du den Button subclasst. Allerdings bekommst Du dann nicht mehr die Nachricht WM_COMMAND gesendet, sondern getrennt WM_LBUTTONDOWN und WM_LBUTTONUP. Ob nun ein richtiger Klick ausgeführt wurde, musst Du natürlich selbst überprüfen, was sich aber über eine map erledigen lässt, also etwa so:

    ...
    std::map<HWND, bool> ButtonStates;
    ...
    case WM_LBUTTONDOWN:
        ButtonStates[hWnd] = true;
    break;
    case WM_LBUTTONUp:
        if (ButtonStates[hWnd]) {
            ButtonStates[hWnd] = false;
            // Klick wurde ausgeführt, also onClick-Handler aufrufen
        }
        else {
            // Es wurde mit gedrückter Maustaste über den Button gefahren und dann losgelassen
        }
    break;
    

    Also irgendwie so. Bitte nicht als gültigen oder gar guten Code bewerten, nur so als Idee. Dann könntest Du den Button-Status noch bei MouseOut zurücksetzen, damit der Klick tatsächlich nur dann ausgeführt wird, wenn sich die Maus die ganze Zeit bei ButtonDown und ButtonUp über den Button befindet.


Anmelden zum Antworten