From: Willy Denoyette [MVP] on

"SQACSharp" <lsdisciples(a)hotmail.com> wrote in message
news:1162777298.122438.228350(a)b28g2000cwb.googlegroups.com...
|I change ReturnMsg to a IntPointer
| IntPtr ReturnMsg = IntPtr.Zero;
|
| Here is the missing declaration for SendMessage :
| [DllImport("user32.dll", CharSet = CharSet.Auto)]
| public static extern IntPtr SendMessage(IntPtr handle, uint msg, IntPtr
| wParam, IntPtr
| lParam);
|
| But it still return 0 for and 0 bytes read....
|
|
|
| Michel
|

This should work, provided the target copied the Name into the shared
buffer, that is the target must handle the WM_GETCONTROLNAME message!!!!
THIS IS TRUE FOR WINDOWS FORMS APPLICATIONS, but in general it's NOT the
case for native Windows applications!.

....
int size = 65356;
IntPtr retSize = SendMessage(hwnd, msg, new IntPtr(size), bufferMem);
if(retSize != IntPtr.Zero) // retSize should hold the number of TCHAR
returned
{
int nSize = (int)retSize * sizeof(char);
byteArray = new byte[nSize]; //allocate array to hold the control
name in UNICODE char's
retVal = ReadProcessMemory(processHandle, bufferMem, byteArray, new
IntPtr(nSize), out written);
if(!retval)
// failed...
else
// success, copy byte array to string..
...
}

Willy.


From: Willy Denoyette [MVP] on

"SQACSharp" <lsdisciples(a)hotmail.com> wrote in message
news:1162778801.492593.235980(a)k70g2000cwa.googlegroups.com...
| the function RegisterWindowMessage("WM_GETCONTROLNAME");
| return 49589..... If I call RegisterWindowMessage("WM_BLABLABLA"); it
| also return 49589 ??????
|
| Is this return value is a kind of non found return value????
| Are you sure I can use registerWindowMessage to get the int value of
| const "WM_GETCONTROLNAME" ???
|
|
| System.UInt32 SendMsg;
| SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME");
| MessageBox.Show(SendMsg.ToString());
|

No, the value returned is the unique "message ID" produced by the system,
it's used to identify the WM_GETCONTROLNAME message. Each application
calling RegisterWindowMessage("WM_GETCONTROLNAME");
will get the same value back.
If you send this ID using SendMessage, the another application, provided she
has called RegisterWindowMessage("WM_GETCONTROLNAME")) and installed a
handler for this message,
knows that she has to return the "Control Name" corresponding to the hwnd
into the shared buffer.



Willy.


From: SQACSharp on
Thanks again for your help Willy but it still not working at all.

1 - I'm still thinking that the problem is the message.
RegisterWindowMessage("WM_GETCONTROLNAME"); and
RegisterWindowMessage("WM_BLABLABLA"); should not return the same value
: 49589 it make no sense.

2- You said that the target must handle the WM_GETCONTROLNAME
message....you mean the object must have a "name" property? In my case
all my object have a "name" property.

since i'm trying to solve this problem for almost two weeks, i need to
find another solution because WM_GETCONTROLNAME is defenitivly not
working (my code is the same as the last code you post in the thread)


Here is my problem :
I try to create an automated testing tools (like rational robot,
silktest, winrunner, ...etc...)
I can do everything except identifying the object by name or by it's
property.

Question 1 : Is there any other way to get the name property of the
control? By example if I want to get the "hint" , "Left", "top" , "
BorderStyle" , "visible" , ... How i'm suppose to do that?

Question 2 : How the automated testing tool like rational robot can
retrieve the object name without sending API message. In spy++ If I
log the message sended to my application while an automation tool (like
rational robot) is retreiving the properties of a control the only
message sended look like
<00171> 000203A2 R message:0xC1C6 [Registered:"SQA Dispatch Message8"]
lResult:00000000
<00172> 000203A2 S message:0xC1C6 [Registered:"SQA Dispatch Message8"]
wParam:00000000 lParam:0012F91C
.....
<00189> 000203A2 S message:0xBD33 [User-defined:WM_USER+47411]
wParam:2501056D lParam:000203A2
<00190> 000203A2 R message:0xBD33 [User-defined:WM_USER+47411]
lResult:B110103E

