Uchwyt przycisku ToolBar

0

Pragne komunikować się z pewną aplikacją. Moim celem jest klikniecie przycisku ToolBar'a

Z tego co jednak wiem i widze: przyciski ToolBar'a nie mają uchwytów. W jaki sposób mogę więc się z nimi skomunikowac?

uchwyt:= FindWindow(nil, 'aplikacja_do_komunikacji')); // Kod sprawdzony, 100% poprawny
uchwyt:= FindWindowEx(uchwyt, 0, 'ToolBarWindow32', nil); //To dokladnie ten toolbar. Sprawdzone 100%

// i co dalej? :(
1

Poczytaj: http://msdn.microsoft.com/pl-pl/library/windows/desktop/bb787389(v=vs.85).aspx a tak w ogółe na prawdę ciężko najpierw: http://bit.ly/11Jbfgu - chyba, że to już próbowałeś, ale myślę, że Użytkownik, który jest od tak dawna na forum, wspomniał by o tym co już próbował. I że w ogóle powinien próbować zanim napisze z czymś na forum.

0

Dadam tylko że wcześniej trzeba pobrać ID buttona np. za pomocą TB_GETBUTTON

0

Moglbym prosic o jakiś przyklad :( Probowalem juz wczesniej z tym TB_PRESSBUTTON. Angielski znam - słabo, a z google translator niewiele rozumiem.

Aby przetestowac(znajejsc) prawidlowy id sprobowalem nastepujacej petli

for i := 0 to 10 do
  for j := 0 to 10 do
    SendMessage(uchwyt, TB_PRESSBUTTON, i, j); // lipa, zaden przycisk nie zostal klikniety
0

@bronex: Ty jako doświadczony Użytkownik na forum, powinieneś umieć szukać. A przede wszystkim czytać co również @kAzek napisał. Taka pętla Ci nic nie da, bo zmienna J i jej zawartosć będzie dla aplikacji z d... to raz. Dwa nie wiadomo czy będą buttony o tak niskim Id. Trzeba było spojrzeć na MSDN. Pogooglować. Mi się udało z google znależć kod bazujący na zmiennej Amiga2 i kod działa. Warunek jest taki aby właśnie używać takiej metody z VirtualAllocEx, ponieważ inaczej dostaniemy kod błędu "Odmowa dostępu".

//...
uses
  CommCtrl;

var
  ControlCnt : Byte;
  WinrarToolBarH : HWND;

function EnumChildWinProc(AHandle : HWND) : boolean; stdcall;
var
  ControlName, ControlText : array[0..255] of Char;
begin
  Result := True;
  GetClassName(AHandle, ControlName, SizeOf(ControlName));
  SendMessage(AHandle, WM_GETTEXT, SizeOf(ControlText), integer(@ControlText));
  with Form1 do
  begin
    ControlCnt := ControlCnt + 1;
    if ControlCnt = 6 then
    begin
      WinrarToolBarH := AHandle;
      Result := False;
    end;
    Memo1.Lines.Add('$' + IntToHex(AHandle, 1) + ' = ' + ControlName + ' = "' + ControlText + '"');
  end;
end;

procedure TForm1.Button1Click(Sender : TObject);
var
  AppH : HWND;
  ProcessH : THandle;
  ResBtn : TTBButton;
  BytesRead, Pid : DWORD;
  PtrButton : ^TTBButton;
begin
  Memo1.Clear;
  ControlCnt := 0;
  AppH := FindWindow('WinRarWindow', nil);
  EnumChildWindows(AppH, @EnumChildWinProc, 0);
  GetWindowThreadProcessID(WinrarToolBarH, @Pid);
  ProcessH := OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
  PtrButton := VirtualAllocEx(ProcessH, nil, SizeOf(TTBButton), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  SendMessage(WinrarToolBarH, TB_GETBUTTON, 0, Integer(Pointer(PtrButton)));
  ReadProcessMemory(ProcessH, PtrButton, @ResBtn, SizeOf(TTBButton), BytesRead);
  VirtualFreeEx(ProcessH, PtrButton, 0, MEM_RELEASE);
  CloseHandle(ProcessH);
  SendMessage(WinrarToolBarH, WM_COMMAND, ResBtn.idCommand, 0);
end;

Przykładowy kod jest dla WinRAR'a i działa liczba po parametrze TB_GETBUTTON możesz ustawić na wyższą (maksymalnie do ilości buttonów na toolbarze minus - 1). Co w przypadku WinRAR'a, na którym ja testowałem, l;czba wynosi 10. A i niestety TB_PRESSBUTTON nie działało. Być może w WinRAR'ze obsługa buttonów jest zrobiona tylko przez WM_COMMAND. Bo robienie przykładowo poniższego kodu nie skutkowało reakcją, a błędów po GerlastError nie było. Może z tym @kAzek albo ktoś inny tutaj, będzie umiał naprowadzić.

  PostMessage(WinrarToolBarH, TB_PRESSBUTTON, ResBtn.idCommand, MakeLParam(1, 0));
  PostMessage(WinrarToolBarH, TB_PRESSBUTTON, ResBtn.idCommand, MakeLParam(0, 0));

1 użytkowników online, w tym zalogowanych: 0, gości: 1