Can someone tell me what am I doing wrong?
Thanks,
Gil
Try showing the line of code and any relevant definitions.
--
Scott McPhillips [VC++ MVP]
case WM_VSCROLL:
switch (LOWORD(wParam))
{
case SB_LINEDOWN:
{
RECT rectInvalidbyScroll;
ScrollWindowEx(hWnd,0,-100,NULL,NULL,NULL,
&rectInvalidbyScroll,SW_INVALIDATE);
SetScrollPos(hWnd,SB_VERT,
GetScrollPos(hWnd,SB_VERT)+100,true);
UpdateWindow(hWnd);
}
break;
}
break;
case WM_PAINT:
{
PAINTSTRUCT psMainWinPS;
HDC hdcTableWinClient=BeginPaint(hWnd,&psMainWinPS);
TextOut(hdcTableWinClient, 70, 300, "Line of Text:", 13 );
EndPaint(hWnd,&psMainWinPS);
}
break;
I'm using numeric constants on purpose, to simplify the code just to
get it working first.
Thank you for your response
Gil
It looks like you are scrolling the client area to the left, and then in
WM_PAINT, you are just simply drawing text over the invalidated area.
However, you aren't painting the background prior to drawing the text, so it
seems to me you would just be drawing text over what was there prior to the
scroll. You might want to try using something such as FillRect to first
flood the invalid area with some solid color prior to drawing the text.
Regards,
Mike
"Gil Porat" <gil...@netvision.net.il> wrote in message
news:a3932674.02112...@posting.google.com...
Hi Mike
Actually I scrolling the client area up. The problem is that
ScrollWindowEx doesn't invalidate any area (I used the dubugger's
watch and saw that the invalid RECT contained nothing but 0s). I tried
to FillRect the entire client area but it made no difference. Here is
what I added:
RECT rectMainWin;
GetClientRect(hWnd,&rectMainWin);
// and after the existing
HDC hdcTableWinClient=BeginPaint(hWnd,&psMainWinPS);
// I added
FillRect(hdcTableWinClient,&rectMainWin,(HBRUSH)(COLOR_WINDOW+1));
Thank you for your help,
Gil
Well, obviously something is screwy, but to try and narrow it down, perhaps
you can try manually calculating the area that *should* have been
invalidated by ScrollWindowEx, and just before your UpdateWindow, explicitly
call InvalidateRect with that area.
Regards,
Mike
"Gil Porat" <gil...@netvision.net.il> wrote in message
news:a3932674.02112...@posting.google.com...
Hello Mike
I tried invalidating the area which needs redrawing and I've also
tried invalidating the entire client area. The strange thing that
happens is that the RECT I invalidate doesn't change at all when I
scroll. If I invalidate the entire client area, pushning the down
arrow on the scroll bar only causes the client area to be redrawn
excatly the same way it was before the scroll. If I invalidate only
the part of the client area from which ScrollWindowEx scrolls, that
part remains unchanged after the scroll.
I think that maybe my problem isn't at the ScrollWindowEx function
itself. Perhaps there something else that needs to be done earlier
(when registering the window class, creating the window, etc.) or
later (in the WM_PAINT section) that you assume I've done but I
haven't. I'm rather new at Win32 programming.
Can you think of anything like that?
Thanks,
Gil
Let's see... your original code:
> case SB_LINEDOWN:
> {
> RECT rectInvalidbyScroll;
> ScrollWindowEx(hWnd,0,-100,NULL,NULL,NULL,
> &rectInvalidbyScroll,SW_INVALIDATE);
> SetScrollPos(hWnd,SB_VERT,
> GetScrollPos(hWnd,SB_VERT)+100,true);
> UpdateWindow(hWnd);
> }
> break;
> }
> break;
> case WM_PAINT:
> {
> PAINTSTRUCT psMainWinPS;
> HDC hdcTableWinClient=BeginPaint(hWnd,&psMainWinPS);
> TextOut(hdcTableWinClient, 70, 300, "Line of Text:", 13 );
> EndPaint(hWnd,&psMainWinPS);
> }
> break;
Looking at it closer, maybe what is going on is this:
You are ScrollWindowEx'ing to move the whole window up 100 pixels.
ScrollWindowEx invalidates only that portion which was 'uncovered' after the
scroll occurred -- which is the bottom 100 pixels of your client rect. At
this point the invalid area still contains what was there before the scroll.
Now, after the invalidation, you call UpdateWindow, so an immediate WM_PAINT
is processed, and you are redrawing some text at x=70, y=300. Now, what's
not clear is what that location even corresponds to because the invalid area
uncovered by ScrollWindowEx is going to be at the very bottom of your client
rectangle. If the (70, 300) is somewhere in the middle, then you are still
going to have artifacts at the bottom -- probably just junk, and the new
text is just going to draw somewhere in the middle maybe. All bets are off
as soon as the entire window is invalidated, because your painting code is
set up only to draw a single line of text at a fixed location. So, any prior
effect of scrolling is going to be flooded by the background brush (in
WM_ERASEBKGND) and this single line of text. That is why, when you tried
invalidating the entire client rect, you are seeing the same thing being
redrawn over and over.
If you are trying to create an effect resembling a ticker tape, it's a bit
more complicated than this. Your painting code really needs to have a
considerable amount of logic behind it so that it can, at Windows' beckoned
call, completely reconstruct any portion of the client area. That involves
keeping track of the current scroll positions; and in the paint handler,
calling GetClipBox to determine what part of the client rect actually
*needs* redrawing. It's then a matter of calculating what and where each
element needs to be redrawn.
Since you are pretty new to this, some of it may seem a bit overwhelming. I
wish I could just help you make better sense of it all, but I think there's
no substitute for staring at working code. My best advice would be to yank
apart a few sample apps on CodeProject or CodeGuru. Many of them will be MFC
though, and you appear to be writing a Petzold-style straight C app. FWIW,
Petzold's Programming Windows 95 has some example code that uses
ScrollWindow in Chapter 3 ("Painting with Text"). Although I believe it's
out of print, you can probably find an inexpensive copy of it on half.com.
Regards,
Mike
Hello Mike
Silly me. I have already had a working program which actually did
scroll the contents of a client area. The code in that program
actually did do all the logical drawing work for the scroll, and the
scroll bar was just a graphic control used to interact with the user.
Foolishly I thought that it's impossible that I have to do all this
work myself and that ScrollWindowEx probably does it all for me, so
what I have is an increadibly unefficient program which uses double
the processing time actually required to scroll.
OK, so now I got everything I need to know except for this: What does
ScrollWindowEx actually do? I can just use SetScrollInfo every time
the user uses the scroll bar in order to update the scroll bar's
appearence, and perhaps use GetScrollPos to help me with my drawing.
So what do I need ScrollWindowEx for?
Thanks again for your help
Gil
All ScrollWindow[Ex] does is take one area of your dc and copies it
up/down/left/right in a quick transfer (probably like a BitBlt). Depending
on the flags specified, it may or may not invalidate the area 'uncovered' by
the scroll, but if it does, it's still your responsibility to redraw
*something* in that invalidated area. As you've found out, what actually
needs to be redrawn in the invalid area entirely dependent on your WM_PAINT
handler's code.
Regards,
Mike
"Gil Porat" <gil...@netvision.net.il> wrote in message
news:a3932674.02120...@posting.google.com...
Hi Mike
So I don't actually have to use ScrollWindow[Ex] in order to scroll. I
can just do all the drawing myself. OK, I now know all I need in order
to scroll a client area succesfully.
Thank you very much, you've been a great help
Gil
Yep, ScrollWindow is more or less just a quick way of moving what is already
on the dc as opposed to fully redrawing the entire client area altogether.
There's nothing stopping you from setting a few member variables during some
event that causes a scroll; then simply invalidating the entire client area,
redrawing it in the next WM_PAINT. The drawback is performance: ScrollWindow
(theoretically) saves some cpu cycles by invalidating only the uncovered
area. If your code isn't optimized to redraw only that area which lies
within the invalid rect (ie GetClipBox) in the first place, there is little
performance advantage to using ScrollWindow.
Anyway, I'm glad to have helped you in some small way. You are quite welcome
:).
Regards,
Mike
"Gil Porat" <gil...@netvision.net.il> wrote in message
news:a3932674.02120...@posting.google.com...
>