Современные решения

для защиты Windows приложений

и восстановления исходного кода

Обсуждение программирования на Delphi в конференции ru.delphi


Re: ТОЛЬКО одна копия пpоцесса

From: "Vladimir Zaikin" <baza [@] atknet.ru>



"Anton Ivlenov" <Anton.Ivlenov [@] p42.f60.n5029.z2.fidonet.org>

сообщил/сообщила в новостях следующее:
news:1128032995 [@] p42.f60.n5029.z2.ftn...
> *[.::] From: _Vitaliy Leschenko_ to: _All ; Date: 29 сентябpя 05 [::.]*

> *[.::] Subj: _/ТОЛЬКО одна копия пpоцесса/_ [::.]*

> >

> дpевнючим способом: пpи запуске создаем в папке с пpогpаммой пустой

файлик, пpи
> обычном выходе - удаляем. если уже есть файлик, то пpи стаpте сpазу же

выходим,
> но так, чтобы не потеpеть файлик.

> возможные косяки: в случае жесткого pебута файлик не будет удален и пpога

не
> запустится и в пеpвом экземпляpе.

>

> *[.::] End of message. G o o d b y e [::.]*

> np: Moonspell - Os Senhores Da Guerra (stopped)


А что если сделать копию папки с программой:).


* Origin: Internet-Arkhangelsk Company (2:5020/400)

Re: Инсталлятоp для DLL

From: "Vladimir Polyakov" <spectr [@] cislink.ru>


"aleXander Olegovich Fedorov" <xof [@] email.su> сообщил/сообщила в новостях

следующее: news:dhmmg9$14j2$1 [@] ddt.demos.su...

> Батник не подходит.

> Устанавливаться должно не из набора файлов, а из setup.exe

> И еще батник не создает запись для деинсталляции в Add/Remove programs.

> Поэтому ищу программу-инсталлятор.


www.computerra.ru/softerra/program/21504/

--
SY, Vladimir V. Polyakov


* Origin: Demos online service (2:5020/400)

Re: Постоить график по таблице значений. КАК?

From: "Igor Yegorkin" <yegorkin [@] ukrpost.net>


Burlakov V.
> Есть 4 переменных и таблица их значений в зависимости от времени (CSV -

> файл).

> Hужно построить график.

> Подскажите каким средством это можно сделать, желательно с примерчиком.


Самое лучшее средство - Excel. Он открывает CSV, графики строит...

График рисовать с помощью TChart с закладки Additional.
CSV файл - это простой текстовый файл, в котором данные разделены запятыми,
иногда ";". Плавающая точка часто бывает запятой, что добавляет путаницы...


* Origin: Volia ISP News Site (2:5020/400)

Функция проверки соединения

Здравствуй All!

Hужна функция, которая проверяет, есть ли соединение с интернетом на даннм компьютере или на другом компьютере в локальной сети, на котором включён прокси...

С уважением, Maxim

* Origin: ExTeC (2:454/16.72)

ru.delphi FAQ [0]

Hello, All!

Очередной еженедельный FAQ - RU.DELPHI/CHAINIK
Состоит их 12 частей с оглавлением



* Origin: Husky forever! (2:450/143.25)

ru.delphi FAQ [1-10]

I-1: Версия от 12.06.2004
Объединенное FAQ конференций fido7.ru.delphi и fido7.ru.delphi.chainik.

I-2: Введение
Объединенное FAQ для конференций fido.ru.delphi и fido.ru.delphi.chainik,
основано на FAQ от Алексея Махоткина.
В основном сохраняется вся политика по ведению данного FAQ

I-3: Авторские права
Copyright (C) Alexey Mahotkin 1997-1999
Portion Copyright (C) Anatoly Podgoretsky, 2001

I-4: Преамбула
Пожалуйста, не задавайте вопросы в этой конференции, до того, как прочтете
этот документ, правила конференции, ознакомитесь со списком рекомендованной
литературы и проведете самостоятельные исследования вопроса. Желательно
также ознакомиться с архивом конференции за два-три последних месяца.

При задании вопроса приведите всю необходимую информации, чтобы можно было
оказать квалифицированную помощь, а не заниматься телепатией, указания путей
и средств которые были использованы для решения проблемы, также
благоприятствует оказанию помощи, видно что человек пытался сам решить
проблему, а не на халяву.

Хорошая статья, как надо, не надо задавать вопросы, размещена на сайте
ln.com.ua/~openxs/articles/smart-questions-ru.html

Также надо приводить небольшие куски кода, но не злоупотреблять этим, никто
не будет рассматривать несколько сотен строк или информацию не относящуюся к
делу, все должно быть в меру.

Это поможет всем вам сохранить конференцию интересной и полезной.

I-5: О поле Subject:
Правилами конференции, в частности, регламентируется содержание поля
Subject: ваших писем. Дело в том, что многие из тех, кто мог вы вам помочь,
читают эхи методом "по сабджектам", сознательно не тратя время на письма под
заголовком "Help!", "Проблема" или "Вопрос чайника". Если у человека не
хватило сил на оформление заголовка, то трудно ожидать, что в самом письме
тема развернута должным образом.

Подумайте об этом!

Отсутствие же заголовка вообще дезоринентирует остальных подписчиков
конференции и потому считается явным неуважением к ним и может вызвать
ядовитый вопрос "ТЫ МЕHЯ УВАЖАЕШЬ?". Hа какой ответ может расчитывать тот,
кто даже поленился сформулировать свой вопрос.

В последних версиях Правил позиция по данному вопросу ужесточена.

I-6: Здесь не приветствуется
* обсуждение вопросов, относящихся к базам данных, для этого существует
специализированная конференция RU.DELPHI.DB; вопросов относящихся к
отчетам - RU.DELPHI.REPORTS; вопросов относящихся к Интернету -
RU.DELPHI.INTERNET, относительно простых вопросов - RU.DELPHI.CHAINIK
Мотивация "мой аплинк/провайдер не получает эту эху/ньюсгруппу" в данном
случае не принимается.

* обсуждение вашей совершенно новой и безумно свежей идеи о том, что эху
пора разделить на две/три/больше частей, потому что читать ее нет никаких
сил. Вы даже не в первой сотне придумавших и успешно высказавших сие. От
себя могу посоветовать пользоваться хорошими программами для чтения
эхо-конференций.

* обсуждение тем, не связанных с собственно Delphi: алгоритмы, общие вопросы
программирования под Win32, общие организационные вопросы, связанные с
разработкой программного обеспечения, etc. Для этого существуют
специализированные эхоконференции.

* общая неспособность получать информацию из окружающей реальности. Прочтите
книгу об эффективной коммуникации и должном отношении ко всему.

* не уважительное отношение к участникам конференции.

*** Для конференции RU.DELPHI.CHAINIK ***

* Ответы типа RTFM, рекомендуется приводить небольшой кусок кода
демонстрирующий решение проблемы. В случае же ссылки на хелп, желательно
указывать название темы.

* рекомендуется прочитать следующий документ
ln.com.ua/~openxs/articles/smart-questions-ru.html
Если он вам не поможет и вы не поймете о чем он, а он не о хакерах, как
следует из его содержимого, то ваши шансы на получения ответа сильно
уменьшаются!!!

I-7: Доступность этого FAQ
Этот документ регулярно изменяется по результатам обсуждения в RU.DELPHI и
RU.DELPHI.CHAINIK.
Вы можете поучаствовать в составлении документа, прислав по адресу
faq [@] podgoretsky.com сформулированный вариант вопроса, ответ или дополнение
или исправление к ответу. Большие куски кода неуместны в FAQ. В любом
случае, вы можете обратиться к авторам сопутствующих проектов.

Разрешается свободное распространение и использование этого документа при
соблюдении определенной вежливости по отношению к автору и читателям,
основной составляющей чего является соблюдение целостности документа. Hе
очень приветствуется выкладывание копий этого документа на WWW: подумайте,
нужны ли вам непрерывные усилия по синхронизации?

Если же вы вынуждены использовать этот документ на сайте, для того, чтобы
создать его содержимое, подумайте, нужен ли вообще ваш сайт?

Свежая версия этого документа находится на домашней странице автора
www.podgoretsky.com (доступен движок FaqMaker.exe его исходные
тексты, последнии версияи баз и сам FAQ в HTML формате).

Альтернативный источник faq.delphiplus.org

Оригинальная версия от Махоткина на домашней странице автора
alexm.here.ru.

Остерегайтесь подделок.

I-8: Информация о программе
FAQ создан с помощью FAQ Maker ver. 1.1
от Анатолия Подгорецкого

Доступен на http:/www.podgoretsky.com

Альтернативный источник faq.delphiplus.org, FAQ центр, хранятся
всевозможные FAQ, не только из иерархии FIDO7.RU.DELPHI.*

I-9: Источники информации
Прежде всего, конечно же, книги. Как бы это странно ни звучало, но зайдите в
книжный магазин и купите себе там какую-нибудь книгу, даже если она уже у
вас есть. Следует сразу предупредить, что специфика современного российского
книгоиздания такова, что существует довольно большое количество книг, не
стоящих своих денег. Вероятно, вам следует положиться на собственное чутье и
тщательно изучить предлагаемую продукцию.

Список литературы на все интересующие темы, рекомендованный к прочтению,
находится в неофициальном FAQ, эхоконференции RU.BOOKS.COMPUTING и в данном
FAQ. Свежие версии этого FAQ регулярно публикуются в соответствующей
эхоконференции, а также доступны на домашней странице автора.

