Actually, thank you very much for your comment.
I think the feature in which you select a row if first character of first row is same as typed character needs to be disabled.
This is not only an issue for CCellEdit, but also CCellDateCtrl and CCellTimeCtrl (which I cam currently working on as a user requested this). I feel if so many controls have a problem, it only gets confusing keeping the feature.
I am just commenting the code as in:
void CConfigListCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
BOOL bCall = TRUE;
if (m_ActiveCell.m_lItem != -1 && m_ActiveCell.m_lSubItem != -1)
{
bCall = m_ActiveCell.m_pCellCtrl->OnChar(nChar, nRepCnt, nFlags);
InvalidateActiveCellRect();
SetItem(m_ActiveCell.m_lItem, m_ActiveCell.m_lSubItem, m_ActiveCell.m_pCellCtrl->GetSelectedTextValue());
}
// Never call CListCtrl::OnChar: reason:
// If do so, will automatically highlight a row in which first character of first column is same as typed character.
// No notification received, and m_ActiveCell remains the active cell, so display is inconsistent.
//if (bCall)
// CListCtrl::OnChar(nChar, nRepCnt, nFlags);
}
Latest code will soon be out on:
http://www.codeproject.com/KB/list/MFCCListCtrlDerClass.aspx
Reply
Hi Maurizio, Thank you for your feedback. That is indeed a bug which I found myself and corrected in my CodeProject article: http://www.codeproject.com/KB/list/MFCCListCtrlDerClass.aspx?fid=1643538 (This newer version has lots of bug fixes and enhancements, including full theme support b I am only able to support VS 2010 though) My comment about your fix: You have added bCall=FALSE; In fact, it is CCellEdit::OnChar that should return FALSE. This way, you keep standard behaviour, except when a CCellEdit is ActiveCell. Kind Regards, Christopher Camacho
ReplyDear Christopher I downloaded the configurableCtrl VS 2010, but I have a problem when I type a character in an CCellEdit, the focus goes to the line that begin with character typed. I have changed the CConfigListCtrl::OnChar, see below and all look working well, some suggestion? void CConfigListCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { BOOL bCall = TRUE; if (m_ActiveCell.m_lItem != -1 && m_ActiveCell.m_lSubItem != -1) { bCall = m_ActiveCell.m_pActiveCtrl->OnChar(nChar, nRepCnt, nFlags); InvalidateActiveCellRect(); SetItem(m_ActiveCell.m_lItem, m_ActiveCell.m_lSubItem, m_ActiveCell.m_pActiveCtrl->GetSelectedTextValue()); bCall=FALSE; // Fontana } if (bCall) CListCtrl::OnChar(nChar, nRepCnt, nFlags); }
ReplyI am not updating the style for frames and buttons.
After second thoughts, I realise I do not have the resources for doing this.
Essentially, I would need a computer with each version of Windows: 2000, ME, XP, Vista, 7 and be able to run and test application on each machine.
Worse: for this to be really viable, I would need to support future versions of Windows b something I am not in a position to guarantee.
I feel this is a job for a Software vendor or the MFC team.
If you application needs an up do date look and feel, then this control is not suitable as it is.
ReplyThank you!
I see what you mean about the scroll bar in drop downs. I will see what I can do to fix that. I donbt quite follow you about the other outdated looks, but I will investigate.
Otherwise, I have fixed issues with Esc, Enter and F4 in my latest code changes b not yet available to you, as not even submitted. You can also navigate using up and down arrows in latest code changes I am making for both combo box and date picker (I have not done color picker yet).
I donbt like the way I displayed dates in a strict dd/MM/yyyy format, so I am currently making changes so date displayed is in the short date format of computer (so will display as MM/dd/yyyy).
Another change I need to make is tabbing within the control: you should be able to tab from one control into another within the list control. I will have a style so on tabbing out of a control with this style set, tab out of the list control altogether.
ReplyThanks for the responses! Another concern is that the controls appear outdated. Check out this sample - the dropdown arrow and calendar navigation arrows are blue instead of gray: http://www.codeproject.com/KB/list/Extended_List_Control.aspx. But I like how your dropdowns are persistent and don't require a double-click first. In fact, in your dialog Select Row dropdown has a modern scrollbar, whereas all the other controls (dropdowns and scrollbars within the list, OK button, etc.) use the outdated look.
Reply...actually, on pressing 'Enter', you want to select the currently selected item. My solution above doesn't do that. Instead of having: void CCellDropDown::CloseDropDown have 2 functions: virtual void CCellDropDown::OnEnter() void CCellDropDown::OnEsc() Call these in CConfigListCtrl::OnEnter CConfigListCtrl::OnEsc which replace: CConfigListCtrl::ClosePopUp CCellDropDown::OnEnter() needs to be implemented for drop down, date controls and color pickers. I'll do that later - sorry I am too busy right now.Reply
The code got formated. ClosePopUp should read:
void CConfigListCtrl::ClosePopUp(DWORD dwLocation, CCellCtrl *pCellCtrl)
{
CCellDropDown *pDropDown = dynamic_cast<CCellDropDown *>(pCellCtrl);
if (pDropDown)
pDropDown->CloseDropDown();
}
It is the lines in bold that need to be added:
BOOL CConfigurableCtrlDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
return m_ListCtrl.OnEnterEsc(pMsg->wParam);
return CDialogEx::PreTranslateMessage(pMsg);
}
(sorry - didn't realise formating took place in comments too)
Reply
Thank you for pointing this issue out.
An MFC dialog box closes when user presses Esc and Enter (which is even worse!)
To prevent this from occuring, you need to make following modifications:
Add a public function in CellDropDown.h/.cpp as follow:
void CCellDropDown::CloseDropDown()
{
if (m_bPopUpOpen)
{
m_bPopUpOpen = FALSE;
m_pPopUpWnd->ShowWindow(SW_HIDE);
GetWindowFromHandle()->InvalidateRect(&m_rcBounding, FALSE);
}
}
Add the following 2 functions in ConfigListCtrl.cpp
void CConfigListCtrl::ClosePopUp(DWORD dwLocation, CCellCtrl *pCellCtrl)
{
CCellDropDown *pDropDown = dynamic_cast(pCellCtrl);
if (pDropDown)
pDropDown->CloseDropDown();
}
BOOL CConfigListCtrl::OnEnterEsc(WPARAM param)
{
if(param == VK_ESCAPE || param == VK_RETURN)
ForEachCellCtrl(m_CtrlMap, &CConfigListCtrl::ClosePopUp);
return TRUE;
}
where:
void ClosePopUp(DWORD dwLocation, CCellCtrl *pCellCtrl);
is private and
BOOL OnEnterEsc(WPARAM param)
is public.
Now, all that remains to be done is to add a PreTranslateMessage function to CConfigurableCtrlDlg (the main dialog box) using the wizard, and add the two lines shown below:
BOOL CConfigurableCtrlDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
return m_ListCtrl.OnEnterEsc(pMsg->wParam);
return CDialogEx::PreTranslateMessage(pMsg);
}
This is what you get with Visual Studio 2010. Visual Studio 2006 might be slightly different.
I shall update the sources.
Also, I have just noticed that F4 does not open and close the drop downs.
I shall fix that too.
Reply
Thank you so much for this example - it's been very helpful! I have a small usability nitpick, and that's regarding the behavior of the ESC key. When a dropdown menu or the time/date popup is open, I believe the user expectation is that ESC would close the dropdown/popup and not the entire dialog.
Reply