一.如何設置鼠標樣式?
在CSharp的WinForm開發中,可以通過下面的API設置鼠標樣式:

1 //把鼠標樣式設置為十字(系統自帶的一種鼠標樣式) 2 this.Cursor = Cursors.Cross; 3 //把鼠標樣式設置為自定義圖片 4 this.Cursor = new Cursor(string fileName);//要求file為cur格式 5 this.Cursor = new Cursor(IntPtr handel); 6 this.Cursor = new Cursor(System.IO.Stream stream); 7 this.Cursor = new Cursor(Type type, string resource);
如果系統提供的鼠標樣式不能滿足需求,那么勢必要把指定的圖片作為鼠標樣式,項目的資源文件一般是png/jpg/bmp等普通圖片格式,而API卻需要一個cur格式的圖片資源作為參數。。。
當然,去找一個在線轉換工具處理一下也不麻煩,但資源文件的每一次變更都要重新做一次處理,這是我們所無法接受的,而且有的目標文件甚至是動態生成的,根本無法得到一個確定的cur文件,所以我們有理由去尋找一種用普通圖片來設置鼠標樣式的方法
二.如何用png文件設置鼠標樣式?
搜索一下,很容易得到下面的可用代碼:(先別着急copy,下面代碼有Bug)

1 public void SetCursor(Bitmap cursor, Point hotPoint) 2 { 3 int hotX = hotPoint.X; 4 int hotY = hotPoint.Y; 5 Bitmap myNewCursor = new Bitmap(cursor.Width * 2 - hotX, cursor.Height * 2 - hotY); 6 Graphics g = Graphics.FromImage(myNewCursor); 7 g.Clear(Color.FromArgb(0, 0, 0, 0)); 8 g.DrawImage(cursor, cursor.Width - hotX, cursor.Height - hotY, cursor.Width, 9 cursor.Height); 10 11 this.Cursor = new Cursor(myNewCursor.GetHicon()); 12 13 g.Dispose(); 14 myNewCursor.Dispose(); 15 }
P.S.上面的代碼來自前輩的博文,點我查看
網絡上的可用代碼大都是這個版本(包括百度文庫),拿到代碼copy進自己的類,在類開頭注釋中寫上源碼鏈接,稍微一改,嗯,不錯,現成代碼確實好用,效果挺好。。。
第一次希望把自定義圖片的左上角作為鼠標熱點(就是箭頭形鼠標尖尖的那個位置),直接使用上面的代碼,效果很棒,沒有發現任何問題
今天要把自定義圖片的左下角作為鼠標熱點(因為目標圖片是一支鉛筆,畫圖工具里的小鉛筆),直接使用上面代碼,發現不好用了,熱點始終無法對准左下角,百思不得其解,只好開始挖自定義鼠標樣式的原理
最終得到了下面的代碼:(下面的代碼就是完美的解決方案,着急的話先拿去用吧,大可放心使用,不着急的話可以看看下面的原理,非常簡單)

1 /// <summary> 2 /// 設置鼠標樣式 3 /// </summary> 4 /// <param name="cursor"></param> 5 /// <param name="hotPoint"></param> 6 private void SetCursor(string imageFile, Point hotPoint) 7 { 8 int hotX = hotPoint.X; 9 int hotY = hotPoint.Y; 10 Bitmap cursor = new Bitmap(imageFile); 11 //創建大圖 12 Bitmap myNewCursor = new Bitmap(cursor.Width * 2, cursor.Height * 2); 13 Graphics g = Graphics.FromImage(myNewCursor); 14 g.Clear(Color.FromArgb(120, 0, 0, 0)); 15 g.DrawImage(cursor, cursor.Width - hotX, cursor.Height - hotY, cursor.Width, cursor.Height); 16 //設置鼠標指針樣式 17 this.Cursor = new Cursor(myNewCursor.GetHicon()); 18 //釋放資源 19 g.Dispose(); 20 myNewCursor.Dispose(); 21 }
其實只是對之前的現成代碼做了一點點改動,但確實修復了這個Bug
三.自定義鼠標樣式的原理
首先清楚一點:設置目標圖片為鼠標樣式,那么熱點默認在圖片中心
那么理論上熱點不可能跑到左上角去,但系統默認的箭形鼠標熱點不就在左上角嗎?怎么做到的?
下面這幅圖應該足夠解釋清楚設置鼠標熱點的原理了:
P.S.圖中的灰黑色部分應該是全透明的,這里設置成半透明只是為了便於觀察
我們只做了兩件事情:
- 創建一個透明Bitmap,寬/高都是目標圖片的2倍
- 把目標圖片draw到我們的透明Bitmap中,使得目標圖片上的熱點恰好落在透明Bitmap中心