您的位置:首页 > 其它

windows开发常见问题系列--1 窗口显示相关

2014-05-22 21:49 357 查看
窗口置顶问题:

对于一个非模态的对话框,ATL 、或者WTL 等窗口显示时不能置顶显示。主要表现为显示时不置顶或者被其他窗口盖住。

通常设置置顶窗口的的方法为:SetWindowPos(HWND_TOPMOST, 0 , 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);

SetWindowPos()只是做一个标记,调用一次即可。

如下代码可以解决问题:通常在窗口show()之后调用。

HWND hForeWnd = ::GetForegroundWindow();
DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd,NULL);
DWORD dwCurID = ::GetCurrentThreadId();
::AttachThreadInput(dwCurID,dwForeID,TRUE);
::ShowWindow(hWnd,SW_SHOWNORMAL);
::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
::SetForegroundWindow(hWnd);
::AttachThreadInput(dwCurID,dwForeID,FALSE);

右下角弹窗:

很多软件有需要弹窗的场景,弹窗提示升级更新,弹窗广告,天窗提示天气,,,推广等等,如今的世界人类已经无法阻止泡泡了。

弹窗的位置计算方法:

获得桌面可是区域:

void _GetWorkAreaVisibleRect(OUT CRect& rcArea)
{
RECT rc;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);

int nXScreen = 0;
int nYScreen = 0;
nXScreen = ::GetSystemMetrics(SM_CXSCREEN);
nYScreen = ::GetSystemMetrics(SM_CYSCREEN);

rcArea= CRect(rc);

//>自动隐藏任务栏
if (rcArea.Width() == nXScreen && rcArea.Height() == nYScreen)
{
RECT rcShell;
HWND hwndTray = NULL;
hwndTray = ::FindWindow(_T("Shell_TrayWnd"), NULL);

if (hwndTray)
{
::GetWindowRect(hwndTray, &rcShell);
CRect rcTray = CRect(rcShell);

if (nXScreen == rcTray.Width())
{
if (rcTray.bottom > nYScreen/2) ///>下
{
rcArea.bottom -= rcTray.Height();
}
else  ///>上
{
rcArea.top += rcTray.Height();
}
}
else  ///>左右
{
if (rcTray.left < nXScreen/2) //>左
{
rcArea.left += rcTray.Width();
}
else
{
rcArea.right -= rcTray.Width();
}
}
}
}
}


移动窗口位置函数:

void  _AdjustPanelPos()
{
CRect rc;
_GetWorkAreaVisibleRect(rc);

CRect rcWin;
GetWindowRect(rcWin);

int nPos = 0;
if (rc.bottom < m_ptPopPos.y) ///>底部
{
rcWin.MoveToX(m_ptPopPos.x - rcWin.Width() / 2);
rcWin.MoveToY(rc.bottom - rcWin.Height());
nPos = 1;
}
else if (rc.right < m_ptPopPos.x) ///>右边
{
rcWin.MoveToX(rc.right - rcWin.Width());
rcWin.MoveToY(rc.bottom - rcWin.Height());
nPos = 2;
}
else if (rc.top > m_ptPopPos.y) ///>上边
{
rcWin.MoveToX(m_ptPopPos.x - rcWin.Width() / 2);
rcWin.MoveToY(rc.top);
}
else ///>左边
{
rcWin.MoveToX(rc.left);
rcWin.MoveToY(rc.bottom - rcWin.Height());
nPos = 3;
}

if (rcWin.left < rc.left)
rcWin.OffsetRect(rc.left - rcWin.left, 0);

if (rcWin.top < rc.top)
rcWin.OffsetRect(0, rc.top - rcWin.top);

if (rcWin.right > rc.right)
rcWin.OffsetRect(rc.right - rcWin.right, 0);

if (rcWin.bottom > rc.bottom)
rcWin.OffsetRect(0, rc.bottom - rcWin.bottom);

CPoint ptLT = CPoint(rcWin.left, rcWin.top);
::MoveWindow(m_hWnd, ptLT.x, ptLT.y, rcWin.Width(), rcWin.Height(), FALSE);
}
使用方法:

void Show()
{
_AdjustPopPos();
SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
ShowWindow(SW_SHOWNA);

}


我想一个有良心的泡泡应该是不抢焦点的,不然影响用户输入或者正在玩游戏或者手正忙着。所以用了 SW_SHOWNA SWP_NOACTIVATE
这些参数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