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 + -
显示快捷键?