2

My application fails to print after the latest security update.

None of the API calls fail, yet the images don't show even in PDF. Text and shapes like lines print fine.

The code loads a JPG image using IPicture interface and OleLoadPicture(). Then I use its Render() call to convert it into a HBITMAP and finally StretchBlt() on printing HDC.

None of the calls fail, all return values are checked. Everyhing worked fine until today and latest Windows security updates. Sure, if I uninstall KB5000808 update on my computer or KB5000802 on my client's computer everything is back to normal but this is not a long term solution.

Anyone having similar problems as of today? Any idea how to solve this? Any other way to print images?

EDIT:

Same problem even if I use a bitmap instead of a JPG image. So there's no problem with JPG rendering. On the other hand, both JPG and BITMAP show on the screen. Only printing does not work.

IgorD
  • 155
  • 1
  • 8
  • Looks similar to [this problem](https://stackoverflow.com/questions/66607946/calling-windows-selectobject-in-a-printer-compatible-device-context-returns-null). I traced the issue down to a call to `SelectObject`. Strangely, other applications continue printing bitmaps. – Diomidis Spinellis Mar 13 '21 at 05:59
  • You write that non of the API calls fail. Are you verifying the return value of `SelectObject`? – Diomidis Spinellis Mar 13 '21 at 06:21
  • 1
    SelectObject() looked so innocent that I hardly ever check its result. Well, sure yes, I get NULL. Amazingly, even if I create new HDC on my own - CreateDC ("DISPLAY", NULL/*prnName*/, NULL, NULL); - SelectObject() will fail again even on that HDC as well as if I have try with valid printer name obtained via GetDefaultPrinter(). – IgorD Mar 13 '21 at 11:31
  • Keep in mind that bitmaps can only be selected into a memory device context. You need to set `HDC hdcMem = CreateCompatibleDC(prn);` and use that. I guess that will fail for the printer but succeed for the display. – Diomidis Spinellis Mar 13 '21 at 12:39
  • This is what I had all this time: hdcMem = CreateCompatibleDC(prn); But since yesterday I tried everything, even creating a DC on my own with the printer name or with a text DISPLAY. None of it lets me add a bitmap to it with SelectObject() while printing. Outside of printig the same code works just fine. And actually I have one and only function for displaying bitmaps., on screen or on printer. – IgorD Mar 13 '21 at 13:05
  • 1
    And I even used a hdc from a front window. So .... HDC winHdc = GetDC (frontHwnd); HDC hdcMem = CreateCompatibleDC (winHdc); HBITMAP hSavedBitmap = SelectObject (hdcMem, hBitmap); ... This code snippet works well while I'm drawing things on the screen, but when I start printing it fails on SelectObject(). Amazing. – IgorD Mar 13 '21 at 13:46
  • There is another discussion of this problem here: https://stackoverflow.com/questions/66607946/calling-windows-selectobject-in-a-printer-compatible-device-context-returns-null – UweBaemayr Mar 17 '21 at 16:44

1 Answers1

1

I solved by using StretchDIBits instead of StretchBlt win32 api

Paul
  • 26
  • 2
  • I directly use the win32 api. I have never used IPicture. But looking at documentation could you not simply call IPicture::Render with the printer DC? – Paul Mar 13 '21 at 21:29
  • I'd be happy to accept your answer as I'm investigating StretchDIBits() and GetDIBits() but can you please post a link or give some example code? A function having passed HBITMAP and HDC and drawing it with StretchDIBits() – IgorD Mar 13 '21 at 23:01
  • IPicture and render into the printer dc? Good question. Maybe I can really do that. And I'm using IPicture from plain C so I call it as iPicture->lpvtbl->Render(); – IgorD Mar 13 '21 at 23:10
  • In the end I solved it by using Render from IPicture. Thanks for leading me to the simplest solution. – IgorD Mar 14 '21 at 12:31
  • In my case, I was lucky enough to to be creating my hbitmap with the CreateDIBSection api. So I had all information required for call to StreDIBits.But you can look at: https://stackoverflow.com/questions/9606906/saving-bmp-file-using-hbitmap-createdibsection-in-c-win32 Obviously, you won't save file, but you will have all the information you need. Also, be careful of ySrc parameter in StretchDIBits call , I needed to reverse it (height-y). – Paul Mar 14 '21 at 12:46
  • That's great news! Cheers! – Paul Mar 14 '21 at 12:47
  • Hey thanks a lot. Seems like I had the bitmap code ready before I even realised how to handle IPicture and since BitBlt() lets me use transparency converting IPicture to a bitmap seemd like a good idea. – IgorD Mar 14 '21 at 14:31