剪贴板中的Windows CF_DIB到CF_BITMAP

时间:2013-05-23 10:31:28

标签: windows bitmap clipboard

我根本没有使用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种格式:DIBBITMAP。当我选择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

1 个答案:

答案 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的编程。