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

📄 tlmouse.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 4 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	TLMouse.c - handle tree list mouse events

	$Id: TLMouse.c,v 1.24 2002/10/01 18:27:00 pbj Exp $
____________________________________________________________________________*/

#include "TLIntern.h"
#include "math.h"

#define DRAGDEADZONE 2

#define WHEELTHRESHOLD	WHEEL_DELTA

#define TLK_NONE		0x0000
#define TLK_BUTTON		0x0001
#define TLK_SELECT		0x0002
#define TLK_ACTIVE		0x0003

#define TOOLTIPVERTICALOFFSET	20


//	_______________________________________________
//
//  remove tooltip text

BOOL 
TLKillToolTip (
		TLWndData*	pWD) 
{
	POINT pt;
	RECT rc;

	GetCursorPos (&pt);
	ScreenToClient (pWD->hWnd, &pt);
	GetClientRect (pWD->hWnd, &rc);

	if (!PtInRect (&rc, pt)) 
	{
		SendMessage (pWD->hWndToolTip, TTM_TRACKACTIVATE, FALSE, 0);
		return TRUE;
	}
	else
		return FALSE;
}


//	_______________________________________________
//
//  Determine if mouse is over item element

static INT 
sPointInItemArea (
		TLTreeItem*		p, 
		TLColumnItem*	pci,
		int				ix, 
		POINT			mpt) 
{
	TLListItem* pli;
	RECT rc;
	int iSubItem;

	pli = p->listItem;
	iSubItem = 0;

	while (pci && pli) 
	{
		iSubItem++;

		if (pli->state & TLIS_VISIBLE) 
		{
			rc.left = ix;
			rc.right = rc.left + pci->cx;
			rc.top = p->selectRect.top;
			rc.bottom = p->selectRect.bottom;

			if (PtInRect (&rc, mpt))
				return iSubItem;
		}

		ix += pci->cx;

		pci = pci->nextItem;
		pli = pli->nextItem;
	}

	return 0;
}


//	_______________________________________________
//
//  Search for object containing given point

static TLTreeItem* 
sTextItemSearch (
		TLTreeItem*		pStart, 
		TLColumnItem*	pci,
		int				ix, 
		POINT			mpt, 
		int*			iSubItem) 
{
	TLTreeItem* p;
	TLTreeItem* pp;

	p = pStart;
	while (p) 
	{
		if (PtInRect (&p->selectRect, mpt)) 
		{
			if (PtInRect (&p->hiliteRect, mpt)) 
			{
				*iSubItem = sPointInItemArea (p, pci, ix, mpt);
				return p;
			}
		}

		if (p->state & TLIS_EXPANDED) 
		{
			pp = sTextItemSearch (p->childItem, pci, ix, mpt, iSubItem);
			if (pp) 
				return pp;
		}

		if (p->buttonRect.right < p->buttonRect.left) 
			return NULL;

		p = p->nextItem;
	}

	return NULL;
}


//	_______________________________________________
//
//  Determine if mouse is over active list element

static INT
sPointInActiveArea (
		TLTreeItem*		p, 
		TLColumnItem*	pci,
		int				ix, 
		POINT			mpt) 
{
	TLListItem* pli;
	RECT rc;
	int iSubItem;

	pli = p->listItem;
	iSubItem = 1;

	while (pci && pli) 
	{
		if (pci->bMouseNotify) 
		{
			if (pli->state & TLIS_VISIBLE) 
			{
				rc.left = ix + pci->cxImageOffset;
				rc.right = rc.left + BITMAPWIDTH;
				rc.top = p->selectRect.top;
				rc.bottom = p->selectRect.bottom;

				if (PtInRect (&rc, mpt)) 
					return iSubItem;
			}
		}

		iSubItem++;
		ix += pci->cx;

		pci = pci->nextItem;
		pli = pli->nextItem;
	}

	return 0;
}


//	_______________________________________________
//
//  Search for object containing given point

