Content

  • I-1: Версия от 21.08.2006
  • I-2: Введение
  • I-3: Авторские права
  • I-4: Преамбула
  • I-5: О поле Subject:
  • I-6: Здесь не приветствуется
  • I-7: Доступность этого FAQ
  • I-8: Информация о программе
  • I-9: Источники информации
  • I-10: Список рекомендуемой литературы
  • Q-11: Каким именно релизом Delphi вообще стоит пользоваться для каждой конкретной версии?
  • Q-12: Как исправить проблемы с вызовом помощи при одновременно стоящих Delphi 1 и Delphi 2
  • Q-13: Delphi 2 и 3 не отображают русские TTF под Windows NT WorkStation + ServicePack#3
  • Q-14: Как включить окошко CPU Window?
  • Q-15: Как установить компонент от Delphi одной версии под Delphi другой версии, если имеется только .DCU
  • Q-16: Delphi 4 виснут при запуске. Видеокарта S3 Virge.
  • Q-17: Как вывести диалог выбора каталога?
  • Q-18: При работе программ на D1 под Win95 на иконках TBitBtn'ов обнаруживаются странные артефакты
  • Q-19: Можно ли скомпилировать на Delphi 2/3/4 программу, работающую под Windows 3.1?
  • Q-20: Куда из Delphi 3 делся модуль для работы с ReportSmith? А мои любимые модули работы с OLE
  • Q-21: Как сделать так, чтобы при щелчке по кнопке или по TLabel запускался браузер
  • Q-22: Hе работает передача данных по OLE в русский Excel.
  • Q-23: Как русифицировать сообщения программы?
  • Q-24: Как во время компиляции модуля определить, под какой версией Delphi она происходит?
  • Q-25: Как сделать так, чтобы при щелчке по кнопке или по TLabel отправить письмо
  • Q-26: Как сделать так, чтобы программу можно было запустить только в одном экземпляре?
  • Q-27: Как мне вывести какое-нибудь окошко с картинкой, пока программа грузится?
  • Q-28: Как объявлять переменные, чтобы они были видны в других модулях проекта.
  • Q-29: А как поместить свою иконку на taskbar, там где часы и переключатель клавиатуры?
  • Q-30: Как форматировать денежные суммы, чтобы было видно всегда два знака после запятой
  • Q-31: Как сделать плавно изменяющийся цвет заголовка окна, как в MSOffice'95?
  • Q-32: Как сделать так, чтобы по Alt-F4 форма не просто закрывалась, а выдавала запрос на сохранение?
  • Q-33: Как мне перекодировать строки из Win-кодировки в Dos-кодировку и наоборот?
  • Q-34: Кaк yзнaть кaкиe фyнкции нaхoдятcя в DLL и кaк их иcпoльзoвaть?
  • Q-35: Как отловить события создания или удаления файлов другими программами?
  • Q-36: Почему у меня record a : word; b : longint end; имеет размер восемь байт вместо шести?
  • Q-37: Не перерисовываются окна во время длинного цикла
  • Q-38: Как отследить "уход" курсора мыши с компонента?
  • Q-39: Как мне запустить какую-нибудь программу
  • Q-40: Как правильно закрыть и удалить форму?
  • Q-41: Я создал объект TStrings, но при попытке обращения к нему выдается ошибка.
  • Q-42: Мне надо добавить много строк в TListbox или в TCombobox или в TMemo
  • Q-43: Как правильно создавать компоненты run-time?
  • Q-44: Как мне запрограммировать непрямоугольную форму, например, как у Norton CrashGuard, в форме щита?
  • Q-45: Как использовать свои курсоры в программе?
  • Q-46: Как ограничить перемещение курсора мыши какой-либо областью экрана?
  • Q-47: Как сделать так, чтобы запущенная программа не была видна на панели задач?
  • Q-48: Как из программы переключить раскладку клавиатуры?
  • Q-49: Как получить короткий путь файла если имеется длинный?
  • Q-50: String в PChar и обратно
  • Q-51: Как при наведении курсора на кнопку менять ее цвет?
  • Q-52: Как написать сервис для Windows NT?
  • Q-53: Как работать с реестром?
  • Q-54: Как выдвинуть дверцу CD-ROM'а?
  • Q-55: Как перехватывать клавиши, нажатые в окне другой программы? И вообще, любые события
  • Q-56: Как сделать индикатор прогресса для длительного запроса?
  • Q-57: Как вызывать из 32-битной программы 16-битные DLL?
  • Q-58: Как получить набранный в Блокноте текст в свою пpогpаммку?
  • Q-59: Как скопировать экран в буфер обмена?
  • Q-60: Где взять подробную документацию по работе с RTF, TRichEdit?
  • Q-61: Как показать Hint для MenuItem?
  • Q-62: Как можно перетаскивать форму не только за заголовок?
  • Q-63: Как сделать прозрачным фон при выводе Canvas.TextOut?
  • Q-64: Как применить изменение в реестре без перезагрузки компьютера?
  • Q-65: Как добавить пункты в системное меню окна?
  • Q-66: Как в Мемо установить каретку в нyжнyю позицию?
  • Q-67: Можно ли сделать так, чтобы в исполняемом файле программы находился какой-нибудь звук в формате .wav
  • Q-68: Как сделать в меню список последних открытых файлов?
  • Q-69: Как узнать и поменять разрешение экрана?
  • Q-70: Какое событие происходит при минимизации окна?
  • Q-71: Как во время выполнения программы создать так называемый "array of const"
  • Q-72: Как сохранить в ini файле настройки TFont?
  • Q-73: Как обратиться к определенному адресу физической памяти?
  • Q-74: Как закрыть внешнюю программу?
  • Q-75: Как загрузить из ImageList иконку приложения?
  • Q-76: Как использовать в качестве обработчика сообщения обычную процедуру, а не метод объекта?
  • Q-77: Как отловить нажатие Enter в TEdit?
  • Q-78: В какой позиции Memo находится каретка?
  • Q-79: Как работать с графическими форматами, хотя бы самыми известными?
  • Q-80: Почему после RichEdit1.Lines.SaveToFile(name) в файле, кроме моего текста, ещё всякий бред написан?
  • Q-81: Как работать с файлами архивов, хотя бы самыми распространенными?
  • Q-82: Как вставить картинку в TDrawGrid?
  • Q-83: Как использовать DirectX в своей программе?
  • Q-84: Как дождаться завершения программы, запущенной ShellExecute?
  • Q-85: Как использовать OpenGL в своей программе?
  • Q-86: Как в TMemo вставить дату в позицию каретки?
  • Q-87: Как отловить системную ошибку при операциях с файлами?
  • Q-88: Где достать процедуру типа "сумма прописью"?
  • Q-89: Как узнать, была ли создана ли определенная форма?
  • Q-90: Какие инструменты можно применить для коллективной разработки проекта?
  • Q-91: Что такое Handle окна, и как его полyчить?
  • Q-92: Как можно обнаружить утечки памяти и ресурсов в программе?
  • Q-93: Как проиграть midi файл?
  • Q-94: Мне нужно заниматься разбором математических выражений
  • Q-95: Как обратиться к свойству по его имени?
  • Q-96: Как уменьшить размер исполняемого файла программы?
  • Q-97: Как нажать Ctrl+Del программным путем?
  • Q-98: Где достать всяких иконок, картинок для кнопок, etc. для своей программы?
  • Q-99: Аналог Case для строк
  • Q-100: Как в TListBox пеpетаскивать итемы?
  • Q-101: Как отловить нажатие клавиш F1..F10?
  • Q-102: Как мне работать с файлами MS Word или таблицами MS Excel?
  • Q-103: Как записать в файл несколько TImage?
  • Q-104: Как показать текстовый файл в TLabel?
  • Q-105: Delphi 5.0 and Win2K
  • Q-106: Почему в консольных приложениях неправильно отображаются русские буквы?
  • Q-107: В чем pазличия ShellExecute и CreateProcess?
  • Q-108: Как вставить картинку в StatusPanel?
  • Q-109: Как внедрить dll в другое приложение?
  • Q-110: Как показывать хинты для частично видимых элементов ListBox?
  • Q-111: Как центрировать по форме модальный диалог?
  • Q-112: Чем отличаются TLabel и TStaticText?
  • Q-113: Как издать звук через PC Speaker?
  • Q-114: Как корректнее завершать приложение- Terminate или MainForm.Close?
  • Q-115: Как узнать версию Windows?
  • Q-116: Как из dll узнать узнать полный путь к этой dll.
  • Q-117: Как отобразить каталог?
  • Q-118: Как узнать кол-во цветов цветовой палитры?
  • Q-119: Как ввести текст в "чужой" Edit?
  • Q-120: Как заставить мигать кнопку приложения на AppBar?
  • Q-121: Как сделать программу без главной формы?
  • Q-122: Как убрать VerticalScrollBar из TListBox навсегда?
  • Q-123: Как показать диалог выбора директории?
  • Q-124: Как убрать из ListView горизонтальный скролбар навсегда?
  • Q-125: Кaк искать oкнo по части eгo нaзвaния?
  • Q-126: Как обнаружить активность юзера?
  • Q-127: Как yзнать текущую Ru/En pаскладкy клавиатypы?
  • Q-128: Как передать строку другому приложению?
  • Q-129: Как RichEdit сделать скролл на конец текста?
  • Q-130: Удаление файлов из временного каталога, безопасно ли?
  • Q-131: Как узнать состояние управляющих клавиш - Shift, Ctrl, Alt?
  • Q-132: Как сохранить всю форму в файл (как Delphi в *.dfm)?
  • Q-133: Как контрол может сам себя разрушить?
  • Q-134: Как отследить переход фокуса в приложении?
  • Q-135: Как заставить MediaPlayer крутить один и тот же клип?
  • Q-136: Как назначить процедуру собственному пункту системного меню?
  • Q-137: Какой класс окна у консоли?
  • Q-138: Какое сообщение надо отлавливать в Application.OnMessage для отслеживания клавиши Alt (vk_menu)
  • Q-139: Как спрятать контрол, если известен его Handle?
  • Q-140: Как поменять иконку и стpокy в заголовке консольного окна?
  • Q-141: Как сделать окно без VCL?
  • Q-142: Как избежать повторного запуска моего приложения?
  • Q-143: Как записать массив в файл?
  • Q-144: Delphi 6 требует Proxies.pas
  • Q-145: О библиотеке RxLib
  • Q-146: Как хранить настройки программ.
  • Q-147: Как вывести ProgresBar на StatusBar?
  • Q-148: Как нажать клавиши в другом приложении?
  • Q-149: Как перетащить файлы из проводника в мою программу?
  • Q-150: Как использовать в Дельфи API фyнкции?
  • Q-151: Автоматическое определение кодировки текста
  • Q-152: Как помигать лампочками на клавиатуре?
  • Q-153: Как создать в runtime форму?
  • Q-154: Как прочитать порт или записать в него?
  • Q-155: Как работать с битами?
  • Q-156: Как удалить непустой каталог?
  • Q-157: Как получить список файлов со всеми подкаталогами?
  • Q-158: Как преобразовать unix time в TDateTime?
  • Q-159: Как сделать .manifest для Windows XP?
  • Q-160: Как узнать версию программы?
  • Q-161: Как выключить или перезагрузить компьютер?
  • Q-162: Куда пропали те или другие компоненты в Д7?
  • Q-163: Время работы Windows
  • Q-164: Как отформатировать текст в TRichEdit?
  • Q-165: Как определить откуда была запущена программа?
  • Q-166: Как ассоциировать тип файлов с программой?
  • Q-167: Как сохранить содержимое буфера обмена в JPG?
  • Q-168: Как отловить нажатие клавиш в контроле?
  • Q-169: Как получить номер строки, в которой произошло исключение?
  • Q-170: Как назначить программу обработчиком URL scheme?

  • I-1: Версия от 21.08.2006

     Объединенное  FAQ  конференций  ru.delphi  и  ru.delphi.chainik.

    I-2: Введение

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

    I-3: Авторские права

     Copyright  (C)  Alexey  Mahotkin  1997-1999
     Portions  Copyright  (C)  Anatoly  Podgoretsky,  2001
     Support  by  Andrew  O.  Shadoura,  2005-2006

    I-4: Преамбула

     Пожалуйста,  не  задавайте  вопросы  в  этой  конференции  до  того,  как  прочтете  этот  документ,  правила  конференции,  ознакомитесь  со  списком  рекомендованной  литературы  и  проведете  самостоятельные  исследования  вопроса.  Желательно  также  ознакомиться  с  архивом  конференции  за  два-три  последних  месяца.
     
     При  задании  вопроса  приведите  всю  необходимую  информации,  чтобы  можно  было  оказать  квалифицированную  помощь,  а  не  заниматься  телепатией;  указание  путей  и  средств  которые  были  использованы  для  решения  проблемы  также  благоприятствует  оказанию  помощи,  т.к.  видно  что  человек  пытался  сам  решить  проблему,  а  не  надеялся  на  халяву.
     
     Хорошая  статья  по  поводу  того,  как  надо,  а  как  не  надо  задавать  вопросы,  размещена  на  сайте:
     http://ln.com.ua/~openxs/articles/smart-questions-ru.html
     
     Также  надо  приводить  небольшие  куски  кода,  но  не  злоупотреблять  этим,  никто  не  будет  рассматривать  несколько  сотен  строк  или  информацию,  не  относящуюся  к  делу.  Все  должно  быть  в  меру.
     
     Это  поможет  всем  вам  сохранить  конференцию  интересной  и  полезной.

    I-5: О поле Subject:

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

    I-6: Здесь не приветствуется

     *  обсуждение  вопросов,  относящихся  к  базам  данных,  для  этого  существует  специализированная  конференция  RU.DELPHI.DB;  вопросов  относящихся  к  отчетам  -  RU.DELPHI.REPORTS;  вопросов  относящихся  к  Интернету    -  RU.DELPHI.INTERNET,  относительно  простых  вопросов  -  RU.DELPHI.CHAINIK  
     Мотивация  "мой  аплинк/провайдер  не  получает  эту  эху/ньюсгруппу"  в  данном  случае  не  принимается.
     
     *  обсуждение  вашей  совершенно  новой  и  безумно  свежей  идеи  о  том,  что  эху  пора  разделить  на  две/три/больше  частей,  потому  что  читать  ее  нет  никаких  сил.  Вы  даже  не  в  первой  сотне  придумавших  и  успешно  высказавших  сие.  От  себя  могу  посоветовать  пользоваться  хорошими  программами  для  чтения  эхо-конференций.
     
     *  обсуждение  тем,  не  связанных  с  собственно  Delphi:  алгоритмы,  общие  вопросы  программирования  под  Win32,  общие  организационные  вопросы,  связанные  с  разработкой  программного  обеспечения,  etc.  Для  этого  существуют  специализированные  эхоконференции.
     
     *  общая  неспособность  получать  информацию  из  окружающей  реальности.  Прочтите  книгу  об  эффективной  коммуникации  и  должном  отношении  ко  всему.
     
     *  неуважительное  отношение  к  участникам  конференции.  
     
     ***  Для  конференции  RU.DELPHI.CHAINIK  ***
     
     *  Ответы  типа  RTFM,  рекомендуется  приводить  небольшой  кусок  кода  демонстрирующий  решение  проблемы.  В  случае  же  ссылки  на  хелп,  желательно  указывать  название  темы.
     
     *  рекомендуется  прочитать  следующий  документ  http://ln.com.ua/~openxs/articles/smart-questions-ru.html
     Если  он  вам  не  поможет  и  вы  не  поймете  о  чем  он,  а  он  не  о  хакерах,  как  следует  из  его  содержимого,  то  ваши  шансы  на  получения  ответа  сильно  уменьшаются!!!

    I-7: Доступность этого FAQ

     Этот  документ  регулярно  изменяется  по  результатам  обсуждения  в  RU.DELPHI  и  RU.DELPHI.CHAINIK.  
     Вы  можете  поучаствовать  в  составлении  документа,  прислав  прислав  модератору  RU.DELPHI  или  Анатолию  Подгорецкому  (по  адресу
     faq@podgoretsky.com)  сформулированный  вариант  вопроса,  ответ  или  дополнение  или  исправление  к  ответу.  Большие  куски  кода  неуместны  в  FAQ.  В  любом  случае,  вы  можете  обратиться  к  авторам  сопутствующих  проектов.
           
     Разрешается  свободное  распространение  и  использование  этого  документа  при  соблюдении  определенной  вежливости  по  отношению  к  автору  и  читателям,  основной  составляющей  чего  является  соблюдение  целостности  документа.  Hе  очень  приветствуется  выкладывание  копий  этого  документа  на  WWW:  подумайте,  нужны  ли  вам  непрерывные  усилия  по  синхронизации?
     
     Если  же  вы  вынуждены  использовать  этот  документ  на  сайте,  для  того,  чтобы  создать  его  содержимое,  подумайте,  нужен  ли  вообще  ваш  сайт?
           
     Свежая  версия  этого  документа  находится  на  домашней  странице  автора  http://www.podgoretsky.com  (доступен  движок  FaqMaker.exe  его  исходные  тексты,  последнии  версияи  баз  и  сам  FAQ  в  HTML  формате).  
     
     Альтернативный  источник  http://faq.delphiplus.org
     
     Оригинальная  версия  от  Махоткина  на  домашней  странице  автора  http://alexm.here.ru.  
     
     Остерегайтесь  подделок.

    I-8: Информация о программе

     FAQ  создан  с  помощью  FAQ  Maker  ver.  1.1
     от  Анатолия  Подгорецкого
     
     Доступен  на  http:/www.podgoretsky.com  
     
     Альтернативный  источник  http://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  (это  первый  уровень)  стоит  не  столь  дорого  и  вы  имеете  все  шансы  купить  ее,  например,  для  своей  организации.  Более  того,  на  http://msdn.microsoft.com  можно  получить  доступ  к  львиной  доле  документации  из  MSDN.
     Большинство  вопросов  типа  "А  как  сделать..."  могут  быть  легко  решены  после
     прочтения  соответствующей  главы  в  MSDN.  Вы  сэкономите  массу  своего  и  чужого  времени.
     
     Традиционно  обитатели  RU.DELPHI  питают  заслуженную  любовь  и  уважение  к  библиотеке  rxLib.  Это  большая  библиотека  компонент  для  Delphi  всех  версий  и  C++Builder,  распространяемая  по  системе  freeware  с  полными  исходными  текстами  и  файлами  помощи  на  русском  языке.  Выяснено,  что  эта  библиотека  способна  покрыть  очень  большое  количество  запросов  программистов  на  Delphi  самого  разного  уровня,  и  в  частности,  именно  на  нее  будут  даваться  обильные  ссылки  далее  по  тексту.  В  настоящее  время  проект  прекратил  свое  существование,  но  не  умер,  а  в  включен  в  состав  более  крупного  проекта  JEDI  Visual  Component  Library  (JVCL)  и  JEDI  Code  Library  (JCL).  Дополнительную  информацию  вы  можете  получить  по  адресу  http://www.delphi-jedi.org/  
     
     По  поводу  RxLib  в  данном  FAQ  есть  отдельная  статья  Q-145  и  неплохой  источник  http://www.delphiplus.org,  который  взял  на  себя  роль  в  отслеживании  ситуации  с  этой  бибилотеки,  кроме  самой  библиотеки  на  нем  расположено  много  интересных  материалов  и  особенно  интересны  новости,  стоит  периодически  туда  заглядывать.
     
     Так  как  ситуациая  постоянно  меняется,  то  одни  ссылки  становятся  не  действительными  и  появляются  новые,  но  в  последнее  время  стоит  смотреть  следующие  ссылки  http://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  над  всеми  прочими  средствами  разработки.

    I-10: Список рекомендуемой литературы

     1.  А.  Архангельский,  В.  Ильин,  М.  Тагин    
     Русская  справка  (HELP)  по  Delphi  5  и  Object  Pascal  (32  стр.  с  CD-ROM)
     Бином,  ISBN  5-7989-0168-8
     
     2.  А.  Архангельский.  Программирование  в  Delphi  5  
     Бином,  ISBN  5-7989-0104-1
     
     3.  А.  Архангельский.  Программирование  в  Delphi  6  
     Бином,  ISBN  5-7989-0227-7
     
     4.  П.  Даpахвелидзе,  Е.  Маpков  
     Delphi  4  в  подлиннике
     
     5.  П.  Дарахвелидзе,  Е.  Марков,  О.  Котенок  
     Программирование  в  Delphi  5  
     BHV-СПб,  ISBN  5-8206-0052-5
     
     6)  П.В.  Шумаков,  В.В.  Фаронов  "Delphi  xx.  Руководство  разработчика  баз  данных."
     
     7)  М.Кэнту  
     Delphi  4  для  пpофессионалов
     
     8.  Ч.Калвеpт
     Delphi  4,  Энциклопедия  пользователя
     
     9.  Стив  Тейксейра,  Ксавье  Пачеко
     Delphi  5.  Руководство  разработчика.  Том  1.  
     Основные  методы  и  технологии  программирования    
     Вильямс,  ISBN  5-8459-0016-6
     2000  Вильямс  
     
     10.  Стив  Тейксейра  И  Ксавье  Пачеко
     Delphi  5.  Руководство  разработчика.  Том  2.  
     Разработка  компонентов  и  работа  с  базами  данных  
     2000  Вильямс  
     ISBN  5-8459-0066-2
     
     11.  Конопка  Рей
     Создание  оригинальных  компонент  в  среде  Delphi:  Пер.  с  англ./Рей  Конопка.
     К.:  НИПФ  -  "ДиаСофт  Лтд.",  1996.  -  512  с.
     ISBN  5-7707-9551-4
     
     12.  Лишнер  Рэй
     Секреты  Delphi  2:  Пер.  с  англ./Рэй  Лишнер.  -
     К.:  НИПФ  -  "ДиаСофт  Лтд.",  1996.  -  800  с.
     ISBN  966-7033-10-4
     
     13.  Том  Сван  "Секреты  32-разрядного  программирования  в  Delphi"
     Диалектика,  Киев,  1997.  480  стр.,
     ISBN  966-506-052-X  (рус.)
     
     14.  Дэн  Оузьер  "Дельфи  2.  Освой  самостоятельно."  
     Восточная  Книжная  Компания,
     1997.  624  стр.  Binom.
     
     15.  Михаил  Кpаснов.  DirectX  Гpафика  в  пpоектах  Delphi
     BHV
     ISBN-5-94157-033-3
     
     В  списке  отсутствует  ряд  хороших  книг,  по  причине  недостаточнысти  данных,  если  у  кого  есть  замечания,  исправления  или  дополнения  по  данной  статье,  то  просьба  посылать  их  прямо  на  mailto:  anatoly@podgoresky.com
     
     Новые  книги  можно  искать  и  заказывать  через  Интернет  на  сайте  http://books.ru
     Там  же  как  правило  есть  аннотация.
     
     Кроме  указанных  книг  существует  большое  количество  ресурсов  в  Интернете  посвященных  Дельфи  -  это  статьи,  электронные  библиотеки  и  прочее.  Один  из  ресурсов  расположен  на  моем  сайте  -  это  несколько  проектов  электронных  библиотека,  в  совокупности  свыше  200  книг.  Доступ  ко  всем  проектам  прямо  с  главной  страницы  http://www.podgoretsky.com,  существует  так  же  доступ  и  по  FTP  (3  анонимных  сессии)
     
     Один  из  недостатков  -  это  то,  что  сервер  сильно  перегружен  все  24  часа  в  сутки,  семь  дней  в  неделю,  поэтому  скорость  весьма  низкая  и  использовать  какой  либо  менеджер  закачек;  также  не  рекомендуется  использовать  многопотоковую  закачку,  это  не  ускорит  сам  процесс  закачки,  а  только  уменьшит  возможность  закачки  для  других  пользователей.  
     Большинство  книг  с  моего  сервера  также  доступны  и  на  других  серверах,  и  если  есть  возможность  взять  их  из  другого  источника,  то  это  будет  более  оптимальным  вариантом  по  скорости.
     
     Анатолий  Подгорецкий

    Q-11: Каким именно релизом 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/
     
     В  данный  момент  появились  и  другие  обновления,  поэтому  стоит  периодически  проверять  данные  папки.  Учитываю  постоянные  изменения  у  Борланда,  вполне  может  оказаться,  что  в  будущем  данные  папки  могут  быть  недоступны.

    Q-12: Как исправить проблемы с вызовом помощи при одновременно стоящих Delphi 1 и Delphi 2

     (AP):  Решаются  так...
           
     В  regedit  убейте  из  секции  HKLM\SOFTWARE\Microsoft\Windows\Help  все,  что  равно  "...\help".
           
     Изменив  соответствующие  пути,  импортируйте  в  реестр  следующий  файлик:
           
     REGEDIT4
     
     [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppPaths\delphi32.exe]  
     @="C:\\DELPHI2\\BIN\\delphi32.exe"  "Path"="C:\\DELPHI2\\HELP"

    Q-13: Delphi 2 и 3 не отображают русские TTF под Windows NT WorkStation + ServicePack#3

     (AlPe):  Попробуй  сделать  в  
     
     [HKLM\Software\Microsoft\Windows  NT\CurrentVersion\FontMapper]
     DEFAULT=0xcc  (204)  вместо  0x00  (Именно  DEFAULT,  а  не  (Default)  :-)
     
     получше  маленько  будет...

    Q-14: Как включить окошко CPU Window?

     Вставьте  в  реестр  строковый  ключ
           
     HKCU\Software\Borland\Delphi\2.0\Debugging\
     EnableCPU=1
     
     Соответственно,  для  Delphi  3  --  Delphi\3.0.

    Q-15: Как установить компонент от Delphi одной версии под Delphi другой версии, если имеется только .DCU

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

    Q-16: Delphi 4 виснут при запуске. Видеокарта S3 Virge.

     REGEDIT4
     [HKEY_CURRENT_CONFIG\Display\Settings]
     "BusThrottle"="on"
     
     Если  не  помогает,  то  попробуйте  добавить  в  system.ini:
           
     [Display]
     "BusThrottle"="On"
     
     Можно  также  попробовать  снизить  аппратное  ускорение  или  поиграться  количеством  цветов,  но  наиболее  кардинальное  решение  -  сменить  видеокарту.

    Q-17: Как вывести диалог выбора каталога?

     (DS):  SelectDirectory,  rxLib:  TDirectoryEdit.
     
     Из  современных  средств  SHBrowseForFolder

    Q-18: При работе программ на D1 под Win95 на иконках TBitBtn'ов обнаруживаются странные артефакты

     При  работе  программ  на  Delphi  1  под  Windows  95  в  hicolor-режимах  на  иконках  TBitBtn'ов  обнаруживаются  странные  коричневые  артефакты.  Как  от  них  избавиться?
           
     (AB):  Залить  фон  битмапа  синим  цветом.

    Q-19: Можно ли скомпилировать на Delphi 2/3/4 программу, работающую под Windows 3.1?

     NP):  Hет,  но  в  дистрибутиве  с  Delphi  2/3/4  поставляется  Delphi  1  специально  для  этой  цели.

    Q-20: Куда из Delphi 3 делся модуль для работы с ReportSmith? А мои любимые модули работы с OLE

     Они  лежат  в  X:\DELPHI3\LIB\DELPHI2.

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

     uses  
         ShellApi;
     
     В  обработчике  OnClick  метки  или  клавиши  ввести  следующий  код.
     
     ShellExecute(Handle,'open','http://faq.delphiplus.org',nil,nil,SW_SHOWNORMAL);

    Q-22: 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-23: Как русифицировать сообщения программы?

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

    Q-24: Как во время компиляции модуля определить, под какой версией 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-25: Как сделать так, чтобы при щелчке по кнопке или по TLabel отправить письмо

     В  разделе  uses
         ShellAPI.
     
     В  обработчике  OnClick  метки  или  клавиши  ввести  следующий  код.
     
     ShellExecute(Handle,'open','mailto:lalala@lala.ru',nil,nil,SW_SHOWNORMAL);

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

     Воспользуйтесь  функцией  ActivatePrevInstance  из  библиотеки  rxLib.  Для  завершения  второго  экземпляра  используйте  Application.Terminate.
           
     (AS):  Другой  вариант:  X:\DELPHI2\DEMOS\IPCDEMOS\ipcthrd.pas,  функция  IsMonitorRunning().

    Q-27: Как мне вывести какое-нибудь окошко с картинкой, пока программа грузится?

     Смотрите  пример  в  X:\DELPHI\DEMOS\DB\MASTAPP\mastapp.dpr.
           
     Удобно  использовать  функцию  ShowSplashWindow  из  rxLib.

    Q-28: Как объявлять переменные, чтобы они были видны в других модулях проекта.

     Лучше  всего  создать  отдельный  модуль  для  таких  переменных,  назвать  его  скажем  ComVars.pas  и  подключать  его  в  остальных  модулях.
     
     unit  ComVars;
     
     interface
     
     var
         MyVar  :  Integer
     
     implementation
     end.
     
     Кроме  этого  модуля  полезно  создать  еще  два
     
     ComConst  -  для  общих  констант
     ComUtils  -  для  общих  процедур
     
     
     

    Q-29: А как поместить свою иконку на taskbar, там где часы и переключатель клавиатуры?

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

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

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

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

     В  rxLib  есть  TGradientCaption.

    Q-32: Как сделать так, чтобы по 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  

    Q-33: Как мне перекодировать строки из Win-кодировки в Dos-кодировку и наоборот?

     CharToOEM,  OEMToChar,  CharToOEMBuff,  OEMToCharBuff.  
     
     1.  if  S  <>  ''  then  CharToOem(PChar(S),PChar(S));
     2.  CharToOem(Pointer(S),Pointer(S));
     
     Примечания:
     
     1.  Не  стоит  вызывать  эту  функцию  если  S  =  ''  будет  ошибка,  второй  вариан  не  имеет  этой  ошибки.
     
     2.  Заметьте  однако,  что  эти  функции  не  умеют  делать  таких,  вещей,  как  koi8-r  в  DOS  и  т.  п.
     
     3.  Не  стоит  использовать  эту  функцию  также  для  преобрахования  из  русской  кодировки  DOS  в  русскую  Windows  и  обратно,  так  как  это  не  преобразование  по  русскому  алфавиту,  а  перекодирова  именно  из  DOS  в  Windows,  то  есть  на  основе  текущей  локализации  системы,  если  нужна  абсолютная  гарантия,  то  следует  вопользоваться  перекодировкой  по  таблице,  рекомендуется  по  полной  таблице  из  всех  256  символов,  на  моей  странице  (http://podgoretsky.com)  есть  универсальная  функция  перекодировки  (CharCvt)  с  набором  некоторых  основных  таблицю
     

    Q-34: К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-35: Как отловить события создания или удаления файлов другими программами?

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

    Q-36: Почему у меня record a : word; b : longint end; имеет размер восемь байт вместо шести?

     Если  не  использовать  ключевое  слово  packed,  то  Дельфи  производит  выравнивание  структуры  на  определенную  границу.  В  разных  версиях  Дельфи  по  разному.
     
     Для  того  что  избежать  этого,  надо  описать  структуру  следующим  образом:
     
     aRec  =  packed  record  
         a  :  Word;
         b  :  LongInt;
     end;
     
     Также  не  стоит  использовать  фундаментальные  типы,  так  как  их  размерность  зависит  от  версии  Дельфи.

    Q-37: Не перерисовываются окна во время длинного цикла

     Моя  программа  довольно  долго  делает  какую-то  полезную  работу,  типа  чтения  дерева  каталогов  или  обильных  вычислений,  и  в  этот  момент  почти  не  работают  остальные  программы.  Как  разрешить  им  это  делать?
           
     Application.ProcessMessages.
           
     (AA):  Если  вы  хотите  отдавать  timeslices  в  нитях,  пользуйтесь  Sleep(0);  это  отдаст  остаток  слайса  системе.
           
     (Win16)  Если  вы  хотите  разрешить  отработку  сообщений  другим  программам,  но  не  вашей,  то  лучше  пользоваться  Yield().

    Q-38: Как отследить "уход" курсора мыши с компонента?

     Надо  обрабатывать  события  CM_MOUSEENTER/CM_MOUSELEAVE.

    Q-39: Как мне запустить какую-нибудь программу

     Как  мне  запустить  какую-нибудь  программу?  А  как  подождать,  пока  эта  программа  не  отработает?  Как  выяснить,  работает  ли  программа  или  уже  завершилась?  Как  принудительно  закрыть  выполняющуюся  программу?
           
     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-40: Как правильно закрыть и удалить форму?

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

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

     TStrings  --  это  базовый  класс.  Вам  нужен  TStringList.

    Q-42: Мне надо добавить много строк в TListbox или в TCombobox или в TMemo

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

    Q-43: Как правильно создавать компоненты 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-44: Как мне запрограммировать непрямоугольную форму, например, как у Norton CrashGuard, в форме щита?

     SetWindowRgn()  (Win32).

    Q-45: Как использовать свои курсоры в программе?

     {$R  CURSORS.RES}
     
     const
         crZoomIn  =  1;
         crZoomOut  =  2;
     
     Screen.Cursors[crZoomIn]  :=  LoadCursor(hInstance,  'CURSOR_ZOOMIN');
     Screen.Cursors[crZoomOut]  :=  LoadCursor(hInstance,  'CURSOR_ZOOMOUT');
     
     С  вашей  программой  должен  быть  слинкован  файл  ресурсов,  содержащий  соответствующие  курсоры.

    Q-46: Как ограничить перемещение курсора мыши какой-либо областью экрана?

     ClipCursor().  Учтите,  что  использование  этой  функции  --  плохой  тон.

    Q-47: Как сделать так, чтобы запущенная программа не была видна на панели задач?

     Во-первых,  можно  по  примеру  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-48: Как из программы переключить раскладку клавиатуры?

     ActivateKeyboardLayout().  Учтите,  что  использование  этой  функции  --  плохой  тон.

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

     GetShortPathName()

    Q-50: String в PChar и обратно

     Для  этого  достаточно  приведения
     
     StringVar  :=  String(PCharVar);
     PCharVar  :=  PChar(StringVar);
     
     Предупреждение:
     Проявляйте  максимум  острожности,  не  меняйте  содержимое  StringVar,  так  как  при  этом  PCharVar  будет  указывать  уже  на  недействительный  адрес.

    Q-51: Как при наведении курсора на кнопку менять ее цвет?

     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-52: Как написать сервис для Windows NT?

     В  поставке  Delphi  4  есть  пример.  http://www.sawatzki.de.

    Q-53: Как работать с реестром?

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

    Q-54: Как выдвинуть дверцу 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-55: Как перехватывать клавиши, нажатые в окне другой программы? И вообще, любые события

     SetWindowsHookEx().

    Q-56: Как сделать индикатор прогресса для длительного запроса?

     Так  как  оценить  объем  запроса  до  его  выполнения  сложно,  то  совсем  непросто  придумать  (и  сделать)  что-то  лучше,  чем  показать  пользователю  TAnimate.
     
     Однако,  чтобы  показывать  что-либо  при  большом  запросе  придется  выполнять  запрос  в  потоке.  См.  пример  %delphi%\demos\db\bkquery
     

    Q-57: Как вызывать из 32-битной программы 16-битные DLL?

     Hадо  применять  так  называемые  "thunks".  Смотри  статьи  на  http://www.thedelphimagazine.com/samples/thunk/thunk95.htm
     

    Q-58: Как получить набранный в Блокноте текст в свою п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-59: Как скопировать экран в буфер обмена?

     keybd_event(VK_SNAPSHOT,  MapVirtualKey(VK_SNAPSHOT,  0),  0,  0);
     keybd_event(VK_SNAPSHOT,  0,  0,  0);

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

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

    Q-61: Как показать Hint для MenuItem?

     Нint,  назначенный  Item,  можно  показать  в  Statusbar:
     
     procedure  TForm1.AppHint(Sender:  TObject);
     begin
         StatusBar1.SimpleText  :=  Application.Hint;
     end;
     
     procedure  TForm1.FormCreate(Sender:  TObject);
     begin
         Application.OnHint  :=  AppHint;
     end;

    Q-62: Как можно перетаскивать форму не только за заголовок?

     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  
     ----------------------------------------------------------------------------
     
     Ещё  один  метод  пе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-63: Как сделать прозрачным фон при выводе Canvas.TextOut?

     Canvas.Brush.Style  :=  bsClear;

    Q-64: Как применить изменение в реестре без перезагрузки компьютера?

     Многие  программы  могут  откликнуться  на:  
     
         SendMessage(HWND_BROADCAST,  WM_SETTINGCHANGE,  ..)      в  Win9х
         SendMessage(HWND_BROADCAST,  WM_WININICHANGE,  0,  ..)  в  NT

    Q-65: Как добавить пункты в системное меню окна?

     Получить  хэндл  системного  меню  окна  можно  с  помощью  функции  GetSystemMenu().

    Q-66: Как в Мемо установить каретку в нyжнyю позицию?

     with  Memo  do
         SelStart  :=  Perform(EM_LINEINDEX,  LineIndex,  0)  +  CharIndex;
     
     PS:  каретка  -  это  специальный  указатель  позиции  ввода  следующего  символа,  не  путать  с  курсором  мышки.

    Q-67: Можно ли сделать так, чтобы в исполняемом файле программы находился какой-нибудь звук в формате .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-68: Как сделать в меню список последних открытых файлов?

     Пусть  список  файлов  хранится  в  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;

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

     Поменять:
           
     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-70: Какое событие происходит при минимизации окна?

     OnResize
     Для  MainForm  :  Application.OnMinimize

    Q-71: Как во время выполнения программы создать так называемый "array of const"

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

    Q-72: Как сохранить в 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-73: Как обратиться к определенному адресу физической памяти?

     Как  обратиться  к  определенному  адресу  физической  памяти?  А  как  прочитать  значение  из  порта?  Где  мой  любимый  массив  Port[]?
           
     Прочитайте  какую-нибудь  книжку  про  программирование  под  Win32.  Вкратце  --  забудьте  про  все  эти  глупости.
     
     P.S.  Q155  содержит  несколько  методов  работы  с  портами,  как  легальных,  так  и  не  вполне.  В  статье  также  содержится  несколько  ссылок  на  наиболее  известные  драйвера.

    Q-74: Как закрыть внешнюю программу?

     Например,  Блокнот  можно  закрыть  так:
     
     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-75: Как загрузить из ImageList иконку приложения?

     ImageList1.GetIcon(Idx,  Application.Icon);

    Q-76: Как использовать в качестве обработчика сообщения обычную процедуру, а не метод объекта?

     У  этой  процедуры  должен  быть  еще  один  дополнительный  параметр.
     В  метод  класса  к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  

    Q-77: Как отловить нажатие 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-78: В какой позиции Memo находится каретка?

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

    Q-79: Как работать с графическими форматами, хотя бы самыми известными?

     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-80: Почему после RichEdit1.Lines.SaveToFile(name) в файле, кроме моего текста, ещё всякий бред написан?

     Таким  образом  в  RTF  сохраняется  информация  об  оформлении  текста.  Если  сохранять  нужно  только  текст,  перед  записью  сделай
     
         RichEdit1.PlainText  :=  True;

    Q-81: Как работать с файлами архивов, хотя бы самыми распространенными?

     Воспользуйтесь  библиотекой  ExceedZip  3.0  (http://www.exceedsoft.com).

    Q-82: Как вставить картинку в 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-83: Как использовать 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-84: Как дождаться завершения программы, запущенной 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-85: Как использовать 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-86: Как в TMemo вставить дату в позицию каретки?

     Memo1.SetSelTextBuf(PChar(DateToStr(Date)));

    Q-87: Как отловить системную ошибку при операциях с файлами?

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

    Q-88: Где достать процедуру типа "сумма прописью"?

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

    Q-89: Как узнать, была ли создана ли определенная форма?

     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-90: Какие инструменты можно применить для коллективной разработки проекта?

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

    Q-91: Что такое Handle окна, и как его полyчить?

     Handle  -  это  число  -  уникальный  идентификатор  окна  (в  данном  случае)  в  системе.
     Получить  его  можно,  например,  так:
     
         hwnd  :=  FindWindow  (nil,  'Form1');  //ищем  окнo  с  заголовком  "Form1"
         if  hwnd  <>  0  then  {нашлось};

    Q-92: Как можно обнаружить утечки памяти и ресурсов в программе?

     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-93: Как проиграть 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-94: Мне нужно заниматься разбором математических выражений

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

    Q-95: Как обратиться к свойству по его имени?

     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  

    Q-96: Как уменьшить размер исполняемого файла программы?

     Писать  на  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-97: Как нажать 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  

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

     http://www.iconbazaar.com
     http://delphiplus.org/freeother.html

    Q-99: Аналог Case для строк

     Вопрос:  Нужно  определить  с  какой  из  заданных  строк  совпадает  некая  строковая  переменная  и  в  зависимости  от  этого  перейти  к  соответсвующей  процедуре.  Как  это  выполнить  без  использования  многочисленных  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-100: Как в 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-101: Как отловить нажатие клавиш 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-102: Как мне работать с файлами 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
     
     -----------------------
     
     Второй  путь,  более  правильный.
     
     Нужно  импортировать  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  
     
     Замечание  от  Denver  The  Marion  
     Нашёл  такую  интересную  закономерность  директива  W.Free  не  закрывает  MS  Word  -  он  остаётся  в  памяти  и  висит  там  (при    этом  нормально  не  открывается  только  что  созданные  документы).  Если  изменить  строку  на  W.Quit  -  всё  работает  нормально.  Рабиралось  всё  это  дело  на  Delphi  5  и  MS  Word  2000.

    Q-103: Как записать в файл несколько 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-104: Как показать текстовый файл в 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-105: Delphi 5.0 and Win2K

     1.  Если  кто  не  читает  readme-файлы  до  начала  установки,  то  с  интересом  узнает,  что  в  сопроводиловке  от  Борланд  указывается  на  проблему  неправильной  работы  инсталлятора,  если  используются  кнопки  Browse  для  смены  каталогов  установки.  При  этом  рекомендуется  набрать/подредактировать  пути  вручную.  (Не  проверял,  просто  действовал
     как  рекомендовано,  хотя  пути  по  умолчанию  никогда  не  использую).
     
     2.  При  установке  с  жесткого  диска,  весь  дистрибутив  вместе  с  папками  Runimage  и  Install  надо  либо  поместить  в  корень  логического  диска  (что  обычно  неудобно),  либо  используя  subst  (или  в  сети  -  use  net),  сотворить  букву  для  этого  пути.  Чтобы  инсталлятор  решил,  что  установка  идет  из  корня  диска.  Иначе  -  облом-с.
     
     3.  При  установке  на  машину,  на  которой  предполагается  наличие  нескольких  программеров,  работающих  посменно,  сначала  придется  поставить  из-под  админа  -  для  всех.  А  потом  -  из-под  каждого  аккаунта  (хотя  бы  в  режиме  Registry  +  Custom).  Иначе  не  будет  компонентов  на  палитре.
     
     4.  Проверить  переменные  среды  %TEMP%  и  %TMP%,  рекомендуется  короткий  путь  -  C:\TEMP
     
     5.  Первичная  установка  под  административным  аккаунтом  с  АНГЛИЙСКИМ  именем,  например  admin
     
     Vladimir  Kladov  
     -----------------------------------
     
     Можно  экспоpтиpовать  y  админа  HKEY_CURRENT_USER/Software/Borland  и  пpосто
     импоpтиpовать  для  каждого  потом.  Так  несколько  быстpее,  чем  инсталиpовать  и  уменьшается  количество  ошибок.
     
     Ruslan  Fedoseev  

    Q-106: Почему в консольных приложениях неправильно отображаются русские буквы?

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

    Q-107: В чем pазличия ShellExecute и CreateProcess?

     ShellExecute  может  запустить  приложение,  ассоциированное  с  расширением  файла,  например:    
     
         ShellExecute(Handle,  'open',  'mydoc.doc',  nil,  nil,  SW_SHOW);
     
     запустит  Word  (или  другое  приложение,  зарегистрованное  для  *.doc)  и  откроет  файл  mydoc.  
     
     CreateProcess  не  обращает  внимание  на  расширения,  но  возможности  этой  функции  гораздо  больше.  Одна  из  главных  -  получение  handles  нового  процесса  и  его  первичного  потока,  с  помощью  которых  можно  запрашивать  информацию  о  ходе  дочернего  процесса.
     
     Надо  заметить,  что  хендл  дочернего  процесса  может  вернуть  функция  ShellExecuteEx,  которая  занимает,  скажем,  промежуточное  положение.

    Q-108: Как вставить картинку в StatusPanel?

     Image1.Parent  :=  StatusBar1;

    Q-109: Как внедрить 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-110: Как показывать хинты для частично видимых элементов ListBox?

     Написать  для  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-111: Как центрировать по форме модальный диалог?

     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;

    Q-112: Чем отличаются TLabel и TStaticText?

     TLabel  is  TGraphicControl
     TStaticText  is  TWinControl
       
     То  есть  у  последнего  есть  окно,  это  дает  возможность  управлять  этим  контролом  с  помощью  сообщений  Windows.

    Q-113: Как издать звук через PC Speaker?

     //  Для  НТ  вызов  функции  из  ОС,  для  9x  прямое  обращение  к  портам
     
     Procedure  BeepEx(Freq:  Word;  Duration:  Integer);
     var  
         Ver:  TOsVersionInfo;
     begin
         Ver.dwOSVersionInfoSize  :=  SizeOf(Ver);
         GetVersionEx(Ver);
         if  Ver.dwPlatformId  =  VER_PLATFORM_WIN32_NT  then  
             Windows.Beep(Freq,  Duration)  
         else  begin
             asm
                 movzx  ecx,  Freq
                 mov  eax,  1193180            //  тактовая  частота
                 sub  edx,  edx
                 div  ecx                              //  преобразование  частоты  в  делитель
                 mov  ecx,  eax
                 mov  al,0b6H
                 out  43H,al                        //  управляющие  слово
                 mov  al,cl
                 out  42h,al                        //  младший  байт  делителя
                 mov  al,ch
                 out  42h,al                        //  старший  байт  делителя
                 in    al,61H
                 or    al,03H
                 out  61H,al                        //  включить  звук
             end;
             sleep(Duration);                //  пауза  на  время  звучани
             asm
                 in    al,61H
                 and  al,0fcH
                 out  61H,al                        //  выключить  звук  по  окончанию  Duration
             end;
         end;
     end;

    Q-114: Как корректнее завершать приложение- Terminate или MainForm.Close?

     Terminate  очень  грубый  метод.    Если  вызывать  Application.Terminate,  то  не  сработают  обработчики  OnCloseQuery,  OnClose  главной  формы.

    Q-115: Как узнать версию Windows?

     Использовать  функцию  API  GetVersionEx
     
     function  GetVersionEx(var  lpVersionInformation:  TOSVersionInfo):  BOOL;  stdcall;
     
     Аргумент  функции  –  структура  TOSVersionInfo,  содержит
     dwVersionInfoSize:DWORD  –  заполняется  как  sizeof  TOSVersionInfo)  перед  вызовом  функции
     
     dwMajorVersion:DWORD  –  старшая  цифра  версии  Windows  
         Windows  95            -  4  
         Windows  98            -  4  
         Windows  Me            -  4  
         Windows  NT  3.51  -  3  
         Windows  NT  4.0    -  4  
         Windows  2000        -  5  
         Windows  XP            -  5  
     
     dwMinorVersion:  DWORD  –  младшая  цифра  версии
         Windows  95            -  0  
         Windows  98            -  10  
         Windows  Me            -  90  
         Windows  NT  3.51  -  51  
         Windows  NT  4.0    -  0  
         Windows  2000        -  0  
         Windows  XP            -  1  
     
     dwBuildNumber:  DWORD
       Win  NT  4  –  номер  билда
       Win  9x      –  старший  байт  –  старшая  и  младшая  цифры  версии  /  младший  –  номер  билда
     
     dwPlatformId:  DWORD
       VER_PLATFORM_WIN32s                        Win32s  on  Windows  3.1.  
       VER_PLATFORM_WIN32_WINDOWS          Win32  on  Windows  9x
       VER_PLATFORM_WIN32_NT                    Win32  on  Windows  NT,  2000
     
     szCSDVersion:DWORD
         NT  –  содержит  PСhar  с  инфо  о  установленном  ServicePack
         9x  –  доп.  инфо,  может  и  не  быть  
     
     Alexander  Kramarenko  
     ++++++++++++++++++++++++++++++++++++++++++++++++++++
     
     type
         TWinVersion  =  (wvUnknown,wv95,wv98,wvME,wvNT3,wvNT4,wvW2K,wvXP);
     
     function  DetectWinVersion  :  TWinVersion;
     var
         OSVersionInfo  :  TOSVersionInfo;
     begin
         Result  :=  wvUnknown;
         OSVersionInfo.dwOSVersionInfoSize  :=  sizeof(TOSVersionInfo);
         if  GetVersionEx(OSVersionInfo)  then  begin
             case  OSVersionInfo.DwMajorVersion  of
                 3:    Result  :=  wvNT3;
                 4:    case  OSVersionInfo.DwMinorVersion  of
                             0:  if  OSVersionInfo.dwPlatformId  =  VER_PLATFORM_WIN32_NT
                                   then  Result  :=  wvNT4
                                   else  Result  :=  wv95;
                             10: Result  :=  wv98;
                             90: Result  :=  wvME;
                         end;
                 5:    case  OSVersionInfo.DwMinorVersion  of
                             0: Result  :=  wvW2K;
                             1: Result  :=  wvXP;
                         end;
             end;
         end;
     end;
     
     function  DetectWinVersionStr  :  string;
     const
         VersStr  :  array[TWinVersion]  of  string  =  (
             'Unknown',
             'Windows  95',
             'Windows  98',
             'Windows  ME',
             'Windows  NT  3',
             'Windows  NT  4',
             'Windows  2000',
             'Windows  XP');
     begin
         Result  :=  VersStr[DetectWinVersion];
     end;
     
     procedure  TForm1.Button1Click(Sender:  TObject);
     begin
         Ver  :=  DetectWinVersion;
         Label1.Caption  :=  IntToStr(Ord(DetectWinVersion));
         Label2.Caption  :=  DetectWinVersionStr;
     end;
     
     Анатолий  Подгорецкий
     +++++++++++++++++++++++++++++++
     
     глобальные  переменные  Win32Platform  (в  справке),  
     Win32MajorVersion,  
     Win32MinorVersion,
     Win32BuildNumber  (в  модуле  SysUtils).  
     
     Инициализируются  они  автоматически,  остается  только  проверить  их.
     
     Юрий  Зотов  
     -+++++++++++++++++++++++++++++
     
     DA>  Может  комy  известен  способ  отличить  Windows  2000  Server  от  Wks?
     
     HKLM\System\CurrentControlSet\Control\ProductOptions
     ProductType:REG_SZ  (WinNT  -  Prof,  ServerNT  -  Server,  LanmanNT  -  сервер  и
     контроллер  домена).
     Именно  по  этому  ключику  сама  винда  определяет.
     Это  также  относится  и  к  NT4  (а  может  и  ко  всему  остальному)
     ++++++++++++++++++++++++++++++
     
     DA>  Может  комy  известен  способ  отличить  Windows  2000  Server  от  Wks?
     
     Для  определения  версии  Windows  используем  API-функцию
     GetVersionEx(pOSVersionInfo),  где  pOSVersionInfo  -  указатель  на  структуру
     следующего  вида:
     
     type
         TOSVersionInfoEx  =  record
             OsVersionInfoSize:  DWORD;  {Размер  структуры  типа  TOSVersionInfo.
     Поле  обязательно  должно  быть  заполнено  перед  вызовом  GetVersionEx}
             MajorVersion:  DWORD;  {основной  номер  версии  ОС}
             MinorVersion:  DWORD;  {дополнительный  номер  версии  ОС}
             BuildNumber:    DWORD;  {номер  сборки  ОС}
             PlatformId:      DWORD;  {Идентификатор  платформы}
             CSDVersion:      array  [0..127]  of  char;  {Текстовая  строка  вида:
     'Service  Pack  3'}
             ServicePackMajor:  WORD;  {основной  номер  service  pack}
             ServicePackMinor:  WORD;  {дополнительный  номер  service  pack}
             SuiteMask:                WORD;  {доступные  программные  пакеты;  доступные  значения:
     VER_SUITE_BACKOFFICE,  VER_SUITE_BLADE,  VER_SUITE_COMPUTE_SERVER,
     VER_SUITE_DATACENTER,  VER_SUITE_ENTERPRISE,  VER_SUITE_EMBEDDEDNT,
     VER_SUITE_PERSONAL,  VER_SUITE_SINGLEUSERTS,  VER_SUITE_SMALLBUSINESS,
     VER_SUITE_SMALLBUSINESS_RESTRICTED,  VER_SUITE_STORAGE_SERVER,
     VER_SUITE_TERMINAL}
             ProductType:            Byte;  {вариант  ОС;  принимает  значения:
                               VER_NT_WORKSTATION,  VER_NT_SERVER,  VER_NT_DOMAIN_CONTROLLER}
             Reserved:  Byte;  {зарезервировано  для  будущих  версий  ОС}
         end;
     
       MajorVersion  может  принимать  следующие  значения:  4  -  Windows  NT4;
     5  -  Windows  2000,  Windows  XP,  Windows  2003  Server,  Windows  2003  R2,
     6  -  Windows  Vista  или  Windows  "Longhorn"  Server.
       MinorVersion  модет  принимать  следующие  значения:  0  -  Windows  Vista,
     Windows  "Longhorn"  Server,  Windows  2000,  Windows  NT4;
     1  -  Windows  XP;  2  -  Windows  2003,  Windows  2003  R2,  Windows  XP  64bit  Edition.
     
     Значения  полей  SuiteMask  и  ProductType  смотри  в  MSDN,  поскольку  в  windows.pas,  включая  Delphi  7  описан  старый  вариант  TOSVersionInfo  (не  знаю,  как  с  этим  обстоят  дела  в  Delphi  .NET).
     Отсюда  можно  сделать  вывод:  или  подправить  windows.pas,  или  описывать  самому  приведенную  выше  структуру  (обрати  внимание,  что  я  специально  назвал  ее  TOSVersionInfoEx,  чтобы  не  конфликтовать  с  TOSVersionInfo  из  windows.pas).
     Может  в  jvcl  поправили  данную  структуру.
     Если  ты  уверен,  что  твой  программный  продукт  будут  использовать  только  на  платформах  версий  Windows  2000  и  старше  (включая  Windows  CE),  тогда  поле  CSDVersion  объяви  как  массив  WideChar  и  используй  вызов  API-функции  GetVersionExW.
     Я  смею  предположить,  что  программа  (вызывающая  GetVersionEx  с  подобной  структурой)  завершится  аварийно,  если  программу  запустить  в  среде  Windows  95/98/Me.
     
     Oleg  Levkin  

    Q-116: Как из dll узнать узнать полный путь к этой dll.

     function  GetModuleFileNameStr(Instance:  THandle):  String;
     var
         buffer  :  array  [0..MAX_PATH]  of  Char;
     begin
         GetModuleFileName(  Instance,  buffer,  MAX_PATH);
         Result  :=  buffer;
     end;
     
           GetModuleFileNameStr(Hinstance);  //  dll  name
           GetModuleFileNameStr(0);  //  exe  name
     
     Leonid  Troyanovsky  

    Q-117: Как отобразить каталог?

     ListBox1.Perform(LB_DIR,  0,  LParam(PChar('*.*')));

    Q-118: Как узнать кол-во цветов цветовой палитры?

     function  GetColorsCount  :  DWord;
     var
         DC  :  HDC;
     begin
         DC  :=  GetDC(  0  );
         Win32Check(DC  <>  0);
         Result  :=1  shl  (GetDeviceCaps(DC,  PLANES)  *
                                         GetDeviceCaps(DC,  BITSPIXEL));
         ReleaseDC(  0,  DC  );
     end;
     
     Leonid  Troyanovsky  

    Q-119: Как ввести текст в "чужой" Edit?

     SendMessage(EditHandle,  WM_SETTEXT,  0,  LParam(PChar('MyText')));

    Q-120: Как заставить мигать кнопку приложения на AppBar?

     procedure  TForm1.Timer1Timer(Sender:  TObject);
     begin
         FlashWindow(Application.Handle,  True);
     end;
     
     Leonid  Troyanovsky  

    Q-121: Как сделать программу без главной формы?

     program  Project1;
     
     uses
         Dialogs;
     
     begin
         ShowMessage('Is  there  anybody  out  there  ?'  );
     end.

    Q-122: Как убрать VerticalScrollBar из TListBox навсегда?

     procedure  TListBoxForEver.CreateParams  (var  Params:
         TCreateParams);  //override
     begin
         inherited  CreateParams(Params);
         Params.Style  :=  Params.Style  and  not  WS_VSCROLL;
     end;
     
     Leonid  Troyanovsky  

    Q-123: Как показать диалог выбора директории?

     из  модуля  FileCtrl.
     
     1.  function  SelectDirectory(const  Caption:  string;  const  Root:  WideString;  out  Directory:  string):  Boolean;  overload;
     2.  function  SelectDirectory(var  Directory:  string;  Options:  TSelectDirOpts;  HelpCtx:  Longint):  Boolean;  overload;
     
     из  RxLib
     TDirectoryEdit  
     
     function  GetDirectory(nFolder:  Longint):  String;
     var
         Bi  :  TBrowseInfo;
         lpName:  array  [0..MAX_PATH]  of  Char;
         ppidl,  aItemLst  :  PItemIDList;
     begin
         SHGetSpecialFolderLocation(Application.Handle,  nFolder,  ppidl);
         FillChar(Bi,  SizeOf(bi),  0);
         Bi.hwndOwner  :=  Application.Handle;
         Bi.pidlRoot  :=  ppidl;
         Bi.pszDisplayName  :=  lpName;
         Bi.lpszTitle  :=  'Open  directory';
         aItemLst  :=  SHBrowseForFolder(Bi);
         CoTaskMemFree(ppidl);
         SHGetPathFromIDList(aItemLst,  lpName);
         CoTaskMemFree(aItemLst);
         Result  :=  lpName;
     end;
     
     Пример  использования  (иначе  не  поймут,  что  такое  nFolder)
     
     //  значения  nFolder  можно  найти  в  описании  
     //  к  SHGetSpecialFolderLocation
     //  из  Win32  Programmer's  Reference  (win32.hlp)
     
     procedure  TForm1.Button1Click(Sender:  TObject);
     begin
         Caption  :=  GetDirectory(CSIDL_DRIVES);
     end;

    Q-124: Как убрать из ListView горизонтальный скролбар навсегда?

     type  
         TNoHScrollListview  =  Class(  TListview  )  
         private  
             Procedure  WMNCCalcSize(  Var  msg:  TMessage  );  message  WM_NCCALCSIZE;  
         end;  
     
     procedure  TNoHScrollListview.WMNCCalcSize(var  msg:  TMessage);  
     var  
         style:  Integer;  
     begin  
         style  :=  getWindowLong(  handle,  GWL_STYLE  );  
         If  (style  and  WS_HSCROLL)  <>  0  Then  
             SetWindowLong(  handle,  GWL_STYLE,  style  and  not  WS_HSCROLL  );  
         inherited;  
     end;  
     
     by  Peter  Below

    Q-125: Кaк искать oкнo по части eгo нaзвaния?

     function  FindNextWnd(StartHWND:  HWND;  AString  :  String):  HWND;
     var
         Buffer  :  array  [0..255]  of  char;
     begin
         Result  :=  StartHWND;
         repeat
             Result  :=  FindWindowEx(0,  Result,  nil,  nil);
             GetWindowText(Result,  Buffer,  SizeOf(Buffer));
             if  StrPos(StrUpper(Buffer),  PChar(UpperCase(AString)))  <>  nil  
             then    Break;
         until  (Result  =  0);
     end;

    Q-126: Как обнаружить активность юзера?

     Application.OnMessage  :=  DoMessageEvent;
     
     procedure  TForm1.DoMessageEvent  (  var  Msg:  TMsg;
         var  Handled:  Boolean);
     begin
         case  Msg.message  of
             WM_KEYFIRST..WM_KEYLAST,
             WM_MOUSEFIRST..WM_MOUSELAST:
                 {Произошли  события  клавиатуры  и  мыши};
               ..
         end;
     end;
     
     Leonid  Troyanovsky  

    Q-127: Как yзнать текущую Ru/En pаскладкy клавиатypы?

     GetKeyboardLayoutName(buffer{:array  [0..KL_NAMELENGTH]  of  Char});
     case  ((StrToInt('$'+  Buffer))  and  $03FF)  of
         LANG_ENGLISH:  Caption  :=  'Eng';
         LANG_RUSSIAN:  Caption  :=  'Rus';
     end;
     ++++++++++++++++++++++++++++
     
     procedure  TForm1.Button1Click(Sender:  TObject);
     var
         AklName:  array  [0..2]  of  Char;
     begin
         GetLocaleInfo(  LoWord(GetKeyboardLayout(0)),
                                       LOCALE_SABBREVLANGNAME,
                                       AklName,
                                       SizeOf(AklName));
         Caption  :=  AklName;
     end;
     
     Leonid  Troyanovsky  

    Q-128: Как передать строку другому приложению?

     получатель:
     
     procedure  ReceiveMessage  (var  Msg:  TMessage);  message  WM_COPYDATA;
     ..
     procedure  TFormReceive.ReceiveMessage;
     var
         pcd  :  PCopyDataStruct;
     begin
         pcd  :=  PCopyDataStruct(Msg.LParam);
         Caption  :=  PChar(pcd.lpData);
     end;
     
     отправитель:
     
     procedure  TFormXXX.Button1Click(Sender:  TObject);
     var
       cd  :  TCopyDataStruct;
     begin
       cd.cbData  :=  Length(Edit1.Text)+1;
       cd.lpData  :=  PChar(Edit1.Text);
       SendMessage  (  FindWindow('TFormReceive',  nil),
                                   WM_COPYDATA,
                                   0,
                                   LParam(@cd));
     end;
     
     Leonid  Troyanovsky  

    Q-129: Как RichEdit сделать скролл на конец текста?

     with  RichEdit  do  begin
         SelLength  :=  0;
         SelStart  :=  Length(Text);
         Perform(EM_SCROLLCARET,0,0);
     end;

    Q-130: Удаление файлов из временного каталога, безопасно ли?

     При  получении  имени  папки  предназначенной  для  хранения  временных  файлов  могут  возникнуть  некоторые  проблемы.
     
     >>  Прекрасно  это  выглядит,  когда  в  качестве  каталога  временных  файлов  назначен  например  C:\Windows
     
     >:-)  Я  и  говорю  что  небезопасно.
     
     Особенно  пикантно  это  выглядит,  в  свете  того,  что
     
     Remarks
     Windows  95/98/Me:  The  GetTempPath  function  gets  the  temporary  file
     path  as  follows:  
     
     The  path  specified  by  the  TMP  environment  variable.  The  path  specified  by  the  TEMP  environment  variable,  if  TMP  is  not  defined  or  if  TMP  specifies  a  directory  that  does  not  exist.  The  current  directory,  if  both  TMP  and  TEMP  are  not  defined  or  specify  nonexistent  directories.  
     
     Этак  переименовываешь  C:\TEMP  -  и  программа  чистит  текущий  каталог  :-)
     
     Windows  NT/2000  or  later:  The  GetTempPath  function  does  not  verify  that  the  directory  specified  by  the  TMP  or  TEMP  environment  variables  exists.  The  function  gets  the  temporary  file  path  as  follows:  
     
     The  path  specified  by  the  TMP  environment  variable.    The  path  specified  by  the  TEMP  environment  variable,  if  TMP  is  not  defined.    The  Windows  directory,  if  both  TMP  and  TEMP  are  not  defined.  
     
     Этак  удаляешь  переменные  окружения  -  и  программа  "деинсталлирует"  Windows
     
     Из  этого  вытекает  следующее,  удаление  файлов  из  любого  каталога,  особенно  из  временного  чрезвычайно  опасная  операция,  не  ты  создал  -  не  трогай.  Удалять  только  ручками,  глядя  на  файлы  и  принимая  решения  индивидуально  по  каждому  файлу.
     
     При  использовании  функции  GetTempPath  проверить  если  подстрока  TEMP  в  результате  и  в  случае  отсутствия  вхождения  запросить  пользователя  для  принятия  решения,  с  рекомендацией  создать  каталог  TEMP  и  необходимые  переменные  среды,  лучше  посоветоваться  обратиться  к  администратору  для  принятия  решения.  Это  простое  правило  позволит  избежать  серьезных  последствий.
     
     Тенцер  А.Л.  
     Andrew  V.  Fionik  
     Anatoly  Podgoretsky  

    Q-131: Как узнать состояние управляющих клавиш - Shift, Ctrl, Alt?

     function  IsKeyDown(vk:  Word):Boolean;
     begin
         Result  :=  GetKeyState(vk)  and  $8000  =  $8000;
     end;
     
     vk  для  Ctrl,  Shift,  Alt  соответственно  равны:  vk_control,  vk_shift  и  vk_menu

    Q-132: Как сохранить всю форму в файл (как Delphi в *.dfm)?

     constructor  TForm1.Create(AOwner:  TComponent);  //  override;
     var
         fname:  String;
     begin
         {  Для  динамически  создаваемых  контролов,  может  требоваться
         RegisterClasses(..);  }
         fname  :=  FormFilename;
         if  FileExists(  fname  )  then
             begin
                 CreateNew(AOwner);
                 ReadComponentResFile(fname,  Self);
             end
         else
             inherited  Create(  AOwner  );
     end;
     
     procedure  TForm1.FormCloseQuery(  Sender:  TObject;
           var  CanClose:  Boolean);
     begin
         WriteComponentResFile(FormFileName,  Self);
     end;
     
     {Peter  Below,  Vladimir  Titov}

    Q-133: Как контрол может сам себя разрушить?

     TMyWinControl  =  class(TWinControl)
     private
         procedure  WMuser1(var  msg:  TMessage);  message  WM_USER+1;
         ...
     public
         procedure  Release;
         ...
     end;
     
     procedure  TMyWinControl.WMuser1;
     begin
         Free;
     end;
     
     procedure  TMyWinControl.Release;
     begin
         PostMessage(Handle,  WM_USER+1,  0,  0);
     end;

    Q-134: Как отследить переход фокуса в приложении?

     procedure  TForm1.AppControlChange(Sender:  TObject);  
     begin  
           if  Sender  is  TScreen  then  
               Caption  :=  TScreen(Sender).ActiveForm.ActiveControl.Name;  
     end;  
     
     procedure  TForm1.FormCreate(Sender:  TObject);  
     begin  
         Screen.OnActiveControlChange  :=  AppControlChange;  
     end;  
     
     Leonid  Troyanovsky  

    Q-135: Как заставить MediaPlayer крутить один и тот же клип?

     procedure  TForm1.WMUser1(var  msg:TMessage);//  message  WM_USER+1;
     begin
         with  MediaPlayer1  do  begin
             Previous;
             Notify  :=  True;
             Play;
         end;
     end;
     
     procedure  TForm1.MediaPlayer1Notify(Sender:  TObject);
     begin
         if  (Sender  as  TMediaPlayer).NotifyValue  =  nvSuccessful  then
             PostMessage(Handle,  WM_USER+1,  0,  0);
     end;

    Q-136: Как назначить процедуру собственному пункту системного меню?

     const  
         cm_mycommand  =  $00A0;  
     
     procedure  TForm1.FormCreate(Sender:  TObject);  
         var  HSysMenu:  HMENU;  
     begin  
         HSysMenu:=GetSystemMenu(Handle,FALSE);  
         InsertMenu(  HSysMenu,  0,  MF_BYPOSITION  or  MF_STRING,  
                                 cm_mycommand,  'MyString');  
     end;  
     
     procedure  TForm1.WMSysCommand  (var  Message:  
         TWMSysCommand);  //  message  WM_SYSCOMMAND;  
     begin  
         case  Message.CmdType  of  
             cm_mycommand:  ShowMessage('My  Command');  
         else  
             inherited;  
         end;  
     end;  
     
     Leonid  Troyanovsky  

    Q-137: Какой класс окна у консоли?

     'tty'  for  9x
     'ConsoleWindowClass'  for  NT

    Q-138: Какое сообщение надо отлавливать в Application.OnMessage для отслеживания клавиши Alt (vk_menu)

     WM_SYSKEYDOWN/WM_SYSKEYUP  

    Q-139: Как спрятать контрол, если известен его Handle?

     ShowWindow(ButtonHandle,  SW_HIDE);  //  SW_SHOW

    Q-140: Как поменять иконку и стpокy в заголовке консольного окна?

     procedure  TForm1.Button1Click(Sender:  TObject);  
     var  
         h  :  HWND;  
         AIcon  :  TIcon;  
     begin  
         AllocConsole;  
         SetConsoleTitle(PChar('Console  Title'));  
         Sleep(0);  
         h  :=  FindWindow(nil,  PChar('Console  Title'));  
         AIcon  :=  TIcon.Create;  
         ImageList1.GetIcon(0,  AIcon);  
         SendMessage(h,  WM_SETICON,  1,  AIcon.Handle);  
         AIcon.Free;  
     end;  
     
     Leonid  Troyanovsky  

    Q-141: Как сделать окно без VCL?

     program  Project1;
     
     {  Copyright  (c)  1996  by  Charlie  Calvert
     
         Standard  Windows  API  application  written  in  Object  Pascal.
         No  VCL  code  included.  This  is  all  done  on  the  Windows  API
         level.
         
         Note  that  you  need  to  include  both  Windows  and  Messages!}
     
     uses
         Windows,  Messages;
     
     const
         AppName  =  'Window1';
     
     function  WindowProc(Window:  HWnd;  AMessage,  WParam,
                                             LParam:  Longint):  Longint;  stdcall;
     begin
         WindowProc  :=  0;
     
         case  AMessage  of
             wm_Destroy:  begin
                 PostQuitMessage(0);
                 Exit;
             end;
         end;
     
         WindowProc  :=  DefWindowProc(Window,  AMessage,  WParam,  LParam);
     end;
     
     {  Register  the  Window  Class  }
     function  WinRegister:  Boolean;
     var
         WindowClass:  TWndClass;
     begin
         WindowClass.Style  :=  cs_hRedraw  or  cs_vRedraw;
         WindowClass.lpfnWndProc  :=  @WindowProc;
         WindowClass.cbClsExtra  :=  0;
         WindowClass.cbWndExtra  :=  0;
         WindowClass.hInstance  :=  HInstance;
         WindowClass.hIcon  :=  LoadIcon(0,  idi_Application);
         WindowClass.hCursor  :=  LoadCursor(0,  idc_Arrow);
         WindowClass.hbrBackground  :=  HBrush(Color_Window);
         WindowClass.lpszMenuName  :=  nil;
         WindowClass.lpszClassName  :=  AppName;
     
         Result  :=  RegisterClass(WindowClass)  <>  0;
     end;
     
     {  Create  the  Window  Class  }
     function  WinCreate:  HWnd;
     var
         hWindow:  HWnd;
     begin
         hWindow  :=  CreateWindow(AppName,  'Object  Pascal  Window',
                                 ws_OverlappedWindow,  cw_UseDefault,  cw_UseDefault,
                                 cw_UseDefault,  cw_UseDefault,  0,  0,  HInstance,  nil);
     
         if  hWindow  <>  0  then  begin
             ShowWindow(hWindow,  CmdShow);
             UpdateWindow(hWindow);
         end;
     
         Result  :=  hWindow;
     end;
     
     var
         AMessage:  TMsg;
         hWindow:  HWnd;
     begin
         if  not  WinRegister  then  begin
             MessageBox(0,  'Register  failed',  nil,  mb_Ok);
             Exit;
         end;
         hWindow  :=  WinCreate;
         if  hWindow  =  0  then  begin
             MessageBox(0,  'WinCreate  failed',  nil,  mb_Ok);
             Exit;
         end;
         while  GetMessage(AMessage,  0,  0,  0)  do  begin
             TranslateMessage(AMessage);
             DispatchMessage(AMessage);
         end;
         Halt(AMessage.wParam);
     end.

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

     type
         TForm1  =  class(TForm)
             Memo1:  TMemo;
             procedure  FormCreate(Sender:  TObject);
         private
             {  Private  declarations  }
             procedure  WMCopyData(var  msg:  TMessage);  message  WM_COPYDATA;
         public
             {  Public  declarations  }
         end;
     
     var
         Form1:  TForm1;
     
     implementation
     
     {$R  *.DFM}
     
     uses
         checkinst;
     
     procedure  TForm1.FormCreate(Sender:  TObject);
     var
         h  :  HWND;
     begin
         h  :=  SetUniqueUID(Handle,  123456);  //  назначаем  уникальный  идентификатор
         if  h  <>  Handle  then
             begin
                 SendString(h,  GetCommandLineStr,  Handle,  0);
                 ActivatePrevInstance(h);
                 Halt;
             end;
     end;
     
     procedure  TForm1.WMCopyData;
     begin
           Memo1.Lines.CommaText  :=  PChar(PCopyDataStruct(msg.LParam).lpData);
     end;
     
     --------------------------checkinst.pas-------------------------
     unit  checkinst;
     
     interface
     
     uses
         Windows,
         Messages,
         Sysutils;
     
     function  SetUniqueUID(ahwnd:  HWND;  uid:  DWord):  HWND;
     procedure  ActivatePrevInstance(ahwnd:  HWND);
     procedure  SendString(ahwnd:HWND;  const  s:  String;  aWParam:  WParam;
     dwData:DWord);
     function  GetCommandLineStr:  String;
     
     implementation
     
     function  SetUniqueUID(ahwnd:  HWND;  uid:  DWord):  HWND;
     var
         ClassName:  array  [0..255]  of  Char;
     begin
         GetClassName(ahwnd,  ClassName,  SizeOf(classname));
         Result  :=  FindWindowEx(0,  0,  ClassName,  nil);
         while  (Result  <>  0)  do
             if  GetProp(Result,  'UID')  =  uid  then
                 Exit
             else
                 Result  :=  FindWindowEx(0,  Result,  ClassName,  nil);
         SetProp(ahwnd,  'UID',  uid);
         Result  :=  ahwnd;
     end;
     
     procedure  ActivatePrevInstance(ahwnd:  HWND);
     var
         h  :  HWND;
     begin
         h  :=  GetWindowLong(ahwnd,  GWL_HWNDPARENT);
         if  IsIconic(h)  then
               ShowWindow(h,  SW_RESTORE);
         SetForegroundWindow(h);
     end;
     
     procedure  SendString(ahwnd:HWND;  const  s:  String;  aWParam:  WParam;
     dwData:DWord);
     var
         cds:  TCopyDataStruct;
     begin
         cds.cbData  :=  Length(s)+1;
         cds.lpData  :=  Pointer(s);
         cds.dwData  :=  dwData;
         SendMessage(ahwnd,  WM_COPYDATA,  aWParam,  LParam(@cds));
     end;
     
     {
     function  GetCommandLineStr:  String;  //LT
     var
         i  :  Integer;
     begin
         for  i  :=  0  to  ParamCount  do
             Result  :=  Result  +  '  '  +  AnsiQuotedStr(ParamStr(i),  '"');
     end;
     }
     
     function  GetCommandLineStr:  String;  //AOS
     begin
         Result:=CmdLine;  //Этот  вариант  предпочтительнее,  т.к.  через  ParamStr  не
                                           //удастся  получить  строку  в  неизменном  виде
     end;
     
     -------------------------EOF  checkinst.pas---------------------
     
     Leonid  Troyanovsky  
     Скорректировано  Andrew  O.  Shadoura,  2:4500/1.25
     ++++++++++++++++++++++++++++++++++++
     
     ===  Вариант  с  Мьютексом  ===
     В  файле  проекта  (.dpr)  прямо  можешь  написать  нечто  вроде:
     uses  windows,...
     var
         H:  THandle;
     begin
         H  :=  CreateMutex(nil,  True,  'уникальное_имя_для_твоей_проги');
         if  GetLastError  =  ERROR_ALREADY_EXISTS  then
         begin
             H  :=  FindWindow(nil,  'название  заголовка  окна  программы');
             SetForegroundWindow(H);
             Exit;
         end;
         Application.Initialize;
         Application.Title  :=  'название  заголовка  окна  программы';
         Application.CreateForm(TAppData,  AppData);
         Application.CreateForm(TMain,  Main);
         Application.Run;
         CloseHandle(H);
     end;
     
     Прочко  Денис  Владимирович.
     sysadmin@)farmeko.khv.ru
     ++++++++++++++++++++++++++++++++++++
     
     Если  быстро  запустить  дважды  приложение,  то  вариант  с  поиском  по  классу  окна  может  не  сработать,  так  как  окно  еще  не  успеет  создаться
     
     Анатолий  Подгорецкий

    Q-143: Как записать массив в файл?

     with  TFileStream.Create('array.dat',  fmCreate  or  fmOpenWrite)  do  begin
         WriteBuffer(a,  SizeOf(a));
         Free;
     end;

    Q-144: Delphi 6 требует Proxies.pas

     {$ifdef  D_6_UP}  //  Это  моя  константа
         DesignIntf,  DesignEditors,  DesignWindows,  DsnConst,
     {$else}
         DsgnIntf,
     {$endif}
     
     Eugene  Mayevski  
     ------------------------------------
     
     Вопрос:  Файл  designeditors.pas  использует  'proxies'  в  uses.
     Исходный  текст  (proxies.pas)  или  откомпилированный  модуль  (proxies.dcu)  нигде  не  находится  ни  на  моем  жеском  диске  ни  на  D6  Pro  CD..
     
     Просто  реорганизуйте  ваш  проект  на  использование  runtime  пакетов  и  добавьте  "DesignIDE"  к  вашемк  списку  runtime  пакетов.  Proxies  находится  здесь,  и  вам  не  нужен  исходный  текст  вообще.  
     
     Почему  это  сделано?  Просто  доя  уверенности,  что  вы  не  сможете  распространять  design  time  части  (property  editors,  component  editors),  это  запрещено  по  личензии.  DesignIDE.bpl  не  является  свободно  распространяемым,  вы  имеете  право  использовать  его  только  на  машине  на  которой  установлена  Delphi,  подобно  Component  libraries.
     
     forums.borland.com

    Q-145: О библиотеке RxLib

     На  сайте  delphiplus.org  в  разделе  Бесплатно|RXLibrary  (http://delphiplus.spils.lv/RXLibrary.html)  лежит  RX  Library  2.75  с  help'ами  и  четырьмя  неофициальными  портами  RX  Library  2.75  под  Delphi  6:
     
             1.  Версия  1.1  (1.18M)  от  Oxygen  Software
             2.  Версия  1  (1.36M)  от  Dennis  Ortiz
             3.  Патч  на  RxLib  версия  1.5  (437K)  от  Polaris  Software
             4.  Версия  от  Epsylon  Technologies
     
     Anatoly  Podgoretsky  wrote:
     >
     >  Hi,  Delphi  Plus!
     >  You  wrote  to  Anatoly  Podgoretsky  on  Tue,  20  Nov  2001  16:00:55  +0000  (UTC):
     >
     >  DP>  14.11.2001  в  раздел  "Бесплатно|Компоненты"  выложен  четвертый
     >  DP>  неофициальный  порт  RX  Library  2.75  под  Delphi  6  (от  Epsylon
     >  DP>  Technologies).
     >
     >  DP>  http://www.delphiplus.org  -  ежедневные  новости  информационных
     >  DP>  технологий  http://www.faq.delphiplus.org  -  коллекция  FAQ  по  Delphi
     >
     >  Прекрасно,  этим  я  больше  доверяю,  а  как  вообще  насчет  характеристики  всех
     >  четырех  портов,  а  то  у  людей  глаза  разбегаются  :-)
     
     Epsylon  Technologies
     *************************
     Здравствуйте!
     Мы  были  вынуждены  сделать  свой  вариант  RxLib  потому,  что  остальные  нас  немного  не  устраивали.
     Сразу  скажу,  зачем  нам  вообще  нужна  библиотека  RxLib  -  она  используется  в  нашем  продукте  в  качестве  некоего  примера  всем  известных  компонентов.  Поэтому  к  такой  библиотеке  с  нашей  стороны  предъявлялось  требование  максимальной  стандартности,  если  можно  применить  такой  термин.  Кроме  того,  наш  продукт  поддерживает  несколько  версий  Delphi  и  C++Builder,  поэтому  от  такой  библиотеки  требуется  одновременная  поддержка  всех  нужных  нам  версий  компиляторов.
     
     Естественно,  мы  рассматривали  варианты  использования  уже  готовой  работы  по  адаптированию  библиотеки  под  Delphi  6.0.
     Однако:
     -  вариант  от  Polaris  заточен  для  использования  пакета  Polaris  Library.
         Туда  что-то  добавлено,  что-то  починено,  что-то  переделано.  Иначе
         говоря,  этот  вариант  не  может  быть  стандартным;
     -  вариант  от  Oxygen  является  версией  ТОЛЬКО  под  Delphi  6.0,  содержит  ряд
         мелких  неточностей  при  переводе  design-time  кода.  Также  там  что-то
         изменено  по  сравнению  с  2.75.  Кроме  того,  не  переименован  модуль
         AppUtils.pas;
     -  вариант  от  Dennis  Ortiz  также  является  версией  только  под  Delphi  6.0.
         Ничего  не  могу  сказать  про  нее  -  мы  туда  глубоко  не  заглядывали.
     
     Не  совсем  понятно,  зачем  выкидывать  из  библиотеки  возможность  поддержки  предыдущих  версий  Delphi,  когда  добавить  вариант  кода  для  Delphi  6.0  ничуть  не  сложнее.  Никто  также  не  против  исправления  каких-либо  ошибок  в  библиотеке,  но  давайте  делать  это  централизованно,  если  уж  авторы  забили  на  свое  детище.  Например,  через  тот  же  Source  Forge.
     
     Наш  вариант  основан  на  общедоступном  коде,  и  содержит  модули  из  2.75,  включая  update  от  16.12.1999  и  патч  для  C+Builder  5.0  от  30.05.2000.  В  эти  модули  добавлена  возможность  работы  под  Delphi  6.0,  в  том  числе  добавлен  макрос  RX_D6  и  переименованы  модули  AppUtils  и  StrUtils.  Все.  Ничего  больше.  Никакая  старая  функциональность  не  удалена,  никакие  баги  не  чинились.  Полдня  работы.
     
     ==
     Andrey  Dementyev,  Epsylon  Technologies,  http://www.epsylontech.com
     Chief  Software  Architect
     
     Информация  от  delphiplus
     ********************************
     1.  C  19-ого  декабря  компания  SGB  Software  совместно  с  Ником  Ходж  (Nick  Hodges)  из  Borland  support  team  займется  дальнейшим  развитием  RxLib.  Надеются  выпустить  3-ю  версию  к  середине  марта  2002  года.  Все  желающие  могут  принять  участие  в  этой  работе,  для  этого  достаточно  написать  на  RxLIb@SGBSoftware.com.
     
     2.  На  DelphiPlus  выложен  материал  "A  где  сейчас  RXLib?"  -  заметка  написанная  по  материалам  переписки  в  эхе  fido7.ru.delphi.  Наконец  эта  история  получила  завершение,  афера  SGB  Software  лопнула,  но  RXLib    не  погибла,  а  вошла  в  состав  более  крупного  проекта  Jedi  Code  Library,  за  эти  руки  нет  опасения,  все  подробности  на  сайте  delphiplus.org,  благодаря  которому  мы  были  постянно  в  курсе  событий  всех  приключений  с  RXLib,  спасибо.
     

    Q-146: Как хранить настройки программ.

     Нижеприведенный  текст  являет  собой  вольное  изложение  отдельных  статей  февральского  выпуска  Microsoft  Platform  SDK.  Год  2001  от  рождества  Христова.  При  проектировании  способов  хранения  настроек  своей  программы  следует  задаться  тремя  вопросами:  
     
         Что  хранить.  
         Где  хранить.  
         Как  хранить.  
     
     Что  хранить
     
     Поскольку  первая  часть  вопроса  нам  известна  по  определению,  т.е.  хранить  мы  будем  настройки  программы,  то  перейдем  ко  второй  части  вопроса.  Ваша  программа  устанавливается  на  КОМПЬЮТЕР  а  пользуются  ей  ПОЛЬЗОВАТЕЛИ.  Соответственно  все  настройки  разделяются  на  две  части  а  то  и  на  все  три  -  настройки  которые  относятся  к  компьютеру  в  целом,  настройки  которые  относятся  ко  всем  локальным  пользователям,  настройки  которые  относятся  к  конкретному  пользовател.  В  зависимости  от  специфики  программы  первая  и  вторая  часть  могут  быть  совмещены  или  разделены.
     Поэтому  важно  сделать  логическое  разделение  -  какие  настройки  вашей  программы  действительно  специфичны  для  самого  ПК,  какие  настройки  должны  прилагаться  ко  всем  пользователям,  какие  должны  прилагаться  к  конкретному  пользователю.  Кроме  того  Микрософт  рекомендует  чтобы  настройки  учитывали  возможную  мобильность  пользователя,  т.е.  для  пользователя  находящегося  в  разных  местах,  возможно  потребуется  иметь  разные  наборы  настроек.
     
     Где  хранить
     
     Вообще  в  голову  приходят  три  вещи.  
         Хранить  настройки  в  системном  реестре.  
         Хранить  настройки  в  каталоге  куда  установлена  программа.  
         Хранить  настройки  в  системном  каталоге  Windows.  
         Хранить  настройка  в  домашнем  каталоге  пользователя.
       
     В  Windows  имеется  три  места  предназначенных  для  хранения  настроек  которыми  и  следует  пользоваться.
     
         Системный  реестр  
         Домашний  каталог  пользователя  (точнее  один  из  его  подкаталогов)  
         Общий  каталог  для  пользователей  
     
     Прочие  мысли  о  местах  хранения  настроек  должны  быть  выброшены  из  голов  как  вредные  и  противоестественные,  Microsoft  уже  за  вас  все  придумала  и  нефиг  извращаться.  Для  тех  кто  не  понимает  почему,  объясняю.  На  нормальной  ОС  (W'NT,  W'2K)  программа  обычно  запускается  от  имени  и  с  правами  конкретного  пользователя.  Обычно,  если  этот  пользователь  не  является  администратором,  он  имеет  право  изменять  содержимое  следующих  ресурсов:
     
         часть  реестра  HKEY_CURRENT_USER\*  
         содержимое  своего  домашнего  каталога  
         содержимое  временного  каталога  (который  как  правило  находится  внутри  домашнего)  
         содержимое  некого  каталога  или  каталогов  специально  выделенного  для  этого  администратором  
     
     При  нормальном  (читайте  параноидальном)  администрировании  системы  прочие  места  либо  доступны  только  в  режиме  чтения,  либо  вообще  недоступны.  В  том  числе  и  папки  \Program  Files  и  Windows.  Посему  любая  попытка  программы  изменять  любые  файловые  ресурсы  окромя  вышеуказанных  черевата  тем  что  ее  (программу)  и  его  (пользователя)  пошлют  подальше.  Причем  далеко  не  в  самой  вежливой  форме.
     
     Пример
     Adobe  Photoshop  и  его  разработчики  наивно  полагают  что  им  должны  быть  выданы  эксклюзивные  права  мусорить  своими  scratch-файлами  в  корневых  каталогах  дисков,  кроме  того  они  полагают  что  им  должна  быть  выдана  в  пользование  в  режиме  полный  доступ  часть  системного  реестра..  Временных  каталогов,  специально  выделенных  для  подобоного  рода  занятий,  их  не  устраивает.  Как  результат  -  Photoshop  имеет  серьезные  проблемы  с  работой  под  Windows  NT/2000.
     
     Системный  реестр
     
     С  точки  зрения  хранения  настроек  программы  системный  реестр  разделен  на  две  части.  Это  ветви  HKEY_CURRENT_USER  для  хранения  настроек  специфичных  для  пользователя,  и  HKEY_LOCAL_MACHINE  для  хранения  настроек  специфичных  для  всего  ПК  и  соответственно  всех  пользователей,  работающих  с  этим  ПК.  Рекомендуемая  структура  ветвей  для  хранения  настроек  программы  -  HKEY_CURRENT_USER\Software\Company  Name\Application  Name\Version  и  соответственно  HKEY_LOCAL_MACHINE\Software\Company  Name\Application  Name\Version.  Параметры  Company  Name,  Application  Name,  Version  желательно  не  хранить  в  виде  hard-coded  строк  в  коде  программы  а  устанавливать  в  опциях  проекта  (Project\Options\Version  Info)  и  доставать  впоследствии  из  ресурса  с  помощью  той  же  библиотеки  RxLib.  Альтернативный  путь  выбирать  данные  о  версии  программы  из  ресурсов  -  использование  Windows  API  (GetFileVersionInfo,  GetFileVersionInfoSize,  VerQueryValue).
     Программе  следует  расчитывать  на  то  что  доступ  к  подключам  HKEY_LOCAL_MACHINE  разрешен  в  режиме  только  для  чтения,  а  доступ  к  подключам  HKEY_CURRENT_USER  допускает  чтение,  изменение  и  создание  новых  подключей  и  значений.
     Программе  следует  расчитывать  на  то  что  нужных  ей  ключей  может  не  оказаться  в  реестре  или  значения  лежащие  в  реестре  имеют  неверный  формат  или  недопустимые  значения.  В  таком  случае,  вместо  несуществующих  или  неверных  значений  настройки,  программа  должна  использовать  значения  по  умолчанию  которые  разработчик  может  "железно  забить  в  код"  или  получить  с  помощью  различных  системных  функций.
     Не  следует  использовать  системный  реестр  для  хранения  больших  кусков  данных.  Вместо  этого  лучше  хранить  объемные  данные  в  отдельном  файле,  а  в  реестре  запомнить  имя  этого  файла.
     
     Домашний  каталог  пользователя
     
     Для  хранения  настроек  слишком  больших  для  того  чтобы  их  размещать  в  реестре  существуют  специально  выделенные  каталоги  внутри  домашнего  каталога  пользователя.  Эти  каталоги  обычно  называются  "специальными  каталогами"  и  имеют  имена  Application  Data  и  Local  Settings.  Полный  путь  к  ним  можно  получить  с  помошью  функций  SHGetSpecialFolderPath  или  SHGetFolderPath.
     
     Общий  каталог  пользователей
     
     Обычно  это  каталог  "Documents  and  Settings\All  users".  Внутри  него  имеются  такие-же  подкаталоги  для  хранения  настроек  и  данных  программ  но  относящихся  ко  всем  пользователям.  Полный  путь  к  ним  можно  также  получить  с  помошью  функций  SHGetSpecialFolderPath  или  SHGetFolderPath.
     
     Как  хранить
     
     Системный  реестр
     Для  работы  с  системным  реестром  можно  использовать  функции  Registry  API  общим  числом  около  40  штук,  а  можно  использовать  классы  из  Registry.pas  -  TRegistry,  TRegistryIniFile,  TRegIniFile.  Особенно  следует  обратить  внимание  на  TRegistryIniFile  который  предоставляет  упрощенную  модель  доступа  к  системному  реестру  очень  схожую  с  моделью  работы  с  INI-файлами.
     
     INI-файлы
     Это  старый  метод  хранения  настроек  программ,  но  все  еще  применяющийся  программистами.  Настройки  хранятся  в  текстовом  файле  в  виде:
     
     [Section1]
     Field1=Value1
     Field2=Value2
     ...
     FieldN=ValueN
     
     [Section2]
     Field1=Value1
     Field2=Value2
     ...
     FieldN=ValueN
     ...
     
     [SectionN]
     Field1=Value1
     Field2=Value2
     ...
     FieldN=ValueN
     
     Для  доступа  к  данным  содержащимся  в  INI-файлах  существуют  классы  из  модуля  IniFiles  -  TIniFile,  TMemIniFile.
     Преимущество  использования  INI-файлов  состоит  в  том  что  их  можно  легко  подредактировать  с  помощью  текстового  редактора.  Они  обычно  легче  воспринимаются  для  прочтения  нежели  дерево  ключей  системного  реестра.
     
     Бинарные  файлы  настроек
     Отдельно  хочется  поговорить  о  использовании  бинарных  файлов  в  качестве  хранилища  для  настроек  программы.  Обычные  мотивы  любителей  использовать  бинарные  файлы:
     
         Экономится  место  
         Настройку  можно  спрятать  от  пользователя  (сделать  нечитабельной)  
     
     Первое  глупо  потому  что  информация  о  настройке  занимает  обычно  немного  места  и  экономия  достигается  мизерная.  Второе  глупо  потому  что  невозможность  просмотра  и  редактирования  настроечных  данных    простыми  средствами  (текстовый  редактор)  или  встроенными  (редактор  реестра)  создает  больше  проблем  как  пользователю  так  разработчику,  нежели  пользы  (причем  весьма  сомнительной)  от  того  что  кто-то  не  сможет  прочитать  что  написано  в  файле.  Кроме  того  использование  бинарного  файла  нельзя  назвать  защитой  от  нежелательного  просмотра,  т.к.  любой  "продвинутый  пользователь"  все  равно  с  помощью  редактора  бинарных  файлов  сможет  просмотреть  и  разобраться  в  содержимом  настройки.
     
     Заключение
     
     Почти  вся  эта  информация  была  вычерпана  из  кладезя  мудрости  под  названием  Platform  SDK  (Software  Development  Kit),  поставляемого  в  составе  сборника  документации  MSDN  (Microsoft  Software  Developer  Network).  Разработчикам  настоятельно  рекомендуется  приобрести  Platform  SDK,  это  снимает  огромную  массу  вопросов  связанную  с  программированием  под  Windows.

    Q-147: Как вывести ProgresBar на StatusBar?

     ---  Андрей  Барташ
     
     Gauge:=TGauge.Create(Form1);
     Gauge.Parent:=  StatusBar1;
     Gauge.Top:=4;
     Gauge.Left  :=  116;
     Gauge.Height  :=  15;
     Gauge.Width  :=  200;
     
     Компонент  TGauge  находится  на  закладке  Samples

    Q-148: Как нажать клавиши в другом приложении?

     "Нажимаем"  клавиши  в  Блокноте  (уже  запущенном):
     
     uses  Sendkey;  {описан  ниже}
     
     procedure  TForm1.Button1Click(Sender:  TObject);
     var
         h:  HWND;
     begin
         h  :=  FindWindow('Notepad',  nil);  //  ищем  окно  Блокнота
         SendMessage(h,  WM_SYSCOMMAND,  SC_HOTKEY,  h);  //  активизируем  его
         PlayKeys(StrToKeys('abcdef'));  //  нажимаем  клавиши
         SendMessage(Handle,  WM_SYSCOMMAND,  SC_HOTKEY,  Handle);  //  возвращаем  фокус
     end;
     
     Коды  vk_  клавиш  можно  найти  в  Win32  Programmer's  Reference  (win32.hlp):      Virtual-Key  Codes.  {В  дельфи  не  описаны  коды  клавиш  ['A'..'Z']  и  ['0'..'9'],  их  получают  с  помощью  Ord,  например,  Ord('A'),  Ord('9')}.
         
     Символы  из  верхнего  ряда  клавиатуры  посылаются  с  нажатым  Shift.  Заметим,  что  символы  в  локальной  кодировке  могут  быть  посланы  после  переключения  кодировки  в  активном  приложении,  например,  если  перключатель  (switch)  Control-Shift,  то  это:
     
         PlayKeys(Chr(vk_control)+#0+Chr(vk_shift)+#0);  {downkey  =  #0};
     
     ---  unit  Sndkey.pas  ---
     
     unit  sndkey;
     
     interface
     
     uses
         Windows,
         Messages;
     
     const
         {VK  constants  missing  from  windows.pas}
         VK_SEMICOLON        =  186;  {;}
         VK_EQUAL                =  187;  {=}
         VK_COMMA                =  188;  {,}
         VK_MINUS                =  189;  {-}
         VK_PERIOD              =  190;  {.}
         VK_SLASH                =  191;  {/}
         VK_BACKQUOTE        =  192;  {`}
         VK_LEFTBRACKET    =  219;  {[}
         VK_BACKSLASH        =  220;  {\}
         VK_RIGHTBRACKET  =  221;  {]}
         VK_QUOTE                =  222;  {'}
     
         downkey  =  #0;
         upkey  =  Chr(KEYEVENTF_KEYUP);  {#2}
     
     procedure  PlayKeys(const  keys:  String);
     function  StrToKeys(const  s:  String):  String;
     
     {Alt-F4:  PlayKeys(Chr(vk_menu)+#0+Chr(vk_f4)+#0+Chr(vk_f4)+#2+Chr(vk_menu)+#2)}
     {"exit":  PlayKeys(StrToKeys('exit'+chr(vk_return)));}
     {"EXIT":  PlayKeys(Chr(vk_shift)+downkey+StrToKeys('exit')+Chr(vk_shift)+upkey));}
     {or  short  form:  PlayKeys(Chr(vk_shift)+#0+StrToKeys('exit'));}
     
     implementation
     
     function  StrToKeys;  {keystroke  for  alone  keys}
     var
         i:  Longint;
         c:  Char;
     begin
         for  i  :=  1  to  Length(s)  do
             begin
                 c  :=  s[i];
                 if  c  in  ['a'..'z']  then  {Upper}
                     c  :=  Chr(Ord(c)  and  not  $20);
                 Result  :=  Result  +  c  +  downkey
                                                   +  c  +  upkey;
             end;
     end;
     
     procedure  PlayKeys;
     const
         ExtendedKeys  :  set  of  byte  =
             [  vk_up,          vk_down,
                 vk_left,      vk_right,
                 vk_home,      vk_end,
                 vk_prior,    vk_next,
                 vk_insert,  vk_delete];
     var
         i,  ips  :  Longint;
         fb,  sb:  Byte;
         keysdown:  String;
     
         procedure  keybd  (vk,  kp  :  Byte);
         begin
             if  vk  in  ExtendedKeys  then
                 kp  :=  kp  +  KEYEVENTF_EXTENDEDKEY;
             keybd_event(vk,  MapVirtualKey(vk,  0),  kp,  0);
         end;
     
     begin
         keysdown  :=  '';
         for  i  :=  1  to  Length(keys)  div  2  do
             begin
                 fb:=  Ord(keys[2*i  -1]);
                 sb:=  Ord(keys[2*i]);
                 if  sb  =  Ord(downkey)  then
                     keysdown  :=  keysdown  +  Chr(fb)
                 else
                     begin
                         ips  :=  pos(Chr(fb),  keysdown);
                         if  ips  >  0  then
                             Delete(keysdown,  ips,  1)
                         else
                             Continue;
                     end;
                 keybd(fb,  sb);
             end;
             {Autocomplete}
             for  i  :=  1  to  Length(keysdown)  do
                 keybd(Ord(keysdown[i]),  Ord(upkey));
     end;
     
     end.
     ---  EOF  unit  Sndkey.pas  ---
     
     Leonid  Troyanovsky  

    Q-149: Как перетащить файлы из проводника в мою программу?

     TMainForm  =  class(TForm)
         ...
     private
         procedure  WMDROPFILES(var  Message:  TWMDROPFILES);  message
     WM_DROPFILES;
         procedure  ProcessFile(Filename:  string);
     end;
     
     procedure  TMainForm.FormCreate(Sender:  TObject);
     begin
         DragAcceptFiles(MainForm.Handle,  TRUE);  //  enable  drag&drop
     end;
     
     procedure  TMainForm.ProcessFile(Filename:  string);
     begin
     //  any  actions
     end;
     
     procedure  TMainForm.WMDROPFILES(var  Message:  TWMDROPFILES);
     var
         Files    :  Longint;
         I            :  Longint;
         Buffer  :  array[0..MAX_PATH]  of  Char;
     begin
         Files  :=  DragQueryFile(Message.Drop,$FFFFFFFF,nil,0);  //  Get  count  of
     files
         for  I  :=  0  to  Files  -  1  do  begin
             DragQueryFile(Message.Drop,I,@Buffer,SizeOf(Buffer));  //  Get  N  file
             ProcessFile(Buffer);  //  do  something  with  the  file
         end;
         DragFinish(Message.Drop);  //  end  drag  loop
     end;
     
     Anatoly  Podgoretsky

    Q-150: Как использовать в Дельфи API фyнкции?

     AA>  как  это  ни  странно,  вызывать  их.  предварительно  заюзав  модуль  windows.
     
     Правильнее  :  вызвать,  предварительно  подключив  модуль,  в  котором  данная  функция  описана  (это  может  быть  windows,  activex,  shellapi  и  т.д.).  
     Найти  модуль  поможет  клавиша  F1  на  имени  функции.
     
     Если  функция  не  нашлась  -  то  попробовать  сделать  поиск  в  папке  с  исходными  текстами  Дельфи.
     
     Если  функция  не  нашлась  -  есть  шанс,  что  в  этой  версии  Дельфи  она  не  описана.  В  этом  случае  надо  поискать  "заголовочный  файл"  (API  header  file)  в  интернете.  Огромная  коллекция  их  находится  на  сайте  www.delphi-jedi.org.
     
     Если  не  помогло  и  это  -  придется  взять  описание  функции  из  документации  производителя  данного  API  (обычно  оно  на  С)  и  самому  сделать  ее  обьявление,  так  же,  как  это  сделано  в  windows.pas,  только  в  своем  юните.
     
     Сергей  Кабиков

    Q-151: Автоматическое определение кодировки текста

     AG>  Существуют  ли  в  сободном  для  изучения  доступе  алгоритмы  автоматического
     AG>  определения  кодировки  текста?
     О,  еще  сколько.  Методом  таблицы  модельных  распределений:
     
     type
         TCodePage  =  (cpWin1251,  cp866,  cpKOI8R);
         PMap  =  ^TMap;
         TMap  =  array  [#$80..#$FF]  of  Char;
     
     function  GetMap(CP:  TCodePage):  PMap;
     {  должна  возвращать  указатель  на  таблицу  перекодировки  из  CP  в  Windows1251
         (nil  для  CP  =  cpWin1251)  }
     begin
         GetMap:=nil;
     end;
     
     function  DetermineRussian(Buf:  PChar;  Count:  Integer):  TCodePage;
     const
         ModelBigrams:  array  [0..33,  0..33]  of  Byte  =  (
           {АБВГДЕЖЗИЙКЛМHОПРСТУФХЦЧШЩЪЫЬЭЮЯ_Ё}
     {А}(0,20,44,12,22,23,16,60,4,9,63,93,47,110,0,16,35,61,81,1,5,13,24,17,12,4,0,0,0,0,14,31,205,1),
     {Б}(19,0,0,0,4,19,0,0,8,0,2,15,1,4,41,0,15,5,0,15,0,2,1,0,0,6,16,37,0,0,0,4,3,0),
     {В}(97,0,1,0,2,57,0,5,40,0,4,25,2,23,78,2,8,28,4,12,0,1,0,0,8,1,0,40,1,0,0,5,106,3),
     {Г}(13,0,0,0,9,5,0,0,15,0,1,17,1,2,96,0,24,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0),
     {Д}(63,0,9,1,2,71,1,0,35,0,3,16,2,22,50,2,19,9,2,25,0,2,1,0,1,0,1,9,4,0,1,5,17,4),
     {Е}(4,14,15,34,56,22,13,14,2,34,39,77,73,150,6,9,101,64,81,1,0,15,5,12,10,6,0,0,0,0,3,4,235,1),
     {Ж}(13,0,0,0,12,47,0,0,16,0,1,0,0,23,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,2,2),
     {З}(76,2,11,3,11,4,1,0,7,0,2,4,11,24,17,0,6,1,0,8,0,0,0,0,0,0,0,16,6,0,1,4,17,0),
     {И}(7,9,32,5,18,60,4,42,31,27,28,46,55,49,12,7,26,60,53,0,5,25,14,28,4,1,0,0,0,0,9,56,255,0),
     {Й}(0,0,0,0,2,0,0,0,0,0,1,3,0,3,0,0,0,10,3,0,0,0,0,1,1,0,0,0,0,0,0,0,122,0),
     {К}(92,0,3,0,0,7,2,1,39,0,0,27,0,14,110,0,18,5,35,18,0,0,11,0,0,0,0,0,0,0,0,0,5,5,0),
     {Л}(85,1,0,2,1,70,6,0,85,0,5,3,0,9,67,1,0,9,0,15,0,0,0,2,0,0,0,9,66,0,15,43,57,4),
     {М}(44,0,0,0,0,65,0,0,47,0,1,1,10,15,57,7,0,2,0,24,0,0,0,0,0,0,0,28,0,0,0,8,109,3),
     {}(139,0,0,1,11,108,0,4,152,0,7,0,1,69,161,0,0,8,25,24,5,1,5,2,0,1,0,83,10,0,1,29,38,5),
     {О}(0,72,139,76,74,32,32,19,12,52,21,93,68,72,7,34,93,102,98,1,2,6,6,19,15,2,0,0,0,1,4,9,252,2),
     {П}(17,0,0,0,0,43,0,0,14,0,1,9,0,1,125,3,120,1,2,8,0,0,0,0,0,0,0,3,6,0,0,3,2,2),
     {Р}(151,1,6,4,3,103,7,0,76,0,4,0,11,10,117,1,0,5,9,39,2,5,0,1,3,0,0,24,7,0,1,10,22,5),
     {С}(24,1,21,0,3,39,0,0,33,0,56,41,11,15,58,30,5,30,183,16,0,4,1,4,1,0,0,8,25,0,1,50,41,2),
     {Т}(83,0,43,0,3,87,0,0,71,0,9,3,2,26,180,0,55,33,1,23,1,0,1,4,0,0,0,20,78,0,0,5,82,4),
     {У}(3,6,7,14,19,8,13,6,0,1,13,15,10,7,0,12,17,16,19,0,1,3,0,12,5,8,0,0,0,0,22,1,65,0),
     {Ф}(4,0,0,0,0,4,0,0,11,0,0,1,0,0,9,0,3,0,0,4,1,0,0,0,0,0,0,0,0,0,0,0,2,0),
     {Х}(9,0,2,0,0,2,0,0,5,0,0,1,0,5,26,0,4,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,76,0),
     {Ц}(5,0,0,0,0,16,0,0,48,0,1,0,0,0,4,0,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,3,0),
     {Ч}(30,0,0,0,0,52,0,0,23,0,3,1,0,14,1,0,0,0,36,5,0,0,0,0,1,0,0,0,1,0,0,0,2,2),
     {Ш}(13,0,0,0,0,28,0,0,17,0,4,4,0,4,3,0,0,0,1,3,0,0,0,0,0,0,0,0,3,0,0,0,1,1),
     {Щ}(6,0,0,0,0,23,0,0,16,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1),
     {Ъ}(0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0),
     {Ы}(0,5,14,1,3,28,0,2,0,22,6,19,21,2,0,5,4,7,10,0,0,37,0,3,4,0,0,0,0,0,0,1,84,0),
     {Ь}(0,1,0,0,0,9,0,10,1,0,13,0,2,26,0,0,0,10,3,0,0,0,1,0,6,0,0,0,0,0,6,4,117,0),
     {Э}(0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,31,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0),
     {Ю}(0,5,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,1,15,0,0,0,1,4,1,15,0,0,0,0,0,0,38,0),
     {Я}(0,0,9,2,7,10,3,19,0,0,1,6,7,8,0,0,2,6,19,0,0,3,5,1,0,3,0,0,0,0,5,2,177,0),
     {_}(42,80,193,43,109,41,18,53,159,0,144,27,83,176,187,229,70,231,99,47,15,13,6,58,7,0,0,0,0,38,0,22,0,2),
     {Ё}(0,0,0,0,3,0,0,0,0,0,2,4,4,8,0,0,5,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
     {  "рейтинг"  буквы  Ё  условно  принимается  равным  1/20  от  "рейтинга"  буквы  E,
         если  сочетание  с  участием  Ё  корректно,  иначе  -  0  }
     type
         TVariation  =  array  [0..33,  0..33]  of  Integer;
     var
         I,  J,  iC,  iPredC,  Max:  Integer;
         C:  Char;
         CP:  TCodePage;
         D,  MinD,  Factor:  Double;
         AMap:  PMap;
         PV:  ^TVariation;
         Vars:  array  [TCodePage]  of  TVariation;
     begin
         DetermineRussian:=cpWin1251;  {  по  yмолчанию  }
         {  вычисление  распределений  биграмм  }
         FillChar(Vars,  SizeOf(Vars),  0);
         for  CP:=Low(Vars)  to  High(Vars)  do  begin
             AMap:=GetMap(CP);
             PV:=@Vars[CP];
             iPredC:=32;
             for  I:=0  to  Count  -  1  do  begin
                 C:=Buf[I];
                 iC:=32;
                 if  C  >=  #128  then  begin
                     if  AMap  <>  nil  then  C:=AMap^[C];
                     if  not  (C  in  ['Ё',  'ё'])  then  begin
                         C:=Chr(Ord(C)  and  not  32);  {  'a'..'я'  ->  'А'..'Я'  }
                         if  C  in  ['А'..'Я']  then  iC:=Ord(C)  -  Ord('А');
                     end
                     else
                         iC:=33;
                 end;
                 Inc(PV^[iPredC,  iC]);
                 iPredC:=iC;
             end;
         end;
         {  вычисление  метрики  и  определение  наиболее  правдоподобной  кодировки  }
         MinD:=0;
         for  CP:=Low(Vars)  to  High(Vars)  do  begin
             PV:=@Vars[CP];
             PV^[32,  32]:=0;
             Max:=1;
             for  I:=0  to  33  do
                 for  J:=0  to  33  do
                     if  PV^[I,  J]  >  Max  then  Max:=PV^[I,  J];
             Factor:=255  /  Max;  {  ноpмализация  }
             D:=0;
             for  I:=0  to  33  do
                 for  J:=0  to  33  do
                     D:=D  +  Abs(PV^[I,  J]  *  Factor  -  ModelBigrams[I,  J]);
             if  (MinD  =  0)  or  (D  <  MinD)  then  begin
                 MinD:=D;
                 DetermineRussian:=CP;
             end;
         end;
     end;
     
     begin
         {  тест:  слово  'Пример'  в  разных  кодировках  (веpоятность  ошибок  на  таких
             коpотких  текстах  высока  -  в  данном  слyчае  пpосто  повезло!)  }
         writeln(DetermineRussian(#$CF#$F0#$E8#$EC#$E5#$F0,  6)  =  cpWin1251);
         writeln(DetermineRussian(#$8F#$E0#$A8#$AC#$A5#$E0,  6)  =  cp866);
         writeln(DetermineRussian(#$F0#$D2#$C9#$CD#$C5#$D2,  6)  =  cpKOI8R);
         readln;
     end.
     
     
     
     
     
     --  
     Best  regards,
       Stas  Malinovski.  stasm#tsl.ru

    Q-152: Как помигать лампочками на клавиатуре?

     var
         KeyState  :  TKeyboardState;
     begin
         GetKeyboardState(KeyState);
         KeyState[VK_NUMLOCK]  :=  KeyState[VK_NUMLOCK]  xor  1;
         SetKeyboardState(KeyState);
     end;
     
     Изменяет  состояние  индикаторов  на  обратное...
     См.  также  VK_NUMLOCK,  VK_CAPITAL
     
     WinNT:
             {
             keybd_event(  VK_SCROLL,  0x46,  KEYEVENTF_EXTENDEDKEY  |  0,  0  );
             keybd_event(  VK_SCROLL,  0x46,  KEYEVENTF_EXTENDEDKEY  |  KEYEVENTF_KEYUP,  0);
             }
     
     Stas  Malinovski.    stasm#tsl.ru
     ==
     
     procedure  TForm1.Timer1Timer(Sender:  TObject);
     begin
         keybd_event(VK_SCROLL,  0,  0,  0);
         keybd_event(VK_SCROLL,  0,  vk_up,  0);
     end;
     ++++++++++++++++++++++++++++
     
     procedure  TForm1.Timer1Timer(Sender:  TObject);
     begin
         keybd_event(VK_SCROLL,  MapVirtualKey(VK_SCROLL,  0)  ,  0,  0);
         keybd_event(VK_SCROLL,  MapVirtualKey(VK_SCROLL,  0),  vk_up,  0);
     end;
     
     Leonid  Troyanovsky  

    Q-153: Как создать в runtime форму?

     with  TxxForm.Create(Self)  do  Show;
     
     with  TxxForm.Create(Self)  do
     try
         ShowModal;
     finally
         Free;
     end;
     

    Q-154: Как прочитать порт или записать в него?

     В  мультизадачных  ОС  как  правило  доступ  к  портам  запрещен  идеологией  системы.  И  это  неспроста  -  подумайте,  что  будет,  если  одновременно  с  вашей  программой  этот  же  порт  попробует  использовать  другая  программа.
     
     Но  в  Win9x  существует  частичная  возможность  обратиться  напрямую  с  помощью  ассемблерных  команд.  Делать  это  надо  с  определенной  осторожность.  Даже  если  вы  получите  доступ  до  порта  на  своей  машине,  то  это  не  означает,  что  это  будет  и  на  другой  машине,  например  доступ  до  LPT  порта  может  быть  закрыт  драйвером  принтера,  такое  редко  но  встречается.  Доступ  к  наиболее  важным  портам  прикрыты  запрещен  полностью  соответствующими  системными  драйверами.
     
     В  Win  NT  доступ  к  оборудованию  со  стороны  пользовательской  программы  запрещен  полностью.  Для  доступа  на  этих  ОС  требуется  использовать  kernel  mode  драйвера,  тоже  самое  рекомендуется  и  для  Win9x.
     Вот  несколько  полезных  ссылок:
     
         TVicHW32            http://www.entechtaiwan.com/tools.htm  
         Tinyport  (NT)  http://www.winsite.com/info/pc/winnt/programr/tinypo21.zip.drag
         DriverX              http://www.tetradyne.com
         giveio  (NT)                    
     http://www.wideman-one.com/gw/tech/Delphi/iopm/index.htm
         Ports,  by  Harold  Howe,  http://www.bcbdev.com/components.htm
     
     Код  доступа  к  портам  с  помощью  ассемблера.
     
     procedure  WritePortByte(Port:Word;  Value:Byte);
     asm
         XCHG    EDX,EAX
         OUT      DX,AL
     end;
     
     procedure  WritePortWord(Port:Word;  Value:Word);
     asm
         XCHG    EDX,EAX
         OUT      DX,AX
     end;
     
     function  ReadPortByte(Port:Word)  :  Byte;
     asm
         MOV      EDX,EAX
         IN        AL,DX
     end;
     
     function  ReadPortWord(Port:Word)  :  Word;
     asm
         MOV      EDX,EAX
         IN        AX,DX
     end;
     
     Примечание:  
     
     Существуют  устройства  с  подряд  идущими  (по  адресам)  _байтовыми_  портами,  к  которым  нельзя  обращаться  со  словными  командами  I/O.  На  сегодня  они  почти  вымерли,  но  :
     
     При  выборе  типа  процедуры  (BYTE  или  WORD)  следует  ориентироваться  на  спецификацию  устройства  ввода-вывода,  к  которому  идет
     обращение.  Не  следует  обращаться  к  байтовому  устройству  с  WORD-ориентированными  процедурами  -  экономия  времени  мизерная,  а  побочные
     эффекты  могут  быть  катастрофическими."
     Например,  некоторые  адаптеры  сбрасывают  биты  ошибок  после  чтения  статус-регистра.  Другие  отображают  несколько  внутренних  регистров  на  один  адрес  I/O,  и  т.п.
     
     На  некоторых  старых  компьютерах  Word    процедуры  могут  не  работать  из  за  специфических  особенностей  интерфейса,  правда  такие  компьютера  практически  уже  не  встречаются.  Есть  ISA  Bus  Specification,  где  эти  вопросы  четко  формализованы.  Выборка  словного  порта  может  быть  разбита  на  два  раза,  даже  если  адрес  четный,  в  зависимости  от  пожеланий  устройства  I/O.  
     

    Q-155: Как работать с битами?

     Есть  два  способа.
     Низкоуровневый  подход  обеспечивается  логическими  операциями  :
     
     var  
         I  :  integer;
         N  :  integer;                                              //  Номер  бита  в  диапазоне  от  0..SizeOf(TYPE)*8  -  1
     
         I  :=  I  or  (1  shl  N);                              //  установка  бита
         I  :=  I  and  not  (1  shl  N);                    //  сброс  бита
         I  :=  I  xor  (1  shl  N);                            //  инверсия  бита
         if  (i  and  (1  shl  N))  <>  0  then...    //  проверка  установленного  бита
     
     Высокоуровневый  подход  опирается  на  представление  числа  в  виде  множества:
     
     type  
         TIntegerSet  =  set  of  0..SizeOf(Integer)*8  -  1;
     var  
         I  :  Integer;
         N  :  Integer;
     
         Include(TIntegerSet(I),  N);          //  установили  N-ный  бит  в  1
         Exclude(TIntegerSet(I),  N);          //  сбросили  N-ный  бит  в  0
         if  N  in  TIntegerSet(I)  then...    //  проверили  N-ный  бит

    Q-156: Как удалить непустой каталог?

     procedure  TForm1.Button1Click(Sender:  TObject);
     var  
         lpFileOp:  TSHFileOpStruct;
     begin
           FillChar(lpFileOp,SizeOf(lpFileOp),0);
           lpFileOp.Wnd  :=  Handle;
           lpFileOp.wFunc  :=  FO_DELETE;
           lpFileOp.pFrom  :=  PChar(Edit1.Text);
           lpFileOp.fFlags  :=  FOF_NOCONFIRMATION;
           SHFileOperation(lpFileOp);
     end;
     
     Ivan  Daniloff  

    Q-157: Как получить список файлов со всеми подкаталогами?

     procedure  ScanDir(StartDir:  string;  Mask:string;  List:TStrings);
     var
         SearchRec  :  TSearchRec;
     begin
         if  Mask  =  ''  then  Mask  :=  '*.*';
         if  StartDir[Length(StartDir)]  <>  '\'  then  StartDir  :=  StartDir  +  '\';
         if  FindFirst(StartDir+Mask,  faAnyFile,  SearchRec)  =  0  then
         begin
             repeat
                 Application.ProcessMessages;        
                 if  (SearchRec.Attr  and  faDirectory)  <>  faDirectory  then
                     List.Add(StartDir  +  SearchRec.Name)
                 else  if  (SearchRec.Name  <>  '..')  and  (SearchRec.Name  <>  '.')  then  begin
                     List.Add(StartDir  +  SearchRec.Name  +  '\');
                     ScanDir(StartDir  +  SearchRec.Name  +  '\',Mask,List);
                 end;
             until  FindNext(SearchRec)  <>  0;
             FindClose(SearchRec);
         end;
     end;
     
     Пример  вызова.  параметры
     1.  имя  папки
     2.  маска,  по  умолчанию  *.*
     3.  хранилище  для  резульатат,  любой  наследник  от  TString,  например  TStringList
     
     procedure  TForm1.Button1Click(Sender:  TObject);
     begin
         ListBox1.Items.Clear;
         ScanDir('c:','',ListBox1.Items);
         Label1.Caption  :=  IntToStr(ListBox1.Items.Count);
     end;
     
     Анатолий  Подгорецкий
     anatoly#podgoretsky.com
     -------------------------------------------------------------
     
     В  связи  с  тем,  что  многие  не  понимают  работу  с  масками,  например  пытаются  искать  файлы  *.txt  во  всех  подкаталогах,  вот  модифицированная  версия  для  поиска  файлов,  которая  для  поиска  подкаталогов  использует  мвску  *.*,  а  для  файлов  указанную  маску.
     Процедура  представлена  Юрием  Зотовым.
     
     procedure  FindAllFiles(List:  TStrings;  Dir,  Mask:  string);
     
         procedure  ScanDir(Dir:  string);
         var
             SR:  TSearchRec;
         begin
             Dir  :=  IncludeTrailingBackSlash(Dir);
             if  FindFirst(Dir  +  '*.*',  faAnyFile  -  faVolumeID,  SR)  =  0  then
             try
                 repeat
                     if  (SR.Name  <>  '.')  and  (SR.Name  <>  '..')  then
                         if  SR.Attr  and  faDirectory  <>  0  then
                             ScanDir(Dir  +  SR.Name)
                         else  
                             if  MatchesMask(SR.Name,  Mask)  then
                                 List.Add(Dir  +  SR.Name)
                 until  FindNext(SR)  <>  0
             finally
                 FindClose(SR)
             end
       end;
     
     begin
         if  (List  =  nil)  or  not  DirectoryExists(Dir)  or  (Mask  =  '')  then
             raise  Exception.Create('Invalid  parameter');  
         List.Clear;
         ScanDir(Dir)
     end;
     
     Примечания:  функция  MatchesMask  существует  только  с  определенных  версий  Дельфи,  как  минимум  в  5  есть.

    Q-158: Как преобразовать unix time в TDateTime?

     unix  timestamp  представляет  собой  число  секунд  начиная  с  1.01.1970  
     
     const
         SecPerDay    =  86400;
         Offset1970  =  25569;
     
     function  UnixTimeToDateTime(UnixTime  :  LongInt):  TDate;
     begin
         Result  :=  UnixTime  /  SecPerDay  +  Offset1970;
     end;
     
     function  DateTimeToUnixTime(DelphiDate  :  TDate)  :  LongInt;
     begin
         Result  :=  Trunc((DelphiDate  -  Offset1970)  *  SecPerDay);
     end;
     
     Если  необходима  корректировка  зимнего/летнего  времени,  то  ее  следует  сделать  самостоятельно.

    Q-159: Как сделать .manifest для Windows XP?

     Для  того,  чтобы  программы  запускаемые  под  Windows  XP,  имели  новый  вид,  необходимо  вместе  с  программой  поставить  файл  *.manifest  или  включить  его  в  ресурс.
     Для  это  изготовить  файл,  по  ниже  приведенной  инструкции,  назвать  его  Project1.exe.manifest,  по  положить  рядышком  с  Project1.exe,  после  это  запускаешь  под  XP  и  радуешься  :-)
     
     
     
             version="1.0.0.0"
           processorArchitecture="*"
           name="Igor.Schevchenko.XPUtilsTest"
           type="win32"
     />
     XP  User  utils  test
     
           
                               type="win32"
                   name="Microsoft.Windows.Common-Controls"
                   version="6.0.0.0"
                   processorArchitecture="X86"
                   publicKeyToken="6595b64144ccf1df"
                   language="*"
               />
           

     

     

     
     Строчку  name="Igor.Schevchenko.XPUtilsTest"  меняешь  на  name="Kostya.Ergin.Project1"
     
     С  уважением,
     Игорь  Шевченко
     ++++++++++++++++++++++++++++++
     
     В  Delphi  Studio  7  Enterprise  и  Professional,  приложения  Borland  VCL  теперь  включают  компоненты,  которые  разрешают  поддержку  Windows®  общих  контролов  версии  6.  Ваше  приложение  автоматически  использует  новые  контролы  Windows  на  системе  Windows  XP,  если  найдет  подходящий  манифест  файл.  Более  подробно  об  этом  в  руководстве  Developer's  Guide  тема  "Common  controls  and  XP  themes"  или  в  справочной  системе.
     
     Анатолий  Подгорецкий
     

    Q-160: Как узнать версию программы?

     function  GetFileVersion(const  FileName:  TFileName;  var  Major,  Minor,  Release,  Build:  Integer):  Boolean;
     var  
         InfoSize,  Wnd:  DWORD;
         VerBuf:  Pointer;
         FI:  PVSFixedFileInfo;
       VerSize:  DWORD;
     begin
         Result:=  False;
         InfoSize:=  GetFileVersionInfoSize(PChar(FileName),  Wnd);
         if  InfoSize  <>  0  then  begin
             GetMem(VerBuf,  InfoSize);
             try
                 if  GetFileVersionInfo(PChar(FileName),  Wnd,  InfoSize,  VerBuf)  then
                     if  VerQueryValue(VerBuf,  '\',  Pointer(FI),  VerSize)  then  begin
                         Major:=  FI.dwFileVersionMS  shr  16;
                         Minor:=  FI.dwFileVersionMS  and  $FFFF;
                         Release:=  FI.dwFileVersionLS  shr  16;
                         Build:=  FI.dwFileVersionLS  and  $FFFF;
                         Result:=  True;
                     end;
             finally
                 FreeMem(VerBuf);
             end;
         end;
     end;
     
     Ilya  Katargin  2:5029/9
     -------------------------------------------------------
     
     function    GetFileVersion(FName:  TFileName):  String;
     var
     S:  String;
     n,  Len:  Cardinal;
     Buf,  Value:  PChar;
     begin
     Result:='';
     S  :=  FName;
     n  :=  GetFileVersionInfoSize(PChar(S),  n);
     if  n  =  0  then  Exit;
     Buf  :=  AllocMem(n);
     GetFileVersionInfo(PChar(S),  0,  n,  Buf);
     if  VerQueryValue(Buf,  PChar('StringFileInfo\041904E3\FileVersion'),
     Pointer(Value),  Len)  then
           Result:=Value;
     FreeMem(Buf,  n);
     end;
     
     шеп  2:5020/1355.256
     -------------------------------------------------
     
     >  if  VerQueryValue(Buf,  PChar('StringFileInfo\041904E3\FileVersion'),
     
     Здесь  жестко  прописан  язык  и  кодовая  страница  '041904E3'.
     В  хелпе  к  Д6  тоже  прописано  жестко:  '040904E4'  (см.  Reading  version
     information  в  хелпе).  Я  ,кстати,  сам  не  сразу  сообразил,  что  это  значение
     в  хелпе  не  работает  для  русского  языка  :(  
     А  ведь  это  значение  можно  взять  там  же:
     type
         TLangChrSet  =  array[0..1]  of  word;
         PLangChrset  =  ^TLangChrSet;
     var
         LangChrSet:  PLangChrSet;
     ...
     после  получения  FileVersionInfo
                 VerQueryValue(Buf,  PChar('VarFileInfo\Translation'),
     pointer(LangChrset),  Len);
                 S:=Format('%.4x%.4x',[LangChrSet^[0],  LangChrSet^[1]]);
     теперь  в  S  у  нас  то,  что  надо  :)
     
     С  Уважением,  Евгений  Переверзев.
     Eugene#asv.afn.ru

    Q-161: Как выключить или перезагрузить компьютер?

     procedure  Shutdown(Flags:  DWORD);
     var
         hToken:  THandle;
         Luid:  Int64;
         NewPrivileges:  TTokenPrivileges;
         OldPrivileges:  TTokenPrivileges;
         OldPrivilegesSize:  DWORD;
     begin
         if  Win32Platform  =  VER_PLATFORM_WIN32_NT  
         then  //  получения  привилегий  для  платформы  NT
         begin
                 //  получения  локального  уникального  ИД
             Win32Check(LookupPrivilegeValue(nil,  'SeShutdownPrivilege',  Luid));  
                 //  получения  токена  процесса
             Win32Check(OpenProcessToken(GetCurrentProcess,
                 TOKEN_ADJUST_PRIVILEGES  or  TOKEN_QUERY,  hToken);  
             NewPrivileges.PrivilegeCount  :=  1;
             NewPrivileges.Privileges[0].Attributes  :=  SE_PRIVILEGE_ENABLED;
             NewPrivileges.Privileges[0].Luid  :=  Luid;
                 //  настройка  привилегий
             AdjustTokenPrivileges(hToken,  
                 False,  
                 NewPrivileges,  
                 SizeOf(OldPrivileges),  
                 OldPrivileges,  
                 OldPrivilegesSize);
             try
                 Win32Check(GetLastError  =  ERROR_SUCCESS);
             finally
                 CloseHandle(hToken);
             end
         end;
         Win32Check(ExitWindowsEx(Flags,  0));
     end;
     
     Вызов:  Shutdown(EWX_SHUTDOWN  or  EWX_POWEROFF);
     
     Флаги  можно  комбинировать  c  помощью  оператора  OR
         EWX_FORCE      -  принудительное  выполнение  операций,  без  сохранения  данных.4
         EWX_LOGOFF      -  выход  из  сеанса  текущего  пользователя;
         EWX_POWEROFF  -  выключение  питания;
         EWX_REBOOT      -  пеpезагpузка  Windows;
         EWX_SHUTDOWN  -  выключение  Windows,  точка  в  которой  безопасно  выключать  питание.
     
     В  разработке  темы  приняли  многие  участники  конференции,  особая  благодарность  Andrey  Gusev  2:5050/121.11  и  Leonid  Troyanovsky  
     ===
     
     Также  можно  использовать  функцию  InitiateSystemShutdown.  С  помощью  данной
     ф-и  можно  выключать/перезагружать  и  удаленные  компьютеры  в  локальной  сети.
     Только  в  этом  случае  дополнительно  необходимо  иметь  привилегию
     SeRemoteShutdownPrivilege.
     Бакланов  Денис  

    Q-162: Куда пропали те или другие компоненты в Д7?

     Последнее  время  часто  задаются  вопросы,  куда  девались  те  или  другие  компоненты  в  Д7.  Большинство  из  них  некуда  не  девалось,  а  просто  не  инсталлировано.  Для  инсталляции  надо  найти  соответсвующий  bpl  файл  в  папке  BIN  и  проинсталлировать.  По  ряду  компонент  надо  поискать  readme,  которые  могут  находиться  в  других  папках,  например  в  DEMOS/
     
     P.S.  Если  ктото  приведет  список  bpl  файлов,  то  статья  будет  дополнена  данной  информацией.
     
     Client/ServerSocket  -  delphi7\bin\dclsockets70.bpl
     Quick  Report  -  delphi7\bin\dclqrt70.bpl
     TeeChart  =  delphi7\Bin\dcltqr70.bpl  
     
     Анатолий  Подгорецкий
     http://podgoretsky.com

    Q-163: Время работы Windows

     //Возврат  времени  работы  Windows
     //  в  формате  TDateTime
     function  WindowsUptimeDays:  TDateTime;
     var
         lpPerformanceCount:  Int64;
         lpFrequency:  Int64;
     begin
         if  QueryPerformanceCounter(lpPerformanceCount)  then  
         begin
             QueryPerformanceFrequency(lpFrequency);
             //  в  отличие  от  GetTickCount  будет  работать  более  49  суток
             Result  :=  lpPerformanceCount  /  lpFrequency  /  SecsPerDay;
         end
         else
             //  на  случай,  если  нет  мультимедийного  таймера
             Result:=  GetTickCount/MSecsPerDay;
     end;
     
     //Возврат  времени  работы  Windows
     //в  формате  d,  hh:mm:ss
     function  WindowsUptimeStr:  string;
     var
         DT:  TDateTime;
     begin
         DT  :=  WindowsUptimeDays:  
         Result  :=  IntToStr((Trunc(DT)))  +  ',  '  +  TimeToStr(DT);
     end;
     
     Вызов
     S  :=  WindowsUptimeStr;  
     
     "Слава  Сысолятин"  
     Fixed  by  Mihail  Tzarckoff,  2:5030/1083.16

    Q-164: Как отформатировать текст в TRichEdit?

     Надо  чтобы  определенная  процедура  сама  форматировала  текст,  который  затем  будет  отображен  в  TRichEdit.  Ну  и  шрифт,  стиль  шрифта  тоже  как  поменять?
     
     //*******************  writecolor  *************************
     procedure  writecolor(Var  RE:  TRichEdit;  Const  S:String;  Const  F:TFont);
     begin
     With  RE  do  begin
                     Lines.BeginUpdate;
                     SelStart:=Length(RE.Text);
                     SelLength:=1;
                     SelText:=S;
                     SelAttributes.Assign(F);
                     Lines.EndUpdate;
     end;  end;
     
     //*******************  writelncolor  *************************
     procedure  writelncolor(Var  RE:  TRichEdit;  Const  S:String;  Const  F:TFont);
     begin
     With  RE  do  begin
                     Lines.BeginUpdate;
                     SelStart:=Length(RE.Text);
                     SelLength:=1;
                     SelText:=S+#13#10;
                     SelAttributes.Assign(F);
                     Lines.EndUpdate;
     end;  end;
     
     ------
     C  уважением  Валерий  Судаков  

    Q-165: Как определить откуда была запущена программа?

     ExtractFilePath(ParamStr(0));

    Q-166: Как ассоциировать тип файлов с программой?

     uses  Registry;
     
     procedure  TForm1.Button1Click(Sender:  TObject);
     const  ErrMess  =  'Ошибка  записи  в  реестр';
     begin
       with  TRegistry.Create  do
         try
           RootKey:=HKEY_CLASSES_ROOT;
           if  not  OpenKey('\JC.Document\shell\open\command',True)  then
             raise  Exception.Create(ErrMess);
           WriteString(EmptyStr,Application.ExeName+'  "%1"');  CloseKey;
           if  not  OpenKey('\.djc',True)  then  raise  Exception.Create(ErrMess);
           WriteString(EmptyStr,'JC.Document');  CloseKey;
         finally
           Free;
         end;
     end;
     
     Igor  Yegorkin  

    Q-167: Как сохранить содержимое буфера обмена в JPG?

     получить  BMP  (uses  Clipbrd)  и  сохранить:
     
     //  сохранение  JPG
     procedure  TForm1.Button2Click(Sender:  TObject);
     begin
       with  TJPEGImage.Create  do
         try  //  даже  Compress  не  нужен
           CompressionQuality:=50;
           PixelFormat:=jf24Bit;
           Assign(Image1.Picture.Bitmap);
           SaveToFile('c:\;-).jpg');
         finally
           Free;
         end;
     end;

    Q-168: Как отловить нажатие клавиш в контроле?

       AG>  Когда  же  нажимаются  "стpелочки"  (VK_UP,  VK_DOWN  итп),  то  пpосто  фокyс  с
       AG>  него  соскакивает  на  дpyгой  контpол,  а  события  нет.  Пpичем,  также  нет  (не
       AG>  пpиходит)  и  самого  KeyDown  (котоpый  я  пpобовал  override_ить).
     
             А  перекрывать  WM_GETDLGCODE  Пушкин  будет?  Если  хочешь,  чтобы  к  твоему
     контролу  пришли  события  от  клавиатуры  при  нажатии  клавиш  управления  курсором,
     верни  из  обработчика  значение  DLGC_WANTARROWS  (в  справке  посмотри,  что  еще
     можно  вернуть).  Иначе  их  обработкой  займется  винда,  передвинув  фокус  на
     соседний  элемент.
     
     Eugene  Kasnerik,  2:450/118.24

    Q-169: Как получить номер строки, в которой произошло исключение?

       AA>  Hеобходимо  получить  номер  текущей  строки  в  CodeEditor  Delphi  (Может  есть
       AA>  такая  функция  или  переменная/константа).
       AA>  Hеобходимо  это  для  того,  что  бы  знать  какой  именно  из  try...except  вызвал
       AA>  исключение.  Совсем  не  хочется  писать  все  это  в  ручную,  ведь  при  добавлении
       AA>  строчки  кода  в  начало  файла  придется  все  исправлять.
     
     Используй  Jedi.  Они  там  могут  просто  по  адресу  вытаскивать  номер  строки  из  
     map-файла,  лежащего  рядом  с  программой.
     
     Andrew  V  Fionik

    Q-170: Как назначить программу обработчиком URL scheme?

     Например,  так:
     
     ===  begin  of  url.reg  ===
     REGEDIT4
     
     [HKEY_CLASSES_ROOT\mysuperproto]
     @="URL:  mysuperproto  Protocol"
     "URL  Protocol"=""
     
     [HKEY_CLASSES_ROOT\mysuperproto\DefaultIcon]
     @="C:\\Program  Files\\MySuperProgram\\MySuperProgram.exe,0"
     
     [HKEY_CLASSES_ROOT\mysuperproto\shell]
     @="open"
     
     [HKEY_CLASSES_ROOT\mysuperproto\shell\open]
     
     [HKEY_CLASSES_ROOT\mysuperproto\shell\open\command]
     @="\"C:\\Program  Files\\MySuperProgram\\MySuperProgram.exe\"  \"%1\""
     ===    end  of  url.reg    ===
     
     После  этого  все  URLы  вида  mysuperproto://go.far.far.away  и  mysuperproto:go.further  будут  обрабатываться  указанной  программой.