I have a problem on windows 2000 and windows XP.
I have in my application an owner draw combo box that works correctly on
win95, 98 and NT.
I have in the CMyCombo::DrawItem(LPDRAWITEMSTRUCT lpdis) method in
which I have done
CDC *pDC = CDC::FromHandle(lpdis->hDC);
that the
pDC->GetWindow()
returns in some cases NULL on win2000 (while on NT, 95 and 98 no).
Having done some controls with this pDC->GetWindow() not NULL, I have
problem of redrawing when the WM_DRAWITEM was sent by the framework to the
combo.
Someone has an idea of what was changed from NT to 2000 about this ?
Or where I can find any documentation about ?
I have just seen on www.codeguru.com , but the solution to a similar problem
doesn't work in my case.
Thanks a lot
Fabio
--
Jeff Partch [MVP]
"Fabio Catarinella" <fabio.ca...@wuerth-phoenix.com> wrote in message
news:efjRAXXDCHA.1880@tkmsftngp04...
I had the same problem once, when I was trying to reposition the dropdown window to make room for a header control. This
worked fine for W95, 98 (don't know about NT) but not for W2K and XP. It turned out that the GetWindow() function
returned NULL during the time the drop down window 'slides' down. It seems that DrawItem isn't drawing in the real drop
down window during this time. And when the 'dropping' is finished the contents seems to be copied to the real drop down
window (without any call to DrawItem()). Also, the items are drawn bottom to top, with the rectangle of the drawn item
always at position 0,0.
It apears that the 'sliding' of owner drawn combo boxes isn't done in Win9X but it does in W2K and XP.
For me, the solution was to do the repositioning of the dropdown window after the OnDropdown() was handled instead of in
DrawItem(). I had to post a user message to myself in OnDropdown() since I had to do it after the drop down was
finished. There are probably other ways to handle it and I am not sure it is the best way, but it worked for me.
I don't know anything about any documentation (i found out by trial and error :-)).
What do you need the window pointer for?
Ruben
I use the pointer for moving the dropdown window, because my combo is a
multicolumn combo and I need to leave space for a header bar in which there
is the description of the columns of the combo.
The problem, so, is due to the fact that if the pointer is null my
application crashes. So I have at the begin of the drawitem a control on the
pDC->GetWindow() different from NULL. But if it is NULL, I cannot redraw the
window when I click on the scroll bar of the combo.
Thanks
Fabio
"Ruben Jönsson" <ru...@pp.sbbs.se> wrote in message
news:dkk0gu4svm27e6r9d...@4ax.com...
This was exactly my problem, I was also making a multicolumn combo box with a header control and got the same result on
W2K and XP (I wonder if we have based it on the same control from Codeguru or Codeproject?).
I handled the moving of the dropdown window in a user defined message. The userdefined message was posted from the
OnDropdown() messagehandler in order to make sure that the dropdown window would be finished with the dropping.
(OnDropdown is sent before it actually drops down).
Use OnCtlColor() to get the HWND of the dropdown window. Don't save the pWnd, it may be temporary.
HBRUSH CMultiCComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_LISTBOX){
//ListBox control
m_hWndDropDown=pWnd->m_hWnd;
}
return CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
}
Ruben
Maybe it's cause I'm stupid (let say... I'm tired ;-) but what's the point
of doing such a thing? you need your own hwnd? why not using "this" directly
(and eventually looking his children)?
--
Quentin Pouplard (Tene/Graff Project)
http://graff.alrj.org
Ruben
I tried to do as you said, but I have some problems because for me it is the
first time that I use user defined messages.
Please, can you tell me where I make an error.
I have insert in my .h
// Generated message map functions
//{{AFX_MSG(MyComboBox)
protected:
afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
//added
afx_msg LRESULT OnComboMsg(WPARAM, LPARAM);
//added
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
and in the .cpp
I have defined my user defined message:
#define WM_COMBO_MSG WM_USER + 131
then
BEGIN_MESSAGE_MAP(MyComboBox, CCComboBox)
//{{AFX_MSG_MAP(MyComboBox)
ON_WM_CTLCOLOR() //
added
ON_MESSAGE(WM_COMBO_MSG, OnComboMsg) // added
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
in the OnDropDown I called the Post Message
::PostMessage(m_hWndDropDown, WM_COMBO_MSG, 0, 0);
and here probably I have done the error, but I don't know what I must pass
to this method.
In fact I don't enter in the
LRESULT CDBComboBox2::OnComboMsg(WPARAM wParam, LPARAM lParam)
{
return 0;
}// OnComboMsg
that is not called.
Thanks a lot
Fabio
"Ruben Jönsson" <ru...@pp.sbbs.se> wrote in message
news:0m01gukchd45013f6...@4ax.com...
I've solved my problem.
Your help was very important for me.
I didn't use the PostMessage (I've also understood where I made the
error...), but using your idea of override the OnCtlColor with taking the
HWND of the drop down window, I've used the ::MoveWindow directly inside my
DrawItem and it seems that it works.
Thanks a lot for everything
Bye
Fabio
"Fabio Catarinella" <fabio.ca...@wuerth-phoenix.com> wrote in message
news:O6uYJniDCHA.1576@tkmsftngp04...
>Hi, Ruben.
>
>I tried to do as you said, but I have some problems because for me it is the
>first time that I use user defined messages.
>Please, can you tell me where I make an error.
>
>I have insert in my .h
>
>// Generated message map functions
> //{{AFX_MSG(MyComboBox)
> protected:
> afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
>//added
> afx_msg LRESULT OnComboMsg(WPARAM, LPARAM);
User defined messages should go after the //}}AFX_MSG and before the
DECLARE_MESSAGE_MAP() macro.
>//added
> //}}AFX_MSG
Here
> DECLARE_MESSAGE_MAP()
>
>and in the .cpp
>
>I have defined my user defined message:
>
>#define WM_COMBO_MSG WM_USER + 131
>
>then
>
>BEGIN_MESSAGE_MAP(MyComboBox, CCComboBox)
> //{{AFX_MSG_MAP(MyComboBox)
> ON_WM_CTLCOLOR() //
>added
> ON_MESSAGE(WM_COMBO_MSG, OnComboMsg) // added
> //}}AFX_MSG_MAP
Same here. The ON_MESSAGE.. should go here.
>END_MESSAGE_MAP()
>
>in the OnDropDown I called the Post Message
>
>::PostMessage(m_hWndDropDown, WM_COMBO_MSG, 0, 0);
>and here probably I have done the error, but I don't know what I must pass
>to this method.
>
>In fact I don't enter in the
>
>LRESULT CDBComboBox2::OnComboMsg(WPARAM wParam, LPARAM lParam)
>{
> return 0;
>}// OnComboMsg
>
>that is not called.
>
>Thanks a lot
Just do PostMessage(WM_COMBO_MSG,0,0); This will post the message to
yourself (this->PostMessage... is implied). You don't want to post
this message to the dropdown window.
The reason to do this is to get your handler called when the dropdown
box has finished drawing (OnDropDown is called before the drawing
begins to let you be able to change the contents of the combo box
before it is dropped down). By doing a PostMessage you put this
handler function on hold until messages are pulled from the message
queue next time, which is after the ComboBox has finished drawing the
drop down window.
OnDropDown is sent (not posted) from the CComboBox class (your base
class) as a step in displaying the drop down window. The combo box
class is then repeatedly calling the virtual function DrawItem() (for
owner drawn combo boxes) for all visible lines. When this is finished
messages from the message queue is handled (which will be your
OnComboMsg).
>
>Fabio
>
Ruben