Click here to Skip to main content
15,883,749 members
Articles / Desktop Programming / MFC

Exile 1.8 - The Password Manager

Rate me:
Please Sign up or sign in to vote.
4.57/5 (51 votes)
6 Mar 20058 min read 255K   7.4K   111  
Yet another password manager.
// TreeCtrlEx.cpp : implementation file
//

#include "stdafx.h"
#include "exile.h"
#include "typedefs.h"
#include "messagebox.h"
#include "TreeCtrlEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTreeCtrlEx

CTreeCtrlEx::CTreeCtrlEx()
{
	m_hDragging = 0;
	m_pimgDrag = 0;
	m_bDragging = FALSE;
}

CTreeCtrlEx::~CTreeCtrlEx()
{
}


BEGIN_MESSAGE_MAP(CTreeCtrlEx, CTreeCtrl)
	//{{AFX_MSG_MAP(CTreeCtrlEx)
	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTreeCtrlEx message handlers

void CTreeCtrlEx::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM hItem = pNMTreeView->itemNew.hItem;

	// First off, do nothing if a root item is being dragged
	if(0 == GetParentItem(hItem))
		return;

	// Creating drag image
	m_pimgDrag = CreateDragImage(hItem);

	if(0 == m_pimgDrag)
		return;

	// Item Hot-Spot - the location of the
    // cursor relative to the upper-left corner of the item rectangle
	CRect rc;
	GetItemRect(hItem, rc, TRUE);

	CPoint pt(pNMTreeView->ptDrag.x, pNMTreeView->ptDrag.y);
	CPoint ptHotSpot(pt);

	ptHotSpot.x -= rc.left;
	ptHotSpot.y -= rc.top;

	CPoint ptClient(0, 0);
	ClientToScreen(&ptClient);
	GetWindowRect(rc);

	pt.x += ptClient.x - rc.left;
	pt.y += ptClient.y - rc.top;

	// Begin drag
	SetCapture();
	m_pimgDrag->BeginDrag(0, ptHotSpot);
	m_pimgDrag->DragEnter(this, pt);

	m_bDragging = TRUE;
	m_hDragging = hItem;

	// Dragged item
	
	*pResult = 0;
}

void CTreeCtrlEx::OnMouseMove(UINT nFlags, CPoint point) 
{
	CTreeCtrl::OnMouseMove(nFlags, point);

	if((m_bDragging) && (m_pimgDrag))
	{
		m_pimgDrag->DragMove(point);
		HTREEITEM hItem = GetDropTarget(point);

		// Some visual feedback
		::SetCursor(hItem ? (HCURSOR)::GetClassLong(m_hWnd, GCL_HCURSOR) :
			LoadCursor(0, IDC_NO));
	} // if
}

HTREEITEM CTreeCtrlEx::GetDropTarget(CPoint pt)
{
	UINT uFlags;
	HTREEITEM hItem = HitTest(pt, &uFlags);

	// If this item is a drop target...
	TV_ITEM tvi;
	tvi.mask = TVIF_HANDLE | TVIF_PARAM;
	tvi.hItem = hItem;

	if(GetItem(&tvi))
	{
		if(!IsDropTarget(tvi.lParam))
			return (HTREEITEM)0;

		m_pimgDrag->DragShowNolock(FALSE);
		SelectDropTarget(hItem);
		m_pimgDrag->DragShowNolock(TRUE);

		return hItem;
	} // if

	return (HTREEITEM)0;
}

