We help IT Professionals succeed at work.

Improve response when handling WM_SIZE message in an external app.

flynny
flynny asked
on
1,145 Views
Last Modified: 2010-08-05
Hi,

this could be a fruitless question but is there anyway i can reduce the amount of flicker when handling a WM_SIZE message in an external program.

Basically i've added some buttons to an external program to make my life easier. however when i resize the window the response is rather slow and flickery. it works but i wondered whether or not theres any improvements i can make.

i handle the WM_SIZE in the following way.

      case WM_SIZE:
                  {
                        int i;
                        for(i=0; i<maxCurrent; i++)
                        {
                              if(currentButtons[i].parent == NULL)
                                    break;

                              if(currentButtons[i].parent->window == pCwp->hwnd) //it buttons parent being resized
                              {
                                    //msg.Format("WM_SIZE:PARENTHWND:%d:BUTTON:%d:TEXT:%s:",pCwp->hwnd, currentButtons[i].buttonWND, currentButtons[i].button->text);            
                                    //logMsg(msg);

                                    RECT wRect;
                                    GetWindowRect(pCwp->hwnd, &wRect);

                                    int buttonx, buttony;
                              //do coordinate comparison for button position                                          
                                    switch ( currentButtons[i].button->dimensions->anchor )
                                    {
                                          case T_LEFT:
                                                buttonx = currentButtons[i].button->dimensions->x;
                                                buttony = currentButtons[i].button->dimensions->y;
                                                break;
                                          case T_RIGHT:
                                                buttonx = (wRect.right - wRect.left) - currentButtons[i].button->dimensions->x;
                                                buttony = currentButtons[i].button->dimensions->y;
                                                break;
                                          case B_LEFT:
                                                buttonx = currentButtons[i].button->dimensions->x;
                                                buttony = (wRect.bottom - wRect.top) - currentButtons[i].button->dimensions->y;
                                                break;
                                          case B_RIGHT:
                                                buttonx = (wRect.right - wRect.left) - currentButtons[i].button->dimensions->x;
                                                buttony = (wRect.bottom - wRect.top) - currentButtons[i].button->dimensions->y;
                                                break;
                                    }

                                    msg.Format("WM_SIZE:OLDCOORDS[x%d,y%d]:NEWCOORDS[x%d,y%d]:",currentButtons[i].button->dimensions->x, currentButtons[i].button->dimensions->y, buttonx, buttony);
                                    logMsg(msg);

                                    BOOL moved =  MoveWindow(currentButtons[i].buttonWND, buttonx, buttony, currentButtons[i].button->dimensions->width, currentButtons[i].button->dimensions->height, TRUE);
                                    //PostMessage(currentButtons[i].parent->window, WM_PAINT, NULL, NULL);
                              }
                        }
                  }
                  break;

where current buttons is an array of buttons ( i need to do this as i could potentially have to increase the amount i need.)

Many Thanks Matt.
Comment
Watch Question

You can reduce flicker by using BeginDeferWindowPos and family - see http://msdn2.microsoft.com/en-us/library/ms632672.aspx  That might also speed it up a bit.
>>>> however when i resize the window the response is rather slow and flickery.
Actually a WM_SIZE was handled only when the user resized the window, e. g. by choosing maximize. If you want to resize a window use MoveWindow or SetWindowPos and omit handling the WM_SIZE message. The problem is, that WM_SIZE message was sent *after* the windows was resized. That's why you'll always have a flicker.

Regards, Alex

Author

Commented:
hi its me thanks for the reply. so where would i call MoveWindow if no in the wm_size?  should i handle this in WM_PINT for instance would this speed things up?
>>>> where would i call MoveWindow
Hmmm. I would assume that you already are calling MoveWindow or SetWindowPos. Or the WM_SIZE message wouldn't have been invoked. As told the WM_SIZE was sent *after* there has been a change of the window's size. Either by user request or programmatically. Programmatically it happens when the window firstly was drawn or with MoveWindow or SetWindowPos. You would need to spot that call and try to set the proper sizes already there.

Author

Commented:
>>>>Hmmm. I would assume that you already are calling MoveWindow or SetWindowPos. Or the WM_SIZE message wouldn't have been invoked.
yes bearing in mind this is an external program and i am simply hooking into its events. the WM_SIZE is called when the window is resized. I tried adding this to the the WM_PAINT ( as i assumed this would be being called before the resize) however this seems to be causing the same slow down and flicker.

>>>> bearing in mind this is an external program and
>>>> i am simply hooking into its events.

Does that mean that you only experience the flicker in case of a 'user-driven' resizing? Not always when are hooking into? If  so, you have to handle the WM_SIZING message rather than the WM_SIZE. WM_SIZING is sent *before* the window was resized and then you actively could change controls which are not drawn already.

Author

Commented:
>>Does that mean that you only experience the flicker in case of a 'user-driven' resizing? Not always when are hooking into?

yes exactly whats happening if i dont do my processing then it doesn't flicker.

>>If  so, you have to handle the WM_SIZING message rather than the WM_SIZE.
this has improved the situation however the response is still significantly delayed.

one problem i do think i have found is the fact that WM_WINDOWPOSCHANGING is called on a resize too.

The way the program works is that it adds the buttons when a WM_WINDOWPOSCHANGING is detected (providing it hasn't already been added) (this is because the WM_CREATE isn't called in this process and this message seemed the best to use.)

I have an array of current hooks, these structures contain information about the current hook including the hwnd of the windows already hooked into. when the WM_WINDOWCHANGING event is triggered i need to test to see if the window has been added to this structure or not. I do this using the following function,

const char* appText = " - HOOKED";

HWND__* FindCurrentWindow( char* name )
{
      char* newTitle = (char*) malloc(strlen(name)+strlen(appText)+1);
      strcpy(newTitle, name);                                    
      strcat(newTitle, appText);

      HWND__* foundWND = FindWindow(NULL, name);
                              
      while( foundWND > 0 )
      {
            if(IsInCurrent(foundWND))
            {
                  SetWindowText(foundWND, newTitle);
                  UpdateWindow(foundWND);
                  foundWND = FindWindow(NULL,name);
            }
            else
                  break;
      }      
      
      //gt foundWND now rename all that have been changed back
      while( FindWindow(NULL, newTitle) > 0 )
            SetWindowText(FindWindow(NULL, newTitle), name);      

      return foundWND;
}

The idea of this function is to check if a) the window is in the current structure and b) if this is another instance of a relevant window. i.e. if findwindow returns positive there could potentially be another instance of this window triggering this. it gets aroud this be renaming the window (tacking on a const char), and then calling findwindow again to see if there are any more instance fo the window. At the end of the check all the windows are renamed back.

The reason i see know this is being called is because i can see the window name changing in the flickering.

could this be the problem?

may thanks,

Matt.

Author

Commented:
yes after checking this it is the WM_WINDOWPOSCHANGING call that is causing the problems and is slowing down the program.

The way i checked this is i created a BOOL resizing which is initally false

i will only run WM_WINDOWPOSCHANGING if this is false and when a WM_SIZING is called this sets it to true.

is there a message i can process that occurs after this WM_WINDOWPOSCHANGING event i can reset the BOOL to false? so for example

WM_RESIZE is called it sets the bool to true
WM_WINDOWPOSCHANGING -s called and as this is fals is not called
<final message> after these two messages is called and resets the BOOL to true;
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.