Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A C# Sample Code/Article Extending the Capabilities of GDI+ in C# (.NET) - Part III

0.00/5 (No votes)
13 Jul 2008 1  
An article about a C# Sample Code/Article Extending the Capabilities of GDI+ in C# (.NET)
Figure 1

Introduction

Here, in continuation to my previous article, I present one more method to select portions of an Image. Like my method 2 in the previous article, one does not have to be bothered about resize/movement problems of the selection rectangle as those will be taken care of by the selection window which is a.k.a. Win32 window.

The approach taken here is that, I trap the WM_EXITSIZEMOVE message in the window procedure of the child form. Earlier in the main form, I override the OnLoad(…) method and create another form, let us call it child-like form (since it almost behaves like a child to the Main Form) and set its owner to my main form. See Figure 1.

protected override void OnLoad(EventArgs e)
{
      chFrm = new ChildForm();
      chFrm.Owner = this;
      chFrm.Show();
      chFrm.Location = new Point(Location.X + 50, Location.Y + 50);
      base.OnLoad(e);
}

Now the current parent of the child-like form is the Desktop-Window and thereby, it becomes transparent (transparency is exhibited in its client area), since it is now equivalent to a pop-up window. When a user tries to move the child-like form, I quickly do two things:

  1. Change its parent from Desktop-window to the Main form
  2. Remove its WS_EX_LAYERED attribute through SetWindowLong(…)win32 API

This ensures that the child-like from can never leave the Main form. And I just need to do the reverse when the user stops the above action.

Note: To get the handle of the Desktop-Window, I use the Win32 API as shown below through pInvoke.

[DllImport("user32.dll")]
static extern IntPtr GetDesktopWindow();

Since we know that if a form becomes a child, we cannot apply the SetLayeredWindowAttributes (…) API on it. So how does the child form still become transparent? Enter WM_EXITSIZEMOVE, of the child Form. The WM_EXITSIZEMOVE message is sent one time to a window, after it has exited the moving or sizing modal loop. So to do the reverse as said above, I quickly do two more things:

  1. Toggle the parent of the child form; from the Main form to the Desktop-Window
  2. Toggle its layered attributes, in that I add the WS_EX_LAYERED attribute back to the child form

The above two things help the child form regain its transparency thus enabling the user to see through its client area.

The Win32-API setting transparency is shown below namely:

[DllImport ("user32.dll")]
public static extern long SetLayeredWindowAttributes
    (IntPtr Handle, int Clr, byte transparency, int clrkey);

The 4th parameter int clrKey, is the key, When calling this API, I mention a particular color for the clrKey parameter and further, I paint the child-like form with the same color. This will create a hole in the form’s client region.

Note: Whenever the form changes its parent, it will also reposition itself in accordance with its current parent, changing its location based on its earlier relative position in the WM_NCLBUTTONDOWN and WM_EXITSIZEMOVE messages which prevent this unwanted change of location.

History

  • 11th July, 2008: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here