В этом разделе разобраны простые примеры, находящиеся на компакт-диске. Все эти примеры уже упоминались ранее, и каждый из них иллюстрирует какую-то отдельно взятую возможность API. Более сложным обобщающим примерам, которые задействуют сразу несколько возможностей API и VCL, посвящен следующий, третий раздел данной главы.
1.2.1. Пример EnumWnd
Программа EnumWnd представляет собой простой пример использования функций EnumWindows
и EnumChildWindows
, а также функций обратного вызова, которые необходимы для работы этих двух функций. Программа ищет все окна, созданные на данный момент в системе, и отображает их в виде дерева: каждый узел дерева соответствует одному окну, дочерние узлы соответствуют дочерним окнам данного окна (рис. 1.8).
Программа EnumWnd является также примером того, как можно работать с параметрами типа LPTSTR, через которые функции Windows API возвращают программе строковые значения. В Char
, использование строк типа string
и строк типа PChar
. Все три способа реализованы в примере EnumWnd
. На главной и единственной форме программы EnumWnd
размещены два компонента: TreeWindow
типа TTreeView
и кнопка BtnBuild
. Обработчик нажатия кнопки выглядит очень лаконично (листинг 1.21).
BtnBuild
procedure TFomWindows.BtnBuildClick(Sender: TObject);
begin
Screen.Cursor:= crHourGlass;
try
TreeWindows.Items.Clear;
EnumWindows(@EnumWindowsProc, 0);
finally
Screen.Cursor:= crDefault;
end;
end;
Рис. 1.8. Окно программы EnumWnd
Все, что делает этот обработчик, — это очищает компонент TreeWindows
и вызывает EnumWindows
, передавая ей функцию обратного вызова EnumWindowsProc
, в которой и выполняется основная работа. Сразу отметим, что в этом примере мы будем использовать одну и ту же функцию обратного вызова как для EnumWindows
, так и для EnumWindowsProc
. Сама функция обратного вызова выглядит следующим образом (листинг 1.22).
EnumWindowsProc
(первый вариант)// Это функция обратного вызова, которая будет
// использоваться при вызове EnumWindows и EnumChildWindows.
// Тип второго параметра не совпадает с типом, который
// указан MSDN. Однако TTreeNode, как и любой класс,
// является указателем, поэтому может использоваться везде,
// где требуется нетипизированный указатель — на двоичном
// уровне между ними нет разницы. Указатель на функцию
// обратного вызова в EnumWindows и EnumChildWindows в
// модуле Windows.dcu объявлен как нетипизированный
// указатель, поэтому компилятор не контролирует
// соответствие реального прототипа заявленному.
function EnumWindowsProc(Wnd: HWND; ParentNode: TTreeNode): Bool; stdcall;
// Система не предусматривает возможности узнать, какова
// длина имени класса, поэтому при получении этого имени
// приходится выделять буфер большой длины в надежде, что
// имя класса не окажется еще длиннее. В данном примере
// размер этого буфера определяется константой ClassNameLen.
// Крайне маловероятно, что имя класса скажется длиннее,
// чем 511 символов (512-й зарезервирован для завершающего
// нулевого символа).
const
ClassNameLen = 512;
var
// Здесь будет храниться заголовок окна
Text: string;
TextLen: Integer;
// Это — буфер для имени класса
ClassName: array[0..ClassNameLen — 1] of Char;
Node: TTreeNode;