2

I have no practice with windows programming at all, but now I have a problem I want to fix in some program. I need to place an image to windows clipboard and I have raw pointer to valid DIB (device independent bitmap)(in my experiments the dib header version is 3). The program uses the model with delayed clipboard rendering, which means that at first we use SetClipboardData(CF_DIB, NULL) and then on WM_RENDERFORMAT message the program place the actual data to clipboard with SetClipboardData(format, dibDataPointer). When I open clipbrd.exe (on windows xp) and I choose the DIB view, I can see an Image without any problem. But in msdn is written that the system can render automatically from CF_DIB to CF_BITMAP format. I think that's why when I look in clipbrd.exe I see 2 formats: DIB and BITMAP. When I select in clipbrd.exe the bitmap format I got an error. At first when I looked at the code I saw that there is no case for CF_BITMAP in system message handler function, so when system asks to render CF_BITMAP nothing valid is placed to clipboard, so I added something like this:

switch(format){
case CF_DIB:
case CF_BITMAP: //new code

    if(format == CF_BITMAP)//new cOde
        format = CF_DIB;// new code
....
    SetClipboardData(format, dibDataPointer);
....

and hope (actually, I knew that won't gonna work, but gave this way a try) that the system will recognize that I'm going to give as a response for CF_BITMAP a DIB data and the system will convert in automatically. So how can I place proper data for WM_RENDERFORMAT message with CF_BITMAP format from the system if I have a DIB data (generally it would be better if I could use the system ability to convert DIB to BITMAP rather then create BITMAP from DIB manually)?

JustAnotherCurious
  • 2,208
  • 15
  • 32
  • 1
    Clipboard formats are a mine field. But I'm fairly sure that nothing is automatic here and CF_DIB is very different from CF_BITMAP. Programs publish data on the clipboard in multiple formats to increase the odds that a consuming program supports one of them. You get the format is likes as the WPARAM in the WM_RENDERFORMAT message. – Hans Passant May 23 '13 at 12:15
  • @HansPassant Yes you are right about the odds. And that is why I wanted to place СF_BITMAP on the clipboard too. Actually for my purposes I found that the programs I want paste pictures (Wordpad for example) want a DIB with v1 header and positive Y coordinate. Actually v3 header is reverse compatible with v1 header and negative Y coordinate is absolutely valid header value. So I'm really disappointed again in Windows, according that system Wordpad can't work with absolutely valid DIB images. =( But still just for interest I leave the question opened. – JustAnotherCurious May 24 '13 at 06:11

1 Answers1

3

Update:

So I found how to fix the issue. At first it's needed to register for delayed rendering only the CF_DIB with SetClipboardData(CF_DIB, NULL). The CF_BITMAP format will be added to the available clipboard types by Windows automatically. Then you need to pass the dib data with header of the first version which is described by BITMAPINFOHEADER (I have v3 version, I doubt that v4 and v5 headers are going to work) structure with positive biHeight (Y Coordinate) on WM_RENDERFORMAT with CF_DIB format required (the system won't ask you for CF_BITMAP because you didn't register it manually). And in this particular case the system will convert CF_DIB to CF_BITMAP automatically. I don't know will this work with any of the compression method for bitmap data, because I've tested only the BI_RGB uncompressed images.

Every other version of bitmapinfo dib header is reverse compatible with BITMAPINFOHEADER and can be successfully copied with memcpy. But don't forget to set biSize to sizeof(BITMAPINFOHEADER). The second part is to setup positive Y coordinate. (I really hope that DIB format with compressed data should always have positive height.) But for uncompressed bitmaps biHeight can be less then zero, and should be made to a positive value. This will cause the image to be upside down, so it's needed to reverse image rows. The mention should be made that the rows are aligned by 4 bytes.

And the worst thing is that all this standards for headers are described in microsoft documentation. But. for example, Paint can get the dib info v3 header with negative height value, the clipbrd.exe can get v3 header with positive height. The wordpad wants only v1 header with positive height. And the windows converts DIB ro BITMAP only with v1 header and positive height. This all are applications which are distributed with windows (no clipbrd.exe in Vista or later). This is a terrible hell. I hope there won't be any more programming for Windows in my entire life.

JustAnotherCurious
  • 2,208
  • 15
  • 32