View Full Version : How to use PrintHookProc?

09-06-2008, 11:15 PM
Hello to all. This is my 1st post here so go easy on me. I've been working on several VBA progs for SolidWorks. One of them is to try to intercept the Print command (like when you click on the Printer icon button) so that I may pop a form up to have the user select a choice then allow the PrintDlg to appear for the print. I've found PrintHookProc to be the closest to what I'm looking for. I already got the Windows handle and Class name for SolidWorks. I've :banghead: for 2 weeks on this and am getting tired. Please help me :beg: on how to get this to work. I would be so thankful :bow:.

Here's a routine I created to capture the hWnd and Class name in SolidWorks to use in a prog. Create a VBA module and copy/paste code below and run. With some slight changes it might be useful for others.

Option Explicit

Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal _
hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

'Purpose : Returns the Windows Handle of a Dialog based on its caption.
'Inputs : sDialogCaption The dialog caption.
' [sClassName] The class name of the dialog. If
' unknown, do not specify
' this parameter.
'Outputs : The Dialogs Window Handle
'Notes : 1/ Find windows scans down the Z Order of the dialogs
' currently displayed,
' 2/ To Call in a VBA form use:
lHwnd = DialogGetHwnd(Me.Caption)
' 3/ Use Spy ++ (comes with Visual Studio), OR the function
' DialogGetClassName to return the class names of forms.

Function DialogGetHwnd(ByVal sDialogCaption As String, Optional sClassName As _
String = vbNullString) As Long
On Error Resume Next
DialogGetHwnd = FindWindowA(sClassName, sDialogCaption)
On Error GoTo 0
End Function

'Purpose : Returns the class name of a object given the handle or caption
'Inputs : [sCaption] = The objects caption
' [lHwnd] = The objects handle
'Outputs :
'Notes : Pass in either sCaption OR lHwnd, to get a class name

Function DialogGetClassName(Optional sCaption As String, Optional lHwnd As _
Long) As String
Const clMaxLen As Long = 256
Dim lRetVal As Long, sResult As String * clMaxLen

If Len(sCaption) Then
'Get Dialog Handle
lHwnd = DialogGetHwnd(sCaption)
End If
If lHwnd Then
'Get Class Name
lRetVal = GetClassName(lHwnd, sResult, clMaxLen)
DialogGetClassName = Left$(sResult, lRetVal)
End If
End Function

Sub main()
Dim swApp As SldWorks.SldWorks
Dim swhWnd As Long, winhWnd As Long
Set swApp = Application.SldWorks
' Get SolidWorks windows handler from SolidWorks:
swhWnd = swApp.Frame.GetHWnd
' Get SolidWorks class name from SolidWorks:
swClsname = DialogGetClassName(vbNullString, swhWnd)
' Get SolidWorks windows handler from Windows:
winhWnd = DialogGetHwnd(swCaption)
' Get SolidWorks class name from Windows:
winClsname = DialogGetClassName(vbNullString, winhWnd)
MsgBox "SW Handle for SW: " & swhWnd & vbCrLf & "SW Class for SW: " & _
swClsname & vbCrLf & "Win Handle for SW: " & winhWnd & vbCrLf & _
"Win Class for SW: " & winClsname
End Sub

Placed code in VBA tags to allow for easier reading. Reformatted to 80 columns to prevent side scrolling.

09-12-2008, 08:59 AM
Hi VectorZ,
Welcome to the board! At VBAX we store working code examples in the Knowledge base, perhaps you could write it up and submit it?