Взаємодія з чужими вікнами - Функції та процедури Win Api - Статті по Делфі - Персональний сайт

Для того, щоб зробити щось над якимось вікном потрібно спочатку отримати його дескриптор, тобто. його становище в оперативній пам'яті. Для цього необхідно використовувати функцію FindWindow. Їй потрібно вказати всього два параметри: спочатку клас вікна, потім його заголовок. Ну з заголовком проблем взагалі немає - його ми бачимо, але як визначити клас. адже він прихований від голосу користувача. Насправді ми можемо вказати тільки заголовок вікна, а замість класу ставимо nil.

Для початку запустіть стандартну програму "Блокнот" - і що ми бачимо? У блокноті у заголовку вікна простежується ім'я поточного файлу. Спочатку, т.к. файлу немає у використанні, заголовок блокнота виглядає так: "Безім'яний - Блокнот". Постараємось за цим критерієм знайти вікно блокнота. Виглядатиме це так:

if FindWindow(nil, 'Безім'яний - Блокнот') <> 0 then ShowMessage('Вікно знайдено') else ShowMessage('Вікно НЕнайдено');

Як ми бачимо з коду, якщо наша програма знайде вікно блокнота, ми побачимо повідомлення про це.

Далі спробуємо пересунути це вікно

var h: HWND; begin h := findwindow(nil, 'Безім'яний - Блокнот'); if h <> 0 then SetWindowPos(h, HWND_BOTTOM, 1, 1, 20, 20, swp_nosize); end;

Знову знаходимо блокнот. Його дескриптор поміщаємо у змінну класу HWND [З англійської Handle Window – дескриптор вікна]. Далі використовуємо функцію SetWindowPos для завдання позиції. Як параметри потрібно вказати:

* Дескриптор вікна, яке хочемо перемістити * Ідентифікатор вікна, яке передує вікну, що переміщується в Z-послідовності. Z-послідовність це порядок, у якому формувалися вікна. Даний параметр вказує з якого вікна необхідно починати писк. Як значенняможе приймати або дескриптор будь-якого вікна в системі, або одне з нижченаведених значень: o HWND_BOTTOM Початок Z-послідовності o HWND_NOTOPMOST Перше вікно яке розташовується не "поверх усі вікна" o HWND_TOP Вершина Z-послідовник o HWND_TOPMOST Перше вікно яке розташовується "поверх усі вікна" * Позиція вікна по горизонталі * Позиція вікна по вертикалі * Ширина вікна * Висота вікна * Специфікатори зміни позиції та розмірів вікна [прапори]. Для встановлення значення можна комбінувати наступні константи o SWP_DRAWFRAME Промальовування кадру навколо вікна. o SWP_FRAMECHANGED Надсилає повідомлення WM_NCCALCSIZE вікну, навіть якщо розмір його не було змінено. Якщо цей прапор не вказано, повідомлення WM_NCCALCSIZE надсилатиметься лише після зміни розмірів вікна. o SWP_HIDEWINDOW Приховує вікно. o SWP_NOACTIVATE Не активує вікно. Якщо цей прапор не буде поставлений, вікно активізується і буде переміщено поверх всіх вікон. А ось чи встане вікно навіть вище за ті вікна, яким задано HWND_TOPMOST чи ні залежить від параметра hWndInsertAfter. o SWP_NOCOPYBITS Якщо цей специфікатор не буде встановлений, тоді вміст клієнтської області вікна буде скопійовано і вставлено у вікно, що з'явилося після його переміщення. o SWP_NOMOVE Повідомляє, що потрібно ігнорувати параметри завдання позиції вікна. o SWP_NOOWNERZORDER Повідомляє, що не слід змінювати позицію вікна власника в Z-послідовності. o SWP_NOREDRAW Не перемальовує вікно. o SWP_NOREPOSITION Такий самий як і SWP_NOOWNERZORDER. o SWP_NOSENDCHANGING Заважає вікну отримати повідомлення WM_WINDOWPOSCHANGING. o SWP_NOSIZE Повідомляє, що потрібно ігнорувати параметри завдання розмірів вікна. o SWP_NOZORDER Зберігає поточне положення в Z-послідовності(ігнорує повідомлення hWndInsertAfter parameter). o SWP_SHOWWINDOW Відображає вікно.

Якщо ця функція виконається успішно, вона поверне відмінне від нуля значення. Ну, ось тепер ми можемо пересувати і змінювати в розмірах чужі вікна. Для того, щоб змінити заголовок вікна, напишемо наступний код:

SetWindowText(FindWindow(nil, 'Безім'яний - Блокнот'), 'Дарова, ламерюга, типу ти потрапив. ');

Функції setwindowtext потрібно вказати лише два параметри: це дескриптор потрібного вікна та нове значення для заголовка. Ось взагалі і все!

Є ще одна цікава функція ShowWindow, яка дозволяє приховувати чи відображати вікна. Використовувати її потрібно так:

ShowWindow(FindWindow(nil, 'Безім'яний - Блокнот'), sw_hide);

У дужках вказуємо спочатку над яким вікном хочемо знущатися, а потім що саме ми хочемо з ним зробити. Як можливі дії можемо вказати:

* SW_HIDE Приховує вікно та активує інше. * SW_MAXIMIZE Розгортає вікно. * SW_MINIMIZE Згортає вікно. * SW_RESTORE Активує та виводить вікно. Якщо вікно було розгорнуте або згорнуте – відновлює вихідний розмір та позицію. * SW_SHOW Активізує та виводить вікно з його оригінальним розміром та положенням. * SW_SHOWDEFAULT Активізує з установками, заданими в структурі STARTUPINFO, яка була передана при створенні процесу програмою, яка запускає потрібну програму. * SW_SHOWMAXIMIZED Виводить вікно у розгорнутому вигляді. * SW_SHOWMINIMIZED Виводить вікно у вигляді піктограми на панелі завдань. * SW_SHOWMINNOACTIVE Виводить вікно в згорнутому вигляді на панелі завдань і не передає йому фокус введення, тобто. вікно, яке раніше було активно залишається активно як і раніше. * SW_SHOWNA Відображає вікно у його поточному стані. Активневікно залишається активним, як і раніше. * SW_SHOWNOACTIVATE Виводить вікно в його останньому положенні та з останніми використовуваними розмірами. Активне вікно залишається активним, як і раніше. * SW_SHOWNORMAL Виводить вікно. Якщо воно було згорнуте або розгорнуто – відновлює його оригінальні розміри та позицію

Але вся складність дій полягає в тому, що в заголовку Блокнота відстежується ім'я поточного файлу і використовувати значення "Безім'яний - Блокнот" ми можемо не завжди: (. Тим більше це не тільки у випадку з блокнотом. Але є вихід: адже функції FindWindow для пошуку вікна ми вказуємо не тільки заголовок потрібного вікна, але ще його клас.Який же це вихід скажете ви, заголовок вікна ми бачимо, значить знаємо, що вказувати - а клас вікна.

У пакет Delphi входимо спеціальна утиліта для відстеження всіх активних процесів, вона називається WinSight32. Ось нею ми й скористаємося. Запустіть її, покопайтеся у списку процесів, шукайте рядок, де значиться поточний заголовок потрібного вікна, наприклад Блокнота, і в лівій частині цього рядка у фігурних дужках ви знайдете ім'я класу вікна. Для блокноту це буде "Notepad". Тепер знаючи ім'я класу вікна, ми можемо переписати пошук вікна таким чином:

ShowWindow(FindWindow('Notepad', nil), sw_hide);

Тепер замість заголовка вікна ми вказуємо значення nil, ігноруючи даний параметр.

Є ще один чудовий спосіб передачі команд вікнам. - Функція PostMessage. Їй як параметри потрібно вказати:

* Дескриптор вікна, якому надсилається повідомлення або такі значення: o HWND_BROADCAST Повідомлення буде надіслано всім вікнам верхнього рівня системи, включаючи неактивні та невидимі вікна, overlapped-вікна, та PopUp-вікна, але повідомлення не будепосилатися дочірнім [Child] вікнам. o NULL Поводиться як функція PostThreadMessage з переданим їй dwThreadId параметром. * Надіслане повідомлення * Перший параметр повідомлення * Другий параметр повідомлення

Наприклад, якщо надіслати повідомлення wm_quit блокноту – вікно буде закрито без виведення будь-яких повідомлень про необхідність збереження!

PostMessage(FindWindow('Notepad', nil), wm_quit, 0, 0);