KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Валентин Озеров, "Советы по Delphi. Версия 1.4.3 от 1.1.2001" бесплатно, без регистрации.
Перейти на страницу:

@YourDLLFunc := GetProcAddress(DLLHandle, 'YourDLLFuncName');

Для использования функции теперь используйте переменную YourDLLFunc, например:

Parm3 := YourDLLFunc(Parm1, Parm2);

Использование указателей на целое

Delphi 1

Сначала вы должны создать тип:

Type Pinteger: ^Integer;

Var MyPtr: Pinteger;

Мне кажется, что в начале вы использовали плохой пример, имеет смысл использовать 32-битный указатель для 16-битной величины или распределять 10 байт для переменной.

Pascal позволяет вам использовать методы NEW и DISPOSE, которые автоматически распределяют и освобождают правильные размеры блока.

Например,

NEW(MyPtr) = GetMem(MyPtr, Sizeof(MyPtr)).

Возможно, вы захотите подсчитать количество целочесленных переменных. В этом случае ознакомьтесь с возможностями TList. Пока лучше используйте линейный массив (или указатель на первый элемент, чтобы вычислить их количество, достаточно разделить количество занимаемой массивом памяти на количество элементов).

Для полноты, это должно быть:

NEW(MyPtr) = GetMem(MyPtr, SizeOf(MyPtr^));

SizeOf(MyPtr) всегда будет равен 4 байта, как 16-битный указатель.

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

Type

 pIntArr = ^IntArr;

 IntArr  = Array[1..1000] of Integer;

Var

 MyPtr : pIntArr;

Begin

 GetMem(MyPtr, 10); { 10 = SizeOf(Integer) * 5 !!}

 { MyPtr[2]:=1; }

 <<<< Заполняем массив >>>>

 MyPtr[2]^:=1;

 FreeMem(MyPtr,10);

End;

Технология похожа на ту, которуя Delphi использует при работе с pchar. Синтаксис очень похож:

type intarray = array[0..20000] of integer;


procedure TForm1.Button1Click(Sender: TObject);

var

 xptr:  ^IntArray;

begin

 GetMem(xptr, 10);

 xptr^[idx] := 1;  { где idx от 0 до 4, поскольку мы имеем 10 байте = 5 целых }

 FreeMem(xptr, 10);

end;

Обратите внимание на то, в вам в действительности нет необходимости распределять массив для 20,000 элементов, но проверка диапазона Delphi не будет работать, если диапазон равен 20,000. (Предостережение будущим пользователям!)

Память

Функция MemAvail для Delphi2?

Delphi 2

В Delphi 1, для того, чтобы получить самый большой возможный участок памяти, мы могли использовать функцию MemAvail, существует ли эквивалент этой функции в Delphi 2?

Нет. Но чтобы получить аппроксимированную сумму доступной памяти, можно воспользоваться функцией API GlobalMemoryStatus (через поле dwAvailVirtual возвращаемой структуры TMemoryStatus).

Steve Schafer

Как работать с блоками памяти размером более 64K?

Nomadic советует:

Так можно помещать в один блок памяти записи из TList (TCollection):

imlementation

 { To use the value of AHIncr, use Ofs(AHIncr). }

procedure AHIncr; far; external 'KERNEL' index 114;


const

 NEXT_SELECTOR: string[13] = 'NEXT_SELECTOR';


function WriteData: THandle;

var

 DataPtr: PChar;

 i: Integer;

begin

 Result := GlobalAlloc(GMEM_SHARE or GMEM_ZEROINIT, {pазмеp большого блока});

 if Result = 0 then Exit;

 DataPtr := GlobalLock(Result);

 {записываем кол-во эл-тов}

 Inc(DataPtr, {pазмеp счетчика эл-тов})

 for i := 0 to {некий}Count-1 do begin

  if LongInt(PtrRec(DataPtr).Ofs) + {pазмеp подблока} >l= $FFFF then begin

   Move(NEXT_SELECTOR, DataPtr^, SizeOf(NEXT_SELECTOR)); {некая константа}

   { коppекция сегмента }

   PtrRec(DataPtr).Seg := PtrRec(DataPtr).Seg + Ofs(AHIncr);

   PtrRec(DataPtr).Ofs := $0;

  end;

  Inc(DataPtr, {pазмеp нового блока});

 end; { for i }

 GlobalUnlock(Result);

end;


procedure ReadData(DataHdl: THandle);

var

 DataPtr : PObjectCfgRec;

 RecsCount: Integer;

 i: Integer;

begin

 if DataHdl = 0 then Exit;

 DataPtr := GlobalLock(DataHdl);

 RecsCount := PInteger(DataPtr)^;

 Inc(PInteger(DataPtr));

 for i := 1 to RecsCount do begin

  { обpаботать данные }

  Inc(DataPtr);

  if PString(DataPtr)^ = NEXT_SELECTOR then begin

   PtrRec(DataPtr).Seg := PtrRec(DataPtr).Seg + Ofs(AHIncr);

   PtrRec(DataPtr).Ofs := $0;

  end;

 end; { for i }

 GlobalUnlock(DataHdl);

end;

События

Назначение обработчика события OnClick пункту меню, созданному во время выполнения программы

Delphi 1

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

theMenuitem.OnClick := TheOnClickHandler;

Затем, в обработчике OnClick, вы приводите sender к TMenuItem и читаете имя:

procedure theform.TheOnClickHandler(Sender: TObject);

var

 fName: String;

begin

 fName := TMenuItem(Sender).name;

 …

end;

События для компонентов, созданных во время работы программы I

Delphi 1

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

Пример:

TForm1 = class(TForm)

 procedure FormCreate(Sender: TObject);

private

FMyButton: TButton;

protected

 procedure Button1Click(Sender: TObject);

 {Кодируем это вручную,для соответствия}

 {структуреTNotifyEvent}

end;


procedure TForm1.FormCreate(Sender: TObject);

begin

FMyButton := TButton.Create;

 {Здесь устанавливаем позицию, заголовок и все остальное}

 FMyButton.OnClick := MyButtonClick;

end;


procedure TForm1.MyButtonClick(Sender: TObject);

begin

ShowMessage('Эй! Ты нажал на мою кнопку!');

end;

События для компонентов, созданных во время работы программы II

Delphi 1

Вот простейший код для нового проекта с одной кнопкой и меню. (Надеюсь, в этом ничего сложного нет ... :)

procedure TForm1.Button1Click(Sender: TObject);

var

 NewItem: TMenuItem;

begin

 NewItem := TMenuItem.Create(Form1);

 NewItem.Caption := 'Динамический элемент ...';

 NewItem.OnClick := xyz;MainMenu1.Items.Insert(0, NewItem); ←Примечание: рекомендую бегло ознакомиться с Delphi-примером для команды Insert…

end;


{Любая старая 'xyz'-процедура (в настоящее время может быть определена одна, например, Form1.DblClick)}

procedure TForm1.xyz(Sender: TObject);

begin

 showmessage('Запусти эту процедуру !!');

end;

Примечание: Если вы пользуетесь неопределенной процедурой, вам понадобиться объявить ее. Лично я все это сделал в «верхнем правом углу» объявления типа формы, примерно так:

private

{ Private declarations }

public

{ Public declarations }

procedure xyz(Sender: TObject); ←К этой процедуре могут иметь доступ не только события Form1 …

Установите свойство обработчика события (например, OnClick, OnDblClick, OnMouseDown и пр.) на процедуру, которую вы создали для обработки этого события. Вам нужно убедиться в том, что параметры в точности соответствуют параметрам ожидаемого заданного обработчика события.

Например:

MySpeedButton.OnClick := MyClickEventHandler;

где…

procedure MyClickEventHandler(Sender: TObject);

begin

end;

Массивы

Динамические массивы V

SottNick пишет:

Если хочется, чтобы в многомерном массиве был разный размер у разных измерений например: VarArray: array[1..2, 1..?] of TType , где ? зависит от "строки" массива (1..2)

То дозволяется сделать так:

1. Объявление

Var VarArray: array of array of array…………

2. Установка длин

SetLength(VarArray, Razmernost1); // У первого измерения

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*