程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Paint.Net學習筆記——三、窗體(下)

Paint.Net學習筆記——三、窗體(下)

編輯:關於.NET

近1個月沒有更新了,不能再懶了,繼續更新PDN的學習筆記!本節將說明PDN中窗體的繼承關系,實 現過程等。

如上圖所示,在PDN中,所有窗體都繼承自PdnBaseForm類,該類繼承自Form類與ISnapManagerHost接 口,該接口定義了SnapManager的get方法,SnapManager是管理界面窗口“粘靠”效果的,該實現方法之 後文章中講述。

現在快速地過一下各個窗體的作用及特點。

BaseForm:

所有PDN裡窗體的基類,主要提供常用窗體方法及注冊、卸載熱鍵。

1、RegisterFormHotKey(Keys,Function<bool,Keys>):注冊熱鍵

PDN擁有設置、處理、卸載熱鍵的功能,這方便了濾鏡開發者的開發。RegisterFormHotKey方法參數 中,有個Function<bool,Keys>。該參數是一個泛型委托,該委托的類型有三種,說明實現該委托 的方法可有多種重載形式。而且該委托的實例,必須實現IComponent和IHotKeyTarget接口,也就是說, 該委托必須由一個窗體發出。在BaseForm中,hotkeyRegistrar是熱鍵注冊字典,保存了所有已注冊的鍵 及委托。接下來的事情就簡單了,重寫ProcessCmdKey方法,處理窗體的鍵盤事件,並從字典中找到該鍵 所對應的委托,執行之。

窗體熱鍵注冊

1    /**//// <summary>
2    /// 注冊窗體范圍的熱鍵,以及當熱鍵摁下的委托。
3    /// 該委托的發起方必須是一個控件,不論是窗體還是窗體還是基本控件,都必須相應該熱 鍵,而且這些窗體都必須繼承自PdnBaseForm
4    /// </summary>
5    public static void RegisterFormHotKey(Keys keys, Function<bool, Keys> callback)
6    {
7      IComponent targetAsComponent = callback.Target as IComponent;
8      IHotKeyTarget targetAsHotKeyTarget = callback.Target as IHotKeyTarget;
9
10      if (targetAsComponent == null && targetAsHotKeyTarget == null)
11      {
12        //檢查委托是否由窗體發出
13        throw new ArgumentException("target instance must implement IComponent or IHotKeyTarget", "callback");
14      }
15
16      if (hotkeyRegistrar == null)
17      {
18        //初始化熱鍵字典
19        hotkeyRegistrar = new Dictionary<Keys, Function<bool, Keys>>();
20      }
21
22      Function<bool, Keys> theDelegate = null;
23
24      if (hotkeyRegistrar.ContainsKey(keys))
25      {
26        如已注冊熱鍵,替換熱鍵委托
27        theDelegate = hotkeyRegistrar[keys];
28        theDelegate += callback;
29        hotkeyRegistrar[keys] = theDelegate;
30      }
31      else
32      {
33        //把熱鍵和委托添加到字典中
34        theDelegate = new Function<bool, Keys>(callback);
35        hotkeyRegistrar.Add(keys, theDelegate);
36      }
37
38      if (targetAsComponent != null)
39      {
40        targetAsComponent.Disposed += TargetAsComponent_Disposed;
41      }
42      else
43      {
44        targetAsHotKeyTarget.Disposed += TargetAsHotKeyTarget_Disposed;
45      }
46    }

2、UnregisterFormHotKey(Keys,Function<bool,Keys>):卸載熱鍵。

該方法就簡單多了,把鍵值從字典中刪除就好了。

MainForm:

這個窗體就是我們運行PDN時看見的窗體了,該窗體提供了所有PDN運行時所支持的窗體功能,包括: 浮動工具窗口、浮動窗口透明漸變效果、文件拖放自動打開功能等等,我們這裡快速浏覽幾個比較重要 的地方:

AppWorkspace:該變量就是我們所稱的“畫布”。

FloaterOpacctiyTimer:該計時器變量控制浮動工具窗口的透明漸變效果:

浮動窗口透明效果實現

1    private void FloaterOpacityTimer_Tick(object sender, System.EventArgs e)
2    {
3      if (this.WindowState == FormWindowState.Minimized ||
4        this.floaters == null ||
5        !PdnBaseForm.EnableOpacity ||
6        this.appWorkspace.ActiveDocumentWorkspace == null)
7        {
8          return;
9        }
10
11      // 以下是我們希望浮動工具窗口出現的:
12      // 1. 如果鼠標在浮動窗口中,那麼它將變為完全不透明
13      // 2. 如果鼠標處於浮動窗口外,那麼它將變為半透明
14      // 3. 無論如何,如果浮動窗口處於主窗體外(這種情況出現於將主窗體不使用最大 化,並移動,使浮動窗口“離開”主窗體),那麼它將變為不透明
15      Rectangle screenDocRect;
16        
17      try
18      {
19        screenDocRect = this.appWorkspace.ActiveDocumentWorkspace.VisibleDocumentBounds;
20      }
21      catch (ObjectDisposedException)
22      {
23        return; // do nothing, we are probably in the process of shutting down the app
24      }
25      for (int i = 0; i < floaters.Length; ++i)
26      {
27        FloatingToolForm ftf = floaters[i];
28        //獲取畫布與浮動窗口的交集矩形
29        Rectangle intersect = Rectangle.Intersect(screenDocRect, ftf.Bounds);
30        double opacity = -1.0;
31        try
32        {
33          if (intersect.Width == 0 ||
34            intersect.Height == 0 ||
35            (ftf.Bounds.Contains(Control.MousePosition) &&
36              !appWorkspace.ActiveDocumentWorkspace.IsMouseCaptured()) ||
37            Utility.DoesControlHaveMouseCaptured(ftf))
38          {
39            //透明度設置最大為1.0,步增0.125
40            opacity = Math.Min(1.0, ftf.Opacity + 0.125);
41          }
42          else
43          {
44            //透明度設置最小為0.75,步減0.0625
45            opacity = Math.Max(0.75, ftf.Opacity - 0.0625);
46          }
47          if (opacity != ftf.Opacity)
48          {
49            ftf.Opacity = opacity;
50          }
51        }
52        catch (System.ComponentModel.Win32Exception)
53        {
54          // 我們不處理這個異常,因為當我們把透明度設為0.7時,Chris Strahl的 電腦報出"the parameter is incorrect"的異常
55          // NVIDIA的GeForce Go顯卡真TM XX?
56        }
57      }
58    }
59

接下來的其他窗體還算中規中矩,沒有什麼特別需要注意的地方,唯一要說的,就是浮動窗體的“粘 靠”效果了。該效果的實現下章節詳細講述。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved