Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2018.09.16;
Скачать: [xml.tar.bz2];

Вниз

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

 
Денис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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.002 c
11-1267379542
tippa
2010-02-28 20:52
2018.09.16
в Memo влазит только 29998 байт текста


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


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


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


2-1470299345
novichoks
2016-08-04 11:29
2018.09.16
StretchBlt





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский