Einzelnen Beitrag anzeigen

Benutzerbild von OrallY
OrallY

Registriert seit: 29. Apr 2003
268 Beiträge
 
#14

Re: Nachrichten vollkommen abfangen

  Alt 27. Mär 2005, 14:11
Danke für die rege Beteiligung .

Zitat von Mephistopheles:
Mich würde erst einmal interessieren, was genau du erreichen möchtest, denn dies wäre hier wohl besser. Ich habe noch nicht einmal deinen aktuellen Lösungsansatz komplett deiner Beschreibung entnehmen können. Hingegen zu einer bestimmten Problemstellung kann man eventuell Alternativen finden.
Ein berechtigter Einwandt, dem ich hiermit nachgehen möchte:
  • Programmfunktion:
    Der Benutzer soll im Endeffekt (genaue Funktion ist irrelevant) überall auf dem Bildschirm mit gedrückter rechter Maustaste zeichnen können. Die Anwendung selbst läuft im Hintergrund und soll den Dienst bereitstellen.
  • Problem:
    Drückt man irgendwo auf dem Bildschirm die Maustaste, erzeugt das loslassen beispielsweise ein Kontextmenü. Dies jedoch will ich vermeiden. Dabei muss das Programm natürlich unterscheiden, wann es ein Kontextmenü zulassen soll (die Maus wurde zwischen Drücken und Loaslassen der Maustaste gar nicht oder kaum bewegt) und wann es genau dies verhindern soll (die Maus bewegt sich bei gedrückter Maustaste).
  • Bisherige Lösung:
    Ein globaler LowLevel-Mousehook der anhand den oben genannten Parametern entscheidet, ob er die Mausnachricht durch den Aufruf von CallNextHookEx weiterleiten oder durch Nichtaufruf die Nachrichten blockieren soll.

    Delphi-Quellcode:
    library mousehook;

    uses
      Windows,
      Messages;

    const
      WM_MOUSEHOOK = WM_USER + $0400;

    type
      TFileMapStuff = record
        aHandle: Cardinal;
        BlockRMB: boolean;
      end;

    const
      BLOCKINGCOUNT = 10;

    var
      HookHandle : HHook;
      FileMapObj : THandle;
      FileMapView : ^TFileMapStuff;
      ComRec : TFileMapStuff;
      MouseEventCounter : integer;
      MouseDown : boolean;

    function MouseHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    var
      mhs: ^TMouseHookStruct;
    begin
      if (wParam <> WM_RBUTTONDOWN) and
         (wParam <> WM_RBUTTONUP) and
        Result := CallNextHookEx(HookHandle, Code, wParam, lParam);

      if code = HC_ACTION then
      begin
        FileMapObj := OpenFileMapping(FILE_MAP_READ, False,'HookMapFile');
        try
          if FileMapObj <> 0 then
          begin
            FileMapView := MapViewOfFile(FileMapObj, FILE_MAP_READ, 0, 0, 0);
            ComRec := FileMapView^;
            UnmapViewOfFile(FileMapView);
            CloseHandle(FileMapObj);
          end;
        except
          Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
          exit;
        end;

        if ((wParam = WM_RBUTTONUP) or (wParam = WM_RBUTTONDOWN)) and not ComRec.BlockRMB then
        begin
          Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
          exit;
        end;

        PostMessage(ComRec.aHandle, WM_MOUSEHOOK, wParam, lParam);

        if (wParam <> WM_RBUTTONDOWN) and
           (wParam <> WM_RBUTTONUP) and
           (wParam <> WM_MOUSEMOVE) then
          exit;

        if wParam = WM_RBUTTONDOWN then
        begin
          MouseDown := true;
          MouseEventCounter := 0;
        end
        else if wParam = WM_RBUTTONUP then
        begin
          MouseDown := false;

          if MouseEventCounter < BLOCKINGCOUNT then //Wurde die Maus nicht/kaum bewegt Tastenklick simulieren
          begin
            mhs := Pointer(lParam);
            MouseEventCounter := BLOCKINGCOUNT;
            mouse_event(MOUSEEVENTF_RIGHTDOWN, mhs^.pt.X, mhs^.pt.Y, 0, 0);
            mouse_event(MOUSEEVENTF_RIGHTUP, mhs^.pt.X, mhs^.pt.Y, 0, 0);
            Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
            exit;
          end
        end;

        if (wParam = WM_MOUSEMOVE) and (MouseDown) then
          if MouseEventCounter < BLOCKINGCOUNT then
            Inc(MouseEventCounter);

      end;
    end;

    procedure InstallHook; stdcall;
    begin
      HookHandle := SetWindowsHookEx(14, @MouseHookProc, hInstance , 0); //14 ist der LL-MouseHook
      MouseEventCounter := 0;
      MouseDown := false;
    end;

    procedure UninstallHook; stdcall;
    begin
      UnhookWindowsHookEx(HookHandle);
    end;

    exports
    InstallHook,
    UninstallHook;

    begin
    end.
    Wie schon gesagt, ich kann mir nicht vorstellen, dass es so sauber ist, CallNextHookEx einfach nicht aufzurufen, oder?
  • Weiteres Problem:
    Mit diesem Lösungsansatz funktioniert zwar das Blockieren der Maustaste, jedoch tritt das im 1. Posting genannte Problem mit dem Highlighting auf. Aus diesem Grund möchte ich verhindern, dass ein Fenster die Nachrichten, die für das Highlighting verantwortlich sind, während des Zeichnens erhält.

greez

P.S.: Ich stelle gerade fest, dass für die Benutzung des MadCodeHooks anscheinend Adminprivilegien erforderlich sind. Liege ich da richtig? Wäre dies der Fall würde diese Möglichkeit für mich schon mal nicht in Frage kommen .
.oO'rallY
Linux is like a tipi: no gates, no windows and a gnu-eating apache inside...
  Mit Zitat antworten Zitat