Форум: "Начинающим";
Текущий архив: 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