(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Немного об окнах и процессах (исходники)

Источник: 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;

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 25.01.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Panda Internet Security - ESD версия - на 1 устройство - (лицензия на 1 год)
go1984 pro
SAP® Crystal Dashboard Design Departmental 2016 WIN INTL NUL
Oracle Database Personal Edition Named User Plus License
Microsoft 365 Business Standard (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Вопросы и ответы по MS SQL Server
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100