// 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::SetLineColor(COLORREF cr)
|
{
|
m_crLineColor = cr;
|
}
|
|
void CVerticalLine::EnableResize()
|
{
|
m_bEnableResize = TRUE;
|
}
|
|
void CVerticalLine::DisableResize()
|
{
|
m_bEnableResize = FALSE;
|
}
|