Printer Dialog using API without a form

I have an ActiveX exe that need to display a printer dialog box. I do not have any forms in the ActiveX exe. All the code I have found for using API code seems to require a form to get the hwnd. I have done the OPEN and Save Dialogs without a form but need help with the print.
thanks,
Pat

'OFS_FILE_OPEN_FLAGS and OFS_FILE_SAVE_FLAGS below
'are mine to save long statements; they're not
'a standard Win32 type.
Public Const OFS_FILE_OPEN_FLAGS = OFN_EXPLORER Or OFN_LONGNAMES Or OFN_CREATEPROMPT Or OFN_NODEREFERENCELINKS Or OFN_HIDEREADONLY Or OFN_ALLOWMULTISELECT
Public Const OFS_FILE_SAVE_FLAGS = OFN_EXPLORER Or OFN_LONGNAMES Or OFN_OVERWRITEPROMPT Or OFN_HIDEREADONLY

Public Type OPENFILENAME
nStructSize As Long
hwndOwner As Long
hInstance As Long
sFilter As String
sCustomFilter As String
nCustFilterSize As Long
nFilterIndex As Long
sFile As String
nFileSize As Long
sFileTitle As String
nTitleSize As Long
sInitDir As String
sDlgTitle As String
flags As Long
nFileOffset As Integer
nFileExt As Integer
sDefFileExt As String
nCustDataSize As Long
fnHook As Long
sTemplateName As String
End Type

Type NMHDR
hwndFrom As Long
idfrom As Long
code As Long
End Type

Type OFNOTIFY
hdr As NMHDR
lpOFN As OPENFILENAME
pszFile As String ' May be NULL
End Type

Type CHOOSECOLORS
lStructSize As Long
hwndOwner As Long
hInstance As Long
rgbResult As Long
lpCustColors As String
flags As Long
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type

Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName(LF_FACESIZE) As Byte
End Type

Public Type CHOOSEFONTS
lStructSize As Long
hwndOwner As Long ' caller's window handle
hDC As Long ' printer DC/IC or NULL
lpLogFont As Long ' ptr. to a LOGFONT struct
iPointSize As Long ' 10 * size in points of selected font
flags As Long ' enum. type flags
rgbColors As Long ' returned text color
lCustData As Long ' data passed to hook fn.
lpfnHook As Long ' ptr. to hook function
lpTemplateName As String ' custom template name
hInstance As Long ' instance handle of.EXE that
lpszStyle As String ' return the style field here
nFontType As Integer ' same value reported to the EnumFonts
MISSING_ALIGNMENT As Integer
nSizeMin As Long ' minimum pt size allowed &
nSizeMax As Long ' max pt size allowed if
End Type

Type PRINTDLGS
lStructSize As Long
hwndOwner As Long
hDevMode As Long
hDevNames As Long
hDC As Long
flags As Long
nFromPage As Integer
nToPage As Integer
nMinPage As Integer
nMaxPage As Integer
nCopies As Integer
hInstance As Long
lCustData As Long
lpfnPrintHook As Long
lpfnSetupHook As Long
lpPrintTemplateName As String
lpSetupTemplateName As String
hPrintTemplate As Long
hSetupTemplate As Long
End Type

Type DEVNAMES
wDriverOffset As Integer
wDeviceOffset As Integer
wOutputOffset As Integer
wDefault As Integer
End Type

Public Const DN_DEFAULTPRN = &H1

Public Type SelectedFile
nFilesSelected As Integer
sFiles() As String
sLastDirectory As String
bCanceled As Boolean
End Type

Public Type SelectedColor
oSelectedColor As OLE_COLOR
bCanceled As Boolean
End Type

Public Type SelectedFont
sSelectedFont As String
bCanceled As Boolean
bBold As Boolean
bItalic As Boolean
nSize As Integer
bUnderline As Boolean
bStrikeOut As Boolean
lColor As Long
sFaceName As String
End Type

Public FileDialog As OPENFILENAME
Public ColorDialog As CHOOSECOLORS
Public FontDialog As CHOOSEFONTS
Public PrintDialog As PRINTDLGS
Dim ParenthWnd As Long

