|
Where the data of the ComboBox are saved in the registry?
|
|
|
|
|
You have to call "SetRegistryKey" in your application first. Otherwise the values are saved in .ini files.
|
|
|
|
|
Hi,
Your work is great. Also, can you help me?
I have created an custom combobox. I have derived it from CWND. In clasical combobox, it is possible to hide the dropdown listbox when user clicks on the dialog(not on a control). Normally, I put the hiding code, killfocus message of the listbox. Clicking any control it hides itself. But when clicking on the dialog, there happend noting since the dialog does not get the focus.
Short, I want to let the dropping listbox disappear when I click on dialog asif I click on any control.
Do you have any idea?
|
|
|
|
|
It was helpfull ......
was looking out for something like this
|
|
|
|
|
Nice one. To make it even better I've added in the autocompletion code from Chris Maunder's CComboCompletion class.
The next task will be to save and load the list of entries via SQL...
|
|
|
|
|
Thanks for the compliment. It's a bit late for you now, but I've just uploaded an update which includes Chris Maunder's auto-completion code, as well as making it compilable in VS2003/2005.
If you add SQL support, be sure to tell me!
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
It's really a good combobox, but a little pity.
The author used CString to store all history, but If I want to delete what I have add to list, so it's hard to do.
Maybe a CArray or CList is pretty to store the history, it's easy to addList, deletelist!!
Benny fun
|
|
|
|
|
I think you've misunderstood the implementation and usage of my control.
I don't store the history in a CString. The history is simply the text stored in the combo's items.
In essence, apart from the extra functions to load and store the history, it behaves exactly like any other combo-box, so to add items you can use AddString, InsertString etc, and to delete items you can use the normal DeleteString function.
The class uses a new version of AddString to make sure that items are always stored in reverse order to that in which they are added. There is also a StoreHistory function which takes the current edit control contents and adds it to the list (as the top-most item).
In trying to allow flexibility, I have made it such that you can populate the combo from the user's profile, a CRecentFileList or an archive. You can save the history to any of these three also, or to a CString for you to store as you wish.
I agree that it would be useful to load/store from/to a CArray/CList, and I may consider adding that to a future update.
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
Hi,thanks for you kindly reply.
I want to implement the function such as: when I dropdown the list, and press DEL key, so it'll delete the highlighted item. Would you give me some advice?
Benny fun
|
|
|
|
|
I would have expected that to work no?
|
|
|
|
|
hi ther!
is it possible to implement more than 1 history comboboxes in the same dialog?
if yes, please show me how to do so? thank you very much for your time n effort!
|
|
|
|
|
I tried the folowing code:
[code]
// CDialogBar m_wndSearchBar;
// create m_wndSearchBar, pass to ReBar::AddBar, etc ...
CHistoryCombo *m_pcomboSearchQuery = (CHistoryCombo *)m_wndSearchBar.GetDlgItem(IDC_COMBO_SEARCH_QUERY);
m_pcomboSearchQuery->LoadHistory("Settings", "SearchQueryHistory");
[/code]
The last string cause assertion in CString code.
So I think I acually get CComboBox pointer not CHistoryCombo.
Is there any way to get a CHistoryCombo pointer?
I know that I can constuct CHistoryCombo directly and then pass to CReBar::AddBar()
but is I think to build all toolbars from dialog resources is more good code style.
|
|
|
|
|
If your dialog bar does not have the combo explicitly declared (and subclassed) as a CHistoryCombo then it will not be one. In fact GetDlgItem() will probably return it as a CTempWnd*. You can find out by adding a line of code like:
TRACE("Combo class = %s\n", m_pcomboSearchQuery->GetRuntimeClass()->m_lpszClassName);
To get it to be a CHistoryCombo you will at some point need to subclass it to one. You could either create your own class derived from CDialogBar and a member variable to it like:
CHistoryCombo m_combo
and then override the OnCreate in your class and do something like:
m_combo.SubclassDlgItem(IDC_COMBO_SEARCH_QUERY, this);
or, you could avoid having your own CDialogBar-derived class by handling it in the main frame, by adding the CHistoryCombo member to the CMainFrame class, and sometime after creating the dialog-bar do something like:
m_combo.SubclassDlgItem(IDC_COMBO_SEARCH_QUERY, &m_wndSearchBar);
Once you have done one of the above, you can then use m_combo to access the combo as a CHistoryCombo.
(The example in the MSDN documentation for CWnd::SubclassDlgItem shows something similar to this)
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
I did use the last your example with SubclassDlgItem.
Its works well.
Thank you again!
|
|
|
|
|
Hi,I found that your CHistoryCombo control has some problem:When the text in the edit box of the combobox is large, the more text exceed the edit box width doesn't appear at all. Can you tell me why? Is it a bug?
liuzz
|
|
|
|
|
To allow text to be entered in the edit box of a combo that is longer than the width of the combo the CBS_AUTOHSCROLL must be used on the combo box. This is the case for all combo boxes. (My demo doesn't have this style and so text will be limited to the combo's width.)
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
The problem has been solved. Thanks you!;P
liuzz
|
|
|
|
|
Is it be possible to scroll the text on the right automatically?
For example if you have long paths (e.g. D:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\ConnectionManager\Bin) while 'navigating' to it, would be much more useful to show the right hand side of the text (e.g. ...\CompactFrameworkSDK\ConnectionManager\Bin), rather than left part (e.g. D:\Program Files\Microsoft Visual Studio .NET 2003\...).
Can your class do this?
|
|
|
|
|
The standard combo box does this when you click on the item, or select it from the drop-list. My class is no different in this respect.
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
Right, ok.
I was thinking more, when the drop-down is actually showing, before making the selection, the text to be moved on the right, so the right hand side of the text will be visible.
However since then the only soultion I could find was to have an owner-drawn list box, unless you have any other ideas?
Thanks.
|
|
|
|
|
Is it possible to have the same functionality here using serialization? I mean deriving a class from CComboBox and implementing serialization for the ComboBox elements. I tried to do this but my serialize() function doesn't get called and CObject's get called instead. Although, the IMPLEMENT_SERIAL() and DECLARE_SERIAL() were there.
Can any one tell my why, thanx...
|
|
|
|
|
It would help if you could post some of your code (or email it to me) so I can see how you're trying to do it. Are you using the >>/<< operators, or Serialize(ar), or ReadObject/WriteObject? I would have thought that the simplest way is to either have a CHistoryCombo::Serialize() function, and call it directly, or to have overrides of LoadHistory/SaveHistory that take a CArchive&.
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
Hello Paul,
This is how i wrote the CSerialComboBox:
///////////////////////////////////////////
class CSerialComboBox : public CComboBox
{
DECLARE_SERIAL(CSerialComboBox)
// Construction
public:
CSerialComboBox();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSerialComboBox)
//}}AFX_VIRTUAL
// Implementation
public:
void Serialize(CArchive& ar);
virtual ~CSerialComboBox();
// Generated message map functions
protected:
//{{AFX_MSG(CSerialComboBox)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// SerialComboBox.cpp : implementation file
//
#include "stdafx.h"
#include "logFilter.h"
#include "SerialComboBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CSerialComboBox, CComboBox, VERSIONABLE_SCHEMA )
/////////////////////////////////////////////////////////////////////////////
// CSerialComboBox
CSerialComboBox::CSerialComboBox()
{
}
CSerialComboBox::~CSerialComboBox()
{
}
void CSerialComboBox::Serialize(CArchive &ar)
{
CComboBox::Serialize(ar);
CString strTemp;
int nCount = CComboBox::GetCount();
if(ar.IsStoring())
{
for (int i=0; i <= nCount; i++)
{
CComboBox::GetLBText( i, (char*) LPCTSTR(strTemp));
ar << strTemp;
}
}
else {
}
}
BEGIN_MESSAGE_MAP(CSerialComboBox, CComboBox)
//{{AFX_MSG_MAP(CSerialComboBox)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
and here how it is used in my dialog class:
void CMainDialog::OnExit()
{
CFile fSerial;
CFileException fileEx;
// fSerial.Open("presist.mus",CFile::Read
if (!fSerial.Open("presist.mus",
CFile::modeCreate | CFile::modeWrite, &fileEx))
{
PrintFileException(fileEx.m_cause);
TRACE( "File Exception: Can't creat presistance file");
exit(2); //Can't creat output file
}
CArchive arcSerial(&fSerial,CArchive::store);
CSerialComboBox *FileNames, *FilterCriteria;
FileNames = (CSerialComboBox*) GetDlgItem(IDC_FILENAME);
FilterCriteria = (CSerialComboBox*) GetDlgItem(IDC_CRITERIA);
//FileNames->Serialize(fserial);
FilterCriteria->Serialize(arcSerial);
exit(0);
}
the problem is that the Serialize() in CSerialComboBox class doesn't get called and the one in CObject which only returns. One more thing, the visual studio recognizes the CSerialComboBox but when i want to go to the funtion definitions it says that they are not defined. what might be the reason for that...
Thanx alot for your help,
Bye...
|
|
|
|
|
The main problem isn't with the serialization. It is this:
FilterCriteria = (CSerialComboBox*) GetDlgItem(IDC_CRITERIA); You can't simply cast a CWnd* to a CSerialComboBox* . Whatever you cast it to it's still really a CWnd* . If you break in a debugger after the line above, and look at what it says FilterCriteria is, it will tell you it's a CTempWnd* .
You need to subclass the control to a CSerialComboBox to be able to use it as that. This is normally done by setting up a member variable mapping using the ClassWizard. This subclasses the window handle.
When you call the MFC GetDlgItem() , the function first gets the HWND for the control, and then it looks it up to find the CWnd* it is currently mapped to (see documentation for CWnd::FromHandle ). In your case it's not mapped to anything so you get a CTempWnd object. The function then always returns it as a CWnd* .
If you had already subclassed it to a CSerialComboBox , then the pointer returned would be a CSerialComboBox* (albeit upcast to a CWnd* ), and the debugger would show it as that. (Using something like DYNAMIC_DOWNCAST can help with making sure you have the correct cast.)
So, to fix your problem, map the control to a CSerialComboBox .
As for the functions not being found, I assume you mean in the ClassView. The best remedy for this is to delete your workspace's ncb file. You will need to close the workspace first.
Perhaps I could make a suggestion about your Serialize() function. When serializing a list of items where the number of items is dynamic, it s a good idea to store the number of items first, then store each item in a loop. Then, on loading, you will then first read the number of items, then you know how many times to loop and read the actual items.
I hope this helps!
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
hi Paul,
Your are right about that, I gotta subclass my combobox for it to work.
Thanx alot for your advice and happy coding..
MM.
|
|
|
|