?
Solved

Improve response when handling WM_SIZE message in an external app.

Posted on 2007-09-28
9
Medium Priority
?
1,016 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.
0
Comment
Question by:flynny
  • 4
  • 4
9 Comments
 
LVL 14

Expert Comment

by:RichieHindle
ID: 19978353
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.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 19978494
>>>> 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
0
 

Author Comment

by:flynny
ID: 19978624
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?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 19978750
>>>> 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.
0
 

Author Comment

by:flynny
ID: 19978828
>>>>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.

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 19978868
>>>> 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.
0
 

Author Comment

by:flynny
ID: 19979468
>>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.
0
 

Author Comment

by:flynny
ID: 19979592
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;
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 2000 total points
ID: 19979942
a) the window is in the current structure and
b) if this is another instance of a relevant window
Maybe you could try the following:
- I assume you have the hwnd of the application frame window
- with that you could invoke EnumChildWindows to get the child windows
   of that frame
- for each child window you may call GetWindowText to check whether it is
   one you want to hook into

>>>> could this be the problem?
I doubt that calling SetWindowText would lead to repainting let alone a size or pos change. I would assume you'lle get the pos change because of the buttons. If the window has some clip options active adding buttons may lead to a change. You might check that theory by calling GetWindowsOrg when you initially found the window. Then save these values and compare them with the values you get when handling the WM_WINDOWPOSCHANGING message. Maybe you could set the buttons initially inactive and not visible to come around that problem. At least you should omit handling both WM_SIZE and WM_WINDOWPOSCHANGING.  You should handle only the latter and move any resizing and painting there.


0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

830 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