Print Page | Close Window

[solved] v17 BUG ProcessPendingPaintMessages hangs

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Toolkit Pro
Forum Description: Topics Related to Codejock Toolkit Pro
URL: http://forum.codejock.com/forum_posts.asp?TID=22835
Printed Date: 28 March 2024 at 12:34pm
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: [solved] v17 BUG ProcessPendingPaintMessages hangs
Posted By: MacW
Subject: [solved] v17 BUG ProcessPendingPaintMessages hangs
Date Posted: 11 January 2016 at 7:07am
Sometimes, when I resize a XTP pane with the mouse, XTP stops responding and hangs in

ProcessPendingPaintMessages

in the GetMessage() call.

The method is called from

void CXTPDockingPaneSplitterWnd::OnLButtonDown(UINT /*nFlags*/, CPoint point)

You first query if a message is available via PeekMessage(...) and then enter GetMessage.

This will block if messages are processing between your call to PeekMessage and the GetMessage call. This can happen on a fast PC I guess or if the system is under stress.

I can reproduce this at will with certain "expensive" panels which cause a lot of work when processing WM_SIZE. At all times, XTP stops in ProcessPendingPaintMessages(). This did not happen with the version before the 17 - whatever was the last update of XTP 16.x before that.

The only work-aronud I have found so far is do press <Windows>+<D> two times and then click on my window. This pushes new messages into the message queue and XTP wakes up because the blocking GetMessageCall returns.

The pane which always allows to reproduce this contains a CHtmlView.





Replies:
Posted By: astoyan
Date Posted: 12 January 2016 at 12:00am
Can you please try to reproduce the problem using any of our samples or provide a custom sample application? We are aware about this issue in the previous versions, what you faced with is most likely a scenario that we did not take into account.

Regards,
  Alexander


Posted By: MacW
Date Posted: 12 January 2016 at 3:27am
I cannot send you my application, sorry

Basically I host a CHTMLView inside the panel, and this HTMLView renders Maps using OpenLayers. We have an embedded WebBrowser control in a HTMLView and this may cause problems because of the multi.-threaded nature of the CWebBrowserCtrl and how it processes messages.

Maybe you can repro it by embedding a CHtmlView in a panel and then let it navigate to a complex web page, then resize the panel.

I can reproduce it in 9/10 cased. I just click on the panel border and start moving it, and XTP freezes in the GetMessage call. The only reason for this is that between your four calls to PeekMessage and the GetMessage call, the message queue was emptied.

I thought I had a work-around by de-coupling the code that I run when W_SIZE is received by setting a timer instead and processing the code 1 second later. But still XTP blocks sometimes. When I disable the resizing of the CHTMLView in response to WM_SIZE, XTP does not block.

I even tried to handle the xtpPaneActionSplitterResizing and xtpPaneActionSplitterResized events, disabling the HTML view WM_SIZE handing between these two events. The idea was to wait until XTP has finished sizing the panel and then update the size of the HTMLView. Still, customers report that it still freezes sometimes on their machines.



Posted By: MacW
Date Posted: 18 January 2016 at 3:53am
Any news on this?

The bug reports from my users pile up, because all XTP Panels which an embedded CHTMLView cause this problem - attempting to resize such a panel freezes XTP immediately.


Posted By: MacW
Date Posted: 19 January 2016 at 5:23am
This is all taking way too long. My users are killing me.
Over a week, and no feedback on this. I'm sorry to say but I wonder why I pay the fees every year.

Although I really hate to change Codejock code, I saw no other chance to fix this. I changed your code, which reliably freezes, with this code:
BOOL CXTPDrawHelpers::ProcessPendingPaintMessages(HWND hWnd /*= NULL*/)
{
MSG msg;
const UINT MESSAGES[] = { WM_PAINT , WM_ERASEBKGND , WM_SYNCPAINT , WM_NCPAINT };

while (true) {
bool processed = false;
for (int k = 0; k < _countof(MESSAGES); k++) {
while (::PeekMessage(&msg, hWnd, MESSAGES[k], MESSAGES[k], PM_REMOVE)) {
if (msg.message == WM_QUIT) {
return FALSE;
}
::DispatchMessage(&msg);
::ValidateRect(msg.hwnd, NULL);
processed = true;
}
}
if (!processed) return TRUE;
}
}

which (apparently) does the same as your code, but does not freeze the application. It's just a work-around but it does the job. I hope you can fix this more elegantly.


