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

窗口置顶问题:

        对于一个非模态的对话框,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 这些参数。


     

        

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值