从ole32.dll获取光标(4个奇怪的字节)

时间:2016-07-09 10:53:11

标签: c++ winapi

美好的一天!

我正在尝试将此enter image description here光标从“ole32.dll”加载到我的程序中。

最初我不知道这个游标的名称(索引),所以我使用Resource Hacker并将其解压缩到一个文件中。指数为“4”。该文件包含以下内容:

0x00, 0x00, 0x02, 0x00, 0x01, 0x00, // ICONDIR header

0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01,
0x00, 0x00, 0x16, 0x00, 0x00, 0x00, // ICONDIRENTRY header

0x28 ... // image data of the cursor itself (the size of this block is 304 bytes)

然后我写了一个简单的代码(在C#上,但没关系):

var hmodule = LoadLibrary("ole32.dll");
var hres = FindResource(hmodule, 4, RT_CURSOR);
var size = SizeofResource(hmodule, hres);
var hcursor = LoadResource(hmodule, hres);

但是我发现SizeofResource函数返回 308 ,而不是304.然后我得到了字节数组:

0x00, 0x00, 0x00, 0x00, // 4 missed bytes
0x28 ... // data, 304 bytes

所以我的问题是:这4个字节是什么意思?它是一些不存在的结构的长度吗?

第二个问题:在一般情况下,我如何获得光标资源的正确标题(特别是热点的x- / y坐标和光标图像的宽度/高度)?

谢谢!

1 个答案:

答案 0 :(得分:2)

  

“最初我不知道这个游标的名称(索引),所以我使用了Resource Hacker并将其解压缩到一个文件中。”

这是你出错的第一个地方。您不应该只从Windows DLL中提取资源并期望使用它们。如果它们是供公众使用的,那么将有一个记录的机制来使用它们。如果没有,那么你不应该使用它们。它们是私有的,专用于操作系统。偷他们几乎肯定是不合法的;咨询律师。

在这种情况下,我们的想法是当您使用OLE库实现拖放时,将自动显示游标。处理IDropSource::GiveFeedback时,将值DRAGDROP_S_USEDEFAULTCURSORS返回到...使用默认游标。

  

然后我写了一个简单的代码......

这就是 真的 出错的地方。除了合法性之外,如果您想将与Windows捆绑在一起的游标提取到文件中并将它们作为嵌入资源包含在您的应用程序中,那么您完全可以自由地执行此操作。但你应该当然不做的是尝试在Windows DLL内部进行浏览以使用未记录的项目。这不仅在法律上是可疑的,而且在技术上无效,因为只要Windows更新,您的代码就会停止工作。您还遇到了各种棘手的问题,可能与填充有关,或者只是没有充分记录的实现细节。这不值得进一步调查;这是其中一种情况,当它疼痛时,你应该停止这样做。

如果你绝对坚持试图伤害自己,那么至少要通过调用LoadCursor(或LoadImage以获得更多控制权)来轻松实现。这些辅助函数可以为您处理所有事情,包括为系统的当前DPI设置加载适当大小的光标以及映射热点的坐标。在处理标准资源类型时,很少有令人信服的理由可以手动查找和加载它们。

// error-checking omitted, because we are hardcore
HMODULE hmodOle = LoadLibraryEx(TEXT("ole32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE);
HCURSOR hCursor = LoadCursor(hmodOle, MAKEINTRESOURCE(2));
FreeLibrary(hmodOle);

另请注意,在我检查的位置(在Windows Server 2003和Windows 7上),您在问题中显示的光标实际上是#2,而不是#4。光标#4是具有快捷方式覆盖的光标。当然可能随时改变。我是否提到过您应该提取资源并将该文件嵌入到您自己的可执行文件中,而不是依赖于Windows DLL中的私有资源?