For Each mnu As MenuItem In mnuWindows.MenuItems If mnu.Checked Then MessageBox.Show(mnu.Text & "窗口是激活状态!") Else MessageBox.Show(mnu.Text & "窗口是非激活状态!") End If Next
一个更好的解决方案,不用加事件,也可以判断标题; 没有考虑不规则窗体的情况。 参考如下代码: using System.Runtime.InteropServices;[DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd);[DllImport("user32.dll")] public static extern IntPtr GetWindowDC(IntPtr hWnd);[DllImport("user32.dll")] public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);[DllImport("gdi32.dll")] public static extern int GetClipBox(IntPtr hDC, ref Rectangle lpRect);/// <summary> /// 判断窗体是否被遮挡 /// </summary> /// <param name="hWnd">窗体句柄</param> /// <returns>返回窗体是否被完全遮挡</returns> public bool WindowPall(IntPtr AHandle) { if (!IsWindowVisible(AHandle)) return false; // 窗体不可见 IntPtr vDC = GetWindowDC(AHandle); try { Rectangle vRect = new Rectangle(); GetClipBox(vDC, ref vRect); return vRect.Width - vRect.Left <= 0 && vRect.Height - vRect.Top <= 0; // 特别说明:Rectangle.Width对应API中RECT.Right、Rectangle.Height为RECT.Bottom } finally { ReleaseDC(AHandle, vDC); } }private void timer1_Tick(object sender, EventArgs e) { Text = WindowPall(Handle).ToString(); }
api Getwindowrect 获取 窗口 X Y 高宽长度.. 是否少与 其他窗口的 X Y 高宽长度 可以吗? 我也不太懂..只是感觉当你打开你的 窗口 Getwindowrect 信息保存起来.. 然后 当你打开其他窗口的时候 用那窗口的信息 对比你应用程序的窗口信息.. 我的愚见.. 有空帮我顶下贴.. 我也有个大困难 http://topic.csdn.net/u/20080119/13/fc2a2576-e924-4cf0-a185-e67853afab91.htmlhttp://topic.csdn.net/u/20080119/11/0d1b8aec-b349-4699-b837-fdeac8ab22a8.html
不胜感激.
在根据GetWindowPlacement取得的信息判断。
具体用法自己找吧
当使用代码激活或用户激活窗体时发生。
草上飞
等 级:
发表于:2008-01-20 15:10:596楼 得分:0
用FindWindow或FindWindowEx找到此窗口的句柄,然后用GetWindowPlacement返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置
在根据GetWindowPlacement取得的信息判断。
具体用法自己找吧
=============
我试下,GetWindowPlacement这个方法不值得那个属性能判断出是否被挡住
ouhou 按照你的描述,在form的Activated事件中写代码就可以了。 public event EventHandler Activated
当使用代码激活或用户激活窗体时发生。
=====
事件那部分代码都搞定了,就是还没完成断出是否被挡住,如果挡住激活下.
现在我没判断,都去激或下,窗口闪动太多了
看窗口有没有焦点
==========================
看焦点没用的,窗口没挡住,也有可能失去焦点
请教下`GetWindowPlacement涵数返回的WINDOWPLACEMENT具体参数说明能详细说明下吗?
我全部跟踪了下,发现只能取得它的大小,或者最大话,最小话,另外没什么发现.
各位高手再帮忙看看啊,我以前做b/s比较多,winform编程不太搞,很多不熟悉.
昵称非法
等 级:
发表于:2008-01-21 00:42:5812楼 得分:0
尝试:GetForegroundWindow
===========================
应该不行,这个函数只能获取活动窗口,屏幕上能挡住别的窗口的窗口一般都不是激活窗口。
我也试过gettopwindow只能取得最顶层的窗口。都不能判断出窗口是否被挡住。
各位高手还有别的方法能判断下吗?取巧的方法也行。
小小风
等 级:
发表于:2008-01-21 09:20:2916楼 得分:0
定时刷新,将窗口为TopMost,也就是说,你失去焦点将会自动获得焦点~~~
=============================================
这个不现实,我程序里的所有窗口都有可能吸附在一起,把所有窗口设置TopMost等于没设置。
下面这段代码是VB.Net的,你可以参考一下
For Each mnu As MenuItem In mnuWindows.MenuItems
If mnu.Checked Then
MessageBox.Show(mnu.Text & "窗口是激活状态!")
Else
MessageBox.Show(mnu.Text & "窗口是非激活状态!")
End If
Next
缺点就是不能判断窗体标题栏是否也被遮挡。
参考如下代码:
bool windowPaint = false;private void Form1_Paint(object sender, PaintEventArgs e)
{
windowPaint = e.ClipRectangle.Width > 0 && e.ClipRectangle.Height > 0; // 存在刷新的区域
}
private void timer1_Tick(object sender, EventArgs e)
{
windowPaint = false;
Invalidate();
if (windowPaint)
Text = "客户区可见";
else Text = "客户区不可见";
}
没有考虑不规则窗体的情况。
参考如下代码:
using System.Runtime.InteropServices;[DllImport("user32.dll")]
public static extern bool IsWindowVisible(IntPtr hWnd);[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);[DllImport("gdi32.dll")]
public static extern int GetClipBox(IntPtr hDC, ref Rectangle lpRect);/// <summary>
/// 判断窗体是否被遮挡
/// </summary>
/// <param name="hWnd">窗体句柄</param>
/// <returns>返回窗体是否被完全遮挡</returns>
public bool WindowPall(IntPtr AHandle)
{
if (!IsWindowVisible(AHandle)) return false; // 窗体不可见
IntPtr vDC = GetWindowDC(AHandle);
try
{
Rectangle vRect = new Rectangle();
GetClipBox(vDC, ref vRect);
return vRect.Width - vRect.Left <= 0 && vRect.Height - vRect.Top <= 0;
// 特别说明:Rectangle.Width对应API中RECT.Right、Rectangle.Height为RECT.Bottom
}
finally
{
ReleaseDC(AHandle, vDC);
}
}private void timer1_Tick(object sender, EventArgs e)
{
Text = WindowPall(Handle).ToString();
}
我的愚见.. 有空帮我顶下贴.. 我也有个大困难 http://topic.csdn.net/u/20080119/13/fc2a2576-e924-4cf0-a185-e67853afab91.htmlhttp://topic.csdn.net/u/20080119/11/0d1b8aec-b349-4699-b837-fdeac8ab22a8.html
2. 用GetClientRect获取各个窗体在屏幕上的位置.
3. 检查是否有重合
4. 如果有重合, 取得重合部分中心点, 用GetWindowFromPoint, 获取重合点的top窗体, 检查是否是你的窗体, 如果不是, 说明被遮挡.
...{
Text = e.ClipRectangle.Width.ToString();
}
在窗体的Paint事件中,有一个ClipRectangle的属性,解释为“获取要在其中进行绘画的矩形”
这个属性的作用就是:窗体在刷新的时候,为提高效率一些被遮挡的区域就不用再绘制。
那么判断窗体是否被完全遮挡,只需要判断刷新时是否产生有效绘制。
bool windowPaint = false;private void Form1_Paint(object sender, PaintEventArgs e)
...{
windowPaint = e.ClipRectangle.Width > 0 && e.ClipRectangle.Height > 0; // 存在刷新的区域
}private void timer1_Tick(object sender, EventArgs e)
...{
windowPaint = false;
Invalidate();
if (windowPaint)
Text = "客户区可见";
else Text = "客户区不可见";
}根据这个思路写出如上代码。测试的结果是对客户区判断有效,对标题栏判断失效。
联想到Delphi中OnPaint中没有参数,这个刷新区域能通过Canvas.ClipRect属性获得。
分析VCL源代码
function TCanvas.GetClipRect: TRect;
begin
RequiredState([csHandleValid]);
GetClipBox(FHandle, Result);
end;
找到GetClipBox函数。
按经验GetWindowDC可以取得整个窗体的画布(包括客户区和非客户区);
这样就有了线索,二话不说动手测试吧。
---Delphi----
function WindowPall(AHandle: THandle): Boolean; // 窗体是否被遮住
var
vDC: THandle;
vRect: TRect;
begin
Result := False;
if not IsWindowVisible(AHandle) then Exit;
vDC := GetWindowDC(AHandle);
try
GetClipBox(vDC, vRect);
Result := (vRect.Right - vRect.Left <= 0) and (vRect.Bottom - vRect.Top <= 0);
finally
ReleaseDC(AHandle, vDC);
end;
end; { WindowPall }procedure TForm1.Timer1Timer(Sender: TObject);
begin
Application.Title := BoolToStr(WindowPall(Handle), True);
end;
达到理想效果。翻译成C#。
using System.Runtime.InteropServices;[DllImport("user32.dll")]
public static extern bool IsWindowVisible(IntPtr hWnd);[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);[DllImport("gdi32.dll")]
public static extern int GetClipBox(IntPtr hDC, ref Rectangle lpRect);/**//// <summary>
/// 判断窗体是否被遮挡
/// </summary>
/// <param name="hWnd">窗体句柄</param>
/// <returns>返回窗体是否被完全遮挡</returns>
public bool WindowPall(IntPtr AHandle)
...{
if (!IsWindowVisible(AHandle)) return false; // 窗体不可见
IntPtr vDC = GetWindowDC(AHandle);
try
...{
Rectangle vRect = new Rectangle();
GetClipBox(vDC, ref vRect);
return vRect.Width - vRect.Left <= 0 && vRect.Height - vRect.Top <= 0;
// 特别说明:Rectangle.Width对应API中RECT.Right、Rectangle.Height为RECT.Bottom
}
finally
...{
ReleaseDC(AHandle, vDC);
}
}private void timer1_Tick(object sender, EventArgs e)
...{
Text = WindowPall(Handle).ToString();
}这个解决方案没有考虑不规则窗体的情况,可能和GetClipRgn有关,有兴趣的朋友可以自己做做,做出来别忘记和大家分享一下。主页上的某文章下次提问先找找多好哎 orz,服了楼主
to zswang
你的方法可以判断全部遮挡,但是不能判断,部分遮挡。不过还是谢谢。to shrinerain
你的方法还没试,等晚上慢慢搞。谢谢各位还有好的方法吗?不胜感激。