What’s the difference between FreeResource and, say, DestroyAcceleratorTable


MaxMax asks a number of resource-related questions, starting with "How do you Unlock a Lock­Resource?" and culminating in "What are the differences between Free­Resource and Destroy­Accelerator­Table, Destroy­Object, etc.? It would be much easier to use a single function instead of a collection of five."

It helps if you understand the history of resources, because the functions were designed back when resources were managed very differently from how they are today. The usage pattern is still the same:

  • Find­Resource
  • Load­Resource
  • Lock­Resource
  • use the resource
  • Unlock­Resource
  • Free­Resource

You unlock a resource by calling, um, Unlock­Resource.

Although the usage pattern is the same, the mechanism under the covers is completely different. In 16-bit Windows, loading a resource entailed allocating a chunk of memory, then filling that memory block from the disk image. In Win32, resources are mapped into the address space as part of the image; there is no memory allocation and no explicit loading.

The next thing to understand is that resources are just blobs of binary data. They are not live objects. It's not like there's a HBITMAP sitting in there just waiting to be found.

Think of resource data as a set of blueprints. If you call Find­Resource + Load­Resource + Lock­Resource, you wind up with the blueprints for a radio, but that's not the same as actually having a radio. To do that, you need to hand the radio blueprints to somebody who knows how to read electronic schematic diagrams and who knows how to solder wires together in order to convert the potential radio into an actual radio.

If you've been following the sporadic series on the format of resources, you'll know that these schematic diagrams can often be quite complicated. The Load­Bitmap function first does the Find­Resource + Load­Resource + Lock­Resource dance to locate the bitmap blueprint, but then it needs to actually make the bitmap, which is done by parsing the raw resource data and trying to make sense of it, calling functions like Create­Bitmap and Set­DI­Bits to convert the blueprint into an actual bitmap.

That's why, if you use these helper functions like Load­Accelerators to convert the blueprint into an object, you need to use the corresponding cleanup function like Destroy­Accelerator­Table when you want to destroy the object. You have to use the correct cleanup function, of course. You can't destroy a bitmap with Destroy­Accelerator­Table any more than you can put a radio in the clothing drop bin.

Just like when the radio guy returns the original blueprints plus a brand new radio, you return the blueprints to the library, but if you want to destroy the radio, you have to take it to the electronics recycling facility.

Comments (5)
  1. JS Bangs says:

    Tortured analogies are my favorite part of the Old New Thing.

  2. laonianren says:

    "Frameworks"

    I used to go to the council tip and I'd have to sort my rubbish into the appropriate bins.  Now I hire a skip and let the skip man worry about it.  It's more expensive but it saves me a lot of time.

  3. David Walker says:

    I usually hate analogies, but these are not too bad.  On the other hand, a friend of mine says "Don't tell me what something is LIKE, tell me what it IS!".

    And besides, what's wrong with dropping a radio into the clothing drop bin?  Someone looking for clothing will end up with a new radio!  I hope it has tubes.

  4. Ben Voigt [Visual C++ MVP] says:

    According to MSDN, you can't unlock/unload/free a resource directly (although it may disappear when you call FreeLibrary).  Of course Raymond is right that the objects reconstituted from the resource data should be properly cleaned up.

  5. Henning Makholm says:

    @Ben: And yet the Windows SDK defines UnlockResource and FreeResource as no-ops for the benefit of old code from back in time when you could unlock and free them. UnlockResource is a do-nothing macro, but FreeResource is an actual Kernel32 entry point (documented to do nothing). Perhaps it did something in Win32s?

Comments are closed.