|
oh yes, my bad completely
I may or may not be responsible for my own actions
|
|
|
|
|
yes and no.
Extension methods, while requiring a static keyword, are really instance methods; now Parse and TryParse are basically static methods, they operate on a string and return a specific type, they don't operate on that type (the MSDN example is string.WordCount which operates on an existing string and returns an int).
So you could have this definition (note the first argument isn't used at all):
public static class MoreTryParse {
public static bool TryParse(this RectangleF dummy, string s, out RectangleF rect) {
float x=0;
float y=0;
float w=0;
float h=0;
if (s.StartsWith("(") && s.EndsWith(")")) s=s.Substring(1, s.Length-2);
string[] sa=s.Split(',');
if (sa.Length==4 && float.TryParse(sa[0], out x) && float.TryParse(sa[1], out y) &&
float.TryParse(sa[2], out w)&& float.TryParse(sa[3], out h)) {
rect=new RectangleF(x, y, w, h);
return true;
} else {
rect=new RectangleF(0, 0, 0, 0);
return false;
}
}
}
but then you would have to call it like this:
public void test(string s) {
RectangleF rect=new RectangleF();
bool result=rect.TryParse(s, out r1);
log(s+" result="+result+" rect="+rect.ToString());
}
which is a bit silly, as you have to create a dummy RectangleF in order to get the actual one.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.3
|
|
|
|
|
But I'm intrested in that calling convention
string s = "0.0,0.0,1.0,1.0";
RectangleF rect = RectangleF.Parse(s);
I wonder if there is any mechanism available to add public static methods to the class?
If not it'd be of value to add it to future revisions of C#
Чесноков
|
|
|
|
|
Chesnokov Yuriy wrote: add public static methods
No, that is not supported in C#.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.3
|
|
|
|
|
I don't think this is possible. I don't see what is wrong with
RectangleF rect = MyParserClass.ParseRectangleF(s);
... though.
|
|
|
|
|
That is fine of course, however it would be even nicer if one could add static extension classes, so one can hide the fact that RectangleF is lacking the static Parse() and TryParse() methods other types are offering (int, float, DateTime, etc).
It could e.g. look like:
public static class MoreTryParse {
public static bool TryParse(static, string s, out RectangleF rect) {
...
}
}
and be called like so:
public void test(string s) {
RectangleF rect;
bool result=RectangleF.TryParse(s, out r1);
log(s+" result="+result+" rect="+rect.ToString());
}
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.3
|
|
|
|
|
That's a matter of taste, I think. I don't like extension methods much as it stands because you never know where they are actually defined.
Your declaration wouldn't do the job, it doesn't declare anywhere that it's a static extension on RectangleF. It would have to be
public static bool TryParse(static RectangleF, string s, out RectangleF rect) { ... }
or perhaps
public static bool TryParse(static<T>, string s, out RectangleF rect) where T:RectangleF { ... }
... allowing you to extend entire generic hierarchy subtrees where it was convenient to do so.
|
|
|
|
|
yes, public static bool TryParse(static RectangleF, string s, out RectangleF rect) { ... } is what I meant.
BobJanova wrote: you never know where they are actually defined.
the IDE can worry about that, you don't have to.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.3
|
|
|
|
|
Although we declare extension methods to be static, they actually work on instances (note that we specify the 'this' keyword in the first parameter). I would love to have the feature you're asking for, so we can use Rectangle.Parse(str) . In your case, the neater alternative is to create a static Parser class and have a ToRectangeF method like this:
static class Parser {
static RectangeF ToRectangeF(string s) {
....
}
}
|
|
|
|
|
Perhaps an implementation like this[^], which I discussed with him when he originally raised this question this morning.
|
|
|
|
|
Hi All,
I am trying to simulate a button click using the SendMessage function of the Win32API. My application is C# WinForms .net 4.0 (the application performing the automation)
EDIT: The application I am trying to automate is not of my own work and I have no control over source code in any way.
First of all I am using FindWindow to get the handle to the window I want, I know this is working as the value of the handle is correct (as found using Spy++)
Next I am getting the handle of the child control (the button I want to click), again I know I am getting the correct value here.
Then I use SetActiveWindow() and pass in the window handle (which appears to work fine)
Then I use SendMessage() to simulate a mouse left button down and a mouse left button up. For now I just want to simulate the "Cancel" button for testing, which when clicked manually will simply close the form. My code however does nothing, the thing that is annoying me thou is that the "Cancel" button actually gets focus (just like it would if it had been clicked manually) but no action is taken.
Does anybody know why this could be happening? Is it possible that the application is question could be detecting I am using the SendMessage function and deciding not to process the relevant code? sort of like a "prevent automation" feature.
Thanks for any help, and the relevant code for SendMessage is as follows (also note, I have tried PostMessage too)
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
uint WM_LBUTTONDOWN = 0x0201;
uint WM_LBUTTONUP = 0x0202;
uint BM_SETSTATE = 0x00F3;
uint BN_CLICKED = 245;
void Function()
{
SendMessage(hwndButton, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwndButton, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwndButton, BM_SETSTATE, IntPtr.Zero, IntPtr.Zero);
SendMessage(hwndButton, BN_CLICKED, IntPtr.Zero, IntPtr.Zero);
}
I may or may not be responsible for my own actions
modified on Tuesday, May 31, 2011 11:59 AM
|
|
|
|
|
Did you try BM_CLICK instead?
|
|
|
|
|
I think BM_CLICK is the same as I have BN_CLICKED (seen different name in different places). I have used a value of 245, if you know a different value for BM_CLICK then please let me know and I will give that a try
I may or may not be responsible for my own actions
|
|
|
|
|
Not sure if your BN_CLICKED and BM_CLICK are same, but here is what the documentation at http://msdn.microsoft.com/en-us/library/bb775985(VS.85).aspx[^] says:
"Simulates the user clicking a button. This message causes the button to receive the WM_LBUTTONDOWN and WM_LBUTTONUP messages, and the button's parent window to receive a BN_CLICKED notification code."
I believe that the parent must be notified of the event for it to handle the event and BM_CLICK does this.
|
|
|
|
|
And I just verified that BM_CLICK is 245 (0x00F5) in winuser.h
|
|
|
|
|
Hmmm, so this is what I am using for BN_CLICKED so this should be the same as you suggested then
I may or may not be responsible for my own actions
|
|
|
|
|
Why are you attempting to go the long way round to automate the application? There's a feature called Microsoft Active Accessibility (MSAA)[^] which provides accessibility for WinForms applications. This allows you to get access to controls, and automate them.
|
|
|
|
|
Thanks for your reply, but I think you think this application I want to automate is my own application? Just to clear it up, this is a 3rd party application which I have no control over source code in any way.
Perhaps I am wrong and there is more to the information you linked, but it appears these are guidelines on how to create an application that allows for programmatic calls to achieve automation, right?
I may or may not be responsible for my own actions
|
|
|
|
|
|
How to convert RectangleF to and back from string representation in a similar way as Int32.Parse()?
Чесноков
|
|
|
|
|
You could use this[^] to convert it to a string, but you would need to write your own method to reconvert from strings to the structure.
The best things in life are not things.
|
|
|
|
|
The following class could be used (with a bit of beefing up) to convert back from a string representation:
namespace ParseRectangleF
{
using System;
using System.Drawing;
public static class ParserUtility
{
public static RectangleF Parse(string value)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException(value);
value = value.Replace("{", string.Empty).Replace("}", string.Empty).Replace(" ", string.Empty);
var rectangle = new RectangleF();
rectangle.X = GetValue(value, "X=");
rectangle.Y = GetValue(value, "Y=");
rectangle.Width = GetValue(value, "Width=");
rectangle.Height = GetValue(value, "Height=");
return rectangle;
}
private static float GetValue(string value, string key)
{
if (!key.EndsWith("="))
{
key += "=";
}
int ordinal = value.IndexOf(key, StringComparison.CurrentCultureIgnoreCase);
int length = ordinal + key.Length;
int commaPos = value.IndexOf(",", length);
if (commaPos < length)
{
commaPos = value.Length;
}
string text = value.Substring(length, commaPos - length);
float output;
if (!float.TryParse(text, out output))
{
throw new ArgumentException(
string.Format("The input {0} is not the right format for Parse. It should be formatted like X=nn, Y=, Width=nn, Height=nn.", value));
}
return output;
}
}
} To call it, all you need to do is:
RectangleF rect = ParserUtility.Parse("{x=10, y=10, width=100,height=300");
|
|
|
|
|
Thank you for the code, why the same can not be executed with System.Drawing.RectangleConverter.
It worked with Rectangle but failed with RectangleF
Чесноков
|
|
|
|
|
You can achieve the same effect with the RectangleConverter, if you use the following code:
RectangleF rect = (RectangleF)(Rectangle)conv.ConvertFromInvariantString("10,10,100,300"); The ConvertFrom methods return an object, so you need to cast it into a Rectangle first before you can cast it into a RectangleF. It's a bit backwards, I know, but it does work.
|
|
|
|
|
the values in RectangleF are fractional
Чесноков
|
|
|
|
|