Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Strange Behavior in NT 4.0

Posted on 1997-05-17
11
Medium Priority
?
271 Views
Last Modified: 2013-12-03
I have a Win32 C app that works fine in W95 and NT 3.51. In NT 4.0, however, the client area of the app window (it's SDI) does not seem to get painted properly. Instead of a white background, it shows whatever was on the screen behind it when the app was launched. When the screen refreshes, the client area displays again what is on the screen, not the usual white background. (In all other respects, the app functions normally.)

I handle the WM_PAINT message by calling this function:

void RepaintScreen(HWND hWnd, PAINTSTRUCT ps, short ylen)      {
      
int iCtr;
HDC hDc;
int begin = 0;



          Y = 2;  
          if ( SCREEN_LINES > (ylen/Spacing) && bScreenLines )
                begin = SCREEN_LINES - (ylen/Spacing);
          //hDc = BeginPaint(hWnd,&ps);
          hDc = ps.hdc;
             for (iCtr = begin; iCtr < SCREEN_LINES; iCtr++)      
             {
                   if ( lpsScrn[iCtr][0] != '\0' )
                   {
                        TextOut(hDc, 1, Y, lpsScrn[iCtr], lstrlen(lpsScrn[iCtr]));                     
                      Y = CheckForScroll(hWnd,
                                                Y,
                                                Spacing,
                                                lstrlen(lpsScrn[iCtr]) * tm.tmMaxCharWidth);
                   }
            }
              EndPaint(hWnd,&ps);
         
               return;
}


RepaintScreen() calls CheckForScroll():

int CheckForScroll(hWnd,CurrentPosition,Spacing, Length)
HWND hWnd;
int CurrentPosition;
int Spacing;
int Length;
{
    RECT rect;                        /* RECT structure for validation */
    rect.top = CurrentPosition;       /* top of last line of text       */
    rect.bottom = CurrentPosition+Spacing+1; /* bottom of last line       */
    rect.left = 1;                  /* left most column of line       */
    rect.right = Length+1;            /* right most column of line       */
            
    GetClientRect(hWnd,(LPRECT)&rect);      /* get rect for current client   */
    if(CurrentPosition + (Spacing*2) > rect.bottom) /* will line fit       */
    {
                              /* if not scroll window and        */
                              /* update client window             */
            ScrollWindowEx(hWnd,0,-(Spacing+1), (CONST RECT*) NULL,
                              (CONST RECT*) NULL,
                              (HRGN)NULL,(RECT FAR*)NULL, 0);
      
            return(CurrentPosition);
    }
    return(CurrentPosition+Spacing);
}

0
Comment
Question by:godzilla
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 3
11 Comments
 
LVL 1

Expert Comment

by:ete
ID: 1397447
Could you give us a little bit more information:

- how do you fill the window class structure (specially the background brush) before registering it?

- how do you handle WM_PAINT and WM_ERASEBKGND in your window procedure?

Regards ETE
0
 

Author Comment

by:godzilla
ID: 1397448
This is how the WNDCLASS structure is filled:

        wc.style = 0;
        wc.lpfnWndProc = (WNDPROC)WindowsProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon(hInstance, ICON) ;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName = (LPSTR)MENU_NAME ;
        wc.lpszClassName = (LPSTR)CLASS_NAME ;


This is how WM_PAINT is handled (works fine for 16-bit programs):

case WM_PAINT:
            RepaintScreen(hWnd,cyClient);
      break;
void RepaintScreen(HWND hWnd,short ylen)      {
      
PAINTSTRUCT ps;
int iCtr;
HDC hDc;
int begin = 0;



          Y = 2;  
          if ( SCREEN_LINES > (ylen/Spacing) && bScreenLines )
                begin = SCREEN_LINES - (ylen/Spacing);
          hDc = BeginPaint(hWndLocal,&ps);
             for (iCtr = begin; iCtr < SCREEN_LINES; iCtr++)      
             {
                   if ( lpsScrn[iCtr][0] != '\0' )
                   {
                        TextOut(hDc, 1, Y, lpsScrn[iCtr], lstrlen(lpsScrn[iCtr]));                     
                      Y = CheckForScroll(hWndLocal,
                                                Y,
                                                Spacing,
                                                lstrlen(lpsScrn[iCtr]) * tm.tmMaxCharWidth);
                   }
            }
            UpdateWindow(hWndLocal);
              EndPaint(hWndLocal,&ps);
             ReleaseDC(hWndLocal, hDc);
         
               return;
}
         

WM_ERASEBKGND is not handled (could that be the problem?)

0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1397449
1. Use hdc memeber of PAINTSTRUCT:

   hDc=pc.hdc;

2. Do not use UpdateWindow() inside WM_PAINT handling function - it may cause endless loop. It is not necessary to call UpdateWindow() here.

3. Do not call ReleaseDC()

0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
LVL 1

Accepted Solution

by:
ete earned 450 total points
ID: 1397450
Follow the instructions Nick mentioned and check also the following points:

1. Because you use break to to end WM_PAINT, make sure that your window procedure returns 0L

2. Your RepaintScreen() function gets hWnd as a parameter, but the function uses hWndLocal. I hope that this is only a spelling mistake. If not and hWndLocal is global variable, this may be the cause your problem.

3. Ensure, that your CheckForScroll() function does not generate new WM_PAINT messages.

Best regards,
ETE
0
 

Author Comment

by:godzilla
ID: 1397451
Good answers, but they didn't do the trick. Here's some more information: My CheckForScroll() function. Perhaps the problem lies here?

int CheckForScroll(hWnd,CurrentPosition,Spacing, Length)
HWND hWnd;
int CurrentPosition;
int Spacing;
int Length;
{
    RECT rect;                        /* RECT structure for validation */
    rect.top = CurrentPosition;       /* top of last line of text       */
    rect.bottom = CurrentPosition+Spacing+1; /* bottom of last line       */
    rect.left = 1;                  /* left most column of line       */
    rect.right = Length+1;            /* right most column of line       */
    ValidateRect(hWnd,(LPRECT)&rect);   /* validate line so that it is   */
                              /* not blanked on next paint       */
            
    GetClientRect(hWnd,(LPRECT)&rect);      /* get rect for current client   */
    if(CurrentPosition + (Spacing*2) > rect.bottom) /* will line fit       */
    {
                              /* if not scroll window and        */
                              /* update client window             */
            ScrollWindowEx(hWnd,0,-(Spacing+1), (RECT FAR*) NULL,
                              (RECT FAR*) NULL,
                              (HRGN)NULL,(RECT FAR*)NULL, (UINT)NULL);
      
            return(CurrentPosition);
    }
    return(CurrentPosition+Spacing);
}


0
 
LVL 1

Expert Comment

by:ete
ID: 1397452
You should not call ValidateRect() API inside the WM_PAINT.

The BeginPaint function automatically validates the entire client area. ValidateRect() nor ValidateRgn() function should be called if a portion of the update region must be validated before the next WM_PAINT message is generated.

Win32 continues to generate WM_PAINT messages until the current update region is validated.

By the way, you should not use unnecessarry typecasting of NULL in your code, when the parameter is plain UINT. In Win32 NULL is defined differently than in Win16. Just use honest 0 instead.


My best regards
ETE
0
 

Author Comment

by:godzilla
ID: 1397453
Ete, I've made changes according to your latest suggestions. The client area still isn't being painted or refreshed, though.
0
 

Author Comment

by:godzilla
ID: 1397454
Edited text of question
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1397455
Try to comment line with 'ScrollWindowEx' and see what happens.
Then try to use SW_ERASE or/and SW_VALIDATE as last parameter for ScrollWindowEx.

In my opinion, it's dangerous and, may be, not correctly to use ScrollWindow.. in WM_PAINT handler.
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1397456
Or, just use ScrollWindow instead of ScrollWindowEx - in any case you don't use extended features of ScrollWindowEx..
0
 

Author Comment

by:godzilla
ID: 1397457
I tried commenting out ScrollWindowEx, and it had no effect on the problem, so the cause must be elsewhere.
0

Featured Post

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question