Problems subclassing VB windows - CallWindowProc....

Hi,

I have the following code in my form:
-------------------------------------------------------------------------------------
Private Sub Form_Load()
   glngPrevWndProc = GetWindowLong(hwnd, GWL_WNDPROC)
   SetWindowLong hwnd, GWL_WNDPROC, AddressOf MyWindowProc
End Sub

Private Sub Form_Unload(Cancel As Integer)
   'pass control back to previous windows
   SetWindowLong hwnd, GWL_WNDPROC, glngPrevWndProc
End Sub
-------------------------------------------------------------------------------------

And a snippet from the following in my module
-------------------------------------------------------------------------------------
Public Type DEV_BROADCAST_HDR
    dbcc_size As Integer
    dbcc_devicetype As Integer
    dbcc_reserved As Integer
End Type

Public Type DEV_BROADCAST_DEVICEINTERFACE
    dbcc_size As Integer
    dbcc_devicetype As Integer
    dbcc_reserved As Integer
    dbcc_classguid As Variant
    dbcc_name As Variant
End Type

Public Declare Function CallWindowProc Lib "user32" _
  Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
                           ByVal hwnd As Long, _
                           ByVal Msg As Long, _
                           ByVal wParam As Long, _
                           ByVal lParam As Long) As Long

Public Declare Function GetWindowLong Lib "user32" _
  Alias "GetWindowLongA" (ByVal hwnd As Long, _
                          ByVal nIndex As Long) As Long

Public Declare Function SetWindowLong Lib "user32" _
  Alias "SetWindowLongA" (ByVal hwnd As Long, _
                          ByVal nIndex As Long, _
                          ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = (-4)
Public Const WM_DEVICECHANGE = &H219
Public Const UNSAFE_REMOVE = &H1C

Public glngPrevWndProc As Long

Public Function MyWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  If Msg = WM_DEVICECHANGE Then

    Select Case wParam
      Case &H8000&
        Call Form1.DeviceArrival (msgbox)
     
      Case &H8004&
        Call Form1.DeviceRemoveComplete (msgbox)
    End Select

    MyWindowProc = 0
    Exit Function
  End If
 
 ' pass the rest messages onto VB's own Window Procedure
  MyWindowProc = CallWindowProc(glngPrevWndProc, hwnd, Msg, wParam, lParam)
End Function

-------------------------------------------------------------------------------------

This code runs fine, but I would like to get the value of lParam, which I understand may contain device information, and is one of the following types:

Public Type DEV_BROADCAST_HDR
    dbcc_size As Integer
    dbcc_devicetype As Integer
    dbcc_reserved As Integer
End Type

Public Type DEV_BROADCAST_DEVICEINTERFACE
    dbcc_size As Integer
    dbcc_devicetype As Integer
    dbcc_reserved As Integer
    dbcc_classguid As Variant
    dbcc_name As Variant
End Type

My question is, how do I use one of the types above to get the details of lParam?

Thanks,

AArnie.

AArnieAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Erick37Commented:
You can use CopyMemory api to get the structure from a pointer:

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
        (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)



'...


Dim dev As DEV_BROADCAST_HDR

'Get the structure from lParam
Call CopyMemory(dev, ByVal lParam, LenB(dev))

'Modify dev here


'Pass the pointer back to lParam
Call CopyMemory(ByVal lParam, dev, LenB(dev))
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ArkCommented:
....
   dbcc_classguid As Variant
.....

Call CopyMemory(ByVal lParam, dev, LenB(dev))

In best case fill dbcc_classguid with garbage, but most likely crash apps. Variant is not an API data type
0
Erick37Commented:
Private Type GUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(0 To 7) As Byte
End Type

Public Type DEV_BROADCAST_DEVICEINTERFACE
    dbcc_size As Integer
    dbcc_devicetype As Integer
    dbcc_reserved As Integer
    dbcc_classguid As GUID
    dbcc_name As Long '? Pointer to a null-terminated string that specifies the name of the device.
End Type

Here is my best guess as to how to declare the type.  dbcc_name is declared as Short in all the .NET samples I saw, so I believe it is a Long data type in VB.  
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

ArkCommented:
//C prototype
typedef struct _DEV_BROADCAST_DEVICEINTERFACE {
  DWORD dbcc_size;
  DWORD dbcc_devicetype;
  DWORD dbcc_reserved;
  GUID dbcc_classguid;
  TCHAR dbcc_name[1];
} DEV_BROADCAST_DEVICEINTERFACE *PDEV_BROADCAST_DEVICEINTERFACE;

'VB equivalent
Public Type DEV_BROADCAST_DEVICEINTERFACE
    dbcc_size As Long
    dbcc_devicetype As Long
    dbcc_reserved As Long
    dbcc_classguid As GUID
    dbcc_name As Long '? Pointer to a null-terminated string that specifies the name of the device.
End Type

TCHAR means ANSI string (CHAR) for win9x and Unicode string (WCHAR) for NT
0
ArkCommented:
PS
Integer in .NET is Long in VB while Short = Integer, so

Public Type DEV_BROADCAST_HDR
    dbcc_size As Long
    dbcc_devicetype As Long
    dbcc_reserved As Long
End Type

Private Type GUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(0 To 7) As Byte
End Type

Public Type DEV_BROADCAST_DEVICEINTERFACE
    dbcc_size As Long
    dbcc_devicetype As Long
    dbcc_reserved As Long
    dbcc_classguid As GUID
    dbcc_name As String
End Type

Since dbcc_name is tha LAST membor of structure, its safety ebough to declare it as string
0
Erick37Commented:
AArnie - you left absolutely no comments on this thread.  Grading with a C is inappropriate.
0
AArnieAuthor Commented:
Erick37,

Apologies, I haven't read this question for a while, and thought I had asked for more than was supplied in the answer. I should have read it again before accepting/grading.

In fact your answer was spot on, and will be helpful, so I will post and ask for the grade to be ammended.

Hope this is satisfactory.

AArnie.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.