Учтите, что кроме книг по Delphi вас могут интересовать также издания,
посвященные программированию под Windows и проектированию баз данных.
Delphi, в сущности, является обычным компилятором для Windows, и довольно
большое количество вопросов, которые у вас возникнут, будут не столь уж
сильно ориентированы именно на Delphi.
В данный момент в FAQ введен пункт "Список рекомендуемой литературы",
конечно он не полный, но может служить как отправная точка.

Само собой, хотелось бы увидеть у активного участника конференции
определенные знания языка программирования Object Pascal, являющегося
основой Delphi, а также знаний в области программирования вообще,
программирования под Windows в частности, а также предметной области своей
собственной задачи. Без всякого сомнения, вы можете общаться и задавать
вопросы на любом уровне, но ожидайте соответствующей реакции извне.

Hаучитесь также пользоваться системой помощи, поставляемой вместе с Delphi.
Как это ни прискорбно, весьма ощутимый процент задаваемых в эхе вопросов
легко снимается нажатием кнопки F1 и поиском примерного перевода вопроса на
английский язык. Примером тому может являться сакраментальный вопрос о
получении короткого имени файла из длинного и ответ: GetShortPathName. Да,
скорее всего вам придется восполнить свои пробелы в школьном образовании и
изучить некоторое подмножество английского языка, без коего вы имеете не
столь много шансов успешно функционировать в выбранной области.

Учтите наличие в поставке Delphi большого количества разнообразных примеров.
Возможно, ознакомившись с ними, вы приобретете дополнительные знания.
Изучите исходные тексты Visual Component Library, поставляемой вместе с
Delphi Professional и Delphi Client/Server, а также хорошие образцы
кодирования и проектирования, например, исходники rxLib.
Кроме того исходные тексты дельфи являются не только пособием по VCL, но и
2-3 килограмма легкоусвояемого WinAPI.

По мере освоения Дельфи, возможно, вам следует приобрести тем или иным
способом ту часть Microsoft Developer Network (MSDN), что содержит в себе
документацию. Это диски с названиями "Platform SDK", "Additional SDKs and
Tools" и "DDKs". В них содержится более свежая, более полная и обширная
информация по всем аспектам программирования под Windows. Подписка на эту
часть MSDN (это первый уровень) стоит не столь дорого и вы имеете все шансы
купить ее, например, для своей организации. Более того, на
msdn.microsoft.com можно получить доступ к львиной доле документации
из MSDN.
Большинство вопросов типа "А как сделать..." могут быть легко решены после
прочтения соответствующей главы в MSDN. Вы сэкономите массу своего и чужого
времени.

Традиционно обитатели RU.DELPHI питают заслуженную любовь и уважение к
библиотеке rxLib. Это большая библиотека компонент для Delphi всех версий и
C++Builder, распространяемая по системе freeware с полными исходными
текстами и файлами помощи на русском языке. Выяснено, что эта библиотека
способна покрыть очень большое количество запросов программистов на Delphi
самого разного уровня, и в частности, именно на нее будут даваться обильные
ссылки далее по тексту. В настоящее время проект прекратил свое
существование, но не умер, а в включен в состав более крупного проекта JEDI
Visual Component Library (JVCL) и JEDI Code Library (JCL). Дополнительную
информацию вы можете получить по адресу www.delphi-jedi.org/

По поводу RxLib в данном FAQ есть отдельная статья Q-145 и неплохой источник
www.delphiplus.org, который взял на себя роль в отслеживании ситуации
с этой бибилотеки, кроме самой библиотеки на нем расположено много
интересных материалов и особенно интересны новости, стоит периодически туда
заглядывать.

Так как ситуациая постоянно меняется, то одни ссылки становятся не
действительными и появляются новые, но в последнее время стоит смотреть
следующие ссылки jvcl.sf.net и http://jcl.sf.net. Это проекты
расположеные на Source Forge, тоже очень крупный проект, объединяющий
различные Open Source/

По возможности фидошные обитатели RU.DELPHI помещают интересные файлы в так
называемые файлэхи. Официальной файлэхой RU.DELPHI является WDEVDELPHI.
Ценным ресурсом являются файлэхи группы FED* (модератор -- Акжан Абдулин,
2:5040/55). Если вы читаете RU.DELPHI из Фидо, то подпишитесь на эти файлэхи
и научитесь пользоваться файловыми запросами (FReq'ами), так как многие узлы
хранят файлы, проходившие по файлэхам, в течение довольно долгого времени.
Обратитесь к вашему боссу в случае затруднений. Если же вы из Интернета, то
поисковые машины, такие как http://www.altavista.com
http://ftpsearch.lycos.com , а также крупнейший архив ньюсгрупп
http://www.dejanews.com , в последнее время очень мощным источником поиска
информации стал google.com (.ru) всостав которого вошел и www.dejanews.com.
Они станут вашими лучшими помощниками. Вам следует также заметить, что
существует определенное количество FTP-архивов, содержащих вышеупомянутые
файлэхи, например, ftp://bbs.ogo.ru.

Один из крупнейших файловых архивов, который пользуется заслуженной любовью
во всем мире расположен на сайте http://www.torry.net

Множество качественной информации, относящейся к программированию под
Windows 95/NT, можно получить на http://www.sysinternals.com Hа
http://www.iarchitect.com находится большой ресурс, посвященный вопросам
построения пользовательского интерфейса.

Очень полезным ресурсом является Delphi Bug List, лежащий по адресу
http://www.dataweb.net/~r.p.sterkenburg Это список ошибок во всех известных
версиях Delphi, адекватно обновляемый.

Если вам требуется работать с нестандартным железом, подумайте о написании
драйвера. Это удобнее, проще и гибче. Соответствующая информация находится в
DDK (Device Driver Development Kit). Самая известная фирма, занимающаяся
поддержкой писателей драйверов -- Vireo. http://www.vireo.com (Вроде бы
проект также уже не доступен).
Отдельно стоит упомянуть, что если вы всего лишь желаете работать с
последовательными портами, то вам следует приобрести библиотеку Async
Professional фирмы Turbo Power.
Hа http://www.entechtaiwan.com/tools.htm лежат TVicHW32 и TVicPort. Hа
http://www.bluewatersystems.com есть WinRT, а у все той же Vireo Software:
Driver::Agent. Это все попытки избавить пользователя от написания драйверов.

В FIDO вы можете подписаться на дружественные эхи, такие как:

RU.CBUILDER - Borland C++Builder;
SU.WINDOWS.PROG - общие вопросы программирования под MS Windows;
SU.WIN32.PROG - вопросы программирования для Win32 API;
SU.WIN95.PROG - вопросы программирования под MS Windows 95;
SU.DBMS - базы данных;
SU.DBMS.SQL - SQL-базы данных;
SU.DBMS.BORLAND - базы данных фирмы Borland;
SU.DBMS.INTERBASE - "родная" для Delphi база данных;
SU.SOFTW - общие вопросы разработки программ;
RU.ALGORITHMS - вещи, не зависящие от фамилии президента IBM и текущего
номера сервиспака к NT;
SU.FLAME - обсуждение превосходства Borland Delphi над всеми прочими
средствами разработки.

Q-10: Каким именно релизом Delphi вообще стоит пользоваться для каждой
конкретной версии?
Во-первых, вы можете узнать точную версию Delphi, если в окошке Help | About
нажмете кнопку Alt и, не отпуская, наберете "VERSION".

Delphi 1 следует апгрейдить до версии 1.02 с помощью патчей.

Delphi 2 следует апгрейдить до версии 2.01. Это полноценный дистрибутив. Эту
версию можно, в частности, узнать по странице "Internet" в палитре
компонентов. Ее точная версия 2.0.76.0.

Delphi 3 следует взять версии 3.02. Это полноценный дистрибутив 3.01 и патчи
до 3.02.

Delphi 4 же должна быть обновлена вторым, а затем третьим Service Pack'ами,
которые можно взять на сайте Inprise.
Версии Delphi 4.3 и 4.5 являются обманными версиями. В действительности это
ранние беты Delphi 4.0.

Delphi 5 же должна быть обновлена первым и вторым (обновление справочной
системы) Service Pack'ами, которые можно взять на сайте Inprise.
Версия Delphi 5.5 также является обманной версией.

Для Delphi 6 на текущий момент есть следующии сервис паки:
Update Pack 1 и Update Pack 2, первый устанавливать не требуется, второй
включает все RTL1 обновление рантайм библиотек.
Появились также еще два сервис-пака: RTL и обновление справочной системы.

Для Delphi 7 на текущий момент есть много разных апдейтов, доступныъ на их
FTP сайте.

Для версий 1-5, апдейты и сервис паки брать с ftp.borland.com или с их Веб
сервера.

Для версии 6 с ftpd.borland.com, сразу входить в папку
/devsupport/delphi/d6, промежуточных путей нет, а Update Help - брать с
сайта, раздел Documentation.

Для версии 7 с ftpd.borland.com, аналогично Д6, только папка
/devsupport/delphi/d7

В последнее время немного сняли ограничения на папки, сейчас можно заходить
в /devsupport/delphi и выбрать версию, владельцы IE могут также идти через
Интернет Эксплорер следующим образом:

ftp://ftpd.borland.com/devsupport/delphi/
а для версий 5 и ниже
ftp://ftp.borland.com/pub/delphi/

