[英]WinAPI - Loading Ressources from a DLL
我正在使用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);
我究竟做错了什么?
只需将LoadCursor与相应的hInstance一起使用。 这适用于MFC和我的所有Windows应用程序。
当您将BM_CURSOR_GRAB CURSOR "./grab.cur"
行包含到rc文件中时,在生成的PE中将是(BM_CURSOR_GRAB, RT_GROUP_CURSOR)
资源。 所以类型将是RT_GROUP_CURSOR
而不是RT_CURSOR
。
那么您需要调用LookupIconIdFromDirectoryEx
函数以获取最适合指定大小的游标的名称(id)。
在此之后,你需要重新加载资源-已经RT_CURSOR
与返回ID LookupIconIdFromDirectoryEx
。
最后在调用CreateIconFromResourceEx
使用它。
但是,更简单的LoadImage
使用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
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();
}
}
}
错误的变种:
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),
则错误在字符串SizeofResource(dll,hRes),
;
如果此函数返回NULL,则问题出在LoadResource(dll, hRes)
。
如果此函数返回NULL,则为LockResource(hMem)
的错误; LockResource(hMem)
。
错误在字符串CreateIconFromResource(pBytes, dwSize, false, 0x00030000)
。
您可以遍历调试器下的代码,查看程序的哪一行首先返回错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.