public override void MoveControl(Rectangle valueRect, PropertyEnumerator propEnum) { if (mInPlaceCtrl == null) { return; } if (mInPlaceCtrl is PropInPlaceDateTime) { valueRect.Height--; Win32Calls.RECT rect = new Win32Calls.RECT(); Win32Calls.GetWindowRect(mInPlaceCtrl.Handle, ref rect); Rectangle bounds = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); bounds = mInPlaceCtrl.Parent.RectangleToClient(bounds); if (bounds != valueRect) { mInPlaceCtrl.Invalidate(); // Bounds doesn't work because of DateTimePicker.PreferredHeight Win32Calls.SetWindowPos(mInPlaceCtrl.Handle, IntPtr.Zero, valueRect.Left, valueRect.Top, valueRect.Width, valueRect.Height, Win32Calls.SWP_NOZORDER | Win32Calls.SWP_NOACTIVATE | Win32Calls.SWP_NOREDRAW); // Causes WM_NCPAINT Win32Calls.RedrawWindow(mInPlaceCtrl.Handle, IntPtr.Zero, IntPtr.Zero, 0x0561); } } else { // Find where the string is actually displayed (a look instance could place it anywhere) Graphics graphics = mParentWnd.CreateGraphics(); Rectangle strRect = propEnum.Property.Value.GetStringValueRect(graphics, valueRect, Point.Empty /* not used */); strRect.X -= (propEnum.Property.Value.EditboxLeftMargin == -1 ? propEnum.Property.ParentGrid.GlobalTextMargin : propEnum.Property.Value.EditboxLeftMargin); strRect.Width = valueRect.Right - strRect.Left; // Calculate the height of the editbox, based on the font height Rectangle editRect = strRect; editRect.Inflate(0, -1); Win32Calls.TEXTMETRIC tm = new Win32Calls.TEXTMETRIC(); Win32Calls.GetTextMetrics(graphics, mInPlaceCtrl.Font, ref tm); graphics.Dispose(); int extraHeight = editRect.Height - tm.tmHeight; editRect.Y += extraHeight / 2; editRect.Height -= extraHeight; if (mInPlaceCtrl.Bounds != editRect) { mInPlaceCtrl.Bounds = editRect; } } }
public override void MoveControl(Rectangle valueRect, PropertyEnumerator propEnum) { if (mInPlaceCtrl == null) return; if (mInPlaceCtrl is PropInPlaceDateTime) { valueRect.Height--; Win32Calls.RECT rect = new Win32Calls.RECT(); Win32Calls.GetWindowRect(mInPlaceCtrl.Handle, ref rect); Rectangle bounds = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); bounds = mInPlaceCtrl.Parent.RectangleToClient(bounds); if (bounds != valueRect) { mInPlaceCtrl.Invalidate(); // Bounds doesn't work because of DateTimePicker.PreferredHeight Win32Calls.SetWindowPos(mInPlaceCtrl.Handle, IntPtr.Zero, valueRect.Left, valueRect.Top, valueRect.Width, valueRect.Height, Win32Calls.SWP_NOZORDER | Win32Calls.SWP_NOACTIVATE | Win32Calls.SWP_NOREDRAW); // Causes WM_NCPAINT Win32Calls.RedrawWindow(mInPlaceCtrl.Handle, IntPtr.Zero, IntPtr.Zero, 0x0561); } } else { // Find where the string is actually displayed (a look instance could place it anywhere) Graphics graphics = mParentWnd.CreateGraphics(); Rectangle strRect = propEnum.Property.Value.GetStringValueRect(graphics, valueRect, Point.Empty /* not used */); strRect.X -= (propEnum.Property.Value.EditboxLeftMargin == -1 ? propEnum.Property.ParentGrid.GlobalTextMargin : propEnum.Property.Value.EditboxLeftMargin); strRect.Width = valueRect.Right - strRect.Left; // Calculate the height of the editbox, based on the font height Rectangle editRect = strRect; editRect.Inflate(0, -1); Win32Calls.TEXTMETRIC tm = new Win32Calls.TEXTMETRIC(); Win32Calls.GetTextMetrics(graphics, mInPlaceCtrl.Font, ref tm); graphics.Dispose(); int extraHeight = editRect.Height - tm.tmHeight; editRect.Y += extraHeight / 2; editRect.Height -= extraHeight; if (mInPlaceCtrl.Bounds != editRect) mInPlaceCtrl.Bounds = editRect; } }
protected override void WndProc(ref Message m) { if (m.Msg == Win32Calls.WM_NCCALCSIZE) { Win32Calls.NCCALCSIZE_PARAMS csp; csp = (Win32Calls.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32Calls.NCCALCSIZE_PARAMS)); Rectangle rect = new Rectangle(csp.rgrc0.Left, csp.rgrc0.Top, csp.rgrc0.Right - csp.rgrc0.Left, csp.rgrc0.Bottom - csp.rgrc0.Top); rect.Inflate(-2, -2); csp.rgrc0.Left = rect.X; csp.rgrc0.Right = rect.X + rect.Width; csp.rgrc0.Top = rect.Y; csp.rgrc0.Bottom = rect.Y + rect.Height; Marshal.StructureToPtr(csp, m.LParam, false); } else if (m.Msg == Win32Calls.WM_NCPAINT) { IntPtr hDC = Win32Calls.GetWindowDC(m.HWnd); Graphics graphics = Graphics.FromHdc(hDC); Win32Calls.RECT rc = new Win32Calls.RECT(); Win32Calls.GetWindowRect(m.HWnd, ref rc); Rectangle rect = new Rectangle(0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top); if (Focused) { ControlPaint.DrawFocusRectangle(graphics, rect); } else { Rectangle bkRect = rect; bkRect.Width--; bkRect.Height--; Pen pen = new Pen(Parent.BackColor); graphics.DrawRectangle(pen, bkRect); pen.Dispose(); } rect.Inflate(-1, -1); rect.Width--; rect.Height--; graphics.DrawLine(SystemPens.ControlDarkDark, new Point(rect.Left, rect.Bottom), rect.Location); graphics.DrawLine(SystemPens.ControlDarkDark, rect.Location, new Point(rect.Right, rect.Top)); graphics.DrawLine(SystemPens.ControlLightLight, new Point(rect.Left, rect.Bottom), new Point(rect.Right, rect.Bottom)); graphics.DrawLine(SystemPens.ControlLightLight, new Point(rect.Right, rect.Bottom), new Point(rect.Right, rect.Top)); Win32Calls.ReleaseDC(m.HWnd, hDC); } base.WndProc(ref m); }
protected override void WndProc(ref Message m) { if (m.Msg == Win32Calls.WM_SETFOCUS) { // The window that lose the focus is stored for future reference // in OnGotFocus. if the handle is in another application, the stored // value will be null. _wmFocusMissingArg = FromHandle(m.WParam); } else if (m.Msg == Win32Calls.WM_KILLFOCUS) { // The window that gained the focus is stored for future reference // in OnLostFocus. if the handle is in another application, the stored // value will be null. _wmFocusMissingArg = FromHandle(m.WParam); } else if (m.Msg == Win32Calls.WM_ERASEBKGND) { if (Multiline) { // If I don't intercept this message, the control flickers when it is multiline // Some code must also be added in WM_PAINT return; } } else if (m.Msg == Win32Calls.WM_PAINT) { if (Multiline) { Graphics g = CreateGraphics(); Win32Calls.RECT rect = new Win32Calls.RECT(); Win32Calls.GetUpdateRect(Handle, out rect, false); g.FillRectangle(new SolidBrush(BackColor), Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom)); g.Dispose(); } } else if (m.Msg == Win32Calls.WM_MOUSEACTIVATE) { if (Focused == false) { if (Form.ActiveForm is PropInPlaceUITypeEditor.DropDownForm) { Focus(); } } } base.WndProc(ref m); }
public void SetMargins(int left, int top, int right, int bottom) { Win32Calls.RECT rect = new Win32Calls.RECT(left, top, right, bottom); Win32Calls.SendMessage(Handle, Win32Calls.TTM_SETMARGIN, 0, ref rect); }
protected override void WndProc(ref Message m) { if (m.Msg == Win32Calls.WM_MOUSEACTIVATE) { if (Focused == false) { Rectangle itemRect; Point pt = PointToClient(MousePosition); if (ClientRectangle.Contains(pt)) { PropertyEnumerator propEnum = PropertyItemFromPoint(pt, out itemRect); if (SelectedPropertyEnumerator != propEnum) { _dontShowInPlaceCtrlInGotFocus = true; // When we are in the dropdown part of a UITypeEditor, we want to forward the click // to the control (internalgrid or another inplace control). If Focus() is not called, // it behaves like the MSPG if (Form.ActiveForm is PropInPlaceUITypeEditor.DropDownForm) Focus(); } } } } else if (m.Msg == Win32Calls.WM_LBUTTONDOWN) { // If we don't do all this stuff here, a shift + double-click is not correctly detected // (this is used when double-clicking a property label to cycle values) _doubleClickDone = false; long now = DateTime.Now.Ticks; int x = Win32Calls.LoWord((int)m.LParam); int y = Win32Calls.HiWord((int)m.LParam); if ((_lastTimeClicked != 0) && ((int)((now - _lastTimeClicked) / 0x2710) < SystemInformation.DoubleClickTime)) { if ((Math.Abs(x - _lastPosClicked.X) < SystemInformation.DoubleClickSize.Width) && (Math.Abs(y - _lastPosClicked.Y) < SystemInformation.DoubleClickSize.Height)) _doubleClickDone = true; _lastTimeClicked = 0; _lastPosClicked = Point.Empty; } if (_doubleClickDone == false) { _lastTimeClicked = now; _lastPosClicked = new Point(x, y); } } else if (m.Msg == Win32Calls.WM_LBUTTONDBLCLK) { _lastTimeClicked = 0; } else if (m.Msg == Win32Calls.WM_NCCALCSIZE) { // if (m.WParam != IntPtr.Zero) { Win32Calls.NCCALCSIZE_PARAMS csp; csp = (Win32Calls.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32Calls.NCCALCSIZE_PARAMS)); Rectangle rect = new Rectangle(csp.rgrc0.Left, csp.rgrc0.Top, csp.rgrc0.Right - csp.rgrc0.Left, csp.rgrc0.Bottom - csp.rgrc0.Top); DrawManager.NcCalcSize(ref rect); csp.rgrc0.Left = rect.X; csp.rgrc0.Right = rect.X + rect.Width; csp.rgrc0.Top = rect.Y; csp.rgrc0.Bottom = rect.Y + rect.Height; Marshal.StructureToPtr(csp, m.LParam, false); } } else if (m.Msg == Win32Calls.WM_NOTIFY) { if (m.LParam != IntPtr.Zero) { Win32Calls.NMHDR nmhdr = (Win32Calls.NMHDR)m.GetLParam(typeof(Win32Calls.NMHDR)); if (nmhdr.code == Win32Calls.TTN_SHOW) { if ((ToolTip != null) && (nmhdr.hwndFrom == ToolTip.Handle)) { ToolTip.Location = _toolTipLocation; m.Result = (IntPtr)1; return; } } } } else if (m.Msg == Win32Calls.WM_NCPAINT) { IntPtr hDC = Win32Calls.GetWindowDC(m.HWnd); Graphics graphics = Graphics.FromHdc(hDC); Win32Calls.RECT rc = new Win32Calls.RECT(); Win32Calls.GetWindowRect(m.HWnd, ref rc); Rectangle rect = new Rectangle(0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top); DrawManager.DrawGridNonClientArea(graphics, rect); Win32Calls.ReleaseDC(m.HWnd, hDC); } else if (m.Msg == Win32Calls.WM_VSCROLL) { int nSBCode = Win32Calls.LoWord((int)m.WParam); if (nSBCode == Win32Calls.SB_ENDSCROLL) { _scrollingInProgress = false; if ((_parentCtrl.NavigationKeyMode == PropertyGrid.NavigationKeyModes.TabKey) && ((_parentCtrl.TabKeyNavigationMode & PropertyGrid.TabKeyNavigationModes.TabKeyWithAutoFocus) != 0)) { ShowInPlaceControl(SelectedPropertyEnumerator); } return; } _scrollingInProgress = true; Rectangle clientRect = ClientRectangle; int itemsPerPage = clientRect.Height / _basicPropertyHeight; // Get some info about the old state of the scroll Win32Calls.SCROLLINFO si = new Win32Calls.SCROLLINFO(); si.cbSize = Marshal.SizeOf(si); si.fMask = Win32Calls.SIF_PAGE | Win32Calls.SIF_RANGE; Win32Calls.GetScrollInfo(Handle, Win32Calls.SB_VERT, ref si); switch (nSBCode) { case Win32Calls.SB_LINEDOWN: { if ((si.nPage > 0) && (Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) < si.nMax - (si.nPage - 1))) { if (_firstDisplayedLine == FirstDisplayedProperty.Property.HeightMultiplier) { _firstDisplayedPropertyEnumerator.MoveNext(); _firstDisplayedLine = 1; } else _firstDisplayedLine++; Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) + 1, true); Invalidate(); } break; } case Win32Calls.SB_LINEUP: { if (Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) > 0) { if (_firstDisplayedLine > 1) _firstDisplayedLine--; else { _firstDisplayedPropertyEnumerator.MovePrev(); _firstDisplayedLine = FirstDisplayedProperty.Property.HeightMultiplier; } Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) - 1, true); Invalidate(); } break; } case Win32Calls.SB_PAGEDOWN: { int counter = 0; PropertyVisibleDeepEnumerator enumerator = FirstDisplayedProperty.GetVisibleDeepEnumerator(); while (enumerator != enumerator.RightBound) { Rectangle itemRect = GetAbsoluteItemRect(enumerator); if (itemRect.Bottom > clientRect.Bottom) { // We have found the last displayed property pointed by iter PropertyVisibleDeepEnumerator currentLastDisplayedPropertyEnum = enumerator.GetVisibleDeepEnumerator(); int lastItemDisplayLine = (clientRect.Bottom - itemRect.Top) / _basicPropertyHeight + 1; // We loop to make it scroll up without creating blank space at the bottom do { // Scroll one line at the top if (_firstDisplayedLine == FirstDisplayedProperty.Property.HeightMultiplier) { _firstDisplayedPropertyEnumerator.MoveNext(); _firstDisplayedLine = 1; } else _firstDisplayedLine++; // Determine the new bottom item if (lastItemDisplayLine == currentLastDisplayedPropertyEnum.Property.HeightMultiplier) { currentLastDisplayedPropertyEnum.MoveNext(); lastItemDisplayLine = 1; } else lastItemDisplayLine++; counter++; } while ((counter < itemsPerPage - 1) && (currentLastDisplayedPropertyEnum != currentLastDisplayedPropertyEnum.RightBound)); break; } enumerator.MoveNext(); } Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) + counter, true); Invalidate(); break; } case Win32Calls.SB_PAGEUP: { int newPos = Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) - itemsPerPage + 1; // Provide a limit for the maximum position if (newPos < 0) newPos = 0; // Scroll the first displayed element for (int i = 0; i < Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT) - newPos; i++) { if (_firstDisplayedLine > 1) _firstDisplayedLine--; else { _firstDisplayedPropertyEnumerator.MovePrev(); _firstDisplayedLine = FirstDisplayedProperty.Property.HeightMultiplier; } } Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, newPos, true); Invalidate(); break; } case Win32Calls.SB_THUMBTRACK: case Win32Calls.SB_THUMBPOSITION: { if (FirstDisplayedProperty != RightBound.GetVisibleDeepEnumerator()) { int nPos = Win32Calls.HiWord((int)m.WParam); int currentPos = Win32Calls.GetScrollPos(Handle, Win32Calls.SB_VERT); // Scroll the first displayed element int i = 0; for (; i < Math.Abs((nPos - currentPos)); i++) { if (nPos > currentPos) { if (FirstDisplayedProperty.Property.HeightMultiplier == _firstDisplayedLine) { _firstDisplayedPropertyEnumerator.MoveNext(); _firstDisplayedLine = 1; } else _firstDisplayedLine++; if (_firstDisplayedPropertyEnumerator == RightBound.GetVisibleDeepEnumerator()) break; } else { if (_firstDisplayedLine > 1) _firstDisplayedLine--; else { _firstDisplayedPropertyEnumerator.MovePrev(); _firstDisplayedLine = FirstDisplayedProperty.Property.HeightMultiplier; } } } if (nPos < currentPos) Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, currentPos - i, true); else Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, currentPos + i, true); Invalidate(); } break; } } if (Focused == false) Focus(); CheckScrollbar(); } base.WndProc(ref m); }
protected override void OnKeyUp(KeyEventArgs e) { // If the Control key is released the cursor is restored to default in case we were on a hyperlinked property // a hyperlink property. if (e.KeyCode == Keys.ControlKey) { if (_currentInPlaceControl != null) { Win32Calls.RECT rect = new Win32Calls.RECT(); Win32Calls.GetWindowRect(_currentInPlaceControl.Handle, ref rect); Rectangle bounds = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); if (bounds.Contains(MousePosition)) { base.OnKeyUp(e); return; } } Rectangle itemRect; Point pt = PointToClient(MousePosition); PropertyEnumerator propEnum = PropertyItemFromPoint(pt, out itemRect); if (!(propEnum.Property is PropertyHyperLink)) Cursor = Cursors.Arrow; } base.OnKeyUp(e); }
protected override void OnKeyDown(KeyEventArgs e) { // If only Control is clicked we simulate a mouse move so that the cursor could be updated on // a hyperlink property. if (e.KeyCode == Keys.ControlKey) { if (_currentInPlaceControl != null) { Win32Calls.RECT rect = new Win32Calls.RECT(); Win32Calls.GetWindowRect(_currentInPlaceControl.Handle, ref rect); Rectangle bounds = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); if (bounds.Contains(MousePosition)) { base.OnKeyDown(e); return; } } Rectangle itemRect; Point pt = PointToClient(MousePosition); PropertyEnumerator propEnum = PropertyItemFromPoint(pt, out itemRect); if (propEnum.Property != null) propEnum.Property.OverrideCursor(pt, itemRect, propEnum); base.OnKeyDown(e); return; } Property selectedProperty = _selectedPropertyEnum.Property; if (selectedProperty != null) { // Hide the tooltip if it is visible // if (ToolTip != null) // ToolTip.SetText("", null); if (_currentInPlaceControl != null) { IInPlaceControl c = (_currentInPlaceControl as IInPlaceControl); if ((c != null) && c.OnParentKeyDown(e)) return; } switch (e.KeyCode) { case Keys.F4: { if ((_currentInPlaceControl != null) && (e.Modifiers == 0)) { IInPlaceControl c = (_currentInPlaceControl as IInPlaceControl); if (c != null) { c.OnF4(); } } break; } case Keys.Space: case Keys.Return: { if ((SelectedPropertyEnumerator.Property.CanBeDisabledManually) && (e.KeyCode == Keys.Space)) { if (SelectedPropertyEnumerator.HasParent == false) { EnableProperty(SelectedPropertyEnumerator, !SelectedPropertyEnumerator.Property.Enabled); #if _DOTNET2 e.SuppressKeyPress = true; #else HandleRef handle = new HandleRef(this, this.Handle); Win32Calls.RemovePendingMessages(handle, 0x102, 0x102); Win32Calls.RemovePendingMessages(handle, 0x106, 0x106); Win32Calls.RemovePendingMessages(handle, 0x286, 0x286); e.Handled = true; #endif } else { // The user can press on the checkbox only if its parent category is enabled if (SelectedPropertyEnumerator.Parent.Property.Enabled) { EnableProperty(SelectedPropertyEnumerator, !SelectedPropertyEnumerator.Property.Enabled); #if _DOTNET2 e.SuppressKeyPress = true; #else HandleRef handle = new HandleRef(this, this.Handle); Win32Calls.RemovePendingMessages(handle, 0x102, 0x102); Win32Calls.RemovePendingMessages(handle, 0x106, 0x106); Win32Calls.RemovePendingMessages(handle, 0x286, 0x286); e.Handled = true; #endif } } } // TODO : the following code should not be in this class. else if (SelectedPropertyEnumerator.Property is PropertyHyperLink) { if (SelectedPropertyEnumerator.Property.Enabled) { PropertyHyperLinkClickedEventArgs ev = new PropertyHyperLinkClickedEventArgs(SelectedPropertyEnumerator, SelectedPropertyEnumerator.Property.HyperLink); _parentCtrl.OnHyperLinkPropertyClicked(ev); } } else if (HasOneVisibleChild(SelectedPropertyEnumerator)) { Property property = SelectedPropertyEnumerator.Property; ExpandProperty(SelectedPropertyEnumerator, !property.Expanded); } break; } case Keys.Right: // Opens the item if it is a closed category case Keys.Add: { if ((e.KeyCode == Keys.Right) && (ModifierKeys == Keys.Control)) { SetLabelColumnWidthRatio((double)(LabelColumnWidth + 3) / (ClientRectangle.Width - LeftColumnWidth)); break; } if (SelectedPropertyEnumerator.Children.Count > 0) { Property property = SelectedPropertyEnumerator.Property; if (!property.Expanded && HasOneVisibleChild(SelectedPropertyEnumerator)) { ExpandProperty(SelectedPropertyEnumerator, true); break; } } if (e.KeyCode == Keys.Add) break; goto case Keys.Down; } case Keys.Down: // Moves the selected item down { if (e.Modifiers == Keys.Alt) { if (_currentInPlaceControl != null) { IInPlaceControl c = (_currentInPlaceControl as IInPlaceControl); if ((c != null) && !SelectedPropertyEnumerator.Property.Value.IsReadOnly(SelectedPropertyEnumerator)) { c.OnF4(); break; } } } PropertyVisibleDeepEnumerator nextEnum = new PropertyVisibleDeepEnumerator(_selectedPropertyEnum.Node); nextEnum.MoveNext(); Property nextProperty = nextEnum.Property; if (nextProperty != null) { Rectangle clientRect = ClientRectangle; Rectangle itemRect = GetAbsoluteItemRect(nextEnum); if (itemRect.Top < clientRect.Top) // Test if the item is above the top of the grid { while (true) { Win32Calls.SendMessage(Handle, Win32Calls.WM_VSCROLL, Win32Calls.MakeLong(Win32Calls.SB_LINEUP, 0), 0); itemRect = GetAbsoluteItemRect(nextEnum); if (itemRect.Top == clientRect.Top) break; } Win32Calls.SendMessage(Handle, Win32Calls.WM_VSCROLL, Win32Calls.MakeLong(Win32Calls.SB_ENDSCROLL, 0), 0); } else if (itemRect.Bottom > clientRect.Bottom) // Test if the item is below the bottom of the grid { // We scroll in a loop because the item may have a row height greater than the base row height // if the current selected item is the last one displayed // (TODO: we could be more performant by avoiding scrolls and directly calculating which property // needs to be the first displayed) _parentCtrl.BeginUpdate(); // To avoid the remancence of the inplace control do { Win32Calls.SendMessage(Handle, Win32Calls.WM_VSCROLL, Win32Calls.MakeLong(Win32Calls.SB_LINEDOWN, 0), 0); itemRect = GetAbsoluteItemRect(nextEnum); } while ((itemRect.Bottom > clientRect.Bottom) && (itemRect.Top > clientRect.Top)); Win32Calls.SendMessage(Handle, Win32Calls.WM_VSCROLL, Win32Calls.MakeLong(Win32Calls.SB_ENDSCROLL, 0), 0); _parentCtrl.EndUpdate(); } SelectProperty(nextEnum); } break; } case Keys.Left: // Closes the item if it is an expanded category case Keys.Subtract: { if ((e.KeyCode == Keys.Left) && (ModifierKeys == Keys.Control)) { SetLabelColumnWidthRatio((double)(LabelColumnWidth - 3) / (ClientRectangle.Width - LeftColumnWidth)); break; } if (SelectedPropertyEnumerator.Children.Count > 0) { Property property = SelectedPropertyEnumerator.Property; if (property.Expanded && HasOneVisibleChild(SelectedPropertyEnumerator)) { ExpandProperty(SelectedPropertyEnumerator, false); break; } } if (e.KeyCode == Keys.Subtract) break; goto case Keys.Up; } case Keys.Up: // Moves the selected item up { PropertyVisibleDeepEnumerator prevEnum = new PropertyVisibleDeepEnumerator(_selectedPropertyEnum.Node); prevEnum.MovePrev(); Property prevProperty = prevEnum.Property; if (prevProperty != null) { Rectangle clientRect = ClientRectangle; Rectangle itemRect = GetAbsoluteItemRect(prevEnum); if (itemRect.Top < clientRect.Top) { _firstDisplayedLine = 1; FirstDisplayedProperty = prevEnum; } else if (itemRect.Bottom > clientRect.Bottom) { while(true) { Win32Calls.SendMessage(Handle, Win32Calls.WM_VSCROLL, Win32Calls.MakeLong(Win32Calls.SB_LINEDOWN, 0), 0); itemRect = GetAbsoluteItemRect(prevEnum); if (itemRect.Bottom < clientRect.Bottom) break; } Win32Calls.SendMessage(Handle, Win32Calls.WM_VSCROLL, Win32Calls.MakeLong(Win32Calls.SB_ENDSCROLL, 0), 0); } SelectProperty(prevEnum); } break; } case Keys.Next: { Rectangle clientRect = ClientRectangle; int itemsPerPage = clientRect.Height / _basicPropertyHeight - 1; Rectangle itemRect = GetAbsoluteItemRect(SelectedPropertyEnumerator); // Find the item one page down int count = 0; PropertyEnumerator propEnum = SelectedPropertyEnumerator.GetVisibleDeepEnumerator(); int lineCount = (propEnum == FirstDisplayedProperty ? _firstDisplayedLine : 1); while ((count < itemsPerPage) && (propEnum != propEnum.RightBound)) { if (lineCount == propEnum.Property.HeightMultiplier) { propEnum.MoveNext(); lineCount = 1; } else lineCount++; count++; } // Selected item is above the grid ? if (itemRect.Bottom < clientRect.Top) { if (propEnum == propEnum.RightBound) { propEnum.MovePrev(); _firstDisplayedLine = propEnum.Property.HeightMultiplier; } else _firstDisplayedLine = lineCount; SelectProperty(propEnum); EnsureVisible(propEnum); } // Selected item is in or below the grid ? else { if (propEnum == propEnum.RightBound) // Not a complete page down because at the far bottom ? { propEnum.MovePrev(); lineCount = propEnum.Property.HeightMultiplier; PropertyVisibleDeepEnumerator propertyToSelectEnum = propEnum.GetVisibleDeepEnumerator(); count = itemsPerPage; while ((propEnum != _activePropertyCollection.GetVisibleDeepEnumerator().MoveFirst()) && (count > 0)) { if (lineCount > 1) lineCount--; else { propEnum.MovePrev(); lineCount = propEnum.Property.HeightMultiplier; } count--; } _firstDisplayedLine = lineCount; FirstDisplayedProperty = propEnum as PropertyVisibleDeepEnumerator; SelectProperty(propertyToSelectEnum); } else { // The grid height is to small to properly page down ? if (itemsPerPage < propEnum.Property.HeightMultiplier) { // Advance one item if (propEnum != _activePropertyCollection.GetVisibleDeepEnumerator().MoveLast()) { if (propEnum == SelectedPropertyEnumerator) propEnum.MoveNext(); _firstDisplayedLine = 1; FirstDisplayedProperty = propEnum as PropertyVisibleDeepEnumerator; SelectProperty(propEnum); } } else { FirstDisplayedProperty = SelectedPropertyEnumerator; SelectProperty(propEnum); } } } Invalidate(); break; } case Keys.Prior: { Rectangle clientRect = ClientRectangle; int itemsPerPage = clientRect.Height / _basicPropertyHeight - 1; // Find the item one page up int count = 0; PropertyVisibleDeepEnumerator enumerator = SelectedPropertyEnumerator.GetVisibleDeepEnumerator(); int lineCount = enumerator.Property.HeightMultiplier; while ((count < itemsPerPage) && (enumerator != _activePropertyCollection.GetVisibleDeepEnumerator().MoveFirst())) { if (lineCount == 1) { enumerator.MovePrev(); lineCount = enumerator.Property.HeightMultiplier; } else lineCount--; count++; } if ((count == 0) && (enumerator != _activePropertyCollection.GetVisibleDeepEnumerator().MoveFirst())) { enumerator.MovePrev(); count = 1; } Rectangle itemRect = GetAbsoluteItemRect(enumerator); // Is the new selected item in the grid ? if ((itemRect.Top >= clientRect.Top) && (itemRect.Bottom < clientRect.Bottom)) SelectProperty(enumerator); // Is the new selected item below the grid ? else if (itemRect.Bottom > clientRect.Bottom) { PropertyEnumerator currentEnum = enumerator.GetVisibleDeepEnumerator(); lineCount = 1; while((count > 0) && (currentEnum != _activePropertyCollection.GetVisibleDeepEnumerator().MoveFirst())) { if (lineCount == 1) { currentEnum.MovePrev(); lineCount = currentEnum.Property.HeightMultiplier; } else lineCount--; count--; } FirstDisplayedProperty = currentEnum as PropertyVisibleDeepEnumerator; SelectProperty(enumerator); } // Is the new selected item above the grid ? else if (itemRect.Top < clientRect.Top) { _firstDisplayedLine = 1; FirstDisplayedProperty = enumerator; SelectProperty(FirstDisplayedProperty); } Refresh(); break; } case Keys.Home: { Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, 0, true); _firstDisplayedPropertyEnumerator = _activePropertyCollection.GetVisibleDeepEnumerator(); _firstDisplayedPropertyEnumerator.MoveFirst(); _firstDisplayedLine = 1; SelectProperty(FirstDisplayedProperty); break; } case Keys.End: { Rectangle clientRect = ClientRectangle; _firstDisplayedPropertyEnumerator = _activePropertyCollection.GetVisibleDeepEnumerator(); _firstDisplayedPropertyEnumerator.MoveLast(); _firstDisplayedLine = 1; PropertyVisibleDeepEnumerator currentEnum = _firstDisplayedPropertyEnumerator.GetVisibleDeepEnumerator(); Rectangle itemRect = GetItemRect(currentEnum); while ((_firstDisplayedPropertyEnumerator != _activePropertyCollection.GetVisibleDeepEnumerator().MoveFirst()) && (clientRect.Bottom - itemRect.Bottom > _basicPropertyHeight)) { if (_firstDisplayedLine > 1) _firstDisplayedLine--; else { _firstDisplayedPropertyEnumerator.MovePrev(); _firstDisplayedLine = _firstDisplayedPropertyEnumerator.Property.HeightMultiplier; } itemRect = GetItemRect(currentEnum); } Win32Calls.SCROLLINFO si = new Win32Calls.SCROLLINFO(); si.cbSize = Marshal.SizeOf(si); si.fMask = Win32Calls.SIF_PAGE | Win32Calls.SIF_RANGE; Win32Calls.GetScrollInfo(Handle, Win32Calls.SB_VERT, ref si); Win32Calls.SetScrollPos(Handle, Win32Calls.SB_VERT, si.nMax - (si.nPage - 1), true); PropertyVisibleDeepEnumerator lastEnum = _activePropertyCollection.GetVisibleDeepEnumerator(); lastEnum.MoveLast(); SelectProperty(lastEnum); break; } case Keys.A: { if (e.Control) { if (_multiSelectMode == PropertyGrid.MultiSelectModes.SameLevel) { // Find the parent of the concerned level PropertyEnumerator ancestorEnum; if (SelectedPropertyEnumerator.Children.Count == 0) ancestorEnum = SelectedPropertyEnumerator.Parent; else ancestorEnum = SelectedPropertyEnumerator; // And browse all properties at this level and under PropertyEnumerator propEnum = ancestorEnum.Children.GetVisibleDeepEnumerator(); propEnum.RestrictedToThisLevelAndUnder = true; while(propEnum != ancestorEnum.Children.RightBound) { if (_parentCtrl.OnValidateMultiSelection(SelectedPropertyEnumerator, propEnum as PropertyVisibleDeepEnumerator)) { propEnum.Property.SelectedInternal = true; _multiSelectedItems.Add(propEnum); } propEnum.MoveNext(); } Invalidate(); } else if (_multiSelectMode == PropertyGrid.MultiSelectModes.Global) { PropertyEnumerator propEnum = _activePropertyCollection.GetVisibleDeepEnumerator(); propEnum.MoveFirst(); while (propEnum != propEnum.RightBound) { if ((propEnum != SelectedPropertyEnumerator) && (propEnum.Children.Count == 0)) { if (_parentCtrl.OnValidateMultiSelection(SelectedPropertyEnumerator, propEnum as PropertyVisibleDeepEnumerator)) { propEnum.Property.SelectedInternal = true; _multiSelectedItems.Add(propEnum); } } propEnum.MoveNext(); } Invalidate(); } } break; } } } base.OnKeyDown(e); }
protected override void WndProc(ref Message m) { if (m.Msg == Win32Calls.WM_SETFOCUS) { // The window that lose the focus is stored for future reference // in OnGotFocus. if the handle is in another application, the stored // value will be null. _wmFocusMissingArg = FromHandle(m.WParam); } else if (m.Msg == Win32Calls.WM_KILLFOCUS) { // The window that gained the focus is stored for future reference // in OnLostFocus. if the handle is in another application, the stored // value will be null. _wmFocusMissingArg = FromHandle(m.WParam); } else if (m.Msg == Win32Calls.WM_ERASEBKGND) { if (Multiline) { // If I don't intercept this message, the control flickers when it is multiline // Some code must also be added in WM_PAINT return; } } else if (m.Msg == Win32Calls.WM_PAINT) { if (Multiline) { Graphics g = CreateGraphics(); Win32Calls.RECT rect = new Win32Calls.RECT(); Win32Calls.GetUpdateRect(Handle, out rect, false); g.FillRectangle(new SolidBrush(BackColor), Rectangle.FromLTRB(rect.Left,rect.Top,rect.Right,rect.Bottom)); g.Dispose(); } } else if (m.Msg == Win32Calls.WM_MOUSEACTIVATE) { if (Focused == false) { if (Form.ActiveForm is PropInPlaceUITypeEditor.DropDownForm) Focus(); } } base.WndProc(ref m); }
protected override void WndProc(ref Message m) { if (m.Msg == Win32Calls.WM_NCCALCSIZE) { Win32Calls.NCCALCSIZE_PARAMS csp; csp = (Win32Calls.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32Calls.NCCALCSIZE_PARAMS)); Rectangle rect = new Rectangle(csp.rgrc0.Left, csp.rgrc0.Top, csp.rgrc0.Right - csp.rgrc0.Left, csp.rgrc0.Bottom - csp.rgrc0.Top); rect.Inflate(-2, -2); csp.rgrc0.Left = rect.X; csp.rgrc0.Right = rect.X + rect.Width; csp.rgrc0.Top = rect.Y; csp.rgrc0.Bottom = rect.Y + rect.Height; Marshal.StructureToPtr(csp, m.LParam, false); } else if (m.Msg == Win32Calls.WM_NCPAINT) { IntPtr hDC = Win32Calls.GetWindowDC(m.HWnd); Graphics graphics = Graphics.FromHdc(hDC); Win32Calls.RECT rc = new Win32Calls.RECT(); Win32Calls.GetWindowRect(m.HWnd, ref rc); Rectangle rect = new Rectangle(0, 0, rc.Right - rc.Left, rc.Bottom - rc.Top); if (Focused) ControlPaint.DrawFocusRectangle(graphics, rect); else { Rectangle bkRect = rect; bkRect.Width--; bkRect.Height--; Pen pen = new Pen(Parent.BackColor); graphics.DrawRectangle(pen, bkRect); pen.Dispose(); } rect.Inflate(-1, -1); rect.Width--; rect.Height--; graphics.DrawLine(SystemPens.ControlDarkDark, new Point(rect.Left, rect.Bottom), rect.Location); graphics.DrawLine(SystemPens.ControlDarkDark, rect.Location, new Point(rect.Right, rect.Top)); graphics.DrawLine(SystemPens.ControlLightLight, new Point(rect.Left, rect.Bottom), new Point(rect.Right, rect.Bottom)); graphics.DrawLine(SystemPens.ControlLightLight, new Point(rect.Right, rect.Bottom), new Point(rect.Right, rect.Top)); Win32Calls.ReleaseDC(m.HWnd, hDC); } base.WndProc(ref m); }
public void SetMargins(int left, int top, int right, int bottom) { Win32Calls.RECT rect = new Win32Calls.RECT(left, top, right, bottom); Win32Calls.SendMessage(Handle, Win32Calls.TTM_SETMARGIN, 0, ref rect); }