No announcement yet.

Problem with my Rich Edit print preview

  • Filter
  • Time
  • Show
Clear All
new posts

  • 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

  • #2
    Charles, just searched for "vista stretchblt" and found this - does it help?


    • #3
      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.


      • #4
        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.

          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
           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
              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"
                 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
                       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
                    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
                 END IF
              CASE %WM_VSCROLL
                    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
                    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
           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