先上效果图:

图中用了一个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. hdu - 6276,2018CCPC湖南全国邀请赛A题,水题,二分

    题意: 求H的最大值,  H是指存在H篇论文,这H篇被引用的次数都大于等于H次. 思路:题意得,  最多只有N遍论文,所以H的最大值为N, 常识得知H的最小值为0. 所以H的答案在[0,N]之间,二分 ...

  2. SPP-net论文总结

    SPPNet方法来自<Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition> ,是大神 ...

  3. Python20-Day01

    简述编译型与解释型语言的区别,且分别列出你知道的哪些语言属于编译型,哪些属于解释 编译型语言是一种以编译器来实现的编程语言,优缺点:执行速度快,调试麻烦 编译型语言:Java,Go,C,C++ 解释性 ...

  4. java 数据存储

    简单的记录一下而已. 1.寄存器: 特点:快,存储有限. 存储地点:处理器内部. 2.堆栈 特点:仅次于寄存器快,通过堆栈指针在处理器获取支持.堆栈指针下移,分配内存,上移,释放内存.此外须知生命周期 ...

  5. 一个网页从输入URL到页面加载完的过程

    过程概述 1.浏览器查找域名对应的IP地址 2.浏览器根据IP地址与服务器建立socket连接 3.浏览器与服务器通信:浏览器请求,服务器处理请求和响应 4.浏览器与服务器断开连接 具体过程 1.搜索 ...

  6. AOP:jdk的动态代理

    1.文件结构 2.建立接口 package com.wangcf.manager; public interface IUserManager { public void add(); public ...

  7. python 二维矩阵及转byte知识点

    1.注意python中的数组和list形式混合: 数组在numpy里面: 2.二维数组这样定义可以修改固定位置的值: rawDataArray_temp = [([0]*nIRImageWidth)f ...

  8. 基础算法学习2-dp

    一.算法题: 最大子阵 给定一个n×m 的矩阵 A,求A 中的一个非空子矩阵,使这个子矩阵中的元素和最大.其中,A 的子矩阵指在 A 中行和列均连续的一部分.输入格式输入的第一行包含两个整数 n,m( ...

  9. 第二次c++作业(觉得渐渐入门系列)

    其实说实话,我还是不敢很确定地说面向对象和面向过程这两种语言,我确实能分得开,但是我觉得倒是比以前好很多了.//(大概是谈了对象,知道了什么是面向对象编程) 1.从个人角度来说, a:面向过程就是-- ...

  10. maven 添加tomcat依赖

    https://my.oschina.net/angel243/blog/178554