Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Harte Nuss: Cursor zu einer bestimmten Farbe springen (https://www.delphipraxis.net/109156-harte-nuss-cursor-zu-einer-bestimmten-farbe-springen.html)

Ajin 25. Feb 2008 13:47


Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Hallo DP!

Stellt euch vor ihr habt ein Fenster mit 3 Symbolen vor euch. Jedes Symbol hat eine eigene Farbe lässt sich innerhalb des Fensters verschieben. Die Anwendung soll nun eines der 3 Symbole mit der Maus erfassen (Drag) und ein kleinwenig verschieben.

Ich weiss nicht genau wie AUTOIT das macht, aber es "findet" z.B. das Sybol mit der Hex-Farbe: 0xFF00FF und bewegt es einen Zentimeter in irgendeine Richtung.

Ich weiss wie ich mit Delphi die Farbe am Mauscursor erkennen kann, aber wie zum Knüppel kann man den Cursor auf eine bestimmte Farbe springen lassen?

Muss ich da den Inhalt des Fensters rastern oder wie macht man das genau? :wiejetzt:

Union 25. Feb 2008 13:54

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Du musst den Canvas des Festers in eine Bitmap schreiben und kannst dann mit Scanline auf die Pixel zugreifen. Beim ersten Treffer hast Du die Position des Pixels mit der gewünschten Vergleichsfarbe gefunden.

Ajin 25. Feb 2008 14:24

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Ich hab mal die Suchfunktion bemüht und einiges zum Thema Scanline entdeckt. Aber "Du musst den Canvas des Festers in eine Bitmap schreiben" -- da habe ich nicht die geringste Ahnung wie ich das anstellen könnte. Sowas hab ich noch nie gemacht :?:

Union 25. Feb 2008 15:14

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Ok, es geht auch direkt mit dem Canvas des Formulars über Pixel. Nur schnell ist das dann nicht.
Delphi-Quellcode:
function FindColorInForm(AForm : TForm; AColor : TColor; var APoint : TPoint) : boolean;
var
   r, c : integer;
begin
   result := False;
   r := 0;
   while (r < AForm.ClientHeight) and not result do
   begin
      c := 0;
      while (c < AForm.ClientWidth) and not result do
      begin
         if AForm.Canvas.Pixels[c, r] = AColor then
         begin
            APoint.X := c;
            APoint.Y := r;
            result := True;
         end;
         inc(c);
      end;
      inc(r);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   pt : TPoint;
begin
   // Zum Test z.B. ein rotes TLabel irgendwo aufs Formular setzen
   if FindColorInForm(self, clRed, pt);
      Showmessage(Format('%d/%d', [pt.X, pt.Y]))
end;

Ajin 25. Feb 2008 15:24

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Das wär schon prima! Nur muss ich statt einer TForm ein Fensterhandle auf die Farbe untersuchen.

Ich hab sowas zusammengeschustert und hing daran bevor dein Post kam:

Delphi-Quellcode:
clientHandle:=FindAWindow('Notepad', '');
canvas:=TCanvas.Create;
try
 if clientHandle=0 then
    ShowMessage('Notepad Handle not found!')
  else
   BringWindowToTop(clientHandle);
   canvas.Handle:=clientHandle;
finally
  canvas.free;
Ich dachte wenn ich das canvas vom fensterhanlde der Anwendung habe könnte ich damit weiter fahren und nach der Farbe suchen.

Kann man FindColorInForm irgendwie umschreiben zu einem FindColorInWindow?

Union 25. Feb 2008 15:53

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Ja das geht. So bekommst Du das Desktopbitmap im Bereich eines Fensters:
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var
   WindowHandle : HWND;
   DC : HDC;
   Rect : TRect;
   Bmp : TBitmap;
begin
   WindowHandle := FindWindow(nil, PChar('Unbenannt - Editor'));
   if WindowHandle > 0 then
   begin
      DC := GetWindowDc(WindowHandle);
      GetWindowRect(WindowHandle, Rect);
      Bmp := TBitmap.Create;
      Bmp.Pixelformat := pf8bit;
      Bmp.Width := Rect.Right - Rect.Left;
      Bmp.Height := Rect.Bottom - Rect.Top;
      BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DC, 0, 0, SRCCOPY);
      ReleaseDc(WindowHandle, DC);
      // Hier dann Funktion zum Durchsuchen des Bitmap aufrufen...
     
      Bmp.Free;
   end;
