MFC之ListCtrl动态添加按钮

先上效果图:

图中用了一个CListCtrl插件,隐藏了网格线(LVS_EX_GRIDLINES)。

添加了“删除”按钮(按钮上贴了图片),选中哪一行则显示在哪一行。

有两种方式创建按钮,一种是直接根据行数(比如n行)创建n按钮,然后根据自己需求全部显示,或是动态显示,只显示所选中的那一行按钮;

另一种是每次只创建选中行的一个按钮,并且销毁上一次创建的按钮(第一次除外)。

本实例选用第二种方法,第一种方法也用了,但是效果不好,有其他bug.

-----------------------------------------------------------------创建按钮源代码如下---------------------------------------------------------------------

有4个基本文件,ButtonEx.h,   ButtonEx.cpp,   ListCtrlEx.h,   ListCtrlEx.cpp.

//ButtonEx.h
#pragma once

#include "WDBitmapButton.h"
// CButtonEx
#define  WM_BN_CLICK  WM_USER + 100
class CButtonEx : public CWDBitmapButton
{
	DECLARE_DYNAMIC(CButtonEx)

public:
	CButtonEx();
	CButtonEx( int nItem, int nSubItem, CRect rect, HWND hParent );
	virtual ~CButtonEx();

protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClicked();
	int m_inItem;
	int m_inSubItem;
	CRect m_rect;
	HWND m_hParent;
	BOOL bEnable;
};

  

// ButtonEx.cpp : 实现文件
//

#include "stdafx.h"
#include "ButtonEx.h"


// CButtonEx

IMPLEMENT_DYNAMIC(CButtonEx, CButton)

CButtonEx::CButtonEx()
{

}

CButtonEx::~CButtonEx()
{
}

CButtonEx::CButtonEx( int nItem, int nSubItem, CRect rect, HWND hParent )    //-
{
    m_inItem = nItem;
    m_inSubItem = nSubItem;
    m_rect = rect;
    m_hParent = hParent;
    bEnable = TRUE;
}

BEGIN_MESSAGE_MAP(CButtonEx, CButton)
    ON_CONTROL_REFLECT(BN_CLICKED, &CButtonEx::OnBnClicked)
END_MESSAGE_MAP()


// CButtonEx 消息处理程序


void CButtonEx::OnBnClicked()
{
    // TODO: 在此添加控件通知处理程序代码
    ::SendMessage( m_hParent, WM_BN_CLICK, m_inItem, m_inSubItem );   //
}

//ListCtrl.h
#pragma once #include "ButtonEx.h" #include <map> using namespace std; typedef map<int,CButtonEx*>button_map; // CListCtrlEx class CListCtrlEx : public CListCtrl { DECLARE_DYNAMIC(CListCtrlEx) public: CListCtrlEx(); virtual ~CListCtrlEx(); protected: DECLARE_MESSAGE_MAP() public: void createItemButton( int nItem, int nSubItem, HWND hMain ); void release(); void deleteItemEx( int iCount, int nItem ); button_map m_mButton; WCHAR * charToWchar(char *s); public: UINT m_uID; //void updateListCtrlButtonPos(); //void enableButton( BOOL bFlag, int iItem ); };

  

// ListCtrlEx.cpp : 实现文件
//

#include "stdafx.h"
#include "ListCtrlEx.h"
#include "resource.h"
#define  MAX_PATH 256

// CListCtrlEx

IMPLEMENT_DYNAMIC(CListCtrlEx, CListCtrl)

CListCtrlEx::CListCtrlEx()
{
}

CListCtrlEx::~CListCtrlEx()
{
}


BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
END_MESSAGE_MAP()



// CListCtrlEx 消息处理程序

void CListCtrlEx::createItemButton( int nItem, int nSubItem, HWND hMain )
{

	m_mButton.clear();
	char *name = NULL;
	CString strPath;
	::GetModuleFileName( NULL, strPath.GetBuffer(MAX_PATH), MAX_PATH );
	strPath.ReleaseBuffer();//当前文件的绝对路径
	strPath = strPath.Left(strPath.ReverseFind(_T('\\')));//文件所在目录
	strPath=strPath.Left(strPath.ReverseFind(_T('\\')));//文件目录的父目录

	name = (LPSTR)(LPCSTR)strPath;
	WCHAR name_on[256] = {};

	wcscpy(name_on,charToWchar(name));
	wcscat(name_on,L"//Invaray//Invaray//res//delete.png");
	
		
	CRect rect;
	if( !EnsureVisible(nItem, TRUE)) 
		return ;

	GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
	DWORD dwStyle =  WS_CHILD | WS_VISIBLE;
	CButtonEx *pButton = new CButtonEx(nItem,nSubItem,rect,hMain);
	rect.bottom = rect.bottom-2;
	pButton->Create(_T(""),dwStyle, rect, this, m_uID);
	//m_uID++;
	pButton->SetImage(name_on,name_on,name_on);
	m_mButton.insert( make_pair( nItem, pButton ) );

	return;
}

WCHAR * CListCtrlEx::charToWchar(char *s)
{
	int w_nlen=MultiByteToWideChar(CP_ACP,0,s,-1,NULL,0);
	WCHAR *ret;
	ret=(WCHAR*) malloc(sizeof(WCHAR)*w_nlen);
	memset(ret,0,sizeof(ret));
	MultiByteToWideChar(CP_ACP,0,s,-1,ret,w_nlen);
	return ret;
}

