Recent

Author Topic: Bitblt on Windows 8.1 and black image results  (Read 8526 times)

PaulANormanNZ

  • Jr. Member
  • **
  • Posts: 97
Bitblt on Windows 8.1 and black image results
« on: April 23, 2014, 01:54:04 pm »
Hi,

I'm not sure what is wrong with my code, this used to work on Delphi under Xp.

I have tried it under FPC 2.7.1 in Lazarus (CodeTyphon 4.8) Windows 8.1 Pro, and now I always get just black filled rectangles of the correct dimensions (attached).

I am effectively trying to screen capture TWinControls (like TBitBtns). Appreciate any pointers please for code. This is the main portion of my function, var control here is screen.ActiveControl


try
DC := GetDC ( thisForm.handle);

   R := Control.boundsRect;
   bmp := tBitmap.create;
   bmp.width := R.Right-R.Left;
   bmp.Height := R.Bottom - R.Top;

   Bitblt(bmp.canvas.handle,0,0,bmp.Width,bmp.height,dc,r.left,r.top,SRCCOPY );

   bmp.SaveToFile( SavePath + 'check.bmp');

   jpegMake := tjpegimage.Create;
   jpegMake.Assign(Bmp);
   jpegMake.CompressionQuality := 100;

    saveName :=  SavePath + saveName ;
   jpegMake.saveToFile ( SAVEnAME);
   bmp.free;
   jpegMake.Free;   
finally
 if (dc <> null) then
 releasedc(thisForm.handle,dc);
 end;
                 

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8583
  • FPC developer.
Re: Bitblt on Windows 8.1 and black image results
« Reply #1 on: April 23, 2014, 07:31:23 pm »

   bmp := tBitmap.create;
   bmp.width := R.Right-R.Left;
   bmp.Height := R.Bottom - R.Top;

   Bitblt(bmp.canvas.handle,0,0,bmp.Width,bmp.height,dc,r.left,r.top,SRCCOPY );

The bmp you create has no relation to the form or another handle bearing control. Thus its canvas has probably no windows handle, so this will fail.  Do you have the complete functioning code for Delphi?
 

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: Bitblt on Windows 8.1 and black image results
« Reply #2 on: April 23, 2014, 11:00:17 pm »
Create a compatible bitmap and assign it to your bmp:
Code: [Select]
var
...
  cBMP: HBITMAP;
...
     bmp := Graphics.tBitmap.create;
     cBMP := CreateCompatibleBitmap(DC, R.Right - R.Left, R.Bottom - R.Top);  //<---
     bmp.Handle:=cBMP;  //<---

     Bitblt(bmp.canvas.handle,0,0,bmp.Width,bmp.height,dc,r.left,r.top,SRCCOPY );


PaulANormanNZ

  • Jr. Member
  • **
  • Posts: 97
Re: Bitblt on Windows 8.1 and black image results
« Reply #3 on: April 24, 2014, 09:13:11 am »
Thanks marcov,
     - that was pretty much identical to the Delphi code. Didn't in Delphi require CreateCompatibleBitmap(), perhaps some direct casting or something behind the scenes?

Many thanks for that engkin,
     - implemented it, and it works very well, as per attachments.

Although I found I had to use Windows unit (before , Graphics)
.. or the positioning was all wrong and instead I took a photo of the top right of the form instead (as shown in no Windows unit - saveAsFile.jpg attached)

I use this in generating application images for help files. The unit and form are attached in the 7z.  I think Peter Belowes gave some pointers for this in the past.

Paul

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8583
  • FPC developer.
Re: Bitblt on Windows 8.1 and black image results
« Reply #4 on: April 24, 2014, 11:52:10 am »
Afaik Delphi only creates a handle under the hood when the parent of the tbitmap is assigned to a gui control, that's why  I asked.

PaulANormanNZ

  • Jr. Member
  • **
  • Posts: 97
Re: Bitblt on Windows 8.1 and black image results
« Reply #5 on: April 24, 2014, 12:26:07 pm »
Thanks,

I don't know about the inner working of Delphi on that one, but looking at FP TBitmap, it seems to inherit from TRasterImage  somewhere along the way, and TRasterImage appears to provide BitmapHandleNeeded; with appropriate steps?

taazz

  • Hero Member
  • *****
  • Posts: 5365
Re: Bitblt on Windows 8.1 and black image results
« Reply #6 on: April 24, 2014, 02:21:20 pm »
Afaik Delphi only creates a handle under the hood when the parent of the tbitmap is assigned to a gui control, that's why  I asked.
erm are you sure this isn't for the canva? TBitmap should have a handle or create a DIB handle the first time it is required what you describe will make the code windows dependant makes no sense for TBitmap non at all.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

z505

  • New Member
  • *
  • Posts: 38
  • think first, code after
Re: Bitblt on Windows 8.1 and black image results
« Reply #7 on: March 09, 2017, 05:03:51 am »
Create a compatible bitmap and assign it to your bmp:
Code: [Select]
var
...
  cBMP: HBITMAP;
...
     bmp := Graphics.tBitmap.create;
     cBMP := CreateCompatibleBitmap(DC, R.Right - R.Left, R.Bottom - R.Top);  //<---
     bmp.Handle:=cBMP;  //<---

     Bitblt(bmp.canvas.handle,0,0,bmp.Width,bmp.height,dc,r.left,r.top,SRCCOPY );


Sorry for replying to an old post, but remember if you CreateCompatibleBitmap() you should then free the memory when you are done, to not cause GDI leak or similar, AFAIK.
Code: Pascal  [Select][+][-]
  1.         DeleteObject(cBMP);
  2.  

The MSDN says:
Quote
When you no longer need the bitmap, call the DeleteObject function to delete it.

MSDN doesn't specify what would happen if you did not DeleteObject, but maybe a leak would occur (I'm too lazy to test to see if that's what happens with some leak check tool).
think first, code after

 

TinyPortal © 2005-2018