-
Как определить однозначно окно если их 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);
Помогите пожалуйста кто может
-
на основании чего принимается решение, какому именно окну надо отправлять сообщение?
-
> Anklav (20.01.2009 10:45:00) [0]
Wnd: HWND; одназначно определяет окно.
-
по нажатию кнопки на пример у меня 4 окна (все называются "Lineage II") при нажатии Q чтобы происходила эмуляция для первого окна кнопки F1, при нажатии A эмуляция для второго окна кнопки F1 и т. д.
-
> Wnd: HWND; одназначно определяет окно.
Названия окон одинаковы и он будет производить эмуляцию во всех окнах с таким заголовком
-
> Anklav (20.01.2009 13:21:04) [4]
Откуда ты взял эти окна? Может надо при создании/появление запоминать их хендлы. Что кроме загововка есть еще у укон.
-
> Откуда ты взял эти окна? > Может надо при создании/появление запоминать их хендлы. > Что кроме загововка есть еще у укон.
Окна запускаются обычно, с ехешника. Если при появлении/создании их отпределать то какаим образом это сделать?
-
> Anklav (20.01.09 14:52) [6]
Ты хочешь сказать, что интересующие тебя окна абсолютно ничем не отличаются ? Тогда какая разница, в какое из этих окон послать сообщения ?
-
> Ты хочешь сказать, что интересующие тебя окна абсолютно > ничем не отличаются ? > Тогда какая разница, в какое из этих окон послать сообщения > ?
Я и хочу чтобы конкретному окну из этих 4х (например первому по времени запуска) отправлялась эмуляция кнопки F1 по нажатию клавиши Q. А второму окну тот же F1 но по нажитию клавиши A. Все окна загружены последовательно.
-
Т.е. единственное их отличие - это порядок создания, а больше окна НИЧЕМ не отличаются ?
-
> Anklav (20.01.09 14:52) [6]
> Если при появлении/создании их отпределать то какаим образом > это сделать?
EnumThreadWindows after WaitForInputIdle, если, конечно, окна создаются первичным потоком. В противном случае - EnumWindows with GetWindowThreadProcessId.
А после определения нужного хендла надо SetWindowsHookEx на создавший его поток, дабы отследить момент разрушения окна.
-- Regards, LVT.
-
> Anklav (20.01.09 10:45)
> Процедура эмуляции кнопки
В печь ее.
-- Regards, LVT.
-
> Leonid Troyanovsky
Спасибо огромное! Буду проверять.
-
> Т.е. единственное их отличие - это порядок создания, а больше > окна НИЧЕМ не отличаются ?
Я запускаю 4 раза подряд 1 ехешник с игрой. Запускаются 4 окна с одинаковым названием. И нужно их как-то разделить и определенному окну в зависимости о нажатия определенной кнопки отпралять определенное сообщение. Проблема в том что я незнаю как их разделить, пробовал переименовать поочереди чтобы были разные заголовки, но название заголовка воозвращяется стандартное. (И вообще я пока нуб по Делфи...)
-
При отправлении сообщения окну оно не должно становиться активным
-
> Anklav (20.01.09 20:13) [14]
> При отправлении сообщения окну оно не должно становиться > активным
Смело полагай, что этот пункт уже выполнен.
-- Regards, LVT.
-
> Я запускаю
Значит после очередного N-го запуска ты волен и можешь получить хэндл нового окна и сохранить как N-й хэндл.
-
> я пока нуб
Нуб - это звучит гордо ?
-
> Нуб - это звучит гордо ?
Нуб это новичок) а как этот хэндл получить от всех окон и отправлять сообщения конкретным окнам по этоим хэндл'ам?
-
> как этот хэндл получить от всех окон
см. [10]
> отправлять сообщения конкретным окнам
Send/PostMessage
-
Буду пробовать, спасибо всем )
-
если я запускаю все окна с одного ехешника то поток у меня так же один?
EnumThreadWindows ( DWORD dwThreadId, // идентификатор потока <--- искать через функцию GetWindowThreadProcessId? WNDENUMPROC lpfn, // указатель на функцию возврата <-- какую функцию использовать? LPARAM lParam // значение, определяемое прикладной программой );
а значение этой функции использовать чтобы отправлять сообщения нужному окну?
-
> если я запускаю ...окна
.. то ты, наверно, пользуешься при этом функцией ZapuskayuOkna() ?
-
> > .. то ты, наверно, пользуешься при этом функцией ZapuskayuOkna() > ?
впринципе если написать такую функцию то можно, а так нет не пользуюсь.
-
аа все понял.. сори жестко тупил.
-
> если я запускаю все окна с одного ехешника
Сомневаюсь я однако, что сей вопрос имеет право находиться в конференции WinAPI. Бо если б автор создавал окна функциями CreateWindow(Ex), он бы таких вопросов бы не задавал.
-
вот класс выдранный из кода, позволяет найти все окна определённого класса, давно делал, но суть понять можно, перебираем все окна с помощью ф. 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;
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);
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);
p^.winOther := MakeWord(WD_TEMP, 0);
StrDispose(Buffer);
end;
-
на днях решал похожую задачу, вот версия переделанного класса (см. выше)
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);
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
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
hGRYM := TFindObjects.Create('Afx', 'ДубльГИС', DefEventFindProcB);
hGRYM.FindFirst();
finalization
hGRYM.Destroy;
end.
-
mktoflb soghzmix dxagv xhqd ptfyxeo megjaul zcsuknle
-
|