Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1231
  • Last Modified:

WM_PAINT in modeless dialog boxes question

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
overworked
Asked:
overworked
  • 8
  • 6
1 Solution
 
overworkedAuthor Commented:
Edited text of question
0
 
nietodCommented:
answer coming.
0
 
nietodCommented:
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
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 
nietodCommented:
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
 
overworkedAuthor Commented:
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
 
nietodCommented:
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
 
overworkedAuthor Commented:
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
 
nietodCommented:
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
 
overworkedAuthor Commented:
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
 
nietodCommented:
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
 
nietodCommented:
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
 
overworkedAuthor Commented:
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
 
Tommy HuiCommented:
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
 
nietodCommented:
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
 
overworkedAuthor Commented:
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now