- Change the way that application shutdown works in order to support JavaScript 'onbeforeunload' handling (issue #853). See comments in cef_life_span_handler.h for a detailed description of the new shutdown process.

- Fix a crash on Linux during window destruction (issue #681).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1149 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2013-03-19 22:59:33 +00:00
parent e3b297416f
commit 7ded60a218
33 changed files with 871 additions and 138 deletions

View File

@ -42,6 +42,12 @@ BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
// Used for processing messages on the main application thread while running
// in multi-threaded message loop mode.
HWND hMessageWnd = NULL;
HWND CreateMessageWindow(HINSTANCE hInstance);
LRESULT CALLBACK MessageWndProc(HWND, UINT, WPARAM, LPARAM);
// The global ClientHandler reference.
extern CefRefPtr<ClientHandler> g_handler;
@ -115,6 +121,10 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
// recieves a WM_QUIT message.
CefRunMessageLoop();
} else {
// Create a hidden window for message processing.
hMessageWnd = CreateMessageWindow(hInstance);
ASSERT(hMessageWnd);
MSG msg;
// Run the application message loop.
@ -125,6 +135,9 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
}
}
DestroyWindow(hMessageWnd);
hMessageWnd = NULL;
result = static_cast<int>(msg.wParam);
}
@ -541,17 +554,24 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
break;
case WM_CLOSE:
if (g_handler.get()) {
if (g_handler.get() && !g_handler->IsClosing()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
// Let the browser window know we are about to destroy it.
browser->GetHost()->ParentWindowWillClose();
// Notify the browser window that we would like to close it. This
// will result in a call to ClientHandler::DoClose() if the
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false);
// Cancel the close.
return 0;
}
}
// Allow the close.
break;
case WM_DESTROY:
PostQuitMessage(0);
// Quitting CEF is handled in ClientHandler::OnBeforeClose().
return 0;
}
@ -576,9 +596,50 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
return (INT_PTR)FALSE;
}
HWND CreateMessageWindow(HINSTANCE hInstance) {
static const wchar_t kWndClass[] = L"ClientMessageWindow";
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = MessageWndProc;
wc.hInstance = hInstance;
wc.lpszClassName = kWndClass;
RegisterClassEx(&wc);
return CreateWindow(kWndClass, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
hInstance, 0);
}
LRESULT CALLBACK MessageWndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam) {
switch (message) {
case WM_COMMAND: {
int wmId = LOWORD(wParam);
switch (wmId) {
case ID_QUIT:
PostQuitMessage(0);
return 0;
}
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Global functions
std::string AppGetWorkingDirectory() {
return szWorkingDir;
}
void AppQuitMessageLoop() {
CefRefPtr<CefCommandLine> command_line = AppGetCommandLine();
if (command_line->HasSwitch(cefclient::kMultiThreadedMessageLoop)) {
// Running in multi-threaded message loop mode. Need to execute
// PostQuitMessage on the main application thread.
ASSERT(hMessageWnd);
PostMessage(hMessageWnd, WM_COMMAND, ID_QUIT, 0);
} else {
CefQuitMessageLoop();
}
}