Announcement

Collapse
No announcement yet.

TrayClockWClass

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TrayClockWClass

    Hi,<br>
    ich versuche, mit folgendem Code den Text der Uhr zu verändern:<br>
    <br>
    program&nbsp;TrayClock;<br>
    <br>
    uses&nbsp;Windows,&nbsp;Messages;<br>
    <br>
    var<br>
    &nbsp;&nbsp;TrayHandle:&nbsp;hWnd;<br>
    <br>
    begin<br>
    &nbsp;&nbsp;TrayHandle&nbsp;:=&nbsp;FindWindowEx(F indWindowEx(FindWindow('Shell_TrayWnd',<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;nil),<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;0,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;'TrayNotifyWnd',<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;nil),<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;0,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;'TrayClockWClass',<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;nil);<br>
    &nbsp;&nbsp;SendMessage(TrayHandle,&nbsp;WM_SETTEX T,&nbsp;0,&nbsp;LPARAM(PChar('Test')));<br>
    end.<br>
    <br>
    Das ganze funktioniert auch, WinSight32 zeigt tatsächlich den neuen Text an, aber unten in der Uhr steht er nicht. Wnn man die Messages von TrayClockWClass abhört, so wird WM_USER + 0x64 gesndet, wmm man die Maus bewegt. Jedesmal wenn WM_TIMER empfangen wird, so sendet TrayClockWClass WM_SETTEXT an sich selbst, es wird also mit WM_SETTEXT gearbeitet.<br>
    Man hat mir geraten, WM_SETTEXT mit einem anderen wParam-Wert zu benutzen, da TrayClockWClass vielleicht auf diese Weise fremde von eigenen Messages unterscheidet, ich konnte jedoch nicht herausfinden, welchen Wert ich sonst senden sollte. Irgendjemand hat mir mal einen Link zu Inject-DLLs gegeben, aber den ist weg.<br>
    <br>
    Kann mir jemand sagen, was ich machen muss?
    <br>
    Danke im Voraus,
    d3g

  • #2
    Hi

    Nach Deinem Versuch solltest Du mal mit getWindowText() den Text der Uhr lesen. Du wirst feststellen das die Uhr Deinen Text tatsächlich speichert. ABER, wie so oft beim "Hacken" funktioniert das was Du vorhast nicht, weil die Uhr wahrscheinlich eine eigene Zeichenroutine benutzt )
    Die Message wm_user + $64 sieht sehr nach der eigentlichen Zeichen-Message aus, d.h. jedesmal wenn diese Message eintrifft zeichnet sich die Uhr neu indem sie direkt die Systemuhrzeit in einen String umwandelt und dann direkt zeichnet.

    Gruß Hage

    Comment


    • #3
      Hi Hagen,<br>
      danke schonmal. Wie's aussieht kann ich das nur über eine Inject-DLL mit einer eigenen WindowProc-Funktion für die Uhr lösen. Weiß jemand, wie das geht?<br>
      <br>
      MfG,
      d3

      Comment


      • #4
        Hi

        Im Delphi Demo Ordner findest Du zwei Projekte die 1. einen CopyHookHandler und ein ContextMenuHandler beschreiben. Nehme den ICopyHook, im Hook selber machst Du NICHTS. Es geht nur darum das dieser Handler in einer DLL durch die Shell=Explorer geladen wird. Damit IST Deiner DLL als COM Erweiterung in den Explorer Prozess eingebunden. D.h. in dieser DLL kannst Du Dein SubClassing der Clock gefahrlos durchführen. Du brauchst also keine Inject-DLL da der Explorer selber solche COM Erweiterungen in sich selbst "injeziert".

        Gruß Hage

        Comment


        • #5
          Hallo Hagen,
          gut, das Projekt habe ich gefunden und kompiliert. Da ich allerdings nicht viel Ahnung von COM habe, weiß ich jetzt nicht wirklich, was ich mit der DLL anfangen kann. So wie ich das vestanden habe, wird die DLL automatisch von der Explorer.exe gealden - wieso? - und ich kann irgendwie damit die TrayClock ändern, da die DLL zur Explorer.exe dazugehört, aber wie?

          Danke schonmal,
          d3

          Comment


          • #6
            <pre>

            unit CopyHk;

            interface

            uses
            Windows, ComObj, ComServ, SysUtils, ShlObj, Messages, Graphics;

            Const
            CLSID_CopyHookShellExtension: TGUID = (
            D1:$8e3e0f0a; D2:$0fcc; D3:$11ce; D4$bc, $b0, $b3, $fd, $0e, $25, $38, $19));

            type
            TCopyHook = class(TComObject, ICopyHookA)
            public
            function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar;
            dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall;
            end;

            implementation

            function TCopyHook.CopyCallBack(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar;
            dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT;
            begin
            Result := ID_YES;
            end;

            var
            OldWndProc: Pointer = nil;

            function FindClock: hWnd;
            var
            Wnd: hWnd;
            begin
            Wnd := FindWindow ('Shell_TrayWnd', nil);
            Wnd := FindWindowEx(Wnd, 0, 'TrayNotifyWnd', nil);
            Wnd := FindWindowEx(Wnd, 0, 'TrayClockWClass', nil);
            if IsWindow(Wnd) then Result := Wnd else Result := 0;
            end;

            function MyClockWndproc(Wnd: hWnd; Msg,wParam,lParam: Integer): Integer; stdcall;

            function GetText(Wnd: hWnd): String;
            begin
            SetLength(Result, MAX_PATH);
            SetLength(Result, GetWindowText(Wnd, PChar(Result), Length(Result)));
            Result := Result + FormatDateTime(' HH:NN', Now);
            end;

            function CalcWidth(Wnd: hWnd): Integer;
            // Breite der Uhr ermitteln
            var
            DC: hDC;
            R: TRect;
            S: String;
            begin
            SendMessage(Wnd, wm_SetRedraw, 1, 0);
            S := GetText(Wnd);
            DC := GetDC(Wnd);
            try
            SelectObject(DC, GetStockObject(ANSI_VAR_FONT));
            R.Left := 0;
            R.Top := 0;
            R.Right := 1024;
            R.Bottom := 1024;
            DrawText(DC, PChar(S), Length(S), R, dt_Left or dt_SingleLine or dt_CalcRect);
            finally
            ReleaseDC(Wnd, DC);
            end;
            Result := R.Right + 8;
            SendMessage(Wnd, wm_SetRedraw, 0, 0);
            end;

            procedure PaintWindow(Wnd: hWnd);
            var
            DC: hDC;
            R: TRect;
            B: hBrush;
            S: String;
            begin
            SendMessage(Wnd, wm_SetRedraw, 1, 0);
            GetClientRect(Wnd, R);
            S := GetText(Wnd);
            DC := GetDC(Wnd);
            B := CreateSolidBrush(ColorToRGB(clBtnFace));
            try
            B := SelectObject(DC, B);
            SelectObject(DC, GetStockObject(ANSI_VAR_FONT));
            FillRect(DC, R, B);
            DrawText(DC, PChar(S), Length(S), R, dt_VCenter or dt_Center or dt_SingleLine);
            finally
            DeleteObject(SelectObject(DC, B));
            ReleaseDC(Wnd, DC);
            end;
            SendMessage(Wnd, wm_SetRedraw, 0, 0);
            end;

            begin
            Result := 0;
            if (Msg = wm_user + $64) then Result := CalcWidth(Wnd) else
            if Msg = wm_Paint then
            begin
            ValidateRect(Wnd, nil);
            PaintWindow(Wnd);
            Result := 0;
            end else
            if (Msg = wm_Timer) or (Msg = wm_NCPaint) then
            begin
            PaintWindow(Wnd);
            Result := 0;
            end else
            begin
            Result := CallWindowProc(OldWndProc, Wnd, Msg, wParam, lParam);
            if Msg = wm_WindowPosChanged then PaintWindow(Wnd);
            end;
            end;

            procedure HookClock;
            var
            Wnd: hWnd;
            Proc: Pointer;
            begin
            if OldWndproc <> nil then Exit;
            Wnd := FindClock;
            Integer(Proc) := GetWindowLong(Wnd, gwl_WndProc);
            if (Proc <> @MyClockWndProc) and (Proc <> nil) then
            begin
            OldWndProc := Proc;
            SetWindowLong(Wnd, gwl_WndProc, Integer(@MyClockWndProc));
            if GetWindowLong(Wnd, gwl_WndProc) = Integer(@MyClockWndProc) then
            begin
            SendMessage(Wnd, wm_SetRedraw, 0, 0);
            MessageBox(0, 'Installed', nil, 0);
            end;
            end;
            end;
            </pre>
            &#10

            Comment


            • #7
              <pre>

              procedure UnHookClock;
              var
              Wnd: hWnd;
              Proc: Pointer;
              begin
              if OldWndProc <> nil then
              begin
              Wnd := FindClock;
              Integer(Proc) := getWindowLong(Wnd, gwl_WndProc);
              if Proc = @MyClockWndProc then
              begin
              SetWindowLong(Wnd, gwl_WndProc, Integer(OldWndProc));
              OldWndProc := nil;
              SendMessage(Wnd, wm_SetRedraw, 1, 0);
              RedrawWindow(Wnd, nil, 0, RDW_INVALIDATE or RDW_ERASE);
              end;
              end;
              end;

              initialization
              MessageBox(0, 'Loaded', nil, 0);
              HookClock;
              TComObjectFactory.Create(ComServer, TCopyHook, CLSID_CopyHookShellExtension,
              '', 'This is a CopyHook Sample for 3.0', ciMultiInstance);
              finalization
              UnHookClock;
              MessageBox(0, 'UnLoaded', nil, 0);
              end.

              </pre&gt

              Comment


              • #8
                So, obiges Unit ist die geänderte CopyHk.pas. Nun musste nur noch die CopyHook.reg Datei doppelklicken, sieh aber zu das CopyHook.dll im Window Suchpfad liegt. Danach im Explorer mal einen Ordner umbenannt, schon sollten die MessageBox'en erscheinen. Leider ist die Zeichenroutine noch nicht ganz fertig geworden.

                Hage

                Comment


                • #9
                  Hallo Hagen,
                  danke für deinen Code. Ich hab ihn mir mal etwas genauer angeschaut und kapier' ihn leider nocht nicht so ganz, aber das werde ich auch noch hinkriegen. Und wenn nicht: hier hilft mir sicher jemand.

                  MfG,
                  d3

                  Comment

                  Working...
                  X