天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 57|回复: 0

MFC——LIstCtrl中嵌入Edit和Combobox控件

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
在MFC中经常会使用到ListCtrl控件,并且在控件中可以对单元格进行Edit的编辑或者ComboBox的编辑。实现ListCtrl中用edit和combobox编辑并数据同步,下面就是我用到的这个功能的简单实例。


为了让ListCtrol能更好的为我们所用,我们创建一个CEditListCtrl类继承自CListCtrl:


EditListCtrl.h


#pragma once
#include "ListEdit.h"
#include "ListComboBox.h"
#include "_PersistAttriMapXML.h"

#define  IDC_CELL_EDIT                0xffe0
#define  IDC_CELL_COMBOBOX        0xffe1

// CEditListCtrl

class CEditListCtrl : public CListCtrl
{
        DECLARE_DYNAMIC(CEditListCtrl)

public:
        CEditListCtrl();
        virtual ~CEditListCtrl();

protected:
        DECLARE_MESSAGE_MAP()

private:
        CListEdit m_edit;
        CListComboBox m_comboBox;
        int m_nRow; //行
        int m_nCol; //列

public:

        // 当编辑完成后同步数据
        void DisposeEdit(void);

        //发送失效消息
        void SendInvalidateMsg();

        // 设置当前窗口的风格
        void SetStyle(void);
        afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
        afx_msg void OnCbnSelchangeCbCellComboBox();

        afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
        afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
};




EditListCtrl.cpp
// EditListCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "CADIPlatform.h"
#include "EditListCtrl.h"
#include "CodeDBHelper.h"
#include "PersistXmlParser.h"

// CEditListCtrl

IMPLEMENT_DYNAMIC(CEditListCtrl, CListCtrl)

CEditListCtrl::CEditListCtrl()
{

}

CEditListCtrl::~CEditListCtrl()
{
}


BEGIN_MESSAGE_MAP(CEditListCtrl, CListCtrl)
        ON_WM_LBUTTONDBLCLK()
        ON_CBN_SELCHANGE(IDC_CELL_COMBOBOX, &CEditListCtrl::OnCbnSelchangeCbCellComboBox)
        ON_WM_HSCROLL()
        ON_WM_VSCROLL()
END_MESSAGE_MAP()



// CEditListCtrl message handlers

// 当编辑完成后同步数据
void CEditListCtrl::DisposeEdit(void)
{
        int nIndex = GetSelectionMark();
        //同步更新处理数据
        CString sLable;
        _PersistItem* pPersistItem = (_PersistItem*)GetItemData(m_nRow);
        if(NULL == pPersistItem) return ;

        if(0 == m_nCol) //edit控件
        {
                CString szLable;
                m_edit.GetWindowText(szLable);
                SetItemText(m_nRow,m_nCol,szLable);
                pPersistItem->szPersistence = szLable;

                m_edit.ShowWindow(SW_HIDE);
        }
        else if((1 == m_nCol) || (2 == m_nCol))
        {
                m_comboBox.ShowWindow(SW_HIDE);
        }

}

// 设置当前窗口的风格
void CEditListCtrl::SetStyle(void)
{
        LONG lStyle;
        lStyle = GetWindowLong(m_hWnd,GWL_STYLE);
        lStyle &= ~LVS_TYPEMASK; //清除显示方式
        lStyle |= LVS_REPORT; //list模式
        lStyle |= LVS_SINGLESEL; //单选
        SetWindowLong(m_hWnd,GWL_STYLE,lStyle);

        //扩展模式
        DWORD dwStyle = GetExtendedStyle();
        dwStyle |= LVS_EX_FULLROWSELECT; //选中某行使其整行高亮
        dwStyle |= LVS_EX_GRIDLINES; //网格线
        SetExtendedStyle(dwStyle); //设置扩展风格
}

void CEditListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
        // TODO: Add your message handler code here and/or call default
        CListCtrl::OnLButtonDblClk(nFlags, point);

        LVHITTESTINFO info;
        info.pt = point;
        info.flags = LVHT_ONITEMLABEL;

        if(SubItemHitTest(&info) >= 0)
        {
                m_nRow = info.iItem;
                m_nCol = info.iSubItem;

                CRect rect;
                GetSubItemRect(m_nRow,m_nCol,LVIR_LABEL,rect);

                CString strValue;
                strValue = GetItemText(m_nRow,m_nCol);

                _PersistItem* pPersistItem = (_PersistItem*)GetItemData(m_nRow);
                if(NULL == pPersistItem) return ;
                //Edit单元格
                if((0 == m_nCol))
                {
                        if(pPersistItem->nFlag & 0x01)
                        {
                                MB_PROMPT(RES_LOAD_STRING(IDS_ST_MODIFIYPKATTRI_20170502_01));
                                return ;
                        }

                        if(NULL == m_edit)
                        {
                                //创建Edit控件
                                // ES_WANTRETURN 使多行编辑器接收回车键输入并换行。如果不指定该风格,按回车键会选择缺省的命令按钮,这往往会导致对话框的关闭。
                                m_edit.Create(WS_CHILD|WS_BORDER|ES_AUTOHSCROLL|ES_WANTRETURN|ES_LEFT,
                                        CRect(0,0,0,0),this,IDC_CELL_EDIT);
                        }
                        m_edit.MoveWindow(rect);
                        m_edit.SetWindowText(strValue);
                        m_edit.ShowWindow(SW_SHOW);
                        m_edit.SetSel(0,-1);
                        m_edit.SetFocus();
                        UpdateWindow();
                }
                //ComboBox单元格
                if((1 == m_nCol))
                {
                        if(NULL == m_comboBox)
                        {
                                //创建Combobox控件
                                //CBS_DROPDOWNLIST : 下拉式组合框,但是输入框内不能进行输入
                                //WS_CLIPCHILDREN  :  其含义就是,父窗口不对子窗口区域进行绘制。默认情况下父窗口会对子窗口背景是进行绘制的,但是如果父窗口设置了WS_CLIPCHILDREN属性,父亲窗口不在对子窗口背景绘制.
                                m_comboBox.Create(WS_CHILD|WS_VISIBLE|CBS_SORT|WS_BORDER|CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP|CBS_AUTOHSCROLL,
                                        CRect(0,0,0,0),this,IDC_CELL_COMBOBOX);
                        }
                        m_comboBox.MoveWindow(rect);

                        m_comboBox.ShowWindow(SW_SHOW);
                        //TODO comboBox 初始化
                        LoadPlmAttri();
                        //当前cell的值
                        CString strCellValue = GetItemText(m_nRow,m_nCol);
                        int nIndex = m_comboBox.FindStringExact(0,strCellValue);
                        if(CB_ERR == nIndex)
                                m_comboBox.SetCurSel(0); //TODO 设置为当前值的Item
                        else
                                m_comboBox.SetCurSel(nIndex);               
                       
                        m_comboBox.SetFocus();
                        UpdateWindow();
                }
        }
}


void CEditListCtrl::OnCbnSelchangeCbCellComboBox()
{
        //同步更新处理数据
        _PersistItem* pPersistItem = (_PersistItem*)GetItemData(m_nRow);
        if(NULL == pPersistItem) return ;

        if(1 == m_nCol) //combobox控件
        {
                CString szLable;
                int nindex = m_comboBox.GetCurSel();
                m_comboBox.GetLBText(nindex,szLable);
                ATTRIFIELD* pAttriField = (ATTRIFIELD*)m_comboBox.GetItemData(nindex);
                if(NULL == pAttriField)
                        return ;

                //持久化的处理
                if(0 == pAttriField->szComment.CompareNoCase(ATTRIBUTE_PERSISTENCE))
                {
                        pPersistItem->szPersistence=pAttriField->mapPersistenceValue[ATTRIBUTE_VALUE];
                        SetItemText(m_nRow,m_nCol-1,pPersistItem->szPersistence);
                }

                pPersistItem->szUcProperty = pAttriField->szPLMToXML;
                pPersistItem->szXmlOption = pAttriField->szXMLOpention;
                SetItemText(m_nRow,m_nCol,pAttriField->szDetail);               
                m_comboBox.ShowWindow(SW_HIDE);               
        }
}

//发送失效消息
void CEditListCtrl::SendInvalidateMsg()
{
        //Edit单元格
        if((0 == m_nCol))
        {

                if(NULL == m_edit.m_hWnd) return ;
                BOOL bShow = m_edit.IsWindowVisible();
                if(bShow)
                        ::SendMessage(m_edit.m_hWnd,WM_KILLFOCUS,(WPARAM)0,(LPARAM)0);

        }
        else if((1 == m_nCol)) //combobox
        {
                if(NULL == m_comboBox.m_hWnd) return ;

                BOOL bShow = m_comboBox.IsWindowVisible();
                if(bShow)
                        ::SendMessage(m_comboBox.m_hWnd,WM_KILLFOCUS,(WPARAM)0,(LPARAM)0);
        }
}

void CEditListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
        SendInvalidateMsg();

        CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CEditListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
        SendInvalidateMsg();

        CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}



  CEditListCtrl 类是一个控件类在一个dialog容器中动态创建:

        RECT listRect;   
        GetDlgItem(IDC_ST_LISTGROUP)->GetWindowRect(&listRect);  //获取List控件所在位位置,用Group占位
        ScreenToClient(&listRect);

        m_list.Create(WS_CHILD|WS_BORDER|LVS_SINGLESEL|LVS_REPORT,listRect,this,IDC_EDIT_LIST);
        m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_UNDERLINEHOT);
        m_list.ShowWindow(SW_SHOW);
                RECT rect;
        m_list.GetClientRect(&rect);
       
        m_list.InsertColumn(0,FirstColName,LVCFMT_LEFT,rect.right/2);
        m_list.InsertColumn(1,SecondColName,LVCFMT_LEFT,rect.right/2);   
