Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 列表控制_C++_Mfc_Clistctrl - Fatal编程技术网

C++ 列表控制

C++ 列表控制,c++,mfc,clistctrl,C++,Mfc,Clistctrl,在MFC中,我可以编辑列表控件中项目的文本,但只能通过将编辑标签设置为true来编辑第一列。现在,当我单击第一列项目以更改其文本时,我可以更改其文本,但当我单击Enter时,其文本不会更新,为什么以及如何编辑其他列的文本 对于第一列: 使用LVS_EDITLABELS样式创建列表 如果列表中没有对话框控件,则在列表中设置一个对话框控件,例如SetDlgCtrlID(ID_EDITLABEL) 您可能需要一些代码来跟踪当前选择 在messagehandler中创建对单击/双击或其他用户输入作出反

在MFC中,我可以编辑列表控件中项目的文本,但只能通过将编辑标签设置为true来编辑第一列。现在,当我单击第一列项目以更改其文本时,我可以更改其文本,但当我单击Enter时,其文本不会更新,为什么以及如何编辑其他列的文本

对于第一列:

  • 使用LVS_EDITLABELS样式创建列表
  • 如果列表中没有对话框控件,则在列表中设置一个对话框控件,例如SetDlgCtrlID(ID_EDITLABEL)
  • 您可能需要一些代码来跟踪当前选择
  • 在messagehandler中创建对单击/双击或其他用户输入作出反应的编辑(似乎您已经讨论过了),最好将其放在父类中
  • 在父类中为编辑端添加处理程序

    ON_NOTIFY( LVN_ENDLABELEDIT, ID_EDITLABEL, OnEndEdit )
    
    void MyParentClass::OnEndEdit( NMHDR* pNMHDR, LRESULT* pResult )
    {
      NMLVDISPINFO* pLVDI = reinterpret_cast< NMLVDISPINFO* >( pNMHDR );
      if( pLVDI->item.pszText )
        m_List.SetItemText( m_iCurrentSelection, 0, pLVDI->item.pszText );
      *pResult = 0;
    }
    
    通知上的
    (LVN\u ENDLABELEDIT,ID\u editlab,OnEndEdit)
    void MyParentClass::onededit(NMHDR*pNMHDR,LRESULT*pResult)
    {
    NMLVDISPINFO*pLVDI=重新解释广播(pNMHDR);
    如果(pLVDI->item.pszText)
    m_List.SetItemText(m_iccurrentselection,0,pLVDI->item.pszText);
    *预设值=0;
    }
    
对于其他专栏:我还没有尝试过,但应该不会太难,因为您可以在MFC源代码中查找它们是如何做到这一点的。 请注意,上面的代码是使用最新功能包中的CMFCListCtrl测试的,不过我假设普通CListCtrl的行为相同。

对于第一列:

  • 使用LVS_EDITLABELS样式创建列表
  • 如果列表中没有对话框控件,则在列表中设置一个对话框控件,例如SetDlgCtrlID(ID_EDITLABEL)
  • 您可能需要一些代码来跟踪当前选择
  • 在messagehandler中创建对单击/双击或其他用户输入作出反应的编辑(似乎您已经讨论过了),最好将其放在父类中
  • 在父类中为编辑端添加处理程序

    ON_NOTIFY( LVN_ENDLABELEDIT, ID_EDITLABEL, OnEndEdit )
    
    void MyParentClass::OnEndEdit( NMHDR* pNMHDR, LRESULT* pResult )
    {
      NMLVDISPINFO* pLVDI = reinterpret_cast< NMLVDISPINFO* >( pNMHDR );
      if( pLVDI->item.pszText )
        m_List.SetItemText( m_iCurrentSelection, 0, pLVDI->item.pszText );
      *pResult = 0;
    }
    
    通知上的
    (LVN\u ENDLABELEDIT,ID\u editlab,OnEndEdit)
    void MyParentClass::onededit(NMHDR*pNMHDR,LRESULT*pResult)
    {
    NMLVDISPINFO*pLVDI=重新解释广播(pNMHDR);
    如果(pLVDI->item.pszText)
    m_List.SetItemText(m_iccurrentselection,0,pLVDI->item.pszText);
    *预设值=0;
    }
    
