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

📄 dropwnd.cpp

📁 EVC的Grid ctrl应用,有需要的朋友可以联系我哦
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////
// DropWnd.cpp : implementation file
// 
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed 
// unmodified PROVIDING it is not sold for profit without the authors 
// written consent, and providing that this notice and the authors name 
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DropWnd.h"

#include "AdvComboBox.h"
#include "DropListBox.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDropWnd

CDropWnd::CDropWnd( CWnd* pComboParent, list<LIST_ITEM> &itemlist, DWORD dwACBStyle )
:
	m_pComboParent( pComboParent ),
	m_list( itemlist ),
	m_dwACBStyle( dwACBStyle )
{
	m_bResizing = false;

	m_pListFont = new CFont;
	LOGFONT logFont;
	memset( &logFont, 0, sizeof(LOGFONT) );
	strcpy( logFont.lfFaceName, "MS Sans Serif" );
	logFont.lfHeight = 12;
	m_pListFont->CreateFontIndirect(&logFont);
}

CDropWnd::~CDropWnd()
{
	delete m_pListFont;
	delete m_scrollbar;
	delete m_listbox;
}


BEGIN_MESSAGE_MAP(CDropWnd, CWnd)
	//{{AFX_MSG_MAP(CDropWnd)
	ON_WM_CREATE()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_WM_LBUTTONUP()
	ON_WM_SHOWWINDOW()
	ON_WM_ACTIVATEAPP()
	//}}AFX_MSG_MAP
	ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
	ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CDropWnd message handlers

BOOL CDropWnd::PreCreateWindow(CREATESTRUCT& cs) 
{
	//
	// Calc the size of the wnd
	
	return CWnd::PreCreateWindow(cs);
}

//BOOL CDropWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
BOOL CDropWnd::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	return CWnd::Create(0, 0, dwStyle, rect, pParentWnd, nID, pContext);
}

int CDropWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	CRect rcWnd;
	GetClientRect( &rcWnd );

	//
	// Because this window doesn't have an owner, there will appear 
	// a 'blank' button on the taskbar. The following are to hide 
	// that 'blank' button on the taskbar
	ModifyStyleEx( 0, WS_EX_TOOLWINDOW );
	SetWindowPos( &wndTopMost, lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, SWP_SHOWWINDOW );

	//
	// Create scrollbar
	m_rcScroll = rcWnd;
	m_rcScroll.left = m_rcScroll.right - ::GetSystemMetrics(SM_CXVSCROLL);
	m_rcScroll.bottom -= ::GetSystemMetrics(SM_CYVSCROLL);
	m_scrollbar = new CDropScrollBar;
	VERIFY(m_scrollbar->Create( SBS_VERT | SBS_RIGHTALIGN | WS_CHILD, m_rcScroll, this, 100));

	//
	// Create listbox
	m_rcList.SetRect( lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->x+lpCreateStruct->cx-::GetSystemMetrics(SM_CXVSCROLL), lpCreateStruct->y+lpCreateStruct->cy );
	ScreenToClient( m_rcList );
	m_listbox = new CDropListBox(m_pComboParent, m_scrollbar);
	VERIFY(m_listbox->Create( /*WS_VISIBLE | */WS_CHILD | LBS_NOINTEGRALHEIGHT | LBS_OWNERDRAWFIXED, m_rcList, this, 101 ) );
	m_listbox->SetDLBStyle( m_dwACBStyle );
	m_listbox->ShowWindow( SW_SHOW );


	//
	// Resize this wnd so INTEGRAL_HEIGHT applies!?
	CRect rc;
	int nH = m_listbox->GetItemHeight(0);
	nH = nH*(int)m_list.size()+2;
	// Get screen size
	int nScrX = GetSystemMetrics( SM_CXSCREEN );
	int nScrY = GetSystemMetrics( SM_CYSCREEN );

	int nDefaultItems = static_cast<CAdvComboBox*>(m_pComboParent)->GetDefaultVisibleItems();

	//
	// Check to see if the window should be placed over the combobox
	int nY = lpCreateStruct->y;
	int nItems = (int)m_list.size();
	int nItemHeight = m_listbox->GetItemHeight(0);
	int nVisHeight = nScrY - lpCreateStruct->y;
	if( (nVisHeight / nItemHeight) < static_cast<CAdvComboBox*>(m_pComboParent)->GetMinVisibleItems() )
	{
		CRect rcCombo;
		m_pComboParent->GetWindowRect( &rcCombo );
		int nComboTopY = lpCreateStruct->y - rcCombo.Height();
		if( nDefaultItems == -1 || nDefaultItems > nItems )
		{
			nY = (nComboTopY - nH) < 0 ? 0 : (nComboTopY - nH);
			nH = (nY + nH) > nComboTopY ? nComboTopY - nY : nH;
		}
		else
		{
			nY = nComboTopY - nItemHeight*nDefaultItems;
			nY -= 2;
			nY = nY < 0 ? 0 : nY;
			nH = nComboTopY - nY;
		}
	}
	else
	{
		//
		// Place the window below the combo
		// Check height
		if( nDefaultItems == -1 || nDefaultItems > nItems )
		{
			if( lpCreateStruct->y + nH > nScrY )
			{
				nH = nScrY - lpCreateStruct->y;
			}
			else
			if( nH < ::GetSystemMetrics(SM_CYVSCROLL) )
			{
				nH = ::GetSystemMetrics(SM_CYVSCROLL);
			}
		}
		else
		{
			nH = nDefaultItems * nItemHeight;
			nH = (nY+nH) > nScrY ? nScrY-nY : nH;
			nH += 2;
		}
	}

	// Calc width
	int nW = 0;
	CSize size(0,0);
	for( m_iter = m_list.begin(); m_iter != m_list.end(); ++m_iter )
	{
		m_listbox->GetTextSize( m_iter->strText.c_str(), (int)m_iter->strText.length(), size );
		nW = (size.cx > nW) ? size.cx : nW;
	}
	nW += m_rcScroll.Width() +8;
	// Check min width
	if( nW < m_rcList.Width() )
	{
		nW = lpCreateStruct->cx;
	}
	// Check max width
	int nX = lpCreateStruct->x;
	if( nW > nScrX - lpCreateStruct->x )
	{
		nX = nScrX - nW;
		if( nX < 0 )
			nX = 0;
	}
	if( nX == 0 && nW > nScrX )
		nW = nScrX;

	SetWindowPos( &wndTopMost, nX, nY, nW, nH, SWP_SHOWWINDOW|SWP_NOZORDER );

	GetClientRect( &rcWnd );

	//
	// Create sizehandle
	m_rcSizeHandle = rcWnd;
	GetClientRect( &m_rcSizeHandle );
	m_rcSizeHandle.left = m_rcSizeHandle.right - ::GetSystemMetrics(SM_CXVSCROLL);
	m_rcSizeHandle.top = m_rcSizeHandle.bottom - ::GetSystemMetrics(SM_CYVSCROLL);

	//
	// Add items to listbox
	LIST_ITEM item;
	for( m_iter = m_list.begin(); m_iter != m_list.end(); ++m_iter )
	{
		item = *m_iter;
		m_listbox->AddListItem( item );
	}

	//
	// Set values in scrollbar
	m_scrollbar->SetListBox( m_listbox );
	m_scrollbar->ShowScrollBar();
