我根本没有使用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
时,我会看到2种格式: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
{{1}的回复。数据和系统将自动转换。
那么,如果我有DIB
数据,如何从系统中为WM_RENDERFORMAT
格式的CF_BITMAP
消息放置正确的数据(通常情况下,如果我可以使用系统能力转换{会更好{1}}到DIB
而不是手动从DIB
创建BITMAP
?
答案 0 :(得分:2)
更新
所以我找到了解决问题的方法。首先,需要使用only
注册延迟呈现CF_DIB
SetClipboardData(CF_DIB, NULL)
。 CF_BITMAP
格式将自动Windows
添加到可用的剪贴板类型中。然后你需要传递dib
数据与BITMAPINFOHEADER
描述的第一个版本的标题(我有v3版本,我怀疑v4和v5标题将起作用)结构带有正biHeight
需要WM_RENDERFORMAT
格式的CF_DIB
上的1}}(Y坐标)(系统不会要求您CF_BITMAP
,因为您没有手动注册它)。在这种特殊情况下,系统会自动将CF_DIB
转换为CF_BITMAP
。我不知道这是否适用于位图数据的任何压缩方法,因为我只测试了BI_RGB
未压缩的图像。
bitmapinfo
dib
标头的每个其他版本都与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
的编程。