Click here to Skip to main content
14,668,470 members
Rate this:
Please Sign up or sign in to vote.
See more:
I'm writing a WinForms app where I want to show/hide a modeless window at a specific location relative to a control's position of the parent form. Not being able to find anything in the framework that let me do this via google, I started muddling around, and I came up with the following code (which works just fine):

// label1 is the control under which I want to position the modeless form 

// Determine the location of the client rectange in relation to the 
// parent window's location (the clientRectangle.Location property 
// is always (0,0), so we have to calculate this ourselves).
int   clientX         = (int)((this.Size.Width - this.ClientSize.Width) / 2);
int   clientY         = this.Size.Height - clientX - this.ClientSize.Height;
// create the modelsess window and set its location
Form  modelessForm    = new Form();
modelessForm.Location = new Point(this.Location.X + clientX + this.label1.Location.X, 
				  this.Location.Y + clientY + this.label1.Location.Y);


My question is this - Is there a class/method in the framework that does what I'm trying to do?

Side Note: I also considered invoking the API methods DPtoLP and LPtoDP, but that required a lot more code, and even then, I couldn't get it to work.
Posted
Updated 24-Jan-11 5:14am
v2

Rate this:
Please Sign up or sign in to vote.

Solution 1

You can use the methods PointToClient and PointToScreen to do this.

http://msdn.microsoft.com/en-us/library/ms229598.aspx[^]

Good luck!
   
v2
Comments
#realJSOP 24-Jan-11 11:08am
   
I tried that, and it didn't work as expected. The problem is that a form's location is ALWAYS in relation to the top/left corner of the screen, and there's apparently no way to get the actual screen coordinates of a control in a form. I'll go back and look again, though.
Sergey Alexandrovich Kryukov 24-Jan-11 11:28am
   
Apparently what you say here does not matter.
#realJSOP 24-Jan-11 11:14am
   
Harumph - maybe I didn't do it in the right place. That method now comes up with exactly what my code calculates. Answer accepted.
Nish Nishant 24-Jan-11 11:18am
   
See my answer too. With just using PointToScreen, it will stop working if you move the parent form around. So you also need to set the StartPosition to Manual.
#realJSOP 24-Jan-11 11:21am
   
Start position is already set to manual. I reset the position of the modeless form when I mouse over the control in question, so the position is always correct. (The form is hidden when the mouse leaves it.)
Nish Nishant 24-Jan-11 11:22am
   
Ok, interesting then that it did not initially work for you. Maybe you missed something then.
#realJSOP 24-Jan-11 11:24am
   
I think I may have been doing it wrong. I had forgotten that Form is derived from Control.
Rate this:
Please Sign up or sign in to vote.

Solution 2

I don't think there is such API, because it is completely redundant would mess-up useful methods and promote bad design. Yes, putting a windows in a specific location relative to any control is pretty bad design. If you have a justification or motivation for such thing, you should share it, otherwise, who would be interested to help?

You simple made a mistake in calculation. Why, for example, ClientY is calculated through ClientX? It should be done in the same way. It looks like you assume the non-client area size from left and from top of the client is the same, but this is not true. Also, you assume that the immediate parent of label1 is its form, but why? What if you want to add some parent panels with padding, etc.? (By the way, if it's a form, you use bad poorly supportable layout techniques.) Will it fix your position?

Overall, looks like a bad style + elementary calculation errors.
   
Comments
#realJSOP 24-Jan-11 11:18am
   
ClientX gives you the width of the Form's border, which you need to find the Y coordinate of the client rectangle. Doesn't matter though - see my reply to E.F. Like I said in my original question, the calculation was working as expected, and in my answer to E.F., I stated that the method he pointed out was giving me the same position, so there were no errors in my calculation at all.
Sergey Alexandrovich Kryukov 24-Jan-11 12:39pm
   
But border width is different: from top vs. from left, hence a mistake. I have correct calculations - does not matter, of course.
#realJSOP 24-Jan-11 13:00pm
   
If my calcs are getting the same answer that the method provides, how is it "wrong"? I subtracted the border width (which is *the same* for all four sides of the window) and client rectangle height from the overall size of the form. In this case, that calculation determined the desired Y position to be 561. When I used the framework method (the right way), it also came up with 561. You may have a *different* way to calculate it, but that doesn't make my way incorrect.
Sergey Alexandrovich Kryukov 25-Jan-11 14:26pm
   
I did not say you were wrong, I referred to original code by OP _at the time of posting_ and the problem. Sorry for confusion. I actually used to use both ways (also with PointToScreen/PointToClient) with identical results of course -- way to trivial to discuss anything else.
Rate this:
Please Sign up or sign in to vote.

Solution 3

John, something like will work:

private void button1_Click(object sender, EventArgs e)
{
  var dialog = new About();
  dialog.Location = this.PointToScreen(button1.Location);
  dialog.StartPosition = FormStartPosition.Manual;
  dialog.Show();
}


The important line of code there is setting StartPosition to Manual.
   
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100