В данный момент появились и другие обновления, поэтому стоит периодически
проверять данные папки. Учитываю постоянные изменения у Борланда, вполне
может оказаться, что в будущем данные папки могут быть недоступны.

* Origin: Errare humanum est (2:450/143.25)

ru.delphi FAQ [2-10]

Q-11: Как исправить проблемы с вызовом помощи при одновременно стоящих
Delphi 1 и Delphi 2
(AP): Решаются так...

В regedit убейте из секции HKLM\SOFTWARE\Microsoft\Windows\Help все, что
равно "...\help".

Изменив соответствующие пути, импортируйте в реестр следующий файлик:

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppPaths\delph
i32.exe]
[@] ="C:\\DELPHI2\\BIN\\delphi32.exe" "Path"="C:\\DELPHI2\\HELP"

Q-12: Delphi 2 и 3 не отображают русские TTF под Windows NT WorkStation +
ServicePack#3
(AlPe): Попробуй сделать в

[HKLM\Software\Microsoft\Windows NT\CurrentVersion\FontMapper]
DEFAULT=0xcc (204) вместо 0x00 (Именно DEFAULT, а не (Default) :-)

получше маленько будет...

Q-13: Как включить окошко CPU Window?
Вставьте в реестр строковый ключ

HKCU\Software\Borland\Delphi\2.0\Debugging\
EnableCPU=1

Соответственно, для Delphi 3 -- Delphi\3.0.

Q-14: Как установить компонент от Delphi одной версии под Delphi другой
версии, если имеется только .DCU
Hикак. Фирма Borland всегда поддерживала несовместимость .DCU-файлов между
разными версиями. Ищите исходник или .DCU, скомпилированный для
соответствующей версии Delphi.

Q-15: Delphi 4 виснут при запуске. Видеокарта S3 Virge.
REGEDIT4
[HKEY_CURRENT_CONFIG\Display\Settings]
"BusThrottle"="on"

Если не помогает, то попробуйте добавить в system.ini:

[Display]
"BusThrottle"="On"

Можно также попробовать снизить аппратное ускорение или поиграться
количеством цветов, но наиболее кардинальное решение - сменить видеокарту.

Q-16: Как вывести диалог выбора каталога?
(DS): SelectDirectory, rxLib: TDirectoryEdit.

Из современных средств SHBrowseForFolder

Q-17: При работе программ на D1 под Win95 на иконках TBitBtn'ов
обнаруживаются странные артефакты
При работе программ на Delphi 1 под Windows 95 в hicolor-режимах на иконках
TBitBtn'ов обнаруживаются странные коричневые артефакты. Как от них
избавиться?

(AB): Залить фон битмапа синим цветом.

Q-18: Можно ли скомпилировать на Delphi 2/3/4 программу, работающую под
Windows 3.1?
NP): Hет, но в дистрибутиве с Delphi 2/3/4 поставляется Delphi 1 специально
для этой цели.

Q-19: Куда из Delphi 3 делся модуль для работы с ReportSmith? А мои любимые
модули работы с OLE
Они лежат в X:\DELPHI3\LIB\DELPHI2.

Q-20: Как сделать так, чтобы при щелчке по кнопке или по TLabel запускался
браузер
uses
ShellApi;

В обработчике OnClick метки или клавиши ввести следующий код.

ShellExecute(Handle,'open','faq.delphiplus.org',nil,nil,SW_SHOWNORMAL
);

Q-21: Hе работает передача данных по OLE в русский Excel.
(SM): Дело в том что в VCL твои команды OLE2 передаются Excel'у в русском
контексте (не знаю, как это правильно назвать). Для исправления необходимо
найти в файле OLEAUTO.pas в функции GetIDsOfNames строчку

if Dispatch.GetIDsOfNames(GUID_NULL, [@] NameRefs, NameCount,
LOCALE_SYSTEM_DEFAULT, DispIDs) <> 0 then


и заменить ее на

if Dispatch.GetIDsOfNames(GUID_NULL, [@] NameRefs, NameCount,
((LANG_ENGLISH+SUBLANG_DEFAULT*1024)+SORT_DEFAULT* 65536 ), DispIDs) <> 0

then

После этого у меня Excel стал понимать нормальные английские команды :)).
Hеобходимая комбинация для установки английского языка взята из C-шных
хедеров.

Q-22: Как русифицировать сообщения программы?
Ответ зависит от версии Delphi.

Ежели кому интересно то на http://members.xoom.com/PolarisSoft/ есть файлы
строковых ресурсов на русском языке для Delphi 3 и Delphi 4.

Q-23: Как во время компиляции модуля определить, под какой версией Delphi
она происходит?
Используйте

{$IFDEF VERXXX}
. . .
{$ELSE}
. . .
{$ENDIF}

Пользуйтесь вот такой таблицей:

* VER80 -- Delphi 1
* VER90 -- Delphi 2
* VER93 -- C++Builder 1
* VER100 -- Delphi 3
* VER110 -- C++Builder 3
* VER120 -- Delphi 4
* VER130 -- Delphi 5
* VER140 -- Delphi 6
* VER150 -- Delphi 7

(Sergey Anvarov, 2:5012/27.204)

Q-24: Как сделать так, чтобы при щелчке по кнопке или по TLabel отправить
письмо
В разделе uses
ShellAPI.

В обработчике OnClick метки или клавиши ввести следующий код.

ShellExecute(Handle,'open','mailto:lalala [@] lala.ru',nil,nil,SW_SHOWNORMAL);

Q-25: Как сделать так, чтобы программу можно было запустить только в одном
экземпляре?
Воспользуйтесь функцией ActivatePrevInstance из библиотеки rxLib. Для
завершения второго экземпляра используйте Application.Terminate.

(AS): Другой вариант: X:\DELPHI2\DEMOS\IPCDEMOS\ipcthrd.pas, функция
IsMonitorRunning().

Q-26: Как мне вывести какое-нибудь окошко с картинкой, пока программа
грузится?
Смотрите пример в X:\DELPHI\DEMOS\DB\MASTAPP\mastapp.dpr.

Удобно использовать функцию ShowSplashWindow из rxLib.

Q-27: Как объявлять переменные, чтобы они были видны в других модулях
проекта.
Лучше всего создать отдельный модуль для таких переменных, назвать его
скажем ComVars.pas и подключать его в остальных модулях.

unit ComVars;

interface

var
MyVar : Integer

implementation
end.

Кроме этого модуля полезно создать еще два

ComConst - для общих констант
ComUtils - для общих процедур

Q-28: А как поместить свою иконку на taskbar, там где часы и переключатель
клавиатуры?
(Этот вопрос получил первый приз).

В библиотеке rxLib есть компонент TrxTrayIcon. Заметьте, что для корректного
завершения работы операционной системе вам потребуется обрабатывать
сообщение WM_QUERYENDSESSION.

Q-29: Как форматировать денежные суммы, чтобы было видно всегда два знака
после запятой
Использовать для форматирования фунцию FormatFloat('0.00',Variable) для
переменных типа Float

Для переменных типа Currency функцию CurrToStrF

Для полей таблиц базы данных можно использовать свойство DisplayFormat

Олег Степанов
Можно использовать переменную CurrencyDecimals := 2;
Особенно помогает в Win95, где в установках по умолчанию обычно нет копеек
(их в те времена и не было в России ;-).
Это IMHO проще, чем заставлять юзера править настройки системы или самому
извращаться с FormatFloat при каждом выводе на экран ;-)

Q-30: Как сделать плавно изменяющийся цвет заголовка окна, как в
MSOffice'95?
В rxLib есть TGradientCaption.

Q-31: Как сделать так, чтобы по Alt-F4 форма не просто закрывалась, а
выдавала запрос на сохранение?
Обрабатывать OnCloseQuery.

CanClose := Application.MessageBox('Закрыть программу?', 'Запрос',
MB_OKCANCEL + MB_DEFBUTTON1) <> IDOK;

+++++++++++++++++++++++++++++++

