From: SQACSharp on 3 Nov 2006 18:23 I'm trying to get the control name of an editbox in another window. The following code set the value "MyPassword" in the password EditBox but it fail to return the control name of the EditBox. I'm sure the problem is the way i'm using the sendmessage API, the return string and the lParam return 0....is anybody have a clue? any sendmessage api expert here? [DllImport("User32.dll")] public static extern Int32 FindWindow(String lpClassName,String lpWindowName); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle); [DllImport("user32.dll")] public static extern UInt32 RegisterWindowMessage([MarshalAs(UnmanagedType.LPTStr)] String lpString); // .... int hwnd = 0; IntPtr hwndChild = IntPtr.Zero; hwnd = FindWindow(null, "Login"); hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "TEdit", ""); SetControlText((int)hwndChild, WM_SETTEXT, 0, "MyPassword"); //the following is not working as expected to get the control name uint SendMsg; SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME"); long ReturnMsg; IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(ptr, IntPtr.Zero); ReturnMsg=SendMessage((int)hwndChild, (int)SendMsg, 65536, ptr); IntPtr CtrlName = Marshal.ReadIntPtr(ptr); MessageBox.Show(CtrlName.ToString()); MessageBox.Show(ReturnMsg.ToString()); Marshal.FreeCoTaskMem(ptr);
From: SQACSharp on 4 Nov 2006 13:58 Still need help :(
From: Peter Duniho on 4 Nov 2006 14:07 "SQACSharp" <lsdisciples(a)hotmail.com> wrote in message news:1162666690.828659.259590(a)i42g2000cwa.googlegroups.com... > Still need help :( I still don't know the answer.
From: Willy Denoyette [MVP] on 4 Nov 2006 14:48 "SQACSharp" <lsdisciples(a)hotmail.com> wrote in message news:1162596214.680573.161130(a)h54g2000cwb.googlegroups.com... | I'm trying to get the control name of an editbox in another window. | | The following code set the value "MyPassword" in the password EditBox | but it fail to return the control name of the EditBox. I'm sure the | problem is the way i'm using the sendmessage API, the return string and | the lParam return 0....is anybody have a clue? any sendmessage api | expert here? | | [DllImport("User32.dll")] | public static extern Int32 FindWindow(String lpClassName,String | lpWindowName); | [DllImport("user32.dll", CharSet = CharSet.Auto)] | public static extern int SendMessage(int hWnd, int msg, int wParam, | IntPtr lParam); | [DllImport("user32.dll", SetLastError = true)] | public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr | childAfter, string className, string windowTitle); | [DllImport("user32.dll")] | public static extern UInt32 | RegisterWindowMessage([MarshalAs(UnmanagedType.LPTStr)] String | lpString); | // .... | | int hwnd = 0; | IntPtr hwndChild = IntPtr.Zero; | hwnd = FindWindow(null, "Login"); | hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "TEdit", ""); | SetControlText((int)hwndChild, WM_SETTEXT, 0, "MyPassword"); | | //the following is not working as expected to get the control name | uint SendMsg; | SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME"); | long ReturnMsg; | IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr))); | Marshal.WriteIntPtr(ptr, IntPtr.Zero); | ReturnMsg=SendMessage((int)hwndChild, (int)SendMsg, 65536, ptr); | IntPtr CtrlName = Marshal.ReadIntPtr(ptr); | MessageBox.Show(CtrlName.ToString()); | MessageBox.Show(ReturnMsg.ToString()); | Marshal.FreeCoTaskMem(ptr); | You can't use locally allocated heap buffers when the HWND of the window you send the GETCONTROLNAME to, belongs to a thread in another process. You have to allocate the buffer in the other process memory space using OpenProcess followed by VirtualAllocEx, after calling SendMessage you'll have to read the buffer using ReadProcessMemory followed by a call to VirtualFreeEx. Note also that you should carefully check the return values of the API's, and beware that the other process must run in the same winsta/desktop pair, that is, in the same logon session. Willy.
From: SQACSharp on 4 Nov 2006 20:51 Your help is really appreciated Willy since i'm trying to do this since almost a week :( Ok i try to understand how to use the openProcess, VirtualAllocEx, ReadProcessMemory and VirtualFreeEx to solve my problem but i'm not sure exactly how i'm suppose to use the ReadProcessMemory to retreive the controlname returned by my sendmessage API call..This is what it look like after spending 3-4 more hours on that : System.Diagnostics.Process.Start("\"C:\\MyApplication.exe\"", ""); int hwnd = 0; IntPtr hwndChild = IntPtr.Zero; hwnd = FindWindow(null, "Login"); hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "TEdit", ""); SetControlText((int)hwndChild, WM_SETTEXT, 0, "MyPassword!"); // The following is my nightmare to get the controlname....still not working :( System.Diagnostics.Process[] processes; processes = System.Diagnostics.Process.GetProcesses(); uint ProcessId; IntPtr hProcess = IntPtr.Zero; const uint PROCESS_ALL_ACCESS = (uint)(0x000F0000L | 0x00100000L | 0xFFF); foreach (System.Diagnostics.Process instance in processes) { if (instance.ProcessName == "MyApplication") { ProcessId = (uint)instance.Id; hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, (uint)instance.Id); } } if (hProcess == IntPtr.Zero) throw new ApplicationException("Failed to access process"); const int dwBufferSize = 1024; const uint MEM_COMMIT = 0x1000; const uint MEM_RELEASE = 0x8000; const uint PAGE_READWRITE = 0x04; IntPtr lpRemoteBuffer = IntPtr.Zero; IntPtr lpLocalBuffer = IntPtr.Zero; IntPtr threadId = IntPtr.Zero; lpLocalBuffer = Marshal.AllocHGlobal(dwBufferSize); lpRemoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, dwBufferSize, MEM_COMMIT, PAGE_READWRITE); if (lpRemoteBuffer == IntPtr.Zero) throw new SystemException("Failed to allocate memory in remote process"); Int32 SendMsg; SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME"); long ReturnMsg; IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(ptr, IntPtr.Zero); MessageBox.Show(SendMsg.ToString()); ReturnMsg = SendMessage((int)hwndChild, SendMsg, 65536, lpRemoteBuffer); bool bSuccess; bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize,IntPtr.Zero); if (!bSuccess) throw new SystemException("Failed to read from process memory"); string retval; retval = Marshal.PtrToStringAnsi(lpRemoteBuffer); MessageBox.Show(retval); //This is not working....how I'm suppose to read the string value returned by my sendmessage??? Willy Denoyette [MVP] wrote: > "SQACSharp" <lsdisciples(a)hotmail.com> wrote in message > news:1162596214.680573.161130(a)h54g2000cwb.googlegroups.com... > | I'm trying to get the control name of an editbox in another window. > | > | The following code set the value "MyPassword" in the password EditBox > | but it fail to return the control name of the EditBox. I'm sure the > | problem is the way i'm using the sendmessage API, the return string and > | the lParam return 0....is anybody have a clue? any sendmessage api > | expert here? > | > | [DllImport("User32.dll")] > | public static extern Int32 FindWindow(String lpClassName,String > | lpWindowName); > | [DllImport("user32.dll", CharSet = CharSet.Auto)] > | public static extern int SendMessage(int hWnd, int msg, int wParam, > | IntPtr lParam); > | [DllImport("user32.dll", SetLastError = true)] > | public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr > | childAfter, string className, string windowTitle); > | [DllImport("user32.dll")] > | public static extern UInt32 > | RegisterWindowMessage([MarshalAs(UnmanagedType.LPTStr)] String > | lpString); > | // .... > | > | int hwnd = 0; > | IntPtr hwndChild = IntPtr.Zero; > | hwnd = FindWindow(null, "Login"); > | hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "TEdit", ""); > | SetControlText((int)hwndChild, WM_SETTEXT, 0, "MyPassword"); > | > | //the following is not working as expected to get the control name > | uint SendMsg; > | SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME"); > | long ReturnMsg; > | IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr))); > | Marshal.WriteIntPtr(ptr, IntPtr.Zero); > | ReturnMsg=SendMessage((int)hwndChild, (int)SendMsg, 65536, ptr); > | IntPtr CtrlName = Marshal.ReadIntPtr(ptr); > | MessageBox.Show(CtrlName.ToString()); > | MessageBox.Show(ReturnMsg.ToString()); > | Marshal.FreeCoTaskMem(ptr); > | > > You can't use locally allocated heap buffers when the HWND of the window you > send the GETCONTROLNAME to, belongs to a thread in another process. You have > to allocate the buffer in the other process memory space using OpenProcess > followed by VirtualAllocEx, after calling SendMessage you'll have to read > the buffer using ReadProcessMemory followed by a call to VirtualFreeEx. > Note also that you should carefully check the return values of the API's, > and beware that the other process must run in the same winsta/desktop pair, > that is, in the same logon session. > > Willy.
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: How to get any upload using WUA API ? Next: microsoft.common.target |