static TLTreeItem* 
sPointSearchEx (
	TLWndData*		pWD, 
	TLTreeItem*		pStart, 
	TLColumnItem*	pci,
	int				ix,
	POINT			mpt, 
	int*			iType, 
	int*			iSubItem) 
{
	TLTreeItem* p;

	p = pStart;
	while (p) 
	{
		if (pWD->style & TLS_DRAGSELECTION)
		{
			RECT	rcDragSelect;

			rcDragSelect.left = 0;
			rcDragSelect.right = DRAGSELECTINDENT - pWD->iHorizontalPos;
			rcDragSelect.top = p->selectRect.top;
			rcDragSelect.bottom = p->selectRect.bottom;

			if (PtInRect (&rcDragSelect, mpt)) 
			{
				*iType = TLK_SELECT;
				return p;
			}
		}

		*iSubItem = sPointInActiveArea (p, pci, ix, mpt);
		if (*iSubItem) 
		{
			*iType = TLK_ACTIVE;
			return p;
		}
		if (PtInRect (&p->buttonRect, mpt)) 
		{
			*iType = TLK_BUTTON;
			return p;
		}
		if (PtInRect (&p->selectRect, mpt)) 
		{
			if (mpt.x < (p->selectRect.left + BITMAPWIDTH))
				*iType = TLK_ACTIVE;
			else
				*iType = TLK_SELECT;
			return p;
		}
		if (p->state & TLIS_EXPANDED) 
		{
			TLTreeItem* pp;

			pp = sPointSearchEx (pWD, 
					p->childItem, pci, ix, mpt, iType, iSubItem);
			if (pp)
				return pp;
		}
		if (p->buttonRect.right < p->buttonRect.left)
		{
			*iType = TLK_NONE;
			return NULL;
		}
		p = p->nextItem;
	}

	*iType = TLK_NONE;
	return NULL;
}


//	_______________________________________________
//
//  Search for object containing given point

static TLTreeItem* 
sPointSearch (
		TLTreeItem*	pStart, 
		POINT		mpt, 
		int*		iType) 
{
	TLTreeItem* p;
	TLTreeItem* pp;

	p = pStart;
	while (p)
	{
		if (PtInRect (&p->buttonRect, mpt)) 
		{
			*iType = TLK_BUTTON;
			return p;
		}
		if (PtInRect (&p->selectRect, mpt))
		{
			if (mpt.x < (p->selectRect.left + BITMAPWIDTH))
				*iType = TLK_ACTIVE;
			else
				*iType = TLK_SELECT;
			return p;
		}
		if (p->state & TLIS_EXPANDED) 
		{
			pp = sPointSearch (p->childItem, mpt, iType);
			if (pp) return pp;
		}
		if (p->buttonRect.right < p->buttonRect.left)
		{
			*iType = TLK_NONE;
			return NULL;
		}
		p = p->nextItem;
	}

	*iType = TLK_NONE;
	return NULL;
}


//	_______________________________________________
//
//  Search for object containing given point for drag selection

static TLTreeItem* 
sPointSearchDragSelect (
		TLTreeItem*	pStart, 
		POINT		mpt, 
		int*		iType) 
{
	TLTreeItem* p;
	TLTreeItem* pp;
	RECT		rc;

	rc.left = 0;
	rc.right = 32000;

	p = pStart;
	while (p) 
	{
		rc.top = p->selectRect.top;
		rc.bottom = p->selectRect.bottom;

		if (PtInRect (&rc, mpt)) 
		{
			*iType = TLK_SELECT;
			return p;
		}

		if (p->state & TLIS_EXPANDED) 
		{
			pp = sPointSearchDragSelect (p->childItem, mpt, iType);
			if (pp) 
				return pp;
		}

		p = p->nextItem;
	}

	*iType = TLK_NONE;
	return NULL;
}


//	_______________________________________________
//
//  Select range of lines

TLTreeItem* 
TLSelectRange (
		TLWndData*	pWD, 
		TLTreeItem* pFirst, 
		TLTreeItem* pSel,
		TLTreeItem* pLast) 
{
	TLTreeItem* p;
///	TLTreeItem* pFirstSelectParent;
	BOOL bSel;

	p = pFirst;
	bSel = (pLast != NULL);
///	pFirstSelectParent = pWD->firstSelectItem->parentItem;

	if (pSel == pWD->firstSelectItem) 
	{
		pSel->state |= TLIS_SELECTED;
		pWD->iNumberSelected = 1;
		TLInvalidateItem (pWD, pSel);
		return pSel;
	}

	while (p && !bSel) 
	{
		if (p == pSel) 
		{
			bSel = TRUE;
			pLast = pWD->firstSelectItem;
		}
		else if (p == pWD->firstSelectItem) 
		{
			bSel = TRUE;
			pLast = pSel;
		}

		if (!bSel)
		{
			if ((p->childItem) && (p->state & TLIS_EXPANDED)) 
			{
				pLast = TLSelectRange (pWD, p->childItem, pSel, pLast);
				if (pLast)
				{
					bSel = TRUE;
					p = p->nextItem;
				}
			}
		}

		if (!bSel)
			p = p->nextItem;
	}

	if (bSel) 
	{
		while (p && bSel) 
		{
			if (p == pLast) 
				bSel = FALSE;

///			if (p->parentItem == pFirstSelectParent)
			{
				p->state |= TLIS_SELECTED;
				(pWD->iNumberSelected)++;
				TLInvalidateItem (pWD, p);
			}

			if ((p->childItem) && (p->state & TLIS_EXPANDED)) 
			{
				pLast = TLSelectRange (pWD, p->childItem, pSel, pLast);
				if (!pLast)
					bSel = FALSE;
			}

			p = p->nextItem;
		}

		if (!bSel)
			return NULL;
	}

	return pLast;
}


