| 1 |
|
|---|
| 2 | using System;
|
|---|
| 3 | using System.Collections.Generic;
|
|---|
| 4 | using System.Linq;
|
|---|
| 5 | using System.Text;
|
|---|
| 6 | using System.Threading.Tasks;
|
|---|
| 7 | using System.Drawing;
|
|---|
| 8 | using System.Windows.Forms;
|
|---|
| 9 | using Microsoft.Win32;
|
|---|
| 10 |
|
|---|
| 11 | namespace Common
|
|---|
| 12 | {
|
|---|
| 13 | class ResizableControls
|
|---|
| 14 | {
|
|---|
| 15 | int dragSize = 16;
|
|---|
| 16 | Point mouseStartPos = Point.Empty;
|
|---|
| 17 | Control movedControl = null;
|
|---|
| 18 | Size movedControlSize;
|
|---|
| 19 | Size movedControlParentSize;
|
|---|
| 20 | Form form;
|
|---|
| 21 | Point lastMousePos;
|
|---|
| 22 | string RegSubKey = "ControlHeight";
|
|---|
| 23 | RegistryKey regKey;
|
|---|
| 24 | int richTextBoxMinHeight = 24;
|
|---|
| 25 | int listViewMinHeight = 48;
|
|---|
| 26 | int dataGridViewMinHeight = 24;
|
|---|
| 27 |
|
|---|
| 28 | public void InitForm(Form form)
|
|---|
| 29 | {
|
|---|
| 30 | this.form = form;
|
|---|
| 31 | InitControlsRecursive(form.Controls);
|
|---|
| 32 |
|
|---|
| 33 | LoadFromRegistry(form);
|
|---|
| 34 | }
|
|---|
| 35 |
|
|---|
| 36 | public void InitControlsRecursive(Control.ControlCollection coll)
|
|---|
| 37 | {
|
|---|
| 38 | foreach (Control c in coll)
|
|---|
| 39 | {
|
|---|
| 40 | if (c is ResizableListView) (c as ResizableListView).MouseDownEx += HandleMouseDownEx;
|
|---|
| 41 | else c.MouseDown += HandleMouseDown;
|
|---|
| 42 | if (c is ResizableListView) (c as ResizableListView).MouseUpEx += HandleMouseUpEx;
|
|---|
| 43 | else c.MouseUp += HandleMouseUp;
|
|---|
| 44 | if (c is ResizableListView) (c as ResizableListView).MouseMoveEx += HandleMouseMoveEx;
|
|---|
| 45 | else c.MouseMove += HandleMouseMove;
|
|---|
| 46 | c.MouseLeave += HandleMouseLeave;
|
|---|
| 47 | //c.MouseCaptureChanged += MouseCaptureChanged;
|
|---|
| 48 | InitControlsRecursive(c.Controls);
|
|---|
| 49 | }
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | public static Control FindControlAtPoint(Control container, Point pos)
|
|---|
| 53 | {
|
|---|
| 54 | Control child;
|
|---|
| 55 | foreach (Control c in container.Controls)
|
|---|
| 56 | {
|
|---|
| 57 | if (c.Visible && c.Bounds.Contains(pos))
|
|---|
| 58 | {
|
|---|
| 59 | child = FindControlAtPoint(c, new Point(pos.X - c.Left, pos.Y - c.Top));
|
|---|
| 60 | if (child == null) return c;
|
|---|
| 61 | else return child;
|
|---|
| 62 | }
|
|---|
| 63 | }
|
|---|
| 64 | return null;
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | public static Control FindControlAtCursor(Form form)
|
|---|
| 68 | {
|
|---|
| 69 | Point pos = Cursor.Position;
|
|---|
| 70 | if (form.Bounds.Contains(pos))
|
|---|
| 71 | return FindControlAtPoint(form, form.PointToClient(pos));
|
|---|
| 72 | return null;
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | private void MouseCaptureChanged(object sender, EventArgs e)
|
|---|
| 76 | {
|
|---|
| 77 | mouseStartPos = Point.Empty;
|
|---|
| 78 | movedControl = null;
|
|---|
| 79 | }
|
|---|
| 80 |
|
|---|
| 81 | private void HandleMouseDown(object sender, MouseEventArgs e)
|
|---|
| 82 | {
|
|---|
| 83 | HandleMouseDownEx(sender, new MouseEventArgsEx(e.Button, e.Clicks, e.X, e.Y, e.Delta));
|
|---|
| 84 | }
|
|---|
| 85 |
|
|---|
| 86 | private void HandleMouseDownEx(object sender, MouseEventArgsEx e)
|
|---|
| 87 | {
|
|---|
| 88 | Point pos = Cursor.Position;
|
|---|
| 89 | mouseStartPos = pos;
|
|---|
| 90 | lastMousePos = pos;
|
|---|
| 91 | movedControl = FindControlAtPoint(form, form.PointToClient(pos));
|
|---|
| 92 | if (movedControl != null)
|
|---|
| 93 | {
|
|---|
| 94 | Rectangle dragArea = new Rectangle(movedControl.PointToScreen(new Point(0,
|
|---|
| 95 | movedControl.Size.Height - dragSize)), new Size(movedControl.Size.Width, dragSize));
|
|---|
| 96 | if (dragArea.Contains(pos) &&
|
|---|
| 97 | ((movedControl is RichTextBox) || (movedControl is ListView) || (movedControl is DataGridView)))
|
|---|
| 98 | {
|
|---|
| 99 | movedControlSize = movedControl.Size;
|
|---|
| 100 | movedControlParentSize = movedControl.Parent.Parent.Size;
|
|---|
| 101 | e.Handled = true;
|
|---|
| 102 | }
|
|---|
| 103 | else movedControl = null;
|
|---|
| 104 | }
|
|---|
| 105 | }
|
|---|
| 106 |
|
|---|
| 107 | private void HandleMouseLeave(object sender, EventArgs e)
|
|---|
| 108 | {
|
|---|
| 109 | mouseStartPos = Point.Empty;
|
|---|
| 110 | movedControl = null;
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | private void HandleMouseUp(object sender, MouseEventArgs e)
|
|---|
| 114 | {
|
|---|
| 115 | HandleMouseUpEx(sender, new MouseEventArgsEx(e.Button, e.Clicks, e.X, e.Y, e.Delta));
|
|---|
| 116 | }
|
|---|
| 117 |
|
|---|
| 118 | private void HandleMouseUpEx(object sender, MouseEventArgsEx e)
|
|---|
| 119 | {
|
|---|
| 120 | mouseStartPos = Point.Empty;
|
|---|
| 121 | movedControl = null;
|
|---|
| 122 | }
|
|---|
| 123 |
|
|---|
| 124 | private void HandleMouseMove(object sender, MouseEventArgs e)
|
|---|
| 125 | {
|
|---|
| 126 | HandleMouseMoveEx(sender, new MouseEventArgsEx(e.Button, e.Clicks, e.X, e.Y, e.Delta));
|
|---|
| 127 | }
|
|---|
| 128 |
|
|---|
| 129 | private void HandleMouseMoveEx(object sender, MouseEventArgsEx e)
|
|---|
| 130 | {
|
|---|
| 131 | Point pos = Cursor.Position;
|
|---|
| 132 |
|
|---|
| 133 | // Show pan cursor for bottom right corner
|
|---|
| 134 | Control movableControl = FindControlAtPoint(form, form.PointToClient(pos));
|
|---|
| 135 | if (movableControl != null)
|
|---|
| 136 | {
|
|---|
| 137 | Rectangle dragArea = new Rectangle(movableControl.PointToScreen(new Point(0,
|
|---|
| 138 | movableControl.Size.Height - dragSize)), new Size(movableControl.Size.Width, dragSize));
|
|---|
| 139 | if (dragArea.Contains(pos) &&
|
|---|
| 140 | ((movableControl is RichTextBox) || (movableControl is ListView) || (movableControl is DataGridView)))
|
|---|
| 141 | {
|
|---|
| 142 | if (Cursor.Current != Cursors.SizeNS) Cursor.Current = Cursors.SizeNS;
|
|---|
| 143 | }
|
|---|
| 144 | else if (Cursor.Current == Cursors.SizeNS) Cursor.Current = Cursors.Default;
|
|---|
| 145 | }
|
|---|
| 146 |
|
|---|
| 147 | if ((mouseStartPos != Point.Empty) && (movedControl != null) && (lastMousePos != pos))
|
|---|
| 148 | {
|
|---|
| 149 | Point posDiff = Point.Subtract(pos, (Size)lastMousePos);
|
|---|
| 150 | posDiff.X = 0; // Allow only resize of height
|
|---|
| 151 | //movedControl.Size = (Size)Point.Add(posDiff, movedControl.Size);
|
|---|
| 152 | Cursor.Current = Cursors.Arrow;
|
|---|
| 153 |
|
|---|
| 154 | Size newControlSize = (Size)Point.Add(posDiff, movedControl.Size);
|
|---|
| 155 | if ((movedControl is RichTextBox) && (newControlSize.Height < richTextBoxMinHeight)) posDiff.Y = movedControl.Height - richTextBoxMinHeight;
|
|---|
| 156 | else if ((movedControl is ListView) && (newControlSize.Height < listViewMinHeight)) posDiff.Y = movedControl.Height - listViewMinHeight;
|
|---|
| 157 | else if ((movedControl is DataGridView) && (newControlSize.Height < dataGridViewMinHeight)) posDiff.Y = movedControl.Height - dataGridViewMinHeight;
|
|---|
| 158 | ResizeParent(movedControl, posDiff);
|
|---|
| 159 | lastMousePos = pos;
|
|---|
| 160 | regKey.SetValue(movedControl.Name, movedControl.Height);
|
|---|
| 161 | }
|
|---|
| 162 | }
|
|---|
| 163 |
|
|---|
| 164 | private void ResizeParent(Control control, Point diff)
|
|---|
| 165 | {
|
|---|
| 166 | if ((control.Parent != null) && !diff.IsEmpty)
|
|---|
| 167 | {
|
|---|
| 168 | if ((control.Parent is Panel) && (control.Parent as Panel).AutoScroll) return;
|
|---|
| 169 | if (control.Parent is Panel)
|
|---|
| 170 | control.Parent.Size = (Size)Point.Add(diff, control.Parent.Size);
|
|---|
| 171 | ResizeParent(control.Parent, diff);
|
|---|
| 172 | }
|
|---|
| 173 | }
|
|---|
| 174 |
|
|---|
| 175 | private void LoadFromRegistry(Form form)
|
|---|
| 176 | {
|
|---|
| 177 | regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + form.Name, true);
|
|---|
| 178 | if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + form.Name);
|
|---|
| 179 | LoadControlFromRegistry(form, regKey);
|
|---|
| 180 | }
|
|---|
| 181 |
|
|---|
| 182 | private void LoadControlFromRegistry(Control control, RegistryKey regKey)
|
|---|
| 183 | {
|
|---|
| 184 | if ((control is RichTextBox) || (control is ListView) || (control is DataGridView))
|
|---|
| 185 | {
|
|---|
| 186 | int newHeight = (int)regKey.GetValue(control.Name, control.Height);
|
|---|
| 187 | if ((control is RichTextBox) && (newHeight < richTextBoxMinHeight)) newHeight = richTextBoxMinHeight;
|
|---|
| 188 | else if ((control is ListView) && (newHeight < listViewMinHeight)) newHeight = listViewMinHeight;
|
|---|
| 189 | else if ((control is DataGridView) && (newHeight < dataGridViewMinHeight)) newHeight = dataGridViewMinHeight;
|
|---|
| 190 | ResizeParent(control, Point.Subtract(new Point(control.Width, newHeight), control.Size));
|
|---|
| 191 | }
|
|---|
| 192 | foreach (Control child in control.Controls)
|
|---|
| 193 | {
|
|---|
| 194 | LoadControlFromRegistry(child, regKey);
|
|---|
| 195 | }
|
|---|
| 196 | }
|
|---|
| 197 | }
|
|---|
| 198 |
|
|---|
| 199 | public class MouseEventArgsEx : MouseEventArgs
|
|---|
| 200 | {
|
|---|
| 201 | bool handled;
|
|---|
| 202 |
|
|---|
| 203 | public MouseEventArgsEx(MouseButtons button, int clicks, int x, int y, int delta): base(button, clicks, x, y, delta)
|
|---|
| 204 | {
|
|---|
| 205 | handled = false;
|
|---|
| 206 | }
|
|---|
| 207 |
|
|---|
| 208 | public bool Handled { get { return handled; } set { handled = value; } }
|
|---|
| 209 | }
|
|---|
| 210 |
|
|---|
| 211 |
|
|---|
| 212 | public class ResizableListView : ListView
|
|---|
| 213 | {
|
|---|
| 214 | public event EventHandler<MouseEventArgsEx> MouseDownEx;
|
|---|
| 215 | public event EventHandler<MouseEventArgsEx> MouseUpEx;
|
|---|
| 216 | public event EventHandler<MouseEventArgsEx> MouseMoveEx;
|
|---|
| 217 |
|
|---|
| 218 | protected override void WndProc(ref Message m)
|
|---|
| 219 | {
|
|---|
| 220 | Boolean handled = false;
|
|---|
| 221 | m.Result = IntPtr.Zero;
|
|---|
| 222 |
|
|---|
| 223 | const int WM_MOUSEMOVE = 0x0200;
|
|---|
| 224 | const int WM_LBUTTONDOWN = 0x0201;
|
|---|
| 225 | const int WM_LBUTTONUP = 0x0202;
|
|---|
| 226 | if (m.Msg == WM_LBUTTONDOWN)
|
|---|
| 227 | {
|
|---|
| 228 | IntPtr xy = m.LParam;
|
|---|
| 229 | int x = unchecked((short)(long)xy);
|
|---|
| 230 | int y = unchecked((short)((long)xy >> 16));
|
|---|
| 231 | MouseEventArgsEx eventArgs = new MouseEventArgsEx(MouseButtons.Left, 1, x, y, 0);
|
|---|
| 232 | MouseDownEx(this, eventArgs);
|
|---|
| 233 | handled = eventArgs.Handled;
|
|---|
| 234 | } else
|
|---|
| 235 | if (m.Msg == WM_LBUTTONUP)
|
|---|
| 236 | {
|
|---|
| 237 | IntPtr xy = m.LParam;
|
|---|
| 238 | int x = unchecked((short)(long)xy);
|
|---|
| 239 | int y = unchecked((short)((long)xy >> 16));
|
|---|
| 240 | MouseEventArgsEx eventArgs = new MouseEventArgsEx(MouseButtons.Left, 1, x, y, 0);
|
|---|
| 241 | MouseUpEx(this, eventArgs);
|
|---|
| 242 | handled = eventArgs.Handled;
|
|---|
| 243 | }
|
|---|
| 244 | else
|
|---|
| 245 | if (m.Msg == WM_MOUSEMOVE)
|
|---|
| 246 | {
|
|---|
| 247 | IntPtr xy = m.LParam;
|
|---|
| 248 | int x = unchecked((short)(long)xy);
|
|---|
| 249 | int y = unchecked((short)((long)xy >> 16));
|
|---|
| 250 | MouseEventArgsEx eventArgs = new MouseEventArgsEx(MouseButtons.Left, 1, x, y, 0);
|
|---|
| 251 | MouseMoveEx(this, eventArgs);
|
|---|
| 252 | handled = eventArgs.Handled;
|
|---|
| 253 | }
|
|---|
| 254 | if (!handled) base.WndProc(ref m);
|
|---|
| 255 | // else DefWndProc(ref m);
|
|---|
| 256 | }
|
|---|
| 257 | }
|
|---|
| 258 | }
|
|---|