Solved

How to use PageSetUp API function from VB?

Posted on 1998-12-17
11
364 Views
Last Modified: 2008-03-10
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
Comment
Question by:burkmar
  • 7
  • 3
11 Comments
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1451126
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
 

Author Comment

by:burkmar
ID: 1451127

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
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1451128
burkmar,
    give me a bit and I'll see what I can do...
0
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1451129
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
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1451130
burkmar,
    Call GlobalFree after CopyMemory... sorry
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 1

Accepted Solution

by:
muffinthedog earned 150 total points
ID: 1451131
bufkmar,
    see previous comments...

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

Author Comment

by:burkmar
ID: 1451132
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
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1451133
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
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1451134
""
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
 

Author Comment

by:burkmar
ID: 1451135
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
 
LVL 7

Expert Comment

by:JimMorgan
ID: 2130884
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now