首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實作類 QQ 截圖工具 (2/3):MyRectangle 核心類別完整程式碼

     編輯:關於C#

MyRectangle 類別職責

  • 封裝主選區矩形與 8 個控制點小矩形 (四角 + 四邊中點)。
  • 追蹤滑鼠狀態:繪製中、移動中、縮放中 (8 方向)。
  • 提供反轉繪製 (ControlPaint.DrawReversibleFrame) 無殘影更新。
  • 根據滑鼠位置自動切換游標 (十字、雙向箭頭、移動)。

核心屬性 (節選)


public class MyRectangle
{
    // 主矩形
    public int X, Y, Width, Height, MinWidth = 5, MinHeight = 5;
    public int DownPointX, DownPointY; // 滑鼠按下起始點
    public Rectangle Rect => new Rectangle(X, Y, Width, Height);

    // 8 個控制點小矩形
    public int LittleRectSize = 4;
    public Rectangle LeftTop, LeftMid, LeftBot, RightTop, RightMid, RightBot, TopMid, BotMid;

    // 狀態旗標
    public bool MoveMode, SizeMode;
    public bool OnLeftTop, OnLeftMid, OnLeftBot, OnRightTop, OnRightMid, OnRightBot, OnTopMid, OnBotMid, OnCenter;
    public Cursor CurrentCursor { get; private set; } = Cursors.Cross;
    ...
}

關鍵方法

1. 更新控制點位置


void UpdateHandles()
{
    int o = LittleRectSize / 2;
    LeftTop   = new Rectangle(X - o, Y - o, LittleRectSize, LittleRectSize);
    LeftMid   = new Rectangle(X - o, Y + Height/2 - o, LittleRectSize, LittleRectSize);
    LeftBot   = new Rectangle(X - o, Y + Height - o, LittleRectSize, LittleRectSize);
    RightTop  = new Rectangle(X + Width - o, Y - o, LittleRectSize, LittleRectSize);
    RightMid  = new Rectangle(X + Width - o, Y + Height/2 - o, LittleRectSize, LittleRectSize);
    RightBot  = new Rectangle(X + Width - o, Y + Height - o, LittleRectSize, LittleRectSize);
    TopMid    = new Rectangle(X + Width/2 - o, Y - o, LittleRectSize, LittleRectSize);
    BotMid    = new Rectangle(X + Width/2 - o, Y + Height - o, LittleRectSize, LittleRectSize);
}

2. 反轉繪製 (無殘影)


void Draw(Color backColor)
{
    UpdateHandles();
    ControlPaint.DrawReversibleFrame(Rect, backColor, FrameStyle.Dashed);
    foreach (var r in new[]{LeftTop,LeftMid,LeftBot,RightTop,RightMid,RightBot,TopMid,BotMid})
        ControlPaint.FillReversibleRectangle(r, Color.White);
}

// 重載:繪製中即時更新
void Draw(MouseEventArgs e, Color backColor)
{
    Draw(backColor); // 先抹除舊框
    // 計算新寬高
    Width  = e.X < DownPointX ? DownPointX - e.X : e.X - DownPointX;
    Height = e.Y < DownPointY ? DownPointY - e.Y : e.Y - DownPointY;
    X = e.X < DownPointX ? e.X : DownPointX;
    Y = e.Y < DownPointY ? e.Y : DownPointY;
    Draw(backColor); // 再畫新框
}

3. 滑鼠位置判斷與模式切換


void CheckMouse(MouseEventArgs e)
{
    ResetFlags();
    if (LeftTop.Contains(e.Location))       { OnLeftTop = true;  CurrentCursor = Cursors.SizeNWSE; }
    else if (LeftMid.Contains(e.Location))  { OnLeftMid = true;  CurrentCursor = Cursors.SizeWE; }
    else if (LeftBot.Contains(e.Location))  { OnLeftBot = true;  CurrentCursor = Cursors.SizeNESW; }
    else if (RightTop.Contains(e.Location)) { OnRightTop = true; CurrentCursor = Cursors.SizeNESW; }
    else if (RightMid.Contains(e.Location)) { OnRightMid = true; CurrentCursor = Cursors.SizeWE; }
    else if (RightBot.Contains(e.Location)) { OnRightBot = true; CurrentCursor = Cursors.SizeNWSE; }
    else if (TopMid.Contains(e.Location))   { OnTopMid = true;   CurrentCursor = Cursors.SizeNS; }
    else if (BotMid.Contains(e.Location))   { OnBotMid = true;   CurrentCursor = Cursors.SizeNS; }
    else if (Rect.Contains(e.Location))     { OnCenter = true;   CurrentCursor = Cursors.SizeAll; }
    else                                     CurrentCursor = Cursors.Cross;

    // 按下時進入對應模式
    if (e.Button == MouseButtons.Left)
    {
        if (OnCenter && !SizeMode) MoveMode = true;
        else if (!MoveMode) SizeMode = true;
    }
    else { MoveMode = SizeMode = false; }
}

4. 縮放邏輯 (8 方向獨立處理邊界)


void Resize(MouseEventArgs e)
{
    if (!SizeMode) return;
    if (OnLeftTop)    { if (Right - e.X < MinWidth || Bottom - e.Y < MinHeight) return; Width = Right - e.X; Height = Bottom - e.Y; X = e.X; Y = e.Y; }
    else if (OnLeftMid)  { if (Right - e.X < MinWidth) return; Width = Right - e.X; X = e.X; }
    else if (OnLeftBot)  { if (Right - e.X < MinWidth || e.Y - Top < MinHeight) return; Width = Right - e.X; Height = e.Y - Top; X = e.X; }
    else if (OnRightTop) { if (e.X - Left < MinWidth || Bottom - e.Y < MinHeight) return; Width = e.X - Left; Height = Bottom - e.Y; Y = e.Y; }
    else if (OnRightMid) { if (e.X - Left < MinWidth) return; Width = e.X - Left; }
    else if (OnRightBot) { if (e.X - Left < MinWidth || e.Y - Top < MinHeight) return; Width = e.X - Left; Height = e.Y - Top; }
    else if (OnTopMid)   { if (Bottom - e.Y < MinHeight) return; Height = Bottom - e.Y; Y = e.Y; }
    else if (OnBotMid)   { if (e.Y - Top < MinHeight) return; Height = e.Y - Top; }
}

小結

MyRectangle 將選區幾何、控制點、游標、繪製、互動邏輯全封裝,表單層僅需轉發滑鼠事件並呼叫 Draw/Resize,實現關注點分離。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved