본문 바로가기
C & C++/MFC 컨트롤

다이얼로그 자석 효과

by izen8 2011. 12. 14.
반응형

다이얼로그의 클래스 위자드에서 OnWindowPosChanging 함수를 추가합니다.

그 다음 아래와 같이 코드를 작성합니다.

void 다이얼로그명::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
   CDialog::OnWindowPosChanging(lpwndpos);

   CRect rect;

   GetWindowRect ( &rect);

   int cx = GetSystemMetrics(SM_CXSCREEN);
   int cy = GetSystemMetrics(SM_CYSCREEN);

   // 바탕화면의 경계에서의 자석효과

   if ((lpwndpos->x > 0) && (lpwndpos->x <= 20))
      lpwndpos->x = 0;

   if ((lpwndpos->y > 0) && (lpwndpos->y <= 20))
      lpwndpos->y = 0;

   if ((lpwndpos->x + rect.Width() >= cx-20) && (lpwndpos->x + rect.Width() < cx))
      lpwndpos->x = cx - rect.Width();

   if ((lpwndpos->y + rect.Height() >= cy-20) && (lpwndpos->y + rect.Height() < cy))
      lpwndpos->y = cy - rect.Height();
}


* 숫자를 적게 하면 바탕화면의 자석효과 거리가 쫍아지고 크게하면 자석효과가 일어나는 거리가 커집니다.


Winamp 에서 보면 프로그램이 움직이다가 벽에 달라 붙죠? 그걸 구현해 보도록 하겠습니다. 

2.본문 
윈도우가 움직일때 메세지가 발생합니다. WM_WINDOWPOSCHANGING 이라는 메세지가 발생하죠. 이때 발생하는 메세지에서 윈도우의 위치를 비교해서 적당한 Offset 에 걸렸을때 윈도우를 강제로 옮겨 주면 됩니다.
아래의 소스를 참고하세요. 

3.예제 

// m_nYOffset 과 m_nXOffset 값을 바꾸어 주시면 됩니다. void CSnapDialog::OnWindowPosChanging( WINDOWPOS* lpwndpos ) { CRect wndRect, trayRect; int leftTaskbar = 0, rightTaskbar = 0, topTaskbar = 0, bottomTaskbar = 0; GetWindowRect(&wndRect); // Screen resolution int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN); // Find the taskbar CWnd* pWnd = FindWindow(_T("Shell_TrayWnd"), _T("")); pWnd->GetWindowRect(&trayRect); int wndWidth = wndRect.right - wndRect.left; int wndHeight = wndRect.bottom - wndRect.top; if(trayRect.top <= 0 && trayRect.left <= 0 && trayRect.right >= screenWidth) { // top taskbar topTaskbar = trayRect.bottom - trayRect.top; } else if(trayRect.top > 0 && trayRect.left <= 0) { // bottom taskbar bottomTaskbar = trayRect.bottom - trayRect.top; } else if(trayRect.top <= 0 && trayRect.left > 0) { // right taskbar rightTaskbar = trayRect.right - trayRect.left; } else { // left taskbar leftTaskbar = trayRect.right - trayRect.left; } // Snap to screen border // Left border if(lpwndpos->x >= -m_nXOffset + leftTaskbar && lpwndpos->x <= leftTaskbar + m_nXOffset) { lpwndpos->x = leftTaskbar; } // Top border if(lpwndpos->y >= -m_nYOffset && lpwndpos->y <= topTaskbar + m_nYOffset) { lpwndpos->y = topTaskbar; } // Right border if(lpwndpos->x + wndWidth <= screenWidth - rightTaskbar + m_nXOffset && lpwndpos->x + wndWidth >= screenWidth - rightTaskbar - m_nXOffset) { lpwndpos->x = screenWidth - rightTaskbar - wndWidth; } // Bottom border if( lpwndpos->y + wndHeight <= screenHeight - bottomTaskbar + m_nYOffset && lpwndpos->y + wndHeight >= screenHeight - bottomTaskbar - m_nYOffset) { lpwndpos->y = screenHeight - bottomTaskbar - wndHeight; } }



반응형

댓글