GDI位图/ DC在32位和64位进程中的像素大小限制是什么?

我正在编写一个执行低级别打印的Win32应用程序,为此我正在处理GDI位图和设备上下文 。

代码基本上这样做(伪代码):

HDC hCompDc = ::CreateCompatibleDC(hDC); BITMAPINFOHEADER infoHeader = {0}; infoHeader.biSize = sizeof(infoHeader); infoHeader.biWidth = nWidth; infoHeader.biHeight = -nHeight; //The document must be right side up infoHeader.biPlanes = 1; infoHeader.biBitCount = 24; infoHeader.biCompression = BI_RGB; BITMAPINFO info; info.bmiHeader = infoHeader; //Use file on disk to store large bitmap data HANDLE hFileScatch = ::CreateFile(strTempPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); UINT64 ncbLineSz = nWidth * 3; if(ncbLineSz & 0x3) ncbLineSz = (ncbLineSz & ~0x3) + 0x4; //Must be DWORD aligned UINT64 uiSzBmp = ncbLineSz * nHeight; HANDLE hFileMapObj = ::CreateFileMapping(hFileScatch, NULL, PAGE_READWRITE, (DWORD)(uiSzBmp >> 32), (DWORD)(uiSzBmp), NULL); BYTE* pMemory = 0; HBITMAP hBitmap = ::CreateDIBSection(hDC, &info, DIB_RGB_COLORS, (void**)&pMemory, hFileMapObj, 0); ::SelectObject(hCompDc, hBitmap); //Do drawing on `hCompDc` using other GDI APIs //... //And print ::SetAbortProc(hPrintDC, _printerAbortProc); ::StartDoc(hPrintDC, &docInfo); ::StartPage(hPrintDC); ::BitBlt(hPrintDC, rcPrintArea.left, rcPrintArea.top, rcRenderArea.Width(), rcRenderArea.Height(), hCompDc, //DC from rcRenderArea.left, rcRenderArea.top, SRCCOPY); ::EndPage(hPrintDC); //Clean up, etc. //... 

这在一定程度上起作用。 让我解释:

由于我处理的打印机分辨率是300 dpi(而通常屏幕是96 dpi),所以位图的大小非常大。

例如,如果我有一个3900 x 86625像素的位图,它需要大约966 MB的DIB部分。 (我可以知道,如果我用上面的代码中的CreateDIBSection中的默认内存分配replace为由磁盘上的文件支持的file mapping object )。否则,我明白我可以在32位进程中达到连续RAM空间的限制与那块内存。 但是那不是发生了什么。

当我在32位进程中使用该位图大小运行代码时,使用由磁盘上文件支持的file mapping object创build位图,但生成的位图/图像完全空白,而完全相同的代码在64位进程编译,产生一个正常的位图。

所以鉴于这一点,我很好奇,如果有这些GDI对象有特定的图像大小限制? 对于32位和64位进程。

还有一个方面的问题 – 有没有什么办法知道在绘图时达到了这个尺寸限制?

PS。 我的实际代码对所有的Win32 API都有错误检查,而我上面描述的32位进程生成了一个空白的位图,但是在一个GDI API中并没有失败。