On Mon, 01 May 2006 20:51:35 +0200, "Alf P. Steinbach"
<alfps@start.no> wrote:
[color=blue]
>* Lucian Wischik:[color=green]
>> Grzegorz Wróbel </dev/null@localhost.localdomain> wrote:[color=darkred]
>>> HRSRC hres;
>>> HGLOBAL hglob;
>>> void* p;
>>> hres = FindResource(GetModuleHandle(NULL),id,type);
>>> hglob = LoadResource(GetModuleHandle(NULL),hres);
>>> p = LockResource(hglob);
>>> FreeResource(hRes);[/color]
>>
>> You're not meant to use FreeResource. It does nothing. So just
>>
>> HRSRC hres = FindResource(hInstance,id,type);
>> hglob = LoadResource(hInstance,hres);
>> void *p = LockResource(hglob)
>>
>> and no need to free anything. I actually find these three lines rather
>> beautiful, clean, understandable and easy! Alf, in your quest to make
>> a framework/wrapper, I think that these three should be at the BOTTOM
>> of your priority list.[/color]
>
>Perhaps. But add error checking and MAKEINTRESOURCE calls (converting
>integers to kludgeon pointers). However, wrapping these three calls in a
>single function is not a big deal; the problem lies not with
>encapsulating the three calls above in a single function, i.e. not with
>the procedural aspect, but with representing id+type as a cohesive unit
>that can be safely passed around and that centralizes the
>MAKEINTRESOURCE calls, perhaps also dealing with type safety of
>resources, while not needlessly sacrificing efficiency.
>
>At the lowest level, tackling just the kludgeon representation, I'm
>thinking something like
>
> // The intent of this class is to provide safety & clarity
> // (especially wrt. string lifetime), while preserving efficiency
> // for integer atom-like names.
> class AtomLikeName
> {
> private:
> std::wstring myIdentifier;
> unsigned short myIntValue;
>
> public:
> AtomLikeName( std::wstring const& value )
> : myIdentifier( value )
> , myIntValue( 0 )
> {
> assert( myIdentifier.length() > 0 );
> }
>
> AtomLikeName( unsigned short value, bool isAtom = false )
> : myIntValue( value )
> {
> assert( 0 < myIntValue );
> assert( myIntValue <= (isAtom? 0xBFFF : 0x7FFF) );
> }
>
> bool isPseudoPointer() const { return (myIntValue != 0); }
>
> // Can be a pseudo-pointer:
> wchar_t const* value() const
> {
> return (isPseudoPointer()?
> MAKEINTRESOURCE( myIntValue ) : myIdentifier.c_str()
> );
> }
>
> // Comparision operations can be defined in terms of asString().
> std::wstring asString() const
> {
> return (isPseudoPointer()?
> L"#" + stringFrom( myIntValue ) : myIdentifier
> );
> }
> };
>
>Then an id+type+(possible language)+(more remotely possible file spec)
>can be added on top.[/color]
Don't forget that resources in Windows can be created on the fly. They
don't have to be embedded in the executable or a DLL, although that is
a popular alternative.
Just an idea I have been playing with:
One could have a factory class for each kind of resource and let the
factory be a template taking a parameter of different kinds of
resource managers. In the debugging phase, for example, resource data
could be kept in a configuration file (e.g. XML, or even an INI file)
which would be read by the resource manager as text. The binary
resource would be created on the fly by the resource manager. Slow, of
course, but a whole lot easier to edit during development. No
recompiling, no linking, just edit the configuration and run.
Once everything is satisfactory, the configuration file could be
parsed and compiled as a RES file by an external tool and linked to
the executable. The template resource manager used for debugging would
be swapped for one that loads resources the "normal" way.
I believe this is similar to how some GUI libraries manage resources
on Linux, isn't it?
--
Bob Hairgrove
NoSpamPlease@Home.com