Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Size/move loop and delay in DefWindowProc


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
21 replies to this topic

#21 adeyblue   Members   -  Reputation: 518

Like
0Likes
Like

Posted 16 January 2009 - 06:14 PM

It's down to a 500ms wait on an event when there are no mouse, keyboard, or sync messages in the queue. The event seems to be signalled when there are input messages available. There's also lots of resource locking which is mostly block-until-available so 500ms would be a lower bound to the stall. Lots of calls to user mode as well for hooking purposes so there's a few context switches to account for too.

The "highlights" from WM_SYSCOMMAND to WM_MOVING:

xxxSysCommand-
Calls some hook back in UM
xxxIsDragging-
GetKeyState(VK_LBUTTON)-
Just checks some bits, nothing heavy
Sets mouse capture to window-
Locks and unlocks the window
Checks if the thread's impersonation token or the process token is restricted
Checks user has WINSTA_WRITEATTRIBUTES permission on the Window Station
xxxInternalGetMessage (..., WM_MOUSEFIRST, WM_XBUTTONDBLCLK..)-
if any mouse action
Calls mouse hooks -> back to UM
Removes WM_LBUTTONUP from Queue
Calls mouse hooks again -> back to UM
seems it loops around couple of times
otherwise
Exits without doing anything of note
xxxInternalGetMessage(..., WM_QUEUESYNC, WM_QUEUESYNC)
if no message-
xxxInternalGetMessage(..., WM_KEYFIRST, WM_KEYLAST)
if no message-
xxxSleepThread(7, 500, 1)
KeClearEvent()
KeWaitForSingleObject(ClearedEvent, -500ms) // seems to be for input
end if
Releases mouse capture on window-
Locks and unlocks the window again
Puts WM_MOUSEMOVE in message queue
Calls window proc with WM_CAPTURECHANGED (0x0215)
returns whether the message x/y pos was within a specified rect (if there was a message)
if dragging
xxxSetWindowPos(PWND, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) -
BeginDeferWindowPos(1)
DeferWindowPos()
EndDeferWindowPosEx()
Z-Order checking stuff for a few windows
Call app WndProc with WM_WINDOWPOSCHANGING
Updates the previous top most window if there was one
Locks screen and blits the valid bits
Unlocks the screen
Sends any WM_WINDOWPOSCHANGED messages
returns
not checked beyond here for this case
returns
end if
xxxMoveSize-
Clips cursor to area
Call app WndProc with WM_GETMINMAXINFO
Draw the drag rectange-
SetWindowPos(PVOID, 0, x, y, width, height, (SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOZORDER))-
Locks screen and blits the valid bits to the new pos
Unlocks the screen
Updates relevant Windows
Fakes a mouse move
Call app WndProc with WM_ENTERSIZEMOVE
Locks Capture Window
Show Cursor
GetMessage(wnd, no filter)-
Scan's system queue for all messages-
GetNextSysMessage-
WM_MOUSEMOVE posted (prob due to fake move above)
Mouse hooks called
WM_MOUSEMOVE consumed (deleted from queue)
Hooks called again
Updates drag rect-
Calls WndProc with WM_MOVING
Redraws the rect
Wait for messages



Sponsor:

#22 MicroVirus   Members   -  Reputation: 100

Like
0Likes
Like

Posted 20 April 2011 - 02:00 PM

Hello all,

I know this is a very late reply but I felt I might be able to help people searching for answers to this question by adding some information.
What happens in the 'stall' is that DefWindowProc takes over complete control. You enter DefWindowProc and it doesn't return until the move is completed.
During that time, DefWindowProc will send a lot of WM_* messages to your own window procedure (including move updates), one important one being WM_PAINT (and I'm guessing only if your system settings are such that the windows are drawn during move and resize operations). So, you can draw and therefore update your window during the stalls by responding to WM_PAINT with a scene draw.
The bad news is that all your regular game code, starting with your message pump and ending with the normal process & draw loops, don't get called during the entire operation.
Testing with a couple of other applications, I think I may have found the one compelling reason for applications to supply their own customised title bar with system menu: so as to avoid DefWindowProc hanging on non-client messages (NC_* window messages).
It seems then that the solution is either to remove all the non-client regions from your window (by setting the appropriate window styles) and implementing your own move/resize and title bar.
Or, you somehow use multi-threading to keep the core going and the window updated; somehow having your gui be pretty much a stub thread while the 'real' thread does all the work (not sure how easy this is to do...).

Hopefully, this can still help someone.
Best Regards,
MicroVirus




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS