[comp.windows.ms.programmer] Scoping question using C and SDK

akm@cs.uoregon.edu (Anant Kartik Mithal) (01/23/91)

I'm confused by what the scope of a variable is in a Windows program.
I would assume that it uses standard C scoping (assuming that you are 
using C, which is what I'm using). In the Guide to Programming, in the
chapter "Output to a Window," they give an example which requires a
bunch of HPEN, HBRUSH etc. They ask you to construct a program (pages
3-8 thru 3-9) that is something like

HPEN hPen;		/* black pen to draw outlines of rectangles  */	
HBRUSH hOldBrush;			/* handle to old brush */
HBRUSH hRedBrush;			/* handle to red brush */
HBRUSH hGreyBrush;			/* handle to grey brush */


WinMain()
{
	.
	.
}

MainWndProc()
{
	HDC hDC;
	PAINTSTRUCT ps;
	HPEN hOldPen;

	switch ()

		case(WM_CREATE)
		{
		<statements initializing the Grey and Red brushes>
		}

		case(WM_PAINT)
		{
		<statements using the grey and red brushes>
		}
}

It seemed to me that I could define all the pens and brushes within
MainWndProc, so that they would  not be global variables (they were
being used only in the WM_CREATE and the WM_PAINT cases, both within
MainWndProc. However, when I did that, it didn't work. When I went to
the way things are defined in the book, it worked. Unfortunately, that
doesn't give me any way of figuring out what the scoping rules are...

Any help would be much appreciated.

kartik

--
Anant Kartik Mithal                                     akm@cs.uoregon.edu
Network Manager, 					(503)346-4408 (msgs)
Department of Computer Science,                         (503)346-4156 (direct)
University of Oregon, Eugene, OR 97403-1202

spolsky-joel@cs.yale.edu (Joel Spolsky) (01/23/91)

In article <1991Jan23.044611.21227@cs.uoregon.edu> akm@cs.uoregon.edu
(Anant Kartik Mithal) asks why pens, brushes, etc. that are
initialized in WM_CREATE and used in WM_PAINT must be global and
cannot be local to the window function in which they are used.

What you want to do is:

WndProc (blah blah)
{
	HBRUSH hbFoo;

	...

	case WM_CREATE:

		hbFoo = GetMeABrush();
		break;

	case WM_PAINT:

		use hbFoo;
}

The reason this will not work is a function of C's scoping rules. The
variable hbFoo is a local, temporary variable which goes away
when the function returns. Since the WM_CREATE clause and the WM_PAINT
clause are executed on different passes through the window function,
this variable is not preserved. The solution is either to make the brush
global or to keep it local but add the "static" keyword so that it is
allocated in the data segment and not on the stack.		

--
Joel Spolsky          // And these streets, Quiet as a sleeping army
spolsky@cs.yale.edu   // Send their battered dreams to heaven.   _Paul Simon

slh@wolf.cs.washington.edu (Scott Heyano) (01/24/91)

In article <1991Jan23.044611.21227@cs.uoregon.edu> akm@cs.uoregon.edu (Anant Kartik Mithal) writes:
|I'm confused by what the scope of a variable is in a Windows program.
|I would assume that it uses standard C scoping (assuming that you are 
|using C, which is what I'm using). In the Guide to Programming, in the
|chapter "Output to a Window," they give an example which requires a
|bunch of HPEN, HBRUSH etc. They ask you to construct a program (pages
|3-8 thru 3-9) that is something like
[stuff]
|It seemed to me that I could define all the pens and brushes within
|MainWndProc, so that they would  not be global variables (they were
|being used only in the WM_CREATE and the WM_PAINT cases, both within
|MainWndProc. However, when I did that, it didn't work. When I went to
|the way things are defined in the book, it worked. Unfortunately, that
|doesn't give me any way of figuring out what the scoping rules are...

	It doesn't have anything to do with windows or scoping rules,
	globals are static, locals are not (unless you explicitly
	declare as such).
	The various cases of the function are executed during
	different invocations of the function, so the values
	set in one case clause are lost by the time there are used in another.
	Try putting the variables back inside the function &
	declaring them static.

awd@dbase.A-T.COM (Alastair Dallas) (01/25/91)

In article <1991Jan23.044611.21227@cs.uoregon.edu>, akm@cs.uoregon.edu (Anant Kartik Mithal) writes:
> I'm confused by what the scope of a variable is in a Windows program.
>
> ...
> 
> It seemed to me that I could define all the pens and brushes within
> MainWndProc, so that they would  not be global variables (they were
> being used only in the WM_CREATE and the WM_PAINT cases, both within
> MainWndProc. However, when I did that, it didn't work. When I went to
> the way things are defined in the book, it worked. Unfortunately, that
> doesn't give me any way of figuring out what the scoping rules are...

This isn't scope, it's storage class.  If the variables are automatics,
allocated on the stack, the values which WM_CREATE so carefully stores
there will be garbage by the time the WndProc gets called with a 
WM_PAINT.  You can put them in WndProc but you have to declare them
'static' so that they hang around between invocations.

> Any help would be much appreciated.

This bit me when I was trying to set a flag to indicate that the mouse
button was down in order to change the behavior of WM_MOUSEMOVE.  The
flag has to be static storage class, as a few seconds in CodeView
taught me--you should be glad you asked this question about painting,
which is a lot easier to debug than mousedown events!

/alastair/
> 
> kartik
> 
> --
> Anant Kartik Mithal                                     akm@cs.uoregon.edu
> Network Manager, 					(503)346-4408 (msgs)
> Department of Computer Science,                         (503)346-4156 (direct)
> University of Oregon, Eugene, OR 97403-1202