Public Function ShowOpen(ByVal hWnd As Long, Optional ByVal centerForm As Boolean = True) As SelectedFile
Dim ret As Long
Dim Count As Integer
Dim fileNameHolder As String
Dim LastCharacter As Integer
Dim NewCharacter As Integer
Dim tempFiles(1 To 200) As String
Dim hInst As Long
Dim Thread As Long

Public Function ShowColor(ByVal hWnd As Long, Optional ByVal centerForm As Boolean = True) As SelectedColor
Dim customcolors() As Byte ' dynamic (resizable) array
Dim i As Integer
Dim ret As Long
Dim hInst As Long
Dim Thread As Long

Public Function ShowFont(ByVal hWnd As Long, ByVal startingFontName As String, Optional ByVal centerForm As Boolean = True) As SelectedFont
Dim ret As Long
Dim lfLogFont As LOGFONT
Dim hInst As Long
Dim Thread As Long
Dim i As Integer

Ark,
That is not exactly what I was asking for but I am flexible. It works in both VB6 and VBA. I need to determine what printer was selected. How do I determine what properties/methods belong to the oDlg object?
For each oDlg in ???
debug.print ????.Name
next

Ark,
I just found out the CreateObject will not work for me. I am looking to use this solution in both VB and VBA. The Common Dialog is a licensed component and will not work in a VBA enviornment. It worked when I first tested it because I tested on my development machine which contains VB6. When I tried to use it in a VBA script on an non developement machine I received the cannot not create ActiveX component message. Thank you anyway for your suggestion. It sure did seem simple.
pat

The Me keyword behaves like an implicitly declared variable. It represents the class or form that is currently active. However, in your case in which you don't have any form, just pass 0 as the window handle to the ShowPrinter method.

Hi
1. Hwnd property of any common dialog set a window, which can receive dialog messages to subclass/change behavior of dialog window etc. If you don't need such functionality (in most cases this is true), you can pass 0 (it means desktop window) as hwnd.

2. "cannot not create ActiveX component message" means that target machine doesn't have comdlg32.ocx installed. Just copy this file from your machine to windows\system32 folder and use resgsvr32.exe comdlg32.ocx to register this component, or imclude this OCX into setup package and it register automaticaly.

3. Set oDlg = CreateObject(("MSComDlg.CommonDialog")
Now oDlg have all properties/methods like dialog control placed on form. The only difference - there is no 'autocomplete' future - after pressing dot drop down list doesn't appear. You can get/set what you want:

2. The Comdlg32.ocx already existed in \system32. I used regsvr32 to register it and it was successful. However, I cannot use the Create in VBA without a form. I found this microsoft KB that explains. http://support.microsoft.com/kb/281848

3. I added TLBINF32 as a reference in the project and then ran

Set oDlg = CreateObject("MSComDlg.CommonDialog")
oDlg.ShowPrinter
'
Set TLInfo = TLI.InterfaceInfoFromObject(oDlg) 'grab info from object
Set SR = TLInfo.Members.GetFilteredMembers(False)
'
'loop through attribute members of the object
'
For i = 1 To SR.Count
Debug.Print SR.Item(i).Name
next i

This listed all the properties for the oDlg object. However, I did not see a PrinterName or DeviceName property. I need to know which printer was selected so that I can set the PRINTER object to the printer the user selected. What property of oDlg returns the Printername?
thanks

Ark,
I am using your solution. Thank you verey much. Using your solution I was able to set the printer to the user's choice. I gave you the bulk of the points.

jkaios,
I could not use your solution becasue I could not get it to set the printer to the printer the user choose. The printer dialog box would save the user's choice but I could not figure out how to get the selected printer. While I appreciate all the code you supplied, in the end it would not set the printer. That is why I split the points the way I did.

Here are a few simple, working, games that you can use as-is or as the basis for your own games.
Tic-Tac-Toe
This is one of the simplest of all games.
The game allows for a choice of who goes first and keeps track of the number of wins for…

Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…