//	SendMessage( WM_SHOWWINDOW, (WPARAM)1, 0 );

	//
	//
	SetCapture();
	return 0;
}



LONG CDropWnd::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
	SetCapture();
	return FALSE;
}

LONG CDropWnd::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
	ReleaseCapture();
	return FALSE;
}


void CDropWnd::OnMouseMove(UINT nFlags, CPoint point) 
{
	//
	//
	if( m_bResizing )
	{
		CRect rcWnd;
		GetWindowRect( &rcWnd );
		if( point.x + m_nMouseDiffX >= ::GetSystemMetrics(SM_CXVSCROLL) )
		{
			rcWnd.right = rcWnd.left + point.x + m_nMouseDiffX +2;
		}
		else
		{
			rcWnd.right = rcWnd.left + ::GetSystemMetrics(SM_CXVSCROLL) +1;
		}

		if( point.y + m_nMouseDiffY >= ::GetSystemMetrics(SM_CYVSCROLL) )
		{
			rcWnd.bottom = rcWnd.top + point.y + m_nMouseDiffY +2;
		}
		else
		{
			rcWnd.bottom = rcWnd.top + ::GetSystemMetrics(SM_CXVSCROLL) +1;
		}
		MoveWindow( &rcWnd );
		return;
	}

	//
	// Check point
	if( m_rcList.PtInRect( point ) )
	{
		HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
		SetCursor( hCursor );
		ReleaseCapture();
		m_scrollbar->SendMessage( WM_VRC_RELEASECAPTURE );
		m_listbox->SetFocus();
		m_listbox->SendMessage( WM_VRC_SETCAPTURE );
	}
	else
	if( m_rcScroll.PtInRect( point ) )
	{
		HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
		SetCursor( hCursor );
		m_scrollbar->SetFocus();
		ReleaseCapture();
		m_listbox->SendMessage( WM_VRC_RELEASECAPTURE );
		m_scrollbar->SendMessage( WM_VRC_SETCAPTURE );
	}
	else
	{
		if( m_rcSizeHandle.PtInRect( point ) )
		{
			HCURSOR hCursor = LoadCursor( NULL, IDC_SIZENWSE );
			SetCursor( hCursor );
		}
		else
		{
			HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
			SetCursor( hCursor );
		}
		SetCapture();
		CWnd::OnMouseMove(nFlags, point);
	}
}

void CDropWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{
	if( m_rcSizeHandle.PtInRect( point ) )
	{
		m_bResizing = true;
		m_ptLastResize = point;

		CRect rcClient;
		GetClientRect( &rcClient );
		m_nMouseDiffX = rcClient.Width() - point.x;
		m_nMouseDiffY = rcClient.Height() - point.y;
		return;
	}


//
// Clean up the code below...
//

	CRect rc;
	CRect rcVScroll(0,0,0,0);
	GetClientRect( &rc );
	DWORD dwStyle = GetStyle();
	
	// Take away vertical scroll

	if( rc.PtInRect( point ) )
	{
	}
	else
	{
		//
		// Calc the point in the parent(PropertyListBox)
		CWnd* pParent = m_pComboParent->GetParent();
		CRect rcParentClient;
		CRect rcParentWnd;
		pParent->GetClientRect( &rcParentClient );
		pParent->GetWindowRect( &rcParentWnd );

		CPoint pt = point;
		ClientToScreen( &pt );
			pt.x -= rcParentWnd.left;
			pt.y -= rcParentWnd.top;

		CAdvComboBox* pList = static_cast<CAdvComboBox*>(m_pComboParent);
		if( !pList->PointInWindow( pt ) )
		{
			
			ReleaseCapture();

//			CString str;
//			str.Format( "MousePos (NOT PtInRect): X:%d, y:%d\n", pt.x, pt.y );
//			OutputDebugString( str );
			m_pComboParent->PostMessage( WM_DESTROY_DROPLIST );
		}
		else
		{
//			CString str;
//			str.Format( "MousePos in combo\n " );
//			OutputDebugString( str );
			ReleaseCapture();
			m_pComboParent->PostMessage( WM_DESTROY_DROPLIST );
		}
		//
		// Send input to parent
/*		INPUT input;
		input.type = INPUT_MOUSE;
		input.mi.dx = pt.x;
		input.mi.dy = pt.y;
		input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
		input.mi.time = 0;
		SendInput( 1, &input, sizeof(INPUT) );
*/
	}

	
	CWnd::OnLButtonDown(nFlags, point);
}

void CDropWnd::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if( m_bResizing )
	{
		m_bResizing = false;
	}
	CWnd::OnLButtonUp(nFlags, point);
}




void CDropWnd::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);

	m_rcList.SetRect( 0, 0, cx-::GetSystemMetrics(SM_CXVSCROLL), cy );
	m_listbox->MoveWindow( &m_rcList );

	m_rcScroll.SetRect( cx-::GetSystemMetrics(SM_CXVSCROLL), 0, cx, cy-::GetSystemMetrics(SM_CYVSCROLL) );
	m_scrollbar->MoveWindow( &m_rcScroll );

	m_rcSizeHandle.SetRect( cx-::GetSystemMetrics(SM_CXVSCROLL), cy-::GetSystemMetrics(SM_CYVSCROLL), cx, cy );
	InvalidateRect( &m_rcSizeHandle );

	//
	// Fix the scrollbar
	SCROLLINFO info;
	info.cbSize = sizeof(SCROLLINFO);
	if( m_scrollbar->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
	{
		info.nPage = m_listbox->GetBottomIndex() - m_listbox->GetTopIndex();
		m_scrollbar->SetScrollInfo( &info );
	}

}

void CDropWnd::OnPaint() {
	CPaintDC dc(this);
	dc.DrawFrameControl(m_rcSizeHandle, DFC_SCROLL, DFCS_SCROLLSIZEGRIP );
}

BOOL CDropWnd::DestroyWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	ReleaseCapture();
	m_listbox->DestroyWindow();
	
	return CWnd::DestroyWindow();
}

void CDropWnd::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CWnd::OnShowWindow(bShow, nStatus);
	
	// TODO: Add your message handler code here
	if( bShow )
	{
//		AnimateWindow( GetSafeHwnd(), 80, AW_VER_POSITIVE | AW_ACTIVATE | AW_SLIDE);
	}
	else
	{
//		AnimateWindow( GetSafeHwnd(), 80, AW_VER_NEGATIVE | AW_HIDE | AW_SLIDE);
	}
	
}


void CDropWnd::OnActivateApp(BOOL bActive, DWORD hTask) 
{
	CWnd::OnActivateApp(bActive, hTask);
	
	// TODO: Add your message handler code here
	if( bActive )
	{
	}
	else
	{
		m_pComboParent->PostMessage( WM_DESTROY_DROPLIST );
	}
	
}





⌨️ 快捷键说明

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