//	_______________________________________________
//
//  De-dragover Tree

BOOL 
TLDeDragOverTree (
		TLWndData*	pWD, 
		TLTreeItem* p, 
		TLTreeItem* pExcept) 
{
	BOOL bDedragged = FALSE;

	while (p) 
	{
		if (p->childItem)
			bDedragged = TLDeDragOverTree (pWD, p->childItem, pExcept);

		if (p != pExcept) 
		{
			if (p->state & (TLIS_DRAGGEDOVER|
							TLIS_DRAGGEDBEFORE|
							TLIS_DRAGGEDAFTER)) 
			{
				p->state &= ~(TLIS_DRAGGEDOVER|
							  TLIS_DRAGGEDBEFORE|
							  TLIS_DRAGGEDAFTER);
				TLInvalidateItem (pWD, p);
				bDedragged = TRUE;
			}
		}
		p = p->nextItem;
	}

	return bDedragged;
}


//	_______________________________________________
//
//  cursor is moving during internal drag operation

static BOOL 
sDragOverInternal (
		TLWndData*	pWD, 
		LPARAM		lParam)
{
	INT			irow, iHitType;
	TLTreeItem* pHit;
	POINT		mpt;
	BOOL		bRet;

	BOOL		bShift = FALSE;

	mpt.x = LOWORD (lParam);
	mpt.y = HIWORD (lParam);

	pWD->nmTreeList.hdr.code = 0;
	pWD->nmTreeList.itemNew.hItem = NULL;
	pWD->nmTreeList.itemNew.state = 0;
	pWD->nmTreeList.itemOld.hItem = NULL;

	pHit = sPointSearch (pWD->rootItem, mpt, &iHitType);

	switch (iHitType) {
	case TLK_NONE :
		TLDeDragOverTree (pWD, pWD->rootItem, NULL);
		SetCursor (pWD->hCursorNoDrag);
		pWD->firstSelectItem = NULL;
		if (pWD->focusItem) 
		{
			pHit = pWD->focusItem;
			pWD->focusItem = NULL;
		}
		pWD->nmTreeList.itemNew.hItem = NULL;
		pWD->nmTreeList.itemNew.state = 0;
		pWD->nmTreeList.hdr.code = TLN_DRAGGEDOVER;
		bRet = FALSE;
		break;

	default :
		if (pWD->uDragScrollState == 0) 
		{
			irow = 0;
			TLGetRow (pWD->rootItem, pHit, &irow);
			if (irow == pWD->iFirstRow)
			{
				pWD->iFirstRow--;
				if (pWD->iFirstRow < 0)
					pWD->iFirstRow = 0;
				else 
				{
					SetTimer (pWD->hWnd, 
							DRAGSCROLLTIMERID, DRAGSCROLLTIME, NULL);
					pWD->uDragScrollState = DRAGSCROLL_DOWN;
					pWD->nmTreeList.itemNew.hItem = NULL;
					pWD->nmTreeList.itemNew.state = 0;
					pWD->nmTreeList.hdr.code = TLN_AUTOSCROLLED;
					pWD->nmTreeList.flags |= TLC_BYMOUSE;
					SendMessage (pWD->hWndParent, WM_NOTIFY, 
							pWD->id, (LPARAM)&(pWD->nmTreeList));
				}
			}
			if (irow == (pWD->iFirstRow + pWD->iMaxRows)) 
			{
				pWD->iFirstRow++;
				SetTimer (pWD->hWnd, 
						DRAGSCROLLTIMERID, DRAGSCROLLTIME, NULL);
				pWD->uDragScrollState = DRAGSCROLL_UP;
				pWD->nmTreeList.itemNew.hItem = NULL;
				pWD->nmTreeList.itemNew.state = 0;
				pWD->nmTreeList.hdr.code = TLN_AUTOSCROLLED;
				pWD->nmTreeList.flags |= TLC_BYMOUSE;
				SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,
						(LPARAM)&(pWD->nmTreeList));
			}
		}

		TLDeDragOverTree (pWD, pWD->rootItem, pHit);
		SetCursor (pWD->hCursorDragging);

⌨️ 快捷键说明

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