Announcement

Collapse
No announcement yet.

Problem with my Rich Edit print preview

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Charles Dietz
    replied
    Problem solved

    As Chris surmised, 'StretchDIBits' is required for Vista. I had to change only the following callback function to incorporate that API. I'm embarrassed to admit how many hours I required getting there, even making heavy use of Poffs2, and for that reason, I thought others might benefit from the code.

    Code:
    TYPE MyBITMAPINFO
      bmiHeader AS BITMAPINFOHEADER
      bmiColors(0 TO 1) AS RGBQUAD
    END TYPE
    
    CALLBACK FUNCTION printPreviewProc()
       LOCAL hdc AS DWORD, xppi, yppi, hPrnDC, hOldBmp, result AS LONG
       LOCAL ps AS PAINTSTRUCT, s AS STRING, wi, ht AS SINGLE
       STATIC bm AS BITMAP                  'bitmap of rich edit page
       STATIC bmBits AS STRING             'string serving as memory for DIB bits
       STATIC bmSize AS LONG               'space needed by bitmap bits
       STATIC bmInfo AS myBITMAPINFO       'structure defining properties of a DIB
       STATIC bitsPtr AS STRING PTR        'pointer to string memory
       STATIC nWi, nHt, nx, ny, xp, yp, x, y, kx, ky AS DWORD
       STATIC nPage, numPages, dPages, lastPage, hVScroll, hHScroll AS LONG
       STATIC memdc, hBmp AS DWORD, zoom AS SINGLE, si, ssi AS SCROLLINFO, r AS rect
       SELECT CASE CBMSG
          CASE %WM_INITDIALOG
             'create window that proportionally matches printed paper 
             'with hidden scrollbars for zoom feature
             IF PRINTERCOUNT = 0 THEN
                MSGBOX "No windows printers are connected", %MB_ICONERROR, "Initialize Print Preview"
                DIALOG END CBHNDL: EXIT FUNCTION
             END IF
             XPRINT ATTACH DEFAULT
             XPRINT GET CLIENT TO wi, ht
             XPRINT GET DC TO hPrnDC
             hdc = GetDC(CBHNDL)
             xppi = GetDeviceCaps(hdc, %LOGPIXELSX)
             yppi = GetDeviceCaps(hdc, %LOGPIXELSY)
             nHt = .90 * GetDeviceCaps(hdc, %VERTRES) - 90
             nWi = (wi/ht) * (xppi / yppi) * nHt
             x = MAX(460, nWi + 60)
             DIALOG SET CLIENT CBHNDL, x, nHt + 60
             DIALOG SET LOC CBHNDL, 100, 10
             nx = (x - nWi - 9)/2: ny = 30
             CONTROL SET SIZE CBHNDL, %IDC_VScroll, 18, nHt
             CONTROL SET LOC CBHNDL, %IDC_VScroll, nx + nWi, ny
             CONTROL SET SIZE CBHNDL, %IDC_HScroll, nWi, 18
             CONTROL SET LOC CBHNDL, %IDC_HScroll, nx, nHt + ny
             CONTROL SHOW STATE CBHNDL, %IDC_VScroll, %SW_HIDE
             CONTROL SHOW STATE CBHNDL, %IDC_HScroll, %SW_HIDE
             CONTROL HANDLE CBHNDL, %IDC_VScroll TO hVScroll
             CONTROL HANDLE CBHNDL, %IDC_HScroll TO hHScroll
    
             memdc = CreateCompatibleDC(hPrnDC)
             hBmp = CreateCompatibleBitmap(hPrnDC, wi, ht)
             SelectObject memdc, hBmp
             
             'initialize info for DIB (device independent bitmap)
             bmInfo.bmiHeader.biSize = SIZEOF(bmInfo.bmiHeader)
             bmInfo.bmiHeader.biWidth = wi
             bmInfo.bmiHeader.biHeight = ht
             bmInfo.bmiHeader.biPlanes = 1
             bmInfo.bmiHeader.biBitCount = 1 'monochrome
             bmInfo.bmiHeader.biCompression = %BI_RGB
             bmInfo.bmiColors(0).rgbBlue = 255
             bmInfo.bmiColors(0).rgbGreen = 255
             bmInfo.bmiColors(0).rgbRed = 255
             bmInfo.bmiColors(1).rgbBlue = 0
             bmInfo.bmiColors(1).rgbGreen = 0
             bmInfo.bmiColors(1).rgbRed = 0
             
             'create string for DIB memory space [bmBits]
             'and calculate size needed it [bmSize]
             bmBits = STRING$(SIZEOF(BITMAPINFOHEADER), 0)
             bmSize = wi  
             bmSize = (bmSize + 1) / 8
             bmSize = ((bmSize + 3) / 4) * 4
             bmSize = bmSize * ht
             bmBits = bmBits + STRING$(bmSize, 0)
             bitsPtr = STRPTR(bmbits) + SIZEOF(BITMAPINFOHEADER)
             
             'initialize top controls for specifying pages to preview
             xp = wi: yp = ht: zoom = 1: x = 0: y = 0
             numPages = printRTF(hPrnDC, -1, 0, -1)
             IF numPages THEN
                nPage = 1: CONTROL SET TEXT CBHNDL, %IDC_PageNo, " 1": GOSUB previewPage
             END IF
             dPages = MAX(numPages / 10, 5)
             r.nLeft = nx: r.nTop = ny
             r.nRight = r.nLeft + nWi: r.nBottom = r.nTop + nHt
             CONTROL SET TEXT CBHNDL, %IDC_NumPages, "of" + STR$(numPages) + " pages"
             CONTROL SEND CBHNDL, %IDC_PageNo, %EM_SETSEL, -1, 0
             CONTROL SET FOCUS CBHNDL, %IDC_PageNo
          CASE %WM_PAINT
             hdc = BeginPaint(CBHNDL, ps)
             result = StretchDIBits(hdc, nx, ny, nWi, nHt, x, y, xp/zoom, yp/zoom, _
                      BYVAL bitsPtr, BYVAL VARPTR(bmInfo), %DIB_RGB_COLORS, %SRCCOPY)
             EndPaint CBHNDL, ps
          CASE %WM_COMMAND
             IF CBCTL = %IDC_Fwd THEN
                IF nPage < numPages THEN INCR nPage: GOSUB previewPage
             ELSEIF CBCTL = %IDC_Bwd THEN
                IF nPage > 1 THEN DECR nPage: GOSUB previewPage
             ELSEIF CBCTL = %IDC_FastFwd THEN
                nPage = MIN(nPage + dPages, numPages)
                IF nPage <> lastPage THEN GOSUB previewPage
             ELSEIF CBCTL = %IDC_FastBwd THEN
                nPage = MAX(nPage - dPages, 1)
                IF nPage <> lastPage THEN GOSUB previewPage
             ELSEIF CBCTL = %IDOK THEN 'clicked ENTER key
                CONTROL GET TEXT CBHNDL, %IDC_PageNo TO s
                IF VAL(s) THEN
                   nPage = MAX(1, MIN(VAL(s), numPages))
                   CONTROL SET TEXT CBHNDL, %IDC_PageNo, STR$(nPage)
                   IF nPage <> lastPage THEN
                      lastPage = nPage: zoom = 2.25
                      GOSUB previewPage
                   END IF
                END IF
             ELSEIF CBCTL = %IDCANCEL THEN 'clicked ESC key
                DIALOG END CBHNDL
             ELSEIF CBCTL = %IDC_Zoom THEN
                zoom = 1.5 * zoom: IF zoom > 2.25 THEN zoom = 1
                IF zoom > 1 THEN
                   CONTROL SHOW STATE CBHNDL, %IDC_VScroll, %SW_SHOW
                   CONTROL SHOW STATE CBHNDL, %IDC_HScroll, %SW_SHOW
                   si.cbSize = LEN(si)
                   si.fMask  = %SIF_ALL
                   si.nPage = (1 - 1/zoom)*yp/4
                   si.nMax  = 5 * si.nPage
                   si.nPos   = 0   'ky * si.nPage
                   SetScrollInfo hVScroll, %SB_CTL, si, 1
                   ssi.cbSize = LEN(ssi)
                   ssi.fMask  = %SIF_ALL
                   ssi.nPage = (1 - 1/zoom)*xp/4
                   ssi.nMax  = 5 * ssi.nPage
                   ssi.nPos   = 0   'kx * ssi.nPage
                   SetScrollInfo hHScroll, %SB_CTL, ssi, 1
                   x = ssi.nPos: y = 4 * si.nPage  'y = si.nPos
                ELSE
                   x = 0: y = 0
                   CONTROL SHOW STATE CBHNDL, %IDC_VScroll, %SW_HIDE
                   CONTROL SHOW STATE CBHNDL, %IDC_HScroll, %SW_HIDE
                END IF
                InvalidateRect CBHNDL, r, 0
             ELSEIF CBCTL = %IDC_Print THEN
                printFile
             ELSE
                EXIT FUNCTION
             END IF
             IF zoom > 1 AND CBCTL < %IDC_Zoom THEN
                zoom = 2.25: DIALOG SEND CBHNDL, %WM_COMMAND, %IDC_Zoom, 0
             END IF
             IF CBCTL < %IDC_Print THEN 'clear visible focus of buttons pressed
                CONTROL SEND CBHNDL, CBCTL, %BM_SETSTYLE, %BS_PUSHBUTTON, %TRUE
             END IF
          CASE %WM_VSCROLL
             SELECT CASE LOWRD(CBWPARAM)
                CASE %SB_LINEDOWN, %SB_PAGEDOWN 
                   si.nPos = MAX(si.nPos + si.nPage, si.nMin): y = y - si.nPage
                CASE %SB_LINEUP, %SB_PAGEUP
                   si.nPos = MIN(si.nPos - si.nPage, si.nMax - si.nPage): y = y + si.nPage
                CASE %SB_THUMBTRACK
                   si.nPos = MIN(HIWRD(CBWPARAM), si.nMax - si.nPage): y = 4 * si.nPage - si.nPos
                CASE ELSE
                   EXIT FUNCTION
             END SELECT
             InvalidateRect CBHNDL, r, 0
             si.cbSize = SIZEOF(si)
             si.fMask = %SIF_POS OR %SIF_PAGE
             SetScrollInfo hVScroll, %SB_CTL, si, 1
          CASE %WM_HSCROLL
             SELECT CASE LOWRD(CBWPARAM)
                CASE %SB_LINEDOWN, %SB_PAGEDOWN
                   ssi.nPos = MIN(ssi.nPos + ssi.nPage, ssi.nMax - ssi.nPage): x = x + ssi.nPage
                CASE %SB_LINEUP, %SB_PAGEUP
                   ssi.nPos = MAX(ssi.nPos - ssi.nPage, ssi.nMin): x = x - ssi.nPage
                CASE %SB_THUMBTRACK
                   ssi.nPos = MIN(HIWRD(CBWPARAM), ssi.nMax - ssi.nPage): x = ssi.nPos
                CASE ELSE
                   EXIT FUNCTION
             END SELECT
             InvalidateRect CBHNDL, r, 0 
             ssi.cbSize = SIZEOF(ssi)
             ssi.fMask = %SIF_POS OR %SIF_PAGE
             SetScrollInfo hHScroll, %SB_CTL, ssi, 1
          CASE %WM_DESTROY
             DeleteDC memdc
             DeleteObject hBmp
             XPRINT CANCEL
       END SELECT
       EXIT FUNCTION
    previewPage:
       IF nPage THEN
          PatBlt memdc, 0, 0, xp, yp, %PATCOPY
          printRTF memdc, 0, pageEnd(nPage-1) + 1, pageEnd(nPage)
          GetDIBits(memDC, hBmp, 0, yp, BYVAL bitsPtr, BYVAL VARPTR(bmInfo), %DIB_RGB_COLORS)
          InvalidateRect CBHNDL, r, 0: lastPage = nPage
          CONTROL SET TEXT CBHNDL, %IDC_PageNo, STR$(MIN(nPage, numPages))
       END IF
       RETURN
    END FUNCTION

    Leave a comment:


  • Charles Dietz
    replied
    Thanks Chris. You may very well have the answer. I googled with only "stretchblt", and did not find what you did... I should have searched with "Vista stretchblt", as you did.

    Anyway, now I have to figure out how to implement the stretchDIBits function. It looks kind of complicated. I'll report back what the results are. Thanks, again.

    Leave a comment:


  • Chris Holbrook
    replied
    Charles, just searched for "vista stretchblt" and found this - does it help?

    Leave a comment:


  • Charles Dietz
    started a topic Problem with my Rich Edit print preview

    Problem with my Rich Edit print preview

    This code demonstrates a problem I am having running it on my Vista laptop. The code runs properly on my two other computers with XP. The problem is with the StretchBlt() function under %WM_PAINT of the PrintPreview callback. It returns a result of 0 for my Vista laptop, but 1 for my other two computers... same printers, same code, same compiler. I though that over the last year, I must have used the print preview feature on this laptop, but maybe not.

    Although this technique is slow, it does give very accurate previews, even showing the slight differences for different printers due to their differing dead spaces. So I would like to keep the algorithm, but for the life of me, I can't detect what's wrong... so I am hoping that one of you GUI experts can spot what is going on. The code is attached as PrnPreview.bas, and any text or rtf file can be opened.
    Attached Files
Working...
X