Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2018.09.16;
Скачать: CL | DM;

Вниз

Инициализация значений компонента   Найти похожие ветки 

 
Денис11998833   (2016-08-06 15:20) [0]

Сделал компонент, наследник от TImage. Если максимально упростить описание, то хочу чтобы, в TPicture грузилась картинка из ресурса при создании компонента, в runtime. Наследник сделан, свойство с именем ресурса добавлено, добавлен метод который загружает ресурс в TPicture. Положил на форму компонент, дёргаю вручную новый метод картинка грузится, всё хорошо.

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


 
Kilkennycat ©   (2016-08-07 01:22) [1]


> Добавил вызов загрузки ресурса в конец конструктора, ничего
> не вышло

И никакой ошибки не сказало? А репаинт\рефреш\инвалидате - че-нить из этого (не помню что в делфи перерисовывает) потом вызывается?


 
Германн ©   (2016-08-07 01:59) [2]


>
> Денис11998833   (06.08.16 15:20)
>
> Сделал компонент, наследник от TImage.

Ну ты хотя бы хоть какой-нибудь код привел.


 
ВладОшин ©   (2016-08-07 10:01) [3]

все должно работать, может с ресурсом намудрил, не там ищет


 
iop ©   (2016-08-07 10:44) [4]

Добавил вызов загрузки ресурса в конец конструктора

твоя картинка загруженная в конструкторе убивается в в унаследованном loaded.
если ты ее вообще в конструкторе верно загрузил.

зачем-то


 
iop ©   (2016-08-07 10:48) [5]

кроме того, у тебя наверняка есть паблишед свойство в котором лежит имя ресурса картинки.

так вот в конструкторе ты его значения не узнаешь. оно там еще пустое.


 
Денис11998833   (2016-08-08 11:17) [6]

> И никакой ошибки не сказало? А репаинт\рефреш\инвалидате - че-нить из этого (не помню что в делфи перерисовывает) потом вызывается?

Ошибки никакой. Отладчиком увидел, что свойства с именем ресурса пустые в момент вызова конструктора компонента.

> все должно работать, может с ресурсом намудрил, не там ищет

Вручную дёргаю метод ApplyCaption в OnCreate формы, всё норм, картинки грузятся, всё хорошо.

> так вот в конструкторе ты его значения не узнаешь. оно там еще пустое.

Судя по всему в этом и проблема, только как  решить не знаю. Поясните пож, почему оно пустое? Я понимаю, что в designtime, когда только кидаешь компонент на форму, все свойства заданы по умолчанию. А что происходит в Runtime когда программа создаёт мой компонент, не совсем ясно. Я думал, что когда в рантайме вызывается конструктор компоненты, паблишед свойства уже инициализированы значениями которые я прописал в дезайнтайме. Оказалось всё не так.

> Ну ты хотя бы хоть какой-нибудь код привел.

Не хотелось заграмождать пост, думал истинна проста и где то рядом). Вот собсно весь код компонента:


 
Денис11998833   (2016-08-08 11:18) [7]

> И никакой ошибки не сказало? А репаинт\рефреш\инвалидате - че-нить из этого (не помню что в делфи перерисовывает) потом вызывается?

Ошибки никакой. Отладчиком увидел, что свойства с именем ресурса пустые в момент вызова конструктора компонента.

> все должно работать, может с ресурсом намудрил, не там ищет

Вручную дёргаю метод ApplyCaption в OnCreate формы, всё норм, картинки грузятся, всё хорошо.

> так вот в конструкторе ты его значения не узнаешь. оно там еще пустое.

Судя по всему в этом и проблема, только как  решить не знаю. Поясните пож, почему оно пустое? Я понимаю, что в designtime, когда только кидаешь компонент на форму, все свойства заданы по умолчанию. А что происходит в Runtime когда программа создаёт мой компонент, не совсем ясно. Я думал, что когда в рантайме вызывается конструктор компоненты, паблишед свойства уже инициализированы значениями которые я прописал в дезайнтайме. Оказалось всё не так.

> Ну ты хотя бы хоть какой-нибудь код привел.

Не хотелось заграмождать пост, думал истинна проста и где то рядом). Вот собсно весь код компонента:


unit uPngGraphicButton;

interface

uses ExtCtrls, Graphics, Classes, UITypes, Dialogs, PNGImage, GIFImg, JPEG,
Messages, Controls, SysUtils, Forms;

type
 TCaptionOffsets = class(TPersistent)
 private
   FOffsetNormalX: integer;
   FOffsetNormalY: integer;
   FOffsetDownX: integer;
   FOffsetDownY: integer;
 published
   property OffsetNormalX: integer read FOffsetNormalX write FOffsetNormalX default 0;
   property OffsetNormalY: integer read FOffsetNormalY write FOffsetNormalY default -1;
   property OffsetDownX: integer read FOffsetDownX write FOffsetDownX default 0;
   property OffsetDownY: integer read FOffsetDownY write FOffsetDownY default 0;
 end;

 TPNGGraphicButton = class(TImage)
 private
   FCaptionFont: TFont;
   //FCaptionOffsetX, FCaptionOffsetY: integer;
   FCaptionOffsets: TCaptionOffsets;
   FLoadFromResource: boolean;
   FResourceName: string;
   FResourceHandle: THandle;
   FCaption: string;
   FPictureNormal,
   FPictureHover,
   FPictureDown,
   FPictureNotActive: TPicture;
   procedure SetNormalPicture(Value: TPicture);
   procedure SetHoverPicture(Value: TPicture);
   procedure SetDownPicture(Value: TPicture);
   procedure SetNotActivePicture(Value: TPicture);
   procedure SetFont(const Value: TFont);
   procedure SetCaptionOffsets(const Value: TCaptionOffsets);
   procedure WriteText(WPicture: TPicture; DownImg: boolean);
   procedure LoadPngResource(ResName:string; Picture: TPicture);
 protected
   //procedure Paint; override;
   procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
     X, Y: Integer); override;
   procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
     X, Y: Integer); override;
   //procedure MouseEnter; override;
   procedure CMMouseEnter(var msg: TMessage);
       message CM_MOUSEENTER;
   procedure CMMouseLeave(var msg: TMessage);
       message CM_MOUSELEAVE;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   procedure ApplyCaption;
   procedure LoadAllResources;
 published
   property Caption: string read FCaption write FCaption;
   property CaptionOffsets: TCaptionOffsets read FCaptionOffsets write SetCaptionOffsets;
   property Font: TFont read FCaptionFont write SetFont;
   property PictureNormal: TPicture read FPictureNormal write SetNormalPicture;
   property PictureHover: TPicture read FPictureHover write SetHoverPicture;
   property PictureDown: TPicture read FPictureDown write SetDownPicture;
   property PictureNotActive: TPicture read FPictureNotActive write SetNotActivePicture;
   property LoadFromResource: boolean read FLoadFromResource write FLoadFromResource default True;
   property ResourceName: string read FResourceName write FResourceName;
   property ResourceHandle: THandle read FResourceHandle write FResourceHandle;
 end;

procedure Register;

implementation

uses Windows, UxTheme;

procedure Register;
begin
 RegisterComponents("oTweak", [TPNGGraphicButton]);
end;

constructor TPNGGraphicButton.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FCaptionFont:=TFont.Create;
 FPictureNormal := TPicture.Create;
 FPictureHover := TPicture.Create;
 FPictureDown := TPicture.Create;
 FPictureNotActive := TPicture.Create;
 FCaptionOffsets:=TCaptionOffsets.Create;
 FLoadFromResource:=True;

 FCaptionFont.Name:="Segoe UI";
 FCaptionFont.Height:=-18;
 FCaptionFont.Color:=clWhite;

 FCaptionOffsets.OffsetNormalX:=0;
 FCaptionOffsets.OffsetNormalY:=-1;
 FCaptionOffsets.OffsetDownX:=0;
 FCaptionOffsets.OffsetDownY:=0;

 ApplyCaption;
end;

