Reputation: 61
I'm developing an applicaion for Windows 7 with VisualStudio2017. This application wants to have special cursors which are loaded from a DLL. So first I created a DLL and added the following .rc file:
BM_CURSOR_GRAB CURSOR "./grab.cur"
BM_CURSOR_GRABBING CURSOR "./grabbing.cur"
BM_CURSOR_GRAB and BM_CURSOR_GRABBING are defined in a header file as:
#define BM_CURSOR_GRAB 100
#define BM_CURSOR_GRABBING 101
I compile the DLL - that works and check it with ResourceEditor.exe
My resources are included:
Now the "non working" part starts. My application wants to load the cursor, but FindResource
doesn't find it. Here is my code:
HMODULE dll = LoadLibrary("BenjaMiniRessources.dll");
HRSRC hRes = FindResource(dll, MAKEINTRESOURCE(100), RT_CURSOR);
DWORD dwSize = SizeofResource(dll,hRes);
HGLOBAL hMem = LoadResource(dll, hRes);
LPBYTE pBytes = (LPBYTE)LockResource(hMem);
Cursor = CreateIconFromResource(pBytes, dwSize, false, 0x00030000);
What am I doing wrong?
Upvotes: 1
Views: 1316
Reputation: 33804
when you include
BM_CURSOR_GRAB CURSOR "./grab.cur"
line to rc file, in generated PE will be (BM_CURSOR_GRAB, RT_GROUP_CURSOR)
resource. so type will be RT_GROUP_CURSOR
but not RT_CURSOR
.
then you need call LookupIconIdFromDirectoryEx
function for get name (id) of cursor that best fits the specified size.
after this you need again load resource - already RT_CURSOR
with id returned from LookupIconIdFromDirectoryEx
.
and finally use it in call CreateIconFromResourceEx
.
but however, more simply call LoadImage
with IMAGE_CURSOR
resource type.
(HCURSOR)LoadImageW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), IMAGE_CURSOR,
0, 0, 0);
for example, for use actual resource size. or is you want use default system cursor size:
(HCURSOR)LoadImageW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), IMAGE_CURSOR,
GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR), 0);
or
(HCURSOR)LoadImageW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), IMAGE_CURSOR,
0, 0, LR_DEFAULTSIZE);
or simply
LoadCursorW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB));
last call internal call LoadImageW
with LR_DEFAULTSIZE | LR_SHARED
flags
however code for direct access resource (LoadImageW
do this internal)
ULONG GetResourcePointer(void** ppv, ULONG* pcb, HMODULE hModule, PCWSTR lpName, PCWSTR lpType)
{
if (HRSRC hResource = FindResource(hModule, lpName, lpType))
{
if (HGLOBAL hResData = LoadResource(hModule, hResource))
{
if (PVOID pv = LockResource(hResData))
{
if (ULONG cb = SizeofResource(hModule, hResource))
{
*ppv = pv, *pcb = cb;
return NOERROR;
}
}
}
}
return GetLastError();
}
ULONG err = NOERROR;
HCURSOR hcur;
if (HMODULE hmod = (HMODULE)LoadLibraryW(L"*"))
{
ULONG cb, err;
PVOID pv;
if (!(err = GetResourcePointer(&pv, &cb, hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), RT_GROUP_CURSOR)))
{
if (int nID = LookupIconIdFromDirectoryEx((PBYTE)pv, FALSE, 0, 0, LR_DEFAULTCOLOR))
{
if (!(err = GetResourcePointer(&pv, &cb, hmod, MAKEINTRESOURCE(nID), RT_CURSOR)))
{
if (!(hcur = (HCURSOR)CreateIconFromResourceEx((PBYTE)pv, cb,
FALSE, 0x00030000, 0, 0, LR_DEFAULTCOLOR|LR_DEFAULTSIZE)))
{
err = GetLastError();
}
}
}
else
{
err = GetLastError();
}
}
}
Upvotes: 4
Reputation: 101
Variants of errors:
LoadLibrary("BenjaMiniRessources.dll")
is NULL;FindResource(dll, MAKEINTRESOURCE(100), RT_CURSOR)
is NULL. (Maybe type of this resource is RT_GROUP_CURSOR or RT_ANICURSOR);The error is in string SizeofResource(dll,hRes),
if return value is NULL;
The problem is in LoadResource(dll, hRes)
, if this function returns NULL;
The fault in LockResource(hMem)
, if this function returns NULL;
The error is in string CreateIconFromResource(pBytes, dwSize, false, 0x00030000)
.
You can go through the code under the debugger and see which one of the lines of the program first returns an error.
Upvotes: 0
Reputation: 15375
Use simply LoadCursor with the corresponding hInstance. This works in the MFC and all of my Windows applications.
Upvotes: 5