Why doesn't Chrome hang when a plugin fails? - winapi

I understand that Chrome using re-parenting in order to have child plugins such as Flash render from different processes.
I have experimented with this, and I have got it working using the SetParent Win32 call.
However, when I force the child GUI thread to block, the parent process will also hang as soon as the mouse moves over a the window area owned by the child process. Presumably this is because the message loop in the parent application is calling down to the child and it never responds. How does Chrome get around this?

Flash uses the re-parenting trick. It has its own .exe and renders to its own window. That doesn't prevent hangs, any message that is sent from that window to its owner is going to block when the owner isn't pumping messages. As you found out.
Browsers uses a different trick. They create an invisible helper process for each tab and render to a memory device context. And blits the result to their desktop window. Any input messages are shuttled back to that process. That makes them immune from crashes and hangs in that process, killing that helper process keeps the browser going. Much harder to do yourself.

Related

How can I ensure my process receive focus when one of its child process closes?

A little background
Our application (AppA) is calling a 3rd party application (AppB). We are simulating AppB's window as being modal to our application.
pseudo
while AppB_Running
If AppA_focused
SetForeGroundWindow(AppB_Hwnd)
HandleMessage
SetForegroundWindow(AppA_HWnd)
This has been working for years without incidents, that is, until we started rolling out Windows 10. We started receiving reports that a random app (AppC) was sometime getting the focus when we closed AppB (Actually, given our user's tech expertise, the report were more along the line "Closing AppB kills AppA" but I digress). That behavior can be reproduced occasionnaly(<5%) on dev machine (But not yet while debugging...)
So far, test result suggest AppC is the application that had the focus before AppA.
Is there a way I can ensure AppA gets the focus back when AppB closes?
Extra notes
The problem can be reproduced even if AppA only ever loses focus to AppB. (AppC never being focused after AppA started)
While this does not directly answer my original question, it does give some more insight on the problem and might be useful to someone else.
Part of the issue was an oversight on our end. More specifically, the way we obtained AppB_HWnd. We basically picked the first top level window we encountered. In our current test case, that window happens to be an invisible windows ('MSCTFIME UI'). Calling SetForegroundWindow on an invisible window doesn't seem to cause problems per se, Windows seems to just bring to front one of the process' visible window. It is when said process does not have any visible windows left that things seems to go awry. That usually happen in our case between the moment AppB's main window is closed and the moment the process ends.
So... Don't call SetForegroundWindow on an invisible window
As for why we didn't have any trouble in Win7? Maybe the first window was always a visible one. Or maybe SetForegroundWindow behaved differently back then.

Visual Studio Time Out

When I debug my program, which consists of looping over thousands of entries in vectors multiple times, it simply freezes the program but does not provide any error messages whatsoever. Does Visual Studio have some sort of auto-time out that I am experiencing?
Check may be your program is going into infinite loop Or doing some heavy task that makes your UI unresponsive(if you have windows form). Since you are debugging this program then why dont you set breakpoint in code and check where your program is causing issue.
And yes there is no time out for Visual Studio,But for program window.This is known as Hang Status.
When an application (or more accurately, a thread) creates a window on the desktop, it enters into an implicit contract with the Desktop Window Manager (DWM) to process window messages in a timely fashion. The DWM posts messages (keyboard/mouse input and messages from other windows, as well as itself) into the thread-specific message queue. The thread retrieves and dispatches those messages via its message queue. If the thread does not service the queue by calling GetMessage(), messages are not processed, and the window hangs: it can neither redraw nor can it accept input from the user. The operating system detects this state by attaching a timer to pending messages in the message queue. If a message has not been retrieved within 5 seconds, the DWM declares the window to be hung. You can query this particular window state via the IsHungAppWindow() API.
Detection is only the first step. At this point, the user still cannot even terminate the application - clicking the X (Close) button would result in a WM_CLOSE message, which would be stuck in the message queue just like any other message. The Desktop Window Manager assists by seamlessly hiding and then replacing the hung window with a 'ghost' copy displaying a bitmap of the original window's previous client area (and adding "Not Responding" to the title bar). As long as the original window's thread does not retrieve messages, the DWM manages both windows simultaneously, but allows the user to interact only with the ghost copy. Using this ghost window, the user can only move, minimize, and - most importantly - close the unresponsive application, but not change its internal state.
A nice article is written in this following link.
How program window works

How to intercept a window message in a shell extension

I have a shell extension that needs to reload its configuration when a specific window message (custom message registered with RegisterWindowMessage) is broadcasted by another application.
I tried several approaches to intercept the message:
Installing a window subclass callback on a window of Windows Explorer, using SetWindowSubclass. This works on Window 7, but not on Windows 8, because apparently DllMain is not called on the main thread, and SetWindowSubclass doesn't work from another thread. This is mentioned in the documentation:
You cannot use the subclassing helper functions to subclass a window across threads
Installing a hook for CALLWNDPROC, using SetWindowsHookEx. Because I don't want to slow down the whole system, I install the hook for a specific thread only (the explorer's main thread). This works on Windows 8, but not on Windows 7... I suspect this is because I'm hooking on the wrong thread, but I'm not sure. And anyway, this approach seems overly intrusive.
Creating a message-only window to handle the message. This doesn't work at all, because message-only windows don't receive broadcasted messages.
Is there a reliable way to receive a window message in a shell extension?
A window message initially seemed to be the easiest way to notify the shell extension, but if you think another mechanism would be more appropriate, I'm open to suggestions.
Create a hidden window and listen for the message in its window procedure.
Register a window class that has default values for all the fields apart from the window procedure and class name. You don't need to specify anything else in the window class since the window will never be visible.
When you create the window, pass 0 for the window style. Specifically exclude WS_VISIBLE.
Pass 0 for the WndParent when you create the window. This will make it a top level window and so eligible to receive broadcast messages.

