Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29282 Discussions

Print window keeps coming up behind my application window

Ken2
Beginner
1,008 Views

I use the FORTRAN_WINPRINT.F90 to print from my applications, but the print window (the one that allows you to select your printer) opens almost always behind my applications window.  Not every time, but more probably more than 70% of the time.  So users think the program has stopped when it is actually waiting for input.  How do I get this Print window to always come up in front of my applications window?

0 Kudos
9 Replies
GVautier
New Contributor III
1,008 Views

Hello

I don't know FORTRAN_WINPRINT.F90 but I think that you must have to pass the handle of your window to the print dialog in order for it to be displayed in the foreground.

0 Kudos
Steven_L_Intel1
Employee
1,008 Views

Right - in the initialization of PRINTDLG_Struct, the hwnd component needs to be set to your window handle. You could modify the code to pass that in, or perhaps replace NULL with GetForegroundWindow(), though that is said to have issues in some cases.

0 Kudos
Ken2
Beginner
1,008 Views

I appreciate the help.  But I'm not sure how to do this.  I am not a Windows programmer.   I went into the print routine and changed the line:

PRINTDLG_Struct%hwndOwner = NULL to PRINTDLG_Struct%hwndOwner = GetForegroundWindow()

The compiler gives me this error: 

Error 1  error #6404: This name does not have a type, and must have an explicit type.  

I am not sure how to declare the "Type" or if this is the correct location to make the change.

 

 

 

 

 

 

 

 

0 Kudos
Steven_L_Intel1
Employee
1,008 Views

You need to add "use user32" as a line next to the other "use" statements.

FWIW, I'm working on a revised version of this that uses PrintDlgEx, as Microsoft is hinting that PrintDlg will go away in some unspecified future version of Windows. One thing I noticed is that PrintDlgEx won't accept NULL as the owner HWND. I hate to use GetForegroundWindow as a default, but I may not have a better choice. I am adding OwnerWindow as an optional argument so if you have a GUI app you can pass the correct handle.

0 Kudos
Ken2
Beginner
1,008 Views

That works.  Now the print window pops up over the application window, I click on print or hit return, the print window closes then I can not return to the application window which is still open.  Clicking on it does not make the window active again.  Any suggestions?

0 Kudos
Steven_L_Intel1
Employee
1,008 Views

I haven't seen that behavior when I've been testing. Is your application a console app or GUI? If GUI, you will need to supply the HWND of your application window - using GetForegroundWindow for this purpose will probably have ill effects in such cases.

0 Kudos
Paul_Curtis
Valued Contributor I
1,008 Views

Steve, thanks for the heads-up on the future deprecation of PrintDlg(), I haven't paid any attention to that function for years.  I have now reworked my apps to use PrintDlgEx().  The following module shows my initialization of the dialog; note that flags are set to remove most of the options so the presentation is like that of PrintDlg().

MODULE printfunc
	SAVE

	!	this is a reworked version of a STRUCTURE
	TYPE T_DEVMODE_KT
		integer(BYTE) dmDeviceName(32)		! knowns  BYTE 
		integer(WORD) dmSpecVersion			! knowns  WORD 
		integer(WORD) dmDriverVersion		! knowns  WORD 
		integer(WORD) dmSize				! knowns  WORD 
		integer(WORD) dmDriverExtra			! knowns  WORD 
		integer(DWORD) dmFields				! knowns  DWORD 
		integer(SHORT) dmOrientation		! knowns  short 
		integer(SHORT) dmPaperSize			! knowns  short 
		integer(SHORT) dmPaperLength		! knowns  short 
		integer(SHORT) dmPaperWidth			! knowns  short 
		integer(SHORT) dmScale				! knowns  short 
		integer(SHORT) dmCopies				! knowns  short 
		integer(SHORT) dmDefaultSource		! knowns  short 
		integer(SHORT) dmPrintQuality		! knowns  short 
		integer(SHORT) dmColor				! knowns  short 
		integer(SHORT) dmDuplex				! knowns  short 
		integer(SHORT) dmYResolution		! knowns  short 
		integer(SHORT) dmTTOption			! knowns  short 
		integer(SHORT) dmCollate			! knowns  short 
		integer(BYTE)  dmFormName(32)		! knowns  BYTE 
		integer(WORD)  dmLogPixels			! knowns  WORD 
		integer(DWORD) dmBitsPerPel			! knowns  DWORD 
		integer(DWORD) dmPelsWidth			! knowns  DWORD 
		integer(DWORD) dmPelsHeight		    ! knowns  DWORD 
		integer(DWORD) dmDisplayFlags		! knowns  DWORD 
		integer(DWORD) dmDisplayFrequency   ! knowns  DWORD 
		integer(DWORD) dmICMMethod          ! knowns  DWORD 
		integer(DWORD) dmICMIntent          ! knowns  DWORD 
		integer(DWORD) dmMediaType          ! knowns  DWORD 
		integer(DWORD) dmDitherType         ! knowns  DWORD 
		integer(DWORD) dmReserved1          ! knowns  DWORD 
		integer(DWORD) dmReserved2          ! knowns  DWORD 
		integer(DWORD) dmPanningWidth       ! knowns  DWORD 
		integer(DWORD) dmPanningHeight      ! knowns  DWORD 
	END TYPE T_DEVMODE_KT
    
    !   copied from comdlg32.f90, where this function
    !   is only available for 64-bit builds
    INTERFACE 
    FUNCTION PrintDlgEx( &
            arg1)
    use ifwinty
      integer(LONG) :: PrintDlgEx ! HRESULT
      !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'PrintDlgExA' :: PrintDlgEx
      !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: arg1
      TYPE (T_PRINTDLGEX) arg1 ! LPPRINTDLGEXA arg1
     END FUNCTION
    END INTERFACE
    
    !   these WinAPI constants are not present in ifwinty.f90
    INTEGER, PARAMETER      :: PD_RESULT_PRINT          = 1
    INTEGER, PARAMETER      :: START_PAGE_GENERAL       = -1
    INTEGER, PARAMETER      :: PD_EXCLUSIONFLAGS        = Z'01000000'
    INTEGER, PARAMETER      :: PD_NOCURRENTPAGE         = Z'00800000'
    INTEGER, PARAMETER      :: PD_EXCL_COPIESANDCOLLATE = IOR(DM_COPIES, DM_COLLATE)

