Exemple #1
0
HDC ShowPrintDlg(HWND hwndParent)
{
	// if Windows 2000 and above
	if((GetVersion() & 0xff) >= 5)
	{
		PRINTDLGEX	pdlgx	= { sizeof(pdlgx), hwndParent, g_hDevMode, g_hDevNames };
		pdlgx.Flags			= PD_RETURNDC | PD_NOPAGENUMS | PD_NOCURRENTPAGE | PD_NOWARNING | PD_HIDEPRINTTOFILE;
		pdlgx.nStartPage	= START_PAGE_GENERAL;

		if(S_OK == PrintDlgEx(&pdlgx) && pdlgx.dwResultAction != PD_RESULT_CANCEL)
		{
			g_hDevMode		= pdlgx.hDevMode;
			g_hDevNames		= pdlgx.hDevNames;
			g_nPrinterWidth = GetPrinterWidth(pdlgx.hDC);

			return pdlgx.hDC;
		}
	}
	// Win9x and WinNT need the old-style print dialog
	else
	{
		PRINTDLG	pdlg	= { sizeof(pdlg),  hwndParent, g_hDevMode, g_hDevNames };
		pdlg.Flags			= PD_RETURNDC | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE;

		if(PrintDlg(&pdlg))
		{
			g_hDevMode		= pdlg.hDevMode;
			g_hDevNames		= pdlg.hDevNames;
			g_nPrinterWidth = GetPrinterWidth(pdlg.hDC);

			return pdlg.hDC;
		}
	}

	return NULL;
}
Exemple #2
0
void OnMenuPrint(WindowInfo *win, bool waitForCompletion)
{
    // we remember some printer settings per process
    static ScopedMem<DEVMODE> defaultDevMode;
    static PrintScaleAdv defaultScaleAdv = PrintScaleShrink;
    static bool defaultAsImage = false;

    bool printSelection = false;
    Vec<PRINTPAGERANGE> ranges;
    PRINTER_INFO_2 printerInfo = { 0 };

    if (!HasPermission(Perm_PrinterAccess)) return;

    DisplayModel *dm = win->dm;
    assert(dm);
    if (!dm) return;

    if (!dm->engine || !dm->engine->AllowsPrinting())
        return;

    if (win->IsChm()) {
        win->dm->AsChmEngine()->PrintCurrentPage();
        return;
    }

    if (win->printThread) {
        int res = MessageBox(win->hwndFrame, _TR("Printing is still in progress. Abort and start over?"), _TR("Printing in progress."), MB_ICONEXCLAMATION | MB_YESNO | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        if (res == IDNO)
            return;
    }
    AbortPrinting(win);

    PRINTDLGEX pd;
    ZeroMemory(&pd, sizeof(PRINTDLGEX));
    pd.lStructSize = sizeof(PRINTDLGEX);
    pd.hwndOwner   = win->hwndFrame;
    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
    if (!win->selectionOnPage)
        pd.Flags |= PD_NOSELECTION;
    pd.nCopies     = 1;
    /* by default print all pages */
    pd.nPageRanges = 1;
    pd.nMaxPageRanges = MAXPAGERANGES;
    PRINTPAGERANGE *ppr = AllocArray<PRINTPAGERANGE>(MAXPAGERANGES);
    pd.lpPageRanges = ppr;
    ppr->nFromPage = 1;
    ppr->nToPage = dm->PageCount();
    pd.nMinPage = 1;
    pd.nMaxPage = dm->PageCount();
    pd.nStartPage = START_PAGE_GENERAL;

    Print_Advanced_Data advanced(PrintRangeAll, defaultScaleAdv, defaultAsImage);
    ScopedMem<DLGTEMPLATE> dlgTemplate; // needed for RTL languages
    HPROPSHEETPAGE hPsp = CreatePrintAdvancedPropSheet(&advanced, dlgTemplate);
    pd.lphPropertyPages = &hPsp;
    pd.nPropertyPages = 1;

    // restore remembered settings
    if (defaultDevMode)
        pd.hDevMode = GlobalMemDup(defaultDevMode.Get(), defaultDevMode.Get()->dmSize + defaultDevMode.Get()->dmDriverExtra);

    if (PrintDlgEx(&pd) != S_OK) {
        if (CommDlgExtendedError() != 0) {
            /* if PrintDlg was cancelled then
               CommDlgExtendedError is zero, otherwise it returns the
               error code, which we could look at here if we wanted.
               for now just warn the user that printing has stopped
               becasue of an error */
            MessageBox(win->hwndFrame, _TR("Couldn't initialize printer"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        }
        goto Exit;
    }

    if (pd.dwResultAction == PD_RESULT_PRINT || pd.dwResultAction == PD_RESULT_APPLY) {
        // remember settings for this process
        LPDEVMODE devMode = (LPDEVMODE)GlobalLock(pd.hDevMode);
        if (devMode) {
            defaultDevMode.Set((LPDEVMODE)memdup(devMode, devMode->dmSize + devMode->dmDriverExtra));
            GlobalUnlock(pd.hDevMode);
        }
        defaultScaleAdv = advanced.scale;
        defaultAsImage = advanced.asImage;
    }

    if (pd.dwResultAction != PD_RESULT_PRINT)
        goto Exit;

    if (pd.Flags & PD_CURRENTPAGE) {
        PRINTPAGERANGE pr = { dm->CurrentPageNo(), dm->CurrentPageNo() };
        ranges.Append(pr);
    } else if (win->selectionOnPage && (pd.Flags & PD_SELECTION)) {
        printSelection = true;
    } else if (!(pd.Flags & PD_PAGENUMS)) {
        PRINTPAGERANGE pr = { 1, dm->PageCount() };
        ranges.Append(pr);
    } else {
        assert(pd.nPageRanges > 0);
        for (DWORD i = 0; i < pd.nPageRanges; i++)
            ranges.Append(pd.lpPageRanges[i]);
    }

    LPDEVNAMES devNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
    LPDEVMODE devMode = (LPDEVMODE)GlobalLock(pd.hDevMode);
    if (devNames) {
        printerInfo.pDriverName = (LPWSTR)devNames + devNames->wDriverOffset;
        printerInfo.pPrinterName = (LPWSTR)devNames + devNames->wDeviceOffset;
        printerInfo.pPortName = (LPWSTR)devNames + devNames->wOutputOffset;
    }
    PrintData *data = new PrintData(dm->engine, &printerInfo, devMode, ranges, advanced,
                                    dm->Rotation(), printSelection ? win->selectionOnPage : NULL);
    if (devNames)
        GlobalUnlock(pd.hDevNames);
    if (devMode)
        GlobalUnlock(pd.hDevMode);

    if (!waitForCompletion)
        PrintToDeviceOnThread(win, data);
    else {
        PrintToDevice(*data);
        delete data;
    }

Exit:
    free(ppr);
    GlobalFree(pd.hDevNames);
    GlobalFree(pd.hDevMode);
}
int QPrintDialogPrivate::openWindowsPrintDialogModally()
{
    Q_Q(QPrintDialog);
    QWidget *parent = q->parentWidget();
    if (parent)
        parent = parent->window();
    else
        parent = QApplication::activeWindow();

    // If there is no window, fall back to the print dialog itself
    if (parent == 0)
        parent = q;

    QWidget modal_widget;
    modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
    modal_widget.setParent(parent, Qt::Window);
    QApplicationPrivate::enterModal(&modal_widget);

    HGLOBAL *tempDevNames = ep->createDevNames();

    bool done;
    bool result;
    bool doPrinting;

    PRINTPAGERANGE pageRange;
    PRINTDLGEX pd;
    memset(&pd, 0, sizeof(PRINTDLGEX));
    pd.lStructSize = sizeof(PRINTDLGEX);
    pd.lpPageRanges = &pageRange;
    qt_win_setup_PRINTDLGEX(&pd, parent, q, this, tempDevNames);

    do {
        done = true;
        doPrinting = false;
        result = (PrintDlgEx(&pd) == S_OK);
        if (result && (pd.dwResultAction == PD_RESULT_PRINT
                       || pd.dwResultAction == PD_RESULT_APPLY))
        {
            doPrinting = (pd.dwResultAction == PD_RESULT_PRINT);
            if ((pd.Flags & PD_PAGENUMS)
                && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage))
            {
                pd.lpPageRanges[0].nFromPage = 1;
                pd.lpPageRanges[0].nToPage = 1;
                done = false;
            }
            if (pd.hDC == 0)
                result = false;
        }

        if (!done) {
            QMessageBox::warning(0, QPrintDialog::tr("Print"),
                                 QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."),
                                 QPrintDialog::tr("OK"));
        }
    } while (!done);

    QApplicationPrivate::leaveModal(&modal_widget);

    qt_win_eatMouseMove();

    // write values back...
    if (result && (pd.dwResultAction == PD_RESULT_PRINT
                   || pd.dwResultAction == PD_RESULT_APPLY))
    {
        qt_win_read_back_PRINTDLGEX(&pd, q, this);
        // update printer validity
        printer->d_func()->validPrinter = !ep->name.isEmpty();
    }

    // Cleanup...
    GlobalFree(tempDevNames);

    q->done(result && doPrinting);

    return result && doPrinting;
}
Exemple #4
0
BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
{
#if 1
    PRINTDLG pd;
    UNREFERENCED_PARAMETER(path);

    ZeroMemory(&pd, sizeof(PRINTDLG));
    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner   = hWnd;
    pd.hDevMode    = NULL;     /* Don't forget to free or store hDevMode*/
    pd.hDevNames   = NULL;     /* Don't forget to free or store hDevNames*/
    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
    pd.nCopies     = 1;
    pd.nFromPage   = 0xFFFF;
    pd.nToPage     = 0xFFFF;
    pd.nMinPage    = 1;
    pd.nMaxPage    = 0xFFFF;
    if (PrintDlg(&pd))
    {
        /* GDI calls to render output. */
        DeleteDC(pd.hDC); /* Delete DC when done.*/
    }
#else
    HRESULT hResult;
    PRINTDLGEX pd;

    hResult = PrintDlgEx(&pd);
    if (hResult == S_OK)
    {
        switch (pd.dwResultAction)
        {
        case PD_RESULT_APPLY:
            /*The user clicked the Apply button and later clicked the Cancel button. This indicates that the user wants to apply the changes made in the property sheet, but does not yet want to print. The PRINTDLGEX structure contains the information specified by the user at the time the Apply button was clicked. */
            break;
        case PD_RESULT_CANCEL:
            /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
            break;
        case PD_RESULT_PRINT:
            /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
            break;
        default:
            break;
        }
    }
    else
    {
        switch (hResult)
        {
        case E_OUTOFMEMORY:
            /*Insufficient memory. */
            break;
        case E_INVALIDARG:
            /* One or more arguments are invalid. */
            break;
        case E_POINTER:
            /*Invalid pointer. */
            break;
        case E_HANDLE:
            /*Invalid handle. */
            break;
        case E_FAIL:
            /*Unspecified error. */
            break;
        default:
            break;
        }
        return FALSE;
    }
#endif
    return TRUE;
}
LRESULT CMainWindow::DoCommand(int id)
{
    switch (id)
    {
    case ID_FILE_OPEN:
        loadOrSaveFile(true);
        break;
    case ID_FILE_SAVEAS:
        loadOrSaveFile(false);
        break;
    case ID_FILE_SAVE:
        loadOrSaveFile(false, m_filename);
        break;
    case ID_FILE_EXIT:
        ::PostQuitMessage(0);
        return 0;
    case IDM_SHOWFINDBAR:
        {
            m_bShowFindBar = true;
            ::ShowWindow(m_FindBar, SW_SHOW);
            RECT rect;
            GetClientRect(*this, &rect);
            ::SetWindowPos(m_hWndEdit, HWND_TOP,
                rect.left, rect.top,
                rect.right-rect.left, rect.bottom-rect.top-30,
                SWP_SHOWWINDOW);
            ::SetWindowPos(m_FindBar, HWND_TOP,
                rect.left, rect.bottom-30,
                rect.right-rect.left, 30,
                SWP_SHOWWINDOW);
            ::SetFocus(m_FindBar);
            SendEditor(SCI_SETSELECTIONSTART, 0);
            SendEditor(SCI_SETSELECTIONEND, 0);
            SendEditor(SCI_SEARCHANCHOR);
        }
        break;
    case IDM_FINDNEXT:
        SendEditor(SCI_SEARCHANCHOR);
        SendEditor(SCI_SEARCHNEXT, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str());
        SendEditor(SCI_SCROLLCARET);
        break;
    case IDM_FINDPREV:
        SendEditor(SCI_SEARCHANCHOR);
        SendEditor(SCI_SEARCHPREV, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str());
        SendEditor(SCI_SCROLLCARET);
        break;
    case IDM_FINDEXIT:
        if (IsWindowVisible(m_FindBar))
        {
            RECT rect;
            GetClientRect(*this, &rect);
            m_bShowFindBar = false;
            ::ShowWindow(m_FindBar, SW_HIDE);
            ::SetWindowPos(m_hWndEdit, HWND_TOP,
                rect.left, rect.top,
                rect.right-rect.left, rect.bottom-rect.top,
                SWP_SHOWWINDOW);
        }
        else
            PostQuitMessage(0);
        break;
    case ID_FILE_SETTINGS:
        {
            tstring svnCmd = L" /command:settings /page:20";
            RunCommand(svnCmd);
        }
        break;
    case ID_FILE_APPLYPATCH:
        {
            std::wstring command = L" /diff:\"";
            command += m_filename;
            command += L"\"";
            std::wstring tortoiseMergePath = GetAppDirectory() + L"TortoiseMerge.exe";
            CCreateProcessHelper::CreateProcessDetached(tortoiseMergePath.c_str(), command.c_str());
        }
        break;
    case ID_FILE_PAGESETUP:
        {
            TCHAR localeInfo[3] = { 0 };
            GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3);
            // Metric system. '1' is US System
            int defaultMargin = localeInfo[0] == '0' ? 2540 : 1000;

            PAGESETUPDLG pdlg = {0};
            pdlg.lStructSize = sizeof(PAGESETUPDLG);
            pdlg.hwndOwner = *this;
            pdlg.hInstance = NULL;
            pdlg.Flags = PSD_DEFAULTMINMARGINS|PSD_MARGINS|PSD_DISABLEPAPER|PSD_DISABLEORIENTATION;
            if (localeInfo[0] == '0')
                pdlg.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;

            CRegStdDWORD m_regMargLeft   = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmarginleft", defaultMargin);
            CRegStdDWORD m_regMargTop    = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmargintop", defaultMargin);
            CRegStdDWORD m_regMargRight  = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmarginright", defaultMargin);
            CRegStdDWORD m_regMargBottom = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmarginbottom", defaultMargin);

            pdlg.rtMargin.left   = (long)(DWORD)m_regMargLeft;
            pdlg.rtMargin.top    = (long)(DWORD)m_regMargTop;
            pdlg.rtMargin.right  = (long)(DWORD)m_regMargRight;
            pdlg.rtMargin.bottom = (long)(DWORD)m_regMargBottom;

            if (!PageSetupDlg(&pdlg))
                return false;

            m_regMargLeft   = pdlg.rtMargin.left;
            m_regMargTop    = pdlg.rtMargin.top;
            m_regMargRight  = pdlg.rtMargin.right;
            m_regMargBottom = pdlg.rtMargin.bottom;
        }
        break;
    case ID_FILE_PRINT:
        {
            PRINTDLGEX pdlg = {0};
            pdlg.lStructSize = sizeof(PRINTDLGEX);
            pdlg.hwndOwner = *this;
            pdlg.hInstance = NULL;
            pdlg.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_ALLPAGES | PD_RETURNDC | PD_NOCURRENTPAGE | PD_NOPAGENUMS;
            pdlg.nMinPage = 1;
            pdlg.nMaxPage = 0xffffU; // We do not know how many pages in the document
            pdlg.nCopies = 1;
            pdlg.hDC = 0;
            pdlg.nStartPage = START_PAGE_GENERAL;

            // See if a range has been selected
            size_t startPos = SendEditor(SCI_GETSELECTIONSTART);
            size_t endPos = SendEditor(SCI_GETSELECTIONEND);

            if (startPos == endPos)
                pdlg.Flags |= PD_NOSELECTION;
            else
                pdlg.Flags |= PD_SELECTION;

            HRESULT hResult = PrintDlgEx(&pdlg);
            if ((hResult != S_OK) || (pdlg.dwResultAction != PD_RESULT_PRINT))
                return 0;

            // reset all indicators
            size_t endpos = SendEditor(SCI_GETLENGTH);
            for (int i = INDIC_CONTAINER; i <= INDIC_MAX; ++i)
            {
                SendEditor(SCI_SETINDICATORCURRENT, i);
                SendEditor(SCI_INDICATORCLEARRANGE, 0, endpos);
            }
            // store and reset UI settings
            int viewws = (int)SendEditor(SCI_GETVIEWWS);
            SendEditor(SCI_SETVIEWWS, 0);
            int edgemode = (int)SendEditor(SCI_GETEDGEMODE);
            SendEditor(SCI_SETEDGEMODE, EDGE_NONE);
            SendEditor(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END);

            HDC hdc = pdlg.hDC;

            RECT rectMargins, rectPhysMargins;
            POINT ptPage;
            POINT ptDpi;

            // Get printer resolution
            ptDpi.x = GetDeviceCaps(hdc, LOGPIXELSX);    // dpi in X direction
            ptDpi.y = GetDeviceCaps(hdc, LOGPIXELSY);    // dpi in Y direction

            // Start by getting the physical page size (in device units).
            ptPage.x = GetDeviceCaps(hdc, PHYSICALWIDTH);   // device units
            ptPage.y = GetDeviceCaps(hdc, PHYSICALHEIGHT);  // device units

            // Get the dimensions of the unprintable
            // part of the page (in device units).
            rectPhysMargins.left = GetDeviceCaps(hdc, PHYSICALOFFSETX);
            rectPhysMargins.top = GetDeviceCaps(hdc, PHYSICALOFFSETY);

            // To get the right and lower unprintable area,
            // we take the entire width and height of the paper and
            // subtract everything else.
            rectPhysMargins.right = ptPage.x                        // total paper width
                - GetDeviceCaps(hdc, HORZRES)                       // printable width
                - rectPhysMargins.left;                             // left unprintable margin

            rectPhysMargins.bottom = ptPage.y                       // total paper height
                - GetDeviceCaps(hdc, VERTRES)                       // printable height
                - rectPhysMargins.top;                              // right unprintable margin

            TCHAR localeInfo[3] = { 0 };
            GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3);
            // Metric system. '1' is US System
            int defaultMargin = localeInfo[0] == '0' ? 2540 : 1000;
            RECT pagesetupMargin;
            CRegStdDWORD m_regMargLeft   = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmarginleft", defaultMargin);
            CRegStdDWORD m_regMargTop    = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmargintop", defaultMargin);
            CRegStdDWORD m_regMargRight  = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmarginright", defaultMargin);
            CRegStdDWORD m_regMargBottom = CRegStdDWORD(L"Software\\TortoiseSVN\\UDiffpagesetupmarginbottom", defaultMargin);

            pagesetupMargin.left   = (long)(DWORD)m_regMargLeft;
            pagesetupMargin.top    = (long)(DWORD)m_regMargTop;
            pagesetupMargin.right  = (long)(DWORD)m_regMargRight;
            pagesetupMargin.bottom = (long)(DWORD)m_regMargBottom;

            if (pagesetupMargin.left != 0 || pagesetupMargin.right != 0 ||
                pagesetupMargin.top != 0 || pagesetupMargin.bottom != 0)
            {
                RECT rectSetup;

                // Convert the hundredths of millimeters (HiMetric) or
                // thousandths of inches (HiEnglish) margin values
                // from the Page Setup dialog to device units.
                // (There are 2540 hundredths of a mm in an inch.)
                if (localeInfo[0] == '0')
                {
                    // Metric system. '1' is US System
                    rectSetup.left      = MulDiv (pagesetupMargin.left, ptDpi.x, 2540);
                    rectSetup.top       = MulDiv (pagesetupMargin.top, ptDpi.y, 2540);
                    rectSetup.right     = MulDiv(pagesetupMargin.right, ptDpi.x, 2540);
                    rectSetup.bottom    = MulDiv(pagesetupMargin.bottom, ptDpi.y, 2540);
                }
                else
                {
                    rectSetup.left      = MulDiv(pagesetupMargin.left, ptDpi.x, 1000);
                    rectSetup.top       = MulDiv(pagesetupMargin.top, ptDpi.y, 1000);
                    rectSetup.right     = MulDiv(pagesetupMargin.right, ptDpi.x, 1000);
                    rectSetup.bottom    = MulDiv(pagesetupMargin.bottom, ptDpi.y, 1000);
                }

                // Don't reduce margins below the minimum printable area
                rectMargins.left    = max(rectPhysMargins.left, rectSetup.left);
                rectMargins.top     = max(rectPhysMargins.top, rectSetup.top);
                rectMargins.right   = max(rectPhysMargins.right, rectSetup.right);
                rectMargins.bottom  = max(rectPhysMargins.bottom, rectSetup.bottom);
            }
            else
            {
                rectMargins.left    = rectPhysMargins.left;
                rectMargins.top     = rectPhysMargins.top;
                rectMargins.right   = rectPhysMargins.right;
                rectMargins.bottom  = rectPhysMargins.bottom;
            }

            // rectMargins now contains the values used to shrink the printable
            // area of the page.

            // Convert device coordinates into logical coordinates
            DPtoLP(hdc, (LPPOINT) &rectMargins, 2);
            DPtoLP(hdc, (LPPOINT)&rectPhysMargins, 2);

            // Convert page size to logical units and we're done!
            DPtoLP(hdc, (LPPOINT) &ptPage, 1);


            DOCINFO di = {sizeof(DOCINFO), 0, 0, 0, 0};
            di.lpszDocName = m_filename.c_str();
            di.lpszOutput = 0;
            di.lpszDatatype = 0;
            di.fwType = 0;
            if (::StartDoc(hdc, &di) < 0)
            {
                ::DeleteDC(hdc);
                return 0;
            }

            size_t lengthDoc = SendEditor(SCI_GETLENGTH);
            size_t lengthDocMax = lengthDoc;
            size_t lengthPrinted = 0;

            // Requested to print selection
            if (pdlg.Flags & PD_SELECTION)
            {
                if (startPos > endPos)
                {
                    lengthPrinted = endPos;
                    lengthDoc = startPos;
                }
                else
                {
                    lengthPrinted = startPos;
                    lengthDoc = endPos;
                }

                if (lengthDoc > lengthDocMax)
                    lengthDoc = lengthDocMax;
            }

            // We must subtract the physical margins from the printable area
            Sci_RangeToFormat frPrint;
            frPrint.hdc             = hdc;
            frPrint.hdcTarget       = hdc;
            frPrint.rc.left         = rectMargins.left - rectPhysMargins.left;
            frPrint.rc.top          = rectMargins.top - rectPhysMargins.top;
            frPrint.rc.right        = ptPage.x - rectMargins.right - rectPhysMargins.left;
            frPrint.rc.bottom       = ptPage.y - rectMargins.bottom - rectPhysMargins.top;
            frPrint.rcPage.left     = 0;
            frPrint.rcPage.top      = 0;
            frPrint.rcPage.right    = ptPage.x - rectPhysMargins.left - rectPhysMargins.right - 1;
            frPrint.rcPage.bottom   = ptPage.y - rectPhysMargins.top - rectPhysMargins.bottom - 1;

            // Print each page
            while (lengthPrinted < lengthDoc)
            {
                ::StartPage(hdc);

                frPrint.chrg.cpMin = (long)lengthPrinted;
                frPrint.chrg.cpMax = (long)lengthDoc;

                lengthPrinted = SendEditor(SCI_FORMATRANGE, true, reinterpret_cast<LPARAM>(&frPrint));

                ::EndPage(hdc);
            }

            SendEditor(SCI_FORMATRANGE, FALSE, 0);

            ::EndDoc(hdc);
            ::DeleteDC(hdc);

            if (pdlg.hDevMode != NULL)
                GlobalFree(pdlg.hDevMode);
            if (pdlg.hDevNames != NULL)
                GlobalFree(pdlg.hDevNames);
            if (pdlg.lpPageRanges != NULL)
                GlobalFree(pdlg.lpPageRanges);

            // reset the UI
            SendEditor(SCI_SETVIEWWS, viewws);
            SendEditor(SCI_SETEDGEMODE, edgemode);
            SendEditor(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_NONE);
        }
        break;
    default:
        break;
    };
    return 1;
}
Exemple #6
0
void OnMenuPrint(WindowInfo *win, bool waitForCompletion)
{
    // we remember some printer settings per process
    static ScopedMem<DEVMODE> defaultDevMode;
    static PrintScaleAdv defaultScaleAdv = PrintScaleShrink;
    static bool defaultAsImage = false;

    static bool hasDefaults = false;
    if (!hasDefaults) {
        hasDefaults = true;
        defaultAsImage = gGlobalPrefs->printerDefaults.printAsImage;
        if (str::EqI(gGlobalPrefs->printerDefaults.printScale, "fit"))
            defaultScaleAdv = PrintScaleFit;
        else if (str::EqI(gGlobalPrefs->printerDefaults.printScale, "none"))
            defaultScaleAdv = PrintScaleNone;
    }

    bool printSelection = false;
    Vec<PRINTPAGERANGE> ranges;
    PRINTER_INFO_2 printerInfo = { 0 };

    if (!HasPermission(Perm_PrinterAccess))
        return;

    if (win->AsChm()) {
        // the Print dialog allows access to the file system, so fall back
        // to printing the entire document without dialog if that isn't desired
        bool showUI = HasPermission(Perm_DiskAccess);
        win->AsChm()->PrintCurrentPage(showUI);
        return;
    }
    if (win->AsEbook()) {
        // TODO: use EbookEngine for printing?
        return;
    }

    CrashIf(!win->AsFixed());
    if (!win->AsFixed()) return;
    DisplayModel *dm = win->AsFixed();

#ifndef DISABLE_DOCUMENT_RESTRICTIONS
    if (!dm->engine()->AllowsPrinting())
        return;
#endif

    if (win->printThread) {
        int res = MessageBox(win->hwndFrame, 
                             _TR("Printing is still in progress. Abort and start over?"),
                             _TR("Printing in progress."),
                             MB_ICONEXCLAMATION | MB_YESNO | MbRtlReadingMaybe());
        if (res == IDNO)
            return;
    }
    AbortPrinting(win);

    // the Print dialog allows access to the file system, so fall back
    // to printing the entire document without dialog if that isn't desired
    if (!HasPermission(Perm_DiskAccess)) {
        PrintFile(dm->engine());
        return;
    }

    PRINTDLGEX pd;
    ZeroMemory(&pd, sizeof(PRINTDLGEX));
    pd.lStructSize = sizeof(PRINTDLGEX);
    pd.hwndOwner   = win->hwndFrame;
    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
    if (!win->selectionOnPage)
        pd.Flags |= PD_NOSELECTION;
    pd.nCopies     = 1;
    /* by default print all pages */
    pd.nPageRanges = 1;
    pd.nMaxPageRanges = MAXPAGERANGES;
    PRINTPAGERANGE *ppr = AllocArray<PRINTPAGERANGE>(MAXPAGERANGES);
    pd.lpPageRanges = ppr;
    ppr->nFromPage = 1;
    ppr->nToPage = dm->PageCount();
    pd.nMinPage = 1;
    pd.nMaxPage = dm->PageCount();
    pd.nStartPage = START_PAGE_GENERAL;

    Print_Advanced_Data advanced(PrintRangeAll, defaultScaleAdv, defaultAsImage);
    ScopedMem<DLGTEMPLATE> dlgTemplate; // needed for RTL languages
    HPROPSHEETPAGE hPsp = CreatePrintAdvancedPropSheet(&advanced, dlgTemplate);
    pd.lphPropertyPages = &hPsp;
    pd.nPropertyPages = 1;

    // restore remembered settings
    if (defaultDevMode) {
        DEVMODE *p = defaultDevMode.Get();
        pd.hDevMode = GlobalMemDup(p, p->dmSize + p->dmDriverExtra);
    }

    if (PrintDlgEx(&pd) != S_OK) {
        if (CommDlgExtendedError() != 0) {
            /* if PrintDlg was cancelled then
               CommDlgExtendedError is zero, otherwise it returns the
               error code, which we could look at here if we wanted.
               for now just warn the user that printing has stopped
               becasue of an error */
            MessageBoxWarning(win->hwndFrame, _TR("Couldn't initialize printer"), 
                              _TR("Printing problem."));
        }
        goto Exit;
    }

    if (pd.dwResultAction == PD_RESULT_PRINT || pd.dwResultAction == PD_RESULT_APPLY) {
        // remember settings for this process
        LPDEVMODE devMode = (LPDEVMODE)GlobalLock(pd.hDevMode);
        if (devMode) {
            defaultDevMode.Set((LPDEVMODE)memdup(devMode, devMode->dmSize + devMode->dmDriverExtra));
            GlobalUnlock(pd.hDevMode);
        }
        defaultScaleAdv = advanced.scale;
        defaultAsImage = advanced.asImage;
    }

    if (pd.dwResultAction != PD_RESULT_PRINT)
        goto Exit;

    if (pd.Flags & PD_CURRENTPAGE) {
        PRINTPAGERANGE pr = { dm->CurrentPageNo(), dm->CurrentPageNo() };
        ranges.Append(pr);
    } else if (win->selectionOnPage && (pd.Flags & PD_SELECTION)) {
        printSelection = true;
    } else if (!(pd.Flags & PD_PAGENUMS)) {
        PRINTPAGERANGE pr = { 1, dm->PageCount() };
        ranges.Append(pr);
    } else {
        assert(pd.nPageRanges > 0);
        for (DWORD i = 0; i < pd.nPageRanges; i++)
            ranges.Append(pd.lpPageRanges[i]);
    }

    LPDEVNAMES devNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
    LPDEVMODE devMode = (LPDEVMODE)GlobalLock(pd.hDevMode);
    if (devNames) {
        printerInfo.pDriverName = (LPWSTR)devNames + devNames->wDriverOffset;
        printerInfo.pPrinterName = (LPWSTR)devNames + devNames->wDeviceOffset;
        printerInfo.pPortName = (LPWSTR)devNames + devNames->wOutputOffset;
    }
    PrintData *data = new PrintData(dm->engine(), &printerInfo, devMode, ranges, advanced,
                                    dm->GetRotation(), printSelection ? win->selectionOnPage : NULL);
    if (devNames)
        GlobalUnlock(pd.hDevNames);
    if (devMode)
        GlobalUnlock(pd.hDevMode);

    // if a file is missing and the engine can't thus be cloned,
    // we print using the original engine on the main thread
    // so that the document can't be closed and the original engine
    // unexpectedly deleted
    // TODO: instead prevent closing the document so that printing
    // can still happen on a separate thread and be interruptible
    bool failedEngineClone = dm->engine() && !data->engine;
    if (failedEngineClone)
        data->engine = dm->engine();

    if (!waitForCompletion && !failedEngineClone)
        PrintToDeviceOnThread(win, data);
    else {
        PrintToDevice(*data);
        if (failedEngineClone)
            data->engine = NULL;
        delete data;
    }

Exit:
    free(ppr);
    GlobalFree(pd.hDevNames);
    GlobalFree(pd.hDevMode);
}
Exemple #7
0
void
DumpPrinter(HWND hwnd, LPTSTR szAppName, LPTSTR szFileName)
{
    PRINTDLGEX pd;
    DEVNAMES * pDevNames;
    LPCTSTR szDevice;
    GP_PRINT pr;
    HANDLE printer;
    DOC_INFO_1 di;
    DWORD jobid;
    HRESULT hr;
    LPSTR buf;
    int count;
    FILE *f;
    long lsize;
    long ldone;
    TCHAR pcdone[10];

    if ((f = _tfopen(szFileName, TEXT("rb"))) == NULL)
	return;
    fseek(f, 0L, SEEK_END);
    lsize = ftell(f);
    if (lsize <= 0)
	lsize = 1;
    fseek(f, 0L, SEEK_SET);
    ldone = 0;

    /* Print Property Sheet  */
    /* See http://support.microsoft.com/kb/240082 */
    memset(&pd, 0, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.hwndOwner = hwnd;
    pd.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE | PD_USEDEVMODECOPIESANDCOLLATE;
    pd.hDevNames = hDevNames;
    pd.hDevMode = hDevMode;
    pd.hDevNames = NULL;
    pd.hDevMode = NULL;
    pd.nCopies = 1;
    pd.nStartPage = START_PAGE_GENERAL;

    /* Replace the additional options in the lower part of the dialog with
     * a hint to change print options via terminal options.
     */
    pd.lpPrintTemplateName = TEXT("PrintDlgExSelect");
    pd.hInstance = graphwin->hInstance;
    pd.Flags |= PD_ENABLEPRINTTEMPLATE;

    if ((hr = PrintDlgEx(&pd)) != S_OK) {
	DWORD error = CommDlgExtendedError();
	fprintf(stderr, "\nError:  Opening the print dialog failed with error code %04x (%04x).\n", hr, error);
    }

    if (pd.dwResultAction == PD_RESULT_PRINT) {
	pDevNames = (DEVNAMES *) GlobalLock(pd.hDevNames);
	szDevice = (LPCTSTR)pDevNames + pDevNames->wDeviceOffset;
	if (!OpenPrinter((LPTSTR)szDevice, &printer, NULL))
		printer = NULL;
	GlobalUnlock(pd.hDevNames);
	/* We no longer free these structures, but preserve them for the next time
	GlobalFree(pd.hDevMode);
	GlobalFree(pd.hDevNames);
	*/
	hDevNames = pd.hDevNames;
	hDevMode = pd.hDevMode;

	if (printer == NULL)
	    return;	/* abort */

	pr.hdcPrn = printer;
	PrintRegister(&pr);
	if ((buf = (LPSTR) malloc(4096)) != NULL) {
	    EnableWindow(hwnd, FALSE);
	    pr.bUserAbort = FALSE;
	    pr.szTitle = szAppName;
	    pr.hDlgPrint = CreateDialogParam(hdllInstance, TEXT("CancelDlgBox"),
						hwnd, PrintDlgProc, (LPARAM) &pr);
	    SendMessage(GetDlgItem(pr.hDlgPrint, CANCEL_PROGRESS), PBM_SETRANGE32, 0, lsize);

	    di.pDocName = szAppName;
	    di.pOutputFile = NULL;
	    di.pDatatype = TEXT("RAW");
	    if ((jobid = StartDocPrinter(printer, 1, (LPBYTE) &di)) > 0) {
		while (pr.hDlgPrint && !pr.bUserAbort &&
		       (count = fread(buf, 1, 4096, f)) != 0 ) {
		    int ret;
		    DWORD dwBytesWritten;

		    ret = WritePrinter(printer, buf, count, &dwBytesWritten);
		    ldone += count;
		    if (dwBytesWritten > 0) {
			wsprintf(pcdone, TEXT("%d%% done"), (int)(ldone * 100 / lsize));
			SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), pcdone);
			SendMessage(GetDlgItem(pr.hDlgPrint, CANCEL_PROGRESS), PBM_SETPOS, ldone, 0);
		    } else if (ret == 0) {
			SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), TEXT("Error writing to printer!"));
			pr.bUserAbort  = TRUE;
		    }

		    /* handle window messages */
		    PrintAbortProc(printer, 0);
		}
		if (pr.bUserAbort) {
		    if (SetJob(printer, jobid, 0, NULL, JOB_CONTROL_DELETE) == 0) {
			SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), TEXT("Error: Failed to cancel print job!"));
			fprintf(stderr, "Error: Failed to cancel print job!\n");
		    }
		}
		EndDocPrinter(printer);
		if (!pr.bUserAbort) {
		    EnableWindow(hwnd, TRUE);
		    DestroyWindow(pr.hDlgPrint);
		}
		free(buf);
	    }
	}
	ClosePrinter(printer);
	PrintUnregister(&pr);
    }
    fclose(f);
}