如何判断一个窗口已经完全隐藏

饿半肚 2012-02-01 06:23:04
大家新年快乐!恭喜发财!

本人在做一个截图工具,需要在点击“截图”按钮后,先隐藏对话框,再全屏截图。但是现在问题是ShowWindow(SW_HIDE)执行之后,对话框并不是马上就隐藏得干干净净的,所以ShowWindow(SW_HIDE)之后马上截屏还是会把对话框截下来了。请问怎样判断一个窗口是否已经圆满地隐藏完成了?

不想通过Sleep()或者Timer这样的等待几百毫秒的办法去解决,希望能通过更常规更稳妥的办法解决。谢谢大家!
...全文
332 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
笨笨D幸福 2014-04-16
  • 打赏
  • 举报
回复
showWindow(SW_HIDE); 并不是说你调用了就会立马将窗口隐藏,这个函数发送一个消息到消息循环中,然后窗口接到消息才会隐藏,这个过程需要一定的时间和消息循环。你在程序中直接调用后就进行截图,肯定不行。 建议:可以showWindow(SW_HIDE);之后PostMessage一个自定义消息,在自定义消息里处理截图功能。甚至可以通过SendMessage隐藏窗口,通过PostMessage自定义消息截图,这样就可以留给CPU足够的时间用以隐藏和刷新,同时截图的时间也会很恰当。
aaseh 2012-02-04
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 lactoferrin 的回复:]

用PrintWindow可以让一个窗口把它的样子画到一个dc,被遮住的部位也有
因此你可以枚举可见的窗口,分别PrintWindow,然后按照z-order覆盖,这就有点像自己来做桌面组合
[/Quote]
up
zgszft 2012-02-04
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 lactoferrin 的回复:]

如果没有开桌面组合,被你的窗口覆盖的窗口重绘不及时,是没法判断的
[/Quote]
楼主什么操作系统?Windows 7还是什么
Lactoferrin 2012-02-03
  • 打赏
  • 举报
回复
用PrintWindow可以让一个窗口把它的样子画到一个dc,被遮住的部位也有
因此你可以枚举可见的窗口,分别PrintWindow,然后按照z-order覆盖,这就有点像自己来做桌面组合
饿半肚 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 lactoferrin 的回复:]

如果没有开桌面组合,被你的窗口覆盖的窗口重绘不及时,是没法判断的
[/Quote]

个人比较倾向这个答案。
HOUXIAN 2012-02-03
  • 打赏
  • 举报
回复
那这个问题无解??
schlafenhamster 2012-02-03
  • 打赏
  • 举报
回复
每次点“按钮”(不是OK,专门一个)后,打开“aa.bmp”,每次都正常。
方便的话,把程序发到你的资源,大家看看。
wyx100 2012-02-03
  • 打赏
  • 举报
回复
IsWindowVisible()
Lactoferrin 2012-02-03
  • 打赏
  • 举报
回复
如果没有开桌面组合,被你的窗口覆盖的窗口重绘不及时,是没法判断的
schlafenhamster 2012-02-03
  • 打赏
  • 举报
回复
我的工程没什么新鲜的就是一个对话框加一个按钮:
代码就是你贴上的代码:
// 截图:
void CCbDlg::OnButton2()
{
// TODO: Add your control notification handler code here
ShowWindow(SW_HIDE);
//
char str[200];
CPoint point=GetCursorPos(&point);
HWND next=::WindowFromPoint(point);
::GetWindowText(next,str,200);
afxDump << str << "\n";
if(next == *this)
{
afxDump << "Not Hiden!\n";// 没出现过
}
else
{
afxDump << "Hiden!\n";
}
//
int cxScreen=GetSystemMetrics(SM_CXSCREEN);
int cyScreen=GetSystemMetrics(SM_CYSCREEN);

HDC winDc=::GetDC(NULL);

CDC menDC;
menDC.CreateCompatibleDC(CDC::FromHandle(winDc));

CBitmap membitmap;
membitmap.CreateCompatibleBitmap(CDC::FromHandle(winDc),cxScreen,cyScreen);// 创建一个与屏幕设备描述表兼容的位图
menDC.SelectObject(membitmap);
menDC.BitBlt(0,0,cxScreen,cyScreen, CDC::FromHandle(winDc),0,0,SRCCOPY);
::ReleaseDC(NULL,winDc);


BITMAP bmp;
membitmap.GetBitmap(&bmp);//获得位图信息
DWORD bmpBytesSize = bmp.bmWidthBytes * bmp.bmHeight;
BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmpBytesSize ;//文件总的大小
bfh.bfType = (WORD)0x4d42;

BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmpBytesSize;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度

BYTE * p = new byte[bmpBytesSize];//申请内存保存位图数据
GetDIBits(menDC.m_hDC ,
(HBITMAP) membitmap.m_hObject, 0, cyScreen,
p,(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

try
{
CFile fp(_T("aa.bmp"),CFile::modeCreate | CFile::modeWrite);
fp.Write(&bfh, sizeof(BITMAPFILEHEADER));//写入位图文件头
fp.Write(&bih, sizeof(BITMAPINFOHEADER));//写入位图信息头
fp.Write(p, bmp.bmWidthBytes * bmp.bmHeight);//写入位图数据
fp.Close();
}
catch( CFileException * e )
{

e->Delete();
}

delete []p;

menDC.DeleteDC();
membitmap.DeleteObject();
ShowWindow(SW_SHOW);// 我加了一句
}
thinp 2012-02-03
  • 打赏
  • 举报
回复
在WM_SHOWWINDOW中处理截屏,调完 ShowWindow(SW_HIDE);后,会产生一个WM_SHOWWINDOW消息,不过注意在ShowWindow(SW_HIDE);之前设计一个变量,是否需要截屏,如果没这个变量,省得一隐藏就给截屏了,你可以试一下,我没编码试过,不过应该是可以实现的
饿半肚 2012-02-03
  • 打赏
  • 举报
回复
schlafenhamster,能否把你的工程发到我邮箱?谢谢! 373059952@qq.com
SKy_kid 2012-02-03
  • 打赏
  • 举报
回复
e..在OnShowWindow里判断也不靠谱,偷懒的话还是settimer吧= =||。
SKy_kid 2012-02-03
  • 打赏
  • 举报
回复
响应 WM_SHOWWINDOW试试。
schlafenhamster 2012-02-03
  • 打赏
  • 举报
回复
给一段代码,不一定管用:
ShowWindow(SW_HIDE);//
// no paint msg
CPoint point=GetCursorPos(&point);// at 'OK'
HWND next=::WindowFromPoint(point);//
if(next == *this)
{//
afxDump << "Not Hiden!\n";
}
else
{
afxDump << "Hiden!\n";
}
...
chunyou128 2012-02-02
  • 打赏
  • 举报
回复
IsWindowVisible()
hdg3707 2012-02-02
  • 打赏
  • 举报
回复
可以试试把对话框的尺寸改变成最小,再隐藏,也就是把对话框的尺寸变成一个近似点并移到右下角或其它边上,然后再隐藏,好象是用MoveWindow函数
schlafenhamster 2012-02-02
  • 打赏
  • 举报
回复
在VC6上测试正常,没问题!
诶呦 2012-02-02
  • 打赏
  • 举报
回复
ShowWindow()返回值是BOOL值,能不能通过判断它的返回值来实现?
不行的话就用Sleep()或者1楼的方法。
SuperLy 2012-02-02
  • 打赏
  • 举报
回复
看来,消息和实际窗体状态有延迟的,如果IsWindowVisible()都不行,那最简单的方法还是Sleep();吧
加载更多回复(16)

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