Preventing WM_SETCURSOR and WM_NCHITTEST messages from being generated

I'm making an application that hooks itself in to a target application and, when activated by the user, prevents all keyboard and mouse window messages from reaching the target application's window proc. My application does this by translating the incoming input messages, such as WM_MOUSEMOVE, to WM_NULL, so that the window proc is unaware input happened.
The problem is that Windows also automatically sends WM_SETCURSOR and WM_NCHITTEST to the window proc (e.g. when the application calls PeekMessage) when mouse input occurs. These messages aren't posted to the window's message queue, so I can't change them to WM_NULL.
I initially worked around this by subclassing the window proc and simply ignoring WM_SETCURSOR and WM_NCHITTEST there, but subclassing seems to have compatibility issues with some of the applications I'm hooked in to.
My question is: How do I prevent WM_SETCURSOR and WM_NCHITTEST from being generated in the first place OR how do I prevent them from reaching the application's window proc.
Some Ideas to Try
I just finished implementing a global/system wide CallWndRetProc with a WH_CALLWNDPROCRET Windows Hook (like it describes in the past post of the link below).
http://help.lockergnome.com/windows2/Igor-SetCursor-SetWindowsHookEx--ftopict285504.html
Using that in combination with hiding all the system cursors using SetSystemCursor has effectively hidden the cursor for most applications.
If you wanted to continue hacking at this target application, you could try using API Monitor to diagnosis what is going on: http://www.rohitab.com/apimonitor
The guy at rohitab hints at releasing his source code eventually; his site seems to have some of the better forums about Hooking, Subclassing, Injecting, etc.
It sounds like you successfully used SetWindowLongPtr(), but there are a few different ways to get into the address space of the program you are working on...
Have you tried SetCapture()?
Other Links
Here are a few other links that may be useful:
http://support.microsoft.com/kb/31747
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646262(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633569%28v=vs.85%29.aspx#winproc_subclassing
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648395(v=vs.85).aspx
Hope that helps. Good luck.

Debugging SHDocVw.InternetExplorer.Quit not closing iexplore.exe process

I think there's no definite answer so how would you approach debugging this problem?:
My main app (a MicroStation plugin) launces IE using the SHDocVw.InternetExplorer COM wrapper, interacts with it, hides it when it is not used (e.g. intercepts when the user closes the window and sets InternetExplorer.Visible to false).
When the main app is closed the plugin closes IE by calling InternetExplorer.Quit but the iexplore process is left running (the IE is hidden at the moment the main app is closed).
What I have tried:
Calling System.Runtime.InteropServices.Marshal.FinalReleaseComObject on the InternetExplorer object after calling Quit
Setting the reference to the InternetExplorer object to null after Quit and FinalReleaseComObject
Making sure the parent managed objects gets GC'd (checking if Finalize is called) before the main app exits
Creating a test console app and trying to reproduce the problem there. E.g. trying to call Quit when IE is in the hidden state. (I could not reproduce the problem, IE gets closed as soon as the app exits)
What is also interesting, I could not reproduce the problem calling Quit within the same main app (MicroStation plugin) but while the main app is running, not in the exit event handling code. When called in that other place Quit closes IE as expected.
Otherwise the InternetExplorer object is opaque to me.
Are there other ways to debug this problem?
Edit: It may be worth noting that the main app creates a UserControl and makes the IE window a child of this UserControl (using SetWindowLong to change the GWL_STYLE to allow the window to be a child and SetParent to set the UserControl as parent). But when the IE is hidden (which it is when the Quit attempt fails) the parent window is set to 0.
Thanks!

Resources