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

📄 dockingcont.cpp.svn-base

📁 Notepad++ is a generic source code editor (it tries to be anyway) and Notepad replacement written in
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
			return TRUE;
		}
		case WM_MOUSEMOVE:
		{
			if ((_beginDrag == TRUE) && (wParam == MK_LBUTTON))
			{
				int				iItem	= 0;
				TCHITTESTINFO	info	= {0};

				/* get selected sub item */
				info.pt.x = LOWORD(lParam);
				info.pt.y = HIWORD(lParam);
				iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);

				SelectTab(iItem);

				/* send moving message to parent window */
				_dragFromTab = TRUE;
				NotifyParent(DMM_MOVE);
				_beginDrag = FALSE;
			}
            else
            {
                _beginDrag = FALSE;
            }
			return TRUE;
		}
		case WM_NOTIFY:
		{
			LPNMHDR	lpnmhdr = (LPNMHDR)lParam;

			if ((lpnmhdr->hwndFrom == _hContTab) && (lpnmhdr->code == TCN_GETOBJECT))
			{
				int				iItem	= 0;
				TCHITTESTINFO	info	= {0};

				/* get selected sub item */
				info.pt.x = LOWORD(lParam);
				info.pt.y = HIWORD(lParam);
				iItem = ::SendMessage(hwnd, TCM_HITTEST, 0, (LPARAM)&info);

				SelectTab(iItem);
			}
			break;
		}
		default:
			break;
	}

	return ::CallWindowProc(_hDefaultTabProc, hwnd, Message, wParam, lParam);
}

void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct)
{
	TCITEM	tcItem		= {0};
	RECT	rc			= pDrawItemStruct->rcItem;
	
	int		nTab		= pDrawItemStruct->itemID;
	bool	isSelected	= (nTab == getActiveTb());

	/* get current selected item */
	tcItem.mask = TCIF_PARAM;
	::SendMessage(_hContTab, TCM_GETITEM, nTab, (LPARAM)&tcItem);

	char*	text	= ((tTbData*)tcItem.lParam)->pszName;
	int		length	= strlen(((tTbData*)tcItem.lParam)->pszName);


	/* get drawing context */
	HDC hDc = pDrawItemStruct->hDC;

	int nSavedDC = ::SaveDC(hDc);

	// For some bizarre reason the rcItem you get extends above the actual
	// drawing area. We have to workaround this "feature".
	rc.top += ::GetSystemMetrics(SM_CYEDGE);

	::SetBkMode(hDc, TRANSPARENT);
	HBRUSH hBrush = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
	::FillRect(hDc, &rc, hBrush);
	::DeleteObject((HGDIOBJ)hBrush);

	/* draw orange bar */
	if (isSelected == true)
	{
		RECT barRect  = rc;
		barRect.top  += rc.bottom - 4;

		hBrush = ::CreateSolidBrush(RGB(250, 170, 60));
		::FillRect(hDc, &barRect, hBrush);
		::DeleteObject((HGDIOBJ)hBrush);

	}

	/* draw icon if enabled */
	if (((tTbData*)tcItem.lParam)->uMask & DWS_ICONTAB)
	{
		HIMAGELIST	hImageList	= (HIMAGELIST)::SendMessage(_hParent, DMM_GETIMAGELIST, 0, 0);
		int			iPosImage	= ::SendMessage(_hParent, DMM_GETICONPOS, 0, (LPARAM)((tTbData*)tcItem.lParam)->hClient);

		if ((hImageList != NULL) && (iPosImage >= 0))
		{
			/* Get height of image so we */
			SIZE		size		= {0};
			IMAGEINFO	info		= {0};
			RECT &		imageRect	= info.rcImage;
			
			ImageList_GetImageInfo(hImageList, iPosImage, &info);

			/* calculate position of rect */
			::GetTextExtentPoint(hDc, text, length, &size);
			rc.left += ((rc.right - rc.left) - (imageRect.right - imageRect.left) - size.cx - 2) / 2;

			ImageList_Draw(hImageList, iPosImage, hDc, rc.left, ((isSelected == true)?2:3), ILD_NORMAL);

			rc.left += imageRect.right - imageRect.left - ((isSelected == true)?3:0);
		}
	}

	COLORREF _unselectedColor = RGB(0, 0, 0);
	::SetTextColor(hDc, _unselectedColor);

	/* draw text */
	rc.top -= ::GetSystemMetrics(SM_CYEDGE);
	::SelectObject(hDc, _hFont);
	::DrawText(hDc, text, length, &rc, DT_SINGLELINE|DT_VCENTER|DT_CENTER);

	::RestoreDC(hDc, nSavedDC);
}


