Читать «Виртуальная библиотека Delphi» онлайн - страница 99

Unknown

9. Почему при уничтожении компонента в методе OnClick происходит ошибка?

Допустим, вы поместили на форму кнопку, и создали метод OnClick в котором вызываете Button1.Free. Вы видите, что это метод формы — казалось бы, какие препятствия для правильного уничтожения кнопки?

На самом деле Button1.OnClick является свойством и после запуска вашего приложения содержит адрес метода Form1.Button1Click. Именно кнопка вызывает этот метод как свой собственный. А это означает, что кнопка не может удалить себя в своем-же методе. Даже если вы попытаетесь удалить ссылку в OnClick:

Button1.OnClick := nil;

Button1.Free;

то это не поможет — стек настроен на возврат в обработчик TButton, который и вызвал OnClick. Поскольку к моменту возврата объект разрушен — возникает GPF или Access Violation.

10. Есть ли у TDBGrid события OnMouseDown, OnMouseUp и OnMouseMove?

Они есть, но не объявлены published. Вы можете создать наследника TDBGrid и сделать их published.

11. Поиск компонента в форме по имени.

Я хочу делать текущими в форме произвольные компоненты. Как выставить фокус у конкретного компонента ясно - ListBox1.SetFocus. А если я хочу обращаться к некоему компоненту по имени (свойство Name)?

Свойство TForm.Components — массив компонентов формы, который и нужен вам. Вы можете перемещаться по этому массиву пока не найдете компонент с нужным Name. Например:

procedure TForm1.DooDah;

var

  Count: Integer;

begin

  Count := 0;

  while (Count < ComponentCount) and (Components[Count] <> 'Button1') do Inc(Count);

  TButton(Components[Count]).SetFocus;

end;

или еще проще:

procedure TForm1.DooDah;

var

  Target: TComponent;

begin

  Target := FindComponent('Button1');

  TButton(Target).SetFocus;

end;

Оба этих примера показывают как найти компонент TButton с именем Button1, и вызвать его метод SetFocus.

12. Как получить горизонтальный ScrollBar на ListBox?

Пошлите сообщение LB_SETHORIZONTALEXTENT в ListBox. Например, сообщение может быть отослано в момент создания формы:

procedure TForm1.FormCreate(Sender: TObject);

begin

  SendMessage(Listbox1.Handle, LB_SETHORIZONTALEXTENT, 1000, Longint(0));

end;

13. Как определить текущую колонку и строку каретки в компоненте TMemo?

Вы можете использовать сообщения Windows API EM_LINEFROMCHAR и EM_LINEINDEX для определения положения.

var

  LineNum: Longint;

  CharsBeforeLine: Longint;

begin

  LineNum := SendMessage(Memo1.Handle, EM_LINEFROMCHAR, Memo1.SelStart, 0);

  CharsBeforeLine := SendMessage(Memo1.Handle, EM_LINEINDEX, LineNum, 0);