Tim
2007-10-06 01:35:30 UTC
All,
I'm having some trouble with an owner drawn static control. Basically the
performance is awful when I owner draw (Windows Mobile targeted app but the
issue isn't specific to mobile).
Yes, performance totally depends on what you do. In my case even if I do
nothing more than write the text using DrawText(), adding more than a couple
of my derived CStatic classes runs so slowly you can watch them being
individually drawn.
I have about 10 of them I'm adding to a form view to use to display data. I
want to use them to do some additional formatting like changing color and
underlining them (the whole control not just the text). I know about
OnCtrlColor and have been using it. (Interesting thing is that using either
OnCtrlColor or just subclassing them to CStatic and writing text both
perform very well with any number of instances. )But the moment I go to
doing my own paint it starts to run like molasses.
Here's the basic code:
{OK....code is WTL but almost exactly the same as the equivalent MFC - I'm
more looking to understand if I'm doing this correctly and WTL forums are
too sparse on this topic....thanks for understanding}
Background Erase Override:
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
ATLTRACE(_T("CColorStatic::OnEraseBackground()\n"));
return TRUE; // indicates we took care of drawing
}
Most simple OnPaint Override (that still sucks performance-wise):
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CColorStatic::OnPaint());
ATLASSERT(m_hWnd);
CPaintDC dc(this->m_hWnd);
CRect rc;
GetClientRect(&rc);
// Set colors
COLORREF crOldBack = dc.SetBkColor(m_crBack);
COLORREF crOldText = dc.SetTextColor(m_crText);
// Draw
int oldMode = dc.SetBkMode(OPAQUE);
dc.FillSolidRect(&rc, m_crBack); // prevents bleed-thru behind text
dc.DrawText(m_text, m_text.GetLength(), rc, DT_LEFT);
// Clean up
dc.SetTextColor(crOldText);
dc.SetBkColor(crOldBack);
dc.SetBkMode(oldMode);
return TRUE; // indicates we took care of drawing
}
Inside my form view, I subclass the controls. And I set the values, forcing
a repaint, in another method based on user making a selection from a
combobox. As I said, just using a vanilla subclassed CStatic or overriding
OnCtrlColor run very fast independent of the number of static controls. But
even doing minimal GDI changes w/in OnPaint in the derived version just
sucks.
I'm hoping that I'm just doing something stupid -- because I really want to
be able to customize the darn thing.
I have also tried:
1) Not using SetWindowText() and GetWindowText() to add the text to write
and retrieve in OnPaint -- instead using a private member string with
Get/Set methods. No difference in performance.
2) I am currently inheriting from CStatic...... but I have also tried
inherting from CWindow (CWnd) with no real difference in performance.
3) Casting the param passed in to hdc instead of using the this pointer in
the CPaintDC constructor. Also no difference....
4) Returning all four combinations of TRUE/FALSE from
OnEraseBackground/OnPaint -- I know what the return values are for but
someone else suggested returning FALSE was suggested in the SDK -- I doubt
that it was because FALSE would indicate that the window still needs to be
painted -- but I was desparate. Anyway, no difference in performance for
any combination....
Would appreciate any insight. I have also tried converted the whole form
into an OwnerDrawn listbox -- and it performs better that way but you can
see a jitter as the rows are painted....I guess the final solution will be
to go to OwnerDrawn List control -- which I've found can draw anything
fast....
But I digress....I think my current approach is be sound and I would hate to
have to force another control to do this work....
cheers all,
tim
I'm having some trouble with an owner drawn static control. Basically the
performance is awful when I owner draw (Windows Mobile targeted app but the
issue isn't specific to mobile).
Yes, performance totally depends on what you do. In my case even if I do
nothing more than write the text using DrawText(), adding more than a couple
of my derived CStatic classes runs so slowly you can watch them being
individually drawn.
I have about 10 of them I'm adding to a form view to use to display data. I
want to use them to do some additional formatting like changing color and
underlining them (the whole control not just the text). I know about
OnCtrlColor and have been using it. (Interesting thing is that using either
OnCtrlColor or just subclassing them to CStatic and writing text both
perform very well with any number of instances. )But the moment I go to
doing my own paint it starts to run like molasses.
Here's the basic code:
{OK....code is WTL but almost exactly the same as the equivalent MFC - I'm
more looking to understand if I'm doing this correctly and WTL forums are
too sparse on this topic....thanks for understanding}
Background Erase Override:
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
ATLTRACE(_T("CColorStatic::OnEraseBackground()\n"));
return TRUE; // indicates we took care of drawing
}
Most simple OnPaint Override (that still sucks performance-wise):
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CColorStatic::OnPaint());
ATLASSERT(m_hWnd);
CPaintDC dc(this->m_hWnd);
CRect rc;
GetClientRect(&rc);
// Set colors
COLORREF crOldBack = dc.SetBkColor(m_crBack);
COLORREF crOldText = dc.SetTextColor(m_crText);
// Draw
int oldMode = dc.SetBkMode(OPAQUE);
dc.FillSolidRect(&rc, m_crBack); // prevents bleed-thru behind text
dc.DrawText(m_text, m_text.GetLength(), rc, DT_LEFT);
// Clean up
dc.SetTextColor(crOldText);
dc.SetBkColor(crOldBack);
dc.SetBkMode(oldMode);
return TRUE; // indicates we took care of drawing
}
Inside my form view, I subclass the controls. And I set the values, forcing
a repaint, in another method based on user making a selection from a
combobox. As I said, just using a vanilla subclassed CStatic or overriding
OnCtrlColor run very fast independent of the number of static controls. But
even doing minimal GDI changes w/in OnPaint in the derived version just
sucks.
I'm hoping that I'm just doing something stupid -- because I really want to
be able to customize the darn thing.
I have also tried:
1) Not using SetWindowText() and GetWindowText() to add the text to write
and retrieve in OnPaint -- instead using a private member string with
Get/Set methods. No difference in performance.
2) I am currently inheriting from CStatic...... but I have also tried
inherting from CWindow (CWnd) with no real difference in performance.
3) Casting the param passed in to hdc instead of using the this pointer in
the CPaintDC constructor. Also no difference....
4) Returning all four combinations of TRUE/FALSE from
OnEraseBackground/OnPaint -- I know what the return values are for but
someone else suggested returning FALSE was suggested in the SDK -- I doubt
that it was because FALSE would indicate that the window still needs to be
painted -- but I was desparate. Anyway, no difference in performance for
any combination....
Would appreciate any insight. I have also tried converted the whole form
into an OwnerDrawn listbox -- and it performs better that way but you can
see a jitter as the rows are painted....I guess the final solution will be
to go to OwnerDrawn List control -- which I've found can draw anything
fast....
But I digress....I think my current approach is be sound and I would hate to
have to force another control to do this work....
cheers all,
tim