/*********************************************************************************
 *    Process function of dialog
 */
BOOL CALLBACK DockingCont::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch (Message) 
	{
		case WM_NCACTIVATE:
		{
			/* Note: lParam to identify the trigger window */
			if ((int)lParam != -1)
			{
				::SendMessage(_hParent, WM_NCACTIVATE, wParam, 0);
			}
			break;
		}
		case WM_INITDIALOG:
		{
			_hContTab = ::GetDlgItem(_hSelf, IDC_TAB_CONT);
			_hCaption = ::GetDlgItem(_hSelf, IDC_BTN_CAPTION);

			/* intial subclassing of caption */
			::SetWindowLong(_hCaption, GWL_USERDATA, reinterpret_cast<LONG>(this));
			_hDefaultCaptionProc = reinterpret_cast<WNDPROC>(::SetWindowLong(_hCaption, GWL_WNDPROC, reinterpret_cast<LONG>(wndCaptionProc)));

			/* intial subclassing of tab */
			::SetWindowLong(_hContTab, GWL_USERDATA, reinterpret_cast<LONG>(this));
			_hDefaultTabProc = reinterpret_cast<WNDPROC>(::SetWindowLong(_hContTab, GWL_WNDPROC, reinterpret_cast<LONG>(wndTabProc)));
			break;
		}
		case WM_NCCALCSIZE:
		case WM_SIZE:
		{
			onSize();
			break;
		}
		case WM_DRAWITEM :
		{
			/* draw tab or caption */
			if (((DRAWITEMSTRUCT *)lParam)->CtlID == IDC_TAB_CONT)
			{
				drawTabItem((DRAWITEMSTRUCT *)lParam);
				return TRUE;
			}
			else
			{
				drawCaptionItem((DRAWITEMSTRUCT *)lParam);
				return TRUE;
			}
			break;
		}
		case WM_NCLBUTTONDBLCLK :
		{
			RECT	rcWnd		= {0};
			RECT	rcClient	= {0};
			POINT	pt			= {HIWORD(lParam), LOWORD(lParam)};

			getWindowRect(rcWnd);
			getClientRect(rcClient);
			ClientToScreen(_hSelf, &rcClient);
			rcWnd.bottom = rcClient.top;

			/* if in caption */
			if ((rcWnd.top  < pt.x) && (rcWnd.bottom > pt.x) &&
				(rcWnd.left < pt.y) && (rcWnd.right  > pt.y))
			{
				NotifyParent(DMM_DOCKALL);
				return TRUE;
			}
			break;
		}
		case WM_SYSCOMMAND :
		{
			switch (wParam & 0xfff0)
			{
				case SC_MOVE:
					NotifyParent(DMM_MOVE);
					return TRUE;
				default: 
					break;
			}
			return FALSE;
		}
		case WM_COMMAND : 
		{
			switch (LOWORD(wParam))
			{   
				case IDCANCEL:
					doClose();
					return TRUE;
				default :
					break;
			}
			break;
		}
		default:
			break;
	}

	return FALSE;
}

void DockingCont::onSize(void)
{
	TCITEM	tcItem		= {0};
	RECT	rc			= {0};
	RECT	rcTemp		= {0};
	UINT	iItemCnt	= ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0);

	getClientRect(rc);

	if (iItemCnt >= 1)
	{
		/* resize to docked window */
		if (_isFloating == false)
		{
			/* draw caption */
			if (_isTopCaption == TRUE)
			{
				::SetWindowPos(_hCaption, NULL, rc.left, rc.top, rc.right, 16, SWP_NOZORDER | SWP_NOACTIVATE);
				rc.top		+= 16;
				rc.bottom	-= 16;
			}
			else
			{
				::SetWindowPos(_hCaption, NULL, rc.left, rc.top, 16, rc.bottom, SWP_NOZORDER | SWP_NOACTIVATE);
				rc.left		+= 16;
				rc.right	-= 16;
			}

			if (iItemCnt >= 2)
			{
				/* resize tab and plugin control if tabs exceeds one */
				/* resize tab */
				rcTemp = rc;
				rcTemp.top    = (rcTemp.bottom + rcTemp.top) - 22;
				rcTemp.bottom = 20;

				::SetWindowPos(_hContTab, NULL,
								rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, 
								SWP_NOZORDER | SWP_SHOWWINDOW |  SWP_NOACTIVATE);

				/* resize client area for plugin */
				rcTemp = rc;
				rcTemp.top    += 2;
				rcTemp.bottom -= 22;
			}
			else
			{
				/* resize client area for plugin */
				rcTemp = rc;
				rcTemp.top    += 2;
				rcTemp.bottom -= 2;
			}

			/* set position of client area */
			::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL,
							rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, 
							SWP_NOZORDER | SWP_NOACTIVATE);
		}
		/* resize to float window */
		else
		{
			/* update floating size */
			if (_isFloating == true)
			{
				for (size_t iTb = 0; iTb < _vTbData.size(); iTb++)
				{
					getWindowRect(_vTbData[iTb]->rcFloat);
				}
			}			

			/* draw caption */
			if (iItemCnt >= 2)
			{
				/* resize tab if size of elements exceeds one */
				rcTemp = rc;
				rcTemp.top    = rcTemp.bottom - 22;
				rcTemp.bottom = 20;

				::SetWindowPos(_hContTab, NULL,
								rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, 
								SWP_NOZORDER | SWP_SHOWWINDOW);
			}

			/* resize client area for plugin */
			rcTemp = rc;
			rcTemp.bottom -= ((iItemCnt == 1)?0:20);

			::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL,
							rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, 
							SWP_NOZORDER | SWP_NOACTIVATE);
		}
		

		/* get active item data */
		UINT	iItemCnt = ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0);

		/* resize visible plugin windows */
		for (UINT iItem = 0; iItem < iItemCnt; iItem++)
		{
			tcItem.mask		= TCIF_PARAM;
			::SendMessage(_hContTab, TCM_GETITEM, iItem, (LPARAM)&tcItem);

			::SetWindowPos(((tTbData*)tcItem.lParam)->hClient, NULL,
							0, 0, rcTemp.right, rcTemp.bottom, 
							SWP_NOZORDER);
		}
	}
}

void DockingCont::doClose(void)
{
	INT	iItemOff	= 0;
	INT	iItemCnt	= ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0);

	for (INT iItem = 0; iItem < iItemCnt; iItem++)
	{
		TCITEM		tcItem		= {0};

		/* get item data */
		SelectTab(iItemOff);
		tcItem.mask	= TCIF_PARAM;
		::SendMessage(_hContTab, TCM_GETITEM, iItemOff, (LPARAM)&tcItem);

		/* notify child windows */
		if (NotifyParent(DMM_CLOSE) == 0)
		{
			/* delete tab */
			hideToolbar((tTbData*)tcItem.lParam);
		}
		else
		{
			iItemOff++;
		}
	}

	if (iItemOff == 0)
	{
		/* hide dialog first */
		this->doDialog(false);
		::SendMessage(_hParent, WM_SIZE, 0, 0);
	}
}

void DockingCont::showToolbar(tTbData* pTbData, BOOL state)
{
	if (state == SW_SHOW)
	{
		viewToolbar(pTbData);
	}
	else
	{
		hideToolbar(pTbData);
	}
}

int DockingCont::hideToolbar(tTbData *pTbData)
{
	int		iItem	= SearchPosInTab(pTbData);

	/* delete item */
	if (TRUE == ::SendMessage(_hContTab, TCM_DELETEITEM, iItem, 0))
	{
		UINT	iItemCnt = ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0);

		if (iItemCnt != 0)
		{
			TCITEM		tcItem = {0};

			tcItem.mask	= TCIF_PARAM;

			if (iItem == iItemCnt)
			{
				iItem--;
			}

			/* activate new selected item and view plugin dialog */
			_prevItem = iItem;
			SelectTab(iItem);

			/* hide tabs if only one element */
			if (iItemCnt == 1)
			{
				::ShowWindow(_hContTab, SW_HIDE);
			}
		}
		else 
		{
			/* hide dialog */
			this->doDialog(false);

			/* send message to docking manager for resize */
			if (_isFloating == false)
			{
				::SendMessage(_hParent, WM_SIZE, 0, 0);
			}
		}

		/* keep sure, that client is hide!!! */
		::ShowWindow(pTbData->hClient, SW_HIDE);
	}
	onSize();

	return iItem;
}

