[Вопрос] Delphi, работа с хэндлами окон

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ex3me, 19 Jul 2009.

  1. ex3me

    ex3me Member

    Joined:
    7 Jan 2009
    Messages:
    0
    Likes Received:
    63
    Reputations:
    0
    Имеется программа с такой вот "структурой хэндлов"
    [​IMG]
    Как конкретно для такого примера правильно получить хэндл этой самой кнопки "Continue >>>"?

    Перепробовал массу вариантов с FindWindow, FindWindowEx, gw_HWNDNext, gw_CHILD - тщетно. Возможно что-то делаю неправильно.

    Пробовал получить текст из всех окон:

    Code:
    var
      Transfer : HWND;
      TransWnd : array[1..42] of HWND;
       d:string[255];
    
    procedure GetTransHandle();
    var
      i: integer;
    begin
      Transfer := FindWindow(nil, PChar('Hard Disk Wipe Tool 2.35 build 1178'));
      TransWnd[1] := GetWindow(Transfer, GW_CHILD);
      for i := 2 to 10 do
      begin
        TransWnd[i] := GetWindow(TransWnd[i - 1], GW_HWNDNEXT);
        setLength(d,sendMessage(TransWnd[i],WM_GETTEXTLENGTH,0,0)+1);
        SendMessage(TransWnd[i],WM_GETTEXT, wParam(length(d)),lParam(@d[1]));
        writeln(d);
      end;
    end;
    
    begin
    GetTransHandle();
    readln;
    end.
    Выдало сплошную пустоту.

    Есть какие-нибудь идеи?
     
  2. Scripter

    Scripter Member

    Joined:
    3 Sep 2008
    Messages:
    142
    Likes Received:
    95
    Reputations:
    6
    writeln(d) readln что и куда читает я не пойму...

    попробуй заменить на:

    Code:
    Memo1.Lines.Add(d);
    или
    Code:
    var
    f:System.Text;
    begin
    AssignFile(f,'C:\lol.txt');
    Rewrite(f);
    WriteLn(f, d);
    CloseFile(f);
    end;
    
    у тебя процедура ничего не выводит procedure GetTransHandle(пусто);

    begin
    GetTransHandle(); //пустота
    readln; //куда-то что-то читаем
    end.

    эт только догадки, может чем поможет
     
  3. ex3me

    ex3me Member

    Joined:
    7 Jan 2009
    Messages:
    0
    Likes Received:
    63
    Reputations:
    0
    Нет, к сожалению это не то совсем. Нигде там пустот не имеется, и код 200% рабочий. Вопрос заключается в том, как добраться именно к той кнопке, хендл которой изображен на рисунке структуры

    З.Ы. Процедура на то и процедура, что она может не принимать никаких параметров и в отличие от функции не возвращает из себя какое-либо значение. Перечитай "Основы процедурного программирования на Delphi"
     
  4. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    289
    Reputations:
    43
    получить хэндл кнопки?
    PHP:
    FindWindowEx(parentHwnd0'TButton''Continue >>>');
    parentHwnd - хэндл родителя, думаю его получить это раз плюнуть.
    ... На всякий случай FindWindow

    Получить текст всех элементов?
    PHP:
    EnumChildWindow
     
    #4 W!z@rD, 19 Jul 2009
    Last edited: 19 Jul 2009
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,704
    Likes Received:
    1,222
    Reputations:
    455
    заморачиваться над таким? Быстрее перечислить элементы родительноского окна.
    Как написал W!z@rD заюзать функции EnumChildWindows

    Code:
    var
     ButtonHandle:THandle;
    
    function EnumChildProc(wnd:hwnd; lParam:integer):boolean; stdcall;
    var
     buf:array[0..255] of char;
    begin
     GetWindowText(wnd, buf, 255);
     if Lstrcmpi('Continue >>>', buf) = 0 then
      begin
       ButtonHandle := wnd;
       result := false;
      end
     else
      begin
       ButtonHandle := 0;
       result := true;
      end;
    end;
    
    
    procedure TForm1.Button2Click(Sender: TObject);
    var
     WindowHandle:THandle;
    begin
     WindowHandle := FindWindow(nil,'Form1'); // тут свои параметры укажиш
     if WindowHandle <> 0 then
     begin
      EnumChildWindows(WindowHandle, @EnumChildProc, 0);
      ShowMessage('Button Handle = '+inttohex(ButtonHandle, 8));
     end;
    end;
    
     
  6. ex3me

    ex3me Member

    Joined:
    7 Jan 2009
    Messages:
    0
    Likes Received:
    63
    Reputations:
    0
    W!z@rD, slesh, спасибо, но увы - история та же. Button Handle = 000000 конкретно в последнем примере. Самое интересное что Autoit Window Info показывает адекватно хендл энтой кнопки, и если бы хендлы были статичные - было бы намного проще =))) Придется видимо искать другие варианты =\
     
  7. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,704
    Likes Received:
    1,222
    Reputations:
    455
    я сделал подобного вида форму, и нормально нашло всё. может там кнопка чуть по другому называется. попробуй запустить с таким кодом и поискать кнопку в списке.
    Также может у тебя вообще окно не находится
    Code:
    function EnumChildProc(wnd:hwnd; lParam:integer):boolean; stdcall;
    var
     buf:array[0..255] of char;
    begin
     GetWindowText(wnd, buf, 255);
     form1.memo1.lines.add(inttohex(wnd, 8)+' '+buf);
     result := true;
    end;
    
    
     
  8. МongBa†

    МongBa† Member

    Joined:
    12 May 2009
    Messages:
    66
    Likes Received:
    12
    Reputations:
    0
    То ли меня с просони глючит, то ли х3..

    Поставил ту же версию вайпа:
    Code:
    000614CE     TFmMain     Hard Disk Wipe Tool 2.35 build 1178
    TFmMain а не TFmChoose

    Code:
    var wnd:HWND;
        b1,b2:array[0..255] of char;
    begin
     wnd:=FindWindow(nil,PChar('Hard Disk Wipe Tool 2.35 build 1178'));
     if wnd<>0 then
     begin
      GetClassName(wnd,b1,255);
      GetWindowText(wnd, b2, 255);
      Memo1.Lines.Add(inttohex(wnd,8)+'   '+b1+'   '+b2);
     end;
    И если поковырять глубже - структура похожа, но не оно..
    Code:
    00180DE0   TFmMain   Hard Disk Wipe Tool 2.35 build 1178
    ---002611B8   TPanel   
    ------00371188   TPanel   
    ------00171238   TPageControl   
    ---------0010126A   TTabSheet   Device details
    ---------0028117E   TTabSheet   WIPE
    ---001A1212   TStatusBar   
    ---000E1202   TPanel   
    ---0016128C   TPanel  
    З.Ы. ex3me , каким софтом смотрел структуру хендлов? тоже похожим страдаю...
     
  9. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    2 МongBa† эт Spy++ от мелкомягкого.
    щас найду лабу свою...

    [​IMG]
    Качаем проект delphi 7

    ну думаю в комментариях не нуждается, все видно на картинке. посмотрите по коду че и как думаю разберетеся.
     
    _________________________
    1 person likes this.
  10. ex3me

    ex3me Member

    Joined:
    7 Jan 2009
    Messages:
    0
    Likes Received:
    63
    Reputations:
    0
    slesh, мои бока, сорри, окно не то было... На кнопку нажал
    МongBa†, ты прав. Не то окно было!
    Gar|k, мерси, благодаря твоему творению нашел и нажал на кнопку!

    Теперь вопрос нумбер два :D :

    Как нажать на TTabSheet с Caption "WIPE" (хендл нужной мне кнопки появляется только когда клацаю по этому табшиту)?
    [​IMG]
    Собсна пробовал такими способами:
    Code:
    Sendmessage(h,WM_LBUTTONDOWN,MK_LBUTTON,MakeLParam(1,1)); // нажать
    Sendmessage(h,WM_LBUTTONUP,MK_LBUTTON,MakeLParam(1,1));   // и отпустить
    
    Code:
    if (GetWindowText(hw, wText, 255) > 0) then
          if (wText='WIPE') then begin
             SendMessage(hw,WM_IME_KEYDOWN,VK_SPACE,0);
             SendMessage(hw,WM_IME_KEYUP,VK_SPACE,0);
    
    Скажу сразу, что на TButton эти оба способа работают, а вот TTabSheet не хочет нажиматься. Плюс к этому: моя задача заключается в том, чтобы нажать TTabSheet когда окно скрыто, но если это неосуществимо, то хотябы подскажите, пожалуйста, как можно словить чтоли координаты и быстро ткнуть мышкой на этот табшит =\
     
  11. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    289
    Reputations:
    43
    ShowWindow or SetActiveWindow, window API try it
     
Loading...