![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вывод текста в собственном компоненте [D7, WinXP]
Max_005 © (2005-04-18 12:43:00)Пишу компонент. Приведу часть его кода:
type
TMyComp = class(TGraphicControl)
private
function GetCanvas: TCanvas;
...
protected
procedure Paint; override;
...
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Canvas: TCanvas read GetCanvas;
...
function TMSSkinUltraMenu.DestRect: TRect;
var
w, h, cw, ch: Integer;
xyaspect: Double;
begin
if FShowPictute = shwPictureUp then
begin
w := PictureUp.Width;
h := PictureUp.Height;
end;
if FShowPictute = shwPictureMove then
begin
w := PictureMove.Width;
h := PictureMove.Height;
end;
cw := ClientWidth;
ch := ClientHeight;
if Stretch or (Proportional and ((w > cw) or (h > ch))) then
begin
if Proportional and (w > 0) and (h > 0) then
begin
xyaspect := w / h;
if w > h then
begin
w := cw;
h := Trunc(cw / xyaspect);
if h > ch then // woops, too big
begin
h := ch;
w := Trunc(ch * xyaspect);
end;
end
else
begin
h := ch;
w := Trunc(ch * xyaspect);
if w > cw then // woops, too big
begin
w := cw;
h := Trunc(cw / xyaspect);
end;
end;
end
else
begin
w := cw;
h := ch;
end;
end;
with Result do
begin
Left := 0;
Top := 0;
Right := w;
Bottom := h;
end;
if Center then
OffsetRect(Result, (cw - w) div 2, (ch - h) div 2);
end;
procedure TMyComp.Paint;
var
Save: Boolean;
begin
if csDesigning in ComponentState then
with inherited Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
Save := FDrawing;
FDrawing := True;
try
with inherited Canvas do
begin
if FShowPictute = shwPictureUp then
begin
StretchDraw(DestRect, PictureUp.Graphic);
end;
if FShowPictute = shwPictureMove then
begin
StretchDraw(DestRect, PictureMove.Graphic);
end;
end;
finally
FDrawing := Save;
end;
end;
function TMyComp.GetCanvas: TCanvas;
var
Bitmap: TBitmap;
begin
if FShowPictute = shwPictureUp then
begin
if PictureUp.Graphic = nil then
begin
Bitmap := TBitmap.Create;
try
Bitmap.Width := Width;
Bitmap.Height := Height;
PictureUp.Graphic := Bitmap;
finally
Bitmap.Free;
end;
end;
if PictureUp.Graphic is TBitmap then
Result := TBitmap(PictureUp.Graphic).Canvas
else
raise EInvalidOperation.Create(SImageCanvasNeedsBitmap);
end;
if FShowPictute = shwPictureMove then
begin
if PictureMove.Graphic = nil then
begin
Bitmap := TBitmap.Create;
try
Bitmap.Width := Width;
Bitmap.Height := Height;
PictureMove.Graphic := Bitmap;
finally
Bitmap.Free;
end;
end;
if PictureMove.Graphic is TBitmap then
Result := TBitmap(PictureMove.Graphic).Canvas
else
raise EInvalidOperation.Create(SImageCanvasNeedsBitmap);
end;
end;
Но у меня есть одна небольшая загвоздка... Как мне вывести текст в этом компоненте? И чтобы сам текст, цвет, шрифт текста задавались в свойствах? Помогите пожалуйста. Я в процедуре Paintнаписал:
Canvas.Font:=Font;
Canvas.TextOut(Round((Width-Canvas.TextWidth(Caption))/2), Round((Height-Canvas.TextHeight(Caption))/2), Caption);
Но фон текста белый и перекрывает все... а еще он не по середине...
Max_005 (2005-05-24 18:30:00) [1]
type
TYzTextImage = class(TGraphicControl)
private
FPicture: TPicture;
procedure SetPicture(const Value: TPicture);
procedure PictureChanged(Sender: TObject);
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Font;
property ParentFont;
property Picture: TPicture read FPicture write SetPicture;
property Text;
end;
TYzDoubleTextImage = class(TCustomControl)
private
FUpTextImage: TYzTextImage;
FMoveTextImage: TYzTextImage;
procedure SetUpTextImage(const Value: TYzTextImage);
procedure SetMoveTextImage(const Value: TYzTextImage);
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
protected
procedure WMMouseDown(var Message: TMessage); message WM_MOUSEDOWN;
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property UpTextImage: TYzTextImage read FUpTextImage write SetUpTextImage;
property MoveTextImage: TYzTextImage read FMoveTextImage write SetMoveTextImage;
end;
implementation
....
procedure TYzDoubleTextImage.WMMouseDown(var Message: TMessage);
begin
inherited;
//какие-то действия
end;
Можно наверно так сделать... Но как мне тогда определить какая кнопка мыши была нажата, а еще позицию курсора(X, Y) в событии WMMouseDown?
Max_005 (2005-05-23 13:43:00) [2]:(((
Max_005 (2005-05-23 00:30:00) [3]Так нельзя сделать? :(
Max_005 (2005-05-22 22:14:00) [4]Я бы сделал это в TYzTextImage, но тут есть два но... Popup-то лучше наверно в TYzDoubleTextImage выставлять в свойствах... А еще TYzTextImag-и меняются постоянно, при наведении курсора... Я все же думаю лучше какнибудь сделать MouseUp в TYzDoubleTextImage, только вот как не знаю...:(
Max_005 (2005-05-22 21:38:00) [5]Я просто хочу сделать чтобы меню еще расскрывалось нажатием левой кнопкой мыши... Вот мне и нужно событие MouseUp в TYzDoubleTextImage, чтобы расскрывался Popup...
Max_005 (2005-05-22 19:01:00) [6]Я уже думал над этим... Не очень хотелось бы так делать... А как можно передать событие MouseUp по TYzTextImage в TYzDoubleTextImage? Сообщением? Или как-то попроще можно?
Юрий Зотов (2005-05-22 18:54:00) [7]> Max_005 (21.05.05 23:58) [41]
> Такое ощущение что курсор нажимается по TYzTextImage а не по
> TYzDoubleTextImage.
Так оно и есть - ведь клик действительно происходит по TYzTextImage.
> Что делать?
То же самое - заместить метод MouseUp. Но в классе TYzTextImage, а не в TYzDoubleTextImage.
Max_005 (2005-05-22 15:11:00) [8]Подскажите пожалуйста, что я опять неправильно делаю?
Max_005 (2005-05-21 23:58:00) [9]У меня опять проблема возникла...:( В TYzDoubleTextImageнадо чтобы на событие MouseUp делалось определенное действие, делаю так:
type
TYzDoubleTextImage = class(TCustomControl)
...
protected
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
...
procedure TMSCustomSkinMainMenu.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
...
inherited;
end;
Компилится все нормально. Но на это событие ничего не происходит(в самом компоненте)... Такое ощущение что курсор нажимается по TYzTextImage а не по TYzDoubleTextImage. Что делать?
Юрий Зотов (2005-05-21 18:00:00) [10]> Max_005 (21.05.05 17:39) [37]
Не включит. Delphi имеет интеллектуальный линковщик и код, который в программе не используется, в нее и не включается.
Ваши слова будут справедливы в случае, когда модуль содержит ссылки на файлы ресурсов или код в секциях initialization и finalization. Такие ресурсы и код (а также все, что из этого кода вызывается) включаются в программу вместе с самим модулем.
Просто Джо (2005-05-21 17:59:00) [11]
> Когда программа компилируется из модулей берется только
> нужная часть,
Да, это свойство компиляторов Паскаля.
Max_005 (2005-05-21 17:51:00) [12]Или тут все по умному сделано... Когда программа компилируется из модулей берется только нужная часть, а остальная как бы откидывается...
Max_005 (2005-05-21 17:39:00) [13]Вот например, в одном модуле будет много компонентов... А какаянибудь программа будет использовать только один компонент из этого модуля... Она ведь включит в программу весь модуль, и там будут ненужные компоненты... Ведь так? А можно сделать каждый компонент в своем модуле... Подключится модуль этого компонента, и все ничего лишнего...:)
Юрий Зотов (2005-05-21 16:51:00) [14]Купили - это, конечно, хорошо - но все же недостаточно. Ее ведь еще и прочитать нужно. И даже не просто прочитать, а разобраться.
По редакторам свойств - см. раздел 11.1. Какое имя давать классу редактора и нужен ли он вообще - это в 11.1.5. Просто разберитесь с параметрами RegisterPropertyEditor - какой за что отвечает, каким он может быть и что при этом произойдет.
По поводу "Мне кажется программа будет меньше места занимать" - а почему Вам так кажется? Какие есть соображения?
Max_005 (2005-05-21 16:31:00) [15]Юрий Зотов Я купил книгу Фаронова... Все же нужна эта помощь... Я думаю это последний мой вопрос по этой теме :)
Юрий Зотов (2005-05-21 16:18:00) [16]> Max_005 (21.05.05 15:22) [33]
Очень рекомендую:
http://www.findbook.ru/search/d0?ptype=1&pvalue=%C8%F1%EA%F3%F1%F1%F2%E2%EE+%F1%EE%E7%E4%E0%ED%E8%FF+%EA%EE%EC%EF%EE%ED%E5%ED%F2%EE%E2+Delphi&r=0&s=1&viewsize=15&startidx=0
или
http://www.findbook.ru/search/d0?ptype=1&pvalue=%D1%EE%E7%E4%E0%ED%E8%E5+%EA%EE%EC%EF%EE%ED%E5%ED%F2%EE%E2+%E2+%F1%F0%E5%E4%E5+Delphi&r=0&s=1&viewsize=15&startidx=0
А то мы уже тут букварем начинаем заниматься. Форумы все же не для этого.
Max_005 (2005-05-21 15:22:00) [17]Понятно... А тип TInternalSubComponentPropertyв других компонентах тоже так называть или нельзя одинаковые типы делать и надо называть подругому? И еще вот что... Как думаешь может лучше будет сделать вот как: тип TYzTextImageсделать в отдельном модуле, а другие компоненты которые его используют делать тоже в других модулях... т.е. один компонент один модуль... Мне кажется программа будет меньше места занимать...
Юрий Зотов (2005-05-20 23:54:00) [18]> Max_005 (20.05.05 23:02) [31]
Не всегда. Это зависит от того, что мы хотим получить. В большинстве случаев вполне подходят стандартные редакторы свойств, которые подключаются автоматически. Но если нам по каким-причинам требуется изменить отображение свойства и/или способ его редактирования, то нужно писать и регистрировать свой редактор (как в данном случае).
Max_005 (2005-05-20 23:02:00) [19]Значит когда какой-то компонент содержится в каком-то свойстве другого компонента... Надо так делать... Я правильно понял? :)
Юрий Зотов (2005-05-20 21:51:00) [20]Да, они.