Solved

WM_PAINT in modeless dialog boxes question

Posted on 1998-01-27
15
1,177 Views
Last Modified: 2013-12-03
How do I keep my modeless dialog box from repainting itself? I need to keep it from repainting during a move operation and I'm setting a flag during WM_ENTERSIZEMOVE and clearing it during WM_EXITSIZEMOVE but there seems to be no way for me to intercept WM_PAINT's. I've tried flushing the message queue of WM_PAINT's during the move but that no work and I've tried InvalidatingRect of dialog box during move but that no work and I've tried returning TRUE for WM_PAINT message but that no work.

Thanks
0
Comment
Question by:overworked
  • 8
  • 6
15 Comments
 

Author Comment

by:overworked
ID: 1410441
Edited text of question
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410442
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410443
A couple things.

First I suspect that what you did to "flush" the queue of paint messages was to just ignore the messages when they occur, that is, to not paint on them and also to not send them to the default window procedure. This won't work.  (I guess you know that.)  The problem is that WM_PAINT is never actually put in the queue.  The system generates the messages whenever there are not other high proiority messages in the queue and when there are windows that have invalid regions.  

to be continued...
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410444
I should have pointed out in the previous comment that this means that if Windows has an invalid region for your window you will continue to get paint messages until you tell it the region is valid.  The beginpaint/endpaint functions tell it the window is now valid.

What to do about this?  That depends.  

Assuming that you really want to prevent painting (I suspect you might not) you can validate the window or a portion of it useing ValidateRect() or ValidateRgn().  Or you can use BeginPaint()/EndPaint() but not paint (ValidateRect() is probably more efficient, but painting is the bottleneck, doing the BeginPaint()/EndPaint() without painting will execute quickly.)

to be continued...
0
 

Author Comment

by:overworked
ID: 1410445
No, to flush the queue of WM_PAINT msg's, I physically removed all of them from the queue using PeekMessage. I couldn't ignore paint messages if I wanted since I'm not doing any painting - the default dialog processing does all the painting. Since it's a dialog proc message handler, I return TRUE if I process the message. However, doing so for WM_PAINT doesn't stop it and things still get painted. There's no way to call DefDlgProc or DefWindowProc here since this is a dialog box and doing so from my DialogProc would result in recursion. I think you need to re-read my question.

Thanks for trying.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410446
Now I suspect that there might be a better way of handling your situation, but I'm not 100% sure what your situation is.  You said that you don't want to repaint during a move operation, but I'm not sure how to interpret that.  Possibly you want the contents of the window to be copied from the old location to the new?  If so you can intercept the WM_NCCALCSIZE message (let the default window procedure handle it and then you handle it) and use first and second rectangles in the parameters to indicates what portion of the old window should be copied to the new window.  You must return WVR_VALIDRECTS to indicate this.  (This is all documented under WM_NCCALCSIZE.)  

There may be other/better possibilities.  I might be able to provide more if you explained what the (real) problem is or what you are trying to do.
0
 

Author Comment

by:overworked
ID: 1410447
Note:

In original question "I've tried InvalidatingRect" should read "I've tried ValidateRect".

The reason I'm trying to keep my modeless dialog box from painting when its window is being moved is because new Win95/NT desktop interface includes an option which when 'on' results in entire contents of windows being dragged during a move/size operation instead of the standard moving/sizing rectangle. This causes problems for me. Microsoft says this is how I work-around this:

-------------------------------------------------------------------------
The information in this article applies to:
 
- Microsoft Win32 Application Programming Interface (API) included with:
 
 - Microsoft Windows NT versions 3.5 and 3.51
 - Microsoft Windows 95 version 4.0
-------------------------------------------------------------------------
 
Windows NT version 3.5 introduces full drag, which allows you to see the
entire window moving or resizing instead of seeing just an outline of the
window moving or resizing. You can enable full drag by running the Desktop
Control Panel applet and selecting the Full Drag checkbox.
 
When you resize a window with full drag enabled, the application will
receive numerous messages indicating that the window is resizing. (You can
verify this with Spy.) If this has undesirable effects on your application,
you will need to override the full drag feature in your application.
 
When the moving or resizing starts, the application receives this message:
 
WM_ENTERSIZEMOVE (0231)
 
When the moving or resizing finishes, the application receives this
message:
 
WM_EXITSIZEMOVE (0232)
 
The above messages act as a notification that the window is entering and
exiting a sizing or moving operation. If you want, you can use these
notifications to set a flag to prevent the program from handling a WM_PAINT
message during the move or size operation to override full drag.
 

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 22

