Autor Beitrag
Haubi
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Di 14.09.04 12:38 
Hallo zusammen.

Für eine CBT Anwendung brauche ich die Möglichkeit den Text des angeklickten Menüpunktes auszulesen. (z.B. Windows Explorer, Word, etc.). Das mit dem Mousehook hab ich - dank Assarbad's Anleitung - soweit hinbekommen und ich bekomme auch mit, das auf ein Menü (hier: ToolbarWindow32) geklickt wurde.

Mein Ansatz ist, dass ich mit "SendMessage" und "tb_ButtonCount" die Anzahl der Menüpunkte herausfinde, was auch klappt und dann mit "SendMessage" und "tb_GetButtonInfo" an die Eigenschaften se Buttons kommen möchte, was nicht klappt.
"tb_GetButtonInfo" schlägt jedesmal fehl (Rückgabewert= -1).

Ich habe dann im Internet was gefunden, mit der Message "tb_GetButton", hier der Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
var
  ben, zona, ama, selha: THandle;
  ListView: hWnd;
  PTBButton: ^TTBButton;
  Amiga2: TTBButton;
  pid: dword;  // process ID
  ph: dword;  // process handle
  c1: dword;  // dummy variable


begin
  ben := FindWindow('IEframe'nil);
  zona := FindWindowEx(ben, 0'WorkerW'nil);
  ama :=FindWindowEx(zona, 0'ReBarWindow32'nil);
  selha :=FindWindowEx(ama, 0'Toolbarwindow32'nil);

  // ask the process ID of the other process
  GetWindowThreadProcessID(selha, @pid);

  // open the other process
  ph := OpenProcess(PROCESS_ALL_ACCESS, false, pid);

  // allocate memory in the other process
  PTBButton := VirtualAllocEx(ph, nil, sizeOf(TTBButton), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  SendMessage (selha, TB_GETBUTTON, 1, Integer(PTBButton));
  // read the item back from the other process

  ReadProcessMemory(ph, PTBButton, @Amiga2, SizeOf(TTBButton), c1);
  // free the memory of the other process
  
  VirtualFreeEx(ph, PTBButton, 0, MEM_RELEASE);
  // close handle
  CloseHandle(ph);

  // now do whatever you please with Amiga2

end;


Laut Api-Hilfe bekommt man über Amiga2.iString einen Pointer auf den Text.
Amiga2.iString ist laut Definition Integer un bekomme auch eine Wert zurück.
Ich weiss aber nicht wie ich jetzt weitermachen soll, um an den Text zu kommen.

Im voraus schon einmal vielen Dank für eure Bemühungen

Haubi
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 14.09.04 13:02 
Hier der Grund warum es nicht geht und wie du es lösen kannst: www.delphi-forum.de/....php?p=170671#170671
Die Toolbar ist auch eine neues Win32 Steuerelement.
Haubi Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Di 14.09.04 16:11 
Hallo Luckie,

Ich hab mir das mal angeschaut und hab auch schon einen Achtungserfolg erzielt.
Ich hole mir über folgenden Code das Handle und den Namen des unter derm Cursor liegenden Objekts.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
GetCursorPos(pt);
hw := WindowFromPoint(pt);

GetClassName(hw, chrN, SizeOf(chrN));
GetWindowText(hw, chrN, SizeOf(chrN));


Das klappt auch. Ich gebe dann das Handle an folgende Funktion, mit dem abgewandelten Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
function TForm1.ToolbarAuslesen(tbH:HWND; itin:integer):String;
var

  MemLocal:Pointer;
  MemRemote:Pointer;

  pid: dword;  // process ID
  ph: dword;  // process handle
  c1: dword;  // dummy variable
  myText:string;
  NumBytes:Cardinal;
  Size:Cardinal;
  
begin

  // ask the process ID of the other process
  GetWindowThreadProcessID(tbH, @pid);

  // open the other process
  ph := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, false, pid);

  // allocate memory in the other process
  Size := SizeOf(TTBButtonInfo) + SizeOf(Char)*MAX_PATH + 1;

  MemRemote := VirtualAllocEx(ph, nil, sizeOf(TTBButtonInfo), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
  MemLocal :=  VirtualAlloc(nil, SizeOf(TTBButtonInfo), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);

  if Assigned(MemLocal) and Assigned(MemRemote) then
  try
    ZeroMemory(MemLocal, SizeOf(TTBButtonInfo));

    with PTBButtoninfo(MemLocal)^ do
    begin
     dwMask := TBIF_TEXT;
     cbSize := SizeOf(TTBButtonInfo);
     pszText := LPTSTR(Cardinal(MemRemote)+Cardinal(SizeOf(TBButtonInfo)));
     cchText := MAX_PATH;
    end;

    NumBytes := 0;

    WriteProcessMemory(ph, MemRemote, MemLocal, Size, NumBytes);
    SendMessage(tbH, TB_GETBUTTONINFO, itin, LPARAM(MemRemote));
    ReadProcessMemory(ph, MemRemote, MemLocal, Size, NumBytes);

    Result := string(PChar(Cardinal(MemLocal)+Cardinal(SizeOf(TTBButtonInfo))));

   except
     //Alle Exception ignorieren
     showmessage('Exception');
   end;

   if Assigned(MemRemote) then
     VirtualFreeEx(ph, MemRemote, 0, MEM_RELEASE);
   if Assigned(MemLocal) then
     VirtualFree(MemLocal, 0, MEM_RELEASE);

   CloseHandle(ph);

end;


Ich kann damit beispielsweise die Knöpfe der Link-Symbolleiste im Internetexplorer auslesen. Über "GetWindowText" bekomm ich auch den Namen der Leiste. Den Namen bekomme ich z.B. auch für die Google-Toolbar, dort kann ich aber keine Knöpfe mehr auslesen.

Bei Menüs oder anderen Symbolleisten geht aber gar nix mehr.

Vielleicht bin ich aber auch komplett auf dem falschen Dampfer. Über "itin" übergebe ich den Index des Buttons (Denke ich jedenfalls), momentan ist das eine Schleife (0-15).

Ich hab auch keinen Möglichkeit entdeckt, wie ich herausbekomme, welcher Knopf im Objekt ToolbarWindow32 gedrückt wurden ist.

Haubi
Haubi Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Di 14.09.04 19:51 
So,
hab jetzt einen meiner Fehler herausgefunden. Ich hab die Falchen Id für die Buttons verwendet.
Ich hol mir jetzt zuerst die Eigenschaft idCommand, um mir dann für diesen über die Funktion ToolbarAuslesen den Text zu holen.

Was ich allerdings noch nicht hinbekommen hab, ist herauszufinden welcher Button gedrückt wurde.

Haubi
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 14.09.04 23:03 
Dazu müsstest du wohl die Fensterprozedur umbiegen. darf man mal fragen, was das geben soll, wenn es fertig ist? :gruebel:
Haubi Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Di 14.09.04 23:07 
Ich muss immer wieder Abläufe Dokumentieren, eist in den Office Programmen. Ich möchte mit dem Programm meine Arbeitsschritte teilweise aufnehmen und mir so die Arbeit erleichtern. So nach dem Motto:

"Klicken Sie im Menü Datei auf den Menüpunkt Eigenschaften", usw.

Das will ich damit machen.

Habs mit TB_IsButtonPressed hinbekommen. Bin jetzt bei "Klicken Sie auf Datei" und muss jetzt wegen "und dann auf Eigenschaften" noch schauen.

Haubi