void CListCtrlEx::release()
{
	button_map::iterator iter;
	iter = m_mButton.begin();
	while ( iter != m_mButton.end() )
	{
		delete iter->second;
		iter->second = NULL;
		iter++;
	}

}
void CListCtrlEx::deleteItemEx( int iCount, int nItem )
{
	//int iCount = GetItemCount();
	DeleteItem( nItem );
	button_map::iterator iter;
	button_map::iterator iterNext;
#ifdef USE_TOPINDEX_BUTTON
	//add-----------------------------------
	iter = m_mButton.find( nItem );
	iterNext = iter;
	iterNext++;
	while ( iterNext != m_mButton.end() )
	{
		iter->second->bEnable = iterNext->second->bEnable;
		iterNext++;
		iter++;
	}
	//------------------------------
#endif
	iter = m_mButton.find( iCount - 1 );
	if ( iter != m_mButton.end() )
	{
		delete iter->second;
		iter->second = NULL;
		m_mButton.erase( iter );
		//updateListCtrlButtonPos();
	}
}

//void CListCtrlEx::updateListCtrlButtonPos()
//{
//	int iTopIndex = GetTopIndex();
//	int nItem = iTopIndex;
//	button_map::iterator iter;
//	button_map::iterator iterUp;
//	int iLine = 0;
//#ifdef USE_TOPINDEX_BUTTON
//	iter = m_mButton.find( iTopIndex );
//	iterUp = m_mButton.begin();
//	while ( iter != m_mButton.end() )
//	{
//		iterUp->second->EnableWindow( iter->second->bEnable );
//		iter ++;
//		iterUp++;
//	}
//#else
//	for ( ; nItem < GetItemCount(); nItem++ )
//	{
//		iter = m_mButton.find(nItem);
//		if( iter!= m_mButton.end() )
//		{
//			CRect rect;
//			iterUp = m_mButton.find(iLine);
//			rect = iterUp->second->m_rect;
//			iter->second->MoveWindow( &rect );
//			iter->second->ShowWindow( SW_SHOW );
//			if( iLine < iTopIndex )
//			{
//				iterUp->second->ShowWindow( SW_HIDE );
//			}
//			iLine++;
//		}
//	}
//#endif
//
//}

//void CListCtrlEx::enableButton( BOOL bFlag, int iItem )
//{
//	button_map::iterator iter;
//#ifdef USE_TOPINDEX_BUTTON
//	int iTopIndex = GetTopIndex();
//	int nItem = iItem - iTopIndex;
//	iter = m_mButton.find( iItem );
//	if ( iter != m_mButton.end() )
//	{
//		iter->second->bEnable = bFlag;
//	}
//	iter = m_mButton.find( nItem );
//	if ( iter != m_mButton.end() )
//	{
//		iter->second->EnableWindow( bFlag );
//	}
//#else
//	iter = m_mButton.find( iItem );
//	if ( iter != m_mButton.end() )
//	{
//		iter->second->EnableWindow( bFlag );
//	}
//#endif
//
//}

  动态创建Button的函数

createItemButton( int nItem, int nSubItem, HWND hMain ),3个参数分别是行,列,父窗口句柄;

按钮所产生消息:

void CButtonEx::OnBnClicked()
  {
  // TODO: 在此添加控件通知处理程序代码
  ::SendMessage( m_hParent, WM_BN_CLICK, m_inItem, m_inSubItem ); //
  }

可以通过宏WM_BN_CLICK来接收相应的行数和列数。

如,在你的其他文件中添加消息响应函数,ON_MESSAGE( WM_BN_CLICK, onBnCLick) ,LRESULT CXXX::onBnCLick( WPARAM wParam, LPARAM lParam ){}

转载于:https://www.cnblogs.com/shanlizi/p/6845085.html

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC中,要在List Control中插入Check Button按钮,可以通过以下步骤实现: 1. 首先,在资源视图中,打开对话框的资源文件。选择List Control控件,设置其为“报表”风格。 2. 在对话框的OnInitDialog函数中,使用CListCtrl类的SubclassDlgItem函数将List Control控件关联到CListCtrl对象。 ``` m_ListCtrl.SubclassDlgItem(IDC_LIST_CONTROL, this); ``` 3. 调用CListCtrl对象的InsertColumn函数添加列头信息。 ``` m_ListCtrl.InsertColumn(0, _T("列1"), LVCFMT_LEFT, 150); m_ListCtrl.InsertColumn(1, _T("列2"), LVCFMT_LEFT, 100); ``` 4. 使用LVS_EX_CHECKBOXES样式来启用List Control中的Check Box功能。 ``` m_ListCtrl.SetExtendedStyle(m_ListCtrl.GetExtendedStyle() | LVS_EX_CHECKBOXES); ``` 5. 调用CListCtrl对象的InsertItem函数插入行,并使用SetItemText函数设置每行中列的文本内容。 ``` int nItemIndex = m_ListCtrl.InsertItem(0, _T("行1")); m_ListCtrl.SetItemText(nItemIndex, 1, _T("列1内容")); ``` 6. 调用CListCtrl对象的SetCheck函数来设置或清除Check Box的选中状态。 ``` m_ListCtrl.SetCheck(nItemIndex, TRUE); ``` 7. 如果需要处理Check Box的状态变化事件,可以使用NM_CLICK或NM_DBLCLK等消息处理函数,通过调用CListCtrl对象的GetCheck函数获取Check Box的状态。 ``` void CMyDialog::OnClickListControl(NMHDR *pNMHDR, LRESULT *pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if ((pNMListView->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2)) { // Check Box被选中 } else { // Check Box被清除 } *pResult = 0; } ``` 通过以上步骤,就可以在MFC中的List Control中插入Check Box按钮,并对其状态进行操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值