判断一个窗体是否被完全遮挡
来源:互联网 发布:改造房子 知乎 编辑:程序博客网 时间:2024/05/08 15:28
private void Form1_Paint(object sender, PaintEventArgs e)
{
Text = e.ClipRectangle.Width.ToString();
}
{
Text = e.ClipRectangle.Width.ToString();
}
这个属性的作用就是:窗体在刷新的时候,为提高效率一些被遮挡的区域就不用再绘制。
那么判断窗体是否被完全遮挡,只需要判断刷新时是否产生有效绘制。
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 = "客户区不可见";
}
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();
}
[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有关,有兴趣的朋友可以自己做做,做出来别忘记和大家分享一下。
- 判断一个窗体是否被完全遮挡
- 判断窗口是否被完全遮挡的方法
- android 判断view 是否被遮挡
- Android 判断view是否被遮挡
- Android 判断View是否被遮挡
- 判断一个窗体是否已经打开
- hdu 2540 遮挡判断 判断有多少根柱子的投影没有被完全遮挡
- 判断一个Iframe是否完全加载
- 判断一个数是否是完全数
- VC中判断指定窗口是否被其他窗口遮挡
- Android多层级判断view是否被遮挡
- 判断窗体是否关闭
- 判断窗体是否打开
- 判断是否完全相等
- 如何判断一个数是否是完全平方数
- 判断一个数组是否为单一完全循环数组
- 判断一个二叉树是否是完全二叉树
- 判断一个二叉树是否是完全二叉树
- Rafal Olbinski魔幻作品
- 冒泡排序算法
- [转]《范府大院》让韩国人有理由瞧不起中国
- abap编程的一些例子 将数据选择至内表(多行)
- 好来坞明星 Hollywood
- 判断一个窗体是否被完全遮挡
- 乌克兰前美女总理·季莫申科
- Hibernate 中的 QBC
- Britney Spears poses nude for Harper's Bazaar
- php防盗链的方法
- Creative photo
- “华人首富”:李嘉诚一生的前前后后
- “超人”李嘉诚内地最赚钱的项目泄露
- 构造函数