• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 382
  • Last Modified:

How to use PageSetUp API function from VB?

I have found examples of how to use this API function from C code, but I do not know how to convert this to work in VB. For example I don't now how to reference a structure by its 'handle' which I must do to initialise the structure passed to the function.
0
burkmar
Asked:
burkmar
  • 7
  • 3
1 Solution
 
muffinthedogCommented:
burkmar,
think all your going to have to do is declare a variable of type
PAGESETUPDIALOG
Dim MyPageSetupDialog as PAGESETUPDIALOG

set all the elements of the structure for the lStructSize
set the lStructSize to Len(MyPageSetupDialog)
and call the PageSetupDlg function passing the structure
ret = PageSetupDlg(MyPageSetupDialog)

The structure will be passed by reference
0
 
burkmarAuthor Commented:

I have done this and all is well - the function invokes the page set up dialog, but the problem is that if I want to query, for example the page orientation specified by the user, this is NOTavailable directly from any of the components of the PAGESETUPDIALOG structure.  Instead its available from a structure called DEVMODE which is referenced by the PAGESETUPDIALOG structure - but only by a 'handle' to it.  Calling PageSetUpDlg with this component uninitialised, dynamically allocates storage for the DEVMODE structure and, I think, populates it with the info I need, but I do not know how to access it.  If declare a variable of type DEVMODE first, I don't know how I get its 'handle' to put into my PAGESETUPDIALOG structure.  It sounds complicated - try it and you will see what I mean.
0
 
muffinthedogCommented:
burkmar,
    give me a bit and I'll see what I can do...
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
muffinthedogCommented:
burkmar,

Dim dwRet As Long
Dim PSD As PAGESETUPDLG
Dim DM As DEVMODE
Dim pDevMode As Long

PSD.hwndOwner = Form1.hWnd
PSD.lStructSize = Len(PSD)

dwRet = PAGESETUPDLG(PSD)
If PSD.hDevMode Then
    pDevMode = GlobalLock(PSD.hDevMode)
    GlobalFree (PSD.hDevMode)
    CopyMemory DM, pDevMode, Len(DM)
    'Do whatever with DM here
End If
End Sub

Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (lpvDest As Any, ByVal lpvSource As Any, ByVal cbCopy As Long)

0
 
muffinthedogCommented:
burkmar,
    Call GlobalFree after CopyMemory... sorry
0
 
muffinthedogCommented:
bufkmar,
    see previous comments...

If need set structure before calling just use GlobalAlloc... sorry not a better example, but time...
0
 
burkmarAuthor Commented:
Muffinthedog,

Thanks for your excellent help - I'm certainly learning a lot, but everytime some questions get answered, it just throws up more.  When I tried your example and queried the values in DM, they are all zero or empty.  In the information I've seen about using the PageSetUpDlg from 'C', the value of .hDevMode must be Null for the function to populate the structure with the defaults.  However I don't see how I can set a Long value to Null in VB - any ideas.  I tried doing a GlobalAlloc to allocate memory to it first - but no good.  I also tried populating the structure before calling the function (using GlobalAlloc, GlobalLock, CopyMemory and GlobalUnlock) but I just get some very weird results.

I appreciate that I have taken a lot of your time already, but yours is the best help I've had from any source in the WWWorld(!) so I'm going to be cheeky and ask for more!

Many thanks for the help you've already given me.
0
 
muffinthedogCommented:
burkmar,
    try the following and let me know what happens...

Open a new project and add a command button to Form1

Put the following in the click event of the button

Dim PSD As PAGESETUPDLG
Dim DM As DEVMODE
Dim pDevMode As Long

PSD.hwndOwner = Form1.hWnd
PSD.lStructSize = Len(PSD)

dwRet = PAGESETUPDLG(PSD)
If PSD.hDevMode Then
    pDevMode = GlobalLock(PSD.hDevMode)
    CopyMemory DM, pDevMode, Len(DM)
    GlobalFree (PSD.hDevMode)
    'Do whatever with DM here
    MsgBox "DeviceName = " & DM.dmDeviceName
    MsgBox "Version Number = " & DM.dmSpecVersion
    MsgBox "Driver Version = " & DM.dmDriverVersion
    MsgBox "DEVMODE Size = " & DM.dmSize
    MsgBox "Private Data Size = " & DM.dmDriverExtra
    MsgBox "Paper Orientation = " & DM.dmOrientation
End If
End Sub

Add a module to the project and add the following...

Declare Function PAGESETUPDLG Lib "comdlg32.dll" Alias "PageSetupDlgA" (pPagesetupdlg As PAGESETUPDLG) As Long
Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (lpvDest As Any, ByVal lpvSource As Any, ByVal cbCopy As Long)