void CTreeCtrlEx::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CTreeCtrl::OnLButtonUp(nFlags, point);

	if((m_bDragging) && (m_pimgDrag))
	{
		// Release mouse and terminate dragging operation
		m_pimgDrag->DragLeave(this);
		m_pimgDrag->EndDrag();
		::ReleaseCapture();

		m_bDragging = FALSE;
		SelectDropTarget(0);

		// Cleanup
		m_pimgDrag->DeleteImageList();
		delete m_pimgDrag;
		m_pimgDrag = 0;

		// Get item handle
		UINT uFlags;
		HTREEITEM hItem = HitTest(point, &uFlags);

		if(!hItem)
			return;

		// Some vaildation...
		if(m_hDragging == hItem)
		{
			MessageBoxEx(GetSafeHwnd(), IDS_CANTDROPTOITSELF, IDS_TITLE);
			return;
		} // if

		if(GetParentItem(m_hDragging) == hItem)
		{
			MessageBoxEx(GetSafeHwnd(), IDS_CANTDROPONPARENT, IDS_TITLE);
			return;
		} // if

		if(IsChildOf(hItem, m_hDragging))
		{
			MessageBoxEx(GetSafeHwnd(), IDS_CANTDROPONCHILDREN, IDS_TITLE);
			return;
		} // if

		MoveTree(hItem, m_hDragging);
		m_hDragging = 0;

		// Notifying parent about a successful (hopefully)
		// drag operation
		::SendMessage(GetParent()->GetSafeHwnd(), TCEX_ITEMDRAGGED, 0, 0);
	} // if	
}

BOOL CTreeCtrlEx::IsChildOf(const HTREEITEM hItem1, const HTREEITEM hItem2)
{
	HTREEITEM hParent = hItem1;

	hParent = GetParentItem(hParent);

	while(hParent)
	{
		if(hItem2 == hParent)
			return TRUE;

		hParent = GetParentItem(hParent);
	} // while

	return FALSE;
}

void CTreeCtrlEx::MoveTree(HTREEITEM hDest, HTREEITEM hSrc)
{
	CopyTree(hDest, hSrc);
	DeleteItem(hSrc);
}

void CTreeCtrlEx::CopyTree(HTREEITEM hDest, HTREEITEM hSrc)
{
	// Just transferring TV_ITEM
	TV_ITEM tvi;
	TV_INSERTSTRUCT tvIns;
	TCHAR szBuffer[nNameLength];
	
	tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_IMAGE | TVIF_HANDLE;
	tvi.hItem = m_hDragging;
	tvi.pszText = szBuffer;
	tvi.cchTextMax = nNameLength;

	if(!GetItem(&tvi))
		return;

	tvIns.hParent = hDest;
	tvIns.hInsertAfter = TVI_LAST;
	tvIns.item = tvi;

	HTREEITEM hNew = InsertItem(&tvIns);

	// Copy children if there are any
	if(ItemHasChildren(hSrc))
	{
		CopyChildren(hNew, hSrc);
	} // if

	SelectItem(hNew);
}

void CTreeCtrlEx::CopyChildren(HTREEITEM hDest, HTREEITEM hSrc)
{
	// Get first item
	HTREEITEM hItem = GetChildItem(hSrc);

	// Just transferring TV_ITEM
	TV_ITEM tvi;
	TV_INSERTSTRUCT tvIns;
	TCHAR szBuffer[nNameLength];
	
	tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_IMAGE | TVIF_HANDLE;
	tvi.hItem = hItem;
	tvi.pszText = szBuffer;
	tvi.cchTextMax = nNameLength;

	if(!GetItem(&tvi))
		return;

	tvIns.hParent = hDest;
	tvIns.hInsertAfter = TVI_LAST;
	tvIns.item = tvi;

	HTREEITEM hNew = InsertItem(&tvIns);

	// Copy all subitems (if there are any)
	if(ItemHasChildren(hItem))
		CopyChildren(hNew, hItem);

	// Process all siblings
	hItem = GetNextSiblingItem(hItem);

	while(hItem)
	{
		tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_IMAGE | TVIF_HANDLE;
		tvi.hItem = hItem;
		tvi.pszText = szBuffer;
		tvi.cchTextMax = nNameLength;

		if(!GetItem(&tvi))
			return;

		tvIns.hParent = hDest;
		tvIns.hInsertAfter = TVI_LAST;
		tvIns.item = tvi;

		hNew = InsertItem(&tvIns);

		// Copy all subitems (if there are any)
		if(ItemHasChildren(hItem))
			CopyChildren(hNew, hItem);

		hItem = GetNextSiblingItem(hItem);
	} // while
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Russian Federation Russian Federation
I'll think about it later on...

Comments and Discussions