|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Дождаться создания главного окна
есть у меня процесс, который я создал креэйтпроцесс-ом, есть вся информация о нём и параметры, нужно как то дождаться, пока он создаст первое окно. Я не хочу в цикле проверять есть ли у него окна, возможно есь стандартная функция может в рундлл? хуки конечно выход может, хоть и ивращённый, но я с ними не много работал, знаю что можно для одного процесса создать локальный хук без библиотеки, но у меня так не вышло. Может кто помочь - направить?
Последний раз редактировалось reqyz, 27.11.2012 в 19:44. |
#2
|
||||
|
||||
попробуй WaitForInputIdle
Пишу программы за еду. __________________ |
Этот пользователь сказал Спасибо NumLock за это полезное сообщение: | ||
reqyz (29.11.2012)
|
#3
|
|||
|
|||
Функция WaitForInputIdle ждет до тех пор, пока заданный процесс не дождется ввода данных пользователем, без задержки ввода, или до тех пор, пока не истечет интервал блокировки по времени.
не то Ладно, как поставить хук на конкретный мною известный поток, в библиотеке Код:
library dll; uses SysUtils, windows, Classes; var Hook:HHOOK; Handle:THandle; HCBT2:longword; function CreateWND(code: integer; wParam: word; lParam: longword): longword; stdcall; begin if Code<0 then begin Result := CallNextHookEx(Hook, code, WParam, LParam); exit; end; if(code=HCBT2)then begin Handle:=wParam; UnhookWindowsHookEx(Hook); end; end; function SetWnd(HCBT,dwThreadId:longword):THandle; begin Handle:=0; HCBT2:=HCBT; Hook:=SetWindowsHookEx(WH_CBT,@CreateWND,HInstance,dwThreadId); repeat until(Handle>0); end; exports SetWnd; end. Hook возвращает 0 и хук не ставится. вызываю так Код:
var SetWND:function(HCBT,dwThreadId:longword):THandle; dll:=LoadLibrary('dll.dll'); @SetWND:=GetProcAddress(dll,'SetWnd'); Последний раз редактировалось reqyz, 28.11.2012 в 11:31. |
#4
|
||||
|
||||
какая конечная цель?
Пишу программы за еду. __________________ |
#5
|
|||
|
|||
Цитата:
|
#6
|
||||
|
||||
Если задача в том чтобы действительно дождаться, т.е. остановить ту нить из которой был создан процесс - то однозначно WaitForSingleObject. Если же нить создающая процесс должна знать когда окно было создано/уничтожено/свернуто/развернуто и т.п., то вполне хватит SendMessage/PostMessage или, если дело происходит внутри потоков, PostThreadMessage
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
Этот пользователь сказал Спасибо Aristarh Dark за это полезное сообщение: | ||
reqyz (29.11.2012)
|
#7
|
|||
|
|||
Цитата:
|
#8
|
||||
|
||||
Скорее всего я не вижу всей полноты задачи. Подробнее можешь описать?
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#9
|
|||
|
|||
Хорошо. Есть наша программа, есть сторонний процесс, который мы запускаем нашей программой, функцией createprocess далее, нам нужно полуать уведомления, когда тот процесс пытается создать окно или закрыть или появить и т д, сейчас, я это более менее могу делать так -
Код:
library dll; uses SysUtils, windows, Classes,dialogs,messages; var Hook:HHOOK; Handle:THandle; HCBT2:longword; function CreateWND(code: integer; wParam: word;lParam: longword): longword; stdcall; var list:TStringList; begin if Code<0 then begin Result := CallNextHookEx(Hook, code, WParam, LParam); exit; end; if(code=HCBT_CREATEWND)then begin Handle:=wParam; list:=TStringList.Create; if(FileExists('1.txt'))then list.LoadFromFile('1.txt'); list.Add(inttostr(code)+' '+inttostr(lParam)); list.SaveToFile('1.txt'); list.Destroy; //UnhookWindowsHookEx(Hook); // exit; end; Result := CallNextHookEx(Hook, code, WParam, LParam); end; function SetWnd(const HCBT,dwThreadId:longword):THandle; begin result:=SetWindowsHookEx(WH_CBT,@CreateWND,HInstance,dwThreadId); end; exports SetWnd; end. запускаю библиотеку так - Код:
with StartInfo do begin cb := SizeOf(StartInfo); end; CreateProcessA(nil,'process.exe',nil,nil,false,0,nil,nil,StartInfo,ProcInfo); WaitForInputIdle(ProcInfo.hProcess, INFINITE); @SetWNDD:=GetProcAddress(dll,'SetWnd'); if(@SetWNDD<>nil)then Handle:=SetWNDD(WM_CREATE,ProcInfo.dwThreadId);//} а вот как сообщать своей программе что делает тот процесс, не знаю, окон у меня нет, поэтому вариант передачи мне месаджа не сработает, пытался оле и дде, но не полуилось( не работал с ними сам ещё, мне бы библиотеку переделать так, чтобы моё приложение, после вызова функции библиотеки задумалось до тех пор, пока библиотека не вернёт хендл окна с которым произошла операция,(создалось уничтожилось, активизировалось и т д) типо такой функции Handle:=WaitForMessage(dwThreadId,HCBT_CREATEWND); |
#10
|
||||
|
||||
1. callback-функции
2. AllocateHWnd Пишу программы за еду. __________________ |
#11
|
||||
|
||||
Я бы сделал себе хендл (см. Classes.AllocateHWnd и Classes.DeallocateHWnd). Хендл бы передавал в CreateProcess (см. параметр lpEnvironment). В созданном процессе вычитывал бы этот хенд, и отправлят ему сообщения когда надо.
О, NumLock успел раньше Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#12
|
|||
|
|||
Цитата:
Код:
type TMes = class private FHWnd: HWND; protected procedure WMCopyData(var Msg:TMessage); message WM_COPYDATA; public constructor Create(); destructor Destroy; override; end; var Handl:HWND=0; constructor TMes.Create(); begin inherited Create(); FHWnd := AllocateHWnd(WMCopyData); end; destructor TMes.Destroy; begin DeallocateHWnd(FHWnd); inherited Destroy; end; Mess:string; function SetHook(Wnd: HWND;dwThreadId:LongWord): BOOL; stdcall; external 'hooklib.dll'; function RemoveHook: BOOL; stdcall; external 'hooklib.dll'; procedure TMes.WMCopyData(var Msg: TMessage); begin inherited; Mess:=pchar(Msg.WParam); Msg.Result:=1; end; ... messa:=TMes.Create; if(SetHook(messa.FHWnd,ProcInfo.dwThreadId))then ДЛЛ Код:
library hooklib; uses Windows, Messages; const HookMap = '{F3E25943-FCC7-43E5-BE22-7CF35EA5FCC6}'; type PHookData = ^THookData; THookData = packed record AppWnd : HWND; OldHook : HHOOK; end; var hMap : THandle = 0; HookData : PHookData = nil; procedure DLLEntryPoint(dwReason: DWORD); begin case dwReason of DLL_PROCESS_ATTACH: begin hMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(THookData), HookMap); HookData := MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(THookData)); end; DLL_PROCESS_DETACH: begin UnMapViewOfFile(HookData); CloseHandle(hMap); end end end; procedure SaveLog(s:string); var cds:TCopyDataStruct; begin cds.cbData:=length(s)+1; cds.lpData:=pchar(s); SendMessage(HookData^.AppWnd,WM_COPYDATA,0,Cardinal(@cds)); end; function HookProc(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT;stdcall; var WndHeader:array[0..MAX_PATH-1] of char; begin if Code>=0 then begin case Code of HCBT_CREATEWND: if (IsWindow(wParam) and (PCBTCreateWnd(lParam)^.lpcs^.hwndParent=0) and (lstrlen(PCBTCreateWnd(lParam)^.lpcs^.lpszName)>0)) then SaveLog('[Open] '+PCBTCreateWnd(lParam)^.lpcs^.lpszName); HCBT_DESTROYWND: if (IsWindow(wParam) and IsWindowVisible(wParam) and (GetParent(wParam)=0)) then begin GetWindowText(wParam,WndHeader,MAX_PATH); if (WndHeader<>'')then SaveLog('[Close] '+WndHeader); end end; Result := 0; end else Result := CallNextHookEx(HookData^.OldHook, Code, WParam, LParam); end; function SetHook(Wnd: HWND;dwThreadId: DWORD): BOOL; stdcall; begin if HookData <> nil then begin HookData^.AppWnd := Wnd; HookData^.OldHook := SetWindowsHookEx(WH_CBT, HookProc, HInstance,dwThreadId); Result:=HookData^.OldHook <> 0; end else Result:=False; end; function RemoveHook: BOOL; stdcall; begin Result := UnhookWindowsHookEx(HookData^.OldHook); end; exports SetHook, RemoveHook; begin if @DLLProc = nil then DLLProc := @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end. а если без dll Код:
messa:=TMes.Create; CreateProcessA(nil,'process.exe',nil,nil,false,0,Pointer(messa.FHWnd),nil,StartInfo,ProcInfo); Последний раз редактировалось reqyz, 29.11.2012 в 12:44. |
#13
|
|||
|
|||
Поздравьте меня) я справился) всем спасибо)
вот Длл Код:
library hooklib; uses Windows, Messages; const HookMap = '{F3E25943-FCC7-43E5-BE22-7CF35EA5FCC6}'; type PHookData = ^THookData; THookData = packed record AppWnd : HWND; OldHook : HHOOK; end; var hMap : THandle = 0; HookData : PHookData = nil; procedure DLLEntryPoint(dwReason: DWORD); begin case dwReason of DLL_PROCESS_ATTACH: begin hMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(THookData), HookMap); HookData := MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(THookData)); end; DLL_PROCESS_DETACH: begin UnMapViewOfFile(HookData); CloseHandle(hMap); end end end; function HookProc(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT;stdcall; begin if Code>=0 then begin SendMessage(HookData^.AppWnd,Code,WParam,LParam); Result := 0; end else Result := CallNextHookEx(HookData^.OldHook, Code, WParam, LParam); end; function SetHook(Wnd: HWND;dwThreadId: DWORD;WH:Integer): BOOL; stdcall; begin if HookData <> nil then begin HookData^.AppWnd := Wnd; HookData^.OldHook := SetWindowsHookEx(WH, HookProc, HInstance,dwThreadId); Result:=HookData^.OldHook <> 0; end else Result:=False; end; function RemoveHook: BOOL; stdcall; begin Result := UnhookWindowsHookEx(HookData^.OldHook); end; exports SetHook, RemoveHook; begin if @DLLProc = nil then DLLProc := @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end. а вот вызова Код:
type TMes = class private FHWnd: HWND; protected procedure WMCopyData(var Msg:TMessage);virtual; public constructor Create(); destructor Destroy; override; end; procedure ProcessMessages; var Msg: TMsg; function ProcessMessage(): Boolean; var Handled: Boolean; begin Result := False; if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin Result := True; if Msg.Message <> WM_QUIT then begin TranslateMessage(Msg); DispatchMessage(Msg); end; end; end; begin while ProcessMessage() do {loop}; end; constructor TMes.Create(); begin inherited Create(); FHWnd := AllocateHWnd(WMCopyData); end; destructor TMes.Destroy; begin DeallocateHWnd(FHWnd); inherited Destroy; end; var Code_:LongWord; Handle:longword; messa:TMes; function SetHook(Wnd: HWND;dwThreadId:LongWord;WH:Integer): BOOL; stdcall; external 'hooklib.dll'; function RemoveHook: BOOL; stdcall; external 'hooklib.dll'; function StartWait(dwThreadId,code,WH:longword):boolean; begin Code_:=code; messa:=TMes.Create; result:=SetHook(messa.FHWnd,dwThreadId,WH); end; function WaitMessages(dwMilliseconds: LongWord):longword; var i:cardinal; begin Handle:=0; i:=0; repeat ProcessMessages; inc(i); until(Handle>0)or(i=dwMilliseconds); Result:=Handle; messa.Destroy; end; procedure TMes.WMCopyData(var Msg: TMessage); begin if(Msg.Msg=Code_)then begin Handle:=Msg.WParam; RemoveHook; end; end; ... StartWait(ProcInfo.dwThreadId,HCBT_CREATEWND,WH_CBT); Handle:=WaitMessages(INFINITE); |