// VerticalLine.cpp: implementation of the CVerticalLine class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "VerticalLine.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CVerticalLine::CVerticalLine() { m_hWnd = NULL; m_crBkgnd = RGB(255, 255, 255); m_crLineColor = RGB(222, 222, 222); m_bEnableResize = FALSE; } CVerticalLine::~CVerticalLine() { } BOOL CVerticalLine::RegisterWndClass() { WNDCLASS wc; wc.lpszClassName = BYVERTICALLINE_CLASS; wc.hInstance = AfxGetInstanceHandle(); wc.lpfnWndProc = WindowProc; wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); wc.hIcon = 0; wc.lpszMenuName = NULL; wc.hbrBackground = NULL; wc.style = CS_GLOBALCLASS|CS_DBLCLKS; wc.cbClsExtra = 0; wc.cbWndExtra = 0; // ×¢²á×Ô¶¨ÒåÀà return (::RegisterClass(&wc) != 0); } CVerticalLine* CVerticalLine::Hook(HWND hWnd) { CVerticalLine* pVerticalLine = (CVerticalLine*)GetProp(hWnd, BYSTAG_VERTICALLINE); if(pVerticalLine == NULL) { pVerticalLine = new CVerticalLine; pVerticalLine->m_hWnd = hWnd; SetProp(hWnd, BYSTAG_VERTICALLINE, (HANDLE)pVerticalLine); } return pVerticalLine; } void CVerticalLine::Release() { // delete delete this; } void CVerticalLine::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/) { HWND hParent; hParent = GetParent(m_hWnd); if(hParent != NULL) { BYVERTICALLINE_NMHDR iii_nmhdr; iii_nmhdr.nmhdr.hwndFrom = m_hWnd; iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID); iii_nmhdr.nmhdr.code = nCode; iii_nmhdr.dwData = dwData; iii_nmhdr.dwData1 = dwData1; iii_nmhdr.dwData2 = dwData2; SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr); } } //////////////////////////////// // À¹½Ø´°¿ÚÏûÏ¢º¯Êý LRESULT CALLBACK CVerticalLine::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CVerticalLine* pVerticalLine = (CVerticalLine *)GetProp(hWnd, BYSTAG_VERTICALLINE); if(pVerticalLine == NULL && uMsg != WM_NCCREATE) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } // Èç¹ûHookÔòÏìÓ¦ÏûÏ¢ ASSERT(hWnd); switch(uMsg) { case WM_NCCREATE: return OnNcCreate(hWnd, wParam, lParam); case WM_DESTROY: return pVerticalLine->OnDestroy(wParam, lParam); case WM_PAINT: return pVerticalLine->OnPaint(wParam, lParam); case WM_TIMER: return pVerticalLine->OnTimer(wParam, lParam); case WM_SETCURSOR: return pVerticalLine->OnSetCursor(wParam, lParam); case WM_LBUTTONDOWN: return pVerticalLine->OnLButtonDown(wParam, lParam); case WM_GETDLGCODE: return DLGC_WANTALLKEYS; default: break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } /////////////////////////////// // WM_NCCREATE // ´°¿Ú´´½¨Ç°µÄ³õʼ»¯¹¤×÷ LRESULT CVerticalLine::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) { CVerticalLine* pVerticalLine = (CVerticalLine *)GetProp(hWnd, BYSTAG_VERTICALLINE); ASSERT(pVerticalLine == NULL); Hook(hWnd); return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam); } /////////////////////////////// // WM_DESTROY LRESULT CVerticalLine::OnDestroy(WPARAM wParam, LPARAM lParam) { Release(); return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam); } /////////////////////////////// // WM_TIMER LRESULT CVerticalLine::OnTimer(WPARAM wParam, LPARAM lParam) { return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam); } /////////////////////////////// // WM_SETCURSOR LRESULT CVerticalLine::OnSetCursor(WPARAM wParam, LPARAM lParam) { if(m_bEnableResize) { SetCursor(::LoadCursor(NULL, IDC_SIZEWE)); return TRUE; } return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam); } /* * WM_LBUTTONDOWN * Êó±ê×ó¼ü°´Ï */ LRESULT CVerticalLine::OnLButtonDown(WPARAM wParam, LPARAM lParam) { if (!m_bEnableResize) { return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); } POINT pt, ptNew; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); int nMoveX = 0; // ²¶×½Êó±êÏûÏ¢£¬¼ì²âÊÇ·ñÍ϶¯ RECT rcParent, rcWindows; GetClientRect(m_hWnd, &rcWindows); ::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows); ::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows.right); GetClientRect(GetParent(m_hWnd), &rcParent); ::ClientToScreen(GetParent(m_hWnd), (LPPOINT)&rcParent); HDC hDC = GetDC(GetDesktopWindow()); ::DrawFocusRect(hDC, &rcWindows); if (::GetCapture() == NULL) { SetCapture(m_hWnd); ASSERT(m_hWnd == GetCapture()); AfxLockTempMaps(); for (;;) { MSG msg; VERIFY(::GetMessage(&msg, NULL, 0, 0)); if (GetCapture() != m_hWnd) break; switch (msg.message) { case WM_MOUSEMOVE: ptNew = msg.pt; if (ptNew.x < rcParent.left) ptNew.x = rcParent.left; ::DrawFocusRect(hDC, &rcWindows); rcWindows.left = ptNew.x - 3; rcWindows.right = ptNew.x + 3; ::DrawFocusRect(hDC, &rcWindows); ::ScreenToClient(m_hWnd, &ptNew); break; case WM_LBUTTONUP: ptNew = msg.pt; ::ScreenToClient(m_hWnd, &ptNew); nMoveX = ptNew.x - pt.x; goto ExitLoop; case WM_KEYDOWN: if (msg.wParam == VK_ESCAPE) { goto ExitLoop; } break; default: DispatchMessage(&msg); break; } } ExitLoop: ::DrawFocusRect(hDC, &rcWindows); ReleaseDC(GetDesktopWindow(), hDC); ReleaseCapture(); ::InvalidateRect(m_hWnd, NULL, TRUE); Notify((int)BYVERTICALLINE_MOVEX, nMoveX); AfxUnlockTempMaps(FALSE); } return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); } /////////////////////////////// // WM_PAINT LRESULT CVerticalLine::OnPaint(WPARAM wParam, LPARAM lParam) { HDC hDC, hMemDC; HBITMAP hBitmap; RECT rcClient; CString strText; HFONT hFont; HBRUSH hBrushBK; // BeginPaint PAINTSTRUCT ps; hDC = BeginPaint(m_hWnd, &ps); GetClientRect(m_hWnd, &rcClient); hMemDC = ::CreateCompatibleDC(hDC); hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); ::SelectObject(hMemDC, hBitmap); hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); ::SelectObject(hMemDC, hFont); // ±³¾°ÑÕÉ« hBrushBK = CreateSolidBrush( m_crBkgnd ); ::FillRect(hMemDC, &rcClient, hBrushBK); DeleteObject(hBrushBK); // »­Ïß HPEN hPen = CreatePen(PS_SOLID, 1, m_crLineColor); HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPen); ::MoveToEx(hMemDC, rcClient.right-1, 0, NULL); LineTo(hMemDC, rcClient.right - 1, rcClient.bottom); ::SelectObject(hMemDC, hOldPen); // EndPaint ::BitBlt(hDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hMemDC, 0, 0, SRCCOPY); EndPaint(m_hWnd, &ps); ::DeleteObject(hBitmap); ::DeleteDC(hMemDC); return 1; } void CVerticalLine::SetBkgndColor(COLORREF cr) { m_crBkgnd = cr; } void CVerticalLine::EnableResize() { m_bEnableResize = TRUE; } void CVerticalLine::DisableResize() { m_bEnableResize = FALSE; }