Public Const PSD_DEFAULTMINMARGINS = &H0 '  default (printer's)
Public Const PSD_DISABLEMARGINS = &H10
Public Const PSD_DISABLEORIENTATION = &H100
Public Const PSD_DISABLEPAGEPAINTING = &H80000
Public Const PSD_DISABLEPAPER = &H200
Public Const PSD_DISABLEPRINTER = &H20
Public Const PSD_ENABLEPAGEPAINTHOOK = &H40000
Public Const PSD_ENABLEPAGESETUPHOOK = &H2000 '  must be same as PD_*
Public Const PSD_ENABLEPAGESETUPTEMPLATE = &H8000 '  must be same as PD_*
Public Const PSD_ENABLEPAGESETUPTEMPLATEHANDLE = &H20000 '  must be same as PD_*
Public Const PSD_INHUNDREDTHSOFMILLIMETERS = &H8 '  3rd of 4 possible
Public Const PSD_INTHOUSANDTHSOFINCHES = &H4 '  2nd of 4 possible
Public Const PSD_INWININIINTLMEASURE = &H0 '  1st of 4 possible
Public Const PSD_MARGINS = &H2 '  use caller's
Public Const PSD_MINMARGINS = &H1 '  use caller's
Public Const PSD_NOWARNING = &H80 '  must be same as PD_*
Public Const PSD_RETURNDEFAULT = &H400 '  must be same as PD_*
Public Const PSD_SHOWHELP = &H800 '  must be same as PD_*

Public Const CCHDEVICENAME = 32
Public Const CCHFORMNAME = 32

Type DEVMODE
        dmDeviceName As String * CCHDEVICENAME
        dmSpecVersion As Integer
        dmDriverVersion As Integer
        dmSize As Integer
        dmDriverExtra As Integer
        dmFields As Long
        dmOrientation As Integer
        dmPaperSize As Integer
        dmPaperLength As Integer
        dmPaperWidth As Integer
        dmScale As Integer
        dmCopies As Integer
        dmDefaultSource As Integer
        dmPrintQuality As Integer
        dmColor As Integer
        dmDuplex As Integer
        dmYResolution As Integer
        dmTTOption As Integer
        dmCollate As Integer
        dmFormName As String * CCHFORMNAME
        dmUnusedPadding As Integer
        dmBitsPerPel As Integer
        dmPelsWidth As Long
        dmPelsHeight As Long
        dmDisplayFlags As Long
        dmDisplayFrequency As Long
End Type

Type POINTAPI
        x As Long
        y As Long
End Type

Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Type PAGESETUPDLG
        lStructSize As Long
        hwndOwner As Long
        hDevMode As Long
        hDevNames As Long
        flags As Long
        ptPaperSize As POINTAPI
        rtMinMargin As RECT
        rtMargin As RECT
        hInstance As Long
        lCustData As Long
        lpfnPageSetupHook As Long
        lpfnPagePaintHook As Long
        lpPageSetupTemplateName As String
        hPageSetupTemplate As Long
End Type

Run the program and click the command button...

When the printer setup dialog comes up, just click the OK button and see if anything is returned by the MsgBox statements...

If not, would you like a C wrapper DLL (kinda defeats the purpose though)?
0
 
muffinthedogCommented:
""
hDevMode

Handle to a global memory object that contains a DEVMODE structure. On input, if a handle is given, the values in the corresponding DEVMODE structure are used to initialize the controls in the dialog box. On output, the dialog box sets hDevMode to a global memory handle for a DEVMODE structure that contains values specifying the user’s selections. If the user’s selections are not available, the dialog box sets hDevMode to NULL.


0
 
burkmarAuthor Commented:
Muffinthedog,

Your example worked superbly.  I thought that I'd tried this exact method after your last advice, but the code I am working with was so full of commented out efforts and garbage that I must of missed something.  Your help has been superb.  Many, many thanks.

Burkmar.
0
 
JimMorganCommented:
MuffinTheDog:

With the new search engine in EE, I was searching around for information on programmatically changing the pagesetup from VBA.  This is close, however we don't have the rich language capabilities of VB.

One of the problems we seem to find is when we try to prtDevMode in VBA and the database is made into a MDE, the code will not work.  I've been contemplating creating a VB routine outside of Access so that the current pagesetup for the printer could be saved, pagesetup changed either from user's desires or programatically, return to Access to view/print the report, then make another outside call to set the pagesetup back to its original state.

Do you think that these routines could be modified to do that?  It sure will help out a lot of us out over in the Access topic.

Thanks,

Jim
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now