Конференция "WinAPI" » однозначное определение 2+ окон с одним заголовком [D7, WinXP]
 
  • Anklav (20.01.09 10:45) [0]
    Как определить однозначно окно если их 4 и они имеют одно название и отправить этому окну сообщение на эмуляцию кнопки
    Процедура эмуляции кнопки
    procedure EmulateKey(Wnd: HWND; VKey: Integer);
    asm
     push 0
     push edx
     push 0101H //WM_KEYUP
     push eax
     push 0
     push edx
     push 0100H //WM_KEYDOWN
     push eax
     call PostMessage
     call PostMessage
    end;

    // Пример использования:
    EmulateKey(Edit1.Handle, VK_RETURN);

    Помогите пожалуйста кто может
  • Eraser © (20.01.09 11:50) [1]
    на основании чего принимается решение, какому именно окну надо отправлять сообщение?
  • Anatoly Podgoretsky © (20.01.09 13:06) [2]
    > Anklav  (20.01.2009 10:45:00)  [0]

    Wnd: HWND; одназначно определяет окно.
  • Anklav (20.01.09 13:18) [3]
    по нажатию кнопки на пример у меня 4 окна (все называются "Lineage II")
    при нажатии Q чтобы происходила эмуляция для первого окна кнопки F1,
    при нажатии A эмуляция для второго окна кнопки F1 и т. д.
  • Anklav (20.01.09 13:21) [4]

    > Wnd: HWND; одназначно определяет окно.


    Названия окон одинаковы и он будет производить эмуляцию во всех окнах с таким заголовком
  • Anatoly Podgoretsky © (20.01.09 13:48) [5]
    > Anklav  (20.01.2009 13:21:04)  [4]

    Откуда ты взял эти окна?
    Может надо при создании/появление запоминать их хендлы. Что кроме загововка есть еще у укон.
  • Anklav (20.01.09 14:52) [6]

    > Откуда ты взял эти окна?
    > Может надо при создании/появление запоминать их хендлы.
    > Что кроме загововка есть еще у укон.

    Окна запускаются обычно, с ехешника.
    Если при появлении/создании их отпределать то какаим образом это сделать?
  • Сергей М. © (20.01.09 15:14) [7]

    > Anklav   (20.01.09 14:52) [6]


    Ты хочешь сказать, что интересующие тебя окна абсолютно ничем не отличаются ?
    Тогда какая разница, в какое из этих окон послать сообщения ?
  • Anklav (20.01.09 15:23) [8]

    > Ты хочешь сказать, что интересующие тебя окна абсолютно
    > ничем не отличаются ?
    > Тогда какая разница, в какое из этих окон послать сообщения
    > ?

    Я и хочу чтобы конкретному окну из этих 4х (например первому по времени запуска) отправлялась эмуляция кнопки F1 по нажатию клавиши Q. А второму окну тот же F1 но по нажитию  клавиши A.
    Все окна загружены последовательно.
  • Сергей М. © (20.01.09 15:25) [9]
    Т.е. единственное их отличие - это порядок создания, а больше окна НИЧЕМ не отличаются ?
  • Leonid Troyanovsky © (20.01.09 16:21) [10]

    > Anklav   (20.01.09 14:52) [6]

    > Если при появлении/создании их отпределать то какаим образом
    > это сделать?

    EnumThreadWindows after WaitForInputIdle, если, конечно,
    окна создаются первичным потоком.
    В противном случае - EnumWindows with GetWindowThreadProcessId.

    А после определения нужного хендла надо SetWindowsHookEx
    на создавший его поток, дабы отследить момент разрушения окна.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (20.01.09 16:23) [11]

    > Anklav   (20.01.09 10:45)  

    > Процедура эмуляции кнопки

    В печь ее.

    --
    Regards, LVT.
  • Anklav (20.01.09 20:01) [12]

    > Leonid Troyanovsky

    Спасибо огромное! Буду проверять.
  • Anklav (20.01.09 20:10) [13]

    > Т.е. единственное их отличие - это порядок создания, а больше
    > окна НИЧЕМ не отличаются ?

    Я запускаю 4 раза подряд 1 ехешник с игрой. Запускаются 4 окна с одинаковым названием.  И нужно их как-то разделить и определенному окну в зависимости о нажатия определенной кнопки отпралять определенное сообщение.
    Проблема в том что я незнаю как их разделить, пробовал переименовать поочереди чтобы были разные заголовки, но название заголовка воозвращяется стандартное. (И вообще я пока нуб по Делфи...)
  • Anklav (20.01.09 20:13) [14]
    При отправлении сообщения окну оно не должно становиться активным
  • Leonid Troyanovsky © (20.01.09 20:32) [15]

    > Anklav   (20.01.09 20:13) [14]

    > При отправлении сообщения окну оно не должно становиться
    > активным

    Смело полагай, что этот пункт уже выполнен.

    --
    Regards, LVT.
  • Сергей М. © (20.01.09 20:36) [16]

    > Я запускаю


    Значит после очередного N-го запуска ты волен и можешь получить хэндл нового окна и сохранить как N-й хэндл.
  • Сергей М. © (20.01.09 20:37) [17]

    > я пока нуб


    Нуб - это звучит гордо ?
  • Anklav (20.01.09 21:42) [18]

    > Нуб - это звучит гордо ?

    Нуб это новичок)
    а как этот хэндл получить от всех окон и отправлять сообщения конкретным окнам по этоим хэндл'ам?
  • Сергей М. © (21.01.09 08:26) [19]

    > как этот хэндл получить от всех окон


    см. [10]


    > отправлять сообщения конкретным окнам


    Send/PostMessage
  • Anklav (21.01.09 09:21) [20]
    Буду пробовать, спасибо всем )
  • Anklav (21.01.09 19:51) [21]
    если я запускаю все окна с одного ехешника то поток у меня так же один?

    EnumThreadWindows
    (
    DWORD dwThreadId, // идентификатор потока <--- искать через функцию GetWindowThreadProcessId?
    WNDENUMPROC lpfn, // указатель на функцию возврата <-- какую функцию использовать?
    LPARAM lParam // значение, определяемое прикладной программой
    );

    а значение этой функции использовать чтобы отправлять сообщения нужному окну?
  • Сергей М. © (21.01.09 21:08) [22]

    > если я запускаю  ...окна


    .. то ты, наверно, пользуешься при этом функцией ZapuskayuOkna() ?
  • Anklav (21.01.09 21:54) [23]

    >
    > .. то ты, наверно, пользуешься при этом функцией ZapuskayuOkna()
    > ?

    впринципе если написать такую функцию то можно, а так нет не пользуюсь.
  • Anklav (21.01.09 22:57) [24]
    аа все понял.. сори жестко тупил.
  • Германн © (22.01.09 01:12) [25]

    > если я запускаю все окна с одного ехешника

    Сомневаюсь я однако, что сей вопрос имеет право находиться в конференции WinAPI. Бо если б автор создавал окна функциями CreateWindow(Ex), он бы таких вопросов бы не задавал.
  • sambellamy © (24.01.09 17:00) [26]
    вот класс выдранный из кода, позволяет найти все окна определённого класса,
    давно делал, но суть понять можно, перебираем все окна с помощью ф. GetWindow, собираем информацию об окне, если нужный будет найден запоминаем и двигаем дальше ...


    //Хранение информации о окне в файле
     PWindowData = ^TWindowData;
     TWindowData = record
       winOther: Word;
       winText, winClass: string;
       winRect: TRect;
       //Вспомогательные данные
       winHandle: THandle;
       winEnabled, winVisible: Boolean;
     end;

     PPWD = PWindowData;

     TFindObject = class(TObject)
     private
       FListObjects: TList;
       FobjClass: string;
       FTopLevel: HWND;
       FWindowData: PPWD;
       FLastHwnd: HWND;
       function Find(hLast: HWND): HWND;
       procedure Add(h: HWND);
       function Search(h: HWND): bool;
       procedure FreeMemory();
     public
       function GetHWND(): HWND;
       function FindFirst(): HWND;
       function FindNext(): HWND;
       procedure SetClass(objClass: string);
       procedure CopyWindowData(var outPointer: PPWD);
       constructor Create(objClass: string);
       destructor Destroy(); override;
     end;

    { TFindObject }

    procedure TFindObject.Add(h: HWND);
    var
     p: PHWND;
    begin
     new(p);
     p^ := h;
     FListObjects.Add(p);
    end;

    procedure TFindObject.CopyWindowData(var outPointer: PPWD);
    begin
     with outPointer^ do begin
       winOther :=   FWindowData.winOther;
       winText  :=   FWindowData.winText;
       winClass :=   FWindowData.winClass;
       winRect  :=   FWindowData.winRect;
       winHandle  := FWindowData.winHandle;
       winEnabled := FWindowData.winEnabled;
       winVisible := FWindowData.winVisible;
     end;
    end;

    constructor TFindObject.Create(objClass: string);
    begin
     FobjClass := objClass;
     FListObjects := TList.Create;
     FLastHWND := 0;
     FTopLevel := FindWindow('Progman', 'Program Manager');
     New(FWindowData);
    end;

    destructor TFindObject.Destroy;
    begin
     FreeMemory();
     FListObjects.Free;
     Dispose(FWindowData);
     inherited;
    end;

    function TFindObject.Find(hLast: HWND): HWND;
    begin
     result := 0;
     if hLast = 0 then exit;
     WindowData(hLast, FWindowData);
     if (FWindowData.winClass = FobjClass) and (not Search(hLast)) then begin
       Add(hLast);
       FLastHWND := hLast;
       result := hLast;
       exit;
     end;
     result := Find(GetWindow(GetWindow(hLast, GW_CHILD), GW_HWNDFIRST));
     if result <> 0 then exit;
     result := Find(GetWindow(hLast, GW_HWNDNEXT));
    end;

    function TFindObject.FindFirst: HWND;
    begin
     FreeMemory;
     Result := Find(GetWindow(FTopLevel, GW_HWNDFIRST));
    end;

    function TFindObject.FindNext: HWND;
    begin
     result := Find(GetWindow(FTopLevel, GW_HWNDFIRST));
    end;

    procedure TFindObject.FreeMemory;
    var
     p: PHWND;
    begin
     while FListObjects.Count <> 0 do begin
       p := PHWND(FListObjects.First);
       Dispose(p);
       FListObjects.Delete(0);
     end;
    end;

    function TFindObject.GetHWND: HWND;
    begin
     Result := FLastHWND;
    end;

    function TFindObject.Search(h: HWND): bool;
    var
     a: integer;
    begin
     result := false;
     if FListObjects.Count = 0 then exit;
     for a := 0 to FListObjects.Count - 1 do
       if HWND(FListObjects.Items[a]^) = h then begin
         result := true;
         exit;
       end;
    end;

    procedure TFindObject.SetClass(objClass: string);
    begin
     FreeMemory;
     FobjClass := objClass;
    end;

    //функция собирает информацию об окне
    //её нужно будет объявить перед реализацией класса
    procedure WindowData(handle: THandle; var p: PWindowData);
    var
     Buffer: PChar;
    begin
     if (handle = 0) or (p = nil) then exit;
     Buffer := StrAlloc(256);
     //WinText
     GetWindowText(handle, Buffer, 256);
     p^.winText := Trim(StrPas(Buffer));
     GetClassName(handle, Buffer, 255);
     //WinClass
     p^.winClass := Trim(StrPas(Buffer));
     //WinRect
     GetWindowRect(handle, p^.winRect);
     //WinHandle
     p^.winHandle := Handle;
     //WinEnabled
     p^.winEnabled := IsWindowEnabled(handle);
     //WinVisibled
     p^.winVisible := isWindowVisible(handle);
     p^.winOther := MakeWord(WD_TEMP, 0);
     StrDispose(Buffer);
    end;

  • sambellamy © (29.01.09 15:27) [27]
    на днях решал похожую задачу, вот версия переделанного класса (см. выше)

    unit unFindObjects;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

    type
     PHWND = ^HWND;
     PWindowData = ^TWindowData;
     TWindowData = record
       winText, winClass: string;
       winRect: TRect;
       winHandle: THandle;
       winEnabled, winVisible: Boolean;
     end;

     TEventFindProc = function(sText, sClass: string; pData: PWindowData): bool;
     
     //инструмент для поиска окон    
     TFindObjects = class(TObject)
     protected
       FListObjects: TList;
       FobjClass, FobjText: string;
       FTopLevel: HWND;
       FWindowData: PWindowData;
       FLastHwnd: HWND;
       FEventFindProc: TEventFindProc;
       function Find(hLast: HWND): HWND;
       procedure Add(h: HWND);
       function Search(h: HWND): bool;
       procedure FreeMemory();
     public    
       //получение информации об окне
       class procedure WindowData(handle: THandle; var p: PWindowData);    
       //проверка принадлежит окно windows окну parent,
       //буквально можно проверить принадлежит кнопка (window) форме (parent)
       class function FindParentWindow(Window, Parent: HWND): bool;    
       //найти первое окно по условию
       function FindFirst(): HWND;
       //следущее окно
       function FindNext(): HWND;
       //найти сразу все окна  
       procedure FindAll();      
       //доступ к найденным окнам
       procedure Item(index: integer; var outPointer: PWindowData);
       //количество найденных окон
       function Count(): integer;  
       //указатель на последнее наденное окно
       function GetLastHWND(): HWND;      
       //установить новые параметры для поиска окон
       procedure SetClass(objClass: string);
       procedure SetText(objText: string);    
       constructor Create(objClass, objText: string; EventFindProc: TEventFindProc);
       destructor Destroy(); override;
     end;
     
     function DefEventFindProc(sText, sClass: string; pData: PWindowData): bool;
     function DefEventFindProcB(sText, sClass: string; pData: PWindowData): bool;

    var
     hGRYM: TFindObjects;
     
    implementation  
     
    { TFindObjects }

    class procedure TFindObjects.WindowData(handle: THandle; var p: PWindowData);
    var
     Buffer: PChar;
    begin
     if (handle = 0) or (p = nil) then exit;
     Buffer := StrAlloc(256);
     GetWindowText(handle, Buffer, 256);
     p^.winText := Trim(StrPas(Buffer));
     GetClassName(handle, Buffer, 255);
     p^.winClass := Trim(StrPas(Buffer));
     GetWindowRect(handle, p^.winRect);
     p^.winHandle := Handle;
     p^.winEnabled := IsWindowEnabled(handle);
     p^.winVisible := isWindowVisible(handle);
     StrDispose(Buffer);  
    end;  

    procedure TFindObjects.Add(h: HWND);
    var
     p: PHWND;
    begin
     new(p);
     p^ := h;
     FListObjects.Add(p);
    end;

    function TFindObjects.Count: integer;
    begin
     result := FListObjects.Count;
    end;

    constructor TFindObjects.Create(objClass, objText: string; EventFindProc: TEventFindProc);
    begin
     FobjClass := objClass;
     FobjText := objText;
     if Assigned(EventFindProc) then
       FEventFindProc := EventFindProc
     else
       FEventFindProc := DefEventFindProc;
     FListObjects := TList.Create;
     FLastHWND := 0;
     FTopLevel := FindWindow('Progman', 'Program Manager');
     new(FWindowData);
    end;

    destructor TFindObjects.Destroy;
    begin
     FreeMemory();
     FListObjects.Free;
     Dispose(FWindowData);
     inherited;
    end;

    function TFindObjects.Find(hLast: HWND): HWND;
    begin
     result := 0;
     if hLast = 0 then exit;
     WindowData(hLast, FWindowData);
     if (FEventFindProc(FobjText, FobjClass, FWindowData)) and (not Search(hLast)) then begin
       Add(hLast);
       FLastHWND := hLast;
       result := hLast;
       exit;
     end;
     result := Find(GetWindow(GetWindow(hLast, GW_CHILD), GW_HWNDFIRST));
     if result <> 0 then exit;
     result := Find(GetWindow(hLast, GW_HWNDNEXT));
    end;

    procedure TFindObjects.FindAll;
    var
     h: HWND;
    begin
     h := FindFirst();
     while h <> 0 do h := FindNext();  
    end;

    function TFindObjects.FindFirst: HWND;
    begin
     FreeMemory;
     Result := Find(GetWindow(FTopLevel, GW_HWNDFIRST));
    end;

    function TFindObjects.FindNext: HWND;
    begin
     result := Find(GetWindow(FTopLevel, GW_HWNDFIRST));
    end;

    class function TFindObjects.FindParentWindow(Window, Parent: HWND): bool;
    begin
     result := false;
     while (Window <> parent) do begin
       Window := GetParent(Window);
       if window = 0 then exit;
     end;
     result := true;
    end;

    procedure TFindObjects.FreeMemory;
    var
     p: PHWND;
    begin
     while FListObjects.Count <> 0 do begin
       p := PHWND(FListObjects.First);
       Dispose(p);
       FListObjects.Delete(0);
     end;
    end;

    function TFindObjects.GetLastHWND: HWND;
    begin
     Result := FLastHWND;
    end;

    procedure TFindObjects.Item(index: integer; var outPointer: PWindowData);
    var
     pData: PWindowData;
    begin
     outPointer.winHandle := 0;
     if (index < 0) or (index >= FListObjects.Count) then exit;
     pData := PWindowData(FListObjects[index]);
     with outPointer^ do begin
       winText  :=   pData.winText;
       winClass :=   pData.winClass;
       winRect  :=   pData.winRect;
       winHandle  := pData.winHandle;
       winEnabled := pData.winEnabled;
       winVisible := pData.winVisible;
     end;
    end;

    function TFindObjects.Search(h: HWND): bool;
    var
     a: integer;
    begin
     result := false;
     if FListObjects.Count = 0 then exit;
     for a := 0 to FListObjects.Count - 1 do
       if HWND(FListObjects.Items[a]^) = h then begin
         result := true;
         exit;
       end;
    end;

    procedure TFindObjects.SetClass(objClass: string);
    begin
     FreeMemory;
     FobjClass := objClass;
    end;  

    procedure TFindObjects.SetText(objText: string);
    begin
     FreeMemory;
     FobjText:= objText;
    end;
         
    function DefEventFindProc(sText, sClass: string; pData: PWindowData): bool;
    begin
     result := true;
     if (sText = pData.winText) or (sClass = pData.winClass) then exit;
     result := false;
    end;

    function DefEventFindProcB(sText, sClass: string; pData: PWindowData): bool;
    begin
     result := true;
     if (Pos(sText, pData.winText) <> 0) and (Pos(sClass, pData.winClass) <> 0) then exit;
     result := false;
    end;

    initialization
     //находим главное окно программы
     //Астрахань (январь 2009) - ДубльГИС    
     //[Afx:00400000:b:00010011:00000006:00060758]
     hGRYM := TFindObjects.Create('Afx', 'ДубльГИС', DefEventFindProcB);
     hGRYM.FindFirst();
     
    finalization
     hGRYM.Destroy;

    end.


  • ahnprv lihamonts (25.03.09 20:59) [28]
    mktoflb soghzmix dxagv xhqd ptfyxeo megjaul zcsuknle
  • tzedbxwhv hsqmoub (25.03.09 21:00) [29]
    jdlcmngth yclfudbp ehkq tvkrbon nzqwe btxvjge yncgq http://www.kwzjr.fpvxm.com
 
Конференция "WinAPI" » однозначное определение 2+ окон с одним заголовком [D7, WinXP]
Есть новые Нет новых   [134435   +35][b:0.001][p:0.007]