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

  SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE); 

{ восстановим окно } 

  SetWindowPos(Handle, HWND_TOP, 0, 0, WWidth, WHeight, SWP_NOMOVE); 

end;   

Можно поступить другим способом — выставить у формы свойство BorderStyle = bsNone, и написать следующий обработчик OnPaint:

procedure TForm1.FormPaint(Sender: TObject); 

begin 

  Canvas.Brush.Style := bsClear; 

  Canvas.Rectangle(0, 0, Width, Height); 

end;    

8. Почему некоторые компоненты типа TPanel и TEdit не имеют свойства Canvas?

Все наследники TCustomControl имеют Canvas, однако, в большинстве случаев это свойство объявлено protected для предотвращения рисования 'чужаками' на компоненте. Наследники компонента всегда могут получить доступ к унаследованным protected свойствам (типа Canvas), но пользователь компонента — никогда.  

type 

  TCanvasPanel = class(TPanel) 

  public 

    property Canvas; 

  end

Если вы хотите рисовать на компоненте, у которого нет public свойства Canvas, то используйте, например, компонент TPaintBox: положите его на панель TPanel, сделайте Align = Client и рисуйте на TPaintBox.Canvas.

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); 

  Label1.Caption := 'Line ' + IntToStr(LineNum + 1) 

  Lebel2.Caption := 'Position ' + IntToStr(Memo1.SelStart - CharsBeforeLine + 1); 

end;

14. Постранична прокрутка TMemo, реализация Undo и определение строки курсора.

Как прокрутить содержимое компонента TMemo?

Приведенная ниже процедура предполагает, что фокус находится на Edit1 и осуществляет прокрутку в соответствии с нажатыми клавишами.  

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 

begin 

  if Key = VK_F8 then 

    SendMessage(Memo1.Handle,  { HWND для Memo } 

                WM_VSCROLL,    { сообщение Windows } 

                SB_PAGEDOWN,   { на страницу вниз } 

                0)             { не используется } 

  else if Key = VK_F7 then SendMessage(Memo1.Handle, WM_VSCROLL, SB_PAGEUP, 0); 

end;

Если определено всплывающее (popup) меню для TMemo,и заданы клавиши для операций Cut, Copy, Paste, то я могу обрабатывать эти события, вызывая методы CutToClipboard, CopyToClipboard, и т.д. Однако, если я поместили пункт Undo в меню (обычно Ctrl+Z), то как дать знать TMemo, что нужно выполнить Undo?