一个CListCtrl使用中的bug?

wyjie_134 2010-04-26 09:17:19
前几天依靠很多朋友,做好了一个小程序,但是在测试过程中发现了一个小bug,当我在给ClistCtrl控件中的某一行赋值后,如果我向下拖动鼠标或者转动滚轮,就会出现一个复制的假象,其实其他行是没有值的!具体情况如下:假定该控件中我添加了100行,我给第5行赋值了,其他行都没有值,然后我向下拖动鼠标或者转动滚轮,就有可能出现我所说的复制情况,其实其它行是没有值的,注意,是有可能,不是每次都会出现这种复制情况!这到底是怎么回事呢?

PS:我是用了一个封装好的CListCtrl控件,是不是封装的问题呢?后面附上代码!

CComboListCtrl.h

/*******************************************************************************
Author : Aravindan Premkumar
Unregistered Copyright 2003 : Aravindan Premkumar
All Rights Reserved

This piece of code does not have any registered copyright and is free to be
used as necessary. The user is free to modify as per the requirements. As a
fellow developer, all that I expect and request for is to be given the
credit for intially developing this reusable code by not removing my name as
the author.
*******************************************************************************/

#if !defined(AFX_COMBOLISTCTRL_H__9089600F_374F_4BFC_9482_DEAC0E7133E8__INCLUDED_)
#define AFX_COMBOLISTCTRL_H__9089600F_374F_4BFC_9482_DEAC0E7133E8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//the max listCtrl columns
#define MAX_LISTCTRL_COLUMNS 100

#include <afxtempl.h>
#include "InPlaceCombo.h"

class CInPlaceCombo;
class CInPlaceEdit;

// User define message
// This message is posted to the parent
// The message can be handled to make the necessary validations, if any
#define WM_VALIDATE WM_USER + 0x7FFD

// User define message
// This message is posted to the parent
// The message should be handled to spcify the items to the added to the combo
#define WM_SET_ITEMS WM_USER + 0x7FFC

class CComboListCtrl : public CListCtrl
{
public:

// Implementation
typedef enum {MODE_READONLY,MODE_DIGITAL_EDIT,MODE_TEXT_EDIT,MODE_COMBO} COMBOLISTCTRL_COLUMN_MODE;

// Constructor
CComboListCtrl();

CInPlaceCombo inpcb;

// Destructor
virtual ~CComboListCtrl();

// Sets/Resets the column which support the in place combo box
void SetComboColumns(int iColumnIndex, bool bSet = true);

// Sets/Resets the column which support the in place edit control
void SetReadOnlyColumns(int iColumnIndex, bool bSet = true);

// Sets the valid characters for the edit ctrl
void SetValidEditCtrlCharacters(CString& rstrValidCharacters);

// Sets the vertical scroll
void EnableVScroll(bool bEnable = true);

// Sets the horizontal scroll
void EnableHScroll(bool bEnable = true);

//insert column
int CComboListCtrl::InsertColumn(int nCol,LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT,int nWidth = -1,int nSubItem = -1);

//Get column counts
int GetColumnCounts();

//delete all column
void DeleteAllColumn();

//set column Valid char string
void SetColumnValidEditCtrlCharacters(CString &rstrValidCharacters,int column = -1);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CComboListCtrl)
//}}AFX_VIRTUAL

protected:

// Methods
// Generated message map functions
//{{AFX_MSG(CComboListCtrl)
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

private:

// Implementation

// Returns the row & column index of the column on which mouse click event has occured
bool HitTestEx(CPoint& rHitPoint, int* pRowIndex, int* pColumnIndex) const;

// Creates and displays the in place combo box
CInPlaceCombo* ShowInPlaceList(int iRowIndex, int iColumnIndex, CStringList& rComboItemsList,
CString strCurSelecetion = "", int iSel = -1);

// Creates and displays the in place edit control
CInPlaceEdit* ShowInPlaceEdit(int iRowIndex, int iColumnIndex, CString& rstrCurSelection);

// Calculates the cell rect
void CalculateCellRect(int iColumnIndex, int iRowIndex, CRect& robCellRect);

// Checks whether column supports in place combo box
bool IsCombo(int iColumnIndex);

