先上效果图:

图中用了一个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 ){}

MFC之ListCtrl动态添加按钮的更多相关文章

  1. iOS: 学习笔记, 动态添加按钮

    1. 新建iOS -> Single View Application. 2. 个性控制器文件YYViewController.m(此处修改为你相应的控制器文件名) // // YYViewCo ...

  2. WPF 动态添加按钮以及样式字典的引用(Style introduction)

    我们想要达到的结果是,绑定多个Checkbox然后我们还可以获取它是否被选中,其实很简单,我们只要找到那几个关键的对象就可以了. 下面是Ui,其中定义了一个WrapPanel来存放CheckBox,还 ...

  3. MFC 单文档添加按钮

    VS 单文档 添加按钮 今天做项目需要在单文档中创建按钮来响应函数,即点击按钮,调用某函数,特此记录. 1. 在XXXView中添加CButton变量,例如 CButton start; 2. 下来就 ...

  4. 【代码笔记】iOS-UIActionSheet动态添加按钮

    一,效果图. 二,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController : UIVi ...

  5. (转载)VC/MFC 工具栏上动态添加组合框等控件的方法

    引言 工具条作为大多数标准的Windows应用程序的 一个重要组成部分,使其成为促进人机界面友好的一个重要工具.通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开 ...

  6. VC/MFC 工具栏上动态添加组合框等控件的方法

    引言 工具条作为大多数标准的Windows应用程序的一个重要组成部分,使其成为促进人机界面友好的一个重要工具.通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开发 ...

  7. winfrom_动态添加按钮button(设置颜色,大小,按钮字体大小、颜色,位置,事件)

    List<string> strColor = new List<string>(); strColor.Add("#e67817"); strColor. ...

  8. 动态添加试题选项按钮 radioButton(一)

    最近在做WebView加载试题的功能,但是选项按钮如果放的WebView中,点击时反应很慢.于是把选项用原生的RadioButton,而试题题目和答案放在WebView中.但是选项的个数不确定,所以需 ...

  9. Android 在程序中动态添加 View 布局或控件

    有时我们需要在程序中动态添加布局或控件等,下面用程序来展示一下相应的方法: 1.addView 添加View到布局容器 2.removeView 在布局容器中删掉已有的View 3.LayoutPar ...

随机推荐

  1. NO.1:自学tensorflow之路------神经网络背景知识

    引言 从本周,我将开始tensorflow的学习.手头只有一本<tensorflow:实战Google深度学习框架>,这本书对于tensorflow的入门有一定帮助.tensorflow中 ...

  2. dp算法之硬币找零问题

    题目:硬币找零 题目介绍:现在有面值1.3.5元三种硬币无限个,问组成n元的硬币的最小数目? 分析:现在假设n=10,画出状态分布图: 硬币编号 硬币面值p 1 1 2 3 3 5 编号i/n总数j ...

  3. C# 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。

    在菜单 “项目”的最下面 工程属性 菜单,选择“生成”选项卡,将目标平台由“Amy CPU”或者“*64”改成“*86”.

  4. 福大软工1816:Beta(3/7)

    Beta 冲刺 (3/7) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务 文字/口头描述 参与开发关键词提醒部分 展示GitHu ...

  5. C#高级编程 (第六版) 学习 第五章:数组

    第五章 数组 1,简单数组 声明:int[] myArray; 初始化:myArray = new int[4]; 为数组分配内存. 还可以用如下的方法: int[] myArray = new in ...

  6. 按照事务类型分析 DB2 事物的性能

    概述 事务是数据库系统中的核心概念之一.作为数据库系统的逻辑工作单元(Unit of Work),事务必须具有四个属性,即原子性.一致性.隔离性和持久性(ACID).数据库系统往往通过锁机制保证事务的 ...

  7. Microsoft Orleans 之安装

    先决条件 Orleans 是一个.net 类库集,为了使用它,你需要.net 4.5.1 或者更高版本,开发工具集需要visual studio 2015 或者更高版本或者其他支持的开发工具,不支持V ...

  8. PAT---福尔摩斯约会时间

    主要为字符串的处理,注意读懂题目意思. 设置输出域宽和填充字符的函数分别为setw(int n),setfill(char c);两个函数的头文件为#include<iomanip>; # ...

  9. jQuery之回到顶部

    实现回到顶部的功能,根据学了元素滚动实现,温习知识点. 做之前先理清一下步骤和思路: 1.获得页面的滚动长度 var $page = $("html,body"); var dis ...

  10. Hibernate 中 load() 方法导致的 noSession 异常

    之所以要写这个,是因为最近碰到了一个延迟加载的 load() 导致出现 noSession 的异常. 下面第三种方式解决这个问题需要用到一个本地线程的对象,也就是 ThreadLocal 类,之前写过 ...