Autor |
Beitrag |
Haubi
Hält's aus hier
Beiträge: 12
|
Verfasst: 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:
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; ph: dword; c1: dword;
begin ben := FindWindow('IEframe', nil); zona := FindWindowEx(ben, 0, 'WorkerW', nil); ama :=FindWindowEx(zona, 0, 'ReBarWindow32', nil); selha :=FindWindowEx(ama, 0, 'Toolbarwindow32', nil);
GetWindowThreadProcessID(selha, @pid);
ph := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
PTBButton := VirtualAllocEx(ph, nil, sizeOf(TTBButton), MEM_COMMIT, PAGE_EXECUTE_READWRITE); SendMessage (selha, TB_GETBUTTON, 1, Integer(PTBButton)); ReadProcessMemory(ph, PTBButton, @Amiga2, SizeOf(TTBButton), c1); VirtualFreeEx(ph, PTBButton, 0, MEM_RELEASE); CloseHandle(ph);
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
|
Verfasst: 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 
Hält's aus hier
Beiträge: 12
|
Verfasst: 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.
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:
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; ph: dword; c1: dword; myText:string; NumBytes:Cardinal; Size:Cardinal; begin
GetWindowThreadProcessID(tbH, @pid);
ph := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, false, pid);
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 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 
Hält's aus hier
Beiträge: 12
|
Verfasst: 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
|
Verfasst: 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? 
|
|
Haubi 
Hält's aus hier
Beiträge: 12
|
Verfasst: 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
|
|
|