|
Навигация
|
Главная » Delphi Немного об окнах и процессах (исходники)Источник: articles Все окна приложений управляются различными функциями winapi через свои дескрипторы. Поэтому неплохо бы знать как их получать. Рассмотрим функцию findwindow. findwindow(cn,wn:pchar): hwnd; cn - имя класса. wn - имя окна(caption), если = nil, то ищется любое окно этого класса. Функция возвращает дескриптор окна или 'nil' при неудачном поиске. - (с.8) Для определения имени класса чужого приложения воспользуйтесь, поставляемой с delphi, программой winsight 32 через spyfind window. Лучше иметь только нужное окно в этот момент. Для, всем известного калькулятора, получение дескриптора его окна будет выглядеть так : var h : hwnd; begin h:=findwindow('scicalc','Калькулятор'); end; Есть еще одна функция позволяющая определять дескриптор окна. getnextwindow(h:hwnd,c:word):hwnd; h - окно от которого вести отсчет. с = gw_hwndnext - искать следующее окно. c = gw_hwndprev - искать предыдущее окно. Если окна не находится, то возвращается 0. А еще можно считать заголовок окна (и потом по нему искать хендл). getwindowtext(h:hwnd,str:pchar,kol:word):integer; str - строка куда считывать. kol - количество символов. Получение списка окон var wnd : hwnd; buff: array [0..127] of char; begin listbox1.clear; wnd := getwindow(handle, gw_hwndfirst); while wnd <> 0 do begin {Не показываем:} if (wnd <> application.handle) and {-Собственное окно} iswindowvisible(wnd) and {-Невидимые окна} (getwindow(wnd, gw_owner) = 0) and {-Дочернии окна} (getwindowtext(wnd, buff, sizeof(buff)) <> 0) then begin getwindowtext(wnd, buff, sizeof(buff)); listbox1.items.add(strpas(buff)); end; wnd := getwindow(wnd, gw_hwndnext); end; listbox1.itemindex := 0; end; Получение списка процессов var hsnap:thandle; pe:tprocessentry32; begin listbox1.clear; pe.dwsize:=sizeof(pe); hsnap:=createtoolhelp32snapshot(th32cs_snapprocess,0); if process32first(hsnap,pe) then begin listbox1.items.add(pe.szexefile); while process32next(hsnap,pe) do listbox1.items.add(pe.szexefile); end; end; Как получить дескриптор окна другого приложения и сделать его активным? Использование функции windows api findwindow() - простейший способ нахождение окна, при условии, что известен его заголовок или имя оконного класса. Если Вам известна только часть заголовка окна (например 'netscape - ' + 'какой-то неизвестный url'), Вам нужно использовать функцию enumwindows() для получения всех окон, затем вызывать функцию getwindowstext() и getclassname для поиска нужного окна. Следующий пример находит первое окно, содержащее совпадающую часть заголовка окна и полностью совпадающее название оконного класса (если он задан) и делает это окно активным. type pfindwindowstruct = ^tfindwindowstruct; tfindwindowstruct = record caption : string; classname : string; windowhandle : thandle; end; function enumwindowsproc(hwindow : hwnd;lparam : longint) : bool {$ifdef win32} stdcall; {$else} ; export; {$endif} var lpbuffer : pchar; windowcaptionfound : bool; classnamefound : bool; begin getmem(lpbuffer, 255); result := true; windowcaptionfound := false; classnamefound := false; try if getwindowtext(hwindow, lpbuffer, 255) > 0 then if pos(pfindwindowstruct(lparam).caption, strpas(lpbuffer)) > 0 then windowcaptionfound := true; if pfindwindowstruct(lparam).classname = '' then classnamefound := true else if getclassname(hwindow, lpbuffer, 255) > 0 then if pos(pfindwindowstruct(lparam).classname, strpas(lpbuffer)) > 0 then classnamefound := true; if (windowcaptionfound and classnamefound) then begin pfindwindowstruct(lparam).windowhandle := hwindow; result := false; end; finally freemem(lpbuffer, sizeof(lpbuffer^)); end; end; function findawindow(caption : string;classname : string) : thandle; var windowinfo : tfindwindowstruct; begin with windowinfo do begin caption := caption; classname := classname; windowhandle := 0; enumwindows(@enumwindowsproc, longint(@windowinfo)); findawindow := windowhandle; end; end; procedure tform1.button1click(sender: tobject); var thewindowhandle : thandle; begin thewindowhandle := findawindow('netscape - ', ''); if thewindowhandle = 0 then showmessage('window not found!') else bringwindowtotop(thewindowhandle); end; Ниже приведена процедура, позволяющаю отправлять нажатия в любой элемент управления (window control), способный принимать ввод с клавиатуры. Вы можете использовать эту технику чтобы включать клавиши numlock, capslock и scrolllock под windows nt. Та же техника работает и под windows 95 для capslock и scrolllock, но не работает для клавиши numlock. Обратите внимание, что приведены четыре поцедуры: simulatekeydown() - эмулировать нажатие клавиши (без отпускания) simulatekeyup() - эмулировать отпускание клавиши simulatekeystroke() - эмулировать удар по клавише (нажатие и отпускание) и sendkeys(), позволяющие Вам гибко контролировать посылаемые сообщения клавиатуры. simulatekeydown(), simulatekeyup() и simulatekeystroke() получают коды виртуальных клавиш (virtural key) (вроде vk_f1). Процедура simulatekeystroke() получает дополнительный параметр, полезный при эмуляции нажатия printscreen. Когда этот параметр равен нулю весь экран будет скопирован в буфер обмена (clipboard). Если дополнительный параметр равен 1 будет скопированно только активное окно. Четыре метода "button click" демонстрируют использование: buttonclick1 - включает capslock buttonclick2 - перехватывает весь экран в буфер обмена (clipboard). buttonclick3 - перехватывает активное окно в буфер обмена (clipboard). buttonclick4 - устанавливает фокус в edit и отправляет в него строку. Пример: procedure simulatekeydown(key : byte); begin keybd_event(key, 0, 0, 0); end; procedure simulatekeyup(key : byte); begin keybd_event(key, 0, keyeventf_keyup, 0); end; procedure simulatekeystroke(key : byte; extra : dword); begin keybd_event(key,extra,0,0); keybd_event(key,extra,keyeventf_keyup,0); end; procedure sendkeys(s : string); var i : integer; flag : bool; w : word; begin {get the state of the caps lock key} flag := not getkeystate(vk_capital) and 1 = 0; {if the caps lock key is on then turn it off} if flag then simulatekeystroke(vk_capital, 0); for i := 1 to length(s) do begin w := vkkeyscan(s[i]); {if there is not an error in the key translation} if ((hibyte(w) <> $ff) and (lobyte(w) <> $ff)) then begin {if the key requires the shift key down - hold it down} if hibyte(w) and 1 = 1 then simulatekeydown(vk_shift); {send the vk_key} simulatekeystroke(lobyte(w), 0); {if the key required the shift key down - release it} if hibyte(w) and 1 = 1 then simulatekeyup(vk_shift); end; end; {if the caps lock key was on at start, turn it back on} if flag then simulatekeystroke(vk_capital, 0); end; procedure tform1.button1click(sender: tobject); begin {toggle the cap lock} simulatekeystroke(vk_capital, 0); end; procedure tform1.button2click(sender: tobject); begin {capture the entire screen to the clipboard} {by simulating pressing the printscreen key} simulatekeystroke(vk_snapshot, 0); end; procedure tform1.button3click(sender: tobject); begin {capture the active window to the clipboard} {by simulating pressing the printscreen key} simulatekeystroke(vk_snapshot, 1); end; procedure tform1.button4click(sender: tobject); begin {set the focus to a window (edit control) and send it a string} application.processmessages; edit1.setfocus; sendkeys('delphi is rad!'); end; wm_copydata для пересылки данных между формами \ В файле проекта: var i: integer; hmainform:hwnd; copydatastruct:tcopydatastruct; paramstring:string; wparam,lparam:integer; begin \ ищем главное окно приложения, вместо caption - nil, \ поскольку к заголовку главного окна может добавиться заголовок mdichild \ (нужно позаботиться об уникальности имени класса главной формы) hmainform:= findwindow('tmainform',nil); if hmainform = 0 then begin application.initialize; application.createform(tfrmmain,frmmain); for i:=1 to paramcount do tmainform(application.mainform).openfile(paramstr(i)); application.run; end else begin paramstring:=''; for i:=1 to paramcount do begin \ запихиваем все параметры в одну строку с разделителями №13 paramstring:=paramstring+paramstr(i)+ #13; end; \ создаем запись типа tcopydatastruct copydatastruct.lpdata:=pchar(paramstring); copydatastruct.cbdata:=length(paramstring); copydatastruct.dwdata:=0; wparam:=application.handle; lparam:=integer(@copydatastruct); \ отсылаем сообщение wm_copydata главному окну открытого приложения sendmessage(hmainform,wm_copydata,wparam,lparam); application.terminate; end; end. \ Обработчик сообщения wm_copydata procedure tmainform.copydata(var msg: twmcopydata); var paramstr:string; copydatastructure:tcopydatastruct; i:integer; len:integer; begin copydatastructure:= msg.copydatastruct^; paramstr:=''; len:= copydatastructure.cbdata; for i:=0 to len-1 do begin paramstr:=paramstr+(pchar(copydatastructure.lpdata)+i)^; end; i:=0; while not(length(paramstr)=0) do begin if isdelimiter(#13,paramstr,i) then begin openfile(copy(paramstr,0,i-1)); paramstr:=copy(paramstr,i+1,length(paramstr)-i-1); end; inc(i); end; inherited; end; CodeRage 5, Video 1: Delphi: трюки и советы. Новые возможности Embarcadero RAD Studio 2010. Визуальный HTML редактор своими руками. DataSnap XE. Основные принципы выбора прикладного программного обеспечения для построения корпоративной информационной системы (документация). Главная » Delphi |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |