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

C# 圖形開發高階:簽名軌跡擷取、滑鼠事件處理與命中測試演算法 (第 7 講第 6 部分)

     編輯:關於C語言

Marking 狀態管理

  • BeginMark:建立新 PenMarkInfo 物件,尚未加入文件,Marking 回傳 true。
  • EndMark:若新簽名包含至少一筆筆跡則加入文件,否則捨棄,Marking 回傳 false。

OnMouseDown 事件處理核心邏輯

protected override void OnMouseDown(MouseEventArgs e)
{
    base.OnMouseDown(e);
    if (this.Marking)
    {
        myCurrentLine = new PointArrayList();
        LastPoint = new Point(e.X, e.Y);
    }
    else
    {
        // 座標修正 (考慮 AutoScrollPosition)
        int x = e.X - this.AutoScrollPosition.X;
        int y = e.Y - this.AutoScrollPosition.Y;

        // 命中測試:距離平方 < 13 視為命中
        foreach (PenMarkInfo info in myDocument)
        foreach (PointArrayList line in info.Lines)
        foreach (Point p in line)
        {
            double r = (p.X - x)*(p.X - x) + (p.Y - y)*(p.Y - y);
            if (r < 13)
            {
                Rectangle rect = info.Bounds;
                if (myCurrentInfo != null)
                    rect = Rectangle.Union(rect, myCurrentInfo.Bounds);
                rect.Offset(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
                myCurrentInfo = info;
                this.Invalidate(rect); // 宣告局部無效需重繪
                goto EndElse;
            }
        }
        EndElse: ;
    }
}

Invalidate 機制

  • Invalidate(Rectangle):宣告局部區域無效,後續 OnPaint 的 ClipRectangle 即為此矩形,優化重繪範圍。
  • Invalidate() (無參數):宣告整個控制項需重繪。

演算法重點

  • 使用距離平方避免 Math.Sqrt 運算。
  • goto 跳出多層迴圈 (可改用布林旗標或方法抽離)。
  • 命中後合併舊/新邊界並轉換回客戶區座標再 Invalidate。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved