win32listview.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 2,606 行 · 第 1/5 页

CPP
2,606
字号
//Win32Listview.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#ifdef __GNUWIN32__#define _WIN32_IE   0x0400  //this may be a bogus thing to do !#endif//__GNUWIN32__#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/ListViewControl.h"#include "vcf/ApplicationKit/Win32Listview.h"#if defined(__GNUWIN32__) || defined(VCF_MINGW)//add some stupid defines here since they seem to be missing from the mingw Win32 API headers#if (_WIN32_IE >= 0x0400)#if !defined(VCF_MINGW)typedef struct tagNMLVGETINFOTIPA{    NMHDR hdr;    DWORD dwFlags;    LPSTR pszText;    int cchTextMax;    int iItem;    int iSubItem;    LPARAM lParam;} NMLVGETINFOTIPA, *LPNMLVGETINFOTIPA;typedef struct tagNMLVGETINFOTIPW{    NMHDR hdr;    DWORD dwFlags;    LPWSTR pszText;    int cchTextMax;    int iItem;    int iSubItem;    LPARAM lParam;} NMLVGETINFOTIPW, *LPNMLVGETINFOTIPW;#endif// NMLVGETINFOTIPA.dwFlag values#define LVGIT_UNFOLDED  0x0001#define LVN_GETINFOTIPA          (LVN_FIRST-57)#define LVN_GETINFOTIPW          (LVN_FIRST-58)#ifdef UNICODE    #define LVN_GETINFOTIP          LVN_GETINFOTIPW    #define NMLVGETINFOTIP          NMLVGETINFOTIPW    #define LPNMLVGETINFOTIP        LPNMLVGETINFOTIPW#else    #define LVN_GETINFOTIP          LVN_GETINFOTIPA    #define NMLVGETINFOTIP          NMLVGETINFOTIPA    #define LPNMLVGETINFOTIP        LPNMLVGETINFOTIPA#endif#endif      // _WIN32_IE >= 0x0400#if (_WIN32_IE >= 0x0400)#define LVN_HOTTRACK            (LVN_FIRST-21)#endif#if (_WIN32_IE >= 0x0300)#define LVN_ODCACHEHINT         (LVN_FIRST-13)#define LVN_ODFINDITEMA         (LVN_FIRST-52)#define LVN_ODFINDITEMW         (LVN_FIRST-79)#define LVN_ITEMACTIVATE        (LVN_FIRST-14)#define LVN_ODSTATECHANGED      (LVN_FIRST-15)    #ifdef UNICODE        #define LVN_ODFINDITEM          LVN_ODFINDITEMW    #else        #define LVN_ODFINDITEM          LVN_ODFINDITEMA    #endif#endif      // _WIN32_IE >= 0x0300#if (_WIN32_IE >= 0x0300)#define LVN_MARQUEEBEGIN        (LVN_FIRST-56)#endif#if (_WIN32_IE >= 0x0300)//==================== CUSTOM DRAW ==========================================// custom draw return flags// values under 0x00010000 are reserved for global custom draw values.// above that are for specific controls/*#define CDRF_NOTIFYITEMDRAW     0x00000020#if (_WIN32_IE >= 0x0400)#define CDRF_NOTIFYSUBITEMDRAW  0x00000020  // flags are the same, we can distinguish by context#endif#define CDRF_NOTIFYPOSTERASE    0x00000040// drawstage flags// values under 0x00010000 are reserved for global custom draw values.// above that are for specific controls#define CDDS_PREPAINT           0x00000001#define CDDS_POSTPAINT          0x00000002#define CDDS_PREERASE           0x00000003#define CDDS_POSTERASE          0x00000004// the 0x000010000 bit means it's individual item specific#define CDDS_ITEM               0x00010000#define CDDS_ITEMPREPAINT       (CDDS_ITEM | CDDS_PREPAINT)#define CDDS_ITEMPOSTPAINT      (CDDS_ITEM | CDDS_POSTPAINT)#define CDDS_ITEMPREERASE       (CDDS_ITEM | CDDS_PREERASE)#define CDDS_ITEMPOSTERASE      (CDDS_ITEM | CDDS_POSTERASE)#if (_WIN32_IE >= 0x0400)#define CDDS_SUBITEM            0x00020000#endif// itemState flags#define CDIS_SELECTED       0x0001#define CDIS_GRAYED         0x0002#define CDIS_DISABLED       0x0004#define CDIS_CHECKED        0x0008#define CDIS_FOCUS          0x0010#define CDIS_DEFAULT        0x0020#define CDIS_HOT            0x0040#define CDIS_MARKED         0x0080#define CDIS_INDETERMINATE  0x0100typedef struct tagNMCUSTOMDRAWINFO{    NMHDR hdr;    DWORD dwDrawStage;    HDC hdc;    RECT rc;    DWORD dwItemSpec;  // this is control specific, but it's how to specify an item.  valid only with CDDS_ITEM bit set    UINT  uItemState;    LPARAM lItemlParam;} NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW;typedef struct tagNMTTCUSTOMDRAW{    NMCUSTOMDRAW nmcd;    UINT uDrawFlags;} NMTTCUSTOMDRAW, FAR * LPNMTTCUSTOMDRAW;*/#endif      // _WIN32_IE >= 0x0300/*#if (_WIN32_IE >= 0x0400)#define ListView_SetExtendedListViewStyleEx(hwndLV, dwMask, dw)\        (DWORD)SNDMSG((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, dwMask, dw)#endif#define LVM_GETEXTENDEDLISTVIEWSTYLE (LVM_FIRST + 55)#define ListView_GetExtendedListViewStyle(hwndLV)\        (DWORD)SNDMSG((hwndLV), LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)#define LVS_EX_GRIDLINES        0x00000001#define LVS_EX_SUBITEMIMAGES    0x00000002#define LVS_EX_CHECKBOXES       0x00000004#define LVS_EX_TRACKSELECT      0x00000008#define LVS_EX_HEADERDRAGDROP   0x00000010#define LVS_EX_FULLROWSELECT    0x00000020 // applies to report mode only#define LVS_EX_ONECLICKACTIVATE 0x00000040#define LVS_EX_TWOCLICKACTIVATE 0x00000080#if (_WIN32_IE >= 0x0400)#define LVS_EX_FLATSB           0x00000100#define LVS_EX_REGIONAL         0x00000200#define LVS_EX_INFOTIP          0x00000400 // listview does InfoTips for you#define LVS_EX_UNDERLINEHOT     0x00000800#define LVS_EX_UNDERLINECOLD    0x00001000#define LVS_EX_MULTIWORKAREAS   0x00002000#endif*/#endif //__GNUWIN32__using namespace VCFWin32;using namespace VCF;Win32Listview::Win32Listview( ListViewControl* listviewControl ):	AbstractWin32Component( listviewControl ),	listviewControl_( listviewControl ),	oldHeaderWndProc_(NULL),	largeImageListCtrl_(NULL),	smallImageListCtrl_(NULL),	internalMessage_(false){}Win32Listview::~Win32Listview(){	if ( NULL != largeImageListCtrl_ ) {		ImageList_Destroy( largeImageListCtrl_ );	}	if ( NULL != smallImageListCtrl_ ) {		ImageList_Destroy( smallImageListCtrl_ );	}}void Win32Listview::create( Control* owningControl ){	itemAddedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onItemAdded, "Win32Listview::onItemAdded" );	itemDeletedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onItemDeleted, "Win32Listview::onItemDeleted" );	itemChangedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onItemChanged, "Win32Listview::onItemChanged" );	itemSelectedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onItemSelected, "Win32Listview::onItemSelected" );	itemPaintedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onItemPaint, "Win32Listview::onItemPaint" );	subItemAddedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onSubItemAdded, "Win32Listview::onSubItemAdded" );	subItemDeletedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onSubItemDeleted, "Win32Listview::onSubItemDeleted" );	subItemChangedHandler_ =		new ItemEventHandler<Win32Listview>( this, &Win32Listview::onSubItemChanged, "Win32Listview::onSubItemChanged" );	CreateParams params = createParams();	backColor_.copy( owningControl->getColor() );	/*	if ( true != isRegistered() ){		registerWin32Class( getClassName(), wndProc_  );	}	*/	Win32ToolKit* toolkit = (Win32ToolKit*)UIToolkit::internal_getDefaultUIToolkit();	HWND parent = toolkit->getDummyParent();	String className = getClassName();	if ( System::isUnicodeEnabled() ) {		hwnd_ = ::CreateWindowExW( params.second,		                             WC_LISTVIEWW,									 NULL,									 params.first,		                             0,									 0,									 1,									 1,									 parent,									 NULL,									 ::GetModuleHandle(NULL),									 NULL );	}	else {		hwnd_ = ::CreateWindowExA( params.second,		                             WC_LISTVIEWA,//"SysListView32",//className.c_str(),									 NULL,									 params.first,		                             0,									 0,									 1,									 1,									 parent,									 NULL,									 ::GetModuleHandle(NULL),									 NULL );	}	if ( NULL != hwnd_ ){		Win32Object::registerWin32Object( this );		subclassWindow();		registerForFontChanges();		COLORREF backColor = backColor_.getColorRef32();		ListView_SetBkColor( hwnd_, backColor );	}	else {		//throw exception	}	setCreated( true );	headerControlIsTracking_ = false;}void Win32Listview::updateItemSubItems( ListItem* item ){	if ( NULL == item ) {		return;	}	Enumerator<ListItem::SubItem*>* subItems = item->getSubItems();	int index = item->getIndex();	int subItemIndex = 1;	while ( true == subItems->hasMoreElements() ) {		ListItem::SubItem* subItem = subItems->nextElement();		if  (System::isUnicodeEnabled() ) {			LVITEMW lvItem = {0};			lvItem.iSubItem = subItemIndex;			lvItem.pszText  = LPSTR_TEXTCALLBACKW;			SendMessage( hwnd_, LVM_SETITEMTEXTW, index, (LPARAM)&lvItem );		}		else {			LVITEMA lvItem = {0};			lvItem.iSubItem = subItemIndex;			lvItem.pszText  = LPSTR_TEXTCALLBACKA;			SendMessage( hwnd_, LVM_SETITEMTEXTA, index, (LPARAM)&lvItem );		}		subItemIndex ++;	}}void Win32Listview::onSubItemChanged( ItemEvent* event ){	ListItem* item = (ListItem*)event->getSource();	updateItemSubItems( item );}void Win32Listview::onSubItemAdded( ItemEvent* event ){	onSubItemChanged( event );}void Win32Listview::onSubItemDeleted( ItemEvent* event ){	ListItem* item = (ListItem*)event->getSource();	HWND header = ListView_GetHeader( hwnd_ );	if ( NULL != header ) {		int count = Header_GetItemCount( header );		for ( int i=1;i<count;i++ ) {			if  (System::isUnicodeEnabled() ) {				LVITEMW lvItem = {0};				lvItem.iSubItem = i;				lvItem.pszText  = L"";				SendMessage( hwnd_, LVM_SETITEMTEXTW, item->getIndex(), (LPARAM)&lvItem );			}			else {				LVITEMA lvItem = {0};				lvItem.iSubItem = i;				lvItem.pszText  = "";				SendMessage( hwnd_, LVM_SETITEMTEXTA, item->getIndex(), (LPARAM)&lvItem );			}		}	}	onSubItemChanged( event );}void Win32Listview::registerHeaderWndProc(){	if ( NULL == oldHeaderWndProc_ ) {		HWND headerWnd = ListView_GetHeader( hwnd_ );		if ( NULL != headerWnd ) {			SetWindowLong( headerWnd, GWL_USERDATA, (LONG)(LPARAM)this );			oldHeaderWndProc_ = (WNDPROC) SetWindowLong( headerWnd, GWL_WNDPROC, (LONG)Win32Listview::Header_WndProc );		}	}}Win32Object::CreateParams Win32Listview::createParams(){	Win32Object::CreateParams result;	result.first = BORDERED_VIEW | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_ICON | LVS_SHOWSELALWAYS;	result.first &= ~WS_BORDER;	result.second = 0;	return result;}LRESULT CALLBACK Win32Listview::Header_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){	LRESULT result = 0;	Win32Listview* win32ListView = (Win32Listview*) GetWindowLong( hWnd, GWL_USERDATA );	switch ( message ) {		case WM_ERASEBKGND : {			result = 0;		}		break;		case WM_PAINT:{			//result =			PAINTSTRUCT ps;			HDC dc = BeginPaint( hWnd, &ps );			RECT r;			GetClientRect( hWnd, &r );			FillRect( dc, &r, (HBRUSH) (COLOR_3DFACE + 1) );			if ( System::isUnicodeEnabled() ) {				result = CallWindowProcW( win32ListView->oldHeaderWndProc_, hWnd, WM_PAINT, (WPARAM)dc, 0 );			}			else {				result = CallWindowProcA( win32ListView->oldHeaderWndProc_, hWnd, WM_PAINT, (WPARAM)dc, 0 );			}			EndPaint( hWnd, &ps );		}		break;		case WM_DRAWITEM : {						if ( System::isUnicodeEnabled() ) {				result = CallWindowProcW( win32ListView->oldHeaderWndProc_, hWnd, message, wParam, lParam );			}			else {				result = CallWindowProcA( win32ListView->oldHeaderWndProc_, hWnd, message, wParam, lParam );			}		}		break;		case WM_LBUTTONDOWN : {			win32ListView->headerControlIsTracking_ = true;			if ( System::isUnicodeEnabled() ) {				result = CallWindowProcW( win32ListView->oldHeaderWndProc_, hWnd, message, wParam, lParam );			}			else {				result = CallWindowProcA( win32ListView->oldHeaderWndProc_, hWnd, message, wParam, lParam );			}		}		break;		default : {			if ( System::isUnicodeEnabled() ) {				result = CallWindowProcW( win32ListView->oldHeaderWndProc_, hWnd, message, wParam, lParam );			}			else {				result = CallWindowProcA( win32ListView->oldHeaderWndProc_, hWnd, message, wParam, lParam );			}		}		break;	}	return result;}void Win32Listview::postPaintItem( NMLVCUSTOMDRAW* drawItem ){	ListModel* model = listviewControl_->getListModel();	ListItem* item = (ListItem*)drawItem->nmcd.lItemlParam;		if ( NULL != item ) {		//item->setSelected( isItemSelected( item ) );		if ( true == item->canPaint() ) {			RECT tmp = {0,0,0,0};			GraphicsContext* ctx = NULL;			ListView_GetItemRect( hwnd_, drawItem->nmcd.dwItemSpec,				&tmp, LVIR_BOUNDS );			Rect itemRect( tmp.left, tmp.top, tmp.right, tmp.bottom );			ctx = peerControl_->getContext();			item->paint( ctx, &itemRect );			DWORD style = ::GetWindowLong( hwnd_, GWL_STYLE );			if ( style & LVS_REPORT ) {				ColumnModel* colModel = listviewControl_->getColumnModel();				if ( NULL != colModel ) {					ulong32 colIndex = 0;					Enumerator<ColumnItem*>* columns = colModel->getItems();					Enumerator<ListItem::SubItem*>* subItems = item->getSubItems();					Rect subItemRect = itemRect;					while ( (true == columns->hasMoreElements()) && (true == subItems->hasMoreElements()) ) {						ColumnItem* column = columns->nextElement();						subItemRect.right_ = subItemRect.left_ + column->getWidth();						if ( colIndex > 0 ) {							ListItem::SubItem* subItem = subItems->nextElement();							subItem->paint( ctx, &subItemRect, colIndex );						}						subItemRect.left_ = subItemRect.right_;						colIndex ++;

⌨️ 快捷键说明

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