这样就动态的创建了一个listctrl

接下来 我们继续完善 ListCtrl中的Edit 和Combobox的创建

在上面CEditListCtrl 中有两个成员变量 分别是  m_edit 和m_comboBox。 这两个成员变量是我们自顶一个 Edit 和ComboBox

ListEdit.h



#pragma once


// CListEdit

class CListEdit : public CEdit
{
        DECLARE_DYNAMIC(CListEdit)

public:
        CListEdit();
        virtual ~CListEdit();

protected:
        DECLARE_MESSAGE_MAP()
public:
        afx_msg void OnKillFocus(CWnd* pNewWnd);
protected:
        virtual void PreSubclassWindow();
};



ListEdit.cpp


// ListEdit.cpp : implementation file
//

#include "stdafx.h"
#include "CADIPlatform.h"
#include "ListEdit.h"
#include "EditListCtrl.h"


// CListEdit

IMPLEMENT_DYNAMIC(CListEdit, CEdit)

CListEdit::CListEdit()
{

}

CListEdit::~CListEdit()
{
}


BEGIN_MESSAGE_MAP(CListEdit, CEdit)
        ON_WM_KILLFOCUS()
END_MESSAGE_MAP()



// CListEdit message handlers



void CListEdit::OnKillFocus(CWnd* pNewWnd)
{
        CEdit::OnKillFocus(pNewWnd);

        //ShowWindow(SW_HIDE);
        CEditListCtrl* temp = (CEditListCtrl*)GetParent();
        temp->DisposeEdit();

}

void CListEdit::PreSubclassWindow()
{
        // TODO: Add your specialized code here and/or call the base class

        CEdit::PreSubclassWindow();
}


ListComboBox.h


#pragma once


// CListComboBox

class CListComboBox : public CComboBox
{
        DECLARE_DYNAMIC(CListComboBox)

public:
        CListComboBox();
        virtual ~CListComboBox();

protected:
        DECLARE_MESSAGE_MAP()
public:
        afx_msg void OnKillFocus(CWnd* pNewWnd);
        afx_msg void OnCbnDropdown();
};




ListComboBox.cpp


// ListComboBox.cpp : implementation file
//

#include "stdafx.h"
#include "CADIPlatform.h"
#include "ListComboBox.h"
#include "EditListCtrl.h"


// CListComboBox

IMPLEMENT_DYNAMIC(CListComboBox, CComboBox)

CListComboBox::CListComboBox()
{

}

CListComboBox::~CListComboBox()
{
}


BEGIN_MESSAGE_MAP(CListComboBox, CComboBox)
        ON_WM_KILLFOCUS()
        ON_CONTROL_REFLECT(CBN_DROPDOWN, &CListComboBox::OnCbnDropdown)
END_MESSAGE_MAP()



// CListComboBox message handlers

void CListComboBox::OnKillFocus(CWnd* pNewWnd)
{
        CComboBox::OnKillFocus(pNewWnd);
        //ShowWindow(SW_HIDE);

        CEditListCtrl *temp = (CEditListCtrl*)GetParent();
        temp->DisposeEdit(); //调用父窗口的DisposeEdit()函数
}

void CListComboBox::OnCbnDropdown()
{
        CClientDC dc(this);
        int nTotalHeight = 0;
        //获取字体信息
        dc.SelectObject(GetFont());
        //获取当前item的个数
        int nCount = GetCount();
        if(nCount <= 0) return ;
        //获取字体的高度
        CString strLable=_T("");
        GetLBText(GetCurSel(),strLable);
        int nHeight = dc.GetTextExtent(strLable).cy;

        //组合框高度
        CRect rect;
        GetWindowRect(rect);
        int height = rect.Height();

        if(nCount>30)
                nTotalHeight = 30*nHeight + height;
        else
                nTotalHeight = nCount*nHeight + height;

        //设置下拉的高度
        CRect rc;
        GetClientRect(&rc);
        SetWindowPos(NULL,0,0,rc.Width(),rc.Height()+nTotalHeight,SWP_NOZORDER|SWP_NOMOVE|SWP_SHOWWINDOW);
}



在这两个控件中  OnKillFocus 用来让控件失去焦点后的数据同步。

combobox中 CBN_DROPDOWN 消息用来处理计算下拉框的的高度。

 

 

 

 

MFC——LIstCtrl中嵌入Edit和Combobox控件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 11:47 , Processed in 0.140454 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表