![]() |
|
QA: Why does my child list view control repaints when the SIP is toggled?
By Joao Paulo Figueira, August 08, 2003.
QuestionMy MFC application has a CListCtrl as the CMainFrame's child. When I open or close the SIP the CListCtrl will always repaint itself. Why? How can I prevent this? AnswerActually, there will be one situation where the list control will not get repainted and another where it will always repaint. This first situation happens when the SIP does not cover any of the list's displayed data. The second situation will happen when, by opening or closing the SIP, the resizing of the list will imply showing or hiding the scrollbar(s). This is default behaviour. But what happens when the list has enough data to display the vertical scrollbar and you open the SIP? The File Explorer application uses a list view control to display the files and it will not repaint under these circumstances. So why is it different under MFC? MFC will always change the window classes it creates, unless we tell it not to. This is important because, by default, MFC will always add the CS_VREDRAW and CS_HREDRAW to all window classes it uses to create windows, even to the common control classes. As a matter of fact, MFC will superclass these and will even rename them, prepending a WCE_ prefix to the class name. See http://www.pocketpcdn.com/articles/wce_prefix.html. So you are not really using a SysListView32, but a WCE_SysListView32 with the CS_VREDRAW and CS_HREDRAW styles. These will force the window to repaint itself when its size changes, a situation that is forced when the SIP changes its state. Also, your CMainFrame window class will have these style bits set. When you resize its child window (whatever its window class bits are) it will also repaint. So, to solve this problem, we will need to address both windows, and make sure that they will not have those window class style bits set. Fixing the ListFixing the list view control is simple: create it using the API and then subclass it. The sample application shows how to do this in the CDemoList class. Here are the highlights of the class implementation: When the window is being destroyed, you have to unsubclass it: One drawback you have to be aware of is that by using this approach, you will lose the ability to intercept the WM_CREATE message, so your OnCreate handler will never be called. But, by doing this, you have created a bona fide SysListView32 window. Fixing the FrameFixing the CMainFrame window involves another approach, where you have to force MFC to register a window class without the CS_VREDRAW and CS_HREDRAW class styles. The best way to do it is by overriding the CFrameWnd LoadFrame virtual method. Add the following declaration to your CMainFrame class, in the public section: And here is the implementation, using most of CFrameWnd's code: Don't forget to add the following include directive in the cpp file: Finally, you will have to comment out (or delete) one line in the PreCreateWindow code generated by the wizard: This way, your main frame will have the correct window class style bits, and the unnecessary repainting will be avoided. Thank YouTo Alexander Shargin who provided precious help in cracking this one down. SampleYou can also download a sample application - NoRepaint.zip - 28K. Related resources:
DiscussDiscuss this article. Here you can write your comments and read comments of other developers. |
|||||||||||||||||||||