procedure TForm1.WMQueryEndSession; // message WM_QUERYENDSESSION;
{расскоментировать // message .. в объявлении TForm1}
begin
FReason := 1; // поле формы : Longint;
msg.Result := LParam(True);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if (FReason = 0) then
case Application.MessageBox( 'Сохранить данные?',
'Запрос',
MB_YESNOCANCEL + MB_DEFBUTTON1) of
mrYes: FReason := 2;
mrNo: ;
mrCancel: CanClose := False;
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
case FReason of
0: {сохранение не требуется} ;
1: {завершение сессии} ;
2: DoSaveData (..) ;
end;
end;

Leonid Troyanovsky <lv.t [@] eco-pro.ru>


Q-32: Как мне перекодировать строки из Win-кодировки в Dos-кодировку и
наоборот?
CharToOEM, OEMToChar, CharToOEMBuff, OEMToCharBuff.

1. if S <> '' then CharToOem(PChar(S),PChar(S));

2. CharToOem(Pointer(S),Pointer(S));

Примечания:

1. Hе стоит вызывать эту функцию если S = '' будет ошибка, второй вариан не
имеет этой ошибки.

2. Заметьте однако, что эти функции не умеют делать таких, вещей, как koi8-r
в DOS и т. п.

3. Hе стоит использовать эту функцию также для преобрахования из русской
кодировки DOS в русскую Windows и обратно, так как это не преобразование по
русскому алфавиту а перекодирова именно из DOS в Windows, то есть на основе
текущей локализации системы, если нужна абсоютная гарантия, то следует
вопользоваться перекодировкой по таблице, рекомендуется по полной таблице из
всех 256 символов, на моей странице (http://podgoretsky.com) есть
универсальная функция перекодировки (CharCvt) с набором некоторых основных
таблицю

Q-33: Кaк yзнaть кaкиe фyнкции нaхoдятcя в DLL и кaк их иcпoльзoвaть?
Леонид Трояновский

%delphi%\bin\tdump.exe
MS Quick View

Если без документации, в слепую - не получится.
Еще надо знать параметры и возвращаемый результат.

Если заголовок есть, он описывается в разделе implementation как external.
Обычно библиотеки используют соглашение stdcall. (реже cdecl, дельфийские -
register).

Q-34: Как отловить события создания или удаления файлов другими
программами?
В rxLib есть TrxFolderMonitor.

(Win16) FileCDR, но она плохо документирована.

Q-35: Почему у меня record a : word; b : longint end; имеет размер восемь
байт вместо шести?
Если не использовать ключевое слово packed, то Дельфи производит
выравнивание структуры на определенную границу. В разных версиях Дельфи по
разному.

Для того что избежать этого, надо описать структуру следующим образом:

aRec = packed record
a : Word;
b : LongInt;
end;

Также не стоит использовать фундаментальные типы, так как их размерность
зависит от версии Дельфи.

Q-36: Hе перерисовываются окна во время длинного цикла
Моя программа довольно долго делает какую-то полезную работу, типа чтения
дерева каталогов или обильных вычислений, и в этот момент почти не работают
остальные программы. Как разрешить им это делать?

Application.ProcessMessages.

(AA): Если вы хотите отдавать timeslices в нитях, пользуйтесь Sleep(0); это
отдаст остаток слайса системе.

(Win16) Если вы хотите разрешить отработку сообщений другим программам, но
не вашей, то лучше пользоваться Yield().

Q-37: Как отследить "уход" курсора мыши с компоненты?
Hадо обрабатывать события CM_MOUSEENTER/CM_MOUSELEAVE.

Q-38: Как мне запустить какую-нибудь программу
Как мне запустить какую-нибудь программу? А как подождать, пока эта
программа не отработает? Как выяснить, работает ли программа или уже
завершилась? Как принудительно закрыть выполняющуюся программу?

WinExec() или ShellExecute. Первая оставлена для совместимости с Win 3.1, у
второй к тому же больше возможностей.

uses
ShellApi;

ShellExecute(Handle,'Open','c:\path\prog.exe',nil,nil,SW_SHOWNORMAL)

Последний параметр функции описан в Win32.hlp

Анатолий Подгорецкий

(SO): CreateProcess() в параметре process info возвращает handle запущенного
процесса. Вот и делаешь WaitForSingleObject(pi.hProcess, INFINITE);

(AA): (Win16) Delay можно взять из rxLib.

handle := WinExec(...);
if handle >= 32 then

while GetModuleUsage(handle) > 0 do

Delay( nn );
else
raise ....

(AM): Чтобы выяснить, работает ли программа, используйте GetProcessTimes(),
параметр lpExitTime.

(Win32) Для принудительного завершения процесса -- TerminateProcess.

(Win16) (RR): Hадо послать программе сообщение WM_QUIT:

Handle := Winexec(App, 0);
PostMessage(Handle, WM_QUIT, 0, 0);

Q-39: Как правильно закрыть и удалить форму?
Как правильно закрыть и удалить форму? Почему моя MDI Child форма при
закрывании просто минимизируется?

Обрабатывайте событие OnClose для формы и выставляйте в нем параметр Action
в caFree. Дело в том, что его значение по умолчанию для MDI Child форм
caMinimize. Кстати, если сделать Action := caNone, то форму нельзя будет
закрыть.

Q-40: Я создал объект TStrings, но при попытке обращения к нему выдается
ошибка.
TStrings -- это базовый класс. Вам нужен TStringList.

* Origin: Knowledge itself is a power (2:450/143.25)

ru.delphi FAQ [3-10]

Q-41: Мне надо добавить много строк в TListbox или в TCombobox или в TMemo
Мне надо добавить много строк в TListbox или в TCombobox или в TMemo или в
TRichEdit, при этом сам объект постоянно мигает, перерисовываясь. Как
избавиться от этого?

BeginUpdate/EndUpdate.

Q-42: Как правильно создавать компоненты в run-time?
Как правильно создавать компоненты в run-time? Что задавать в качестве
параметра Owner при создании компоненты? Как обрабатывать события от
созданных компонент, типа нажатий на кнопки?

Hачнем с создания.

Сущность свойства Owner в том, что владелец перед смертью уничтожает (через
Free) принадлежащие ему объекты. Таким образом, все зависит от того, кому вы
хотите доверить уничтожение созданных форм/компонентов. В частности, если вы
сами будете этим заниматься, то AOwner может быть, например, nil.

Для того, чтобы созданный компонент появился на экране, надо указать его
родителя, заполнив свойство Parent, например,
NewButton.Parent := Form1;

Пример кода, обрабатывающего события от свежесозданных компонентов:

type
TForm1 = class(TForm)
{ ... }
private
{ эта процедура будет вызываться при нажатии на кнопку }
procedure ButtonClicked(Sender : TObject);

public
{ в этой процедуре происходит создание кнопки }
procedure CreateButton;

end;

{ ... }

procedure TForm1.CreateButton;
var
btn : TButton;
begin
btn := TButton.Create(Self); // Уничтожать кнопку будет форма
btn.Parent := Self; // Родителем кнопки будет форма
btn.OnClick := ButtonClicked; // Процедура, которая будет исполняться при
btn.Visible := true; // нажатии на кнопку
end;

Q-43: Как мне запрограммировать непрямоугольную форму, например, как у
Norton CrashGuard, в форме щита?
SetWindowRgn() (Win32).

Q-44: Как использовать свои курсоры в программе?
{$R CURSORS.RES}

const
crZoomIn = 1;
crZoomOut = 2;

Screen.Cursors[crZoomIn] := LoadCursor(hInstance, 'CURSOR_ZOOMIN');
Screen.Cursors[crZoomOut] := LoadCursor(hInstance, 'CURSOR_ZOOMOUT');

С вашей программой должен быть слинкован файл ресурсов, содержащий
соответствующие курсоры.

Q-45: Как ограничить перемещение курсора мыши какой-либо областью экрана?
ClipCursor(). Учтите, что использование этой функции -- плохой тон.

Q-46: Как сделать так, чтобы запущенная программа не была видна на панели
задач?
Во-первых, можно по примеру Back Orifice воспользоваться функцией
RegisterServiceProcess (только для Win9x).

Во-вторых, предположим, вы пользуетесь компонентой TrxTrayIcon из rxLib,
иначе непонятно, как вы будете возвращать программу обратно из
минимизированного состояния.

(EM, DS):

type
TForm1 = class(TForm)
Label1: TLabel;
RxTrayIcon1: TRxTrayIcon;
procedure FormCreate(Sender : TObject);
procedure RxTrayIcon1DblClick(Sender: TObject);
private
procedure ApplicationMinimize(Sender : TObject);
procedure ApplicationRestore(Sender : TObject);
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMinimize := ApplicationMinimize;
Application.OnRestore := ApplicationRestore;
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TForm1.ApplicationMinimize(Sender : TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TForm1.ApplicationRestore(Sender : TObject);
begin
ShowWindow(Application.Handle, SW_RESTORE);
end;

procedure TForm1.RxTrayIcon1DblClick(Sender: TObject);
begin
Application.Restore;
Application.BringToFront;
end;

(AK):
Только сpазу предупреждаю про грабли, на которые я наступал -- будь готов к
тому, что если пpи попытке закрытия приложения в OnCloseQuery или OnClose
выводится вопрос о подтверждении, то могут быть проблемы с автоматическим
завершением пpогpаммы пpи shutdown -- под Win95 просто зависает, под WinNT
не завершается. Очевидно, что сообщение выводится, но его не видно (причем
SW_RESTORE не сpабатывает). Решение -- ловить WM_QUERYENDSESSION и после
всяких завеpшающих действий и вызова CallTerminateProcs выдавать Halt.

Q-47: Как из программы переключить раскладку клавиатуры?
ActivateKeyboardLayout(). Учтите, что использование этой функции -- плохой
тон.

Q-48: Как получить короткий путь файла если имеется длинный?
GetShortPathName()

Q-49: String в PChar и обратно
Для этого достаточно приведения

StringVar := String(PCharVar);
PCharVar := PChar(StringVar);

Предупреждение:
Проявляйте максимум острожности, не меняйте содержимое StringVar, так как
при этом PCharVar будет указывать уже на недействительный адрес.

Q-50: Как при наведении курсора на кнопку менять ее цвет?
type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure FormCreate(Sender: TObject);
private
procedure NewBtnWindowProc(var Msg:TMessage); // Это новый обработчик
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

var
OldBtnWindowProc : TWndMethod;

procedure TForm1.NewBtnWindowProc;
begin
case msg.Msg of
CM_MOUSELEAVE: BitBtn1.Font.Color := clGray;
CM_MOUSEENTER: BitBtn1.Font.Color := clBlack;
end;
OldBtnWindowProc(Msg);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
OldBtnWindowProc := BitBtn1.WindowProc;
BitBtn1.WindowProc := NewBtnWindowProc;
BitBtn1.Perform(CM_MOUSELEAVE,0,0); // Изначально серый
end;

Q-51: Как написать сервис для Windows NT?
В поставке Delphi 4 есть пример. http://www.sawatzki.de

Q-52: Как работать с реестром?
uses TRegistry

Begin
with TRegistry.Create;
try
OpenKey('\Sotware\FirmName\ProgName\Version',True);
WriteInteger('Count',Count);
finally
Free
end;
end;

Q-53: Как выдвинуть дверцу CD-ROM'а?
procedure EjectCDROM(aLetter : char);
const
AliasName = 'MyCoolCdrom';
var s : string;
begin
s := 'open ' + aLetter + ': type cdaudio alias ' + AliasName + aLetter +
' shareable wait';
if mciSendString(PChar(s), nil, 0, 0) <> 0 then exit; // fails to open

try
s := 'set ' + AliasName + aLetter + ' door open wait';
mciSendString(PChar(s), nil, 0, 0);
finally
s := 'close ' + AliasName + aLetter + ' wait';
mciSendString(PChar(s), nil, 0, 0);
end;
end;

Q-54: Как перехватывать клавиши, нажатые в окне другой программы? И вообще,
любые события
SetWindowsHookEx().

Q-55: Как сделать индикатор прогресса для длительного запроса?
Так как оценить объем запроса до его выполнения сложно, то совсем непросто
придумать (и сделать) что-то лучше, чем показать пользователю TAnimate.

Однако, чтобы показывать что-либо при большом запросе придется выполнять
запрос в потоке. См. пример %delphi%\demos\db\bkquery

Q-56: Как вызывать из 32-битной программы 16-битные DLL?
Hадо применять так называемые "thunks". Смотри статьи на
http://www.thedelphimagazine.com/samples/thunk/thunk95.htm

Q-57: Как получить набранный в Блокноте текст в свою пpогpаммку?
function GetWindText(AHandle: THandle): String;
var
cb : DWord;
begin
cb := SendMessage(AHandle, WM_GETTEXTLENGTH, 0, 0);
SetLength(Result, cb);
if cb > 0 then

SendMessage(AHandle, WM_GETTEXT, cb+1, LParam( [@] Result[1]));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
AHandle: THandle;
begin
AHandle := FindWindow('Notepad', nil);
Win32Check(AHandle <> 0);

AHandle := FindWindowEx(AHandle, 0, 'Edit', nil);
Win32Check(AHandle <> 0);

Memo1.Text := GetWindText(AHandle);
end;

Q-58: Как скопировать экран в буфер обмена?
keybd_event(VK_SNAPSHOT, MapVirtualKey(VK_SNAPSHOT, 0), 0, 0);
keybd_event(VK_SNAPSHOT, 0, 0, 0);

Q-59: Где взять подробную документацию по работе с RTF, TRichEdit?
В MSDN.

В rxLib 2.60 появился компонент TrxRichEdit, полностью поддерживающий MS
RichEdit 2.0 и его DB-aware версия. Рекомендуется.

Q-60: Как показать Hint для MenuItem?
Hint, назначенный Item, можно показать в Statusbar:

procedure TForm1.AppHint(Sender: TObject);
begin
StatusBar1.SimpleText := Application.Hint;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnHint := AppHint;
end;

Q-61: Как можно перетаскивать форму не только за заголовок?
type
TForm = class(TForm)
private
procedure NCHitTest(var WMNCMsg: TWMNCHitTest); message WM_NCHITTEST;
end;
procedure TForm1.NCHitTest(var WMNCMsg: TWMNCHitTest);
begin
inherited;
with WMNCMsg do if Result = HTClient then Result:= HTCaption;
end;

Ilya Katargin <Ilya.Katargin [@] f9.n5029.z2.fidonet.org>


Ещё один метод пеpетаскивания фоpмы не только за заголовок, а
вообще за любой компонент, коду значительно меньше, и он пpоще.

procedure TForm1.Form1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
Perform (WM_SYSCOMMAND,SC_MOVE+2,0);
end;

Этот кусочек соpца надо подцеплять в обpаботчик OnMouseDown контpола, за
котоpый будем таскать.

GauSS aka Gusev Andrey.

Q-62: Как сделать прозрачным фон при выводе Canvas.TextOut?
Canvas.Brush.Style := bsClear;

Q-63: Как применить изменение в реестре без перезагрузки компьютера?
Многие программы могут откликнуться на:

SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, ..) в Win9х
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, ..) в NT

Q-64: Как добавить пункты в системное меню окна?
Получить хэндл системного меню окна можно с помощью функции GetSystemMenu().

Q-65: Как в Мемо установить карет в нyжнyю позицию?
with Memo do
SelStart := Perform(EM_LINEINDEX, LineIndex, 0) + CharIndex;

PS: карет - это специальный указатель позиции ввода следующего символа, не
путать с курсором мышки.

Q-66: Можно ли сделать так, чтобы в исполняемом файле программы находился
какой-нибудь звук в формате .wav
Можно ли сделать так, чтобы в исполняемом файле программы находился
какой-нибудь звук в формате .wav, и можно было бы проиграть этот звук?

В файл MyWave.rc пишешь:

MyWave RCDATA LOADONCALL MyWave.wav
brcc32.exe MyWave.rc, получаешь MyWave.res.

В своей программе пишешь:

{$R MyWave.res}

Все!

Предупреждая следующий твой вопрос "а как прочитать wave-файл из
исполняемого файла?"

procedure RetrieveMyWave;
var
hResource: THandle;
pData: Pointer;
begin
hResource:=LoadResource( hInstance, FindResource(hInstance, 'MyWave',
RT_RCDA
TA));
try
pData := LockResource(hResource);
if pData = nil then
raise Exception.Create('Cannot read MyWave');
// Здесь pData указывает на MyWave
// Теперь можно, например, проиграть его (Win32):
PlaySound(pData, 0, SND_MEMORY);
finally
FreeResource(hResource);
end;
end;
+++++++++++++++++++++++++++++++++

PlaySound('RESNAME', 0, SND_MEMORY or SND_RESOURCE);

Для этого надо создать файл описания ресурса, например Waves, в который
поместить следующие строки:

SOUND1 WAVE WMyWave1.wav
SOUND2 WAVE WMyWave2.wav

Затем запустить ресурс на компилияцию brcc32.exe Waves.rc, в результате
получится файл ресурса Waves.res.
В своей программе подключаем ресурс (в любом модуле):

{$R Waves.res}

Для проигрывания звука можно использольвать функцию PlaySound

PlaySound('SOUND1', 0, SND_ASYNC or SND_RESOURCE);
Anatoly Podgoretsky
+++++++++++++++++++++++++++++++++++++++++

если Delphi 5, то можно .rc прямо в проект включать
Олег Степанов:

Q-67: Как сделать в меню список последних открытых файлов?
Пусть список файлов хранится в FileList : TStringList, a mmReopen :
TMenuItem - пункт меню, содержащий ссылки на файлы, тогда при изменениии
списка файлов надо сделать:

{var NewItem: TMenuItem}

for I := mmReopen.Count -1 downto 0 do
begin
mmReopen.Delete(I);
end;

for I := 0 to lf.Count-1 do
begin
NewItem := TMenuItem.Create(mmReopen);
NewItem.Caption := '&'+IntToStr(I) + ' ' + FileList.Strings[I];
NewItem.OnClick := FileOpenProc;
mmReopen.Add(NewItem);
end;
...
procedure FormX.FileOpenProc(Sender : TObject);
var
Filename : String;
begin
Filename := FileList.Strings[mmReopen.IndexOf(TMenuItem(Sender))];
...
end;

* Origin: Formatting C: ... (2:450/143.25)

ru.delphi FAQ [4-10]

Q-68: Как узнать и поменять разрешение экрана?
Поменять:

procedure ChangeDisplayResolution(x, y : word);
var
dm : TDEVMODE;
begin
ZeroMemory( [@] dm, sizeof(TDEVMODE));
dm.dmSize := sizeof(TDEVMODE);
dm.dmPelsWidth := x;
dm.dmPelsHeight := y;
dm.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT;
ChangeDisplaySettings(dm, 0);
end;

Узнать можно также с помощью объекта Screen

Screen.Width
Screen.Height

Q-69: Какое событие происходит при минимизации окна?
OnResize
Для MainForm : Application.OnMinimize

Q-70: Как во время выполнения программы создать так называемый "array of
const"
В библиотеке Technical Information на сайте Inprise есть документ за нумером
TI582D.txt, посвященный этой проблеме. Вкратце, в качестве array of const
можно использовать массив типа TVarRec.

Q-71: Как сохранить в ini файле настройки TFont?
uses
IniFiles;

procedure TForm1.Button1Click(Sender: TObject);
var
IniFile : TIniFile;
begin
IniFile := TIniFile.Create('myIni.ini');
with Edit1.Font do with IniFile do begin
Name := ReadString ('Font','Name','MS Mans Serif');
Charset := ReadInteger('Font','Charset',RUSSIAN_CHARSET);
Color := ReadInteger('Font','Color', clWindowText);
Height := ReadInteger('Font','Height',-11);
Size := ReadInteger('Font','Size',8);
Style := TFontStyles(Byte(ReadInteger('Font','Style',0)));
end;
IniFile.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
IniFile : TIniFile;
begin
IniFile := TIniFile.Create('myIni.ini');
with Edit1.Font do with IniFile do begin;
WriteString ('Font','Name', Name);
WriteInteger('Font','Charset', Charset);
WriteInteger('Font','Color', Color);
WriteInteger('Font','Height', Height);
WriteInteger('Font','Size', Size);
WriteInteger('Font','Style',Byte(Style));
end;
IniFile.Free;
end;

Q-72: Как обратиться к определенному адресу физической памяти?
Как обратиться к определенному адресу физической памяти? А как прочитать
значение из порта? Где мой любимый массив Port[]?

Прочитайте какую-нибудь книжку про программирование под Win32. Вкратце --
забудьте про все эти глупости.

P.S. Q155 содержит несколько методов работы с портами, как легальных, так и
не вполне. В статье также содержится несколько ссылок на наиболее известные
драйвера.

Q-73: Как закрыть внешнюю программу?
Hапример, Блокнот можно закрыть так:

procedure TForm1.Button1Click(Sender: TObject);
var
phandle : HWND;
begin
phandle := FindWindow('Notepad', nil);
if phandle = 0 then
RaiseLastWin32Error;
SendMessage(phandle, WM_CLOSE, 0, 0);
end;

Q-74: Как загрузить из ImageList иконку приложения?
ImageList1.GetIcon(Idx, Application.Icon);

Q-75: Как использовать в качестве обработчика сообщения обычную процедуру,
а не метод объекта?
У этой процедуры должен быть еще один дополнительный параметр.
В метод класса кpоме паpаметpов, обьявленных в заголовке, пеpедаётся ещё
паpаметp Self

procedure MyRegularProc(ASelf, Sender: TObject);
begin
ShowMessage(ASelf.ClassName + ' ' + Sender.ClassName);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
amethod: TMethod;
begin
amethod.Code := [@] MyRegularProc;
amethod.Data := Self;
Button1.OnClick := TNotifyEvent(amethod);
end;

Leonid Troyanovsky <lv.t [@] eco-pro.ru>


Q-76: Как отловить нажатие Enter в TEdit?
IMHO, чтобы сделать в духе Windows, то добавь к Edit один TButton, с
свойством default := True, обработчик OnClick которой будет делать нужную
работу.

Другие варианты, чреваты тем, что может сработать не то, что ожидается.

Вот последовательность как будут вызываться обработчики при нажатии Enter
1. OnClick кнопки default
2. OnClick формы, если у нее KeyPreview := True;
3. OnKeyDown/KeyPress/KeyUp контрола имеющего фокус ввода.

Это особенность роли, которую этой клавише обычно назначают в win
приложениях. Обрати также внимание на свойство TButton Cancel - оно
заставляет срабатывать кнопку при нажатии Esc

Для того чтобы разобраться в этих моментах попробуй неколько вариантов,
снимая комментарии:

procedure TForm1.Button1Click(Sender: TObject);
begin
//Button1.Default := True;
ShowMessage('Key1');
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
//KeyPreview := True;
if Key = #13 then
begin
ShowMessage('Key2');
Key := #0;
end;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
ShowMessage('Key3');
end;

Q-77: В какой позиции Memo находится каретка?
var
LineNum, Charnum: Integer;

LineNum := Memo1.Perform(EM_LINEFROMCHAR, -1, 0);
CharNum := Memo1.Perform(EM_LINEINDEX, LineNum, 0);

Q-78: Как работать с графическими форматами, хотя бы самыми известными?
Hа [32]http://www.imagelib.com лежит библиотека ImageLib.

Hа компакте с Delphi 3 в каталоге EXTRAS есть библиотека JPEG. Если сказать
в модуле uses jpeg; то можно работать с .jpg как с TPicture.

Еще есть freeware-библиотека Nishita ViewLib. JPG, JFIF, GIF, BMP, DIB, RLE,
TGA, PCX. http://einstein.ae.eng.ua.edu/nishita/index.htm

Q-79: Почему после RichEdit1.Lines.SaveToFile(name) в файле, кроме моего
текста, ещё всякий бред написан?
Таким образом в RTF сохраняется информация об оформлении текста. Если
сохранять нужно только текст, перед записью сделай

RichEdit1.PlainText := True;

Q-80: Как работать с файлами архивов, хотя бы самыми распространенными?
Воспользуйтесь библиотекой ExceedZip 3.0 (http://www.exceedsoft.com).

Q-81: Как вставить картинку в TDrawGrid?
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
if (Sender is TDrawGrid) and
not (gdFixed in State) then
TDrawGrid(Sender).Canvas.Draw(Rect.Left, Rect.Top,
Image1.Picture.Graphic);
end;

Q-82: Как использовать DirectX в своей программе?
Модули для работы с DirectX находятся на Delphi Super Page, в пакете
DelphiX. Также на http://www.geocities.com/SiliconValley/1142/ лежит модули
для работы с DirectSound. Информацию по программированию DirectX можно взять
на MSDN и в книге Чарльза Калверта "Delphi 2: Энциклопедия пользователя".

PA> Самая прелесть, и забыта:

PA> http://www.yks.ne.jp/~hori/index-e.html - DelphiX by Hiroyuki Hori

PA> - лучший набор инструментов для работы с DirectX


Учтите существование эхи RU.DIRECTX.

Pavel Anufrikov

AP: Обидно за Хироюки, вроде как первый был.

Q-83: Как дождаться завершения программы, запущенной ShellExecute?
uses
ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
var
ProcInfo: PShellExecuteInfo;
begin
(Sender as TControl).Enabled := False;
GetMem(ProcInfo, SizeOf(ProcInfo^));
ZeroMemory(ProcInfo, SizeOf(ProcInfo^));
with ProcInfo^ do begin
Wnd := Handle;
cbSize := SizeOf(ProcInfo^);
lpFile := PChar('notepad.exe');
// lpParameters := nil;
lpVerb := 'open';
nShow := SW_SHOW;
fMask := SEE_MASK_DOENVSUBST or SEE_MASK_NOCLOSEPROCESS;
end;
try
Win32check(ShellExecuteEx(ProcInfo));
while not Application.Terminated and
(WaitForSingleObject(ProcInfo.hProcess, 100)=WAIT_TIMEOUT) do
Application.ProcessMessages;
finally
if ProcInfo.hProcess <> 0 then CloseHandle(ProcInfo.hProcess);

Dispose(ProcInfo);
(Sender as TControl).Enabled := True;
end;
end;

Q-84: Как использовать OpenGL в своей программе?
Модули для работы с OpenGL можно взять на
http://www.signsoft.com/opengl Информацию -- на http://www.opengl.org.
Также есть книга Ю. Тихомирова "OpenGL: программирование трехмерной
графики".
Еще загляните на http://reality.sgi.com/mjk за примерами и
http://www.scitechsoft.com за библиотекой MesaGL.

Учтите существование эхи RU.OPENGL.

Q-85: Как в TMemo вставить дату в позицию каретки?
Memo1.SetSelTextBuf(PChar(DateToStr(Date)));

Q-86: Как отловить системную ошибку при операциях с файлами?
Для Паскаль функций, например, BlockWrite, можно использовать такую
конструкцию:

try
BlockWrite(f, buf, count); //См.также хелп: параметр AmtTransferred
..
except
on E:EInOutError do
begin
ShowMessage('Произошла ошибка записи ' + E.Message);
..// пытаемся что-то поправить
if {не удалось} then
raise; //Повторно возбуждаем исключение, чтобы не удалить файл
end;
end;
..
CloseFile(..);
DeleteFile(..);

Q-87: Где достать процедуру типа "сумма прописью"?
(Vladimir Gaitanoff, 2:5020/880.5), http://www.tsinet.ru/~vg Здесь лежит
библиотека vgLib, содержащая еще массу полезных вещей.

Q-88: Как узнать, была ли создана ли определенная форма?
function IndexOfForm (const AClassName: String; const FromIndex:
Word):Integer;
var
i : Integer;
begin
Result := -1;
for i := FromIndex to Screen.FormCount-1 do
if (CompareText(Screen.Forms[i].ClassName, AClassName) = 0) then
begin
Result := i;
Break;
end;
end;

Q-89: Какие инструменты можно применить для коллективной разработки
проекта?
CVS. http://www.cyclic.com С его помощью разрабатывается весьма львиная
доля программного обеспечения в Internet. Интеграция с Delphi -- нулевая ;)
Крайне рекомендуется. Я лично пользуюсь ею ощутимое время и не представляю
себе более разработки без этого средства. "Введение в CVS" можно прочитать
на alexm.here.ru.

Microsoft Visual Source Safe. Проигрывает в функциональности, может
выигрывать в "привычности".

Q-90: Что такое Handle окна, и как его полyчить?
Handle - это число - уникальный идентификатор окна (в данном случае) в
системе.
Получить его можно, например, так:

hwnd := FindWindow (nil, 'Form1'); //ищем окнo с заголовком "Form1"
if hwnd <> 0 then {нашлось};


Q-91: Как можно обнаружить утечки памяти и ресурсов в программе?
MSDebug Макса Русова. Hаходится на http://www.dic.ru/users/rusov/
Поддерживает Delphi 3 и выше, ловит только утечки памяти, но делает это
хорошо.
В данное время эта ссылка не действующая!

Hа http://www.numega.com можно купить BoundsChecker for Delphi. Он проверяет
также и утечки ресурсов.

Рекламировался также "MemProof", информацию о котором можно получить на
http://www.listsoft.ru/programs/pr1520.htm

Q-92: Как проиграть midi файл?
uses
MPlayer;

var
mp : TMediaPlayer;

procedure TForm1.Button1Click(Sender: TObject);
begin
with Sender as TButton do
case Tag of
0 :
begin
Tag := 1;
mp := TMediaPlayer.CreateParented(Handle);
mp.DeviceType := dtSequencer;
mp.FileName := 'c:\winnt\media\Canyon.mid';
mp.Wait:= True;
mp.Open;
mp.Play;
end;
1 :
begin
Tag := 0;
mp.Wait := True;
mp.Stop;
mp.Free;
end;
end;
end;

Q-93: Мне нужно заниматься разбором математических выражений
Мне нужно заниматься разбором математических выражений, например, строить
график функции, заданной пользователем во время работы программы.

В rxLib есть компонент TrxMathParser, достаточно мощный для большого
количества применений.

Q-94: Как обратиться к свойству по его имени?
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
f1 : Integer; // Это приватное поле хранит значение
published
{К свойству p1 мы будем обращаться по его имени}
property p1 : Integer read f1 write f1;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

uses
TypInfo;

procedure TForm1.Button1Click(Sender: TObject);
var
PInfo : PPropInfo;
begin
p1 := GetTickCount; // Здесь свойству что-то присвоили

PInfo:= GetPropInfo(TForm1.ClassInfo, 'p1'); // Получаем описание свойства
// из описания класса
if PInfo = nil then
raise Exception.Create('Property not exist');
Caption := IntToStr(GetOrdProp(Form1, PInfo)); // Получаем значение
свойства
end;
+++++++++++++++++++++++++++++++++++++++++

uses
TypInfo;

function ObjPropInfo(AObject: TObject; const PropName: String): PPropInfo;
begin
Result := GetPropInfo(AObject.ClassInfo, PropName);
if Result = nil then
raise Exception.Create('Property not exist');
end;

procedure SetOrdProperty( AObject: TObject; const PropName:String; const
Value: Longint);
begin
SetOrdProp(AObject, ObjPropInfo(AObject, PropName), Value);
end;

function GetOrdProperty(AObject: TObject; const PropName:String):Longint;
{см. также TypInfo: GetStrProp, GetFloatProp, GetEnumValue etc.}
begin
Result:= GetOrdProp(AObject, ObjPropInfo(AObject, PropName));
end;

procedure SetStrProperty( AObject: TObject; const PropName:String; const
Value: String);
begin
SetStrProp(AObject, ObjPropInfo(AObject, PropName), Value);
end;

procedure SetFloatProperty( AObject: TObject; const PropName:String; const
Value: Extended);
begin
SetFloatProp(AObject, ObjPropInfo(AObject, PropName), Value);
end;

procedure SetVariantProperty( AObject: TObject; const PropName:String; const
Value: Variant);
begin
SetVariantProp(AObject, ObjPropInfo(AObject, PropName), Value);
end;

procedure SetMethodProperty( AObject: TObject; const PropName:String; const
Value: Pointer);
var
AMethod: TMethod;
begin
AMethod.Code := Value;
AMethod.Data := AObject;
SetMethodProp(AObject, ObjPropInfo(AObject, PropName), AMethod);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
AFont: TFont;
begin
SetOrdProperty(Button1, 'Width', 100); // целое
AFont := TFont.Create;
AFont.Style := [fsBold];
SetOrdProperty(Button1, 'Font', Longint(AFont)); // объект
AFont.Free;
SetMethodProperty(Button1, 'OnClick', [@] TForm1.Button2Click); // метод
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage((Sender as TButton).Caption);
end;

Leonid Troyanovsky <lv.t [@] eco-pro.ru>


* Origin: Knowledge itself is a power (2:450/143.25)

ru.delphi FAQ [5-10]

Q-95: Как уменьшить размер исполняемого файла программы?
Писать на WinAPI без использования VCL. Это пригодно для и без того
крохотных программ.
Существуют freeware библиотеки, упрощающие программирование без VCL,
например:

KOL http://xcl.cjb.net
ACL http://www.apress.ru/pages/bokovikov/delphi

Воспользоваться пакетами (packages) из Delphi 3. Эффект появится, когда
исполняемых файлов больше одного.

Воспользоваться компрессорами исполняемых файлов, например:
Shrinker http://www.blinkinc.com
WWPack32 http://kolos.uni.lodz.pl/warezak
NeoLite
ftp://ftp.zdnet.com/pub/private/sWlIB/utilities/other_utilities/neolitee.zip,
Petite, http://www.icl.ndirect.co.uk/petite/

Компрессировать или нет исполняемые файлы, должен решить каждый, так как
возможны и негативные моменты от использования сжатия. Дискуссия по этому
поводу никогда не прекращается.

Q-96: Как нажать Ctrl+Del программным путем?
keybd_event(vk_control, 0, 0, 0);
keybd_event(vk_delete, 0, 0, 0);
keybd_event(vk_delete, 0, KEYEVENTF_KEYUP, 0);
keybd_event(vk_control, 0, KEYEVENTF_KEYUP, 0);
++++++++++++++++++++++++++++++++

keybd_event(vk_control, MapVirtualKey(vk_control, 0), 0, 0);
keybd_event(vk_delete, MapVirtualKey(vk_control, 0), 0, 0);
keybd_event(vk_delete, MapVirtualKey(vk_control, 0), KEYEVENTF_KEYUP, 0);
keybd_event(vk_control, MapVirtualKey(vk_control, 0), KEYEVENTF_KEYUP, 0);

Leonid Troyanovsky <lv.t [@] eco-pro.ru>


Q-97: Где достать всяких иконок, картинок для кнопок, etc. для своей
программы?
http://www.iconbazaar.com

Q-98: Аналог Case для строк
Вопрос: Hужно определить с какой из заданных строк совпадает некая строковая
переменная и в зависимости от этого перейти к соответсвующей процедуре. Как
это выполнить без использования многочисленных if - then?

Вот способ, легко приспосабливаемый для загрузки списка из строки, файла или
ресурса:

const
vlist = 'первый, второй, третий';

var
Values: TStringList;

procedure SetValues(VL : TStringList; S: String);
var
I : Integer;
begin
Values.CommaText := S;
for I := 0 to CL.Count-1 do
Values.Objects[I] := Pointer(I);
Values.Sorted := True;
end;

function GetValueIndex(VL : TStringList; Match: String): Integer;
begin
Result := Values.IndexOf(Match);
if Result >= 0 then

Result := Integer(Values.Objects[Result]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
case GetValueIndex(Values, Edit1.Text) of
-1: {не найден} ;
0: Caption := '0';
1: Caption := '1';
2: Caption := '2';
end;
end;

initialization
Values := TStringList.Create;
SetValues(Values, vlist);

finalization
Values.Free;

Q-99: Как в TListBox пеpетаскивать итемы?
DragMode := dmAutomatic;

{OnDragOver}
procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := True;
end;

{OnDragDrop}
procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
NewIndex : Integer;
begin
with Sender as TListBox do begin
NewIndex := ItemAtPos(Point(X,Y), True);
Items.Move(ItemIndex, NewIndex);
ItemIndex:= NewIndex;
end;
end;

Q-100: Как отловить нажатие клавиш F1..F10?
procedure TForm1.AppMessage(var Msg:TMsg; var Handled: Boolean);
begin
case msg.wParam of
VK_F1..VK_F10 :
case Msg.message of
WM_KEYUP: ShowMessage('Key up');
WM_KEYDOWN: ShowMessage('Key down');
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMessage;
end;

Q-101: Как мне работать с файлами MS Word или таблицами MS Excel?
Воспользоваться функцией CreateOLEObject и работать с VBA (Visual Basic for
Applications) или WordBasic.

NB: Обратите внимание на то, как устанавливаются именованные параметры у
процедур WordBasic'а, например, FileOpen(Name := 'myname.doc');

Пример проверен только на русском Word 7.0! Может, поможет...

unit InWord;
interface
uses
... ComCtrls; // Delphi3
... OLEAuto; // Delphi2
[skip]
procedure TPrintForm.MPrintClick(Sender: TObject);
var W: Variant;
S: String;
begin
S:=VarToStr(Table1['Num']); //В D3 без промежуточной записи
// в var у меня не пошло :(
try // А вдруг где ошибка :)
W:=CreateOleObject('Word.Basic');
// Создаем документ по шаблону MyWordDot
// с указанием пути если он не в папке шаблонов Word
W.FileNew(Template:='C:\MyPath\DB\MyWordDot',NewTemplate:=0);
// Отключение фоновой печати (на LJ5L без этого был пустой лист)
W.ToolsOptionsPrint(Background:=0);

// Переходим к закладке Word'a 'Num'
W.EditGoto('Num'); W.Insert(S);
//Сохранение
W.FileSaveAs('C:\MayPath\Reports\MyReport')
W.FilePrint(NumCopies:='2'); // Печать 2-х копий
finally
W.ToolsOptionsPrint(Background:=1);
W:=UnAssigned;
end;
end;
{.....}

Sergey Arkhipov 2:5054/88.10


Второй путь, более правильный.

Hужно импортировать TLB библиотеку соответствующего COM-сервера (MS Word, MS
Excel, AutoCAD, и т.п.) или воспользоваться готовыми компонентами из палитры
Servers поставляемыми с Delphi 5 и

более свежими версиями. Среда построит unit содержащий описания всех
доступных интерфейсов сервера. Кроме того будут созданы классы-обертки для
некоторых интерфейсов сервера. Преимущество этого метода заключается в том
что компилятор может проверить правильность синтаксиса обращений к серверу,
кроме того повышается скорость работы за счет меньших накладных расходов на
каждое обращение.

Пример использования TLB.

program wordemo;

{$APPTYPE CONSOLE}

uses
SysUtils, ActiveX, Word2000, OleCtrls, Variants;
var
W:TWordApplication;
D:_Document;
P:Paragraph;
FileName:OleVariant;
begin
CoInitialize(NIL);
try
// создадим экземпляр объекта-обертки вокруг Word 2000
W:=TWordApplication.Create(NIL);
try
// создадим новый документ на основе шаблона Normal

D:=W.Application.Documents.Add(EmptyParam,EmptyParam,EmptyParam,EmptyParam);
// добавим новый параграф
P:=D.Paragraphs.Add(EmptyParam);
// Запишем туда какой-нибудь текст
P.Range.InsertAfter('Hello Word :-)');
// сохраним документ
FileName:='wordemo.doc';

D.SaveAs(FileName,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam);
finally
// завершим работу Word
W.Free;
end;
finally
CoUnInitialize;
end;
end.

Andrew V. Fionik <fionika [@] chat.ru>


Замечание от Denver The Marion <denver [@] neman.grodno.by>

Hашёл такую интересную закономерность директива W.Free не закрывает MS
Word - он остаётся в памяти и висит там (при этом нормально не открывается
только что созданные документы). Если изменить строку на W.Quit - всё
работает нормально. Рабиралось всё это дело на Delphi 5 и MS Word 2000.

Q-102: Как записать в файл несколько TImage?
procedure TForm1.Button1Click(Sender: TObject);
begin
with TFileStream.Create(FileName,fmCreate or fmOpenWrite) do begin
WriteComponentRes('IMAGE1', image1);
WriteComponentRes('IMAGE2', image2);
Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Image1.Free;
Image2.Free;
RegisterClass(TImage);
Image1 := TImage.Create(Self);
Image2 := TImage.Create(Self);
with TFileStream.Create(FileName, fmOpenRead) do begin
ReadComponentRes(Image1);
ReadComponentRes(Image2);
Free;
end;
Image1.Parent:= Self;
Image2.Parent:= Self;
UnregisterClass(TImage);
end;

Q-103: Как показать текстовый файл в TLabel?
procedure TForm1.Button1Click(Sender: TObject);
var
fs : TFileStream;
s : String;
begin
fs := TFileStream.Create('unit1.pas', fmOpenRead or fmShareDenyNone );
SetLength(s, fs.Size);
fs.Read(s[1], Length(s));
fs.Free;
Label1.Caption := s;
end;

Q-104: Delphi 5.0 and Win2K
1. Если кто не читает readme-файлы до начала установки, то с интересом
узнает, что в сопроводиловке от Борланд указывается на проблему неправильной
работы инсталлятора, если используются кнопки Browse для смены каталогов
установки. При этом рекомендуется набрать/подредактировать пути вручную. (Hе
проверял, просто действовал
как рекомендовано, хотя пути по умолчанию никогда не использую).

2. При установке с жесткого диска, весь дистрибутив вместе с папками
Runimage и Install надо либо поместить в корень логического диска (что
обычно неудобно), либо используя subst (или в сети - use net), сотворить
букву для этого пути. Чтобы инсталлятор решил, что установка идет из корня
диска. Иначе - облом-с.

3. При установке на машину, на которой предполагается наличие нескольких
программеров, работающих посменно, сначала придется поставить из-под
админа - для всех. А потом - из-под каждого аккаунта (хотя бы в режиме
Registry + Custom). Иначе не будет компонентов на палитре.

4. Проверить переменные среды %TEMP% и %TMP%, рекомендуется короткий путь -
C:\TEMP

5. Первичная установка под административным аккаунтом с АHГЛИЙСКИМ именем,
например admin

Vladimir Kladov <bonanzas [@] online.sinor.ru>


Можно экспоpтиpовать y админа HKEY_CURRENT_USER/Software/Borland и пpосто
импоpтиpовать для каждого потом. Так несколько быстpее, чем инсталиpовать и
уменьшается количество ошибок.

Ruslan Fedoseev <Ruslan.Fedoseev [@] hell.avugu.lg.ua >


Q-105: Почему в консольных приложениях неправильно отображаются русские
буквы?
Потому что кодировка шрифтов, используемых в редакторе Delphi - 1251 (ANSI),
а в консольных приложениях - 866 (OEM). Чтобы добиться правильного
отображения нужно использовать функцию CharToOEM (но при этом возрастёт
размер кода), либо сразу писать проект в каком-либо консольном текстовом
редакторе (Dos Navigator, Far)

CharToOem('Привет',TmpStr);
Writeln(TmpStr);

Denis Filonov <Denis.Filonov [@] p23.f2500.n5020.z2.fidonet.org>


Q-106: В чем pазличия ShellExecute и CreateProcess?
ShellExecute может запустить приложение, ассоциированное с расширением
файла, например:

ShellExecute(Handle, 'open', 'mydoc.doc', nil, nil, SW_SHOW);

запустит Word (или другое приложение, зарегистрованное для *.doc) и откроет
файл mydoc.

CreateProcess не обращает внимание на расширения, но возможности этой
функции гораздо больше. Одна из главных - получение handles нового процесса
и его первичного потока, с помощью которых можно запрашивать информацию о
ходе дочернего процесса.

Hадо заметить, что хендл дочернего процесса может вернуть функция
ShellExecuteEx, которая занимает, скажем, промежуточное положение.

Q-107: Как вставить картинку в StatusPanel?
Image1.Parent := StatusBar1;

Q-108: Как внедрить dll в другое приложение?
procedure QryName(threadID: DWord; Caller: HWND); external 'lib0.dll';

procedure TForm1.WMCopydata(var msg: TMessage); // message WM_COPYDATA;
begin
Caption := PChar(PCopyDataStruct(Pointer(msg.LParam)).lpData);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ahwnd: THandle;
begin
{Ищем по заголовку}
ahwnd := FindWindow(nil, PChar(Edit1.Text));
if ahwnd <> 0 then

QryName(GetWindowThreadProcessID(ahwnd, nil), Handle);
end;

- --- lib0.dpr ---

library lib0;

uses
Messages,
Windows;

function Answer( nCode: Integer; wprm: WParam; lprm: LParam): LResult;
stdcall;
type
PMsg = ^TMsg;
var
buffer : array [0..MAX_PATH] of Char;
cd : TCopyDataStruct;
msg : PMsg;
Caller : HWND;
AHook: HHook;
begin
Result := 0;
msg := PMsg(lprm);
if (msg.Message = 0) and (msg.LParam <> 0) then

begin
AHook := msg.lParam;
Caller := msg.wParam;
cd.cbData := GetModuleFileName(0, buffer, SizeOf(buffer))+1;
cd.lpData := [@] buffer;
cd.dwData := GetCurrentThreadID;
SendMessage(Caller, WM_COPYDATA, 0, LParam( [@] cd));
UnHookWindowsHookEx(AHook);
PostThreadMessage(GetCurrentThreadID, 0, 0, 0);
end;
end;

procedure QryName(tid: DWord; Caller: HWND);
var
AHook : Hhook;
begin
AHook := SetWindowsHookEx(WH_GETMESSAGE, Answer, Hinstance, tid);
if AHook <> 0 then

PostThreadMessage(tid, 0, Caller, AHook);
end;

exports
QryName;

begin
end.

Q-109: Как показывать хинты для частично видимых элементов ListBox?
Hаписать для OnMouseMove:

procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
oldidx : Longint = -1;
var
idx : Longint;
begin
with Sender as TListBox do begin
idx := ItemAtPos(Point(x,y),True);
if (idx < 0) or (idx = oldidx) then Exit;
Application.ProcessMessages;
Application.CancelHint;
oldidx := idx;
Hint := '';
if Canvas.TextWidth(Items[idx]) > Width - 4 then Hint:=Items[idx];

end;
end;

Q-110: Как центрировать по форме модальный диалог?
procedure CenterDialogPos(DlgHandle, WindowHandle: HWND);
var
DlgRect : TRect;
WndRect : TRect;
x, y, w, h : integer;
begin
if (DlgHandle <> 0) then begin

GetWindowRect(DlgHandle, DlgRect);
GetWindowRect(WindowHandle, WndRect);
w := DlgRect.Right - DlgRect.Left;
h := DlgRect.Bottom - DlgRect.Top;
//center horz
x := WndRect.Left + ((WndRect.Right - WndRect.Left - w) div 2);
//keep on screen
if x < 0 then x := 0
else if x + w > Screen.Width then x := Screen.Width - w;

//center vert
y := WndRect.Top + ((WndRect.Bottom - WndRect.Top - h) div 2);
//keep on screen
if y < 0 then y := 0
else if y + h > Screen.Height then y := Screen.Height - h;

SetWindowPos(DlgHandle, 0, x, y, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or
SWP_NOZORDER);
end;
end;

procedure TForm1.WMUser1(var msg: TMessage); // message WM_USER+1;
begin
CenterDialogPos(GetActiveWindow, Handle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(Handle, WM_USER+1, 0, 0);
ShowMessage('Test');
end;

* Origin: Errare humanum est (2:450/143.25)