C# 實現像QQ一樣隱藏窗體
阿新 • • 發佈:2019-01-29
在製作QQ窗體時,其關鍵是判斷滑鼠是否在窗體上,主要是用API函式WindowFromPoint和GetParent來實現的
(1)API函式WindowFromPoint
該函式獲取當前滑鼠下視覺化控制元件的控制代碼。忽略遮蔽、隱藏以及透明視窗。其宣告如下:
[DllImport("user32.dll")]
public static extern int WindowFromPoint(int xPoint, int yPoint);
l xPoint:int,X點值。
l yPoint:int,Y點值。
l 返回值:int,包含了指定點的視窗的控制代碼。如指定的點處沒有視窗存在,則返回零。
int n = WindowFromPoint(120,100);
(2)API函式GetParent
該函式獲取指定控制代碼的父級控制代碼。
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
l hWnd:int,視覺化控制元件的控制代碼。
l 返回值:指定控制代碼的父級控制代碼。
例如,獲取panel1控制元件的父級控制代碼。程式碼如下:
int n = GetParent(panel1.Handle);
(3)API函式GetSystemMetrics
獲取螢幕解析度
[DllImport("user32")]
public static extern int GetSystemMetrics(int nIndex);
1.窗體放置timer1設定interval為2,用來判斷窗體位置隱藏窗體
2.窗體放置timer2設定interval為2,用來顯示隱藏窗體時的動態效果
3.獲取父窗體控制代碼函式FormNameAt
4.窗體放置panel用來判斷滑鼠擡起和按下的事件,擡起timer1開啟,按下關閉
private void panel_Title_MouseDown(object sender, MouseEventArgs e)
{
timer1.Enabled = false; //停止
CPoint = new Point(-e.X, -e.Y); //獲取當前滑鼠的位置
}
private void panel_Title_MouseUp(object sender, MouseEventArgs e)
{
timer1.Enabled = true; //啟動timer1控制元件
}
private void timer1_Tick(object sender, EventArgs e)
{
if (this.Top < 3) //如果窗體被移到螢幕的頂部
{
if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//當滑鼠移致到該窗體上
{
panel_Title.Tag = 1; //設定標識,用於判斷窗體在螢幕頂部
timer2.Enabled = false; //不對窗體進行拉伸操作
this.Top = 0; //使窗體致頂
}
else
{
panel_Title.Tag = 1; //設定標識,用於判斷窗體在螢幕頂部
timer2.Enabled = true; //將窗體在頂部進行隱藏
}
}
else
{
if (this.Left < 3 || this.Right > GetSystemMetrics(0) - 3) //如果窗體被移到螢幕的左端或右端
{
if (this.Left < 3) //如果窗體被移到螢幕的左端
{
if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//當滑鼠移致到該窗體上
{
panel_Title.Tag = 2; //設定標識,用於判斷窗體在螢幕左端
timer2.Enabled = false;
this.Left = 0; //使窗體致左
}
else
{
panel_Title.Tag = 2;
timer2.Enabled = true; //將窗體在左端進行隱藏
}
}
if (this.Right > GetSystemMetrics(0) - 3) //如果窗體被移到螢幕的右端
{
if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//當滑鼠移到該窗體上
{
panel_Title.Tag = 3; //設定標識,用於判斷窗體在螢幕右端
timer2.Enabled = false;
this.Left = GetSystemMetrics(0) - this.Width; //使窗體致右
}
else
{
panel_Title.Tag = 3;
timer2.Enabled = true; //將窗體在右端進行隱藏
}
}
}
}
}
private void timer2_Tick(object sender, EventArgs e)
{
switch (Convert.ToInt16(panel_Title.Tag.ToString())) //對標識進行判斷
{
case 1: //頂端隱藏
{
if (this.Top < 5) //如果窗體的頂端與螢幕頂端距離小於5
this.Top = -(this.Height - 2); //使窗體上移,實現頂端隱藏效果
break;
}
case 2: //左端隱藏
{
if (this.Left < 5) //如果窗體的左端與螢幕左端距離小於5
this.Left = -(this.Width - 2); //使窗體左移,實現左端隱藏效果
break;
}
case 3://右端隱藏
{
if ((this.Left + this.Width) > (GetSystemMetrics(0) - 5)) //如果窗體的右端與螢幕右端距離小於5
this.Left = GetSystemMetrics(0) - 2; //使窗體右移,實現右端隱藏效果
break;
}
}
}
自定義方法FormNameAt用於獲取當前視覺化控制元件的窗體控制代碼。
public IntPtr FormNameAt(int x, int y)
{
IntPtr Tem_hWnd; //設定儲存控制代碼的變數
Tem_Handle = (IntPtr)(WindowFromPoint(x, y)); //獲取當前滑鼠下視覺化控制元件的控制代碼
Tem_hWnd = Tem_Handle; //記錄原始控制代碼
while (Tem_hWnd != ((IntPtr)0)) //遍歷該控制代碼的父級控制代碼
{
Tem_Handle = Tem_hWnd; //記錄當前控制代碼
Tem_hWnd = GetParent(Tem_hWnd); //獲取父級控制代碼
}
return Tem_Handle; //返回最底層的父級控制代碼
}
(1)API函式WindowFromPoint
該函式獲取當前滑鼠下視覺化控制元件的控制代碼。忽略遮蔽、隱藏以及透明視窗。其宣告如下:
[DllImport("user32.dll")]
public static extern int WindowFromPoint(int xPoint, int yPoint);
l xPoint:int,X點值。
l yPoint:int,Y點值。
l 返回值:int,包含了指定點的視窗的控制代碼。如指定的點處沒有視窗存在,則返回零。
int n = WindowFromPoint(120,100);
(2)API函式GetParent
該函式獲取指定控制代碼的父級控制代碼。
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
l hWnd:int,視覺化控制元件的控制代碼。
l 返回值:指定控制代碼的父級控制代碼。
例如,獲取panel1控制元件的父級控制代碼。程式碼如下:
int n = GetParent(panel1.Handle);
(3)API函式GetSystemMetrics
獲取螢幕解析度
[DllImport("user32")]
public static extern int GetSystemMetrics(int nIndex);
1.窗體放置timer1設定interval為2,用來判斷窗體位置隱藏窗體
2.窗體放置timer2設定interval為2,用來顯示隱藏窗體時的動態效果
3.獲取父窗體控制代碼函式FormNameAt
4.窗體放置panel用來判斷滑鼠擡起和按下的事件,擡起timer1開啟,按下關閉
private void panel_Title_MouseDown(object sender, MouseEventArgs e)
{
timer1.Enabled = false; //停止
CPoint = new Point(-e.X, -e.Y); //獲取當前滑鼠的位置
}
private void panel_Title_MouseUp(object sender, MouseEventArgs e)
{
timer1.Enabled = true; //啟動timer1控制元件
}
private void timer1_Tick(object sender, EventArgs e)
{
if (this.Top < 3) //如果窗體被移到螢幕的頂部
{
if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//當滑鼠移致到該窗體上
{
panel_Title.Tag = 1; //設定標識,用於判斷窗體在螢幕頂部
timer2.Enabled = false; //不對窗體進行拉伸操作
this.Top = 0; //使窗體致頂
}
else
{
panel_Title.Tag = 1; //設定標識,用於判斷窗體在螢幕頂部
timer2.Enabled = true; //將窗體在頂部進行隱藏
}
}
else
{
if (this.Left < 3 || this.Right > GetSystemMetrics(0) - 3) //如果窗體被移到螢幕的左端或右端
{
if (this.Left < 3) //如果窗體被移到螢幕的左端
{
if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//當滑鼠移致到該窗體上
{
panel_Title.Tag = 2; //設定標識,用於判斷窗體在螢幕左端
timer2.Enabled = false;
this.Left = 0; //使窗體致左
}
else
{
panel_Title.Tag = 2;
timer2.Enabled = true; //將窗體在左端進行隱藏
}
}
if (this.Right > GetSystemMetrics(0) - 3) //如果窗體被移到螢幕的右端
{
if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//當滑鼠移到該窗體上
{
panel_Title.Tag = 3; //設定標識,用於判斷窗體在螢幕右端
timer2.Enabled = false;
this.Left = GetSystemMetrics(0) - this.Width; //使窗體致右
}
else
{
panel_Title.Tag = 3;
timer2.Enabled = true; //將窗體在右端進行隱藏
}
}
}
}
}
private void timer2_Tick(object sender, EventArgs e)
{
switch (Convert.ToInt16(panel_Title.Tag.ToString())) //對標識進行判斷
{
case 1: //頂端隱藏
{
if (this.Top < 5) //如果窗體的頂端與螢幕頂端距離小於5
this.Top = -(this.Height - 2); //使窗體上移,實現頂端隱藏效果
break;
}
case 2: //左端隱藏
{
if (this.Left < 5) //如果窗體的左端與螢幕左端距離小於5
this.Left = -(this.Width - 2); //使窗體左移,實現左端隱藏效果
break;
}
case 3://右端隱藏
{
if ((this.Left + this.Width) > (GetSystemMetrics(0) - 5)) //如果窗體的右端與螢幕右端距離小於5
this.Left = GetSystemMetrics(0) - 2; //使窗體右移,實現右端隱藏效果
break;
}
}
}
自定義方法FormNameAt用於獲取當前視覺化控制元件的窗體控制代碼。
public IntPtr FormNameAt(int x, int y)
{
IntPtr Tem_hWnd; //設定儲存控制代碼的變數
Tem_Handle = (IntPtr)(WindowFromPoint(x, y)); //獲取當前滑鼠下視覺化控制元件的控制代碼
Tem_hWnd = Tem_Handle; //記錄原始控制代碼
while (Tem_hWnd != ((IntPtr)0)) //遍歷該控制代碼的父級控制代碼
{
Tem_Handle = Tem_hWnd; //記錄當前控制代碼
Tem_hWnd = GetParent(Tem_hWnd); //獲取父級控制代碼
}
return Tem_Handle; //返回最底層的父級控制代碼
}