destructor TPNGGraphicButton.Destroy;
begin
 FCaptionFont.Free;
 FPictureNormal.Free;
 FPictureHover.Free;
 FPictureDown.Free;
 FPictureNotActive.Free;
 FCaptionOffsets.Free;
 inherited Destroy;
end;

procedure TPNGGraphicButton.ApplyCaption;
begin
 LoadAllResources;
 WriteText(PictureNormal, False);
 WriteText(PictureHover, False);
 WriteText(PictureDown, True);
 WriteText(PictureNotActive, False);
 Picture.Assign(PictureNormal);
end;

procedure TPNGGraphicButton.LoadAllResources;
begin
 if (FResourceName<>"") and (FLoadFromResource) then
 begin
   LoadPngResource(FResourceName+"_normal", FPictureNormal);
   LoadPngResource(FResourceName+"_hover", FPictureHover);
   LoadPngResource(FResourceName+"_down", FPictureDown);
   LoadPngResource(FResourceName+"_na", FPictureNotActive);
 end;
end;


 
Денис11998833   (2016-08-08 11:18) [8]


procedure TPNGGraphicButton.LoadPngResource(ResName:string; Picture: TPicture);
var
 MyPNG : TPNGImage;
 hLibRes: THandle;
begin
 if FResourceHandle<>0 then
   hLibRes:=FResourceHandle
 else
   hLibRes:=hInstance;

 if FindResource(hLibRes, PChar(ResName), RT_RCDATA)=0 then
 begin
   Exit;
 end;

 MyPNG := TPNGImage.Create;
 try
   MyPNG.LoadFromResourceName(hLibRes, ResName);
   Picture.Assign(MyPNG);
 finally
   MyPNG.Free;
 end;
end;

procedure TPNGGraphicButton.WriteText(WPicture: TPicture; DownImg: boolean);
var
 X, Y,
 OffsX,
 OffsY: integer;
begin
 if not Assigned(WPicture) then
   Exit;

 if FCaption="" then
   Exit;

 if (WPicture.Graphic is TPNGImage) and (not WPicture.Graphic.Empty)  then
   with ((WPicture.Graphic as TPNGImage)) do
   begin
     Canvas.Font.Assign(FCaptionFont);
     X:=Trunc(WPicture.Width/2-Canvas.TextWidth(FCaption)/2);
     Y:=Trunc(WPicture.Height/2-Canvas.TextHeight("A")/2);

     if DownImg then
     begin
       OffsX:=FCaptionOffsets.OffsetDownX;
       OffsY:=FCaptionOffsets.OffsetDownY;
     end else
     begin
       OffsX:=FCaptionOffsets.OffsetNormalX;
       OffsY:=FCaptionOffsets.OffsetNormalY;
     end;
     X:=X+OffsX;
     Y:=Y+OffsY;
     if X<0 then X:=0;
     if Y<0 then Y:=0;

     SetBkMode(Canvas.Handle, 1);
     Canvas.TextOut(X, Y, FCaption);
   end;
end;

procedure TPNGGraphicButton.SetNormalPicture(Value: TPicture);
begin
 if Assigned(Value) then
   FPictureNormal.Assign(Value);
end;

procedure TPNGGraphicButton.SetHoverPicture(Value: TPicture);
begin
 if Assigned(Value) then
   FPictureHover.Assign(Value);
end;

procedure TPNGGraphicButton.SetDownPicture(Value: TPicture);
begin
 if Assigned(Value) then
   FPictureDown.Assign(Value);
end;

procedure TPNGGraphicButton.SetNotActivePicture(Value: TPicture);
begin
 if Assigned(Value) then
   FPictureNotActive.Assign(Value);
end;

procedure TPNGGraphicButton.SetFont(const Value: TFont);
begin
 if Assigned(Value) then
   FCaptionFont.Assign(Value);
end;

procedure TPNGGraphicButton.SetCaptionOffsets(const Value: TCaptionOffsets);
begin
 if Assigned(Value) then
   FCaptionOffsets.Assign(Value);
end;

procedure TPNGGraphicButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
 { Your code }
 Picture.Assign(PictureDown);
 inherited MouseDown(Button, Shift, X, Y);
end;

procedure TPNGGraphicButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
 { Your code }
 Picture.Assign(PictureNormal);
 inherited MouseUp(Button, Shift, X, Y);
end;

procedure TPNGGraphicButton.CMMouseEnter(var msg: TMessage);
begin
 Picture.Assign(PictureHover);
 inherited;
end;

procedure TPNGGraphicButton.CMMouseLeave(var msg: TMessage);
begin
 Picture.Assign(PictureNormal);
 inherited;
end;

end.


 
iop ©   (2016-08-08 11:38) [9]

Поясните пож, почему оно пустое?

а почему оно должно быть в конструкторе НЕпустое?
по щщучьему велению чтоле?


 
Денис11998833   (2016-08-08 11:46) [10]

> а почему оно должно быть в конструкторе НЕпустое?

Подскажите где про это почитать.. Я нигде не нашёл чёткой последовательности, в какой момент создаётся компонент, как инициализируются его значения, в какой именно момент можно быть уверенным, что компонент полностью создан, установлены значения, которые я прописываю в дезайнтайме. То ли плохо искал, то ли действительно этой инфы очень мало..

Как всё таки в моём частном случае решить вопрос загрузки картинки при создании компонента?


 
iop ©   (2016-08-08 11:52) [11]

при создании ничего грузить не надо.

например во время работы приложения ты вызываешь конструктор.

в дизайне на форме никакого компанента не лежало.
никто ему не выставлял имени ресурса.
и какую картинку ты там собрался грузить при этом?


 
Денис11998833   (2016-08-08 13:09) [12]

> в дизайне на форме никакого компанента не лежало.

это я понимаю. ещё раз повторюсь, из прошлого поста:

> Я понимаю, что в designtime, когда только кидаешь компонент на форму, все свойства заданы по умолчанию. А что происходит в Runtime когда программа создаёт мой компонент, не совсем ясно.

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

Я говорю именно про вызов конструктора в рантайме, с дезайнтаймом всё понятно.


 
iop ©   (2016-08-08 13:16) [13]

в конструкторе паблишед свойства пустые дважды.
1. потому что компонент еще не читал дфм
2. потому что компонент может быть создан в рантайме (не лежал на форме в дизайне)

если он лежал на форме в дизайне и если в дизайне ему сказали имя ресурса, то имя это будет известно и доступно не раньше
procedure Loadded : virtual;


 
Денис11998833   (2016-08-08 13:36) [14]

>если он лежал на форме в дизайне и если в дизайне ему сказали имя ресурса, то имя это будет известно и доступно не раньше
> procedure Loadded : virtual;

Похоже это почти то что надо! А какого то события специального, на изменение значения Loaded не предусмотрено? Какой нибудь OnLoaded


 
iop ©   (2016-08-08 13:41) [15]

изменения значения лоадеда не происходит.
у него вообще нет значения.
это процедура.


 
Денис11998833   (2016-08-08 14:34) [16]

Короче запутался(.. Если всё таки вернуться к проблеме, куда нужно воткнуть мой LoadAllResources чтобы в runtime, подгружались картинки?


 
iop ©   (2016-08-08 15:04) [17]

втыкать надо в loaded;


 
Денис11998833   (2016-08-08 16:35) [18]

Спасибо добрый человек)!

Добавил:


 protected
   procedure Loaded; override;

procedure TPNGGraphicButton.Loaded;
begin
 inherited Loaded;
 ApplyCaption;
end;



И всё запело как надо)



Страницы: 1 вся ветка

Текущий архив: 2018.09.16;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.004 c
2-1470299345
novichoks
2016-08-04 11:29
2018.09.16
StretchBlt


11-1267379542
tippa
2010-02-28 20:52
2018.09.16
в Memo влазит только 29998 байт текста


2-1469453166
Raisa
2016-07-25 16:26
2018.09.16
POS Принтер


2-1470486053
Денис11998833
2016-08-06 15:20
2018.09.16
Инициализация значений компонента


15-1474880632
Кто б сомневался
2016-09-26 12:03
2018.09.16
Как принять сообщение с WhatsApp?