Как выдать текст под наклоном?

Чтобы вывести под любым углом текст необходимо использовать TrueType Fonts (например "Arial"). Например:

var 
  LogFont : TLogFont;

...
  GetObject(Canvas.Font.Handle, SizeOf(TLogFont), @LogFont);
  { Вывести текст 1/10 градуса против часовой стрелки }
  LogFont.lfEscapement := Angle*10; 
  Canvas.Font.Handle := CreateFontIndirect(LogFont);


Как экспортировать таблицу базы данных в ASCII-файл?



procedure TMyTable.ExportToASCII;

var
  I: Integer;
  Dlg: TSaveDialog;
  ASCIIFile: TextFile;
  Res: Boolean;

begin
  if Active then
    if (FieldCount > 0) and (RecordCount > 0) then
      begin
        Dlg := TSaveDialog.Create(Application);
        Dlg.FileName := FASCIIFileName;
        Dlg.Filter := 'ASCII-Fiels (*.asc)|*.asc';
        Dlg.Options := Dlg.Options+[ofPathMustExist, 
          ofOverwritePrompt, ofHideReadOnly];
        Dlg.Title := 'Экспоритровать данные в ASCII-файл';
        try
          Res := Dlg.Execute;
          if Res then
            FASCIIFileName := Dlg.FileName;
        finally
          Dlg.Free;
        end;
        if Res then
          begin
            AssignFile(ASCIIFile, FASCIIFileName);
            Rewrite(ASCIIFile);
            First;
            if FASCIIFieldNames then
              begin
                for I := 0 to FieldCount-1 do
                  begin
                    Write(ASCIIFile, Fields[I].FieldName);
                    if I <> FieldCount-1 then
                      Write(ASCIIFile, FASCIISeparator);
                  end;
                Write(ASCIIFile, #13#10);
              end;
            while not EOF do
              begin
                for I := 0 to FieldCount-1 do
                  begin
                    Write(ASCIIFile, Fields[I].Text);
                    if I <> FieldCount-1 then
                      Write(ASCIIFile, FASCIISeparator);
                  end;
                Next;
                if not EOF then
                  Write(ASCIIFile, #13#10);
              end;
            CloseFile(ASCIIFile);
            if IOResult <> 0 then
              MessageDlg('Ошибка при создании или переписывании '+
                'в ASCII-файл', mtError, [mbOK], 0);
          end;
      end
    else
      MessageDlg('Нет данных для экспортирования.',
        mtInformation, [mbOK], 0)
  else
    MessageDlg('Таблица должна быть открытой, чтобы данные '+
      'можно было экспортировать в ASCII-формат.', mtError,
      [mbOK], 0);
end;

Как выяснить размер BLOB-поля?

Следующая функция поможет определить размер BLOB-поля.

Function GetBlobSize(Field: TBlobField): LongInt;

begin
  with TBlobStream.Create(Field, bmRead) do 
    try
      Result := Seek(0, 2); 
    finally
      Free; 
    end;
end;

Как сравнить bookmarks в таблице?



function TBDEDirect.CompareBookmarks(Bookmark1,
  Bookmark2: TBookmark): Boolean;

var
  Res: DBIResult;
  CompareRes: Word;

begin
  Result := False;
  if CheckDatabase then
    begin
      Res := DbiCompareBookmarks(FDataLink.DataSource.DataSet.Handle,
        Bookmark1, Bookmark2, CompareRes);
      if Res = 0 then
        if CompareRes = 0 then
          Result := True
        else
      else
        Check(Res);
    end;
end;

Как выделить окошко DBGrid другим цветом?


Необходимо обработать событие "OnDrawCellData". Например для того, чтобы пометить выбранное окошко красным фоном, необходимо сделать следующее:

procedure TForm1.DBGridDrawDataCell(Sender:TObject; const Rect:TRect;
  Field:TField; State:TGridDrawState);

begin
  if gdFocused in State then
    with (Sender as TDBGrid).Canvas do
      begin
        Brush.Color := clRed;
        FillRect(Rect);
        TextOut(Rect.Left, Rect.Top, Field.AsString);
      end;
end;

Как закрыть окно подсказки если пользователь закончил приложение?

В следующем примере показано как закрыть окно помощи если пользователь закончил приложение.

procedure TMainForm.FormClose(Sender: TObject; 
          var Action: TCloseAction);

begin
  Winhelp(Handle, 'WINHELP.HLP', HELP_QUIT, 0);
  Action := caFree;
end;

Как установить количество цветов в системной палитре?

Функция GetNumColors возвращает количество цветов для актуально выбранного разрешения экрана.
function GetNumColors: LongInt;
var
   BPP: Integer;
   DC: HDC;
begin
   DC := CreateDC('DISPLAY', nil, nil, nil);
   if DC <> 0 then begin
      try
	 BPP := GetDeviceCaps(DC, BITPIXEL) * GetDeviceCaps(DC, PLANES);
      finally
         DeleteDC(DC);
      end;
      case BPP of
         1: Result := 2;
         4: Result := 16;
         8: Result := 256;
         15: Result := 32768;
         16: Result := 65536;
         24: Result := 16777216;
      end;
   end else
      Result := 0;
end;

Как через индекс обратиться к нескольким компонентам?

Чтобы найти и сделать видимыми, например, компоненты с именами от "Label1" и до "Label5" можно использовать следующий вариант:

for t := 1 to 5 do
  FindComponent('Label' + IntToStr(t)).Visible := TRUE;

Как копировать и вставлять Bitmap через буфер обмена?

Некоторые функции для копирования и вставки Bitmap-объектов через буфер обмена.

function CopyClipToBuf(DC: HDC; Left, Top,
           Width, Height: Integer;  Rop: LongInt;
           var CopyDC: HDC;
           var CopyBitmap: HBitmap): Boolean;

var
  TempBitmap: HBitmap;

begin
  Result := False;
  CopyDC := 0;
  CopyBitmap := 0;
  if DC <> 0 then
    begin
      CopyDC := CreateCompatibleDC(DC);
      if CopyDC <> 0 then
        begin
          CopyBitmap := CreateCompatibleBitmap(DC,
                          Width, Height);
          if CopyBitmap <> 0 then
            begin
              TempBitmap := CopyBitmap;
              CopyBitmap := SelectObject(CopyDC,
                              CopyBitmap);
              Result := BitBlt(CopyDC, 0, 0,
                          Width, Height, DC,
                          Left, Top, Rop);
              CopyBitmap := TempBitmap;
            end;
        end;
    end;
end;

function CopyBufToClip(DC: HDC; var CopyDC: HDC;
           var CopyBitmap: HBitmap; 
           Left, Top, Width, Height: Integer;
           Rop: LongInt; DeleteObjects: Boolean): Boolean;

var
  TempBitmap: HBitmap;

begin
  Result := False;
  if (DC <> 0) and
     (CopyDC <> 0) and
     (CopyBitmap <> 0) then
    begin
      TempBitmap := CopyBitmap;
      CopyBitmap := SelectObject(DC, CopyBitmap);
      Result := BitBlt(DC, Left, Top,
                  Width, Height, CopyDC,
                  0, 0, Rop);
      CopyBitmap := TempBitmap;
      if DeleteObjects then
        begin
          DeleteDC(CopyDC);
          DeleteObject(CopyBitmap);
        end;
    end;
end;

Как выяснить положение курсора в МЕМО?

Необходимо вызвать дважды API-функцию "SendMessage":

var 
  xChr, 
  xRow, 
  xCol: LongInt;
...

xRow := SendMessage(Memo1.Handle, EM_LINEFROMCHAR, Memo1.SelStart, 0);
xChr := SendMessage(Memo1.Handle, EM_LINEINDEX, Zeile, 0);
xCol := Memo1.SelStart - xChr + 1;

Как узнать содержание активной записи в БД?

Следующая функция возвращает в виде указателя на строку содержание активной записи в БД.

function TBDEDirect.GetCurRecord(Lock: DBILockType): PChar;

var
  Res: DBIResult;
  RecSize: Word;
  RecBuf: PChar;
  Bookmark: TBookmark;

begin
  Result := StrNew('');
  if CheckDatabase then
    begin
      RecSize := GetPhysicalRecSize;
      RecBuf := StrAlloc(RecSize+1);
      FillChar(RecBuf^, RecSize+1, #0);
      Bookmark := FDataLink.DataSource.DataSet.GetBookmark;
      DbiSetToBookmark(FDataLink.DataSource.DataSet.Handle,
        Bookmark);
      FDataLink.DataSource.DataSet.FreeBookmark(Bookmark);
      Res := DbiGetRecord(FDataLink.DataSource.DataSet.Handle,
        Lock, RecBuf, nil);
      if Res = 0 then
        Result := RecBuf
      else
        Check(Res);
    end;
end;

Как создать и использовать новую форму курсора?

Для этого необходимо создать новый курсор(ы) в подходящем для этого редакторе ресурсов (например борландовский Resource Workshop). При этом надо обратить внимание на то что имена в редакторе ресурсов (особенно в том, который поставляется с Delphi) надо писать заглавными буквами. После этого "перед внутренним употреблением" (лучше всего в процедуре обработки события OnCreate главной формы) необходимо загрузить курсор(ы) из res-файла как указано ниже:

{$I CURSOR.RES}

Screen.Cursors[1] := LoadCursor(hInstance, 'CURSOR_1');
Button1.Cursor := 1;

Обратите внимание на то, что системные курсоры в Screen.Cursors начинаются с нуля и идут в минусовом направлении. Поэтому при создании новых курсоров лучше выбирать положительные числа (лучше не слишком большие :-)).
Более удобный вариант - это объявить постоянную (равную например 12):

const
   CUR_HAND = 12;

...

Screen.Cursors[CUR_HAND] := LoadCursor(hInstance, 'CURSOR_HAND');
Button1.Cursor := CUR_HAND;

Как выяснить дату последнего изменения файла?

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

function GetFileDate(FileName: string): string;

var
  FHandle: Integer;

begin
  FHandle := FileOpen(FileName, 0);
  try
    Result := DateTimeToStr(FileDateToDateTime(FileGetDate(FHandle)));
  finally
    FileClose(FHandle);
  end;
end;

Как проверять корректность доступа к базе данных?

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

function TBDEDirect.CheckDatabase: Boolean;
var
  DS: TDataSource;
begin
  Result := False;
  DS := GetDataSource;
  if DS = nil then
    begin
      MessageDlg('Не установлена связь с элементом-источником данных.'+
        'Проверьте установку свойства DataSource.',
        mtError, [mbOK], 0);
      Exit;
    end;
  if DS.DataSet = nil then
    begin
      MessageDlg('Доступ к базе данных невозможен.', mtError,
        [mbOK], 0);
      Exit;
    end;
  if TDBDataSet(DS.DataSet).Database = nil then
    begin
      MessageDlg('Доступ к базе данных невозможен.', mtError,
        [mbOK], 0);
      Exit;
    end;
  if TDBDataSet(DS.DataSet).Database.Handle = nil then
    begin
      MessageDlg('Дескриптор (Handle) БД недоступен.', mtError,
        [mbOK], 0);
      Exit;
    end;
  if DS.DataSet.Handle = nil then
    begin
      MessageDlg('Дескриптор курсора (Cursor-Handle) недоступен.', mtError,
        [mbOK], 0);
      Exit;
    end;
  Result := True;
end;

Как узнать, находится ли дискета в дисководе?


type
  TDriveState(DS_NO_DISK, DS_UNFORMATTED_DISK, 
    DS_EMPTY_DISK, DS_DISK_WITH_FILES);

function DriveState(DrvLetter: Char): TDriveState;

var
  Mask: String[6];
  SearchRec: TSearchRec;
  oldMode: Cardinal;
  ReturnCode: Integer;

begin
  oldMode: = SetErrorMode(SEM_FAILCRITICALERRORS);
  Mask:= '?:\*.*';
  Mask[1] := DrvLetter;
  {$I-}  { отключить обработку исключительных ситуаций }
  ReturnCode := FindFirst(Mask, faAnyfile, SearchRec);
  FindClose(SearchRec);

  {$I+}
  case ReturnCode of
    { как минимум один файл был найден }
    0: Result := DS_DISK_WITH_FILES;
    { файлов не найдено и дискета в порядке }
    -18: Result := DS_EMPTY_DISK;
    { DS_NO_DISK для DOS, ERROR_NOT_READY для WinNT, ERROR_PATH_NOT_FOUND для Win 3.1 }
    -21, -3: Result := DS_NO_DISK;
  else
    { дискета лежит в дисководе но она не форматировнная }
    Result := DS_UNFORMATTED_DISK;
  end;
  SetErrorMode(oldMode);
end; { DriveState }

Как выводить формуляр в центр экрана?

Часто встречающийся вопрос начинающего программиста. Чтобы вывести формуляр в центре экрана необходимо (в самом простом случае) изменить свойство формы Position. Значение должно быть установленно в poScreenCenter. Причем это можно делать как в Object Inspector, так и во время работы программы.
Порядок, в котором обрабатываются события при загрузке формы


    OnCreate
    OnShow
    OnPaint
    OnActivate
    OnResize
    OnPaint

Ето может быть важно например для того чтобы координировать некоторые акции по управлению положением формы и т.п.

Как установить минимальные размеры формуляра?

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


type
  TForm1 = class(TForm)
    procedure wmGetMinMaxInfo(var Msg : TMessage); message wm_GetMinMaxInfo;

procedure TForm1.wmGetMinMaxInfo(var Msg : TMessage); 

begin
  PMinMaxInfo(Msg.lParam)^.ptMinTrackSize.X := 600;
  PMinMaxInfo(Msg.lParam)^.ptMinTrackSize.Y := 350;
end;

Как эффективно организовать объявление глобальных переменных?

Один из эффективных способов организации глобальных переменных - создать отдельный Unit и в Interface-части объявить все необходимые переменные (и, естесственно, константы ежели таковые имеются). Если теперь в других модулях записать этот Unit в uses раздел, то все глобальные переменные можно использовать в рамках целого проекта (или проектов).

Как перейти к указанной записи в БД?

Демонстрация перехода к указанной записи через задание номера записи.
function TBDEDirect.GoToRecord(RecNo: LongInt): Boolean;
var
  RecCount: LongInt;
  Bookmark: TBookmark;
  Res: DBIResult;
begin
  Result := False;
  if CheckDatabase then
    begin
      if RecNo < 1 then
        RecNo := 1;
      RecCount := GetRecordCount;
      if RecNo > RecCount then
        RecNo := RecCount;
      Res := DbiSetToRecordNo(FDataLink.DataSource.DataSet.Handle,
        RecNo);
      if Res = 0 then
        begin
          Bookmark := StrAlloc(GetBookmarkSize);
          DbiGetBookmark(FDataLink.DataSource.DataSet.Handle,
            Bookmark);
          FDataLink.DataSource.DataSet.GoToBookmark(Bookmark);
          FDataLink.DataSource.DataSet.FreeBookmark(Bookmark);
          Result := True;
        end
      else
        Check(Res);
    end;
end;

Как вызвать подсказку к подсказке?

В Delphi-приложении можно вызвать помощь в пользовании системой помощи следующим образом:

Application.HelpCommand(Help_HelpOnHelp, 0);

Как вывести главное окно справочной системы?

В 16-битных версиях справочной системы необходимо было вызывать начальное (главное) окно помощи с параметром HELP_CONTENTS в комманде HelpCommand. В 32-битном варианте это осуществляется следующим образом:

Application.HelpCommand(HELP_FINDER, 0);

Примечание: Для того, чтобы показывались "книжки" (или главные темы) - необходимо создать .CNT-файл.

Как скрыть свойства объекта?

В иерархии VCL в большинстве случаев существует уровень объектов-"предшественников" (TCustomXXXX), в которых многие свойства скрыты. Для унаследованных от таких "предшественников" объектов можно "открывать" на выбор те или иные свойства. А как можно сокрыть свойства, которые объявлены в published-области от Object Inspector'а, но при этом оставить возможность доступа во время работы программы? Решение состоит в объявлении свойства "по новой" в public-области. В примере скрытым будет у объекта TMyControl свойство Height.
TMyControl = class(TWinControl)
protected
  procedure SetHeight(Value: Integer);
  function GetHeight: Integer;
public
  property Height: Integer read GetHeight write SetHeight;
end;

procedure TMyControl.SetHeight(Value: Integer);
begin
  inherited Height := Value;
end;

function TMyControl.GetHeight;
begin
  Result := inherited Height;
end;

Как скрыть форму при старте приложения?

К сожалению при создании окна приложения ни в одном из первых событий (OnCreate, OnShow, OnActivate) нет доступа к свойству Visible. Использование функции ShowWindow с параметром SW_HIDE в OnActivate-событии решает проблему (но при этом не избежать кратковременного мерцания окна перед "исчезновением"):
procedure TForm1.OnActivate(Sender: TObject);
begin
  ShowWindow(Handle, SW_HIDE);
end;
чтобы сделать окно опять видимым необходимо вызвать ту же функцию, но уже с другим параметром:
  ShowWindow(Handle, SW_SHOW);
Если Вам лень пользовать API-функции или неприятно видеть мерцание, то есть другой, весьма интересный способ сокрыть окно приложения от любопытствующих глаз:
procedure TForm1.OnCreate(Sender: TObject);
begin
  Left := Screen.Width;
end;
Окно создается видимым, но находится за пределами экрана!

Как "заствавить" формуляр не разворачиваться из иконки?

Для этого необходимо перехватить сообщение "WM_QUERYOPEN". Для этого необходимо объявить соответствующую процедуру в private-области.

{ объявление процедуры в классе TMainForm }
procedure WMQueryOpen(var Msg: TWMQueryOpen); message WM_QUERYOPEN;


{ ... и ее реализация }
procedure TMainForm.WMQueryOpen(var Msg: TWMQueryOpen);
begin
  Msg.Result := 0;
end;

Как ускорить навигацию по исходному тексту?

Весьма удобно при работе с текстами больше двух-трех страниц использовать метки (bookmarks).

Чтобы установить подобную метку - необходимо нажать компбинацию клавиш: CTRL+SHIFT+Число, где "Число" находится в пределах от 0 до 9. После этого можно с любого места "прыгнуть" на эту метку. Для этого необходимо нажать комбинацию CTRL+Число.

Примечание: Чтобы убрать метку - необходимо второй раз нажать CTRL+SHIFT+Число, а чтобы передвинуть метку на другое место - необходимо нажать ту же комбинацию в необходимом месте.
INI-файлы (чтение/запись)

function ReadIni(ASection, AString : String) : String;
var
   sIniFile: TIniFile;
   sPath : String[60];
const
   S = 'xyz'; { стандартная строка для выдачи ошибок чтения }
begin
   GetDir(0,sPath);
   sIniFile := TIniFile.Create(sPath + '\Name.INI');
   Result := sIniFile.ReadString(ASection, AString, S); { [Section] String=Value }
   sIniFile.Free;
end;

procedure WriteIni(ASection, AString, AValue : String);
var
   sIniFile: TIniFile;
   sPath : String[60];
begin
   GetDir(0,sPath);
   sIniFile := TIniFile.Create(sPath + '\Name.INI');
   sIniFile.WriteString(ASection, AString, AValue);; { [Section] String=Value }
   sIniFile.Free;
end;

{ReadSection считывает все пункты указанной секции - т.е. ключи перед знаком "="
ReadSectionValues полностью считывает все строки указанной секции, т.е. Punkt=xyz }


Как создать Ini-файл в директории программы?



По умолчанию ini-файл создается в Windows-директории (например: TIniFile.Create('FOO.INI' )), что приводит к "захламлению" оной. Более (эко-)логично (за исключением случаев, когда программа делается для CD-ROM) если ini-файл создается в той же директории что и главная программа. Это достигается с помощью одной строки:


IniFile := TIniFile.Create(ChangeFileExt(ParamStr(0),'.INI'));
С помощью API-функции SendMessage можно задать поля в Memo-компоненте.
Если необходимо, например, сделать отступ в 20 пикселей слева то можно
это сделать следующим образом:

var Rect: TRect;
begin
  SendMessage( Memo1.Handle, EM_GETRECT, 0, LongInt(@Rect));
  Rect.Left:= 20;
  SendMessage(Memo1.Handle, EM_SETRECT, 0, LongInt(@Rect));
  Memo1.Refresh;
end;

Как "быструю подсказку" (Hints) сделать многострочной?

Необходимо создать соответствующую компоненту которая показывает "быструю подсказку" (Hints) с более чем одной строкой. Компонента наследуется от TComponent и называется TMHint. Hint-текст можно задавать следующим образом: "Строка 1@Строка 2@Строка 3". Символ '@' используется как разделитель строк. Если Вам нравится другой символ - измените свойство Separator. Свойство Active указывает на активность (TRUE) или неактивность (FALSE) "многострочности".

unit MHint;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages,
  Classes, Graphics, Controls, Forms, Dialogs;

type
  TMHint = class(TComponent)
  private
    ScreenSize: Integer;
    FActive: Boolean;
    FSeparator: Char;
    FOnShowHint: TShowHintEvent;
  protected
    procedure SetActive(Value: Boolean);
    procedure SetSeparator(Value: char);
    procedure NewHintInfo(var HintStr: string; 
      var CanShow: Boolean;
      var HintInfo: THintInfo);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Active: Boolean
      read FActive write SetActive;
    property Separator: Char
      read FSeparator write SetSeparator;
  end;

procedure Register;

implementation

constructor TMHint.Create(AOwner: TComponent);

begin
  inherited Create(AOwner);
  FActive := True;
  FSeparator := '@';
  Application.OnShowHint := NewHintInfo;
  ScreenSize := GetSystemMetrics(SM_CYSCREEN);
end;

procedure TMHint.SetActive(Value: Boolean);

begin
  FActive := Value;
end;

procedure TMHint.SetSeparator(Value: Char);

begin
  FSeparator := Value;
end;

procedure TMHint.NewHintInfo(var HintStr: string; 
  var CanShow: Boolean;
  var HintInfo: THintInfo);

var 
  I: Byte;

begin
  if FActive then
    begin
      I := Pos(FSeparator, HintStr);
      while I > 0 do
        begin
          HintStr[I] := #13;
          I := Pos(FSeparator, HintStr);
        end;
      if HintInfo.HintPos.Y+10 > ScreenSize then
        HintInfo.HintPos.Y := ScreenSize-11;
    end;
end;

procedure Register;

begin
  RegisterComponents('MyComponents', [TMHint]);
end;

end.


Или вот ещё пример.

Как создать и вызвать модальный формуляр?

Модальные формуляры довольно часто выгоднее (с точки зрения использования памяти) временно создавать, и после того, как формуляр был вызван, отработан и закрыт, - освободить его из памяти. В противном случае Delphi-приложение может быть настоящим "пожирателем памяти". Примерно так может выглядеть вызов такого формуляра:

ModalForm := TModalForm.Create(Self);
try
  ModalForm.ShowModal;
finally 
  ModalForm.Free;
end;

Как различаются между собой Paint-события: Invalidate, Update и Refresh?



Invalidate      весь объект перерисовывается заново; обычно перерисовывается только часть бывшая перед этим закрытой


Update незамедлительная перерисовка


Refresh Invalidate + Update

Как сделать отступ в Memo?

С помощью API-функции SendMessage можно задать поля в Memo-компоненте. Если необходимо, например, сделать отступ в 20 пикселей слева то можно это сделать следующим образом:

var Rect: TRect;
begin
  SendMessage( Memo1.Handle, EM_GETRECT, 0, LongInt(@Rect));
  Rect.Left:= 20;
  SendMessage(Memo1.Handle, EM_SETRECT, 0, LongInt(@Rect));
  Memo1.Refresh;
end;
Системные сообщения (сокращения)
BM  - ButtonMode
BN  - Button
BS  - ButtonStyle
CB  - ComboBox
CBN - Combo Box Notifications
CBS - ComboBoxStyle
EM  - EditMessage
ES  - EditStyle
FM  - FileManager
LB  - ListBox
LBN - ListBox Notifications
LBS - ListBoxStyle
MB  - MessageButton (Typen)
PS  - PenStyle
SB  - ScrollBar
SBS - ScrollBarStyle
SM  - SystemMetrics
SPI - SystemParametersInfo
WM  - WindowMessage
WS  - WindowStyle

Как можно опросить различные параметры системы, например количество свободных ресурсов?

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

Variable := GetFreeSystemResources(GFSR_SYSTEMRESOURCES);
Другие функции опроса параметров системы (описаны в системе помощи): GetWinFlags, SystemParametersInfo, GetDeviceCaps и GetFreeSpace.


Для 32-bit систем необходимо вызывать GetSystemMetrics, GetSystemInfo и SystemParametersInfo.

Как управлять табуляцией в Memo-компоненте?

Для этого необходимо поставить свойство "WantTabs" в "True". Теперь для управления штртной табуляции необходимо вызвать API-функцию SendMessage. В последнем параметре функция ожидает указатель на массив с элементами типа Word, в котором указаны позиции в единицах экрана. Для примера вызов функции с указанием двух позиций табуляции:
procedure TForm1.FormCreate(Sender:TObject);
const
  Tabs: array[0..1] of Word = (4, 8);
begin
  SendMessage(Memo1.Handle, EM_SetTabStops, 2, LongInt(@Tabs));
end;

Как вывести окно перед другими окнами не выводя наверх родительское окно?

Если это не мешает общему ходу программы, то одно из самых простых решений - использование рабочего стола (Desktop) как родительское окно. Для этого необходимо перекрыть CreateParams подчиненного окна следующим образом:

...

private
  procedure CreateParams(var Params: TCreateParams); override;

...

procedure TForm2.CreateParams(var Params: TCreateParams);

begin
  inherited CreateParams(Params);
  Params.WndParent := GetDesktopWindow;
end;

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

В следующем примере показано как можно передвигать форму если пользователь "захватил" Client-пространство. Наиболее простое решение - "обмануть" Windows и Client-пространство выдать за заголовок окна.

unit DragMain;

interface

uses
  SysUtils, WinTypes, WinProcs,  Messages,
  Classes, Graphics, Controls, Forms, Dialogs, StdCrtls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure ButtonClick(Sender: TObject);
  private	
    procedure WMNCHitTest(var M: TWMNCHitTest);
                 message wm_NCCHitTest;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1. WMNCHitTest(var M: TWMNCHitTest); 

begin
  inherited;
  if M.Result = htClient then
    M.Result := htCaption;
end;


procedure TForm1.Button1Click(Sender: TObject);

begin
  Close;
end;

end.