.NET Forum / Windows Forms / WinForm General / October 2004
Where is MAKEWPARAM
|
|
Thread rating:  |
Louise - 26 Oct 2004 16:13 GMT Can anyone tell me why makewparam gives the build error 'makewparam is not declared'? Do I have to create a reference?
Stoitcho Goutsev \(100\) [C# MVP] - 26 Oct 2004 17:56 GMT Louise,
MAKEWPARAM was a c/c++ macro it is not an API function. Unless you use c++ there is no preprocessor thus, macros.
 Signature HTH Stoitcho Goutsev (100) [C# MVP]
> Can anyone tell me why makewparam gives the build error 'makewparam is not > declared'? Do I have to create a reference? Louise - 26 Oct 2004 20:59 GMT Hi Stoitcho,
Thankyou for the reply - even though its not the answer I hoped for. I'm using VB .NET. Do you know of a function or method I could use instead to create wparam and lparam?
Louise
"Stoitcho Goutsev (100) [C# MVP]" wrote:
> Louise, > [quoted text clipped - 3 lines] > > Can anyone tell me why makewparam gives the build error 'makewparam is not > > declared'? Do I have to create a reference? Herfried K. Wagner [MVP] - 26 Oct 2004 21:45 GMT "Louise" <Louise@discussions.microsoft.com> schrieb:
> I'm using VB .NET. Do you know of a function or method > I could use instead to create wparam and lparam? Untested:
\\\ Private Function MAKEWPARAM( _ ByVal l As Int32, _ ByVal h As Int32 _ ) As Int32 Return (l And &HFFFF) Or (h << 16) End Function ///
 Signature Herfried K. Wagner [MVP] <URL:http://dotnet.mvps.org/
Stoitcho Goutsev \(100\) [C# MVP] - 26 Oct 2004 21:53 GMT Hi Louise,
wParams and lParams are nothing but Int32 with the current 32 bit versions of Windows.
To create such a function is not a big deal. I don't feel comfortable myself with VB syntax so I'll give you a sample in c#, but it has to be straightforward to translate it in VB
I'm not sure how VB handles bitwise and shift operations that's why I'll give you a version that I'm sure can be translated easely in VB
static int MakeWParam(int loWord, int hiWord) { return loWord + hiWord*65536; }
I guess you might want to have IntPtr as return value.
static IntPtr MakeWParam(int loWord, int hiWord) { return new IntPtr(loWord + hiWord*65536); }
There are chances that loWord and hiWord are actually bigger than 16 bit.
in c# I'd do (loWord & 0xFFFF) + ((hiWord & 0xFFFF)<< 16);
the latter is exaclty what the macros does, but I don't know if VB supports those operations
-- HTH Stoitcho Goutsev (100) [C# MVP]
> Hi Stoitcho, > [quoted text clipped - 15 lines] >> > not >> > declared'? Do I have to create a reference? Louise - 27 Oct 2004 17:35 GMT Hello guys,
Thank you very much for your help. I think I am now creating my parameters correctly, but this only takes me on to my next problem. I'm using these parameters to send messages to a selected window. The messages to the window seem to work ok but messages to the client area have no effect. e.g.
reslt = MoveWindow(mywindow.handle, 200, 150, 175, 300, 1)
works. But
reslt = PostMessage(mywindow.handle, WM_RBUTTONDOWN, 100, 100) reslt = PostMessage(mywindow.handle, WM_RBUTTONUP, 100, 100)
doesnt. any ideas about why that might be?
Thanks again,
Louise.
> Can anyone tell me why makewparam gives the build error 'makewparam is not > declared'? Do I have to create a reference? Stoitcho Goutsev \(100\) [C# MVP] - 27 Oct 2004 18:04 GMT Hi Louise, Does mywindow receive the messages? Because it might receive the messages but does some checking (for example the real position of the mouse cursor or call GetAsyncKeyState to check the mouse buttons) and then ignore the messages. Use Spy++ tool to check if the messages are delievered to the target
 Signature HTH Stoitcho Goutsev (100) [C# MVP]
> Hello guys, > [quoted text clipped - 20 lines] >> not >> declared'? Do I have to create a reference? Louise - 27 Oct 2004 21:25 GMT Hi Stoitcho,
Wow, what a great tool.
My postmessage attempt doesnt seem to reach the window
reslt = PostMessage(myslave.handle, WM_RBUTTONDOWN, 100, 100) reslt = PostMessage(myslave.handle, WM_RBUTTONUP, 100, 100)
there are no messages listed. But the send message commands
reslt = SendMessage(myslave.handle, WM_RBUTTONDOWN, 100, 100) reslt = SendMessage(myslave.handle, WM_RBUTTONUP, 100, 100) each produce a WM_NULL R and a WM_NULL S log record. I'm sending these messages to notepad. Is this some sort of security device that I have to switch off? I'm using XP SP3 and I also have Zonealarm Pro running.
Lou.
"Stoitcho Goutsev (100) [C# MVP]" wrote:
> Hi Louise, > Does mywindow receive the messages? Because it might receive the messages [quoted text clipped - 27 lines] > >> not > >> declared'? Do I have to create a reference? Stoitcho Goutsev \(100\) [C# MVP] - 27 Oct 2004 21:54 GMT Hi Louise,
No there is not security for that, beside the security permisions that your application needs to have in order to use PInvoke. As long as you can use MoveWindow API that is a sign that you have enough security permisions.
My guess is that your WM_RBUTTONXXX has wrong numbers
They need to be
WM_MBUTTONDOWN = 0x0207 WM_MBUTTONUP = 0x0208
WM_NULL is 0x0000. I don't know how you declare those constants, but check their value. Otherwise it doesn't make sense to me. Spy++ must've caught posted messages on the notpad side.
 Signature HTH Stoitcho Goutsev (100) [C# MVP]
> Hi Stoitcho, > [quoted text clipped - 52 lines] >> >> not >> >> declared'? Do I have to create a reference? Louise - 28 Oct 2004 13:49 GMT Hi Stoitcho,
Sorry to keep on with this but its become one of those problems that has taken over every minute of my thoughts. Still getting no response from the target window - after anther fruitless evening.
My form declarations include:
Private Function MAKEPARAM(ByVal LoWord As Int32, ByVal HiWord As Int32) As Long Return LoWord + (HiWord * 65536) End Function Const WM_RBUTTONDOWN = &H207 Const WM_RBUTTONUP = &H208
and I have a button_click event with:
reslt = SendMessage(mywindow.handle, WM_RBUTTONDOWN, MAKEPARAM(0, 0), MAKEPARAM(10, 20)) reslt = SendMessage(mywindow.handle, WM_RBUTTONUP, MAKEPARAM(0, 0), MAKEPARAM(10, 20))
the output from the spy++ log for the target window is:
<00001> 000307DA S WM_NULL wParam:00000207 lParam:00000000 <00002> 000307DA R WM_NULL lResult:00000000 <00003> 000307DA S WM_NULL wParam:00000208 lParam:00000000 <00004> 000307DA R WM_NULL lResult:00000000
I'm not sure how this output should look. I expected the first line to be something like:
S WM_RBUTTONDOWN wParam: 00000000 lparam:00100020
Any suggestions would be very welcome.
Lou.
"Stoitcho Goutsev (100) [C# MVP]" wrote:
> Hi Louise, > [quoted text clipped - 69 lines] > >> >> not > >> >> declared'? Do I have to create a reference? Stoitcho Goutsev \(100\) [C# MVP] - 28 Oct 2004 14:12 GMT Hi Louise,
Yes, that is strange. I believe this is not the problem, but mouse messages are normally post rather than sent. I know that you tried this in the first place and I know that Notepad couldn't know whether it is post or sent. Anyways, the code you post looks OK to me so, my next guess is that you didn't declare SendMessage method correctly. Can you post some working sample that demonstrates the problem in order to stop guessing?
 Signature Stoitcho Goutsev (100) [C# MVP]
> Hi Stoitcho, > [quoted text clipped - 119 lines] >> >> >> not >> >> >> declared'? Do I have to create a reference? Louise - 28 Oct 2004 17:15 GMT Hi Stoitcho,
This is a not-working example. A simple form with two buttons. Button1 opens Notepad and Button2 should type the letter P and do a right mouse-click.
I really an very grateful to you for looking at this. If you can point out whats wrong here I promise to go away and start a new thread with my next problem.
Lou.
Public Class Form1 Inherits System.Windows.Forms.Form Private Declare Function SetActiveWindow Lib "user32" Alias "SetActiveWindow" (ByVal hwnd As Long) As Long Private Declare Function SetForegroundWindow Lib "USER32" (ByVal hwnd As Long) As Boolean Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const VK_P = &H50 Const WM_KEYDOWN = &H100 Const WM_KEYUP = &H101 Const WM_RBUTTONDOWN = &H207 Const WM_RBUTTONUP = &H208
Private Function MAKEPARAM(ByVal LoWord As Int32, ByVal HiWord As Int32) As Long Return LoWord + (HiWord * 65536) End Function Public Structure NoteWindow Public handle As Long Public process As process End Structure Public mywindow As NoteWindow Public myProcess As Process
#Region " Windows Form Designer generated code "
Public Sub New() MyBase.New()
'This call is required by the Windows Form Designer. InitializeComponent()
'Add any initialization after the InitializeComponent() call myProcess = New Process() mywindow = New NoteWindow()
End Sub
'Form overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub
'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.Button1 = New System.Windows.Forms.Button() Me.Button2 = New System.Windows.Forms.Button() Me.SuspendLayout() ' 'Button1 ' Me.Button1.Location = New System.Drawing.Point(24, 24) Me.Button1.Name = "Button1" Me.Button1.Size = New System.Drawing.Size(104, 40) Me.Button1.TabIndex = 10 Me.Button1.Text = "Open Notepad" ' 'Button2 ' Me.Button2.Location = New System.Drawing.Point(24, 72) Me.Button2.Name = "Button2" Me.Button2.Size = New System.Drawing.Size(104, 40) Me.Button2.TabIndex = 11 Me.Button2.Text = "Send Messages" ' 'Form1 ' Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(176, 165) Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button2, Me.Button1}) Me.Name = "Form1" Me.Text = "Form1" Me.ResumeLayout(False)
End Sub
#End Region
Friend WithEvents Button2 As System.Windows.Forms.Button Friend WithEvents Button1 As System.Windows.Forms.Button
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click myProcess.StartInfo.FileName = "Notepad.exe" myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal myProcess.Start() myProcess.WaitForInputIdle() mywindow.process = myProcess mywindow.handle = myProcess.MainWindowHandle.ToString
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim reslt As New Long() SetActiveWindow(mywindow.handle) SetForegroundWindow(mywindow.handle) reslt = SendMessage(mywindow.handle, WM_KEYDOWN, MAKEPARAM(VK_P, 0), MAKEPARAM(1, 0)) reslt = SendMessage(mywindow.handle, WM_KEYUP, MAKEPARAM(VK_P, 0), MAKEPARAM(1, 0)) reslt = PostMessage(mywindow.handle, WM_RBUTTONDOWN, MAKEPARAM(0, 0), MAKEPARAM(10, 20)) reslt = PostMessage(mywindow.handle, WM_RBUTTONUP, MAKEPARAM(0, 0), MAKEPARAM(10, 20))
End Sub End Class
Stoitcho Goutsev \(100\) [C# MVP] - 28 Oct 2004 20:05 GMT Hi Louise,
Here is your code fixed. What were the problems:
1. Wrong types were used for the API methods. Check the types that I use. This is important because the stack frame that the managed code sends to the API has to be what the target expects otherwise it gets wrong parameter values.
2. I used Herfried K. Wagner version of MAKEWPARAM the reason being is that using multiplication throws overflow exception with VB. I believe it can be done that way, but I fill my self lost in VB types system and typecasting.
3. The reason why Notepad didn't receive any of the messages with your version of the programwas that Notpad has one main top-level window and the actual editor is a child of this main window. What you did is to send the messages to the main window. It doesn't know what to do with them. You have to send the messages to the edit window. You can check the windows structure of Notepad with Spy++. What I do is I use GetWindow API to get the first child of the main window. It happens that this is the edit window. But actually the correct way would be to go thru all children and find the correct one.
4. You don't send keyboard messages. Unlike the mouse messages where probably is not a big of a difference if you send or post the msg, keyboard messages have to be posted. The reason being is that in the message loop usually there is TranslateMessage call that generates WM_CHAR for example or call for generates shortcut events, etc. So, you post keyboard messages rather than send them.
Take a look on the changes I've made. If you have more problems don't hesitate to post them in the ng
Public Class Form1 Inherits System.Windows.Forms.Form Private Declare Function SetActiveWindow Lib "user32" Alias "SetActiveWindow" (ByVal hwnd As IntPtr) As IntPtr Private Declare Function SetForegroundWindow Lib "USER32" (ByVal hwnd As IntPtr) As Boolean Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Long Private Declare Function GetWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As IntPtr, ByVal uCmd As Integer) As IntPtr
Const VK_P = &H50 Const WM_KEYDOWN = &H100 Const WM_KEYUP = &H101 Const WM_RBUTTONDOWN = &H204 Const WM_RBUTTONUP = &H205 Const GW_CHILD = &H5
Private Function MAKEPARAM(ByVal l As Int32, ByVal h As Int32) As Int32 Return (l And &HFFFF) Or (h << 16) End Function
'Private Function MAKEPARAM(ByVal LoWord As UInt16, ByVal HiWord As UInt16) As UInt32 ' Return LoWord Or (HiWord << 16) 'End Function
Public Structure NoteWindow Public handle As IntPtr Public process As process End Structure Public mywindow As NoteWindow Public myProcess As Process
#Region " Windows Form Designer generated code "
Public Sub New() MyBase.New()
'This call is required by the Windows Form Designer. InitializeComponent()
'Add any initialization after the InitializeComponent() call myProcess = New Process mywindow = New NoteWindow
End Sub
'Form overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub
'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.Button1 = New System.Windows.Forms.Button Me.Button2 = New System.Windows.Forms.Button Me.SuspendLayout() ' 'Button1 ' Me.Button1.Location = New System.Drawing.Point(24, 24) Me.Button1.Name = "Button1" Me.Button1.Size = New System.Drawing.Size(104, 40) Me.Button1.TabIndex = 10 Me.Button1.Text = "Open Notepad" ' 'Button2 ' Me.Button2.Location = New System.Drawing.Point(24, 72) Me.Button2.Name = "Button2" Me.Button2.Size = New System.Drawing.Size(104, 40) Me.Button2.TabIndex = 11 Me.Button2.Text = "Send Messages" ' 'Form1 ' Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(176, 165) Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button2, Me.Button1}) Me.Name = "Form1" Me.Text = "Form1" Me.ResumeLayout(False)
End Sub
#End Region
Friend WithEvents Button2 As System.Windows.Forms.Button Friend WithEvents Button1 As System.Windows.Forms.Button
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click myProcess.StartInfo.FileName = "Notepad.exe" myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal myProcess.Start() myProcess.WaitForInputIdle() mywindow.process = myProcess mywindow.handle = myProcess.MainWindowHandle
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim reslt As New Long Dim editBox As New IntPtr SetActiveWindow(mywindow.handle) SetForegroundWindow(mywindow.handle) editBox = IntPtr.Zero
editBox = GetWindow(mywindow.handle, GW_CHILD)
reslt = PostMessage(editBox, WM_KEYDOWN, MAKEPARAM(VK_P, 0), MAKEPARAM(1, &H19)) reslt = PostMessage(editBox, WM_KEYUP, MAKEPARAM(VK_P, 0), MAKEPARAM(1, &HC019)) reslt = PostMessage(editBox, WM_RBUTTONDOWN, MAKEPARAM(0, 0), MAKEPARAM(10, 20)) reslt = PostMessage(editBox, WM_RBUTTONUP, MAKEPARAM(0, 0), MAKEPARAM(10, 20))
End Sub End Class
--- HTH Stoitcho Goutsev (100) [C# MVP]
Louise - 30 Oct 2004 18:04 GMT Hi Stoitcho,
Sorry for the delay in replying - I had to go away for a couple of days.
This code is absolutely terrific I'm so very grateful, thankyou very much. I obviously have a lot to learn but you have given me some very good pointers and saved me a heck of a lot of time.
Thankyou again,
Lou.
"Stoitcho Goutsev (100) [C# MVP]" wrote:
> Hi Louise, > [quoted text clipped - 173 lines] > HTH > Stoitcho Goutsev (100) [C# MVP] Stoitcho Goutsev \(100\) [C# MVP] - 31 Oct 2004 15:02 GMT Hi Louise,
You are very welome. If you have more questions just post them
 Signature Stoitcho Goutsev (100) [C# MVP]
> Hi Stoitcho, > [quoted text clipped - 204 lines] >> HTH >> Stoitcho Goutsev (100) [C# MVP]
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|