移动窗口并调整底部闪烁的大小

问题描述:

我试图制作一种弹出通知窗口,滑出任务栏。移动窗口并调整底部闪烁的大小

目前我只是试图让它工作,如果任务栏在屏幕的底部,我让它工作就像它应该。

但遇到的问题IM是当窗口开始出现/滑动它的底部忽明忽暗(取决于有多大我已经把我的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; 
} 
+0

你应该列出你正在编程的API在标签中。 – nobar

+0

@nobar - 你认为不存在的是什么?它使用WinApi--还有什么合理的预期? (你不需要像使用X11那样定位一堆库中的一个,这个功能就在user32.dll和comctrl32.dll中 - 这两个部分都是WinApi) – enhzflep

+0

你的代码是不可读的。你能否更好地格式化它。 –

改为使用AnimateWindow。它很容易使用。你可能需要处理WM_PRINT,这也可以直接退出。

如果有的话,你想保持你的代码的工作,然后

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

2)处理WM_ERASEBACKGROUND

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

祝你好运

+0

'AnimateWindow'是一个很好的(更好的)建议,其余的观点也回答了提出的问题。每个都值得奖励。 – enhzflep

+0

哦,哇,我不知道AnimateWindow。只是一个简单的问题,我如何让我的文本保持在WM_PAINT中,以便在动画中显示? – mutotu

+0

使用WM_PAINT事件。当你在WM_DRAW上绘图时。没有调用BeginPaint&EndPaint.cast WPARAM获得hdc – milevyo