最近项目中的一个功能让我纠结了很久,写出来总结一下。下面描述下我的需求。
项目中有开启第三方软件(飞信),需要控制它的大小,位置固定,不能最小化、关闭,这些操作对于没有重绘窗体使用API很容易实现,可这些对重绘窗体却不太好使。最先开始想到的是不让鼠标移上去,这样自然不能点击操作了,可客户那边反馈过来的是触摸屏操作,这种实现方式行不通了,只能另寻它法了。
这问题困扰了我两周了。好不夸张的说,走在路上都在想解决办法。就在昨天差点被车撞了,我很庆幸驾驶员没有喝醉酒之类的情况。
进入正题说说我的解决办法吧,不过觉得有些投机取巧,在此与大家分享交流,也希望能找到更好的解决方法。上文中我所说的重绘窗体什么样呢?最直观的感受就是漂亮。下面以计算机器和飞信为例,看看操作前后的效果。
看到了吧,右上角的最大化、最小化没了,关闭也禁用了。不能移动了,不能改变大小了(默认已禁用,可以拿其它程序试试)。有点小成就感了,再来看看飞信。
移动可改变大小的问题是解决了,“最小化”、“关闭”(就最小化功能)还在那,开始纠结,开始抓狂,开始种种设想。能不能把“最小化”、“关闭”按钮那块隐藏,能不能裁切.....不但设想实践,算是找到了比较好的方法,看看效果吧。
其实就是截取了窗体的一部分。
View Code
1 using System;
2 using System.Drawing;
3 using System.Windows.Forms;
4 using System.Runtime.InteropServices;
5
6 namespace Fetion
7 {
8 public partial class Form2 : Form
9 {
10 public Form2()
11 {
12 InitializeComponent();
13 }
14
15 [DllImport("user32.dll", EntryPoint = "FindWindow")]
16 private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
17
18 [DllImport("user32.dll")]
19 private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle rect);
20
21 [DllImport("user32.dll")]
22 private static extern bool GetClientRect(IntPtr hWnd, ref Rect lpRect);
23
24 [DllImport("user32.dll")]
25 static extern IntPtr GetSystemMenu(IntPtr hwnd, bool bRevert);
26
27 [DllImport("user32.dll")]
28 static extern bool DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);
29
30 [DllImport("user32.dll")]
31 static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
32
33
34 [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
35 public static extern int GetWindowLong(IntPtr hwnd, int nIndex);
36
37 [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
38 public static extern int SetWindowLong(IntPtr hMenu, int nIndex, int dwNewLong);
39
40 [DllImport("user32.dll")]
41 public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
42
43 [DllImport("gdi32.dll")]
44 public static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);
45
46 [StructLayout(LayoutKind.Sequential)]
47 struct Rect
48 {
49 public int left, top, right, bottom;
50
51 }
52
53 const uint SC_MOVE = 0xF010; //移动
54 const uint SC_SIZE = 0xF000; //大小
55 const uint SC_CLOSE = 0xF060;//关闭
56 const uint MF_BYCOMMAND = 0x00; //按命令方式
57 const uint MF_DISABLED = 0x02; //不可用
58
59 int GWL_STYLE = -16;
60 int WS_MAXIMIZEBOX = 0x10000;
61 int WS_MINIMIZEBOX = 0x20000;
62
63 private void Form2_Load(object sender, EventArgs e)
64 {
65
66 IntPtr ParenthWnd = FindWindow("FxWnd", "飞信2011");
67
68 /*重绘窗体不可行*/
69 int nStyle = GetWindowLong(ParenthWnd, GWL_STYLE);
70 nStyle &= ~(WS_MAXIMIZEBOX);
71 SetWindowLong(ParenthWnd, GWL_STYLE, nStyle);//废掉最大化按钮
72 nStyle &= ~(WS_MINIMIZEBOX);
73 SetWindowLong(ParenthWnd, GWL_STYLE, nStyle);//废掉最小化按钮
74
75
76 IntPtr hMenu = GetSystemMenu(ParenthWnd, false);
77 DeleteMenu(hMenu, SC_MOVE, MF_BYCOMMAND);//不让移动
78 DeleteMenu(hMenu, SC_SIZE, MF_BYCOMMAND);//不让改大小
79 EnableMenuItem(hMenu, SC_CLOSE, MF_DISABLED);//禁用关闭按钮(重绘窗体不可行)
80
81 Rect crect = new Rect(); ;
82 GetClientRect(ParenthWnd, ref crect);
83 IntPtr OutRgn = CreateRoundRectRgn(0, 20, crect.right, crect.bottom + 5, 5, 5);
84 SetWindowRgn(ParenthWnd, OutRgn, true);
85
86 }
87
88 }
89 }
最后提前祝各位园友节日快乐,准备好去哪旅行了没?