CONTAINS

	FUNCTION printer_setup (hwin, hdc, orientation) RESULT (ok)
		IMPLICIT NONE
		INTEGER(HANDLE),INTENT(IN)   :: hwin
		INTEGER(HANDLE),INTENT(OUT)  :: hdc
		INTEGER, INTENT(OUT)         :: orientation
		INTEGER                      :: lret
		LOGICAL                      :: ok
		TYPE(T_PRINTDLGEX)           :: pdx
		TYPE(T_DOCINFO)              :: di
		TYPE(T_DEVMODE_KT)		     :: devmode
		POINTER(dm, devmode)

        !   PrintDlgEx data structure   
        pdx%lStructSize         = SIZEOF(pdx) 
        pdx%hwndOwner           = hwin
        pdx%hDevMode            = NULL
        pdx%hDevNames           = NULL
        pdx%hDC                 = NULL
        pdx%Flags               = MOR(PD_RETURNDC,         PD_NOPAGENUMS,     &
                                      PD_HIDEPRINTTOFILE,  PD_EXCLUSIONFLAGS, &
                                      PD_USEDEVMODECOPIES, PD_NOSELECTION,    &
                                      PD_NOCURRENTPAGE                        )
        pdx%Flags2              = 0
        pdx%ExclusionFlags      = PD_EXCL_COPIESANDCOLLATE 
        pdx%nPageRanges         = 0     ! all these
        pdx%nMaxPageRanges      = 1     !  items are
        pdx%lpPageRanges        = NULL  !   ignored when 
        pdx%nMinPage            = 0     !    PD_NOPAGENUMS is
        pdx%nMaxPage            = 0     !     included in %flags
        pdx%nCopies             = 1
        pdx%hInstance           = NULL
        pdx%lpPrintTemplateName = NULL
        pdx%lpCallback          = NULL
        pdx%nPropertyPages      = 0
        pdx%lphPropertyPages    = NULL
        pdx%nStartPage          = START_PAGE_GENERAL
        pdx%dwResultAction      = 0

		ok = .FALSE.
		IF (PrintDlgEx(pdx) == S_OK) THEN       ! S_OK = 0
		    IF (pdx%dwResultAction == PD_RESULT_PRINT) THEN
			    hdc             = pdx%hdc
			    di%cbSize       = SIZEOF (di)
			    di%lpszDocName  = LOC("Program output"C) 
			    di%lpszOutput   = NULL
    	
			    !	a DevMode structure is returned with information about
			    !	the selected page orientation: portrait=1, landscape=2
			    dm = GlobalLock (pdx%hDevMode)
			    orientation = INT4(devmode%dmOrientation)
			    IF (orientation /= 2) orientation = 1	! just in case
    			
			    ok = (StartDoc(hdc, di) /= SP_ERROR)
			    IF (.NOT.ok) lret = MessageBox (hwin, "Printer Problem"C,"Error!"C, MB_OK)
			    
		    END IF
		END IF
		
		!   free the memory allocated by PrintDlgEx
		lret = GlobalFree (pdx%hDevMode)
		lret = GlobalFree (pdx%hDevNames)
		 
	END FUNCTION printer_setup

END MODULE printfunc
  



 


 

0 Kudos
Ken2
Beginner
1,008 Views

You guys are great programmers, unfortunately both of you are over my head a ways. 

With the code above I'm not sure how to use it in FORTRAN.  It has errors when I try to compile.   An in the FORTRAN_Winprint.f90 routine I am not sure how to get the main program's window handle and then how to pass it into this routine. 

If you guys have any examples I would appreciate it.

0 Kudos
Steven_L_Intel1
Employee
1,008 Views

You can continue to use the existing code for now - it still works,. Paul's code just puts up the printer selection dialog, it doesn't do the printing.

0 Kudos
Reply