我完全没有windows编程的经验,但现在我有一个问题,我想在一些程序中解决。我需要把一个图像放到windows剪贴板上,并且我有指向有效DIB (设备独立位图)的原始指针(在我的实验中,dib头版本是3)。程序使用延迟剪贴板渲染的模型,这意味着我们首先使用SetClipboardData(CF_DIB, NULL),然后在WM_RENDERFORMAT消息上,程序使用SetClipboardData(format, dibDataPointer)将实际数据放到剪贴板上。当我打开clipbrd.exe (在windows xp上)并选择DIB视图时,我可以毫无问题地看到图像。但在msdn中编写的系统可以自动从CF_DIB格式渲染到CF_BITMAP格式。我想这就是为什么当我查看clipbrd.exe时,我看到两种格式:DIB和BITMAP。当我在clipbrd.exe中选择bitmap格式时,我得到了一个错误。起初,当我查看代码时,我发现系统消息处理函数中没有CF_BITMAP,所以当系统请求呈现CF_BITMAP时,剪贴板中没有任何有效的内容,所以我添加了如下内容:
switch(format){
case CF_DIB:
case CF_BITMAP: //new code
if(format == CF_BITMAP)//new cOde
format = CF_DIB;// new code
....
SetClipboardData(format, dibDataPointer);
....并希望(实际上,我知道这不会起作用,但尝试了一下这种方式),系统会识别出我将给CF_BITMAP一个DIB数据作为响应,系统会自动转换。那么,如果我有CF_BITMAP数据,如何从系统中为DIB格式的WM_RENDERFORMAT消息放置适当的数据(通常,如果我可以使用系统功能将DIB转换为BITMAP,而不是手动从DIB创建BITMAP,那会更好)?
发布于 2013-05-24 16:56:31
更新:
所以我找到了解决这个问题的方法。首先,需要使用SetClipboardData(CF_DIB, NULL)注册延迟渲染only CF_DIB。Windows会自动将CF_BITMAP格式添加到可用的剪贴板类型中。然后你需要传递带有BITMAPINFOHEADER描述的第一个版本的报头的dib数据(我有v3版本,我怀疑v4和v5报头是否可以工作),结构是正的biHeight (Y坐标),在WM_RENDERFORMAT上需要CF_DIB格式(系统不会要求你提供CF_BITMAP,因为你没有手动注册)。在这种特殊情况下,系统会自动将CF_DIB转换为CF_BITMAP。我不知道这是否适用于位图数据的任何压缩方法,因为我只测试了BI_RGB未压缩的图像。
所有其他版本的bitmapinfo dib header都与BITMAPINFOHEADER反向兼容,并且可以使用memcpy成功复制。但不要忘记将biSize设置为sizeof(BITMAPINFOHEADER)。第二部分是建立正Y坐标。(我真的希望包含压缩数据的DIB格式应该始终具有正的高度。)但是对于未压缩的位图,biHeight可以小于零,并且应该设置为正值。这将导致图像颠倒,因此需要反转图像行。值得一提的是,行是按4个字节对齐的。
最糟糕的是,所有这些头标准都在microsoft文档中进行了描述。但。例如,Paint可以获取高度为负值的dib info v3报头,clipbrd.exe可以获取高度为正的v3报头。wordpad只需要高度为正的v1标头。并且窗口仅转换具有v1标题和正高度的DIB ro BITMAP。这些都是与windows一起发布的应用程序(在Vista或更高版本中没有clipbrd.exe )。这是个可怕的地狱。我希望在我的整个生命中不会有更多的Windows编程。
https://stackoverflow.com/questions/16711600
复制相似问题