Mausbewegung erkennen ohne WM_MOUSEMOVE



  • WM_MOUSEMOVE ist eine schöne funktion, nur leider nicht, wenn man ein kleines POPUP Fenster hat, das man damit bewegen will! Das Problem ist ganz ganz einfach, das wenn ich die Maus zu schnell bewege, macht sie sprünge von 20 Pixel oder mehr. Wenn die Maus dann auserhalb des Fenters ist, erkennt WM_MOUSEMOVE nichtmehr, das die Mausbewegt wurde, weil ich mich nicht mehr im Fensterbereich befinde. Ich bräuchte nun eine Funktion, die erkennt ob die Maus bewegt wurde, selbst wenn ich ausserhalb des Fensters bin!



  • Du willst dein Fenster verschieben lassen, welches keine Titelzeile hat?
    Den Weg den ich kenne ist: Windows vorgaukeln man hätte die Maus auf ner Titelzeile (WM_NCHITTEST abfangen und entsprechend handeln, einfach mal nach "WM_NCHITTEST" und "Caption" googlen, da wird man garantiert fündig)

    Ansonsten hilft dir SetCapture() evtl. weiter:
    http://msdn.microsoft.com/en-us/library/ms646262(VS.85).aspx



  • Du kannst auch in kleinen Abständen ➡ GetCursorPos() aufrufen und mit der alten Position vergleichen. Wenn sich der Wert verändert hat, kannst du das Popupfenster an die neue Position verschieben.



  • Danke, das funktioniert ganz gut, fast perfekt! Leider geht das Fenster erst in den Fordergrund, wenn man den Mausbutton wieder los läßt und sämtlich WM massages die mit der Maus zu tun haben funktionieren nicht mehr. wie kann ich WM_LBUTTONDOWN und die anderen wieder nutzen, denn die könnte ich noch gut gebrauchen.



  • @Code-Walker: vielleicht solltest du dazuschreiben auf wessen Antwort du dich beziehst.
    Ich *vermute* auf die 1. von geeky, und in dem Fall darf ich dir die 2. ans Herz legen: tu es einfach pollen. Ist zwar verpönt, aber immer noch für viele viele Dinge die einfachste Lösung und vor allem recht robust (=man kann kaum was falschmachen ... ausser vielleich zu schnell zu pollen).


  • Mod

    Geeky hat Dir die Beste und richtige Antwort gegeben. Nimm WM_NCHITTEST und HTCAPTION!



  • Es war an die erste Antwort gerichted, die zweite kahm während ich am schreiben war, sry! Was bedeutet pollen, ich vermute das ist die zweite Antwort. Die erste von Geeky scheint die beste zu sein, das ist auch das einzige was ich dazu bei Google finde, und ist wohl die gängigste Methode.



  • Ich habe das ganze jetzt mal über GetWindowPos versucht, funktioniert soweit auch ganz gut, leider nicht mehr wenn ich das Fenster mit der Maus verlasse. Ich habe einen Timer der ede Millisekunde das jeweilige fenster an die Position setzt, aber es will nicht so wie ich will, das problem isthalt, das wenn ich das Fenster verlasse ...

    WM_NCHITTEST funktioniert noh am besten, leider kann ich die ganzen WM_MOUSE Messages nicht mehr benutzen, die ich aber brauche. Wie kann ich trotz WM_NCHITTEST erkennen ob die Maus gedrückt oder bewegt wurde?



  • Ich habe mir da was überlegt, wie es funktioniert, dafür muss ich aber wissen, i ich heraus bekomme ob die Maus los gelassen wurde, selbst wenn ich nicht mehr in dem bereich meines Fensters bin. Geht das irgentwie?

    EDIT:::::

    Das mit SetCapture() habe ich noch nicht verstanden, kann das sein, wenn ich das Captur auf ein Fenster setze, Nachrichten nurnoch an dieses Fester gehen?

    EDIT:::::

    Es funktioniert! Warum ist die Lösung immer das, wovon man nicht gedacht hat das es die Lösung sein könnte. Man sollte sich wirklich immer erst das anschauen was man am unwarscheinlihsten hält, und am einfachsten ...

    Für die Nachwelt(falls es jemanden interessiert):

    Wenn man sein Popup Fenster verschieben will, wie ein richtiges Fenster mit Titelleiste, dann macht man das folgendermaßen:

    case WM_LBUTTONDOWN:
    {
        SetCapture(FensterHandle);
        BringWindowToTop(FensterHandle);
        GetWindowRect(FensterHandle, &FensterRect);
        GetCursorPos(&MausPosition);
        Abstand.x = MausPosition.x - FensterRect.left;
        Abstand.y = MausPosition.y - FensterRect.top;
        break;
    }
    case WM_LBUTTONUP:
    {
        ReleaseCapture(FensterHandle);
        break;
    }
    case WM_MOUSEMOVE:
    {
        GetCursorPos(&MausPosition);
        MoveWindow(FensterHandle, MausPosition.x - Abstand.x, MausPosition.y - Abstand.y, 200, 200, true);
        break;
    }
    

    Der Code sollteigentlich verständlich sein, aber ich erkläre ihn trotzdem mal! Wenn die linke Maustaste gedrückt wird(WM_LBUTTONDOWN), werden alle Nachrichten die mit der Maus zu tun haben, an das momentanige Fenster geschickt, selbst wenn die Maus sich garnicht mehr in dem Bereich des fensters befindet, das hat den vorteil, das man die Maus so schnell bewegen kann wie man will und das Fenster folgt einem trotzdem noch! Das ganze wird mit SetCapture() realisiert. Nun müssen wir den abstand wischen der Maus und der Fensterposition heraus bekommen. Das ganz könnte man ganz einfach via lParam herausfinden, ich habe mich aber dennoch für eine andere Methode entschieden. Ich subtrahiere die mausposition mit der Fensterposition, als ergebnis erhalte ich den abstand zwishen Maus und Fenster. Wenn wir nun das Fenster bewegen (WM_MOUSEMOVE), soll sich die Position des Fensters der Mausposition anpassen. Zu erst müssen wir dafür wissen wo die maus gerade ist und rufen GetCurserPos() auf. Im zeiten Parameter werden die Daten gespeichert(MausPosition ist eine POINT Variable). Anscließend Setzen wir das Fenster an die jeweilige stelle, dazu müssen wir bloß MoveWindow aufrufen und an der Poition setzen wo wir es haben wollen. Es wird an "MausPosition - abstand gesetzt. Wenn wir nun die Maus ieder los lassen (WM_LBUTTONUP) geben wir den Capture wieder frei, damit die Nachrichten ieder frei gesendet werden können.


  • Mod

    Code-Walker schrieb:

    Das mit SetCapture() habe ich noch nicht verstanden, kann das sein, wenn ich das Captur auf ein Fenster setze, Nachrichten nurnoch an dieses Fester gehen?

    Ja, das gilt für Mausnachrichten. SetCapture wir dverwendet um z.B. bei gedrückter Maustaste ein Drag über andee Fenster zu ermöglichen.



  • Danke hab mich gerade schlau gemacht, habe an mein zuvorigem Post ein Edit dran gehangen 🙂


  • Mod

    Diser Code ist in meinen Augen falsch. Denn Du dürftest nur dann das Fenster bewegen, wenn die Maustaste auch gedrückt ist.
    Jetzt verursacht ja jede Mausbewegung (auch über dem Fenster) ein MoveWindow!



  • Achso, hab ganz vergessen och die "if" mit in den Code zu schreiben. Ich setze bei WM_LBUTTONDOWN die boolische variable auf true, dann überprüfe ich in WM_MOUSEMOVE ob die variable auf true ist, wenn a bewege ich das fenster. Wenn die Maus wieder los gelassen wird, setze ich die variable wieder auf false!


Anmelden zum Antworten