移动窗口并调整底部闪烁

时间:2015-10-19 16:51:34

标签: c++ c winapi

我正在尝试创建一种滑出任务栏的弹出通知窗口。

目前,如果任务栏位于屏幕底部,我只是试图让它工作,我让它按照应有的方式工作。

但问题是,当窗口开始出现/滑动时,它的底部闪烁(取决于我设置m_nIncrement值的大小,它闪烁的底部区域大小与m_nIncrement值) 窗口消失得很好,没有闪烁。

//MyWindow
WNDCLASS wc =
{
    CS_HREDRAW | CS_VREDRAW, __sWndProcDlg, 0, 0, g_hInst, nullptr,
    LoadCursor(nullptr, IDC_ARROW), (HBRUSH)::GetStockObject(BLACK_BRUSH),
    nullptr, m_lpszClassName
};

if (!RegisterClass(&wc))
    return;

m_hWnd = CreateWindowEx(WS_EX_NOACTIVATE, m_lpszClassName, NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, m_hWndParent, NULL, g_hInst, NULL);

//ShowWindow
void _ShowWindow(int _show)
{
    unsigned int nDesktopWidth = m_rcDesktop.right - m_rcDesktop.left;
    unsigned int nDesktopHeight = m_rcDesktop.bottom - m_rcDesktop.top;
    unsigned int nScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
    unsigned int nScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);

    BOOL bTaskbarOnRight = nDesktopWidth<nScreenWidth && m_rcDesktop.left == 0;
    BOOL bTaskbarOnLeft = nDesktopWidth<nScreenWidth && m_rcDesktop.left != 0;
    BOOL bTaskBarOnTop = nDesktopHeight<nScreenHeight && m_rcDesktop.top != 0;
    BOOL bTaskbarOnBottom = nDesktopHeight<nScreenHeight && m_rcDesktop.top == 0;

    if (_show)
    {
        ShowWindow(m_hWnd, SW_SHOW);

        if (bTaskbarOnBottom)
        {
            m_nCurrentPos.cx = m_rcDesktop.right - m_sMaxSize.cx;
            m_nCurrentPos.cy = m_rcDesktop.bottom - m_nCurrentSize.cy;
            m_nTaskbarPlacement = TASKBAR_ON_BOTTOM;
        }


        KillTimer(m_hWnd, IDT_DISAPPEARING);
        SetTimer(m_hWnd, IDT_APPEARING, 1, nullptr);
    }
    else
    {
        KillTimer(m_hWnd, IDT_APPEARING);

        if (bTaskbarOnRight)
            m_nCurrentPos.cx = m_rcDesktop.right - m_sMaxSize.cx;
        else if (bTaskbarOnLeft)
            m_nCurrentPos.cx = m_rcDesktop.left;
        else if (bTaskBarOnTop)
            m_nCurrentPos.cy = m_rcDesktop.top;
        else //if (bTaskbarOnBottom)
            m_nCurrentPos.cy = m_rcDesktop.bottom - m_nCurrentSize.cy;

        SetTimer(m_hWnd, IDT_DISAPPEARING, 1, NULL);
    }
}

//__OnTimer
LRESULT __OnTimer(HWND hWnd, UINT nIDEvent)
{
    int m_nIncrement = 20;
    if (nIDEvent == IDT_APPEARING)
    {
        switch (m_nTaskbarPlacement)
        {
        case TASKBAR_ON_BOTTOM:
            if (m_nCurrentPos.cy > (m_rcDesktop.bottom - m_sMaxSize.cy))
            {
                m_nCurrentPos.cy -= m_nIncrement;
                m_nCurrentSize.cy = m_rcDesktop.bottom - m_nCurrentPos.cy;
            }
            else
                KillTimer(hWnd, IDT_APPEARING);

            break;
        }

        SetFocus(hWnd);
        SetWindowPos(hWnd, HWND_TOPMOST, m_nCurrentPos.cx, m_nCurrentPos.cy, m_sMaxSize.cx, m_nCurrentSize.cy, SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);

    }
    else if (nIDEvent == IDT_DISAPPEARING)
    {
        switch (m_nTaskbarPlacement)
        {
        case TASKBAR_ON_BOTTOM:
            if (m_nCurrentPos.cy < m_rcDesktop.bottom)
            {
                m_nCurrentPos.cy += m_nIncrement;
                m_nCurrentSize.cy = m_rcDesktop.bottom - m_nCurrentPos.cy;
            }
            else
            {
                KillTimer(hWnd, IDT_DISAPPEARING);
                MoveWindow(m_hWnd, 0, 0, 0, 0, FALSE);
                ShowWindow(m_hWnd, SW_HIDE);
            }
            break;
        }

        SetWindowPos(hWnd, HWND_TOPMOST, m_nCurrentPos.cx, m_nCurrentPos.cy, m_sMaxSize.cx, m_nCurrentSize.cy, SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);
    }

    return true;
}

1 个答案:

答案 0 :(得分:1)

使用AnimateWindow代替。它很容易使用。你可能需要处理WM_PRINT,这也很简单。

如果您想继续处理代码,那么:

1)从弹出类中删除标志CS_HREDRAW&amp; CS_VREDRAW

2)处理WM_ERASEBACKGROUND

最后。如果是弹出窗口,请不要调用SetFocus();也许你必须将zorder设置为TOP_MOST

祝你好运