Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Anstatt ID den Namen verwenden? (https://www.delphipraxis.net/72223-anstatt-id-den-namen-verwenden.html)

Mirco 27. Jun 2006 11:28


Anstatt ID den Namen verwenden?
 
Hallo :-D
mit dem Beispiel kann ich ein Edit in einem anderen Programm auslesen.
Ich möchte im nächsten Schritt dann auch reinschreiben können.
Aber zunächst einmal habe ich Probleme mit der ID da die sich ja immer ändert.
Kann man stattdessen nicht auch den Editnamen verwenden?
Wenn ja, wie geht das?

Delphi-Quellcode:
procedure TForm1.Button5Click(Sender: TObject);
var
  hWnd, hEdit: cardinal;
  buffer: array[0..1204] of Char;
begin
  hWnd := FindWindow(nil, 'Fax 1.1');

 hEdit := GetDlgItem(hWnd, 788380); // 788380 ID des Edit
  SendMessage(hEdit, WM_GETTEXT, sizeof(buffer), Integer(@buffer));
  ShowMessage(String(buffer));
end;
Viele Grüsse
Mirco

himitsu 27. Jun 2006 12:15

Re: Anstatt ID den Namen verwenden?
 
Wozu erst über 'nen Namen suchen ... wie wäre es mit 'ner Konstante?

Code:
Const [color=#ff0000]MeinEdit[/color] = 788380;

procedure TForm1.Button5Click(Sender: TObject);
var
  hWnd, hEdit: cardinal;
  buffer: array[0..1204] of Char;
begin
  hWnd := FindWindow(nil, 'Fax 1.1');

  hEdit := GetDlgItem(hWnd, [color=#ff0000]MeinEdit[/color]);
  SendMessage(hEdit, WM_GETTEXT, sizeof(buffer), Integer(@buffer));
  ShowMessage(String(buffer));
end;
Vorzeile: den zu suchenden Namen kann man auch falsch schreiben, ebenfalls wie die ID.
Bei der Konstannte gibt es die ID nur einmal, also leicht zu ändern und bei Konstantennamen kann man sich nicht so einfach verschreiben, da dort meißtens der Compiler meckert ^^

Luckie 27. Jun 2006 12:42

Re: Anstatt ID den Namen verwenden?
 
Zitat:

Zitat von Mirco
Aber zunächst einmal habe ich Probleme mit der ID da die sich ja immer ändert.

Die ID ändert sich nicht.

Mirco 28. Jun 2006 14:06

Re: Anstatt ID den Namen verwenden?
 
Hallo,
merkwürdig, ich muss mir das alles nochmal genau ansehen.
Erstmal Danke
Grüße
Mirco

Mirco 29. Jun 2006 10:04

Re: Anstatt ID den Namen verwenden?
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Luckie
Zitat:

Die ID ändert sich nicht.
Hmm, entweder meinst du was anderes mit der ID als ich, ich meine die Controll ID, die ändert sich bei mir bei jedem Neustart des Programms.
Überprüft mit Winspy (Thomas Stutz)
Bzw. bekomme ich den Inhalt ja nicht mehr angezeigt.

Viele Grüsse
Mirco

Mirco 29. Jun 2006 10:19

Re: Anstatt ID den Namen verwenden?
 
@Luckie,
du hast doch recht, in der Combobox steckt noch ein Edit, diese ID verändert sich nie.

@all
Nur wenn ich diese ID angebe kann ich nix mehr auslesen, warum?
Wieso ist da überhaupt ein Edit drinnen?
:wall:

Viele Grüsse
Mirco

Luckie 29. Jun 2006 11:37

Re: Anstatt ID den Namen verwenden?
 
Aha. Ja das ist ein Delphi-Programm mt der VCL geschrieben. Und die VCL vergibt keine IDs (Siehe OI, dort kan man keine vergeben), sondenr die werden zur Laufzeit aus dem Handle generiert. Und wie du siehst, sind Handle und IControlID identisch. Das Edit, was du gefundne hast ist Bestandteil der Combobox und da das Windows ist und Windows in C geschruieen wurde mit einem C Kompiler ohne VCL, hat das Edit eine feste ID, weil sie so vergeben wurde.

Du köntest aber den Klassennanemn nehmen, wenn es denn nur eine Combobox dort gibt.

Mirco 29. Jun 2006 11:52

Re: Anstatt ID den Namen verwenden?
 
*heul*
neee es gibz 7 Comboboxen.
Gruss
Mirco

Christian Seehase 29. Jun 2006 11:55

Re: Anstatt ID den Namen verwenden?
 
Moin Mirco,

dann könntest Du noch versuchen die ComboBox, zusätzlich, über MSDN-Library durchsuchenGetWindowPlacement zu identifizieren.
Die Position wird sich ja wohl nicht ändern.

Mirco 29. Jun 2006 12:11

Re: Anstatt ID den Namen verwenden?
 
Hallo Christian
Also anhand Position die Id rausbekommen?
Ich versteh das grad nicht so ganz.
Mirco

Christian Seehase 29. Jun 2006 12:13

Re: Anstatt ID den Namen verwenden?
 
Moin Mirco,

wenn ich das richtig verstanden habe, so benötigtst Du doch eine bestimmte ComboBox.
Wenn nun die ID nicht eindeutig ist, so könntest Du mittels EnumChildWindows durch alle Bestandteile des Formulares durchgehen, und die Klasse prüfen. Stimmt die Klasse überein, noch die Position des Controls prüfen. Stimmt die mit dem gesuchten überein, den Text auslesen. Evtl. genügt natürlich auch die Prüfung der Position.

Mirco 29. Jun 2006 12:21

Re: Anstatt ID den Namen verwenden?
 
Hallo Christian,
ich hab schonmal folgendes gemacht, bekomme aber immer nur die erste Checkbox zurück.
Bin ich mit dem Beispiel schon auf dem richtigen Weg?
Grüsse Mirco
Delphi-Quellcode:
const
  WinName = 'Fax 1.1';
  WinClass = nil;

implementation

{$R *.dfm}

function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
var
  buffer, desc: array[0..100] of char; // max. 101 Zeichen
begin
  GetClassname(StHandle, buffer, 100); // 100
  GetWindowText(StHandle, desc, 100); // 100
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  hwnd: dword;
begin
  Memo1.clear;
  hwnd := FindWindow(WinClass, WinName);
  if hwnd <> 0 then
  begin
    showmessage(IntToStr(hwnd));
    if (hwnd = 0) then
    begin
      messagebox(0, 'Programm nicht im Speicher!', 'Warning!', 0);
      exit;
    end;
    EnumChildWindows(hwnd, @EnumProc, Integer(Memo1.Lines));
  end;
end;

Jens Schumann 29. Jun 2006 12:31

Re: Anstatt ID den Namen verwenden?
 
Hallo,
probier mal folgendes
Delphi-Quellcode:
function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
var
  buffer, desc: array[0..100] of char; // max. 101 Zeichen
begin
  GetClassname(StHandle, buffer, 100); // 100 
  GetWindowText(StHandle, desc, 100); // 100 
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
end;

Christian Seehase 29. Jun 2006 13:04

Re: Anstatt ID den Namen verwenden?
 
Moin Mirco,

Du hast in der EnumProc eine wichtige Zeile vergessen:

Delphi-Quellcode:
Result := true;
Ich denke mal, dass Dir der Compiler auch ein Warning ausgegeben hat, dass der Rückgabewert unbestimmt ist.
Aller Voraussicht nach ist der Wert von Result gleich false, so dass nach dem ersten gefundenen Control abgebrochen wird.

BTW:
Korrekter als Boolean ist Longbool als Rückgabewert der Funktion.

Palando 29. Jun 2006 13:27

Re: Anstatt ID den Namen verwenden?
 
Zitat:

Zitat von Christian Seehase
Korrekter als Boolean ist Longbool als Rückgabewert der Funktion.


Wieso das? Wo liegt der Unterschied?

Christian Seehase 29. Jun 2006 13:46

Re: Anstatt ID den Namen verwenden?
 
Moin Markus,

BOOL ist ein 32 Bit grosser Rückgabewert, genauso wie Longbool, wohingegen boolean nur ein Byte gross ist.
Ersatzweise kann man auch BOOL nehmen (in der Windows.pas ist BOOL als Longbool deklariert).

Je nachdem, welche Windows-Headerdatei man heranzieht, ist BOOL als int (windef.h) oder long (wtypes.h) deklariert.
Beide Typen entsprechen dem integer in Delphi.

Palando 29. Jun 2006 14:25

Re: Anstatt ID den Namen verwenden?
 
Ahja.

Danke, wieder was gelernt :)

Mirco 29. Jun 2006 15:43

Re: Anstatt ID den Namen verwenden?
 
Hallo
Danke für eure Antworten.
Ich hab nun folgendes übernommen, obwohl ich die Änderung nicht verstanden habe:
Delphi-Quellcode:
function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
var
  buffer, desc: array[0..100] of char; // max. 101 Zeichen
begin
  GetClassname(StHandle, buffer, 100); // 100
  GetWindowText(StHandle, desc, 100); // 100
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
  Result := true;
end;
Damit bekomm ich nun die einzelnen Komponenten inkl. ID angezeigt, leider wird der Text meiner Combobox nicht ausgelesen, woran kann das liegen?


Ist Result Longbool?

Viele Grüsse
Mirco

Christian Seehase 29. Jun 2006 16:02

Re: Anstatt ID den Namen verwenden?
 
Moin Mirco,

da es sich um ein Control handelt, dass zu einem anderen Prozess gehört, solltest Du mal
Delphi-Quellcode:
SendMessage(StHandle,WM_GETTEXT,101,lParam(@desc[1]);
nehmen statt GetWindowText.

Vielleicht hilft das schon.

[EDIT]
Zitat:

Zitat von Mirco
Ist Result Longbool?

ist es bei Dir nicht, sollte es aber sein, da die Callback-Funktion von EnumChildWindows als Rückgabewert BOOL erwartet.
[/EDIT]

Mirco 29. Jun 2006 16:16

Re: Anstatt ID den Namen verwenden?
 
Hallo Christian,

nun klappt es mit dem Text auslesen.
Vielen Dank, ich werde mit Sicherheit noch einige Zeit brauchen bis ich das alles verstanden haben, aber es ist echt ein verdammt spannendes Thema.

ich hab das jetzt so gemacht.
Delphi-Quellcode:
var
  Result:Longbool;
Viele Grüsse und vielen Dank an alle die mitgedacht haben.
Mirco

Christian Seehase 29. Jun 2006 17:01

Re: Anstatt ID den Namen verwenden?
 
Moin Mirco,

Result ist eine Variable, die der Compiler implizit zur Verfügung stellt, wenn Du eine Funktion deklarierst.
Sie hat den Typ des Rückgabewertes der Funktion.

Um den Typ zu ändern, müsstest Du also die Deklaration der Funktion ändern, und keine Variable mit diesem Namen deklarieren:

Code:
function EnumProc(StHandle: HWND; lines: TStrings): [b]Longbool[/b]; stdcall;

// oder

function EnumProc(StHandle: HWND; lines: TStrings): [b]BOOL[/b]; stdcall;

Mirco 29. Jun 2006 17:48

Re: Anstatt ID den Namen verwenden?
 
Okay, danke.
Mirco

capo 12. Jul 2006 21:46

Re: Anstatt ID den Namen verwenden?
 
hallo

ich habe noch eine frage zum folgenden beispiel:

Delphi-Quellcode:
function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
var
  buffer, desc: array[0..100] of char; // max. 101 Zeichen
begin
  GetClassname(StHandle, buffer, 100); // 100
  GetWindowText(StHandle, desc, 100); // 100
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
  Result := true;
end;
und zwar hierzu
Delphi-Quellcode:
  buffer, desc: array[0..100] of char; // max. 101 Zeichen
ich muss viel mehr text auslesen, habe schon alles mögliche versucht, die zahl erhöhen anderes array (obwohl ich mit den arrays bestimmt fehler gemacht habe).
bekomme immer nur eine bestimmte menge angezeigt, nie alles.


capo

3_of_8 12. Jul 2006 21:59

Re: Anstatt ID den Namen verwenden?
 
Delphi-Quellcode:
function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
const
  MAXLENGTH: Integer = 200;
var
  buffer, desc: array[0..MAXLENGTH] of char;
begin
  GetClassname(StHandle, buffer, MAXLENGTH);
  GetWindowText(StHandle, desc, MAXLENGTH);
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
  Result := true;
end;

himitsu 12. Jul 2006 22:17

Re: Anstatt ID den Namen verwenden?
 
Code:
function EnumProc(StHandle: HWND; lines: TStrings): longbool; stdcall;
var
  buffer: array[0..100] of char;
  [b]desc: array[0..1000] of char;[/b]
begin
  GetClassname(StHandle, buffer, [b]SizeOf(buffer)[/b]);
  GetWindowText(StHandle, desc, [b]SizeOf(dest)[/b]);
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
  Result := true;
end;

Zitat:

Zitat von capo
und zwar hierzu
Delphi-Quellcode:
  buffer, desc: array[0..100] of char; // max. 101 Zeichen

max. 100 Zeichen :warn:

also 100 Zeichen plus die abschließende #0 :zwinker:


[add]
@3_of_8:
entweder
Code:
buffer, desc: array[0..MAXLENGTH[b] - 1[/b]]; of char;
oder
Code:
GetClassname(StHandle, buffer, MAXLENGTH[b] + 1[/b]);

capo 12. Jul 2006 22:36

Re: Anstatt ID den Namen verwenden?
 
hallo
danke für eure antworten,interssiert mich auch.
:-D :-D capo

Mirco 15. Jul 2006 17:12

Re: Anstatt ID den Namen verwenden?
 
ich verwende das nun so

Delphi-Quellcode:
function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
const
  MAXLENGTH: Integer = 200;
var
buffer, desc: array[0..MAXLENGTH - 1]; of char;
begin
   GetClassname(StHandle, buffer, MAXLENGTH + 1);
  GetWindowText(StHandle, desc, MAXLENGTH);
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
  Result := true;
end;
bekomme eine Fehlermeldung:
Zitat:

[Fehler] Unit1.pas(182): Konstantenausdruck erwartet
:wall:

grüße, Mirco

Mirco 16. Jul 2006 22:37

Re: Anstatt ID den Namen verwenden?
 
Hallo,
kann mal jemand was dazu sagen, wäre echt schöööön.
Grüsse
Mirco

Hawkeye219 16. Jul 2006 22:54

Re: Anstatt ID den Namen verwenden?
 
Hallo Mirco,

die Syntaxfehler kannst du so beheben:

Delphi-Quellcode:
function EnumProc(StHandle: HWND; lines: TStrings): boolean; stdcall;
const
  MAXLENGTH = 200; // <-- korrigiert
var
buffer, desc: array[0..MAXLENGTH - 1] of char; // <-- korrigiert
begin
   GetClassname(StHandle, buffer, MAXLENGTH + 1);
  GetWindowText(StHandle, desc, MAXLENGTH);
  lines.add(format('ID: %d, Class: %s, Text: %s', [GetDlgCtrlID(StHandle), buffer, desc]));
  EnumChildWindows(StHandle, @EnumProc, Integer(Lines));
  Result := true;
end;
Statische Arrays kann man nicht mit einer initialisierten Variablen dimensionieren. Das überflüssige Semikolon war wohl nur ein Schreibfehler.

Gruß Hawkeye

Mirco 30. Jul 2006 18:33

Re: Anstatt ID den Namen verwenden?
 
Hallo und vielen Dank.
Grüsse Mirco


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:50 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