Here, in continuation to my previous article, I present two more methods to do the same.
Method 1 Project Name: ReversePaint
As suggested by a reader, we do have an equivalent to
DrawDragRect(…) that is the
public static void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) but the features like resizing the selection rectangle like how one resizes a normal window and Drag-Drop do require similar code as in my earlier sample code. As a POC, I present the sample code in the
ReversePaint download. Please see the function
public void DrawDragRect() for the only major difference. The
CDrawDragRect can derive from both
Form depending upon the coder’s choice.
Method 2 Project Name: WindowPosChanging
Here I take a totally new approach. As one can see, resizing and Dragging and Dropping the selection rectangle needs to behave like a normal window, then why not use a normal window to do the same? So Windows will handle resize and other features automatically. For this, the Window (which is actually going to be a form, let us call it the
childLike form; see Figure below) will have to have a kind of hole in it so that the user can see through it for selecting a part of an image.
There is a Win32-API specifically for it, namely:
public static extern long SetLayeredWindowAttributes
(IntPtr Handle, int Clr, byte transparency, int clrkey);
The fourth parameter
int clrKey, is the key, When calling this API, I mention a particular color for the
clrKey parameter and further I paint the
childLike form with the same color. This will create a hole in the form’s client region.
But there is one down side to it - it will not create a hole in child windows (forms), this API will work only in a Pop-Up Window.
childLike form will have to be a Pop-up Form, and not an MDI Child or Child window. If it is a Pop-up, it will move out of our main Window which host’s the Image. So the form movement needs to be restricted to the Main form. This is achieved by trapping the
WM_WINDOWPOSCHANGING message in the form’s
WndProc(ref Message m) function.
When handing this message, I just ensure that
WINDOWPOS winPos (which I get through the
m.Lparam) does not leave the Main form.
The handling of the message works two fold:
childLike form cannot be dragged outside the
- When the main form is moved I just need to fire a
WM_MOVE message for the
childLike form and this ensures that the
childLike form does not go outside the main form. Just take a look at the following code:
protected override void OnMove(EventArgs e)
if (chFrm != null)
MoveWindow(chFrm.Handle, chFrm.Location.X, chFrm.Location.Y,
chFrm.Size.Width, chFrm.Size.Height, true);
MinimumSize = new Size(chFrm.Size.Width + 100, chFrm.Size.Height);
Please note that the
MoveWindow(...) call made inside the
OnMove(...) function is a dummy.
This is kind of a free gift, just move the Main form all over your desktop and see how the
childLike form follows it dutifully.
That's all for the resize feature, now for the Drag And Drop feature.
Since the form has a hole in it, a user can drag-drop the
childLike form as shown in the image below:
This is achieved by overriding the Mouse-move function and inside it, I call the
BestSelfMoveOnMoveNotRequired () function. This function performs the movement of the
- 10th June, 2008: Initial version
- 2nd July, 2008: Article updated