by Jurjen, improved by Ian Keene
/* ============================================================== file : printscreen.p by : Jurjen Dijkstra (Modified by Ian Keene Oct 2003) dd : 05/16/1999 purpose : draw a window to the default printer. usage : RUN printscreen.p ({&WINDOW-NAME}:HWND, YES). parms : hWindow (integer) HWND of the 'widget' to be drawn GetParent (logical) -Use YES if HWND is a Progress window widget so printscreen.p will draw the border/titlebar. -Use NO for all other widgets. ============================================================== */ DEFINE INPUT PARAMETER hWindow AS INTEGER NO-UNDO. /* HWND */ DEFINE INPUT PARAMETER GetParent AS LOGICAL NO-UNDO. /* hWindow=GetParent(hWindow)? */ RUN MakeDocument. /* API definitions used in this proc have been moved to printscreen.i */ {printscreen.i} PROCEDURE MakeDocument : DEFINE VARIABLE hDC AS INTEGER NO-UNDO. DEFINE VARIABLE lpDocInfo AS MEMPTR NO-UNDO. DEFINE VARIABLE lpDocName AS MEMPTR NO-UNDO. DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO. DEFINE VARIABLE prt-buf AS CHARACTER NO-UNDO. DEFINE VARIABLE prt-out AS CHARACTER NO-UNDO. DEFINE VARIABLE err-check AS INTEGER NO-UNDO. DEFINE VARIABLE drbuf AS CHARACTER NO-UNDO. DEFINE VARIABLE out-buf AS CHARACTER NO-UNDO. DEFINE VARIABLE prt-hwnd AS INTEGER NO-UNDO. ASSIGN prt-out = FILL(" ",127). /* ALLOCATE MEMORY */ RUN GetProfileStringA (INPUT "WINDOWS", INPUT "DEVICE", INPUT "-unknown-,", OUTPUT prt-out, INPUT LENGTH(prt-out), OUTPUT err-check). IF prt-out = "-unknown-," THEN DO: MESSAGE "Aborted, Cannot Determine Default Printer." SKIP VIEW-AS ALERT-BOX INFORMATION. RETURN. END. ASSIGN prt-buf = ENTRY(1,prt-out) drbuf = ENTRY(2,prt-out) out-buf = ENTRY(3,prt-out). /* OPEN THE PRINTER */ RUN OpenPrinterA (INPUT prt-buf, OUTPUT prt-hwnd, INPUT 0). RUN CreateDCA ( "WINSPOOL", prt-buf, 0, 0, OUTPUT hDC) . IF hDC = 0 THEN DO: MESSAGE "Error during CreateDCA in PrintScreen procedure" view-as ALERT-BOX INFORMATION. RETURN. END. SET-SIZE (lpDocName) = LENGTH("PrintScreen") + 1. PUT-STRING(lpDocName,1) = "PrintScreen". SET-SIZE (lpDocInfo) = 12. PUT-LONG (lpDocInfo,1) = 12. PUT-LONG (lpDocInfo,5) = GET-POINTER-VALUE(lpDocName). PUT-LONG (lpDocInfo,9) = 0. RUN StartDocA ( hDC, GET-POINTER-VALUE(lpDocInfo), OUTPUT ReturnValue). IF ReturnValue < 1 THEN MESSAGE "Error during StartDoc in PrintScreen procedure" view-as ALERT-BOX INFORMATION. ELSE DO: RUN StartPage (hDC, OUTPUT ReturnValue). IF ReturnValue < 1 THEN MESSAGE "Error during StartPage in PrintScreen procedure" view-as ALERT-BOX INFORMATION. ELSE DO: RUN PrintWindow (hDC, hWindow). RUN EndPage (hDC, OUTPUT ReturnValue). END. RUN EndDoc (hDC, OUTPUT ReturnValue). END. /* cleanup */ RUN DeleteDC (hDC, OUTPUT ReturnValue). SET-SIZE(lpDocInfo) = 0. SET-SIZE(lpDocName) = 0. END PROCEDURE. /* MakeDocument */ PROCEDURE PrintWindow : /*------------------------------------------------------------------------------ Notes: a couple of extra parameters would be nice, like: input leftmargin, rightmargin, Ytop output Ybottom ------------------------------------------------------------------------------*/ define input parameter hdcDest as INTEGER NO-UNDO. /* Printer */ define input parameter hWin as INTEGER NO-UNDO. /* windows handle to progress window to print */ DEFINE VARIABLE hdcWin as integer no-undo. /* hdc window */ DEFINE VARIABLE PrintHorzRes as integer no-undo. /* printer resolution */ DEFINE VARIABLE PrintVertRes as integer no-undo. DEFINE VARIABLE WinHorzRes as integer no-undo. /* display resolution */ DEFINE VARIABLE WinVertRes as integer no-undo. DEFINE VARIABLE hdcComp as integer no-undo. /* hdc memory */ DEFINE VARIABLE hbmpComp as integer no-undo. /* bitmap in memory */ DEFINE VARIABLE hbmpDest as integer no-undo. /* bitmap on paper */ DEFINE VARIABLE WinWidth as INTEGER NO-UNDO. /* dimensions of window */ DEFINE VARIABLE WinHeight as INTEGER NO-UNDO. DEFINE VARIABLE PictureWidth as integer no-undo. /* dimensions of picture on paper */ DEFINE VARIABLE PictureHeight as integer no-undo. DEFINE VARIABLE Scale as decimal no-undo. DEFINE VARIABLE xMargin as INTEGER NO-UNDO. /* center picture horizontally */ DEFINE VARIABLE numrows as integer no-undo. /* split large pics into rows/cols */ DEFINE VARIABLE numcols as integer no-undo. DEFINE VARIABLE rw as integer no-undo. DEFINE VARIABLE cl as integer no-undo. DEFINE VARIABLE lpRect as MEMPTR NO-UNDO. DEFINE VARIABLE ReturnValue as integer no-undo. DEFINE VARIABLE lpOrigin as MEMPTR NO-UNDO. IF getParent THEN RUN GetParent(hWin, OUTPUT hWin). /* get the window resolution */ run GetDC (hWin, output hdcWin). run GetDeviceCaps(hdcWin, 8 /* = HorzRes */, output WinHorzRes). run GetDeviceCaps(hdcWin, 10 /* = VertRes */, output WinVertRes). /* get the printer resolution */ run GetDeviceCaps(hdcDest, 8 /* = HorzRes */, output PrintHorzRes). run GetDeviceCaps(hdcDest, 10 /* = VertRes */, output PrintVertRes). /* determine dimensions of the window */ /* Also determine the coordinates of the upper-left corner. This is (0,0) for a client window, but will be somewhere around (-4,-20) for a window with titlebar */ SET-SIZE (lpOrigin) = 8. SET-SIZE (lpRect) = 16. RUN GetWindowRect (hWin, GET-POINTER-VALUE(lpRect) , OUTPUT ReturnValue). WinWidth = GET-LONG(lpRect, 9) - GET-LONG(lpRect, 1). WinHeight = GET-LONG(lpRect,13) - GET-LONG(lpRect, 5). PUT-LONG(lpOrigin, 1) = GET-LONG(lpRect, 1). PUT-LONG(lpOrigin, 5) = GET-LONG(lpRect, 5). RUN ScreenToClient (hWin, GET-POINTER-VALUE(lpOrigin), OUTPUT ReturnValue). SET-SIZE (lpRect) = 0. Scale = MINIMUM(PrintHorzRes / WinWidth, PrintVertRes / WinHeight). IF Scale < 1 THEN Scale = 1. run CreateCompatibleDC (hdcWin, output hdcComp). run CreateCompatibleBitmap (hdcComp, integer(winWidth * Scale), integer(winHeight * Scale), output hbmpComp). run CreateCompatibleBitmap (hdcDest, integer(winWidth * Scale), integer(winHeight * Scale), output hbmpDest). run SelectObject (hdcComp, hbmpComp, output ReturnValue). run SelectObject (hdcDest, hbmpDest, output ReturnValue). run StretchBlt (hdcDest, 0, 0, integer(winwidth * Scale) , integer(winHeight * Scale) , hdcWin, get-long(lpOrigin,1), get-long(lpOrigin,5), winwidth, winheight, 13369376, /* = SRCCOPY */ output ReturnValue). /* cleanup */ run ReleaseDC (hWin, hdcWin, output ReturnValue). run DeleteDC (hdcComp, output ReturnValue). run DeleteObject (hbmpComp, output ReturnValue). run DeleteObject (hbmpDest, output ReturnValue). SET-SIZE(lpOrigin)=0. END PROCEDURE. /* PrintWindow */
/* ============================================================== file : printscreen.i by : Jurjen Dijkstra (Modified by Ian Keene Oct 2003) dd : 05/16/1999 purpose : API definitions used in printscreen.p ============================================================== */ &GLOB GDI "gdi32.dll" &GLOB USER "user32.dll" &GLOB BOOL LONG &GLOB COLORREF LONG &GLOB DWORD LONG &GLOB HANDLE LONG &GLOB HDC LONG &GLOB HGDIOBJ LONG &GLOB HWND LONG &GLOB INTEGER LONG &GLOB LONG LONG &GLOB LP LONG &GLOB LPCSTR CHARACTER &GLOB LPCTSTR CHARACTER &GLOB LPSECURITY_ATTRIBUTES LONG &GLOB LPSTRUCT LONG &GLOB LPTSTR CHARACTER &GLOB SHORT SHORT &GLOB UINT LONG &GLOB WORD SHORT PROCEDURE CreateDCA EXTERNAL {&GDI} : DEFINE INPUT PARAMETER lpszDriver AS {&LPCTSTR} NO-UNDO. DEFINE INPUT PARAMETER lpszDevice AS {&LPCTSTR} NO-UNDO. DEFINE INPUT PARAMETER lpszOutput AS {&LP} NO-UNDO. DEFINE INPUT PARAMETER lpInitData AS {&LPSTRUCT} NO-UNDO. DEFINE RETURN PARAMETER hDC AS {&HDC} NO-UNDO. END PROCEDURE. PROCEDURE StartDocA EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER lpdi AS {&LPSTRUCT} NO-UNDO. DEFINE RETURN PARAMETER JobId AS {&int} NO-UNDO. END PROCEDURE. PROCEDURE StartPage EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&int} NO-UNDO. END PROCEDURE. PROCEDURE EndPage EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&int} NO-UNDO. END PROCEDURE. PROCEDURE EndDoc EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&int} NO-UNDO. END PROCEDURE. PROCEDURE GetParent EXTERNAL {&USER} : DEFINE INPUT PARAMETER hWinHdl AS {&HWND} NO-UNDO. DEFINE RETURN PARAMETER hwndParent AS {&HWND} NO-UNDO. END PROCEDURE. PROCEDURE GetDC EXTERNAL {&USER} : DEFINE INPUT PARAMETER hWinHdl AS {&HWND} NO-UNDO. DEFINE RETURN PARAMETER hdc AS {&HDC} NO-UNDO. END PROCEDURE. PROCEDURE GetDeviceCaps EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER nIndex AS {&int} NO-UNDO. DEFINE RETURN PARAMETER dwCaps AS {&int} NO-UNDO. END PROCEDURE. PROCEDURE GetWindowRect EXTERNAL {&USER} : DEFINE INPUT PARAMETER hWinHdl AS {&HWND} NO-UNDO. DEFINE INPUT PARAMETER lpRect AS {&LPSTRUCT} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE ScreenToClient EXTERNAL {&USER} : DEFINE INPUT PARAMETER hWinHdl AS {&HWND} NO-UNDO. DEFINE INPUT PARAMETER lpPoint AS {&LPSTRUCT} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE CreateCompatibleDC EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE RETURN PARAMETER hdcComp AS {&HDC} NO-UNDO. END PROCEDURE. PROCEDURE CreateCompatibleBitmap EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER nWidth AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nHeight AS {&int} NO-UNDO. DEFINE RETURN PARAMETER hbmp AS {&HANDLE} NO-UNDO. END PROCEDURE. PROCEDURE SelectObject EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER hgdiobj AS {&HGDIOBJ} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&HGDIOBJ} NO-UNDO. END PROCEDURE. PROCEDURE StretchBlt EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdcDest AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER nXOriginDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nYOriginDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nWidthDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nHeightDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER hdcSrc AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER nXOriginSrc AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nYOriginSrc AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nWidthSrc AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nHeightSrc AS {&int} NO-UNDO. DEFINE INPUT PARAMETER dwRop AS {&DWORD} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE BitBlt EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdcDest AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER nXOriginDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nYOriginDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nWidthDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nHeightDest AS {&int} NO-UNDO. DEFINE INPUT PARAMETER hdcSrc AS {&HDC} NO-UNDO. DEFINE INPUT PARAMETER nXOriginSrc AS {&int} NO-UNDO. DEFINE INPUT PARAMETER nYOriginSrc AS {&int} NO-UNDO. DEFINE INPUT PARAMETER dwRop AS {&DWORD} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE ReleaseDC EXTERNAL {&USER} : DEFINE INPUT PARAMETER hWinHdl AS {&HWND} NO-UNDO. DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE DeleteDC EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hdc AS {&HDC} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE DeleteObject EXTERNAL {&GDI} : DEFINE INPUT PARAMETER hObject AS {&HGDIOBJ} NO-UNDO. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL} NO-UNDO. END PROCEDURE. PROCEDURE GetProfileStringA EXTERNAL "kernel32.dll": DEFINE INPUT PARAMETER in-appname AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER in-keyname AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER in-default AS CHARACTER NO-UNDO. DEFINE OUTPUT PARAMETER in-ret-str AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER in-n-size AS LONG NO-UNDO. DEFINE RETURN PARAMETER out-nuchr AS LONG NO-UNDO. END PROCEDURE. PROCEDURE OpenPrinterA EXTERNAL "winspool.drv": DEFINE INPUT PARAMETER in-prtname AS CHARACTER NO-UNDO. DEFINE OUTPUT PARAMETER out-hwnd AS LONG NO-UNDO. DEFINE INPUT PARAMETER in-def AS LONG NO-UNDO. END PROCEDURE.