// Checks whether column is read only
bool IsReadOnly(int iColumnIndex);

// Scrolls the list ctrl to bring the in place ctrl to the view
void ScrollToView(int iColumnIndex, /*int iOffSet, */CRect& obCellRect);

// Attributes

// List of columns that support the in place combo box
CList<int, int> m_ComboSupportColumnsList;

// List of columns that are read only
CList<int, int> m_ReadOnlyColumnsList;

// Valid characters
CString m_strValidEditCtrlChars;

// The window style of the in place edit ctrl
DWORD m_dwEditCtrlStyle;

// The window style of the in place combo ctrl
DWORD m_dwDropDownCtrlStyle;

//columnCounts
int m_iColumnCounts;

//column types
COMBOLISTCTRL_COLUMN_MODE m_modeColumn[MAX_LISTCTRL_COLUMNS];

//column
CString m_strValidChars[MAX_LISTCTRL_COLUMNS];
//int m_
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_COMBOLISTCTRL_H__9089600F_374F_4BFC_9482_DEAC0E7133E8__INCLUDED_)


...全文
375 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
rexlend 2012-11-21
  • 打赏
  • 举报
回复
我正在寻找替代CGridCtrl的列表类,正好看到楼主的贴,真是谢谢了。
wyjie_134 2010-04-27
  • 打赏
  • 举报
回复
好消息啊,问题终于解决了

我朋友告诉我,可是尝试添加一个响应,OnMouseWheel,在ComboListCtrl类里
这是针对我要用滚轮来向下查看数据的,在响应中,强制使Edit放掉焦点,然后让焦点被ListCtrl框体获得
如此以来,残影不见了,后面附上相关代码


BOOL CComboListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: Add your message handler code here and/or call default
if (GetFocus() != this)
{
SetFocus();
}

return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
}

在此不得不感叹啊,用如此少的代码解决了非常困扰的问题,我何时才能有这般能力~~
yfc260 2010-04-26
  • 打赏
  • 举报
回复
怎么看不到?
向立天 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wyjie_134 的回复:]
已经放上去了,关键字是下拉框,ListCtrl和控件,希望各位大侠给指出问题,谢谢!
[/Quote]

给个链接啊
gggfnmqj 2010-04-26
  • 打赏
  • 举报
回复
学习一下
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
已经放上去了,关键字是下拉框,ListCtrl和控件,希望各位大侠给指出问题,谢谢!
向立天 2010-04-26
  • 打赏
  • 举报
回复
你还是把工程上传到资源频道让大家去下载调试一下吧
我真的不信有人会把这里的代码都看一遍
Eleven 2010-04-26
  • 打赏
  • 举报
回复
一个图也没看到。。。囧,代码太多。。。
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
我是尽可能多的传上来,因为我也不清楚什么地方有错误,正在学习发图
zhou1xp 2010-04-26
  • 打赏
  • 举报
回复
我晕,写了这么多,我重写这个类还不到你的1/3
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
调用的另一个类
InPlaceEdit.h

/*******************************************************************************
Author : Aravindan Premkumar
Unregistered Copyright 2003 : Aravindan Premkumar
All Rights Reserved

This piece of code does not have any registered copyright and is free to be
used as necessary. The user is free to modify as per the requirements. As a
fellow developer, all that I expect and request for is to be given the
credit for intially developing this reusable code by not removing my name as
the author.
*******************************************************************************/

#if !defined(AFX_INPLACEEDIT_H__175AEDFF_731E_4721_8399_DE406A465861__INCLUDED_)
#define AFX_INPLACEEDIT_H__175AEDFF_731E_4721_8399_DE406A465861__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CInPlaceEdit : public CEdit
{

public:

// Implementation

// Returns the instance of the class
static CInPlaceEdit* GetInstance();

// Deletes the instance of the class
static void DeleteInstance();

// Creates the Windows edit control and attaches it to the object
// Shows the edit ctrl
BOOL ShowEditCtrl(DWORD dwStyle, const RECT& rCellRect, CWnd* pParentWnd,
UINT uiResourceID, int iRowIndex, int iColumnIndex,
CString& strValidChars, CString& rstrCurSelection);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL


// Attributes
// afx_msg void OnPaste(WPARAM wParam, LPARAM lParam);

protected:
// Generated message map functions
//{{AFX_MSG(CInPlaceEdit)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

private:

// Implementation

// Constructor
CInPlaceEdit();

// Hide the copy constructor and operator =
CInPlaceEdit (CInPlaceEdit&) {}

operator = (CInPlaceEdit) {}

// Destructor
virtual ~CInPlaceEdit();

// Attributes

// Index of the item in the list control
int m_iRowIndex;

// Index of the subitem in the list control
int m_iColumnIndex;

// To indicate whether ESC key was pressed
BOOL m_bESC;

// Valid characters
CString m_strValidChars;

// Singleton instance
static CInPlaceEdit* m_pInPlaceEdit;

// Previous string value in the edit control
CString m_strWindowText;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_INPLACEEDIT_H__175AEDFF_731E_4721_8399_DE406A465861__INCLUDED_)


InPlaceEdit.cpp

/*******************************************************************************
Author : Aravindan Premkumar
Unregistered Copyright 2003 : Aravindan Premkumar
All Rights Reserved

This piece of code does not have any registered copyright and is free to be
used as necessary. The user is free to modify as per the requirements. As a
fellow developer, all that I expect and request for is to be given the
credit for intially developing this reusable code by not removing my name as
the author.
*******************************************************************************/

#if !defined(AFX_INPLACEEDIT_H__175AEDFF_731E_4721_8399_DE406A465861__INCLUDED_)
#define AFX_INPLACEEDIT_H__175AEDFF_731E_4721_8399_DE406A465861__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CInPlaceEdit : public CEdit
{

public:

// Implementation

// Returns the instance of the class
static CInPlaceEdit* GetInstance();

// Deletes the instance of the class
static void DeleteInstance();

// Creates the Windows edit control and attaches it to the object
// Shows the edit ctrl
BOOL ShowEditCtrl(DWORD dwStyle, const RECT& rCellRect, CWnd* pParentWnd,
UINT uiResourceID, int iRowIndex, int iColumnIndex,
CString& strValidChars, CString& rstrCurSelection);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL


// Attributes
// afx_msg void OnPaste(WPARAM wParam, LPARAM lParam);

protected:
// Generated message map functions
//{{AFX_MSG(CInPlaceEdit)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

private:

// Implementation

// Constructor
CInPlaceEdit();

// Hide the copy constructor and operator =
CInPlaceEdit (CInPlaceEdit&) {}

operator = (CInPlaceEdit) {}

// Destructor
virtual ~CInPlaceEdit();

// Attributes

// Index of the item in the list control
int m_iRowIndex;

// Index of the subitem in the list control
int m_iColumnIndex;

// To indicate whether ESC key was pressed
BOOL m_bESC;

// Valid characters
CString m_strValidChars;

// Singleton instance
static CInPlaceEdit* m_pInPlaceEdit;

// Previous string value in the edit control
CString m_strWindowText;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_INPLACEEDIT_H__175AEDFF_731E_4721_8399_DE406A465861__INCLUDED_)


wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
CComboListCtrl是用过程中调用过的类
InPlaceCombo.h

/*******************************************************************************
Author : Aravindan Premkumar
Unregistered Copyright 2003 : Aravindan Premkumar
All Rights Reserved

This piece of code does not have any registered copyright and is free to be
used as necessary. The user is free to modify as per the requirements. As a
fellow developer, all that I expect and request for is to be given the
credit for intially developing this reusable code by not removing my name as
the author.
*******************************************************************************/

#if !defined(AFX_INPLACECOMBO_H__2E04D8D9_827F_4FBD_9E87_30AF8C31639D__INCLUDED_)
#define AFX_INPLACECOMBO_H__2E04D8D9_827F_4FBD_9E87_30AF8C31639D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CInPlaceCombo : public CComboBox
{
public:

// Implementation

// Returns the instance of the class
static CInPlaceCombo* GetInstance();

// Deletes the instance of the class
static void DeleteInstance();

// Creates the Windows combo control and attaches it to the object, if needed and shows the combo ctrl
BOOL ShowComboCtrl(DWORD dwStyle, const CRect& rCellRect, CWnd* pParentWnd, UINT uiResourceID,
int iRowIndex, int iColumnIndex, CStringList* pDropDownList, CString strCurSelecetion = "", int iCurSel = -1);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceCombo)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL

protected:

// Generated message map functions
//{{AFX_MSG(CInPlaceCombo)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnCloseup();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

public:

// Implementation
// Constructor
CInPlaceCombo();

// Hide the copy constructor and operator =
CInPlaceCombo (CInPlaceCombo&) {}

operator = (CInPlaceCombo) {}

// Destructor
virtual ~CInPlaceCombo();

// Attributes

// Index of the item in the list control
int m_iRowIndex;

// Index of the subitem in the list control
int m_iColumnIndex;

// To indicate whether ESC key was pressed
BOOL m_bESC;

// Singleton instance
static CInPlaceCombo* m_pInPlaceCombo;

// Previous selected string value in the combo control
CString m_strWindowText;

// List of items to be shown in the drop down
CStringList m_DropDownList;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_INPLACECOMBO_H__2E04D8D9_827F_4FBD_9E87_30AF8C31639D__INCLUDED_)

InPlaceCombo.cpp

/*******************************************************************************
Author : Aravindan Premkumar
Unregistered Copyright 2003 : Aravindan Premkumar
All Rights Reserved

This piece of code does not have any registered copyright and is free to be
used as necessary. The user is free to modify as per the requirements. As a
fellow developer, all that I expect and request for is to be given the
credit for intially developing this reusable code by not removing my name as
the author.
*******************************************************************************/

#if !defined(AFX_INPLACECOMBO_H__2E04D8D9_827F_4FBD_9E87_30AF8C31639D__INCLUDED_)
#define AFX_INPLACECOMBO_H__2E04D8D9_827F_4FBD_9E87_30AF8C31639D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CInPlaceCombo : public CComboBox
{
public:

// Implementation

// Returns the instance of the class
static CInPlaceCombo* GetInstance();

// Deletes the instance of the class
static void DeleteInstance();

// Creates the Windows combo control and attaches it to the object, if needed and shows the combo ctrl
BOOL ShowComboCtrl(DWORD dwStyle, const CRect& rCellRect, CWnd* pParentWnd, UINT uiResourceID,
int iRowIndex, int iColumnIndex, CStringList* pDropDownList, CString strCurSelecetion = "", int iCurSel = -1);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceCombo)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL

protected:

// Generated message map functions
//{{AFX_MSG(CInPlaceCombo)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnCloseup();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

public:

// Implementation
// Constructor
CInPlaceCombo();

// Hide the copy constructor and operator =
CInPlaceCombo (CInPlaceCombo&) {}

operator = (CInPlaceCombo) {}

// Destructor
virtual ~CInPlaceCombo();

// Attributes

// Index of the item in the list control
int m_iRowIndex;

// Index of the subitem in the list control
int m_iColumnIndex;

// To indicate whether ESC key was pressed
BOOL m_bESC;

// Singleton instance
static CInPlaceCombo* m_pInPlaceCombo;

// Previous selected string value in the combo control
CString m_strWindowText;

// List of items to be shown in the drop down
CStringList m_DropDownList;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_INPLACECOMBO_H__2E04D8D9_827F_4FBD_9E87_30AF8C31639D__INCLUDED_)
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
由于字数限制,删除了一些不必要的注释,
CComboListCtrl.cpp

CComboListCtrl::CComboListCtrl()
{
m_iColumnCounts = 0;
m_ComboSupportColumnsList.RemoveAll();
m_ReadOnlyColumnsList.RemoveAll();
m_strValidEditCtrlChars.Empty();
m_dwEditCtrlStyle = ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_LEFT | ES_NOHIDESEL;
m_dwDropDownCtrlStyle = WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL;
}

CComboListCtrl::~CComboListCtrl()
{
CInPlaceCombo::DeleteInstance();
CInPlaceEdit::DeleteInstance();
}


