?? gripper.cpp
字號:
//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 = ::LoadCursor(NULL, IDC_ARROW);
clz.hbrBackground = NULL;
clz.lpszMenuName = NULL;
clz.lpszClassName = MDLG_CLASS_NAME;
if (!::RegisterClass(&clz))
{
systemMessage(TEXT("System Err"));
throw int(98);
}
_isRegistered = TRUE;
}
_hSelf = ::CreateWindowEx(
0,
MDLG_CLASS_NAME,
TEXT(""), 0,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
_hInst,
(LPVOID)this);
hWndServer = _hSelf;
if (!_hSelf)
{
systemMessage(TEXT("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;
::SetWindowLongPtr(hwnd, GWL_USERDATA, reinterpret_cast<LONG>(pDlgMoving));
return TRUE;
default :
pDlgMoving = (Gripper *)::GetWindowLongPtr(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, TEXT("GetLastError() returned %lu"), dwError);
::MessageBox(NULL, str, TEXT("SetWindowsHookEx(MOUSE) failed"), MB_OK | MB_ICONERROR);
}
winVer winVersion = (NppParameters::getInstance())->getWinVersion();
if (winVersion < WV_VISTA)
{
hookKeyboard = ::SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)hookProcKeyboard, _hInst, 0);
if (!hookKeyboard)
{
DWORD dwError = ::GetLastError();
TCHAR str[128];
::wsprintf(str, TEXT("GetLastError() returned %lu"), dwError);
::MessageBox(NULL, str, TEXT("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)
{
}
/* 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 + -