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

   A: Application.ProcessMessages.

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

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

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

   A: WinExec() или ShellExecute. У второй больше возможностей.

   (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): Надо послать программе сообщение WM_QUIT:

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

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

uses ShellApi;

{ ... }

ShellExecute("http://www.company.com", ... );

ShellExecute("mailto:author@somewhere.net", ...);

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

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

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

   A: BeginUpdate/EndUpdate.

   Q: Как мне запрограммировать непрямоугольную форму, например, как у
   Norton CrashGuard, в форме щита?

   A: SetWindowRgn() (Win32).

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

   A:

{$R CURSORS.RES}

const
  crZoomIn = 1;
  crZoomOut = 2;

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

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

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

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

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

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

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

   A: Обрабатывать OnCloseQuery.

   Q: Как получить короткий путь файла если имеется длинный? ("c:\Program
   Files" ==> "c:\progra~1").

   A: GetShortPathName()

   Q: Как написать сервис для Windows NT?

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

   Q: Как работать с registry?

   A: TRegistry

   Q: Как выдвинуть дверцу CD-ROM'а?

   A: mciSendString('Set cdaudio Door Open Wait', nil, 0, handle);

   Также mciSendCommand(mp.DeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);

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

   A: SetWindowsHookEx().

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

   A: Надо применять так называемые "thunks". Смотри статью на
   [29]http://www.itecuk.com/delmag/thunk95.htm.

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

   A: RTFM packed, $A.

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

   A: В MSDN.

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

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

   A: WM_NCHITTEST.

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

   A: Обрабатывать CM_MOUSEENTER/CM_MOUSELEAVE.

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

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

   A: Можно ли сделать так, чтобы в исполняемом файле программы находился
   какой-нибудь звук в формате .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('MyWave', 0, SND_MEMORY);
  finally
    FreeResource(hResource);
  end;
end;

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

   Поменять:

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;

   Q: Как во время выполнения программы создать так называемый "array of
   const", например, параметры для функции Format()?

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

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

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

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

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

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

   A: На [31]http://www.imagelib.com лежит библиотека ImageLib.

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

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

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

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

   Q: Как использовать DirectX в своей программе?

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

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

   A: Как использовать OpenGL в своей программе?

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

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

   Q: Как встроить просмотр HTML в свою программу?

   В Delphi 4 имеется пример Web-браузера на Delphi.

   A: MS Internet Explorer умеет быть элементом управления ActiveX, что
   позволяет поместить его на форму.

   Netscape Navigator умеет делать то же самое, подробности на
   [39]http://www.chami.com/tips/delphi/103096D.html

   Еще на [40]http://www.pbear.com лежат THTMLViewer и TFrameViewer.

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

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

   Q: Какие инструменты можно применить для коллективной разработки
   проекта?

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

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

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

   A: MSDebug Макса Русова. Находится на
   [44]http://www.dic.ru/users/rusov/. Поддерживает Delphi 3 и выше,
   ловит только утечки памяти, но делает это хорошо.

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

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

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

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

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

   A: Писать на WinAPI без использования VCL. Это пригодно для и без того
   крохотных программ.

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

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

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

   A: [51]http://www.iconbazaar.com

   Q: Как сделать ping из своей программы? И вообще, посоветуйте
   какую-нибудь альтернативу стандартным дельфовым Internet-компонентам.

   A: Зайди на [52]http://www.rtfm.be/fpiette. Там кyча компонентов для
   инета с исходниками. Там и ping есть.

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

   A: Начнем с создания.

   Сущность свойства 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: Как мне работать с файлами MS Word или таблицами MS Excel?

   A: Воспользоваться функцией CreateOLEObject и работать с VBA (Visual
   Basic for Applications) или WordBasic.

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

=== Cut Пример by Sergey Arkhipov 2:5054/88.10 ===

Пример проверен только на русском 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;
{.....}

=== Cut Конец примера ===

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

   Во-первых, можно по примеру Back Orifice воспользоваться функцией
   RegisterServiceProcess.

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

   A: (EM, DS):

type
  TForm1 = class(TForm)
    Label1: TLabel;
    RxTrayIcon1: TRxTrayIcon;
    procedure FormCreate(Sender : TObject);
    procedure RxTrayIcon1DblClick(Sender: TObject);
  private
    { Private declarations }
    procedure ApplicationMinimize(Sender : TObject);
    procedure ApplicationRestore(Sender : TObject);
  public
    { Public declarations }
  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_HIDE);
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: После работы программы не сохраняются изменения в базе Paradox. Что
   делать?

   A: Где-нибудь при закрытии главной формы выполните нижеследующие куски
   кода:

   Для Delphi 3: Table.FlushBuffers при открытой таблице.

   Для прочих: Table.Open; Check(dbiSaveChanges(Table.Handle));
   Table.Close;

   Q: Как мне упаковать Paradox или DBF таблицу?

   A: Воспользоваться функцией PackTable из rxLib.

   Для перегенерации индексов:

Table1.Exclusive := True;
Table1.Open;
Check(dbiRegenIndexes(Table1.Handle);

   Q: Почему при добавлении/изменении записей в некоторых запросах
   возникает ошибка Cannot modify a read-only dataset?

   A: Во-первых, должно быть RequestLive := True; во-вторых, чтобы запрос
   был редактируемым, он должен удовлетворять требованиям, изложенным в
   помощи при поиске по "live result sets".

   Q: Почему не работает сортировка и функция UPPER() в Interbase'овской
   базе данных?

   A: Смотри в F.A.Q. по Borland Interbase от демо-центра.

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

   A: В Database Desktop поставьте правильный Language Driver у таблицы,
   например, Pdox ANSI Cyrr.

   Q: Я переписал готовую программу на машину заказчика, а она там не
   запускается -- говорит "Error initializing database engine". Что
   делать?

   A: Прочитать X:\DELPHI\DOC\deploy.txt.

   Q: Как правильно соединяться с базой данных под Personal Oracle?

   A: user/password@2: Это так для Oracle SQL Plus, и более других его
   утилит. А в BDE надо оставить все как для соединения с сетевым
   сервером, (протокол TNS, имя пользователя, кодировку, интерфейсную
   DLL) только вместо имени сервера написать "2:". Это годится и для
   случая, когда на одной машине и сетевой сервер и приложение.

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

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