- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page