Цель: получить прозрачный контрол(кнопку), который бы получал фокус, но на нем можно было рисовать что угодно.
Делаю наследника от TCustomControl. В CreateParam назначаю стиль WS_EX_TRANSPARENT:
TBlnOptionButton = class(TCustomControl)
...
protected
procedure CreateParams(var Params: TCreateParams); override;
...
end;
procedure TBlnOptionButton.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
ExStyle:=ExStyle+WS_EX_TRANSPARENT;
end;
end;
далее отлавливаю сообщение WM_ERASEBKGROUND чтобы очистить фон.
procedure TBlnOptionButton.WMEraseBkgnd(var Msg: TWMEraseBkgnd);
begin
Msg.Result := 1; // Prevent background from getting erased
end;
Рисую на холсте, когда где что надо. Все ок, НО!!! Есить пара проблем
1. если я вывожу на Canvas прозрачную(не только по краям, но и в середине) картинку методом Draw, то при выводе надписи через API-функцию DrawText
DrawText(Canvas.Handle, CString, -1, TextBounds,
DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS);
после нажатия щелчка на контрол остаются грязь. То есть при назатии на кнопку ее текст немного вдавливается(отрисовывается со смещение), и после этого грязь не убирается. Пробовал чистить Canvas через FillRect ниче не помогает.
2. При смене фокуса как честный програмер прорисовываю фокусную рамку обычными функциями LineTo с режимом пера pmNotXor:
if Self.Focused then
begin
Canvas.Brush.Style:=bsClear;
Canvas.Pen.Mode:=aPenMode;
Canvas.Pen.Style:=psDot;
Canvas.Pen.Color:=Self.Color;
r:=Rect(TextLSpacing-3, TextTSpacing-3, Width-1, Height-1);
Canvas.MoveTo(r.Left, r.Top);
Canvas.LineTo(r.Right, r.Top);
Canvas.LineTo(r.Right, r.Bottom);
Canvas.LineTo(r.Left, r.Bottom);
Canvas.LineTo(r.Left, r.Top);
end
проблема в том что фокусная рамка убирается не при потере фокуса, а при получении следующего фокуса. То есть на четный раз рамка стирается, а на нечетный появляется. Что за ерунда?