Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Questions about DEVMODE

ahasan
Beginner
737 Views
Trying to learn a little about printing from a windows program:
When PrintDlg() is executed does it create the DEVMODE structure or is the common part ofDEVMODE already in memory?
Why is it necessary to use GlobalLock to retrieve a pointer to the DEVMODE structure, when addresses of other structures can be obtained by loc(structure)? I know that DEVMODE is a movable memory object, but most everything is in memory and is moved around by the OS.
Why is it necessary to use GlobalFree(hDevMode) and GlobalFree(hDevNames) after executing PrintDlg?
Thanks for any info!
0 Kudos
4 Replies
Jugoslav_Dujic
Valued Contributor II
737 Views
1) PrintDlg creates the DEVMODE structure if PD%hDevMode is NULL on input; otherwise, you're expected to do memory handling yourself
2) The GlobalLock/GlobalFree mechanism is related to memory management. PrintDlg is one of rare APIs which allocates memorywhich you are supposed to use afterwards (again, in case PD%hDevMode.EQ.NULL). Note that most other APIs expect that you prepare the buffer and pass its LOC() and size, and you get a copy of the data. SincePrintDlg does not know from what language it is used, it must use the "least common denominator" memory manager -- native VirtualAlloc/GlobalLock/GlobalUnlock/GlobalFree mechanism. Actually, it's not theissue about "moveable memory" -- rather, once you receive the information about allocated memory (HANDLE PD%hDevMode) in order to release it, you must pass it back to the memory manager which allocated it (GlobalFree). HANDLE must be used rather than LOC because the system can't reliably unmap LOC onto the actual piece of allocated memory.
There's a similarmechanism with e.g. SHBrowseForFolder API -- it returns a LPITEMIDLIST, and you're supposed to release it using appropriate memory deallocator, in this case CoTaskMemFree (but the idea is the same).
Jugoslav
0 Kudos
ahasan
Beginner
737 Views
JugoslavDujic, thanks for the reply and information. Another question about printing:In a past post you outlined how to change DEVMODE so that the Print Dlg box would be initialized to Landscape paper orientation. The following is my approximation of your example:
type(T_DEVMODE) :: DM
Pointer(pDM, DM)
..
..
pd%Flags = PD_RETURNDEFAULT
iret = PrintDlg(pd)
pDM = GlobalLock(pd%hDEVMODE)
DM%Field1%DMORIENTATION = DMORIENT_LANDSCAPE
iret = GlobalUnlock(pd%hDEVMODE)
etc.....
In the Fortran_WinPrint example code (Authored by Steve Lionel and supplied with CVF 6) the procedure appears to be (again in myoutline):
type(T_DEVMODE) :: DEVMODE_struct
! note, no pointer to the DEVMODE_struct
..
pd%Flags = PD_RETURNDEFAULT
iret = PrintDlg(pd)
pDM = GlobalLock(pd%hDEVMODE)
DM%Field1%DMORIENTATION = DMORIENT_LANDSCAPE
iret = DocumentProperties(Null, hPrn, DefPrnName, &
DEVMODE_struct, DM_IN_BUFFER.OR. &
DM_OUT_BUFFER)
iret = GlobalUnlock(pd%hDEVMODE)
etc.....
Just curious.Is there any advantage of one procedure over the other ?

Message Edited by halcyong@fcc.net on 11-27-2004 07:14 AM

0 Kudos
Paul_Curtis
Valued Contributor I
737 Views
Code, called prior to generating print output:
FUNCTION printer_setup (hwin, hdc, orientation) RESULT (ok)
	IMPLICIT NONE
	INTEGER,INTENT(IN)       :: hwin
	INTEGER,INTENT(OUT)      :: hdc, orientation
	INTEGER                  :: lret
	LOGICAL                  :: ok
	TYPE(T_PRINTDLG)         :: pd
	TYPE(T_DOCINFO)          :: di


	!	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



	TYPE(T_DEVMODE_KT)		 :: devmode
	POINTER(dm, devmode)

	pd%lStructSize         = SIZEOF(pd) 
	pd%hwndOwner           = hwin
	pd%hDevMode            = NULL
	pd%hDevNames           = NULL
	pd%hDC                 = NULL 
	pd%Flags               = IOR(PD_RETURNDC, PD_PRINTSETUP)
	pd%nFromPage           = 0
	pd%nToPage             = 0   
	pd%nMinPage            = 0  
	pd%nMaxPage            = 0   
	pd%nCopies             = 1  
	pd%hInstance           = NULL 
	pd%lCustData           = 0 
	pd%lpfnPrintHook       = NULL
	pd%lpfnSetupHook       = NULL 
	pd%lpPrintTemplateName = NULL 
	pd%lpSetupTemplateName = NULL 
	pd%hPrintTemplate      = NULL 
	pd%hSetupTemplate      = NULL

	ok = PrintDlg (pd) 
	IF (ok) THEN 
		hdc = pd%hdc
		di%cbSize       = SIZEOF (di)
		di%lpszDocName  = LOC("KILTEL plot"C) 
		di%lpszOutput   = NULL

		!	a DevMode structure is returned with information about
		!	the selected page orientation: portrait=1, landscape=2;
		!	first, associate the c pointer with the global memory block
		!	allocated by PrintDlg; u
sing GlobalLock works, whereas
		!	passing dm as the initialization of pd%hDevMode does not (?)
		dm = GlobalLock (pd%hDevMode)
		orientation = INT4(devmode%dmOrientation)
		
		!	free the DevMode global memory block
		lret = GlobalFree (pd%hDevMode)
		IF (orientation /= 2) orientation = 1	! just to make sure
		
		!	need to free this block also
		lret = GlobalFree (pd%hDevNames)
		
		!di%lpszDatatype = 
		!di%fwType       = DI_APPBANDING 
		
		IF (StartDoc(hdc, di) /= SP_ERROR) THEN
			ok = .TRUE.
		ELSE
			ok = .FALSE.
			lret = MessageBox (hwin,"Printer Problem"C,"Error!"C,MB_OK)
		END IF
	END IF   
END FUNCTION printer_setup
0 Kudos
ahasan
Beginner
737 Views
Paul, thanks for the code example!
Still need some info on why DocumentProperties() was used in Fortran_WinPrint examplesupplied with CVF (see discussion above).Itmay bejust two different ways to achieve the same goal, but using DocumentProperties() may have some subtle advantages. Just curious. Once I get a better grib on the basics, it will be easier to follow the SDK and to address more complicated printing problems. Thanks.
0 Kudos
Reply