void DockingCont::viewToolbar(tTbData *pTbData)
{
	TCITEM		tcItem		= {0};
	int			iItemCnt	= ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0);

	if (iItemCnt > 0)
	{
		UINT	iItem	= getActiveTb();

		tcItem.mask		= TCIF_PARAM;
		::SendMessage(_hContTab, TCM_GETITEM, iItem, (LPARAM)&tcItem);
		
		/* hide active dialog */
		::ShowWindow(((tTbData*)tcItem.lParam)->hClient, SW_HIDE);
	}

	/* create new tab if it not exist */
	int iTabPos = SearchPosInTab(pTbData);
	if (iTabPos == -1)
	{
		/* set only params and text even if icon available */
		tcItem.mask			= TCIF_PARAM | TCIF_TEXT;

		tcItem.lParam		= (LPARAM)pTbData;

		if (pTbData->uMask & DWS_ICONTAB)
		{
			/* fake here a icon before the text ... */
			char	szText[64];

			strcpy(szText, "    ");
			strcat(szText, pTbData->pszName);

			tcItem.pszText		= szText;
			tcItem.cchTextMax	= strlen(szText);
		}
		else
		{
			/* ... but here put text normal into the tab */
			tcItem.pszText		= pTbData->pszName;
			tcItem.cchTextMax	= strlen(pTbData->pszName);
		}

		::SendMessage(_hContTab, TCM_INSERTITEM, iItemCnt, (LPARAM)&tcItem);
		SelectTab(iItemCnt);
	}
	/* if exists select it and update data */
	else
	{
		tcItem.mask			= TCIF_PARAM;
		tcItem.lParam		= (LPARAM)pTbData;
		::SendMessage(_hContTab, TCM_SETITEM, iTabPos, (LPARAM)&tcItem);
		SelectTab(iTabPos);
	}

	/* show dialog and notify parent to update dialog view */
	if (isVisible() == false)
	{
		this->doDialog();
		::SendMessage(_hParent, WM_SIZE, 0, 0);
	}

	/* set position of client */
	onSize();
}

int DockingCont::SearchPosInTab(tTbData* pTbData)
{
	TCITEM	tcItem		= {0};
	int		iItemCnt	= ::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0);
	int		ret			= -1;

	tcItem.mask	= TCIF_PARAM;

	for (int iItem = 0; iItem < iItemCnt; iItem++)
	{
		::SendMessage(_hContTab, TCM_GETITEM, iItem, (LPARAM)&tcItem);

		if (((tTbData*)tcItem.lParam)->hClient == pTbData->hClient)
		{
			ret = iItem;
			break;
		}
	}
	return ret;
}

void DockingCont::SelectTab(int iItem)
{
	if (iItem != -1)
	{
		TCITEM			tcItem	= {0};

		/* get data of new active dialog */
		tcItem.mask		= TCIF_PARAM;
		::SendMessage(_hContTab, TCM_GETITEM, iItem, (LPARAM)&tcItem);

		/* show active dialog */
		::ShowWindow(((tTbData*)tcItem.lParam)->hClient, SW_SHOW);
		::SetFocus(((tTbData*)tcItem.lParam)->hClient);

		if (iItem != _prevItem)
		{
			/* hide previous dialog */
			::SendMessage(_hContTab, TCM_GETITEM, _prevItem, (LPARAM)&tcItem);
			::ShowWindow(((tTbData*)tcItem.lParam)->hClient, SW_HIDE);
		}

		/* selects the pressed tab and store previous tab */
		::SendMessage(_hContTab, TCM_SETCURSEL, iItem, 0);
		_prevItem = iItem;

		/* update caption text */
		updateCaption();

		onSize();
	}
}

void DockingCont::updateCaption(void)
{
	TCITEM			tcItem	= {0};
	int				iItem	= 0;

	/* get active tab */
	iItem = getActiveTb();

	/* get data of new active dialog */
	tcItem.mask		= TCIF_PARAM;
	::SendMessage(_hContTab, TCM_GETITEM, iItem, (LPARAM)&tcItem);

	/* update caption text */
	strcpy(_pszCaption, ((tTbData*)tcItem.lParam)->pszName);

	/* test if additional information are available */
	if ((((tTbData*)tcItem.lParam)->uMask & DWS_ADDINFO) && 
		(strlen(((tTbData*)tcItem.lParam)->pszAddInfo) != 0))
	{
		strcat(_pszCaption, " - ");
		strcat(_pszCaption, ((tTbData*)tcItem.lParam)->pszAddInfo);
	}

	if (_isFloating == true)
	{
		::SetWindowText(_hSelf, _pszCaption);
	}
	else
	{
		::SetWindowText(_hCaption, _pszCaption);
	}
}

void DockingCont::focusClient(void)
{
	TCITEM		tcItem	= {0};
	int			iItem	= getActiveTb();	

	if (iItem != -1)
	{
		/* get data of new active dialog */
		tcItem.mask		= TCIF_PARAM;
		::SendMessage(_hContTab, TCM_GETITEM, iItem, (LPARAM)&tcItem);

		/* set focus */
		::SetFocus(((tTbData*)tcItem.lParam)->hClient);
	}
}

LPARAM DockingCont::NotifyParent(UINT message)
{
	return ::SendMessage(_hParent, message, 0, (LPARAM)this);
}

⌨️ 快捷键说明

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