对于其他专栏:我还没有尝试过,但应该不会太难,因为您可以在MFC源代码中查找它们是如何做到这一点的。
请注意,上面的代码是使用最新功能包中的CMFCListCtrl进行测试的,尽管我假设普通CListCtrl的行为相同。

不幸的是,不可能使用
LVS_EDITLABELS
LVN_ENDLABELEDIT
编辑第一列以外的其他列


有关解决方法,请参阅关于CodeProject的文章以了解更多信息,它会在需要时动态创建编辑控件。

不幸的是,无法利用
LVS\u EDITLABELS
LVN\u ENDLABELEDIT
编辑第一列以外的其他列


有关解决方法,请参阅关于CodeProject的文章以了解更多信息,它会在需要时动态创建编辑控件。

我们在列表控件的单元格位置创建CEdit控件(当我们双击列表控件时) 当我们按enter键时,它会更新值。 在本例中,当我们单击列表控件时,只修改了1个子项(第2个子项) 您可以创建多个CEdit控件,并使用所有子项进行操作。 列表控件SingleSelection=true

//.h
// Global variables in dialog
private:
    //..
    const static int        ID_TXTCTRL_TOMODIFY = 1001;
    bool                    m_IsEnterPressed;
    CEdit *                 m_pTxtCtrlToModify;

    //..
protected:
    //..
    BOOL PreTranslateMessage(MSG* pMsg);
    virtual BOOL OnInitDialog();
    //..

public:
    //..
    afx_msg void OnNMDblclkList(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnEnKillFocusCtrlToModify();
    //..

//------------------------------------------------------------------
// .cpp


BEGIN_MESSAGE_MAP(DlgMFC, CDialogEx)
    //..
    ON_NOTIFY(NM_DBLCLK, IDC_LIST, &DlgMFC::OnNMDblclkList)
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, &DlgMFC::OnLvnItemchangedList)
    ON_EN_KILLFOCUS(ID_TXTCTRL_TOMODIFY, &DlgMFC::OnEnKillFocusCtrlToModify)
    //..
END_MESSAGE_MAP()

BOOL DlgMFC::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here

    m_pTxtCtrlToModify = NULL;
    m_IsEnterPressed = false;

    //
    return TRUE;  // return TRUE  unless you set the focus to a control
}

// in this function we let to modify only 1 subitem (the 2nd),
// you can create many CEdit controls an do it with all the subitems



    // We create CEdit Control
void DlgMFC::OnNMDblclkList(NMHDR *pNMHDR, LRESULT *pResult)
{
    //LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    //*pResult = 0;


    POSITION p = m_CtrlList.GetFirstSelectedItemPosition();
    int index, id;
    if(p)   
    {
            index   = m_CtrlList    .GetNextSelectedItem(p);       

            CRect rect, rect_ListControl; // rect wiil be cell position in m_CtrlList, rect_ListControl will be m_CtrlList's position in dialog
            if( m_CtrlList.GetSubItemRect(index, 2, LVIR_BOUNDS, rect)) // 2 is subitem number
            {
                if(m_pTxtCtrlToModify != NULL)
                    delete m_pTxtCtrlToModify;
                m_pTxtCtrlToModify = new CEdit(); // Do not forget to delete it at the end of your program (you can use OnClose())


                m_CtrlList.GetWindowRect(&rect_ListControl);
                this->ScreenToClient(&rect);

                rect.left += rect_ListControl.left + 2; // 2 is just a correction
                rect.right += rect_ListControl.left + 2;
                rect.top  += rect_ListControl.top + 2;
                rect.bottom += rect_ListControl.top + 2;

                m_pTxtCtrlToModify->Create(ES_CENTER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, rect, this, ID_TXTCTRL_TOMODIFY);
                m_pTxtCtrlToModify->SetFocus();
                m_pTxtCtrlToModify->SetWindowTextW(m_CtrlList.GetItemText(index, 2)); // 2 is subitem number

            }

    }
}


// If Selection changes, we delete that CEdit
void DlgMFC::OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    *pResult = 0;

    if(m_pTxtCtrlToModify != NULL)
    {
        delete m_pTxtCtrlToModify;
        m_pTxtCtrlToModify = NULL;
    }
}


