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: