Win32Lib Update
- Posted by David Cuny <dcuny at LANSET.COM> Oct 23, 1998
- 1005 views
I've just sent the latest version of Win32Lib to Robert. It includes a number of bug fixes, as well as some new features. As with the last update, this version will cause your old programs to break. I try to keep this to a minimum, but sometimes it becomes clear that changes have to be made. In this case, it's with the onPaint event. This post is long, to explain a bit about Windows graphics, and how Win32 handles them, and what brought about the change. All this is subject to change, but I figured that some sort of explanation would be helpful (we'll see). Prior versions of the event pass no parameters; the function prototype now looks like: Window_OnPaint( integer x1, integer y1, integer x2, integer y2 ) As you might imagine, the procedure now receives the area of the window that needs to be updated. This is sometimes called the "damaged region" of the window. Windows can be "damaged" by resizing, being obscured, and so forth. Anyone who's tried it knows that programming Windows graphics is a bit different than programming DOS graphics. In DOS, things you write to the screen remain there. In Windows. areas of the screen can be "damaged" and require repainting. So it's the job of the onPaint routine to repair any damage to the window. That means that onPaint needs to know how to draw *any* part of the window, on demand. This usually requires that applications be written a bit differently. Prior versions forced the *entire* window to be updated with the call: repaintWindow( iWin ) As you can imagine, this is more than a bit inefficient. I've added a new procedure: updateRect( iWin, integer x1, integer y1, integer x2, integer y2 ) No surprise here - the parameters that it passes are those received by the onPaint procedure. I'm doing more than simply attaching parameters to the onPaint routine, though. Windows had *always* passed a clipping window to onPaint. It just happened that Win32Lib (though repaintWindow) always forced it to be the same size as the window, so it could be ignored. Note the words "clipping window" - this means that within the onPaint event, there is no way to put graphics *outside* the clipping window (that's why it's called a clipping window - graphics are clipped to the bounds of the rectangle). All this may seem a bit abstract, so I've created a couple of demos to show off the features. One particular problem I encountered while writing the code may help explain the issue. But first, some background (and details on Win32Lib's inner workings): If you have the 0.13 alpha version of Win32Lib, there is a tile demo (ex17) that shows off the new createMonochromeBitmap() feature (which doesn't work in NT, sorry). When a bitmap is clicked, the tile is "turned over". This is how this is accomplished: 1. The array holding the bitmaps is updated. 2. repaintWindow() is called, to force the window to be redisplayed. 3. repaintWindow scans through the array, and redraws the all the bitmaps. So the only routine that knows how to write to the window is onPaint. You may notice that there is a bit of flickering as this happens. When repaintWindow() is called, it tells Windows that the *entire* window is damaged (see a couple of paragraphs back). One of the things that Windows does automatically in onPaint is to repaint the damaged portion of the window using the window's background color. Since repaintWindow said that the *entire* window was damaged, the entire window is erased, and you see a flash of white. Then the onPaint routine is called, and it has to redraw *all* the tiles in the window. This happens *every time* it needs to update the window. Very inefficient, and very slow. In the 0.14 version of Win32Lib, I've re-written the code to use repaintRect() to pass the location of the bitmap that needs to be repainted. Since only that portion of the window is erased, only that portion needs to be redrawn. The result is a *much* cleaner. Enough background. Both of the demos are modeled around the above process. The only routine that does any writing to the window is the onPaint routine. The other routines update data structures, and then tell onPaint what part of the window needs to be drawn by calling updateRect. Now onto the problem: I needed to write information to a "status line". Initially, I just placed the line: setPosition( Win, 1, 1 ) wPrintf( Win, "Score: %d", {score} ) into the onPaint routine. Much to my suprise, the text *didn't* show up. That's because it didn't fall any of the the clipping rectangles that was passed to onPaint. Since the text fell outside the clipping region, Windows didn't bother to display it. I finally hacked a solution, by adding this call *outside* of onPaint, whenever I wanted to redisplay the status line: repaintRectangle( Win, 1, 1, 200, 20 ) This created a call to onPaint that "uncovered" the score. There are better solutions to the above scenario, but I thought that people might be interested in getting some feel for what graphics in Win32Lib looks like in v0.14. I'm certain things will become better as time goes on... Well, now people should have some idea why I haven't tried writing a Win32Lib tutorial myself... -- David Cuny