BEGIN_MESSAGE_MAP(CComboListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CComboListCtrl)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndLabelEdit)
ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginLabelEdit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
CInPlaceCombo* CComboListCtrl::ShowInPlaceList(int iRowIndex, int iColumnIndex, CStringList& rComboItemsList,
CString strCurSelecetion /*= ""*/, int iSel /*= -1*/)
{
// The returned obPointer should not be saved

// Make sure that the item is visible
if (!EnsureVisible(iRowIndex, TRUE))
{
return NULL;
}

// Make sure that iColumnIndex is valid
CHeaderCtrl* pHeader = static_cast<CHeaderCtrl*> (GetDlgItem(FIRST_COLUMN));

int iColumnCount = pHeader->GetItemCount();

if (iColumnIndex >= iColumnCount || GetColumnWidth(iColumnIndex) < MIN_COLUMN_WIDTH)
{
return NULL;
}

// Calculate the rectangle specifications for the combo box
CRect obCellRect(0, 0, 0, 0);
CalculateCellRect(iColumnIndex, iRowIndex, obCellRect);

int iHeight = obCellRect.Height();
int iCount = (int )rComboItemsList.GetCount();

iCount = (iCount < MAX_DROP_DOWN_ITEM_COUNT) ?
iCount + MAX_DROP_DOWN_ITEM_COUNT : (MAX_DROP_DOWN_ITEM_COUNT + 1);

obCellRect.bottom += iHeight * iCount;

// Create the in place combobox
CInPlaceCombo* pInPlaceCombo = CInPlaceCombo::GetInstance();
pInPlaceCombo->ShowComboCtrl(m_dwDropDownCtrlStyle, obCellRect, this, 0, iRowIndex, iColumnIndex, &rComboItemsList,
strCurSelecetion, iSel);

return pInPlaceCombo;
}

CInPlaceEdit* CComboListCtrl::ShowInPlaceEdit(int iRowIndex, int iColumnIndex, CString& rstrCurSelection)
{
// Create an in-place edit control
CInPlaceEdit* pInPlaceEdit = CInPlaceEdit::GetInstance();

CRect obCellRect(0, 0, 0, 0);
CalculateCellRect(iColumnIndex, iRowIndex, obCellRect);

pInPlaceEdit->ShowEditCtrl(m_dwEditCtrlStyle, obCellRect, this, 0,
iRowIndex, iColumnIndex,
m_strValidChars[iColumnIndex], rstrCurSelection);

return pInPlaceEdit;
}

void CComboListCtrl::OnHScroll(UINT iSBCode, UINT iPos, CScrollBar* pScrollBar)
{
//

if (GetFocus() != this)
{
SetFocus();
}

CListCtrl::OnHScroll(iSBCode, iPos, pScrollBar);
}

void CComboListCtrl::OnVScroll(UINT iSBCode, UINT iPos, CScrollBar* pScrollBar)
{
//

if (GetFocus() != this)
{
SetFocus();
}

CListCtrl::OnVScroll(iSBCode, iPos, pScrollBar);
}

void CComboListCtrl::OnLButtonDown(UINT iFlags, CPoint obPoint)
{
//

int iColumnIndex = -1;
int iRowIndex = -1;

// Get the current column and row
if (!HitTestEx(obPoint, &iRowIndex, &iColumnIndex))
{
return;
}

CListCtrl::OnLButtonDown(iFlags, obPoint);


if ((GetKeyState(VK_SHIFT) & 0x80) || (GetKeyState(VK_CONTROL) & 0x80))
{
return;
}

// Get the current selection before creating the in place combo box
CString strCurSelection = GetItemText(iRowIndex, iColumnIndex);

if (-1 != iRowIndex)
{
UINT flag = LVIS_FOCUSED;

if ((GetItemState(iRowIndex, flag ) & flag) == flag)
{
// Add check for LVS_EDITLABELS
if (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS)
{
// If combo box is supported
// Create and show the in place combo box
if (IsCombo(iColumnIndex))
{
CStringList obComboItemsList;

GetParent()->SendMessage(WM_SET_ITEMS, (WPARAM)iColumnIndex, (LPARAM)&obComboItemsList);

CInPlaceCombo* pInPlaceComboBox = ShowInPlaceList(iRowIndex, iColumnIndex, obComboItemsList, strCurSelection);
ASSERT(pInPlaceComboBox);

// Set the selection to previous selection
pInPlaceComboBox->SelectString(-1, strCurSelection);
}
// If combo box is not read only
// Create and show the in place edit control
else if (!IsReadOnly(iColumnIndex))
{
CInPlaceEdit* pInPlaceEdit = ShowInPlaceEdit(iRowIndex, iColumnIndex, strCurSelection);
}
}
}
}
}

