/// <include file='doc\ScrollBar.uex' path='docs/doc[@for="ScrollBar.DoScroll"]/*' /> /// <devdoc> /// </devdoc> /// <internalonly/> private void DoScroll(ScrollEventType type) { // For Rtl systems we need to swap increment and decrement // if (RightToLeft == RightToLeft.Yes) { switch (type) { case ScrollEventType.First: type = ScrollEventType.Last; break; case ScrollEventType.Last: type = ScrollEventType.First; break; case ScrollEventType.SmallDecrement: type = ScrollEventType.SmallIncrement; break; case ScrollEventType.SmallIncrement: type = ScrollEventType.SmallDecrement; break; case ScrollEventType.LargeDecrement: type = ScrollEventType.LargeIncrement; break; case ScrollEventType.LargeIncrement: type = ScrollEventType.LargeDecrement; break; } } int newValue = value; int oldValue = value; // The ScrollEventArgs constants are defined in terms of the windows // messages.. this eliminates confusion between the VSCROLL and // HSCROLL constants, which are identical. // switch (type) { case ScrollEventType.First: newValue = minimum; break; case ScrollEventType.Last: newValue = maximum - LargeChange + 1; // si.nMax - si.nPage + 1; break; case ScrollEventType.SmallDecrement: newValue = Math.Max(value - SmallChange, minimum); break; case ScrollEventType.SmallIncrement: newValue = Math.Min(value + SmallChange, maximum - LargeChange + 1); // max - lChange + 1); break; case ScrollEventType.LargeDecrement: newValue = Math.Max(value - LargeChange, minimum); break; case ScrollEventType.LargeIncrement: newValue = Math.Min(value + LargeChange, maximum - LargeChange + 1); // si.nPos + si.nPage,si.nMax - si.nPage + 1); break; case ScrollEventType.ThumbPosition: case ScrollEventType.ThumbTrack: NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); si.fMask = NativeMethods.SIF_TRACKPOS; SafeNativeMethods.GetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_CTL, si); if (RightToLeft == RightToLeft.Yes) { newValue = ReflectPosition(si.nTrackPos); } else { newValue = si.nTrackPos; } break; } ScrollEventArgs se = new ScrollEventArgs(type, oldValue, newValue, this.scrollOrientation); OnScroll(se); Value = se.NewValue; }
/// <summary> /// Gets scrollbar properties /// </summary> /// <param name="scrollbar">The bar.</param> /// <returns></returns> private NativeMethods.SCROLLINFO GetScrollInfo(ScrollOrientation scrollbar) { NativeMethods.SCROLLINFO info; info = new NativeMethods.SCROLLINFO(); info.fMask = NativeMethods.SIF.SIF_ALL; NativeMethods.GetScrollInfo(this.Handle, (int)scrollbar, info); return info; }
/// <include file='doc\ScrollBar.uex' path='docs/doc[@for="ScrollBar.UpdateScrollInfo"]/*' /> /// <devdoc> /// Internal helper method /// </devdoc> /// <internalonly/> protected void UpdateScrollInfo() { if (IsHandleCreated && Enabled) { NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); si.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO)); si.fMask = NativeMethods.SIF_ALL; si.nMin = minimum; si.nMax = maximum; si.nPage = LargeChange; if (RightToLeft == RightToLeft.Yes) { // Reflect the scrollbar position horizontally on an Rtl system si.nPos = ReflectPosition(value); } else { si.nPos = value; } si.nTrackPos = 0; UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_CTL, si, true); } }
/// <summary> /// Updates the horizontal scrollbar. /// </summary> protected virtual void UpdateHorizontalScrollbar() { NativeMethods.SCROLLINFO scrollInfo; int scrollWidth; int pageWidth; scrollWidth = this.ScrollSize.Width - 1; pageWidth = this.PageSize.Width; if (scrollWidth < 1) { scrollWidth = 0; pageWidth = 1; } scrollInfo = new NativeMethods.SCROLLINFO(); scrollInfo.fMask = NativeMethods.SIF.SIF_PAGE | NativeMethods.SIF.SIF_RANGE; if (this.AlwaysShowHScroll || !this.Enabled) { scrollInfo.fMask |= NativeMethods.SIF.SIF_DISABLENOSCROLL; } scrollInfo.nMin = 0; scrollInfo.nMax = scrollWidth; scrollInfo.nPage = pageWidth; this.SetScrollInfo(ScrollOrientation.HorizontalScroll, scrollInfo, true); }
/// <summary> /// Updates the vertical scrollbar. /// </summary> protected virtual void UpdateVerticalScrollbar() { NativeMethods.SCROLLINFO scrollInfo; int scrollHeight; int pageHeight; scrollHeight = this.ScrollSize.Height - 1; pageHeight = this.PageSize.Height; if (scrollHeight < 1) { scrollHeight = 0; pageHeight = 1; } scrollInfo = new NativeMethods.SCROLLINFO(); scrollInfo.fMask = NativeMethods.SIF.SIF_PAGE | NativeMethods.SIF.SIF_RANGE; if (AlwaysShowVScroll) { scrollInfo.fMask |= NativeMethods.SIF.SIF_DISABLENOSCROLL; } scrollInfo.nMin = 0; scrollInfo.nMax = scrollHeight; scrollInfo.nPage = pageHeight; this.SetScrollInfo(ScrollOrientation.VerticalScroll, scrollInfo, true); }
/// <summary> /// Set the given scrollbar's tracking position to the specified value /// </summary> /// <param name="scrollbar">The scrollbar.</param> /// <param name="value">The value.</param> protected virtual void ScrollTo(ScrollOrientation scrollbar, int value) { NativeMethods.SCROLLINFO oldInfo; oldInfo = this.GetScrollInfo(scrollbar); if (value > ((oldInfo.nMax - oldInfo.nMin) + 1) - oldInfo.nPage) { value = ((oldInfo.nMax - oldInfo.nMin) + 1) - oldInfo.nPage; } if (value < oldInfo.nMin) { value = oldInfo.nMin; } if (oldInfo.nPos != value) { NativeMethods.SCROLLINFO scrollInfo; scrollInfo = new NativeMethods.SCROLLINFO(); scrollInfo.fMask = NativeMethods.SIF.SIF_POS; scrollInfo.nPos = value; this.SetScrollInfo(scrollbar, scrollInfo, true); this.OnScroll(new ScrollEventArgs(ScrollEventType.ThumbPosition, oldInfo.nPos, value, scrollbar)); } }
/// <include file='doc\TreeView.uex' path='docs/doc[@for="TreeView.CustomDraw"]/*' /> /// <devdoc> /// Performs custom draw handling /// </devdoc> /// <internalonly/> private void CustomDraw(ref Message m) { NativeMethods.NMTVCUSTOMDRAW nmcd = (NativeMethods.NMTVCUSTOMDRAW)m.GetLParam(typeof(NativeMethods.NMTVCUSTOMDRAW)); // Find out which stage we're drawing switch (nmcd.nmcd.dwDrawStage) { // Do we want OwnerDraw for this paint cycle? case NativeMethods.CDDS_PREPAINT: m.Result = (IntPtr)NativeMethods.CDRF_NOTIFYITEMDRAW; // yes, we do... return; // We've got opt-in on owner draw for items - so handle each one. case NativeMethods.CDDS_ITEMPREPAINT: // get the node Debug.Assert(nmcd.nmcd.dwItemSpec != IntPtr.Zero, "Invalid node handle in ITEMPREPAINT"); TreeNode node = NodeFromHandle((IntPtr)nmcd.nmcd.dwItemSpec); if (node == null) { // this can happen if we are presently inserting the node - it hasn't yet // been added to the handle table m.Result = (IntPtr)(NativeMethods.CDRF_SKIPDEFAULT); return; } int state = nmcd.nmcd.uItemState; // The commctrl TreeView allows you to draw the whole row of a node // or nothing at all. The way we provide OwnerDrawText is by asking it // to draw everything but the text - to do this, we set text color same // as background color. if (drawMode == TreeViewDrawMode.OwnerDrawText) { nmcd.clrText = nmcd.clrTextBk; Marshal.StructureToPtr(nmcd, m.LParam, false); m.Result = (IntPtr) (NativeMethods.CDRF_NEWFONT | NativeMethods.CDRF_NOTIFYPOSTPAINT); return; } else if (drawMode == TreeViewDrawMode.OwnerDrawAll) { Graphics g = Graphics.FromHdcInternal(nmcd.nmcd.hdc); DrawTreeNodeEventArgs e; try { Rectangle bounds = node.RowBounds; NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); si.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO)); si.fMask = NativeMethods.SIF_POS; if (UnsafeNativeMethods.GetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_HORZ,si) != false) { // VsW : 432718 // need to get the correct bounds if horizontal scroll bar is shown. // In this case the bounds.X needs to be negative and width needs to be updated to the increased width (scrolled region). int value = si.nPos; if (value > 0) { bounds.X -= value; bounds.Width += value; } } e = new DrawTreeNodeEventArgs(g, node, bounds, (TreeNodeStates) (state)); OnDrawNode(e); } finally { g.Dispose(); } if (!e.DrawDefault) { m.Result = (IntPtr)(NativeMethods.CDRF_SKIPDEFAULT); return; } } //TreeViewDrawMode.Normal case #if DEBUGGING // Diagnostic output Debug.WriteLine("Itemstate: "+state); Debug.WriteLine("Itemstate: "+ "\nDISABLED" + (((state & NativeMethods.CDIS_DISABLED) != 0) ? "TRUE" : "FALSE") + "\nHOT" + (((state & NativeMethods.CDIS_HOT) != 0) ? "TRUE" : "FALSE") + "\nGRAYED" + (((state & NativeMethods.CDIS_GRAYED) != 0) ? "TRUE" : "FALSE") + "\nSELECTED" + (((state & NativeMethods.CDIS_SELECTED) != 0) ? "TRUE" : "FALSE") + "\nFOCUS" + (((state & NativeMethods.CDIS_FOCUS) != 0) ? "TRUE" : "FALSE") + "\nDEFAULT" + (((state & NativeMethods.CDIS_DEFAULT) != 0) ? "TRUE" : "FALSE") + "\nMARKED" + (((state & NativeMethods.CDIS_MARKED) != 0) ? "TRUE" : "FALSE") + "\nINDETERMINATE" + (((state & NativeMethods.CDIS_INDETERMINATE) != 0) ? "TRUE" : "FALSE")); #endif OwnerDrawPropertyBag renderinfo = GetItemRenderStyles(node,state); // TreeView has problems with drawing items at times; it gets confused // as to which colors apply to which items (see focus rectangle shifting; // when one item is selected, click and hold on another). This needs to be fixed. bool colordelta = false; Color riFore = renderinfo.ForeColor; Color riBack = renderinfo.BackColor; if (renderinfo != null && !riFore.IsEmpty) { nmcd.clrText = ColorTranslator.ToWin32(riFore); colordelta = true; } if (renderinfo != null && !riBack.IsEmpty) { nmcd.clrTextBk = ColorTranslator.ToWin32(riBack); colordelta = true; } if (colordelta) { Marshal.StructureToPtr(nmcd, m.LParam, false); } if (renderinfo != null && renderinfo.Font != null) { // Mess with the DC directly... SafeNativeMethods.SelectObject(new HandleRef(nmcd.nmcd, nmcd.nmcd.hdc), new HandleRef(renderinfo, renderinfo.FontHandle)); // There is a problem in winctl that clips node fonts if the fontsize // is larger than the treeview font size. The behavior is much better in comctl 5 and above. m.Result = (IntPtr)NativeMethods.CDRF_NEWFONT; return; } // fall through and do the default drawing work goto default; case (NativeMethods.CDDS_ITEMPOSTPAINT): //User draws only the text in OwnerDrawText mode, as explained in comments above if (drawMode == TreeViewDrawMode.OwnerDrawText) { Debug.Assert(nmcd.nmcd.dwItemSpec != IntPtr.Zero, "Invalid node handle in ITEMPOSTPAINT"); // Get the node node = NodeFromHandle((IntPtr)nmcd.nmcd.dwItemSpec); if (node == null) { // this can happen if we are presently inserting the node - it hasn't yet // been added to the handle table return; } Graphics g = Graphics.FromHdcInternal(nmcd.nmcd.hdc); DrawTreeNodeEventArgs e; try { Rectangle bounds = node.Bounds; Size textSize = TextRenderer.MeasureText(node.Text, node.TreeView.Font); Point textLoc = new Point(bounds.X -1, bounds.Y); // required to center the text bounds = new Rectangle(textLoc, new Size(textSize.Width, bounds.Height)); e = new DrawTreeNodeEventArgs(g, node, bounds, (TreeNodeStates) (nmcd.nmcd.uItemState)); OnDrawNode(e); if (e.DrawDefault) { //Simulate default text drawing here TreeNodeStates curState = e.State; Font font = (node.NodeFont != null) ? node.NodeFont : node.TreeView.Font; Color color = (((curState & TreeNodeStates.Selected) == TreeNodeStates.Selected) && node.TreeView.Focused) ? SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor; // Draw the actual node. if ((curState & TreeNodeStates.Selected) == TreeNodeStates.Selected) { g.FillRectangle(SystemBrushes.Highlight, bounds); ControlPaint.DrawFocusRectangle(g, bounds, color, SystemColors.Highlight); TextRenderer.DrawText(g, e.Node.Text, font, bounds, color, TextFormatFlags.Default); } else { // For Dev10 bug 478621: We need to draw the BackColor of // nodes same as BackColor of treeview. using (Brush brush = new SolidBrush(BackColor)) { g.FillRectangle(brush, bounds); } TextRenderer.DrawText(g, e.Node.Text, font, bounds, color, TextFormatFlags.Default); } } } finally { g.Dispose(); } m.Result = (IntPtr)NativeMethods.CDRF_NOTIFYSUBITEMDRAW; return; } goto default; default: // just in case we get a spurious message, tell it to do the right thing m.Result = (IntPtr)NativeMethods.CDRF_DODEFAULT; return; } }
internal void SetVirtualSizeNoInvalidate(Size value) { virtualSize = value; SetPositionNoInvalidate(position); // Make sure it's within range NativeMethods.SCROLLINFO info = new NativeMethods.SCROLLINFO(); info.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE; info.nMin = 0; info.nMax = Math.Max(Height, virtualSize.Height) - 1; info.nPage = Height; UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_VERT, info, true); info.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE; info.nMin = 0; info.nMax = Math.Max(Width, virtualSize.Width) - 1; info.nPage = Width; UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_HORZ, info, true); }
private int AdjustScroll(Message m, int pos, int maxPos, bool horizontal) { switch (NativeMethods.Util.LOWORD(m.WParam)) { case NativeMethods.SB_THUMBPOSITION: case NativeMethods.SB_THUMBTRACK: NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); si.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO)); si.fMask = NativeMethods.SIF_TRACKPOS; int direction = horizontal ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; if (SafeNativeMethods.GetScrollInfo(new HandleRef(this, m.HWnd), direction, si)) { pos = si.nTrackPos; } else { pos = NativeMethods.Util.HIWORD(m.WParam); } break; case NativeMethods.SB_LINEUP: if (pos > SCROLL_LINE) { pos-=SCROLL_LINE; } else { pos = 0; } break; case NativeMethods.SB_LINEDOWN: if (pos < maxPos-SCROLL_LINE) { pos+=SCROLL_LINE; } else { pos = maxPos; } break; case NativeMethods.SB_PAGEUP: if (pos > SCROLL_PAGE) { pos-=SCROLL_PAGE; } else { pos = 0; } break; case NativeMethods.SB_PAGEDOWN: if (pos < maxPos-SCROLL_PAGE) { pos+=SCROLL_PAGE; } else { pos = maxPos; } break; } return pos; }
/// <include file='doc\ScrollProperties.uex' path='docs/doc[@for="ScrollProperties.UpdateScrollInfo"]/*' /> /// <devdoc> /// Internal helper method /// </devdoc> /// <internalonly/> internal void UpdateScrollInfo() { if (parent.IsHandleCreated && visible) { NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); si.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO)); si.fMask = NativeMethods.SIF_ALL; si.nMin = minimum; si.nMax = maximum; si.nPage = (parent.AutoScroll) ? PageSize : LargeChange; si.nPos = value; si.nTrackPos = 0; UnsafeNativeMethods.SetScrollInfo(new HandleRef(parent, parent.Handle), Orientation, si, true); } }