Board index » cppbuilder » resources in a component

resources in a component


2005-08-20 04:31:44 PM
cppbuilder46
Hi to everybody
how can I insert more resources bitmap (or string) in a component then
accessible both to at designtime and at runtime?
the instruction:
Bitmap1->LoadFromResourceName((int)HInstance, "BM1");
load the bitmap from a reource's file at designtime but at runtime it don't
work cause the resource is linked in the *.bpl file but not in *.exe file
compilated after the component is inserted in the form;
How solve the problem ?
thanks
Roberto
 
 

Re:resources in a component

"rghinami" < XXXX@XXXXX.COM >wrote in message
Quote
Bitmap1->LoadFromResourceName((int)HInstance, "BM1");

load the bitmap from a reource's file at designtime but at runtime it
don't work cause the resource is linked in the *.bpl file but not in
*.exe file compilated after the component is inserted in the form;
You need to give the component's package its own resource file, and then use
FindClassHInstance() instead of HInstance.
Gambit
 

Re:resources in a component

----- Original Message -----
From: "Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >
Newsgroups: borland.public.cppbuilder.vcl.components.writing
Sent: Monday, August 22, 2005 8:29 PM
Subject: Re: resources in a component
Quote

"rghinami" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>Bitmap1->LoadFromResourceName((int)HInstance, "BM1");
>
>load the bitmap from a reource's file at designtime but at runtime it
>don't work cause the resource is linked in the *.bpl file but not in
>*.exe file compilated after the component is inserted in the form;

You need to give the component's package its own resource file, and then
use
FindClassHInstance() instead of HInstance.


Gambit


Thanks for your answer,
i have not made sense of well probably,
the application of the resources must be served as the inside of the
component;
after your suggestion I have tried this code:
***********
// in the constructor of new component aggregate
int Hi = 0;
Hi = FindClassHInstance(this->ClassType());
if (Hi){
Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
Bitmap1->LoadFromResourceName(Hi , "BM1");
ImgList->Add(Bitmap1, NULL);
Bitmap1->LoadFromResourceName(Hi , "BM2");
ImgList->Add(Bitmap1, NULL);
delete Bitmap1;
}
**********
also so it works when the component is inserted in the form at designtime
but it don't works at runtime:
i think this because the resources inserted in *. bpl file are not then
connected to the executable;
I found a solution, it works but i don't like a lot it:
*************
// in the constructor of new component aggregate
int LibHandle = 0;
LibHandle = (int) LoadLibrary("Pack_Aggregate.bpl"); // name of
*.bpl file
if (LibHandle){
Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
Bitmap1->LoadFromResourceName(LibHandle , "BM1");
ImgList->Add(Bitmap1, NULL);
Bitmap1->LoadFromResourceName(LibHandle , "BM2");
ImgList->Add(Bitmap1, NULL);
delete Bitmap1;
FreeLibrary( (HMODULE) LibHandle);
}
*********
thaks for yours further suggestions
Roberto
 

{smallsort}

Re:resources in a component

"rghinami" < XXXX@XXXXX.COM >wrote in message
Quote
after your suggestion I have tried this code:
***********
// in the constructor of new component aggregate


Hi = FindClassHInstance(this->ClassType());
Try using the __classid operator instead:
Hi = FindClassHInstance(__classid(TWhateverYourClassNameIs));
Quote
also so it works when the component is inserted in the form
at designtime but it don't works at runtime:
Just saying it doesn't work says nothing about the actual problem you are
having. Always provide specific details.
Works fine whenever I use it.
Quote
i think this because the resources inserted in *. bpl file are not
then connected to the executable;
The global HInstance variable points to the instance of the main EXE file.
If you have runtime packages enabled (and why would you? that makes it a
little bit harder to distribute your applications), then the images are
going to be part of the compiled BPL file, not the EXE. That is why you
have to use FindClassHInstance(). It returns the HINSTANCE of the BPL that
the component belongs to. Since the package is already loaded in memory by
the time your component is being instantiated, the HINSTANCE that
FindClassHInstance() returns will be valid when calling one of the
LoadFromResource...() functions.
Gambit
 

Re:resources in a component

Quote
>Hi = FindClassHInstance(this->ClassType());

Try using the __classid operator instead:

Hi = FindClassHInstance(__classid(TWhateverYourClassNameIs));

i tried:
long Hi;
Hi = FindClassHInstance(__classid(TAggregati));
if (Hi){
Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
Bitmap1->LoadFromResourceName(Hi , "BM1");
................
}
long Hi = FindClassHInstance(__classid(TAggregate));
after creating the package (*.bpl) and introducing in a Form the TAggregate
component to test it, it will work.
But after compilating the *.exe, the debug will stop the executable and will
report this message:
"Project Test_Aggregate.exe raised exception class EResNotFound with
message 'Resource BM1 not found'. "
Adding the resource file of the package in the project Test_Aggregate.exe,
it does work, but i don't think this is the right solution.
further suggestions ?
thanks
 

Re:resources in a component

"rghinami" < XXXX@XXXXX.COM >wrote in message
Quote
after creating the package (*.bpl) and introducing in a Form
the TAggregate component to test it, it will work. But after
compilating the *.exe, the debug will stop the executable and
will report this message:

"Project Test_Aggregate.exe raised exception class
EResNotFound with message 'Resource BM1 not found'. "
You never explained exactly how you are setting up the resources in the
first place.
I use FindClassHInstance() in my own packages, so I know it works.
Gambit
 

Re:resources in a component

Hi,
I use PE Resource Explorer by Colin Wilson to check what resources an
executable or a package actually contains. It helped me a lot when I had
similar problems to yours.
Maybe you find it useful:
www.wilsonc.demon.co.uk/d7resourceexplorer.htm
Also, I remember that I used the #pragma statement in the .cpp to bind the
resource file, like:
#pragma "MyResources.res"
Not sure if this helps in your case, though.
Nick
Quote
>>Hi = FindClassHInstance(this->ClassType());
>
>Try using the __classid operator instead:
>
>Hi = FindClassHInstance(__classid(TWhateverYourClassNameIs));
>
i tried:
long Hi;
Hi = FindClassHInstance(__classid(TAggregati));
if (Hi){
Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
Bitmap1->LoadFromResourceName(Hi , "BM1");
................
}
long Hi = FindClassHInstance(__classid(TAggregate));

after creating the package (*.bpl) and introducing in a Form the
TAggregate component to test it, it will work.
But after compilating the *.exe, the debug will stop the executable and
will report this message:

"Project Test_Aggregate.exe raised exception class EResNotFound with
message 'Resource BM1 not found'. "

Adding the resource file of the package in the project Test_Aggregate.exe,
it does work, but i don't think this is the right solution.

further suggestions ?

thanks







 

Re:resources in a component

sorry that should have been:
#pragma resource "MyResource.res"
Nick
 

Re:resources in a component

Quote

I use FindClassHInstance() in my own packages, so I know it works.


Gambit


Hi
thanks for your answers;
I verified the instruction inserted in the component's constructor:
"Hi=FindClassHInstance(__classid(TAggregati));"
it gets the same result of : void * "HInstance" variable.
therefore it is indifferent to use either this or the other one;
The real question is:
a) the resources are correctly linked in the *.bpl package: I have checked
the DLL file "Pack_Aggregate.bpl" with "PE resources explorer" (thanks
Nick): it contains the bitmaps, it's all good!
b) but then using the component in a project, the resources aren't linked
(by the compiler) in the *.exe;
c) as I already said, if the file of resources is also connected to the
project, everything works; but this seems to me like a "non solution";
Roberto
 

Re:resources in a component

Quote
Hi,

I use PE Resource Explorer by Colin Wilson to check what resources an
executable or a package actually contains. It helped me a lot when I had
similar problems to yours.

Maybe you find it useful:

Hi Nick
I used the old borland workshop,
but PE Resource Explorer seems to me excellent
Thanks
Roberto
 

Re:resources in a component

"rghinami" < XXXX@XXXXX.COM >wrote in message
Quote
I verified the instruction inserted in the component's constructor:

"Hi=FindClassHInstance(__classid(TAggregati));"

it gets the same result of : void * "HInstance" variable.

therefore it is indifferent to use either this or the other one;
Yes, there is a big difference between them. The HInstance variable is
always the compiled module that the code belongs to. For an application,
that is the EXE file. For a DLL, that is the DLL file.
FindClassHInstance(), on the other hand, returns the instance of the
library/module that contains the specified class. For FindClassHInstance()
to return the same value as the HInstance variable, the class would have to
be compiled into the same module that owns the HInstance value. This
becomes more important when runtime packages are being used. Calling
FindClassHInstance() in an EXE that has runtime packages enabled, specifying
a class that is contained in a package, will return a value that is
different than the EXE's HInstance value.
Quote
b) but then using the component in a project, the resources aren't linked
(by the compiler) in the *.exe;
They will not be if you have runtime packages enabled. They will remain in
the BPL file. That is why you need to use FindClassHInstance() instead of
the HInstance variable.
Gambit