Question

I am running inside a process where COMCTL32.DLL is loaded twice, once with the version 5.82.7601.17514 and once with the version 6.10.7601.17514. The legacy version is loaded by some legacy DLL the program is linked with, and the other version is loaded by a newer DLL.

If I use GetModuleHandle (L"COMCTL32.DLL") I have no control over the DLL which gets resolved.

When I call GetProcAddress to reach, for instance, TaskDialogIndirect, I get a null pointer back, which is certainly because I got back the handle of the legacy DLL.

So, is there some means of getting to the address of, say TaskDialogIndirect when both DLLs are loaded.

If not, can I somehow make sure that the process loads the 6.10 version and not the 5.82, in the hope that our legacy DLL will work fine with the newer version of COMCTL32?

Était-ce utile?

La solution

I guess you are having to use GetProcAddress() rather than implicit linking because you want your app to run on XP where task dialog is not available.

I can see three options for you:

  1. Use implicit linking, but use delay loading as supported by the MS tool chain. I'm not 100% certain that will give you the correct comctl32 but it's worth a try.
  2. Use the activation context API to make sure that the comctl32 v6 manifest is in play when you call LoadLibrary(). Call LoadLibrary() rather than GetModuleHandle() to make sure that you get the manifest magic.
  3. Enumerate all the modules in the process and select the correct version of comctl32. There is a comprehensive example of how to do this on MSDN.

The activation context approach is the cleanest solution, but the activation context API can be tricky to get into. I personally have used it to ensure that an Excel COM add-in links to comctl32 v6.

The module enumeration approach is quick to implement, somewhat dirty, but will work well.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top