我正在使用VisualStudio2017开发Windows 7应用程序。此应用程序希望具有从DLL加载的特殊游标。所以首先我创建了一个DLL并添加了以下.rc文件:
BM_CURSOR_GRAB CURSOR "./grab.cur"
BM_CURSOR_GRABBING CURSOR "./grabbing.cur"
BM_CURSOR_GRAB和BM_CURSOR_GRABBING在头文件中定义为:
#define BM_CURSOR_GRAB 100
#define BM_CURSOR_GRABBING 101
我编译了DLL - 它可以工作并用ResourceEditor.exe
检查它包括我的资源:
现在“非工作”部分开始了。我的应用程序想要加载光标,但FindResource
找不到它。这是我的代码:
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);
我做错了什么?
答案 0 :(得分:3)
简单地使用LoadCursor和相应的hInstance。这适用于MFC和我的所有Windows应用程序。
答案 1 :(得分:1)
当你包括
BM_CURSOR_GRAB CURSOR "./grab.cur"
行到rc文件,在生成的PE中将是(BM_CURSOR_GRAB, RT_GROUP_CURSOR)
资源。所以类型为RT_GROUP_CURSOR
但不是RT_CURSOR
。
然后你需要调用LookupIconIdFromDirectoryEx
函数来获取最适合指定大小的光标的名称(id)。
在此之后您需要再次加载资源 - 已RT_CURSOR
已从LookupIconIdFromDirectoryEx
返回ID。
最后在通话CreateIconFromResourceEx
中使用它。
但是,更简单地使用IMAGE_CURSOR
资源类型调用LoadImage
。
(HCURSOR)LoadImageW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), IMAGE_CURSOR,
0, 0, 0);
例如,用于实际资源大小。或者你想使用默认的系统光标大小:
(HCURSOR)LoadImageW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), IMAGE_CURSOR,
GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR), 0);
或
(HCURSOR)LoadImageW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB), IMAGE_CURSOR,
0, 0, LR_DEFAULTSIZE);
或只是
LoadCursorW(hmod, MAKEINTRESOURCE(BM_CURSOR_GRAB));
最后使用LoadImageW
标记调用内部调用LR_DEFAULTSIZE | LR_SHARED
但直接访问资源的代码(LoadImageW
执行此内部操作)
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();
}
}
}
答案 2 :(得分:0)
错误的变种:
LoadLibrary("BenjaMiniRessources.dll")
中的返回值为NULL,系统找不到具有指定名称BenjaMiniRessources.dll的库; FindResource(dll, MAKEINTRESOURCE(100), RT_CURSOR)
中的返回值为NULL,则系统在BenjaMiniRessources.dll中找不到RT_CURSOR类型的资源。 (也许这个资源的类型是RT_GROUP_CURSOR或RT_ANICURSOR); 如果返回值为NULL,则错误在字符串SizeofResource(dll,hRes),
中;
问题出在LoadResource(dll, hRes)
,如果此函数返回NULL;
LockResource(hMem)
中的错误,如果此函数返回NULL;
错误在字符串CreateIconFromResource(pBytes, dwSize, false, 0x00030000)
中。
您可以浏览调试器下的代码,看看程序中哪一行首先返回错误。