Трохи про вікна і процесах (исходники), Різне, Програмування, статті

Всі вікна додатків управляються різними функціями 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;

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*