Link to home
Start Free TrialLog in
Avatar of mpdillon
mpdillon

asked on

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
Avatar of jkaios
jkaios
Flag of Marshall Islands image

SOLUTION
Avatar of jkaios
jkaios
Flag of Marshall Islands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Ark
Ark
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mpdillon
mpdillon

ASKER

jkaios,
Thanks for giving me all the dialogs. That was much more than I asked for. However, when I try to implement the code I receive an error.

Sub Main()
  Module1.ShowPrinter Me.hWnd
End Sub
The above code causes the error, "invalid use of ME keyword" when control enters the Main procedure. Could you please explain?
thanks,
pat
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

thanks,
pat
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:
   
    oDlg.Flags = &H8000& 'cdlPDDisablePrintToFile - late binding require values, not constants
    oDlg.ShowPrinter
    MsgBox "Copies: " & oDlg.Copies
'See http://support.microsoft.com/default.aspx?scid=kb;en-us;257688
'FIX: Printer Object Fails to Track Default Printer After Orientation Is Changed
    Printer.TrackDefault=True
    MsgBox Printer.DeviceName

Ark,
1. Passing 0 works fine. Thanks.

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
jkaios,
Hopefully this is my last question. The 0 worked great. However, how do I determine which printer the user selected? I cannot find a property for the printer name.
thanks,
pat
Printer.TrackDefaults=True
MsgBox Printer.DeviceName
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.