end;
Dann kanst Du FindColorInFor Funktion in z.b. FindColorInBitmap umschreiben. Die Koordinaten musst Du dann noch umrechnen. Allerdings darf das Fenster nicht durch andere verdeckt sein.

Ajin 26. Feb 2008 09:24

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Danke für die Antwort. Ich tüftel noch bis heute Nachmittag an dem Fall und präsentiere dann entweder meine Lösung oder noch eine Frage.

Derzeit versuche ich gerade einen Farbwert in der Form: 0x80E0FF oder 80E0FF in einen TColor Wert zu ändern.

Delphi-Quellcode:
 Bmp.Canvas.Pixels[c, r] = HexToColor('0x80E0FF')
Dazu gibts aber ne Menge Forenbeiträge, ich arbeite mich mal da durch. :mrgreen:

DP-Maintenance 26. Feb 2008 12:06

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Multimedia" verschoben.
Das ist eine Delphi-Frage. ;)

Neutral General 26. Feb 2008 12:21

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Hi,

Das ist ganz einfach:

Delphi-Quellcode:
Bmp.Canvas.Pixels[c, r] := $80E0FF;
in Delphi beginnen Hex-Zahlen mit einem $-Zeichen.

Gruß
Neutral General

Ajin 26. Feb 2008 12:51

Re: Harte Nuss: Cursor zu einer bestimmten Farbe springen
 
Huhu!

Somit scheint es zu klappen:

Delphi-Quellcode:
procedure TFmain.Button3Click(Sender: TObject);
var
 WindowHandle : HWND;
   DC : HDC;
   Rect : TRect;
   Bmp : TBitmap;
   r, c : integer;
   result:boolean;
begin
  WindowHandle:=FindAWindow('ICQ', '');
  if WindowHandle <> 0 then
  begin
    bsSkinMessage1.MessageDlg('ICQHandle found!',
    mtInformation, [mbOK], 0);
    DC := GetWindowDc(WindowHandle);
    GetWindowRect(WindowHandle, Rect);
    Bmp := TBitmap.Create;
    //Bmp.Pixelformat := pf8bit;
    Bmp.Width := Rect.Right - Rect.Left;
    Bmp.Height := Rect.Bottom - Rect.Top;
    BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DC, 0, 0, SRCCOPY);
    ReleaseDc(WindowHandle, DC);

      // Hier dann Funktion zum Durchsuchen des Bitmap aufrufen...
      bsSkinMessage1.MessageDlg('Searching Bitmap!',
      mtInformation, [mbOK], 0);
      result:=FALSE;
      r := 0;
      while (r < Bmp.Height) and not result do
      begin
      c := 0;
      while (c < Bmp.Width) and not result do
      begin
         if Bmp.Canvas.Pixels[c, r] = RGB(128,224,255) then
//oder mit $HEX ^^
         begin
            showmessage('color found');
            l_x.Caption := IntToStr(c + Rect.left + 10);
            l_y.Caption := IntToStr(r + Rect.Top + 10);
            result := True;
         end;
         inc(c);
      end;
      inc(r);
   end;


      Bmp.Free;
   end
   else
   begin
     bsSkinMessage1.MessageDlg('ICQ Handle not found!',
     mtError, [mbOK], 0);
   end;
end;
Ich danke euch allen für die Hilfestellungen !


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz