Суббота, 20.04.2024, 18:21 Приветствую вас Гость | Группа "Гости" 
Меню сайта

Категории раздела
Вирусология [40]
Статьи о вирусах
Системные [1]
Работа с системой
Примеры [45]
Приёмы, функции, процедуры
Ceти [1]
Работа с интернет
Шуточные программы [5]
Пишем шуточные программки
Остальное [6]
Всё что не вошло

Популярные статьи

Недавние темы

Опрос
На каком языке кодите?

Всего ответов: 778

Главная » Статьи » Delphi » Примеры

Кое что об окнах и процессах
Все окна приложений управляются различными функциями WinApi через свои дескрипторы.
Поэтому неплохо бы знать как их получать.

Рассмотрим функцию FindWindow.

FindWindow(CN,WN:PChar): HWnd;
CN - имя класса.
WN - имя окна(Caption), если = nil, то ищется любое окно этого класса.

Функция возвращает дескриптор окна или 'nil' при неудачном поиске.

- (с.8) Для определения имени класса чужого приложения воспользуйтесь,
поставляемой с Delphi, программой WinSight 32 через Spy\Find
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;
Категория: Примеры | Добавил: dolphin (14.04.2011)
Просмотров: 7377 | Рейтинг: 5.0/1

Всего комментариев: 0
avatar
Профиль


Логин:
Пароль:

Поиск

Наша кнопка
Вирусология, взгляд из Delphi

Статистика
Top.Mail.Ru Яндекс.Метрика Счетчик тИЦ и PR
Статистика материалов
Файлов: 454
Форум: 1165/8116
Коментариев: 768
Новостей: 29

Статистика пользователей
Всего: 331
За неделю: 2
Вчера: 0
Сегодня: 0
Всего онлайн: 1
Гостей: 1
Пользователей: 0

delphicode.ru © 2008 - 2024 Хостинг от uCoz