bool CComboListCtrl::HitTestEx(CPoint &obPoint, int* pRowIndex, int* pColumnIndex) const
{
if (!pRowIndex || !pColumnIndex)
{
return false;
}

// Get the row index
*pRowIndex = HitTest(obPoint, NULL);

if (pColumnIndex)
{
*pColumnIndex = 0;
}

// Make sure that the ListView is in LVS_REPORT
if ((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
{
return false;
}

// Get the number of columns
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);

int iColumnCount = pHeader->GetItemCount();

// Get bounding rect of item and check whether obPoint falls in it.
CRect obCellRect;
GetItemRect(*pRowIndex, &obCellRect, LVIR_BOUNDS);

if (obCellRect.PtInRect(obPoint))
{
// Now find the column
for (*pColumnIndex = 0; *pColumnIndex < iColumnCount; (*pColumnIndex)++)
{
int iColWidth = GetColumnWidth(*pColumnIndex);

if (obPoint.x >= obCellRect.left && obPoint.x <= (obCellRect.left + iColWidth))
{
return true;
}
obCellRect.left += iColWidth;
}
}
return false;
}

void CComboListCtrl::SetComboColumns(int iColumnIndex, bool bSet /*= true*/)
{
// If the Column Index is not present && Set flag is false
// Then do nothing
// If the Column Index is present && Set flag is true
// Then do nothing
POSITION Pos = m_ComboSupportColumnsList.Find(iColumnIndex);

//
//
if ((NULL == Pos) && bSet)
{
m_ComboSupportColumnsList.AddTail(iColumnIndex);
}

//
//
if ((NULL != Pos) && !bSet)
{
m_ComboSupportColumnsList.RemoveAt(Pos);
}
}

void CComboListCtrl::SetReadOnlyColumns(int iColumnIndex, bool bSet /*= true*/)
{

POSITION Pos = m_ReadOnlyColumnsList.Find(iColumnIndex);

//
//
if ((NULL == Pos) && bSet)
{
m_ReadOnlyColumnsList.AddTail(iColumnIndex);
}

//
//
if ((NULL != Pos) && !bSet)
{
m_ReadOnlyColumnsList.RemoveAt(Pos);
}
}

bool CComboListCtrl::IsReadOnly(int iColumnIndex)
{
if (m_ReadOnlyColumnsList.Find(iColumnIndex))
{
return true;
}

return false;
}

bool CComboListCtrl::IsCombo(int iColumnIndex)
{
if (m_ComboSupportColumnsList.Find(iColumnIndex))
{
return true;
}

return false;
}

void CComboListCtrl::CalculateCellRect(int iColumnIndex, int iRowIndex, CRect& robCellRect)
{
GetItemRect(iRowIndex, &robCellRect, LVIR_BOUNDS);

CRect rcClient;
GetClientRect(&rcClient);

if (robCellRect.right > rcClient.right)
{
robCellRect.right = rcClient.right;
}

ScrollToView(iColumnIndex, robCellRect);
}

void CComboListCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
//

//
SetItemText(pDispInfo->item.iItem, pDispInfo->item.iSubItem, pDispInfo->item.pszText);

GetParent()->SendMessage(WM_VALIDATE, GetDlgCtrlID(), (LPARAM)pDispInfo);

*pResult = 0;
}

void CComboListCtrl::SetValidEditCtrlCharacters(CString &rstrValidCharacters)
{
m_strValidEditCtrlChars = rstrValidCharacters;
}

void CComboListCtrl::SetColumnValidEditCtrlCharacters(CString &rstrValidCharacters,int column)
{
if(column>MAX_LISTCTRL_COLUMNS-1)
return;
if(column == -1)
{
for(int i=0;i<MAX_LISTCTRL_COLUMNS;i++)
{
m_strValidChars[i] = rstrValidCharacters;
}
}
else
m_strValidChars[column] = rstrValidCharacters;
}

