• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

技术天地

MFC之ListCtrl动态添加按钮

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/2019/0914/640.html

先上游戏开发运营效果图:
 
 
 
 
 
图中用了一个CListCtrl插件,躲藏了网格线(LVS_EX_GRIDLINES)。
 
添加了“删除”按钮(按钮上贴了图片),选中哪一行则显现在哪一行。
 
有两种方式创立按钮,一种是直接依据行数(比方n行)创立n按钮,然后依据本人需求全部显现,或是动态显现,只显现所选中的那一行按钮;
 
另一种是每次只创立选中行的一个按钮,并且销毁上一次创立的按钮(第一次除外)。
 
常州手游开发实例选用第二种办法,第一种办法也用了,但是效果不好,有其他bug.
 
-----------------------------------------------------------------创立按钮源代码如下---------------------------------------------------------------------
 
有4个根本文件,ButtonEx.h,   ButtonEx.cpp,   ListCtrlEx.h,   ListCtrlEx.cpp.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//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 );   //
}
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
//ListCtrl.h
#pragma once
#include "ButtonEx.h"
#include
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 );
};
  
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// 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的函数
 
1
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来接纳相应的行数和列数。
 
如,在你手机App外包的其他文件中添加音讯响应函数,ON_MESSAGE( WM_BN_CLICK, onBnCLick) ,LRESULT CXXX::onBnCLick( WPARAM wParam, LPARAM lParam ){}

上篇:上一篇:C++ map用法总结(整理)
下篇:下一篇:c++运用curl库发送https