分区域滚动窗口

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Management;

namespace ZrjScrollView
{
 internal class NativeMethods
 {
  [StructLayout(LayoutKind.Sequential)]
  public struct RECT
  {
   public int left;
   public int top;
   public int right;
   public int bottom;

   public RECT(Rectangle r)
   {
    this.left = r.Left;
    this.top = r.Top;
    this.right = r.Right;
    this.bottom = r.Bottom;
   }

   public static RECT FromXYWH(int x, int y, int width, int height)
   {
    return new RECT(new Rectangle(x, y, width, height));
   }
  }
  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
  static extern int ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT lprcScroll, ref RECT lprcClip, IntPtr hrgnUpdate, ref RECT lprcUpdate, int fuScroll);

  public static int ScrollWindow(Control aControl, int dX, int dY, Rectangle rectScroll, Rectangle rectClip, Rectangle rectUpdate)
  {
   NativeMethods.RECT rcScroll = new RECT(rectScroll);
   NativeMethods.RECT rcClip = new RECT(rectClip);
   NativeMethods.RECT rcUpdate = new RECT(rectUpdate);

   return ScrollWindowEx(aControl.Handle, dX, dY, ref rcScroll, ref rcClip, IntPtr.Zero, ref rcUpdate, 7);
  }

  //取第一块硬盘编号
  public static string GetHardDiskID()
  {
   try
   {
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
    string strHardDiskID = null;
    foreach (ManagementObject mo in searcher.Get())
    {
     strHardDiskID = mo["SerialNumber"].ToString().Trim();
     break;
    }
    return strHardDiskID;
   }
   catch
   {
    return "";
   }
  }//end

 }

 public class ViewAreaBase
 {
  public ViewAreaBase(Control c)
  {
   this.ownerControl = c;
  }

  public void Paint(PaintEventArgs e)
  {
   if (this.visible == false)
    return;

   Rectangle area = this.Bounds;
   if (area.IntersectsWith(e.ClipRectangle) == false)
    return;

   Region oldRegion = e.Graphics.Clip;
   e.Graphics.SetClip(area);

   OnPaint(e);

   e.Graphics.SetClip(oldRegion, System.Drawing.Drawing2D.CombineMode.Replace);
  }

  public virtual void OnPaint(PaintEventArgs e)
  {
   Rectangle area = this.Bounds;
   area.Width -= 1;
   area.Height -= 1;
   e.Graphics.DrawLine(Pens.Black, area.Left, area.Top, area.Right, area.Bottom);
   e.Graphics.DrawLine(Pens.Black, area.Left, area.Bottom, area.Right, area.Top);
  }

  public bool Visible
  {
   get { return visible; }
   set { visible = value; }
  }

  public Control OwnerControl
  {
   get { return ownerControl; }
  }

  #region 属性 Left, Top, Width, Height, Location, Size, Bounds

  public int Left
  {
   get { return x; }
   set { x = value; }
  }

  public int Top
  {
   get { return y; }
   set { y = value; }
  }

  public int Width
  {
   get { return width; }
   set { width = value; }
  }

  public int Height
  {
   get { return height; }
   set { height = value; }
  }

  public Point Location
  {
   get { return new Point(x, y); }
   set { x = value.X; y = value.Y; }
  }

  public Size Size
  {
   get { return new Size(width, height); }
   set { width = value.Width; height = value.Height; }
  }

  public Rectangle Bounds
  {
   get { return new Rectangle(x, y, width, height); }
   set { x = value.Left; y = value.Top; width = value.Width; height = value.Height; }
  }

  #endregion

  private Control ownerControl;
  private bool visible = true;
  private int x;
  private int y;
  private int width;
  private int height;
 }

 public class ScrollViewArea : ViewAreaBase
 {
  public ScrollViewArea(Control c)
   : base(c)
  {
  }

  public virtual void Scroll(int dx, int dy)
  {
   viewOrg.Offset(dx, dy);
   this.OwnerControl.Invalidate(this.Bounds);
  }

  public override void OnPaint(PaintEventArgs e)
  {
   Rectangle vr = new Rectangle(this.Location, this.VirtualSize);
   vr.Offset(-this.ViewOrg.X, -this.ViewOrg.Y);
   vr.Width -= 1;
   vr.Height -= 1;
   e.Graphics.DrawLine(Pens.Blue, vr.Left, vr.Top, vr.Right, vr.Bottom);
   e.Graphics.DrawLine(Pens.Blue, vr.Left, vr.Bottom, vr.Right, vr.Top);
  }

  public Size VirtualSize
  {
   get { return virtualSize; }
   set { virtualSize = value; }
  }

  public Point ViewOrg
  {
   get { return viewOrg; }
   set { viewOrg = value; }
  }

  private Size virtualSize = Size.Empty;
  private Point viewOrg = new Point(0, 0);
 }
 
 public class MainArea : ScrollViewArea
 {
  public MainArea(Control c, string ImageFileName)
   : base(c)
  {
   img = new Bitmap(ImageFileName);
   VirtualSize = img.Size;
  }

  public override void OnPaint(PaintEventArgs e)
  {
   // draw image
   Rectangle dstRect = this.Bounds;
   dstRect.Intersect(e.ClipRectangle);
   Rectangle srcRect = new Rectangle(this.ViewOrg.X + dstRect.Left - this.Left, this.ViewOrg.Y + dstRect.Top - this.Top, dstRect.Width, dstRect.Height);

   e.Graphics.DrawImage(img, dstRect, srcRect, GraphicsUnit.Pixel);
  }

  private Bitmap img;
 }

    public class ScrollViewBase : Control
    {
        public ScrollViewBase()
        {
   InitializeComponent();
        }

  private void InitializeComponent()
  {
   TextBox EditBox = new TextBox();
   EditBox.Location = new Point(0, 0);
   EditBox.Size = new Size(50, 10);

   this.hScrollBar = new HScrollBar();
   this.vScrollBar = new VScrollBar();
   this.brPanel = new Panel();

   this.topLeftArea = new ViewAreaBase(this);
   this.topRightArea = new ScrollViewArea(this);
   this.leftArea = new ScrollViewArea(this);
   this.rightArea = new MainArea(this, @"D:/IMG_0026.JPG");
   this.bottomLeftArea = new ViewAreaBase(this);
   this.bottomRightArea = new ScrollViewArea(this);

   this.SuspendLayout();

   this.SetStyle(ControlStyles.UserPaint, true);
   this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
   this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
   this.SetStyle(ControlStyles.ResizeRedraw, false);
   //this.SetStyle(ControlStyles.Selectable, true);

   this.vScrollBar.TabIndex = 0;
   this.hScrollBar.TabIndex = 1;
   this.brPanel.TabIndex = 2;

   this.brPanel.Width = SystemInformation.VerticalScrollBarWidth;
   this.brPanel.Height = SystemInformation.HorizontalScrollBarHeight;

   this.hScrollBar.Height = this.brPanel.Height;
   this.vScrollBar.Width = this.brPanel.Width;
   this.brPanel.BackColor = System.Drawing.SystemColors.Control;
   this.BackColor = System.Drawing.SystemColors.Window;

   AdjustScrollBars();

   topRightArea.VirtualSize = new Size(rightArea.VirtualSize.Width, topAreaHeight);
   leftArea.VirtualSize = new Size(leftAreaWidth, rightArea.VirtualSize.Height);
   bottomRightArea.VirtualSize = new Size(rightArea.VirtualSize.Width, bottomAreaHeight);

   this.hScrollBar.Scroll += new ScrollEventHandler(hScrollBar_Scroll);
   this.vScrollBar.Scroll += new ScrollEventHandler(vScrollBar_Scroll);
   this.Controls.Add(hScrollBar);
   this.Controls.Add(vScrollBar);
   this.Controls.Add(brPanel);
   this.Controls.Add(EditBox);

   this.ResumeLayout(false);
  }

  protected override void OnMouseWheel(MouseEventArgs e)
  {
   int dx = 0;
   int dy = 0;
   int newValue;

   if (this.vScrollBar.Visible)
   {
    if (e.Delta > 0) // scroll down
    {
     dy = -3 * this.vScrollBar.SmallChange;
     newValue = Math.Max(this.vScrollBar.Minimum, this.vScrollBar.Value + dy);
     dy = Math.Max(dy, newValue - this.vScrollBar.Value);
    }
    else // scroll up
    {
     dy = 3 * this.vScrollBar.SmallChange;
     newValue = Math.Min(this.vScrollBar.Maximum - this.vScrollBar.LargeChange + 1, this.vScrollBar.Value + dy);
     dy = Math.Min(dy, newValue - this.vScrollBar.Value);
    }
    if (dy != 0)
    {
     this.vScrollBar.Value = newValue;
     rightArea.Scroll(0, dy);
     leftArea.Scroll(0, dy);
    }
    if (e is HandledMouseEventArgs)
    {
     ((HandledMouseEventArgs)e).Handled = true;
    }
   }
   else if (this.hScrollBar.Visible)
   {
    if (e.Delta > 0) // scroll left
    {
     dx = -3 * this.hScrollBar.SmallChange;
     newValue = Math.Max(this.hScrollBar.Minimum, this.hScrollBar.Value + dx);
     dx = Math.Max(dx, newValue - this.hScrollBar.Value);
    }
    else // scroll right
    {
     dx = 3 * this.hScrollBar.SmallChange;
     newValue = Math.Min(this.hScrollBar.Maximum - this.hScrollBar.LargeChange + 1, this.hScrollBar.Value + dx);
     dx = Math.Min(dx, newValue - this.hScrollBar.Value);
    }
    if (dx != 0)
    {
     this.hScrollBar.Value = newValue;
     topRightArea.Scroll(dx, 0);
     rightArea.Scroll(dx, 0);
     bottomRightArea.Scroll(dx, 0);
    }
    if (e is HandledMouseEventArgs)
    {
     ((HandledMouseEventArgs)e).Handled = true;
    }
   }
   base.OnMouseWheel(e);
  }
  protected override void OnMouseMove(MouseEventArgs e)
  {
/*
   Graphics g = this.CreateGraphics();
   string str = e.Location.ToString();
   SizeF strSize = g.MeasureString(str, SystemFonts.StatusFont);
   g.FillRectangle(Brushes.White, 0,0,strSize.Width,strSize.Height);
   g.DrawString(str, SystemFonts.StatusFont, Brushes.Red, 0, 0);
   g.Dispose();
*/
   base.OnMouseMove(e);
  }
  protected override void OnPaint(PaintEventArgs e)
  {
   topLeftArea.Paint(e);
   topRightArea.Paint(e);
   leftArea.Paint(e);
   rightArea.Paint(e);
   bottomLeftArea.Paint(e);
   bottomRightArea.Paint(e);

   base.OnPaint(e);
  }
  protected override void OnResize(EventArgs e)
  {
   base.OnResize(e);
   
   this.SuspendLayout();
   AdjustScrollBars();
   this.ResumeLayout(false);
  }

  void vScrollBar_Scroll(object sender, ScrollEventArgs e)
  {
   // 滚动条无变化时返回
   if (e.NewValue == e.OldValue)
    return;

   int dx = 0;
   int dy = e.NewValue - e.OldValue;

   rightArea.Scroll(dx, dy);
   leftArea.Scroll(dx, dy);
/*
   int dx = 0;
   int dy = e.NewValue - e.OldValue;

   Rectangle rcScroll;
   Rectangle rcUpdate;
   
   if (dy > 0)
   {
    rcScroll = new Rectangle(W1, H1+dy, W2, H2-dy);
    rcUpdate = new Rectangle(W1, H1+H2-dy, W2, dy);
   }
   else
   {
    rcScroll = new Rectangle(W1, H1, W2, H2 - dy);
    rcUpdate = new Rectangle(W1, H1, W2, -dy);
   }

   Rectangle rcClip = new Rectangle(W1, H1, W2, H2);
   NativeMethods.ScrollWindow(this, dx, -dy, rcScroll, rcClip, rcUpdate);
*/
  }

  void hScrollBar_Scroll(object sender, ScrollEventArgs e)
  {
   // 滚动条无变化时返回
   if (e.NewValue == e.OldValue)
    return;

   int dx = e.NewValue - e.OldValue;
   int dy = 0;

   topRightArea.Scroll(dx, dy);
   rightArea.Scroll(dx, dy);
   bottomRightArea.Scroll(dx, dy);
/*
   int dx = e.NewValue - e.OldValue;
   int dy = 0;

   Rectangle rcScroll;
   Rectangle rcUpdate;

   if (dx > 0)
   {
    rcScroll = new Rectangle(W1+dx, H1, W2-dx, H2);
    rcUpdate = new Rectangle(W1+W2-dx, H1, dx, H2);
   }
   else
   {
    rcScroll = new Rectangle(W1, H1, W2+dx, H2);
    rcUpdate = new Rectangle(W1, H1, -dx, H2);
   }

   Rectangle rcClip = new Rectangle(W1, H1, W2, H2);
   NativeMethods.ScrollWindow(this, -dx, 0, rcScroll, rcClip, rcUpdate);
*/
  }

  private void AdjustScrollBars()
  {
   if (this.ClientSize.IsEmpty)
    return;

   ShowMsg();

   int scrollBarHeight = this.hScrollBar.Height;
   int scrollBarWidth = this.vScrollBar.Width;

   this.hScrollBar.Visible = (this.ClientSize.Width < leftAreaWidth + rightArea.VirtualSize.Width);
   this.vScrollBar.Visible = (this.ClientSize.Height < topAreaHeight + bottomAreaHeight + rightArea.VirtualSize.Height);
   this.brPanel.Visible = (this.hScrollBar.Visible && this.vScrollBar.Visible);

   if (this.hScrollBar.Visible == false)
    scrollBarHeight = 0;
   if (this.vScrollBar.Visible == false)
    scrollBarWidth = 0;


   #region 调整绘画区大小位置...

   topLeftArea.Location = new Point(0, 0);
   topLeftArea.Size = new Size(leftAreaWidth, topAreaHeight);

   topRightArea.Location = new Point(leftAreaWidth, 0);
   topRightArea.Size = new Size(this.ClientSize.Width - leftAreaWidth - scrollBarWidth, topAreaHeight);

   leftArea.Location = new Point(0, topAreaHeight);
   leftArea.Size = new Size(leftAreaWidth, this.ClientSize.Height - topAreaHeight - scrollBarHeight - bottomAreaHeight);

   rightArea.Location = new Point(leftArea.Width, topLeftArea.Height);
   rightArea.Size = new Size(topRightArea.Width, leftArea.Height);

   bottomLeftArea.Location = new Point(0, topAreaHeight + leftArea.Height);
   bottomLeftArea.Size = new Size(leftAreaWidth, bottomAreaHeight);

   bottomRightArea.Location = new Point(bottomLeftArea.Width, bottomLeftArea.Top);
   bottomRightArea.Size = new Size(rightArea.Width, bottomAreaHeight);

   #endregion

   #region 重新设置各Area的ViewOrg

   int dx = 0;
   int dy = 0;

   dx = Math.Max(Math.Min(rightArea.VirtualSize.Width - rightArea.ViewOrg.X - rightArea.Width, 0), -rightArea.ViewOrg.X);
   dy = Math.Max(Math.Min(rightArea.VirtualSize.Height - rightArea.ViewOrg.Y - rightArea.Height, 0), -rightArea.ViewOrg.Y);

   topRightArea.ViewOrg = topRightArea.ViewOrg + new Size(dx, 0);
   leftArea.ViewOrg = leftArea.ViewOrg + new Size(0, dy);
   rightArea.ViewOrg = rightArea.ViewOrg + new Size(dx, dy);
   bottomRightArea.ViewOrg = bottomRightArea.ViewOrg + new Size(dx, 0);

   #endregion

   #region 调整滚动条大小位置...

   if (this.vScrollBar.Visible)
   {
    this.vScrollBar.Left = this.ClientSize.Width - this.brPanel.Width;
    this.vScrollBar.Top = 0;
    this.vScrollBar.Height = this.ClientSize.Height - scrollBarHeight;

    this.vScrollBar.Maximum = rightArea.VirtualSize.Height;
    this.vScrollBar.SmallChange = 20;
    this.vScrollBar.LargeChange = rightArea.Height;
    this.vScrollBar.Value = rightArea.ViewOrg.Y;
   }

   if (this.hScrollBar.Visible)
   {
    this.hScrollBar.Left = 0;
    this.hScrollBar.Top = this.ClientSize.Height - this.brPanel.Height;
    this.hScrollBar.Width = this.ClientSize.Width - scrollBarWidth;

    this.hScrollBar.Maximum = rightArea.VirtualSize.Width;
    this.hScrollBar.SmallChange = 20;
    this.hScrollBar.LargeChange = rightArea.Width;
    this.hScrollBar.Value = rightArea.ViewOrg.X;
   }

   if (this.brPanel.Visible)
   {
    this.brPanel.Location = new Point(this.hScrollBar.Width, this.vScrollBar.Height);
   }

   #endregion

   ShowMsg();
   this.Invalidate();
  }

  // 私有数据成员
  private ViewAreaBase topLeftArea;
  private ScrollViewArea topRightArea;
  private ScrollViewArea leftArea;
  private MainArea rightArea;
  private ViewAreaBase bottomLeftArea;
  private ScrollViewArea bottomRightArea;

  private HScrollBar hScrollBar;
  private VScrollBar vScrollBar;
  private Panel brPanel;

  TextBox msgBox;

  public TextBox MsgBox
  {
   get { return msgBox; }
   set { msgBox = value; }
  }

  private void ShowMsg()
  {
   StringBuilder sb = new StringBuilder();
   
   sb.AppendFormat("VSize({0,3},{1,3}) ASize({2,3},{3,3}) VOrg({4,3},{5,3}) ScrollValue({6,3},{7,3})/r/n",
    rightArea.VirtualSize.Width, rightArea.VirtualSize.Height, rightArea.Width, rightArea.Height,
    rightArea.ViewOrg.X, rightArea.ViewOrg.Y, hScrollBar.Value, vScrollBar.Value);
 
   ShowMsg(sb.ToString());
  }

  private void ShowMsg(string str)
  {
   if (msgBox != null && msgBox.IsHandleCreated)
   {
    msgBox.SelectionLength = 0;
    msgBox.SelectionStart = msgBox.Text.Length;
    msgBox.SelectedText = str;
   }
  }

  private int topAreaHeight = 60;
  private int leftAreaWidth = 75;
  private int bottomAreaHeight = 55;
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值