что такое hwnd delphi
Работаем с окнами и объектами. Delphi. Api. Часть 1
В этом наброске хочу углубиться в изъезженную тему про работу с формами и объектами на них.
Чтобы что-то сделать с объектом, нам нужно получить его handle — уникальный идентификатор.
Ты наверняка уже сталкивался с api функциями, предназначенными для этих целей. Перечислим их: FindWindow, FindWindowEx, GetWindow. Это далеко не все, но нам их хватит, оговорюсь, что я с GetWindow полностью обхожусь, его мы рассмотрим чуток позднее.
[FindWindow]
синтаксис:
function FindWindow(lpClassName, lpWindowName: PChar): HWND;
HWND это тот же integer, то есть функция возвращает число, handle объекта. Функция работает только для форм, то есть объектов верхнего уровня.
параметры:
lpClassName — класс объекта;
lpWindowName — заголовок, в данном случае формы.
Хочу обратить внимание, что функция находит объект, только если:
переданные класс и заголовок полностью соответствуют классу и заголовку объекта,
заголовок соответствует, а переданный класс nil,
заголовок передан nil, а класс соответствует,
передано nil и nil.
В последнем случае функция возвращает первое по счету окно. Это я к тому, что если FindWindow(nil, ‘wnd.txt — Блокнот’) нам вернет handle окна блокнота, то FindWindow(nil, ‘Блокнот’) или FindWindow(nil, ‘wnd.txt’) нам вернет 0, мы должны знать точные данные об окне. Реализовывать поиск по части заголовка мы будем позже.
[FindWindowEx]
синтаксис:
function FindWindowEx(Parent, Child: HWND; ClassName, WindowName: PChar): HWND;
Здесь у нас всё аналогично, но появляется пара новых параметров:
Parent — handle родительского объекта;
Child — handle дочернего объекта.
Как parent, так и Child имеют право быть нулями.
[пример]
Долго думал, что привести в качестве примера, рассмотрим изъезженное до дыр получение данных из формы логина qip. Как мы знаем (а если не знаем — используем Spy++), форма логина имеет класс TManForm — достаточно редко найдешь форму с таким классом, заголовок нам уже не интересен. На форме стоит TGroupBox, в одном экземпляре, в котором мы находим TComboBox с «ICQ#/Email/SN». Вычислим handle этого объекта:
Если наша функция чего-то не находит, возвращается 0.
[GetWindow]
Эта вещь будет помощней FindWindow и FindWindowEx, синтаксис:
function GetWindow(hWnd: HWND; uCmd: UINT): HWND;
Не похоже на FindWindow, не так ли? Рассмотрим что есть что:
hWnd — handle некоего объекта;
uCmd — команда, действие, указывает как получить новый handle.
Константы для uCmd начинаются с префикса GW_ (от GetWindow), рассмотрим ближе:
GW_CHILD — дочерний объект, первый по счету (их может быть много);
GW_OWNER — по идее должно возвращать handle окна-владельца. Учитываем, что окно-родитель и окно-владелец могут быть разными, это тема для отдельного разговора, оговорюсь лишь, что для определения родителя можно использовать GetParent;
GW_HWNDFIRST, GW_HWNDLAST, GW_HWNDNEXT, GW_HWNDPREV — константы для получения первого, последнего, следующего или предыдущего объекта на этом уровне, то есть когда одинаковый родитель (или его нет).
GW_MAX — честно говоря, не очень понимаю, будет время — разберусь и напишу об этом)
Тут нужно обратить внимание на то, что ни с заголовком, ни с классом объекта функция не работает, нам надо проверять их вручную.
[узнаём заголовок или класс объекта]
Приведу сразу готовые функции, которые использую сам:
это для заголовка.
Что касается класса:
На этом пока остановлюсь, в следующих частях жди примеры работы с GetWindow и функции поиска окон, в том числе рекурсивные, основанные на нём. Также, может быть, рассмотрю работу и с меню.
Подпишись на rss и следующие части не пройдут мимо)
А в качестве постового сегодня ссылка на случай, если Вам нужно создать резюме в Ростове-на-Дону.
Что такое hwnd delphi
FindWindow
GetWindow
GetWindowText
SetWindowText
IsWindow
MoveWindow
IsWindowVisible
EnableWindow
IsWindowEnabled
WindowFromPoint
ShowWindow
CloseWindow
SetWindowPos
GetClassLong
SetClassLong
GetWindowLong
SetWindowLong
GetDesktopWindow
GetParent
Функция FindWindow
ClassName Имя класса, по которому призводится поиск среди ВСЕХ окон системы. WindowName Заголовок окна
Один из параметров может быть равен nil, тогда поиск ведется по другому параметру.
Пример:
Функция GetWindow
function GetWindow(Wnd : HWND; Param) : HWND
Функция возвращает описатель окна удовлетворяющий запросу.
Функция GetWindowText
hWnd Описатель того окна, текст которого нужно получить. lpString Переменная, в которую будет помещен результат nMaxCount
Максимальная длина текста, если текст длиннее, то он обрезается.
Функция SetWindowText
function SetWindowText(hWnd: HWND; lpString: PChar): BOOL;
Устанавливает текст окна.
hWnd Описатель того окна, текст которого нужно установить lpString Строка, содержащая устанавливаемый текст.
Функция IsWindow
function IsWindow(hWnd: HWND): BOOL; Возвращает True, если окно с заданным описателем существует и False в противном случае.
Hwnd Описатель нужного окна
Функция MoveWindow
MoveWindow(hWnd: HWND; X, Y, nWidth, nHeight: Integer; bRepaint: BOOL): BOOL; Перемещает окно в новую позицию.
hWnd Описатель перемещаемого окна. X, Y, nWidth, nHeight Соответственно: новые координаты X,Y; новая ширина, высота. bRepaint Булево значение, показывающее будет ли окно перерисовано заново.
Функция IsWindowVisible
function IsWindowVisible(hWnd: HWND): BOOL;
Возвращает True если данное окно видимо.
hWnd Описатель окна.
Функция EnableWindow
function EnableWindow(hWnd: HWND; bEnable: BOOL): BOOL;
Устанавливает доступность окна(окно недоступно, если оно не отвечает на события мыши, клавиатуры и т.д.). Аналог в Delphi свойство Enabled компонентов. EnableWindow возвращает True, если всё прошло успешно и False в противром случае.
hWnd Описатель окна. bEnable Булево значение, определяющее доступность окна.
Функция IsWindowEnabled
function IsWindowEnabled(hWnd: HWND): BOOL;
Возвращает для заданного окна: True, если окно доступно и False в противном случае.
hWnd Описатель окна.
Функция WindowFromPoint
WindowFromPoint(Point: TPoint): HWND;
Возвращает описатель окна, находящегося в данной точке экрана.
Point Координата точки экрана типа TPoint(определение типа смотри ниже)
Функция
Функция ShowWindow
function ShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL; Показывает или прячет окно.
hWnd Описатель нужного окна nCmdShow Константа, определяющая, что будет сделано с окном: SW_HIDE SW_SHOWNORMALSW_NORMAL SW_SHOWMINIMIZED SW_SHOWMAXIMIZED SW_MAXIMIZE SW_SHOWNOACTIVATE SW_SHOW SW_MINIMIZE SW_SHOWMINNOACTIVE SW_SHOWNA SW_RESTORE SW_SHOWDEFAULT SW_MAX
Функция CloseWindow
function CloseWindow(hWnd: HWND): BOOL; stdcall;
Закрывает окно.
hWnd Описатель закрываемого окна.
SetWindowPos
function SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT): BOOL; stdcall;
Устанавливает окно в новую позицию
hWnd Оптсатель окна hWndInsertAfter Описатель окна, перед которым в списке Z-Order будет вставлено окно hWnd, или одна из следующих констант: HWND_BOTTOM Поместить окно на дно списка Z-Order HWND_TOP Поместить окно на верх списка Z-Order X, Y, cx, cy
uFlags Одна или несколько (разделенных OR) следующих констант: SWP_NOSIZE Не изменять размер окна после перемещения (cx, cy игнорируются) SWP_NOZORDER Не изменять положение окна в списке Z-Order SWP_SHOWWINDOW Сделать окно видимым после перемещения SWP_HIDEWINDOW Спрятать окно после перемещения SWP_NOACTIVATE Не передавать фокус окну после перемещения SWP_NOMOVE Не перемещать окно (игнорируется X, Y)
Функция GetClassLong
function GetClassLong(hWnd: HWND; nIndex: Integer): Integer;
Эта функция возвращает 32-разрядное целое, взятое из определенного поля записи TWndClassEx указанного окна.
hWnd Описатель окна nIndex Константа, определяющая что будет возвращено. Должна быть одна из следующих: GCL_MENUNAME Возвращает указатель на строку, содержащую имя меню класса, определенного в файле ресурсов связанного с некоторой программой. GCL_HBRBACKGROUND Возвращает описатель (HBRUSH) кисти фона, ассоциированной с классом GCL_HCURSOR Возвращает описатель (HCURSOR) курсора, фссоциированного с классом GCL_HICON Возвращает описатель (HICON) пиктограммы, ассоциированной с классом GCL_HMODULE Возвращает описатель процесса (HMODULE), зарегистртровавшего класс. GCL_CBWNDEXTRA Возвращает размер памяти (в байтах), выделенной под хранение дополнительных данных ДАННОГО ОКНА. Описание как использвать эту память, смотри в описании функции GetWindowLong GCL_CBCLSEXTRA Возвращает размер памяти (в байтах), выделенной под хранение дополнительных ДАННОГ КЛАССА GCL_WNDPROC Возвращает адрес оконной процедуры, связанной с классом. GCL_STYLE Возвращает стиль класса (наличие того или иного стиля проверяется побитовой операцией And с помощью констант типа cs_XXX ) GCL_HICONSM
Функция SetClassLong
function SetClassLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Integer; Парная функция функции GetClassLong. Устанавливает в нужное поле соответствующее значение.
Функция возвращает старое значение поля, чтобы его потом можно было исправить или же возврашается ноль, если что-то пошло не так как надо.
hWnd Описатель окна nIndex Одна из констант GCL_XXX из функции GetClassLong. В зависимости от значения этого поля будет изменнено нужное поле.
Обратите внимание:при установке полей-указателей необходимо приведение типа Pointer к типу Integer.
Функция GetWindowLong
function GetWindowLong(hWnd: HWND; nIndex: Integer): Longint; Возвращает информацию о некотором окне в виде 32-битного целого.
hWnd Описатель окна nIndex Константа,определяющая, что будет возвращено. Должна быть одна их следующих:
GWL_WNDPROC Возвращает адрес оконной процедуры, связанной с данным окном. Полученный адрес (после соответсвующих приведений типов) может использоваться в функции CallWindowProc. Данное значение обычно используют, если хотят заменить существующую оконную процедуру на свою собственную, при этом, чтобы не потерять работоспособности окна, обычно и используют CallWindowProc. GWL_HINSTANCE Возвращает описатель приложения, заданный при создании окна функцией CreateWindowEx. GWL_HWNDPARENT Возвращает описатель (HWND) родительского окна GWL_STYLE Возвращает стиль окна. Конкркетные значения стилей узнаются при помощи побитовой операции And и констант WS_XXX GWL_EXSTYLE Возвращает расширенный стиль окна. Конкркетные значения стилей узнаются при помощи побитовой операции And и констант WS_EX_XXX GWL_USERDATA Возвращает 32-битное целое, ассоциированное с окном (это последний параметр в вызове CreateWindow или CreateWindowEx) GWL_ID Возвращает идентификатор окна (он не имеет ничего общего с описателем окна!), задаваемый параметром hMenu для дочерних окон при вызове CreateWindow или CreateWindowEx
Функция SetWindowLong
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint;
Парная к функции GetWindowLong. Изменяет аттрибуты определенного окна.
Функция возвращает старое значение свойства, если вызов прошел удачно или нуль в противном случае.
hWnd Описатель окна nIndex Константа, определяющая, какое свойство будет изменено. Должна быть одной из констант GWL_XXX из описания функции GetWindowLong dwNewLong Новое значение свойства, определяемого константой nIndex
Обратите внимание:при установке полей-указателей необходимо приведение типа Pointer к типу Integer.
Функция GetDesktopWindow
function GetDesktopWindow: HWND
Функция возвращает описатель окна Рабочего Стола (Desktop). Без параметров.
GetParent
function GetParent(hWnd: HWND): HWND;
Возвращает описатель родительского окна для окна hWnd.
hWnd Описатель окна
Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре
Что такое hwnd delphi
Несколько предварительных сурьезных слов.
Режимы отображение окон верхнего уровня.
Системное меню и кнопки заголовка.
Некоторые дополнительные возможности.
Итоги
Режимы отображение окон верхнего уровня.
Давайте попробуем для начала сделать чужое окно активным (мы уже это делали, когда спасали чужое окно в картинку). Для этого можно использовать одну из следующих функций:
Синтаксис:
function SetForeGroundWindow(Wd: Hwnd):Boolean;
Описание: Показывает верхние окно системы.
Wnd: Идентификатор окна.
Возвращаемое значение: True- если функция отработала, False- при ошибке.
Синтаксис:
procedure BringWindowToTop(Wnd: HWnd);
Описание: Активизирует и перемещает Wnd в вершину стека перекрывающихся окон.
Wnd: Всплывающее или дочернее окно.
Возвращаемое значение: Нет
Теперь попробуем проделать с неким окном, имеющим идентификатор окна HD:HWnd некие стандартные действия:
1) Свернуть данное окно;
2) Развернуть данное окно;
3) Закрыть данное окно.
Все данные действия могут быть проделаны с окном при помощи стандартной функции SendMessage или PostMessage, с различными параметрами:
1) SendMessage(HD,WM_SYSCOMMAND,SC_MINIMIZE,0);
2) SendMessage(HD,WM_SYSCOMMAND,SC_MAXIMIZE,0);
3) SendMessage(HD,WM_SYSCOMMAND,SC_CLOSE,0);
Существуют и другие константы, для сообщений вида WM_SYSCOMMAND:
Можно, так же, показать или скрыть окно, используя функцию API:
Синтаксис:
function ShowWindow(Wnd: HWnd; CmdShow: Integer);
Описание: отображает или прячет окно образом, указанным параметром CmdShow.
SW_HIDE
SW_MAXIMIZE
SW_MINIMIZE
SW_RESTORE
SW_SHOW
SW_SHOWDEFAULT
SW_SHOWMAXIMIZED
SW_SHOWMINIMIZED
SW_SHOWMINNOACTIVE
SW_SHOWNA
SW_SHOWNOACTIVATE
SW_SHOWNORMAL
Константы позволяют скрыть/показать окно с различными типами (распахнутым, свернутым, неактивным и пр.)
Давайте теперь попробуем решить ряд наиболее часто встречающихся проблем:
procedure TForm1.Button1Click(Sender: : TObject); // допустим, закрываем по нажатию на клавишу
begin
EnumWindows (@EnumMiniProc, 0); // отрабатываем сворачивание окон.
end;
Для того чтобы окно программы тоже сворачивалось достаточно убрать строку If Wd<>Form1.Handle then в EnumMiniProc
Конечно, можно поставить еще массу условий, по которым будут минимизироваться окна, но это уже дело конкретной задачи.
Еще один пример, который бывает зачастую нужен:
2) Как закрыть (или постоянно закрывать) окна, например содержащие в заголовке подстроку «Реклама»
Begin
GetWindowText(Wd,Nm,255); // считываем текст заголовка окна
ZName:=AnsiUpperCase(String(Nm)); // преобразуем к верхнему регистру т.е РЕКЛАМА
If Pos(ReclamaName,zName)<>0 then SendMessage(WD,WM_SYSCOMMAND,SC_CLOSE,0);
EnumProc := TRUE; // продолжаем перебирать все окна системы.
end;
procedure Tform1.Timer1Timer(Sender: TObject); // будем проверять по таймеру…
begin
Timer1.Interval:= TimeInterval; // установим время до следующего вызова
EnumWindows (@EnumCloseProc, 0); // отрабатываем закрытие окон.
end;
Понятно, что настоящая реклама не дает себе таких заголовков, но общий принцип останется тем же, а так попробуйте поискать общее в заголовках окна, названии классов окна и т.п. Кроме того, использование таймера чревато тем, что окон в системе очень много и за установленный интервал времени все окна не будут отработаны, это приведет к замедлению работы системы. Но решение данной подзадачки автор оставляет за читателем, благо особых сложностей с этим нет (увеличения интервала времени, установка логического условия о том, что проверка уже идет, вставка оператора Application.ProcessMessages и проч.)
На этом все возможности этих функций API не исчерпываются, но общий принцип отображения чужих окон, закрытия, перемещения и прокрутки изложен, дальше нужно от конкретной задачи.
Системное меню и кнопки заголовка.
Системное меню, отображает обычно ряд доступных стандартных функций применимых к окнам.
Обычно к таким функциям относятся следующие команды (применительно к локализованным Windows, в англоязычных названия будут другие, есть подозрения, что английские J):
Все эти команды, а так же ряд других (например, добавленных пользователем) доступны при нажатии на иконку, расположенную в левой части заголовка окна.
Ряд команд имеет кнопку, расположенную в правой части заголовка. Обычно таких кнопок три: свернуть, восстановить, закрыть. Иногда добавляется кнопка помощь.
Синтаксис:
function GetSystemMenu(Wnd: HWnd; Revert: Bool): HMenu;
Описание: Считывает системное меню окна для копирования и модификации.
Для начала надо получить идентификатор системного меню. При помощи приведенной выше функции.
Далее попробуем определить, что именно содержится в системном меню (надо сказать, что приведенные ниже функции API справедливы для любых меню, а не только системных, но об этом несколько позже):
Синтаксис:
function GetMenuString(Menu: HMenu; IDItem: Word; Str: PChar;
MaxCount: Integer; Flag: Word): Integer;
Описание: копирует метку элемента меню в Str. параметры:
Menu: идентификатор меню.
IDItem: идентификатор элемента меню.
Str: принимающий буфер.
MaxCount: размер буфера.
Flag: Одна из констант меню
Возвращаемое значение: Количество реально скопированных байт.
Как видно из описания функции возможно два варианта определения списка по номеру или по выполняемой команде.
Если Flag = mf_ByCommand тогда в качестве IDItem передаются стандартные команды (см. константы в WM_SYSCOMMAND. Предыдущий раздел).
Например
I:=GetMenuString (hMenu, SC_CLOSE, Mn,255,mfByCommand);
Возвращает название пункта системного меню, отвечающего за закрытие окна. I=0 указывает, что такого пункта в системном меню нет.
Если Flag = mf_ByPosition тогда в качестве IDItem передается порядковый номер искомого пункта меню, начиная с 0
Например
I:=GetMenuString (hMenu, 0, Mn,255,mfByPosition);
Количество элементов меню можно получить при помощи функции
Синтаксис:
function GetMenuItemCount(Menu: HMenu): Word;
Описание: определяет число меню и элементов меню верхнего уровня в указанном меню.
Вот как приблизительно может выглядеть функция, которая определяет системное меню окна:
Procedure GetSysMenuItem (Wd:HWND); // Передаем идентификатор окна.
Var
I,K,Q:Word;
hMenuHandle : HMENU;
Nm:Array[0..255] of Char;
Begin
ListBox1.Clear; // Очистим список перед использованием.
hMenuHandle:=GetSystemMenu(Wd, FALSE); // Получим идентификатор
if (hMenuHandle = 0) then Exit; // Если такого меню нет, то выходим
Q:=GetMenuItemCount(hMenuHandle); // Определяем количество пунктов меню.
For k:=0 to Q-1 do
Begin
i:=GetMenuString(hMenuHandle,k,Nm,255,MF_BYPOSITION); // Считываем название
ListBox1.Items.Add(String(Nm)); // Добавляем в список.
End;
End;
Итак, мы получили список пунктов системного меню. Пустые строки, скорее всего, означают разделители. Так же используются акселераторы (&)
Следующим шагом будет определение состояния того или иного пункта меню.
Синтаксис:
function GetMenuState(Menu: HMenu; ID, Flags: Word):
Описание: Считывает инфоpмацию состояния для указанного элемента меню.
Menu: идентификатор меню.
IDItem: идентификатор элемента меню.
Flag: Одна из констант меню
Возвращаемое значение: Маски флагов из следующих значений:
Procedure GetSysMenuStatus (Wd:HWND); // Передаем идентификатор окна.
Var
K,Q,l:Word;
hMenuHandle : HMENU;
Nm:Array[0..255] of Char;
S:String;
Begin
Form1.ListBox1.Clear; // Очистим список перед использованием.
hMenuHandle:=GetSystemMenu(Wd, FALSE); // Получим идентификатор
if (hMenuHandle = 0) then Exit; // Если такого меню нет, то выходим
Q:=GetMenuItemCount(hMenuHandle); // Определяем количество пунктов меню.
For k:=0 to Q-1 do
Begin
GetMenuString(hMenuHandle,k,Nm,255,MF_BYPOSITION); // Считываем название
S:=String(Nm);
l:=GetMenuState(hMenuHandle,k,MF_BYPOSITION); // Считываем состояние пункта меню
If (L and mf_Separator=mf_Separator) then S:=’—————-‘; // Если это разделитель
If (l and mf_Grayed<>mf_Grayed) then S:='(a)’+S; // Если пункт меню подсвечен
Form1.ListBox1.Items.Add(S); // Добавляем в список.
End;
End;
Точно так же можно определять и многие другие параметры пунктов меню. Для получения большего количества информации о пункте меню можно использовать
Синтаксис:
function GetMenuItemInfo(Menu: HMenu; ID, Flags: Word; Info:TMenuItemInfo): Word;
Описание: Выдает информацию о пункте меню.
1) Изменять статус пунктов меню (и соответствующих им кнопок заголовка)
2) Удалять «лишние» пункты меню
3) Добавлять «необходимые» пункты меню.
Будем решать эти вопросы по порядку.
Синтаксис:
function EnableMenuItem(Menu: HMenu; IDEnableItem, Enable: Word): LongBool;
Описание: разрешает, блокирует или затеняет элемент меню в соответствии со значением параметра Enable.
Menu: Идентификатор меню.
IDEnableItem: идентификатор или позиция элемента меню или помечаемый всплывающий элемент.
Enable: Комбинация констант
совмещенные с константами
Следует заметить, что некоторые пункты системного меню связаны с состоянием окна (такие которые задают положение окна и возможность перемещать и изменять его размеры) и даже если удается формально запретить некий пункт (например развернуться) это не значи т, что он будет действительно недоступен.
Включение/выключение пункта меню
procedure EnableSysItem(WD:HWND;Number:Integer);
// передаем описатель окна и номер пункта
Var
hMenuHandle : HMENU;
i : LongInt;
l,r : word;
begin
If (Number mfs_Disabled then R:=R or mfs_Disabled
else R:=R or mfs_Enabled;
i:=LongInt(EnableMenuItem(hMenuHandle,Number,R));
end;
Как уже было сказано, это процедура будет работать далеко не для всех пунктов меню, например кнопку и пункт меню закрыть она будет запрещать очень даже хорошо, а вот например пункт развернуть далеко не всегда. Для того, чтобы сделать это наверняка нужно п росто удалить такую возможность. Т.е. удалить соответствующий пункт системного меню.
Синтаксис:
procedure DeleteMenu(Menu: HMenu Position, Flags: Word): Bool;
Добавить пункт меню можно двумя способами: просто добавить пункт в конец меню:
Синтаксис:
function AppendMenu(Menu: HMenu; Flags, IDNewItem: Word; Name: PChar): Bool;
Описание: Пpисоединяет в конец меню новый элемент, состояние котоpого опpеделяется Flags.
Или вставить пункт меню настроив все необходимые параметры
Синтаксис:
function InsertMenuItem (Menu: HMenu; Flags, IDNewItem: Word; Item: :TMenuItemInfo): Bool;
Описание: Вставляет пункт меню.
Ну и как результат всех наших стараний напишем процедуру, которая разрешает или запрещает кнопку, строку системного меню «закрыть» (а так же комбинацию клавиш Alt+F4):
Удаление или восстановление кнопки закрыть окно.
// Отключает или разрешает так же пункт меню, и комбинацию Alt+F4
Procedure CloseXbtn (Wd:HWND; Enable:Boolean);
Var
hMenuHandle : HMENU;
Begin
hMenuHandle:=GetSystemMenu(Wd,False); // Получим идентификатор
if hMenuHandle=0 then Exit; // Если меню нет
If Enable then // Если надо добавить пункт меню
AppendMenu (hMenuHandle, mf_ByCommand, SC_Close,’&Закрыть Alt+F4′);
Else DeleteMenu(hMenuHandle, SC_Close, mf_ByCommand);
End;
Конечно, куда правильнее было бы использовать функцию InserMenuItem вместо AppendMenu, тогда можно было бы поставить слева значек «закрыть». Но это уже для любителей самим повозиться с API, очень уж не хочется лишать их этого удовольствия J.
Ну, и, наконец, для развлечения тех, кто продрался сквозь все эти кошмары работы с системным меню, предлагаю маленькое развлечение.
Иногда появляется необходимость нарисовать, что-нибудь (например, кнопку) в заголовке чужого окна (а возможно и своего). Это можно сделать очень и очень просто.
Синтаксис:
function DrawFrameControl (DC:HDC;Rc :Trect; uType,uStyle:Word ): Bool;
Описание: Рисует один из элементов в заголовке окна.
DC : контекст устройства в котором происходит рисование.
Rc : Область в которой будет происходить рисование
UType: Тип элемента одна из констант:
DFC_BUTTON Кнопка
DFC_CAPTION Заголовок
DCF_MENU Меню
DFC_SCROLL Полоса прокрутки
Ustyle : Стиль элемента одна из констант:
DFCS_BUTTON3STATE Кнопка с тремя состояниями
DFCS_BUTTONCHECK Флажок
DFCS_BUTTONPUSH Кнопка
DFCS_BUTTONRADIO Переключатель
DFCS_BUTTONRADIOIMAGE Картинка для переключателя
DFCS_BUTTONRADIOMASK Маска для переключателя
DFCS_CAPTIONCLOSE Кнопка закрыть
DFCS_CAPTIONHELP Кнопка помощь (только Window 9x)
DFCS_CAPTIONMAX Кнопка развернуть
DFCS_CAPTIONMIN Кнопка свернуть
DFCS_CAPTIONRESTORE Кнопка восстановить
Для полос прокрутки
DFCS_SCROLLCOMBOBOX Линейка прокрутки выпадаюшего списка DFCS_SCROLLDOWN Кнопка вниз DFCS_SCROLLLEFT Кнопка влево DFCS_SCROLLRIGHT Кнопка вправо DFCS_SCROLLSIZEGRIP Размерная ручка DFCS_SCROLLUP Кнопка вверх
Заметьте, что это функция только рисует элемент заголовка.
14 Отрисовка «фальшивой» кнопки закрыть в заголовке окна.
Procedure DrawFalseClose (Wd:HWND; xPos:Integer);
Var DC:HDC;
begin
DC:=GetWindowDC(Wd); // Получим контекст устройства окна
If DC>0 then
Begin
DrawFrameControl (DC,Rect(xPos,4,xPos+16,020),DFC_Caption,DFCS_CaptionClose);
ReleaseDC(Wd,DC); // Освободим контекст устройства.
End;
end;
Некоторые дополнительные возможности
С приложениями (и окнами верхнего уровня в частности) можно делать огромное количество вещей. Если быть честным, то останавливаться подробно на этих возможностях я не собирался. Но оказалось, что решение этих задач интересует достаточно многих. В этом раз деле попробуем привести некоторые, на мой взгляд, наиболее полезные из них.
Синтаксис:
procedure SetWindowText(Wnd: HWnd; Str: PChar);
Описание: Устанавливает название заголовка для окна или текст оpгана упpавления с помощью стpоки, указанной в Str.
Wnd: Идентификатоp окна или оpгана упpавления.
Str: Стpока (заканчивающаяся пустым символом).
Возвращаемое значение:Нет.
И текст, который иллюстрирует работу данной функции, например, находит окно Дельфы и меняет ее заголовок с «Delphi» на любой другой
Замена текста в заголовке окна.
// Передаем новое название например Дельфи
Procedure ChangeDelphi (NewName:String);
Var Wd:HWND;
Nm:Array[0..255] of Char
St : String;
I:Integer;
Begin
Wd:= FindWindow(‘TAppBuilder’,Nil); // Находим заголовок по классу окна Delphi
If Wd 0 then // Если слово Дельфи есть в заголовке
Begin
Delete(St,i,Lenght(‘Delphi’); // Удаляем
Insert(NewName,St,i); // Вставляем
SetWindowText(Wd,Pchar(St)); // Отправляем новый заголовок окну.
End; // Все
end;
Зачастую необходимо выяснить, не зависло ли окно (или вернее насколько живо оно откликается на попытки системы достучаться до него) Для этих целей можно использовать следующий текст
Существует пара функций:
Синтаксис:
function FlashWindow(Wnd: HWnd; Invert: Bool): Bool;
И вторая функция, которая описана для Delphi 5 а для 3 нет, что обидно, но мы это исправим.
Синтаксис:
function FlashWindowEx(var pfwi: FLASHWINFO): BOOL;
function FlashWindowEx(var pfwi: FLASHWINFO): BOOL; stdcall;
implementation
function FlashWindowEx; external user32 name ‘FlashWindowEx’;
end;
А теперь сама программа, не забудьте подключить модуль кому нужно:
Итак, мы научились управлять чужими окнами верхнего уровня: