А. Григорьев - О чём не пишут в книгах по Delphi

Тут можно читать онлайн А. Григорьев - О чём не пишут в книгах по Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство БХВ-Петербург, год 2008. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    О чём не пишут в книгах по Delphi
  • Автор:
  • Жанр:
  • Издательство:
    БХВ-Петербург
  • Год:
    2008
  • Город:
    СПб
  • ISBN:
    978-5-9775-019003
  • Рейтинг:
    4.25/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

А. Григорьев - О чём не пишут в книгах по Delphi краткое содержание

О чём не пишут в книгах по Delphi - описание и краткое содержание, автор А. Григорьев, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.

Для программистов

О чём не пишут в книгах по Delphi - читать онлайн бесплатно ознакомительный отрывок

О чём не пишут в книгах по Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор А. Григорьев
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Код для получения списка процессов показан в листинге 1.42.

Листинг 1.42. Получение списка процессов с помощью Tool Help

procedure TProcessesInfoForm.FillProcessList;

var

SnapProc: THandle;

ProcEntry: TProcessEntry32;

Item: TListItem;

begin

ClearAll;

// Создаем снимок, в котором сохраняем все процессы, а

// затем в цикле получаем информацию о каждом из этих

// процессов, перенося ее в ListProcesses

SnapProc := CreateToolhelp32Snapshot(TH32CS_SNAPROCESSES, 0);

if SnapProc <> INVALID_HANDLE_VALUE then

try

ProcEntry.dwSize := SizeOf(TProcessEntry32);

if Process32First(SnapProc, ProcEntry) then repeat

Item := ListProcesses.Items.Add;

Item.Caption := ProcEntry.szExeFile;

Item.SubItems.Add(IntToStr(ProcEntry.tb32ProcessID);

Item.SubItems.Add(IntToStr(ProcEntry.th32ParentProcessID));

Item.SubItems.Add(IntToStr(ProcEntry.cntThreads));

// Сохраняем PID в поле Data соответствующего

// элемента списка. Вообще, поле Data имеет тип

// Pointer, а PID - это целое число, но т.к. оба этих

// типа 32-битные, их можно приводить друг к другу

Item.Data := Pointer(ProcEntry.th32ProcessID);

until not Process32Next(SnapProc, ProcEntry);

finally

CloseHandle(SnapProc);

end

else

begin

ListProcesses.Visible := False;

LabelProcessError.Caption :=

'Невозможно получить список процессов:'#13#10'Ошибка №' +

IntToStr(GetLastError);

end;

end;

Для получения списка модулей данного процесса также используется снимок. Функция CreateToolhelp32Snapshotвызывается с параметром TH32CS_SNAPMODULE, в качестве второго параметра ей передается PID процесса, модули которого требуется получить. Навигация по снимку модулей осуществляется с помощью функций Module32Firstи Module32Next. В остальном код получения списка модулей совпадает с кодом, приведенным в листинге 1.42.

1.3.1.2. Получение списка и свойств окон

Список окон, созданных процессом, формируется с помощью функции EnumWindows, которая позволяет получить список всех окон верхнего уровня (т.е. расположенных непосредственно на рабочем столе). Для каждого из этих окон с помощью функции GetWindowThreadProcessIDопределяется идентификатор процесса. Окна, не принадлежащие выбранному процессу, отсеиваются.

Для каждого из окон верхнего уровня, принадлежащих процессу, с помощью функции EnumChildWindowsищутся дочерние окна, а для каждого из найденных таким образом дочерних окон — его дочерние окна. Здесь следует учесть, что EnumChildWindowsвозвращает не только дочерние окна заданного окна, но и все окна, которыми владеют эти дочерние окна. Чтобы в дереве окон не было дублирования, при построении очередного уровня дерева окон отбрасываются все окна, непосредственным родителем которых не является данное окно. Код, выполняющий построение дерева, приведен в листинге 1.43.

Листинг 1.43. Получение всех окон, относящихся к данному процессу

function EnumWindowsProc(Wnd: HWnd; ParentNode: TTreeNode): BOOL; stdcall;

var

Text: string, TextLen: Integer;

ClassName: array [0..ClassNameLen - 1] of Char;

Node: TTreeNode; NodeName: string;

begin

Result := True;

// функция EnumChildWindows возвращает список

// не только прямых потомков окна, но и потомков его

// потомков, поэтому необходимо отсеять все те окна,

// которые не являются прямыми потомками данного

if Assigned(ParentNode) and (THandle(ParentNode.Data) <> GetAncestor(Wnd, GA_PARENT)) then Exit;

TextLen := GetWindowTextLength(Wnd);

SetLength(Text, TextLen);

if TextLen > 0 then GetWindowText(Wnd, PChar(Text), TextLen + 1);

if TextLen > 100 then Text := Copy(Text, 1, 100) + '...';

GetClassName(Wnd, ClassName, ClassNameLen);

ClassName[ClassNameLen - 1] := #0;

if Text = '' then NodeName := 'Без названия (' + ClassName + ')';

else NodeName := Text + ' (' + ClassName + ')';

NodeName := '$' + IntToHex(Wnd, 8) + ' ' + NodeName;

Node := ProcessesInfoForm.TreeWindows.Items.AddChild(ParentNode, NodeName);

Node.Data := Pointer(Wnd);

EnumChildWindows(Wnd, @EnumWindowsProc, LParam(Node));

end;

function EnumTopWindowsProc(Wnd: HWnd; PIDNeeded: Cardinal): BOOL; stdcall;

var

Text: string;

TextLen: Integer;

ClassName: array[0..ClassNameLen - 1] of Chars;

Node: TTreeNode;

NodeName: string;

WndPID: Cardinal;

begin

Result := True;

// Здесь отсеиваются окна, которые не принадлежат

// выбранному процессу

GetWindowThreadProcessID(Wnd, @WndPID);

if WndPID = PIDNeeded then

begin

TextLen := GetWindowTextLength(Wnd);

SetLength(Text, TextLen);

if TextLen > 0 then GetWindowText(Wnd, PChar(Text), TextLen + 1);

if TextLen > 100 then Text := Copy(Text, 1, 100) + '...';

GetClassName(Wnd, ClassName, ClassNameLen);

ClassName[ClassNameLen - 1] := #0;

if Text = '' then NodeName := 'Без названия (' + ClassName + ')'

else NodeName := Text + ' (' + ClassName + ')';

NodeName := '$' + IntToHex(Wnd, 8) + ' ' + NodeName;

Node := ProcessesInfoForm.TreeWindows.Items.AddChild(nil, NodeName);

Node.Data := Pointer(Wnd);

EnumChildWindows(Wnd, @EnumWindowsProc, LParam(Node));

end;

end;

procedure TProcessesInfoForm.FillWindowList(PID: Cardinal);

begin

if PID = 0 then Exit;

EnumWindows(@EnumTopWindowsProc, PID);

end;

В отличие от примера EnumWndиз разд. 1.2.1 здесь для функций EnumWindowsи EnumChildWindowsпредусмотрены разные процедуры обратного вызова. Связано это с тем, что окна верхнего уровня необходимо фильтровать по принадлежности к выбранному процессу, и параметр функции обратного вызова служит для передачи PID этого процесса. А их дочерние окна фильтровать по процессам не обязательно (мы предполагаем, что если некоторое окно верхнего уровня принадлежит данному процессу, то и все его дочерние окна также принадлежат этому процессу), зато нужно передавать указатель на элемент дерева, соответствующий родительскому окну, чтобы процедура знала, где размещать новый элемент. Таким образом, смысл параметра меняется, поэтому требуется новая процедура обратного вызова. (В принципе, можно было бы проверять, есть ли у найденного окна родитель, и в зависимости от этого трактовать параметр так или иначе, используя приведение типов. Но сильно усложняет код, поэтому в учебном примере мы не будем использовать такой способ.)

Примечание

Как уже было сказано ранее, мы полагаем, что если некоторое окно верхнего уровня принадлежит данному процессу, то и все его дочерние окна также принадлежат этому процессу. В общем случае это неверно: функция CreateWindow(Ex)позволяет при создании нового окна использовать в качестве родительского окно другого процесса. Поэтому наш код ошибочно отнесет подобные окна к тому процессу, к которому относятся их родители, а не к тому, который их реально создал. Здесь мы пренебрегаем такой возможностью, потому что для ее учета не нужны дополнительные знания API, необходимо просто запрограммировать более сложный алгоритм отсева. В учебном примере, посвященном API, реализация такого алгоритма была бы неоправданным усложнением. но в реальных программах эту возможность следует учесть.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


А. Григорьев читать все книги автора по порядку

А. Григорьев - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




О чём не пишут в книгах по Delphi отзывы


Отзывы читателей о книге О чём не пишут в книгах по Delphi, автор: А. Григорьев. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x