大佬教程收集整理的这篇文章主要介绍了delphi – 为什么在Win64上调用GetDIBits失败?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我可以想出的最小(至少有点结构化)的代码示例来重现错误.我用Delphi 10 Seattle update 1进行了测试,但是即使使用其他Delphi版本,似乎也出现了错误.
program Project1; {$APPTYPE CONSOLE} {$R *.res} uses Winapi.Windows,System.SysUtils,Vcl.Graphics; type TRGBALine = arraY[Word] of TRGBQuad; PRGBALine = ^TRGBALine; type { same structure as TBitmapInfo,but adds space for two more entries in bmiColors } TMyBitmapInfo = record bmiHeader: TBitmapInfoHeader; bmiColors: arraY[0..2] of TRGBQuad; public constructor Create(AWidth,AHeight: Integer); end; constructor TMyBitmapInfo.Create(AWidth,AHeight: Integer); begin FillChar(bmiHeader,Sizeof(bmiHeader),0); bmiHeader.biSize := SizeOf(bmiHeader); bmiHeader.biWidth := AWidth; bmiHeader.biHeight := -AHeight; //Otherwise the image is upside down. bmiHeader.biPlanes := 1; bmiHeader.biBitCount := 32; bmiHeader.biCompression := BI_BITFIELDS; bmiHeader.biSizeImage := 4*AWidth*AHeight; // 4 = 32 Bits/Pixel div 8 Bits/Byte bmiColors[0].rgbRed := 255; bmiColors[1].rgbGreen := 255; bmiColors[2].rgbBlue := 255; end; procedure Main; var bitmap: TBitmap; res: Cardinal; Bits: PRGBALine; buffer: TMyBitmapInfo; BitmapInfo: TBitmapInfo absolute buffer; BitsSize: Cardinal; icon: TIcon; IconInfo: TIconInfo; begin bitmap := TBitmap.Create; try icon := TIcon.Create; try icon.LoadFromresourcEID(0,Integer(IDI_WINLOGO)); if not GetIconInfo(icon.Handle,IconInfo) then begin Writeln('Error getIconInfo: ',GetLastError); Exit; end; bitmap.pixelFormat := pf32bit; bitmap.Handle := IconInfo.hbmColor; BitsSize := BytesPerScanline(bitmap.Width,32,32) * bitmap.Height; Bits := AllOCMem(BitsSizE); try ZeroMemory(Bits,BitsSizE); buffer := TMyBitmapInfo.Create(bitmap.Width,bitmap.Height); res := GetDIBits(bitmap.Canvas.Handle,bitmap.Handle,bitmap.Height,Bits,BitmapInfo,DIB_RGB_COLORS); if res = 0 then begin Writeln('Error getDIBits: ',GetLastError); Exit; end; Writeln('Succeed'); finally FreeMem(Bits); end; finally icon.Free; end; finally bitmap.Free; end; end; begin try Main; except on E: Exception do Writeln(E.ClassName,': ',E.messagE); end; Readln; end.
因此,您可以通过以适当的顺序将位图句柄和设备上下文分配给局部变量来解决问题,然后将其作为参数传递给GetDIBits.但是我仍然认为代码远远好于避免VCL TBitmap类并直接使用GDI调用,如下面的代码.
我相信你的错误是传递位图句柄及其画布句柄.相反,您应该传递例如通过调用CreateCompatibleDC(0)获得的设备上下文.或将IconInfo.hbmColor传递给GetDIBits.但是不要传递TBitmap的句柄和其画布的句柄.
我也看不到您创建的TBitmap的任何目的.你所做的一切就是获得IconInfo.hbmColor的宽度和高度.您不需要创建TBitmap来实现.
所以如果我是你,我将删除TBitmap,并使用CreateCompatibleDC(0)获取设备上下文.这应该大大简化代码.
您还需要删除对GetIconInfo的调用返回的位图,但是我想您已经知道了这一点,并从该问题中删除了该代码.
坦白说,VCL的对象正好在这里.直接调用GDI函数实际上更简单.也许是这样的:
procedure Main; var res: Cardinal; Bits: PRGBALine; bitmap: Winapi.Windows.TBitmap; DC: HDc; buffer: TMyBitmapInfo; BitmapInfo: TBitmapInfo absolute buffer; BitsSize: Cardinal; IconInfo: TIconInfo; begin if not GetIconInfo(LoaDicon(0,IDI_WINLOGO),IconInfo) then begin Writeln('Error getIconInfo: ',GetLastError); Exit; end; try if GetObject(IconInfo.hbmColor,SizeOf(bitmap),@bitmap) = 0 then begin Writeln('Error getObject'); Exit; end; BitsSize := BytesPerScanline(bitmap.BMWidth,32) * abs(bitmap.bR_858_11845@Height); Bits := AllOCMem(BitsSizE); try buffer := TMyBitmapInfo.Create(bitmap.BMWidth,abs(bitmap.bR_858_11845@Height)); DC := CreateCompatibleDC(0); res := GetDIBits(DC,IconInfo.hbmColor,abs(bitmap.bR_858_11845@Height),DIB_RGB_COLORS); deleteDC(DC); if res = 0 then begin Writeln('Error getDIBits: ',GetLastError); Exit; end; Writeln('Succeed'); finally FreeMem(Bits); end; finally deleteObject(IconInfo.hbmMask); deleteObject(IconInfo.hbmColor); end; end;
以上是大佬教程为你收集整理的delphi – 为什么在Win64上调用GetDIBits失败?全部内容,希望文章能够帮你解决delphi – 为什么在Win64上调用GetDIBits失败?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。