Re: CListBox jitter.
"TonyG" <TonyG@junk.com> wrote in message
news:8loMg.23927$kO3.14352@newssvr12.news.prodigy.com...
The way I am using a CListBox causes the list box contents to jitter. I
think two of the things I am doing causes this problem. Is there is a way
to
stop this?
Here is what I'm doing:
Please understand that in my program, at any time, a background process
may
add a new line to the top of the list box. Normally if you are scrolled
down
somewhere looking at some other line, when the background process adds the
new line, the list box jumps to the top. The user becomes frustrated
because
he was looking at something important and it jumped away from him. So I
want
to keep the list box displaying the same text lines even if new data is
added at the top
I added a new insert function in my CListBox subclass. The background
process uses this to add a new string to the top:
IndexTop = GetTopIndex();
InsertString(0, Text);
if (IndexTop != LB_ERR)
{
// check if the list box is NOT displaying the top entry
if (IndexTop != 0)
{
// don't scroll the screen
SetTopIndex(IndexTop + 1);
}
}
The problem is that when a new string is added, the screen jumps to the
top.
The code then places the window back to where it was before. On some
computers there a VERY noticeable jitter. And a ghost image of the top
lines.
I also have the need to sometimes replace text on a line within the
CListBox. CListBox doesn't have a ReplaceString function. My subclass
function replaces the text by first deleting the line at whatever provided
index and then adding a new line with the new text at that same provided
index. But, unfortunately, of the background process does this and you are
scrolled someplace else, there is jitter.
HOW CAN I STOP THE JITTER?
You might be seeing this "jitter" because of thread inter-dependency and
synchronization issues.
You said that the "background process" calls the above code. I think that
you mean a worker thread calls the code. If so, then you must understand
that CListBox functions like GetTopIndex() and InsertString() and
SetTopIndex() are thin wrappers over calls to SendMessage() with
LB_GETTOPINDEX, LB_INSERTSTRING and LB_SETTOPINDEX
Use of SendMessage between threads is usually bad, for the reason that it
can cause inter-thread dependencies since only the thread that created a
window can handle its messages. So, in your above code, the worker thread's
call to GetTopIndex() will not return until there has been a thread-context
switch to the main GUI thread and then back to the worker, and the same for
both of the calls to InsertString() and SetTopIndex(). The "jitter" might
therefore be caused by the amount of time that all these context switches
require, which might take so lang as to be actually visible to your users.
See Joe Newcomer's essay on "Using Worker Threads" at
http://www.flounder.com/workerthreads.htm , for an alternate approach that
uses PostMessage instead of SendMessage. Scroll down to the sub-section
titled "Worker threads and the GUI II: Don't touch the GUI"
Mike