Look like there is no WM_GETCONTROLNAME message and they are able to
get the controlname?? how ?

Is there any other way to get the "name" property of a control???

From: Willy Denoyette [MVP] on

"SQACSharp" <lsdisciples(a)hotmail.com> wrote in message
news:1162921809.136396.65580(a)i42g2000cwa.googlegroups.com...
| Thanks again for your help Willy but it still not working at all.
|
| 1 - I'm still thinking that the problem is the message.
| RegisterWindowMessage("WM_GETCONTROLNAME"); and
| RegisterWindowMessage("WM_BLABLABLA"); should not return the same value
| : 49589 it make no sense.
|


You don't seem to understand what RegisterWindowsMessage is all about.
When you call:

int r1 = NativeMethods.RegisterWindowMessage("WM_GETCONTROLNAME");
int r2 = NativeMethods.RegisterWindowMessage("WM_BlaBla");
in the same application you will get two different Message ID's Back from
the system.

The first application that calls RegisterWindowMessage gets an int back that
identifies THIS particular message (say "WM_GETCONTROLNAME"), every
successive application which calls the RegisterWindowMessage specifying
"WM_GETCONTROLNAME", will get the same ID back.
The "message ID" is freed by the system after ALL applications that have
called RegisterWindowMessage("WM_GETCONTROLNAME") have terminated. That
means that an application (started after this) who calls
RegisterWindowMessage("BlaBla") will probably get the same ID previously
assigned to identify WM_GETCONTROLNAME back.

The period between the first call of
RegisterWindowMessage("WM_GETCONTROLNAME");
and the time the last application that has called
RegisterWindowMessage("WM_GETCONTROLNAME"); terminates, is called a session.
I and I said before, messageID are guaranteed to remain constant within a
session only.

According the behavior you notice, I can tell that your application is the
first and only one to call RegisterWindowMessage("WM_GETCONTROLNAME");. This
means that there is no other program waiting for WM_GETCONTROLNAME messages,
forcibly you won't get anything back from the other program when calling
SendMessage(..).
As I said before, Windows Forms applications register this WM_GETCONTROLNAME
message as part of their initialization, other Windows applications have to
register WM_GETCONTROLNAME explicitly and must handle the message
accordingly!
Windows Forms does this to overcome an issue with the naming scheme used to
identify a windows class, class names look like :
"WindowsForms10.EDIT.app.0.33c0d9d" and this name might change for every new
application invocation. So Windows Forms has added a Name attribute to it's
form elements and returns this Name when receiving a SendMessage requesting
WM_GETCONTROLNAME.
So it looks like the other application is not Windows Forms, so you
can't/don't have to use this technique, you just need to enumerate a Windows
tree using the know Windows API's, like FindWindows, EnumWindows,
GetClassName etc...

Willy.


From: SQACSharp on
damn.... Theses API functions are not well documented and finding a
working c# usage example is almost impossible.

If I want to enumerate all the controls (windows) in a windows, like
SPY ++?

[DllImport("User32.dll")]
public static extern int FindWindow(String lpClassName,String
lpWindowName);

public delegate bool CallBack(IntPtr hwnd, int lParam);

[DllImport("user32"), SuppressUnmanagedCodeSecurityAttribute]
public static extern int EnumWindows(CallBack x, int y);

IntPtr hwnd = FindWindow(null, "Login");
EnumWindows(???)

What is delegate?
What is this callback?
How the hell i'm suppose to call the enumwindows to get the control of
my application?

After looking for examples in the net for guessing how to call the
EnumWindow function, I still have no clue.

Did you have an example or a something to start with to list the
control in my login window ? (This window contain 2 textbox, 2 labels
and 2 buttons)

I also check another way to interact with the object of my
application....why we cannot reference the external for using code like
this :
IntPtr hwnd = FindWindow(null, "Login");
Form MyExternalForm = FromHandle(hwnd);
MessageBox.Show(MyExternalForm.label1.text)