Posted By: olebed
Date Posted: 19 January 2016 at 8:29am
Hello MacW,

Try to change in our version of ProcessPendingPaintMessages method
if (0 < ::GetMessage(&msg, hWnd, msgPeeked.message, msgPeeked.message))

with
if (::PeekMessage(&msg, hWnd, msgPeeked.message, msgPeeked.message, PM_REMOVE))

I have tested these changes on our samples without hangs.

Also I think
if (msg.message == WM_QUIT)
never be TRUE because msg.message can be only one of { WM_PAINT , WM_ERASEBKGND , WM_SYNCPAINT , WM_NCPAINT }

Regards,
Oleksandr Lebed


Posted By: MacW
Date Posted: 19 January 2016 at 11:22am
MSDN says:

Note that PeekMessage always retrieves https://msdn.microsoft.com/en-us/library/windows/desktop/ms632641%28v=vs.85%29.aspx" rel="nofollow - WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax.

so I considered it safer to handle this case and return FALSE.


Posted By: olebed
Date Posted: 19 January 2016 at 11:29am
Originally posted by MacW MacW wrote:

MSDN says:

Note that PeekMessage always retrieves https://msdn.microsoft.com/en-us/library/windows/desktop/ms632641%28v=vs.85%29.aspx" rel="nofollow - WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax.

so I considered it safer to handle this case and return FALSE.

Ok, I missed this.  But have you tried my proposal ? (I can't yet reproduce behavior of your application on our samples.)




Posted By: MacW
Date Posted: 19 January 2016 at 1:33pm
I' quite sure it will work.

Both solutions avoid the potentially blocking call to GetMessage and use a PeekMessage with PM_REMOVE instead. This also pumps the paint messages, but avoids the risk of blocking in the case that the message is consumed between the PeekMessage and the GetMessage call.


Posted By: olebed
Date Posted: 19 January 2016 at 1:58pm
Yes, logic the same, but

If I change whole method's body then it will be harder in future to track changes in this method with SVN.

That is why I want change just one line and ask you to test, please Smile



Posted By: MacW
Date Posted: 20 January 2016 at 3:59am
Hi, Oleksandr

I tried your solution. It prevents the freeze, but has side-effects.
Your solution allows messages to be processed between the two PeekMessage calls. In my application this causes the following behavior:

I left-click the panel border and start dragging the border left or right. The panel resizes (no freeze,. good!) but then the 'mode' changes and the border stops following the mouse movements - like I had release the left mouse button. But the button is still pressed.

I have to release and left-click again to continue with the resizing.

In my solution, the user can move the border left and right to resize the panel until he releases the mouse button. This is the desired and normal behavior.

I think that the same effect happens in your solution: The first PeekMessage determines that a message needs to be processed. But before the second PeekMessage is called (the replacement for the GetMessage), the message is consumed. PeekMessage returns FALSE and the loop ends. This affects your mouse tracking or something.

The idea in my solution was to process the message straight away, without giving something else the chance to remove it from the message queue. This prevents blocking and unwanted side-effects.






Posted By: Fredrik
Date Posted: 23 January 2016 at 8:06pm
Hi, is this perhaps related to what I have reported twice, last in the last message in the following post? http://forum.codejock.com/forum_posts.asp?TID=22599&KW=&FID=112&PR=3&PID=74264&title=version-170-sneak-peek#74264

I.e. a workaround is to call m_pPaneManager.UseSplitterTracker with FALSE for now.

I submitted a support ticket for over two weeks ago how to easily reproduce the problem in CodeJock samples. No reply as so far. I wonder what happened with the expected response time of 24-48 hours...


-------------
Windows 10, Visual Studio 20157, Toolkit Pro 18.3.0


Posted By: olebed
Date Posted: 24 January 2016 at 3:21am
Hello Fredrik,

Highlighting of backstage commands for Office 2013 (except Word) or Visual Studio 2015 themes do not related with changes in CXTPDrawHelpers::ProcessPendingPaintMessages.  I'm working on those themes now.

But changes in CXTPDrawHelpers::ProcessPendingPaintMessages have impact on DockinPane  with next settings CXTPDockingPaneManager::SetAlphaDockingContext(FALSE) and CXTPDockingPaneManager::SetShowContentsWhileDragging(TRUE). We are looking for solution now.

Regards,
 Lebed Oleksandr


Posted By: MacW
Date Posted: 23 April 2016 at 5:28am
Hi Oleksandr,

this seems to have been fixed successfully in 17.2. Thanks!



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net