Читаем О чём не пишут в книгах по Delphi полностью

И, хотя мы и взяли размер буфера с хорошим запасом, нельзя исключать ситуации, когда имя класса окажется длиннее, чем буфер. Ничего страшного при этом не произойдет, т. к. мы передаем в функцию размер буфера специально для того, чтобы она не пыталась что-то записать за пределами буфера. Но в этом случае завершающий строку символ #0 не попадет в буфер, и при попытке дальше работать с этой строкой какая-нибудь другая функция может, не найдя конца строки в пределах буфера, попытаться поискать этот конец за его пределами, что приведет к непредсказуемым результатам. Поэтому на всякий случай записываем #0 в последний символ буфера. Если имя класса оказалось длиннее буфера, это обрежет строку по границе буфера, а если короче, то это ничему не повредит, т. к. признак конца строки будет в буфере где-то раньше, а все символы после него все равно игнорируются. После этого остается только создать новый элемент в дереве, а чтобы заполнить его дочерние элементы — вызвать EnumChildWindows для получения списка дочерних окон. Так как в EnumChildWindows передается та же функция обратного вызова, получается рекурсия, которая останавливается тогда, когда функция доходит до окна, не имеющего дочерних окон. Ранее мы говорили, что программа EnumWnd демонстрирует три метода получения строки через параметр типа LPTSTR, но пока мы увидели только два (действительно, трудно показать три различных метода на примере получения двух строк). Чтобы показать третий вариант — организацию буфера через строки типа PChar — перепишем функцию EnumWindowsProc (листинг 1.23). В исходном коде программы EnumWnd этот вариант присутствует в виде комментария. Можно убрать этот комментарий, а закомментировать, наоборот, первый вариант, чтобы попробовать, как работает получение строки с помощью PChar.

Листинг 1.23. Функция обратного вызова EnumWindowsProc (второй вариант)

// Ниже приведен другой вариант функции

// EnumWindowsРrос, который отличается от предыдущего тем,

// что буфер для получения заголовка окна организуется

// вручную с помощью переменной типа PChar, а не string. По

// своим функциональным возможностям оба варианта равноценны.

function EnumWindowsProc(Wnd: HWND; ParentNode: TTreeNode): Bool; stdcall;

const

 ClassNameLen = 512;

var

 TextLen: Integer;

 Text: PChar;

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

 Node: TTreeNode;

 NodeName: string;

begin

 Result:= True;

 if Assigned(ParentNode) and (GetParent(Wnd) <> HWND(ParentNode.Data)) then Exit;

 // Здесь, в отличие от предыдущего варианта к длине,

 // получаемой через WM_GETTEXTLENGTH, добавляется

 // единица, потому что нужно вручную учесть добавочный

 // байт для завершающего нуля.

 TextLen:= SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0) + 1;

 // Выделяем требуемое количество памяти. Так как

 // компилятор не освободит эту памяти автоматически,

 // необходимо использовать блок try/finally, иначе будут

 // утечки памяти при исключениях.

 Text:= StrAlloc(TextLen);

 try

// Так как для буфера даже при пустом заголовке будет

 // выделен хотя бы один байт, здесь можно отправлять

// WM_GETTEXT, не проверяя длину строки, как это было

 // в предыдущем варианте — буфер всегда будет

 // корректным.

SendMessage(Wnd, WM_GETTEXT, TextLen, LParam(Text));

 // Обрезаем слишком длинною строку. Модифицировать

 // PChar сложнее, чем string. Вставка нуля в середину

 // строки приводит к тому, что все API-функции будут

 // игнорировать "хвост", но на работу StrDispose это не

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных