Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WindProc 2

Status
Not open for further replies.

LPlates

Programmer
Jun 5, 2003
554
AU
Im SubClassing the App to intercept windows messages...

lngOriginal_Window_Procedure = SetWindowLong(Handle, GWL_WNDPROC, [blue]AddressOf [/blue]WindowProc)

The SendMessage API 'lParam' is declared as Any, however when using the WindProc Procedure it is declared as Long..

[blue]Public Function [/blue]WindowProc([blue]ByVal [/blue]Handle [blue]As Long[/blue], [blue]ByVal [/blue]uMsg [blue]As Long[/blue], [blue]ByVal [/blue]wParam [blue]As Long[/blue], [blue]ByVal [/blue]lParam [blue]As Long[/blue]) As Long


... So incase you havent guessed Im trying to pass parameters other than Long's for example a String: "c:\a\test\path\"

Ive tried a few things including declaring the lParam as Any with no luck.
Any idea's anyone?


 
You cannot do this. The Any keyword is only allowed in declare statement. It means that you cannot declare a variable of type Any in a VB procedure.

The Any data type is supported in API declarations because many API functions accept arguments whose type and meaning changes depending upon its usage. An excellent example is the SendMessage function itself, in which the lParam parameter can assume hundreds of different data types serving different purposes depending upon the actual message being sent. The Any keyword tells VB to disable the data type varification.

To work around this, you need to examine the lParam parameter in the callback procedure itself. It is declared there as a Long argument. However, you can retrieve the actual parameter passed their by treating this argument as a pointer and typecasting it to the desired data type. This typecasting is typically done with CopyMemory function. Note that it is not the real typecasting which we do in C++ but it is a fake typecasting that allows us convert the data passed as lParam parameter back to its original format, whether it was a string, a long, a byte array, an object reference, a UDT or whatever else. (Probably the term typecasting is wrong and should not be used here!)

See this example code below. In this code I have subclassed the main window and sent it a WM_SETTEXT message to change its caption. In the window procedure, the WM_SETTEXT is intercepted and the original text string which was passed as lParam argument is converted back to its original string format, with the help of CopyMemory function. I have choosen WM_SETTEXT because it also accepts a string argument in lParam parameter as you are doing. Similar method can be used to convert other data types, that I mentioned above.

Place a command button and a text box on your form and insert the following code in it.
___
[tt]
Option Explicit
Private Sub Form_Load()
lngOriginal_Window_Procedure = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
Text1.Text = "New Caption"
Command1.Caption = "Change Title"
End Sub

Private Sub Command1_Click()
Dim strTitle As String
strTitle = Text1.Text
MsgBox "Sending WM_SETTEXT message to change the title to """ & strTitle & """."
SendMessage hWnd, WM_SETTEXT, 0, ByVal strTitle
End Sub[/tt]
___

Now add a module to the project and insert the following code in it.
___
[tt]
Option Explicit
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
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
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Const WM_SETTEXT = &HC
Public Const GWL_WNDPROC = (-4)
Public lngOriginal_Window_Procedure As Long
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_SETTEXT Then
Dim strTitle As String
'create a buffer large enough to hold the title string
strTitle = Space$(1024)
'copy the string data from the lParam pointer to strTitle
CopyMemory ByVal strTitle, ByVal lParam, Len(strTitle)
'strip out the null terminator
strTitle = Split(strTitle, vbNullChar)(0)
MsgBox "Trapped WM_SETTEXT message in the window procedure. The new title is """ & strTitle & """, which is retrieved from the lParam (type Long) argument in the window procedure."
End If
WindowProc = CallWindowProc(lngOriginal_Window_Procedure, hWnd, uMsg, wParam, lParam)
End Function[/tt]
___

Run the program and see how it goes. It will give you a clear idea how to get the orginal string back from "[tt]ByVal lParam As Long[/tt]" argument in the window procedure.

Good Luck.
 
Ahh, excellent stuff! A star for you, thanks Hypetia
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top