whats wrong with this program?

whats wrong with this program?

Hi. I've made a simple Win32 program from one of the example dialog programs. I've added code to print the dialog form but it closes the appliaction. Attatched are the files. The printing statements are in FXPrint subroutine. I would like to get this program to print the dialog as a screendump or bitmap in a landscape view by default aswell. Thanks for any help.

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Jugoslav Dujic's picture

Well, look at your own comment ;-)

 
!********************************************************
!  FUNCTION: FXPrint ( dlg, id, callbacktype )
!  PURPOSE:  Prints page
!********************************************************
subroutine FXPrint(hWnd)

You mismatched callback prototype -- it has to have the prototype as in comment. Use Dlg%hWnd member as window handle throughout the code.

Btw, I think I ommitted the statement PD%nCopies = 1 from the code I posted. I'm not sure it is required.

Jugoslav

Jugoslav www.xeffort.com

Hi. Thanks for replying to my help message. I've altered the code and there is an error when DLG%hWnd is used as the window handle(This variable or component must be of a derived or structure type [DLG]). When the handle is left as hWnd the program compiles. When the print button is clicked the printer initializes but does not print.
Here's the code that gets errors.

subroutine FXPrint( Dlg, id, callbacktype )

use comdlg32
use gdi32
use user32
use dfwin
TYPE(T_PRINTDLG) pd
TYPE(T_DOCINFO) DocInfo
TYPE(T_RECT) Rect
INTEGER hdc, iSt,hwnd, iXRes, iYRes

hdc = GetWindowDC(Dlg%hWnd )
call ZeroMemory(LOC(pd), sizeof(pd))
pd%lStructSize= sizeof(pd)
pd%hwndOwner= hWnd
pd%Flags= PD_RETURNDC
PD%nCopies = 1
iSt=PrintDlg(pd)
DocInfo%cbSize = sizeof(DOCINFO)
DocInfo%lpszDocName = LOC("TEST"C)
DocInfo%lpszOutput = NULL

iSt=StartDoc(pd%hDC, DocInfo)
iSt=StartPage(pd%hDC)
iSt=GetWindowRect(Dlg%hWnd ,Rect)
iXRes=GetDeviceCaps(pd%hDC, HORZRES)
iYRes=GetDeviceCaps(pd%hDC, HORZRES)
iSt=StretchBlt(pd%hdc, 0, 0, (Rect%Right-Rect%Left)*iXRes/96, &
(Rect%Bottom-Rect%Top)*iYRes/96, &
hDC, 0, 0, Rect%Right-Rect%Left, Rect%Bottom-Rect%Top, SRCCOPY)
iSt=GetLastError()
iSt=EndPage(pd%hDC)

iSt=EndDoc(pd%hDC)
if (pd%hDevMode /= NULL) iSt=GlobalFree(pd%hDevMode)
if (pd%hDevMode /= NULL) iSt=GlobalFree(pd%hDevNames)
iSt=ReleaseDC(hWnd ,hdc)
iSt=DeleteDC(pd%hDC)

end subroutine FXPrint

Maybe by adding

USE DFLOGM[/PRE]
and then adding 
TYPE(T_DIALOG) dlg

will
solve your problem? HTH

Jugoslav Dujic's picture

It would indeed, but only partially. I have made the deadly sin of modifying a working code on the fly -- in the original version, there was flag PD_RETURNDEFAULT, which caused the PrintDlg not to appear. When I removed it, the shadow PrintDlg was printed along. Besides, the flags to GetDeviceCaps were wrong.

Here's finally the correct code:

subroutine FXPrint( Dlg, id, callbacktype )

use comdlg32 
use dflogm
use gdi32 
use user32 
use dfwin 

implicit none

type(DIALOG):: Dlg
type(T_PRINTDLG) pd 
type(T_DOCINFO) DocInfo 
type(T_RECT) Rect
integer:: hdc, iSt,hwnd, iXRes, iYRes, hBmp, hdcBuffer, &
         id, callbacktype

hdc = GetWindowDC(Dlg%hWnd  ) 
call ZeroMemory(LOC(pd), sizeof(pd)) 
pd%lStructSize= sizeof(pd) 
pd%hwndOwner= Dlg%hWnd
pd%Flags= PD_RETURNDC
PD%nCopies = 1 


iSt=GetWindowRect(Dlg%hWnd ,Rect) 
hdcBuffer = CreateCompatibleDC(NULL)
hBmp = CreateCompatibleBitmap(GetDC(NULL), Rect%Right-Rect%Left, Rect%Bottom-Rect%Top)
iSt = SelectObject(hdcBuffer, hBmp)
iSt=BitBlt(hdcBuffer, 0, 0,  (Rect%Right-Rect%Left), (Rect%Bottom-Rect%Top),  &       
hDC, 0, 0, SRCCOPY) 

if (PrintDlg(pd)) then
   DocInfo%cbSize = sizeof(DOCINFO) 
   DocInfo%lpszDocName = LOC("TEST"C) 
   DocInfo%lpszOutput = NULL 

   iSt=StartDoc(pd%hDC, DocInfo) 
   iSt=StartPage(pd%hDC) 
   iXRes=GetDeviceCaps(pd%hDC, LOGPIXELSX) 
   iYRes=GetDeviceCaps(pd%hDC, LOGPIXELSY) 
   iSt=StretchBlt(pd%hDC, 0, 0,  (Rect%Right-Rect%Left)*iXRes/96,  &    
                 (Rect%Bottom-Rect%Top)*iYRes/96,                    &       
                 hdcBuffer, 0, 0, Rect%Right-Rect%Left, Rect%Bottom-Rect%Top, SRCCOPY) 
   iSt=GetLastError() 
   iSt=EndPage(pd%hDC) 

   iSt=EndDoc(pd%hDC)
end if
if (pd%hDevMode /= NULL) iSt=GlobalFree(pd%hDevMode) 
if (pd%hDevMode /= NULL) iSt=GlobalFree(pd%hDevNames) 
iSt=ReleaseDC(Dlg%hWnd,hdc) 
iSt=DeleteDC(pd%hDC) 
iSt=DeleteDC(hdcBuffer) 
iSt=DeleteObject(hBmp) 
         
end subroutine FXPrint

Jugoslav

Jugoslav www.xeffort.com

Thanks for the source code fix. It now has no errors and prints the dialog box. Is there anyway that the printed rect can be stretched in the width direction without resizing the dialog box on screen? The printer will only print the form to 2/3 of the paper width for some reason. If the dialog box is resized to any larger the printer initializes but does not print. Cheers again.

Dave

Jugoslav Dujic's picture

It's all about arguments to StretchBlt -- arguments 2-5 define the position of the image on the paper. The "magic" number 96 in my code comes from screen resolution of 96 DPI so that the dialog is supposedly printed in natural size. By adjusting these arguments you can position and size the printed image as you wish.

Jugoslav

Jugoslav www.xeffort.com

Cheers for the help. The program now prints the form as desired.

Dave

Login to leave a comment.