Expert Comment

by:nietod
ID: 1410448
you said

No, to flush the queue of WM_PAINT msg's, I physically removed all of them from the queue using PeekMessage.

But you can't do that.  They aren't in the queue.  Windows generates them each time you call PeekMessage (or other message retreval function) and there is no message to return.

Telling the dialog procedure that you handled the paint message by return true doesn't change anything because you still have an invalid region so windows will continue to generate paint messages.

Validating the region will end the paint messages however.  

Again, I suspect this is not what you really want though.  What is it you are trying to do.
0
 

Author Comment

by:overworked
ID: 1410449
Hi Nietod, I see we're online at same time. Refer to my previous comment for exactly what I'm trying to do. btw- I'm doing this all in asm cause it's so much fun! I like asm probably more than you do :)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410450
Stop answering questions before I ask them!

I'm not sure about microsoft's idea here.  I don't see, for example, how this would give the appearance of the old behavior.  Although you would not be painting the contents of the window, the frame would still be updated (I think).  In addition, the old behavior has the "drag box" show the new location/size.  I don't see how their proposed scheme would enable this.

I assume the reason you don't want to paint repeatidly is speed.  Right?  If so, why not set a flag during the move start that causes the slow drawing operations to be skipped.  (Or causes child windows with slow redraws to be hidden).  Then clear the flag or show the child windows at the end of the move.  In this case I would see to it that the windows are at least filled in with their background color or it might be unpleasant to look at.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1410451
Assembly?  Take a look at my "bio"  (I wrote a POWERFUL 500,000 line windows assembly language accounting system.)  I love assembly but have switched to C++ because microsoft has unofficially ended MASM development/support.  (I'm an alpha tester and there has not been an alpha release in 4 or 5 years.)
0
 

Author Comment

by:overworked
ID: 1410452
Actually, in the client area of my main window, I have about 8 modeless dialog boxes all on top of each other like a stereo system. Each dialog is one of my audio devices (cd player, mixer, midi player, wave player, etc..). There's a vert scroll bar when all devices dont fit. When user left clicks on a device surface, I post a WM_NCLBUTTONDOWN,HTCAPTION to get the device in a move state (to facilitate moving device to diff location in stack). During move, I watch WM_MOVING and if the client needs to be scrolled, I call ReleaseCapture to get WIN to stop the move operation, I post a WM_VSCROLL message, and then I post another WM_NCLBUTTONDOWN,HTCAPTION to restart my move operation from where I left off. This works great if user doesn't have 'drag contents' selected in OS. However, when they do and it was necessary to scroll during move, I run into a few problems and my 'device move system' doesn't work as clean. I can overcome it but I really wondered how hard it was to keep my device (modeless dialog box) from repainting itself during the move.

btw, I think the new 'drag contents' thingy operates the same way as it did when off but sends WM_PAINT messages. Therefore, if the WM_PAINT messages never arrived, the moving/sizing border would still be there for user to see, since it didn't get painted over.
0
 
LVL 15

Accepted Solution

by:
Tommy Hui earned 200 total points
ID: 1410453
Why not set the redraw flag on the dialog and all of its children to FALSE (SendMessage(hwnd, WM_SETREDRAW, TRUE or FALSE, 0));


0
 
LVL 22

Expert Comment

by:nietod
ID: 1410454
That's sounds like a good possibility.  

However, another thought might be to do all the moving manually rather than fake windows into moving for your.  Thui's idea will be easier to impliment, but given the complex slightly weird nature of what you are doing, it might be a little cleaner to move the windows yourself.  You just need to draw the drag rectangles and follow the mouse and then when the darag is done, move or resize the window one time.

Is there are reason that each of these windows are dialog boxes?  It SEEMS to me like your life would be easier with regular windows.
0
 

Author Comment

by:overworked
ID: 1410455
That works great thui! It does what it's supposed to do and made me realize that Microsoft didn't. It seems that when full drag is on, no move/size border is there (not even underneath the window contents). Microsoft's explanation of how to disable full-drag comes up short since the old behavior is gone (as nietod suspected).

Nietod: Your suggestion to manually draw drag rect may be the only way now with this full drag prob. I'm using dialog boxes cause each contains buttons/sliders/list boxes/combo boxes and the default functionality of dialog box is exactly what I need and saves me alot of headaches. Thanks for all your un-rewarded suggestions and help!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
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…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

759 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now