Dynamically load a Windows API function

Sometimes an API function is nice to have but will break compatibility with previous versions of Windows. It is possible to load functions dynamically.

For example, we will use the function SHDefExtractIconW. Using it will break Windows 2000 compatibility. Whether that is a problem I’ll leave that up to you.

The windows prototype for this function is:

HRESULT SHDefExtractIcon(
_In_ LPCTSTR pszIconFile,
int iIndex,
_In_ UINT uFlags,
_Out_opt_ HICON *phiconLarge,
_Out_opt_ HICON *phiconSmall,
UINT nIconSize
);

Most API functions use the calling definition __stdcall. Omitting this will lead to stack errors or malfunctioning functions. A variable of the function prototype must be made. It will have the following form:

HRESULT (__stdcall *SHDefExtractIcon)(
_In_ LPCTSTR pszIconFile,
int iIndex,
_In_ UINT uFlags,
_Out_opt_ HICON *phiconLarge,
_Out_opt_ HICON *phiconSmall,
UINT nIconSize
);

Note that the name SHDefExtractIcon is free to choose since this is just a variable declaration.

You can also remove the variable names, leaving them will make it somewhat self-documenting.

Now load the DLL using:

HMODULE module = LoadLibrary(L”shell32.dll”);

and the function using:

SHDefExtractIcon = ( HRESULT(__stdcall *)(LPCTSTR, int, UINT, HICON *, HICON *, UINT))
GetProcAddress(module,”SHDefExtractIconW”);

Here the variable names are removed for clarity. note that API functions accepting string arguments are often available in two variant e.g. MessageBoxA and MessageBoxW, you can use both. The compiler will create an define MessageBox to either one depending on the compiler setting, Multibyte (A) or Unicode(W).

GetProcAddress will return NULL if the function can not be found.

Now the functionn can be called:

(*SHDefExtractIcon)(L”c:\\Windows\\System32\\shell32.dll”, 0,0, &largeIcon, &smallIcon, MAKELPARAM(256, 0));

 

 

 

 

Lastest update in September 2017, inital post in September 2017

Write a comment

I appreciate comments, suggestions, compliments etc. Unfortunately I have no time to reply to them. Useful input will be used for sure!