void CComboListCtrl::EnableHScroll(bool bEnable /*= true*/)
{
if (bEnable)
{
m_dwDropDownCtrlStyle |= WS_HSCROLL;
}
else
{
m_dwDropDownCtrlStyle &= ~WS_HSCROLL;
}
}

void CComboListCtrl::EnableVScroll(bool bEnable /*= true*/)
{
if (bEnable)
{
m_dwDropDownCtrlStyle |= WS_VSCROLL;
}
else
{
m_dwDropDownCtrlStyle &= ~WS_VSCROLL;
}
}

void CComboListCtrl::ScrollToView(int iColumnIndex, /*int iOffSet, */CRect& robCellRect)
{
// Now scroll if we need to expose the column
CRect rcClient;
GetClientRect(&rcClient);

int iColumnWidth = GetColumnWidth(iColumnIndex);

// Get the column iOffset
int iOffSet = 0;
for (int iIndex_ = 0; iIndex_ < iColumnIndex; iIndex_++)
{
iOffSet += GetColumnWidth(iIndex_);
}



CSize obScrollSize(0, 0);

if (((iOffSet + robCellRect.left) < rcClient.left) ||
((iOffSet + robCellRect.left) > rcClient.right))
{
obScrollSize.cx = iOffSet + robCellRect.left;
}
else if ((iOffSet + robCellRect.left + iColumnWidth) > rcClient.right)
{
obScrollSize.cx = iOffSet + robCellRect.left + iColumnWidth - rcClient.right;
}

Scroll(obScrollSize);
robCellRect.left -= obScrollSize.cx;

//
robCellRect.left += iOffSet;
robCellRect.right = robCellRect.left + iColumnWidth;
}

void CComboListCtrl::OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
//
if (IsReadOnly(pDispInfo->item.iSubItem))
{
*pResult = 1;
return;
}

*pResult = 0;
}

int CComboListCtrl::InsertColumn(int nCol,LPCTSTR lpszColumnHeading,int nFormat ,int nWidth,int nSubItem)
{
m_iColumnCounts++;
return CListCtrl::InsertColumn( nCol, lpszColumnHeading, nFormat, nWidth, nSubItem);
}

int CComboListCtrl::GetColumnCounts()
{
return m_iColumnCounts;
}

void CComboListCtrl::DeleteAllColumn()
{
for(int i=0;i<m_iColumnCounts;i++)
{
DeleteColumn(0);
}
}
向立天 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 wyjie_134 的回复:]
工程方面我觉得其它地方问题不大,因为都是用的最基本的做法,就是这里用了一个封装的类,所以我就给出了源码,如果能找到问题最好了,找不到我晚上或者明天发工程吧!
[/Quote]


我先看看
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
工程方面我觉得其它地方问题不大,因为都是用的最基本的做法,就是这里用了一个封装的类,所以我就给出了源码,如果能找到问题最好了,找不到我晚上或者明天发工程吧!
向立天 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 wyjie_134 的回复:]
刚刚又上传了一次,名字不一样,内容一样的
http://download.csdn.net/source/2286292
[/Quote]

只有源码没有工程
这个应该怎么用
我是不是毛病太多了?
呵呵
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
刚刚又上传了一次,名字不一样,内容一样的
http://download.csdn.net/source/2286292
向立天 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 wyjie_134 的回复:]
是我的疏忽了,我先道歉,不过我貌似不是为了这么1,2分才上传这个资源的
我说了我真的是第一次,没有注意到这些,就是急急忙忙的传上去了,我再传一次吧
感谢你的留言~
[/Quote]

我知道你不是故意的
也没有别的意思
重新上传给个连接
我看看
wyjie_134 2010-04-26
  • 打赏
  • 举报
回复
是我的疏忽了,我先道歉,不过我貌似不是为了这么1,2分才上传这个资源的
我说了我真的是第一次,没有注意到这些,就是急急忙忙的传上去了,我再传一次吧
感谢你的留言~
加载更多回复(5)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