single line updates with CScrollView
Joshua -- CAUBLE@KTICORP.MHS.CompuServe.COM
Monday, July 29, 1996
Environment: VC++ 1.52, VC++ 2.0, Win95
I am currently having trouble with screen updates using the default
CScrollView and CDocument implementations created by app wizard. Is
there a way to update the screen while keeping the original text, without
having to redraw the whole screen.
I am using an SDI application framework. With CScrollView as my view
class. I am trying to emulate a command prompt per say, for a client
application i am building.
The problem stems from using the CDC to draw to the screen and having to
write to it all at once, i.e. previous text, prompt, new text, etc. . If
there is a way to write to the screen without having to write all saved
data, command prompt and the chars the users is typing I could use some
help.
I am using the OnChar function in CScrollView to process the keystrokes,
and CString objects in the CDocument class for global text.
Thank you for any help.
i can be reached at either of the below email addresses:
cauble@kticorp.mhs.compuserve.com
al_thor@juno.com
althor@kincyb.com
Mike Blaszczak -- mikeblas@nwlink.com
Saturday, August 03, 1996
At 01:08 PM 7/29/96 EDT, you wrote:
>Environment: VC++ 1.52, VC++ 2.0, Win95
>I am currently having trouble with screen updates using the default
>CScrollView and CDocument implementations created by app wizard.
I don't understand the background of your question. You _must_ have changed
the CScrollView and CDocument implemnetations in your application because,
if you didn't, there would be nothing to update.
>Is there a way to update the screen while keeping the original text,
>without having to redraw the whole screen.
This, too, I don't understand: Windows application's can't update "the
screen". They, instead, paint their output to a device. That device might
be a printer or a window on the screen, or it might be a fancy recording
mechanism that isn't a device at all but instead just plays back the
drawing commands to a device some time later.
Since Windows is a multitasking operating system, it must govern access
to shared resources like the screen and the printer.
What does your application do to update the screen directly? Or did
you really mean to ask about how to update one of the windows your
application owns?
>I am using an SDI application framework. With CScrollView as my view
>class.
You're using something _derived_ from CScrollView for your view class,
right?
>I am trying to emulate a command prompt per say, for a client
>application i am building.
Since you're targeting Win95, why don't you use a console window? That
lets your program pop up a window that is suspiciously similar to a command
prompt window that you'd use in the operatnig system by itself. Maybe
you don't like this approach because the console window has to be a top-level
window and can't have decorations like custom toolbars and status bars.
>The problem stems from using the CDC to draw to the screen and having to
>write to it all at once, i.e. previous text, prompt, new text, etc.
If you're really drawing to the screen, you shouldn't be. This is bad
behaviour for an application.
If you really mean that you're drawing to a window,
using the CDC class doesn't cause the need to paint everything on the
window. Windows show information. You're asked to show information
when Windows decides it is ready and necessary for you to show information:
when some part of your window has become invlaid. When your window is
first created, it is completely invalid. You paint it, and that means
that it isn't invalid anymore: it is now valid.
Now that it is painted, it might become invalid because Windows says
so: maybe the user popped up another window that overwrote the content
of your window and then moved it away. You need to repaint what you
used to have there: that _part_ of your window that was previously
obscured is now invalid.
It might also become invalid because _you_ say so: if the user presses
that causes your program to decide to change what it is showing on
the screen, you call CWnd::InvalidateRect() to tell Windows that you
think you'd like to repaint some part fo the screen.
InvalidateRect() takes two parameters: a rectangle and a flag. The
rectangle dictates what area of the window needs to be updated. You
can pass NULL for the rectangle and Windows will assume that you mean
to update _everything_ in the window. The second flag is TRUE if you
want to erase the area in the rectangle before painitng,
and FALSE if you don't want to erase the area first.
After you call InvalidateRect(), nothing immediately happens. Windows
tries to coalesce invalid rectangles so you only have to paint as few
times as possible. Windows, when it's ready for you to paint, sends
you a WM_ERASEBKGND message so you can reset the area of the window
to whatever background colour or pattern you want to see. If you have
some special bitmap, that's the time to paint it. If you don't handle
WM_ERASEBKGND, the default behaviour uses the colour that the user has
set for windows backgrounds in the Control Panel.
After the background is taken care of, Windows sends a WM_PAINT message.
MFC handles this by initializing some data structures for you: most
importantly, it sets up a CDC object you can paint with. Then, it
calls your view's OnDraw() function--where you can paint whatever
it is you'd like. What you paint, though, is clipped to the area of
your window that you said was invalid.
If the client area of your window goes from (0,0) to (100,100), for
instance, you might call InvalidateRect() with a rectangle from (50,50)
to (70,70). Then, you might call it again with a rectangle from
(50,0) to (70, 50).
Windows realizes that those areas overlap and can be most easily expressed
by the rectangle from (50, 0) to (70, 70). So, it sends only one WM_PAINT
set up to use that region. When you paint, if you try to paint something
at (0,0), you won't really paint it: windows ignores your request because
it knows what's there isn't invalid. This can _very_ significantly
improve your application's performance: as Dean McCrory (my hero) sometimes
says: "Your program will be faster if you don't do work you don't need to do."
If you invalidate too much, you'll see flashing and your users will
notice sluggish response. You'll also cause flashing, flickering display
if you're not careful. If you invalidate too little, ugly little pieces
of unupdated stuff might lie around in your window. Or, worse yet,
you might show the user data that doesn't reflect the current state
of your application. Some people call these "redraw turds"; I, myself,
would never stoop to such a level.
>If there is a way to write to the screen without having to write all saved
>data, command prompt and the chars the users is typing I could use some
>help.
There is no way to ask Windows to save window image data in a way that would
actually help you. You need to write your program so that you can redraw
everything on demand. Windows asks you to paint because it doesn't have
the information it wants to display: it needs you to recreate it.
>I am using the OnChar function in CScrollView to process the keystrokes,
>and CString objects in the CDocument class for global text.
You should look at the TTY sample that comes with the Windows SDK.
It shows a pretty efficient way to hold stuff in memory and let it
scroll off the screen while invalidating only what's necessary.
>Thank you for any help.
Painting is not MFC-specifc, and it is certainly something that the
introductory books on Windows programming cover in great length. You
might consider buying a copy of Petzold's book--it explains how to paint
in pretty good detail. It also has some text that explains the difference
between a window and the screen, and it sounds like you could
really benefit from this information.
(If you really _are_ painting directly on the screen from your
CScrollView-derived class, you should explain why. The full-screen
sample I wrote for my web site shows an alternative approach that
probably could be tailored to your needs.)
.B ekiM
http://www.nwlink.com/~mikeblas/
These words are my own. I do not speak on behalf of Microsoft.
| Вернуться в корень Архива
|