// Do not let the dialog to be closed when we press enter
BOOL DlgMFC::PreTranslateMessage(MSG* pMsg)
{
    if (pMsg->message == WM_KEYDOWN)
    {
        if ((pMsg->wParam == VK_RETURN) || (pMsg->wParam == VK_ESCAPE))
        {
            pMsg->wParam = VK_TAB;
            m_IsEnterPressed = true;
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}


//If we pressed enter, we update it and delete CEdit control 
void DlgMFC::OnEnKillFocusCtrlToModify()
{
    // we will update only when we press enter
    if(m_IsEnterPressed == true)
    {       
        m_IsEnterPressed = false;

        // UPDATE here your Database or just ListControl or both ...
        // Example: We update the same m_CtrlList's cell
        POSITION p = m_CtrlList.GetFirstSelectedItemPosition();
        int index;
        if(p)   
        {
            CString str;
            m_pTxtCtrlToModify->GetWindowTextW(str);
            index   = m_CtrlList    .GetNextSelectedItem(p);
            m_CtrlList.SetItemText(index,2,str); // 2 is subitem number
        }


        // Delete CEdit control
        if(m_pTxtCtrlToModify != NULL)
        {
            delete m_pTxtCtrlToModify;
            m_pTxtCtrlToModify = NULL;
        }

        m_CtrlList.SetFocus();
    }
}
/.h
//对话框中的全局变量
私人:
//..
const static int ID\u TXTCTRL\u TOMODIFY=1001;
bool m_是交互式的;
CEdit*MptxtCtrlToModify;
//..
受保护的:
//..
BOOL预翻译信息(MSG*pMsg);
虚拟BOOL-OnInitDialog();
//..
公众:
//..
afx_msg void onNMDBLCLKLLIST(NMHDR*pNMHDR,LRESULT*PRESLT);
afx_msg void OnLvnItemchangedList(NMHDR*pNMHDR,LRESULT*pResult);
afx_msg void onenkillfocustrltomify();
//..
//------------------------------------------------------------------
//.cpp
开始消息映射(DlgMFC、CDialogEx)
//..
ON_通知(NM_DBLCLK、IDC_列表和DlgMFC::OnNMDblclkList)
ON_通知(LVN_项目变更、IDC_列表和DlgMFC::OnLvnItemchangedList)
关于KILLFOCUS(ID\u TXTCTRL\u TOMODIFY,&DlgMFC::onenkillfocustrltodify)
//..
结束消息映射()
BOOL DlgMFC::OnInitDialog()
{
CDialogEx::OnInitDialog();
//设置此对话框的图标。框架会自动执行此操作
//当应用程序的主窗口不是对话框时
SetIcon(m_hIcon,TRUE);//设置大图标
SetIcon(m_hIcon,FALSE);//设置小图标
//TODO:在此处添加额外的初始化
m_pTxtCtrlToModify=NULL;
m_IsInterpressed=假;
//
return TRUE;//除非将焦点设置为控件,否则返回TRUE
}
//在这个函数中,我们只允许修改一个子项(第二个子项),
//您可以创建多个CEdit控件,并使用所有子项进行操作
//我们创建CEdit控件
void DlgMFC::OnNMDblclkList(NMHDR*pNMHDR,LRESULT*pResult)
{
//LPNMITEMACTIVATE pNMItemActivate=重新解释铸件(pNMHDR);
//*预设值=0;
位置p=m_CtrlList.GetFirstSelectedItemPosition();
int索引,id;
如果(p)
{
index=m_CtrlList.GetNextSelectedItem(p);
rect rect,rect_ListControl;//rect将是m_CtrlList中的单元格位置,rect_ListControl将是m_CtrlList在对话框中的位置
如果(m_CtrlList.GetSubItemRect(index,2,LVIR_BOUNDS,rect))//2是子项编号
{
如果(m_ptxtctrltomify!=NULL)
删除MptxtCtrlToModify;
m_pTxtCtrlToModify=new CEdit();//不要忘记在程序结束时删除它(可以使用OnClose())
m_CtrlList.GetWindowRect(&rect_ListControl);
此->屏幕到客户端(&rect);
rect.left+=rect_ListControl.left+2;//2只是一个更正
rect.right+=r