|
I know this is the first response in 10 years, but a static-code analysis tool found what looks like an obvious problem with line 63 of ComboBoxStyled.cpp:
if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
should probably be
if ((lpDrawItemStruct->itemAction & ODA_SELECT) &&
|
|
|
|
|
.h
public:
void ResetContent();
protected:
afx_msg void OnDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct);
.cpp
void CComboBoxBold::ResetContent()
{
POSITION pos = myMap.GetStartPosition();
ITEMDATA iData;
int iItem;
while (pos!=NULL)
{
myMap.GetNextAssoc(pos,iItem,iData);
DestroyIcon(iData.icon);
}
myMap.RemoveAll();
CComboBox::ResetContent();
}
void CComboBoxBold::OnDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct)
{
ITEMDATA iData;
if (myMap.Lookup(lpDeleteItemStruct->itemID,iData))
{
DestroyIcon(iData.icon);
}
myMap.RemoveKey(lpDeleteItemStruct->itemID);
CComboBox::OnDeleteItem(nIDCtl, lpDeleteItemStruct);
}
|
|
|
|
|
Control works great, but as a warning you need to set the OwnerDraw property to fixed and HasStrings to true. Or if you are creating the control dynamically you need to add CBS_OWNERDRAWFIXED and CBS_HASSTRINGS.
|
|
|
|
|
Oh and I had to overload CComboBoxBold::MeasureItem to make this work without an ASSERT, but that could be because I am using a up to date version of MFC.
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
//
// ComboBoxListBoxProc (Global window procedure)
// Subclasses the combo box's dropdown list box
//
// Parameters :
// hWnd [in] - The list box's window handle
// nMsg [in] - The current windows message
// wParam [in] - The message's WPARAM parameter
// lParam [in] - The message's LPARAM parameter
//
// Returns :
// 0 if the message was handled here or else
// whatever the default message handler returns
//
// Note :
// Sends a BN_CLICKED message to the parent window
// when a checkbox is clicked
//
/////////////////////////////////////////////////////////////////////////////
extern "C" LRESULT FAR PASCAL ComboBoxListBoxProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
static bool bCloseOnLButtonUp = false;
switch (nMsg)
{
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
{
CRect rc;
GetClientRect(hWnd, rc);
CPoint pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
if (PtInRect(rc, pt))
{
INT nItemHeight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0);
INT nTopIndex = SendMessage(hWnd, LB_GETTOPINDEX, 0, 0);
// Compute which index to check/uncheck
INT nIndex = nTopIndex + pt.y / nItemHeight;
SendMessage(hWnd, LB_GETITEMRECT, nIndex, (LONG)(VOID *)&rc);
if (PtInRect(rc, pt))
{
// Invalidate this window
InvalidateRect(hWnd, rc, FALSE);
// Notify that selection has changed
m_pComboBox->GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetWindowLong(m_pComboBox->m_hWnd, GWL_ID), CBN_SELCHANGE), (LPARAM)m_pComboBox->m_hWnd);
// Was the click on the check box?
HDC hdc = GetDC(hWnd);
TEXTMETRIC metrics;
GetTextMetrics(hdc, &metrics);
ReleaseDC(hWnd, hdc);
rc.left = rc.right -18;
if (PtInRect(rc, pt))
{
m_pComboBox->DeleteString(m_pComboBox->GetCurSel());
SendMessage(hWnd,WM_PAINT,0,0);
// Notify that check state has changed
m_pComboBox->GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetWindowLong(m_pComboBox->m_hWnd, GWL_ID), BN_CLICKED), (LPARAM)m_pComboBox->m_hWnd);
}
else
{
bCloseOnLButtonUp = true;
}
}
}
// Do the default handling now
break;
}
case WM_LBUTTONUP:
{
if (!bCloseOnLButtonUp)
return 0;
bCloseOnLButtonUp = false;
}
}
return CallWindowProc(m_pWndProc, hWnd, nMsg, wParam, lParam);
}
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
//
// CCheckComboBox::OnCtlColorListBox (protected member function)
// Handles the WM_CTLCOLORLISTBOX that is sent by the drop down list box
// to the combo box. It is used here to grab the HWND of the list box so
// we can subclass it.
//
// Parameters :
// lParam [in] - The list box's handle
//
// Returns :
// Whatever the default message handler returns
//
/////////////////////////////////////////////////////////////////////////////
LRESULT CComboBoxBold::OnCtlColorListBox(WPARAM, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so...
if (m_hListBox == NULL)
{
HWND hWnd = reinterpret_cast<HWND>(lParam);
if (hWnd != 0 && hWnd != m_hWnd)
{
// Save the listbox handle
m_hListBox = hWnd;
// Do the subclassing
m_pWndProc = reinterpret_cast<WNDPROC>(GetWindowLong(m_hListBox, GWL_WNDPROC));
SetWindowLong(m_hListBox, GWL_WNDPROC, reinterpret_cast<long>(ComboBoxListBoxProc));
}
}
return Default();
}
|
|
|
|
|
|
I will wait for another 2 weeks from now before updating the files, since new bugs could be found.
Creative minds - create creative creations!
|
|
|
|
|
when I changed combobox TYPE property from Dropdown to droplist then it showing Debug Assertion error at run time.
I don't want user input at run time.
any solution?
|
|
|
|
|
Just add the folowing line in the DrawItem function in the beggining of the function:
if (lpDrawItemStruct->itemID == -1)
return;
Creative minds - create creative creations!
|
|
|
|
|
|
I found the same problem - I fixed it by adding following code at the start of DrawItem:
void CComboBoxBold::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (GetCount() == 0 || (int)(lpDrawItemStruct->itemID) < 0 )
return;
CString str;
int n = GetLBTextLen( lpDrawItemStruct->itemID );
GetLBText( lpDrawItemStruct->itemID, str.GetBuffer(n) );
str.ReleaseBuffer();
....
|
|
|
|
|
After using AddString function to add combobox item , I got
Debug Assertion Failed error
File: strcore.cpp
Line:519
Line: 479
|
|
|
|
|
Actually this Assertion failed error coming through
GetLBText(lpDrawItemStruct->itemID,str);
in DrawItem code.
void CComboBoxBold::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (GetCount() == 0)
return;
CString str;
=> GetLBText(lpDrawItemStruct->itemID,str);
CDC dc;
...
Any solution??
Rajesh
|
|
|
|
|
Hi guys,
This debug assertion error is coming because you did not build the correct release mode exe. for that please change the following in project settings
press Alt+F7
1) C/C++ tab, debug info combo, select "none"
2) Goto Link tab,uncheck the Generate debug info checkbox.
Now you wont get the debug error.(think so)
tx
Karpaga Rajan
|
|
|
|
|
i got these error too, i built aplication with combo, i conect my combo with database.
i have change my setting like your suggestion. but it did not solve it. how about it??
|
|
|
|
|
If one removes an item from the combo box then the myMap variable is not updated to remove the ITEMDATA for that, now gone, item.
This means if you have a long lifetime & add/remove items alot then the memory usage of the class will grow, but never shrink.
Just FYI for anyone using this.
|
|
|
|
|
Add a WM_DELETEITEM() handler to the Combo control
with a following code:
void CComboBoxBold::OnDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct)
{
myMap.RemoveKey(lpDeleteItemStruct->itemID);
CComboBox::OnDeleteItem(nIDCtl, lpDeleteItemStruct);
}
Creative minds - create creative creations!
|
|
|
|
|
Actually the more I look at this the more I consider it "broken."
If any item in the list changes position (due to insert or delete) then the icons are no longer associated with the right item.
I discovered IconComboBox which appears to be doing this correctly (http://www.codeproject.com/combobox/iconcombobox.asp).
It was more trivial to add string support to this class than to fix ComboBoxBold.
I'm not asking you to fix it. Just want to make possible users aware that this code is more limited in what it can handle than one might expect.
|
|
|
|
|
As title, It doesn't provide CBS_OWNERDRAWFIXED in CE. I can't overwrite DrawItem(). How can I do?
|
|
|
|
|
I am sorry but i never had an experience with CE , so i'am afraid i can't help you here,
but hopefully one of the other readers here can, so keep visiting the message board...
Creative minds - creates creative creations!
|
|
|
|
|
CE doesn't support ownerdraw for most of the controls. Comboboxes and listboxes are 2 which do NOT support ownerdraw.
|
|
|
|
|
|
Since there were many requests to enable multiple icons , here it is , i updated the article
so that now differernt icons for different items are available.
Creative minds - creates creative creations!
|
|
|
|
|
Hi Alex,
Thanks for the update! Btw, any chance of using a CImageList instead? It's much more convenient than using multiple icon resources. Thanks!
/ravi
Let's put "civil" back in "civilization"
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|