Выбрать главу

Delphi 2.0 добавляет так называемые длинные строки (AnsiString), которыми можно манипулировать как обычными строками в Pascal, но они имеют динамически изменяющийся размер и могут быть размером до 4Гбайт. Можно выполнять преобразования от PChar к AnsiString и наоборот. Старый строковый тип теперь называется ShortString. По умолчанию кличевое слово string соответствует типу AnsiString.

5. Есть ли в Delphi битовые множества?

В явном виде битовых множеств в языке Object Pascal нет. Но вместо этого можно использовать обычные множества, которые на самом деле и хранятся как битовые. Если множество вам нужно для проверки, установлен ли какой то бит в слове (байте и т.д.) можно попробовать такую конструкцию:

type 

  PByteSet = ^TByteSet; 

  TByteSet = set of Byte; 

var 

  W: Word; 

... 

{ если бит 3 в слове W установлен, тогда ... } 

  if 3 in PByteSet(@W)^ then ... 

... 

В Delphi 2.0 есть специальный класс TBitSet, который ведет себя как битовое множество.Для Delphi 1.0 вы можете написать такой класс самостоятельно.

6. Проблема с числом типа Single в DLL.

Я написал на C++ DLL, в которой у меня функция использует число типа float, передал из Delphi число типа Single и получил GPF 'Invalid Opcode'. Что неправильно?

Если вы используете числа с плавающей точкой, лучше передавать их не по значению, а по ссылке (указатель в C++). Вероятно DLL написана на MS Visual C++, так как Microsoft и Borland используют разные соглашения о передаче параметров при работе с сопроцессором. В случае Borland C++ и Delphi должны использовать одинаковый способ передачи параметров и значений (через стек сопроцессора). В любом случае вместо Single лучше использовать Double (double или long float в C++), так как вообще говоря, реальный тип, который соответствует типу Single точно не определен и может измениться в будущем.

7. Как заставить приложение Delphi отвечать на сообщения Windows?

Используем сообщение WM_WININICHANGED в качестве примера. Объявление метода в TForm позволит вам обрабатывать сообщение WM_WININICHANGED:

procedure WMWinIniChange(var Message: TMessage); message WM_WININICHANGE;

Код в implementation может выглядеть так:

procedure TForm1.WMWinIniChange(var Message: TMessage); 

begin 

  inherited

{ ... ваша реакция на событие ... } 

end;

Вызов inherited метода очень важен. Обратите внимание также на то, что для функций, объявленных с директивой message (обработчиков событий Windows) после inherited нет имени наследуемой процедуры, потому что она может быть неизвестна или вообще отсутствовать (в этом случае вы в действительности вызываете процедуру DefaultHandler).

8. Как обработать события от других приложений?

Попробуйте сделать это следующим образом:

type 

  TForm1 = class(TForm) 

  ... 

  private 

    procedure WMNCActivate(var Msg: TMessage); message WM_NCACTIVATE; 

  end

procedure TForm1.WMNCActivate(var Msg: TMessage); 

begin 

{ здесь обработка принятых событий } 

end

9. Как перехватить сообщения Windows и обработать их перед тем, как выполнится строка Application.Run?

Пример проекта показывает, как получить сообщения Windows в данном случае. Это редкий случай, в большинстве случаев переопределение процедуры Application.OnMessage будет делать то же самое.

program Project1; 

uses 

  Forms, 

  Unit1 in 'UNIT1.PAS' { Form1 }

  Messages, WinTypes, WinProcs, 

{$R *.RES} 

var 

  OldWndProc: TFarProc; 

function NewWndProc(hWndAppclass="underline" HWnd; Msg, wParam: Word; lParam: Longint): Longint; export

begin 

{ default WndProc return value } 

  Result := 0; 

{ handle messages here; the message number is in Msg } 

  Result := CallWindowProc(OldWndProc, hWndAppl, Msg, wParam, lParam); 

end

begin 

  Application.CreateForm(TForm1, Form1); 

  OldWndProc := TFarProc(GetWindowLong(Application.Handle, GWL_WNDPROC)); 

  SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc)); 

  Application.Run; 

end

10. Проблема с DragDrop для внешних программ.

Я пишу небольшую программку — "мусорную корзину". В FormCreate вызывается DragAcceptFiles(HANDLE, True). Проблема в том, что когда размер окна восстанавливается и затем минимизируется Drag and Drop перестает работать. Я безуспешно пробовал помещать DragAcceptFiles в разные методы формы. Однако если сделать вызов DragAcceptFiles(Application.Handle, True) в MainForm.Create, то все работает. Как перехватить событие WM_DROPFILES?

Это можно сделать так:

type 

  TMainForm = class(TForm) 

  ... 

    procedure FormCreate(Sender: TObject); 

  private 

    procedure DropFiles(var Msg : TWMDropFiles); message WM_DROPFILES; 

  end

procedure TMainForm.DropFiles(var Msg : TWMDropFiles); 

begin 

  DragQueryPoint(Msg.Drop, Point); 

  NrOfFiles := DragQueryFile(Msg.Drop, Word(-1), FileName, BufSize);