⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gripper.cpp

📁 Notepad++ is a generic source code editor (it tries to be anyway) and Notepad replacement written in
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of docking functionality for Notepad++
//Copyright (C)2006 Jens Lorenz <jens.plugin.npp@gmx.de>
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


#include "dockingResource.h"
#include "math.h"
#include "Docking.h"
#include "Gripper.h"

#ifndef WH_KEYBOARD_LL
#define WH_KEYBOARD_LL 13
#endif

#ifndef WH_MOUSE_LL
#define WH_MOUSE_LL 14
#endif


BOOL Gripper::_isRegistered	= FALSE;

static HWND		hWndServer		= NULL;
static HHOOK	hookMouse		= NULL;
static HHOOK	hookKeyboard	= NULL;

static LRESULT CALLBACK hookProcMouse(INT nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
		switch (wParam)
		{
			case WM_MOUSEMOVE:
			case WM_NCMOUSEMOVE:
				//::PostMessage(hWndServer, wParam, 0, 0);
				::SendMessage(hWndServer, wParam, 0, 0);
				break;
			case WM_LBUTTONUP:
			case WM_NCLBUTTONUP:
				//::PostMessage(hWndServer, wParam, 0, 0);
				::SendMessage(hWndServer, wParam, 0, 0);
				return TRUE;
			default: 
				break;
		}
	}
	return ::CallNextHookEx(hookMouse, nCode, wParam, lParam);
}

static LRESULT CALLBACK hookProcKeyboard(INT nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
		if (wParam == VK_ESCAPE)
		{
			::PostMessage(hWndServer, DMM_CANCEL_MOVE, 0, 0);
			return FALSE;
		}
	}

	return ::CallNextHookEx(hookKeyboard, nCode, wParam, lParam);
}

Gripper::Gripper(void)
{
	_hInst				= NULL;
	_hParent			= NULL;
	_hSelf				= NULL;

	_pDockMgr			= NULL;
	_pCont				= NULL;

	_ptOffset.x			= 0;
	_ptOffset.y			= 0;

	_ptOld.x			= 0;
	_ptOld.y			= 0;
	_bPtOldValid		= FALSE;

	_hTab				= NULL;
	_hTabSource			= NULL;
	_startMovingFromTab	= FALSE;
	_iItem				= 0;

	_hdc				= NULL;
	_hbm				= NULL;
	_hbrush				= NULL;


	memset(&_rcItem, 0, sizeof(RECT));
	memset(&_tcItem, 0, sizeof(TCITEM));
	memset(&_dockData, 0, sizeof(tDockMgr));
}


void Gripper::startGrip(DockingCont* pCont, DockingManager* pDockMgr, void* pRes)
{
	MSG			msg		= {0};
	BOOL		bIsRel  = FALSE;
	HWND		hWnd	= NULL;

	_pDockMgr   = pDockMgr;
	_pCont		= pCont;
	_pRes		= pRes;

	_pDockMgr->getDockInfo(&_dockData);

	if (!_isRegistered)
	{
		WNDCLASS clz;

		clz.style = 0;
		clz.lpfnWndProc = staticWinProc;
		clz.cbClsExtra = 0;
		clz.cbWndExtra = 0;
		clz.hInstance = _hInst;
		clz.hIcon = NULL;
		clz.hCursor = NULL;

		clz.hbrBackground = NULL; 
		clz.lpszMenuName = NULL;
		clz.lpszClassName = MDLG_CLASS_NAME;

		if (!::RegisterClass(&clz))
		{
			systemMessage("System Err");
			throw int(98);
		}
		_isRegistered = TRUE;
	}

	_hSelf = ::CreateWindowEx(
					0,
					MDLG_CLASS_NAME,
					"", 0,
					CW_USEDEFAULT, CW_USEDEFAULT,
					CW_USEDEFAULT, CW_USEDEFAULT,
					NULL,
					NULL,
					_hInst,
					(LPVOID)this);
	hWndServer = _hSelf;

	if (!_hSelf)
	{
		systemMessage("System Err");
		throw int(777);
	}
}


LRESULT CALLBACK Gripper::staticWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	Gripper *pDlgMoving = NULL;
	switch (message)
	{	
		case WM_NCCREATE :
			pDlgMoving = (Gripper *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
			pDlgMoving->_hSelf = hwnd;
			::SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<LONG>(pDlgMoving));
			return TRUE;

		default :
			pDlgMoving = (Gripper *)::GetWindowLong(hwnd, GWL_USERDATA);
			if (!pDlgMoving)
				return ::DefWindowProc(hwnd, message, wParam, lParam);
			return pDlgMoving->runProc(message, wParam, lParam);
	}
}

LRESULT Gripper::runProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_CREATE:
		{
			create();
			break;
		}
		case WM_MOUSEMOVE:
		case WM_NCMOUSEMOVE:
		{
			onMove();
			return TRUE;
		}
		case WM_LBUTTONUP:
		case WM_NCLBUTTONUP:
		{
			/* end hooking */
			if (hookMouse)
			{
				::UnhookWindowsHookEx(hookMouse);
				::UnhookWindowsHookEx(hookKeyboard);
				hookMouse = NULL;
				hookKeyboard = NULL;
			}

			onButtonUp();

			::DestroyWindow(_hSelf);
			return TRUE;
		}
		case DMM_CANCEL_MOVE:
		{
			POINT			pt			= {0,0};
			POINT			ptBuf		= {0,0};
			RECT			rc			= {0};

			::GetCursorPos(&pt);
			getMousePoints(&pt, &ptBuf);

			/* erase last drawn rectangle */
			drawRectangle(ptBuf);

			/* end hooking */
			::UnhookWindowsHookEx(hookMouse);
			::UnhookWindowsHookEx(hookKeyboard);

			::DestroyWindow(_hSelf);
			return FALSE;
		}
		case WM_DESTROY:
		{
			mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
			::SetWindowPos(_hParent, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
			_pCont->focusClient();
			delete _pRes;
			break;
		}
		default:
			break;
	}

	return ::DefWindowProc(_hSelf, message, wParam, lParam);
}

 
void Gripper::create(void)
{
	RECT		rc		= {0};
	POINT		pt		= {0};

	/* start hooking */
	::SetWindowPos(_pCont->getHSelf(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
	::SetCapture(_hSelf);

	if (GetVersion() & 0x80000000)
	{
		hookMouse	= ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)hookProcMouse, _hInst, 0);
	}
	else
	{
		hookMouse	= ::SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)hookProcMouse, _hInst, 0);
	}

    if (!hookMouse)
    {
        DWORD dwError = ::GetLastError();
        TCHAR  str[128];
        ::wsprintf(str, "GetLastError() returned %lu", dwError);
        ::MessageBox(NULL, str, "SetWindowsHookEx(MOUSE) failed", MB_OK | MB_ICONERROR);
    }

	winVer winVersion = (winVer)::SendMessage(_hParent, NPPM_GETWINDOWSVERSION, 0, 0);
	if (winVersion <  WV_VISTA)
	{
	hookKeyboard	= ::SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)hookProcKeyboard, _hInst, 0);
    if (!hookKeyboard)
    {
        DWORD dwError = ::GetLastError();
        TCHAR  str[128];
        ::wsprintf(str, "GetLastError() returned %lu", dwError);
        ::MessageBox(NULL, str, "SetWindowsHookEx(KEYBOARD) failed", MB_OK | MB_ICONERROR);
    }
	}
//  Removed regarding W9x systems
//	mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

	/* calculate the mouse pt within dialog */
	::GetCursorPos(&pt);
	
	/* get tab informations */
	initTabInformation(pt);

	if (_pCont->isFloating() == true)
	{
		::GetWindowRect(_pCont->getHSelf(), &rc);
	}
	else
	{
		_pCont->getClientRect(rc);
		::ScreenToClient(_pCont->getHSelf(), &pt);
	}

	_ptOffset.x	= pt.x - rc.left;
	_ptOffset.y	= pt.y - rc.top;
}


void Gripper::onMove(void)
{
	POINT		pt		= {0,0};
	POINT		ptBuf	= {0,0};

	::GetCursorPos(&pt);
	getMousePoints(&pt, &ptBuf);

	/* On first time: Do not erase previous rect, because it dosn't exist */
	if (_bPtOldValid == TRUE)
		drawRectangle(ptBuf);

	/* tab reordering only when tab was selected */
	if (_startMovingFromTab == TRUE)
	{
		doTabReordering(pt);
	}

	drawRectangle(pt);
	_bPtOldValid = TRUE;
}


void Gripper::onButtonUp(void)
{
	POINT			pt			= {0,0};
	POINT			ptBuf		= {0,0};
	RECT			rc			= {0};
	RECT			rcCorr		= {0};
	DockingCont*	pContMove	= NULL;

	::GetCursorPos(&pt);
	getMousePoints(&pt, &ptBuf);

	/* do nothing, when old point is not valid */
	if (_bPtOldValid == FALSE)
		return;

	/* erase last drawn rectangle */
	drawRectangle(ptBuf);

	/* look if current position is within dockable area */
	DockingCont*	pDockCont = contHitTest(pt);

	if (pDockCont == NULL)
	{
		pDockCont = workHitTest(pt);
	}

	/* add dependency to other container class */
	if (pDockCont == NULL)
	{
		/* calculate new position */
		rc = _pCont->getDataOfActiveTb()->rcFloat;
		_pCont->getClientRect(rcCorr);

		CalcRectToScreen(_dockData.hWnd, &rc);
		CalcRectToScreen(_dockData.hWnd, &rcCorr);

		rc.left    = pt.x - _ptOffset.x;
		rc.top     = pt.y - _ptOffset.y;

		/* correct rectangle position when mouse is not within */
		DoCalcGripperRect(&rc, rcCorr, pt);

		/* change location of toolbars */
		if (_startMovingFromTab == TRUE)
		{
			/* when tab is moved */
			if ((!_pCont->isFloating()) || 
				((_pCont->isFloating()) && (::SendMessage(_hTabSource, TCM_GETITEMCOUNT, 0, 0) > 1)))
			{
				pContMove = _pDockMgr->toggleActiveTb(_pCont, DMM_FLOAT, TRUE, &rc);
			}
		}
		else if (!_pCont->isFloating())
		{
			/* when all windows are moved */
			pContMove = _pDockMgr->toggleVisTb(_pCont, DMM_FLOAT, &rc);
		}

		/* set moving container */
		if (pContMove == NULL)
		{
			pContMove = _pCont;
		}

		/* update window position */
		::MoveWindow(pContMove->getHSelf(), rc.left, rc.top, rc.right, rc.bottom, TRUE);
		::SendMessage(pContMove->getHSelf(), WM_SIZE, 0, 0);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -