Взаємодія з чужими вікнами - delphi sources faq

Уявіть собі, дурний користувач сидить як ні в чому небувало з розумним виглядом вже в який раз намагається скласти документ в Microsoft Word'e, але раптом вікно починає шалено скакати по екрану, в його заголовку виводяться непристойні повідомлення, воно то згортається, то розгортається, змінюючи постійно свої розміри, а під кінець зовсім зникає, несучи в небуття весь текст, який з такою працею набив ламерюга. а якщо так себе в будь-який момент може повести будь-яка програма. враження від цього залишаться на довго.

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

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

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

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

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

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

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

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

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

  • 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". Тепер знаючи ім'я класу вікна ми можемо переписати пошук вікна таким способом:

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

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

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

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