Search code examples
c++winapigdi

c++ GDI printing causes system to freeze


I am curently maintaining an old peace of c++ sofware that creates labels for SD-Cards. The software uses GDI to create the print jobs and usually there is no problem with that. However, after a certain amount of prints, the system freezes forever, even the mouse does not respond anymore. I can't tell where the app crashes, because it happens at different points and it is totally unpredictabe. I am not even sure what code I need to show here.

I aready set loads of breakpoints and stepped through different parts of the code but as the problem appears only randomly, it was not possible for me to come to any conclusion. I also tried to run the app on different environments, such as a VM but regardless what machine I use, the problem reappears.

HDC printerDC = CreateDCW(L"WINSPOOL", printers[SELECTED_PRINTERS[printerIndex]].c_str(), NULL, NULL);

DODEBUG(L"CreateDCW returned: " << printerDC << L" (should be something else than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"CreateDCW");

SetGraphicsMode(printerDC, GM_ADVANCED);

int result4 = StartDocW(printerDC, &di);

DODEBUG(L"StartDocW returned: " << result4 << L" (should be greater than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"StartDocW");

if(result4 > 0)
{
    int result5 = StartPage(printerDC);

    DODEBUG(L"StartPage returned: " << result5 << L" (should be greater than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"StartPage");

    SetBkMode(printerDC, TRANSPARENT);

    //1 dpi = 0.03937 pixel/mm; 1 pixel/mm = 25.4 dpi; 1 dpi = 0.003937 pixel/papersize; 0.1 pixel/papersize = 25.4 dpi;
    //1 px / 1 mm = 25.4 dpi => 1 px = 25.4 dpi * 1 mm => 1/(25.4) px = 25.4 dpi * 1 mm
    //1 dpi = 0.03937 pixel/mm => 1dpi * 1mm = 0.03937 pixel

    BITMAPINFOHEADER bi = { 0 };
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biHeight = (printerPaperYResolution * printLength) / 254;
    bi.biWidth = (printerPaperXResolution * printWidth) / 254;
    bi.biPlanes = 1;
    bi.biBitCount = 24;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;

    //Fix divisible-by-4-bug:
    LONG byteWidth = bi.biWidth * 3;
    LONG xDiv = byteWidth % 12;
    if(xDiv > 0)
    {
        bi.biWidth += (12 - xDiv) / 3;
        byteWidth = bi.biWidth * 3;
    }
    LONG yDiv = (bi.biHeight * 3) % 12;
    if(yDiv > 0)
    {
        bi.biHeight += (12 - yDiv) / 3;
    }

    LONG byteCount = 3 * bi.biHeight*bi.biWidth;

    byte* pBits = new byte[byteCount];
    memset(pBits, 255, byteCount);


    switch(printerIndex)
    {
    case PRINTER_ZERTIFIKAT:
        PrintZertifikat(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
        break;
    case PRINTER_LABEL_PACKUNG:
        PrintLabelPackung(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
        break;
    case PRINTER_LABEL_SDKARTE:
        PrintLabelSDKarte(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
        break;
    case PRINT_ONLY_SDLABEL:
        PrintOnlySDLabel(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
        break;
    }


    int result6 = EndPage(printerDC);

    DODEBUG(L"EndPage returned: " << result6 << L" (should be greater than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"EndPage");

    int result7 = EndDoc(printerDC);
}   

Solution

  • Do you release your HDC properly with DeleteDC()?