mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Create 2272 release branch for CEF3.
git-svn-id: https://chromiumembedded.googlecode.com/svn/branches/2272@1993 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
166
tests/cefclient/main_message_loop_multithreaded_win.cc
Normal file
166
tests/cefclient/main_message_loop_multithreaded_win.cc
Normal file
@ -0,0 +1,166 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/main_message_loop_multithreaded_win.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/util_win.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kWndClass[] = L"Client_MessageWindow";
|
||||
const wchar_t kTaskMessageName[] = L"Client_CustomTask";
|
||||
|
||||
} // namespace
|
||||
|
||||
MainMessageLoopMultithreadedWin::MainMessageLoopMultithreadedWin()
|
||||
: thread_id_(base::PlatformThread::CurrentId()),
|
||||
task_message_id_(RegisterWindowMessage(kTaskMessageName)),
|
||||
dialog_hwnd_(NULL),
|
||||
message_hwnd_(NULL) {
|
||||
}
|
||||
|
||||
MainMessageLoopMultithreadedWin::~MainMessageLoopMultithreadedWin() {
|
||||
DCHECK(RunsTasksOnCurrentThread());
|
||||
DCHECK(!message_hwnd_);
|
||||
DCHECK(queued_tasks_.empty());
|
||||
}
|
||||
|
||||
int MainMessageLoopMultithreadedWin::Run() {
|
||||
DCHECK(RunsTasksOnCurrentThread());
|
||||
|
||||
HINSTANCE hInstance = ::GetModuleHandle(NULL);
|
||||
|
||||
{
|
||||
base::AutoLock lock_scope(lock_);
|
||||
|
||||
// Create the hidden window for message processing.
|
||||
message_hwnd_ = CreateMessageWindow(hInstance);
|
||||
CHECK(message_hwnd_);
|
||||
|
||||
// Store a pointer to |this| in the window's user data.
|
||||
SetUserDataPtr(message_hwnd_, this);
|
||||
|
||||
// Execute any tasks that are currently queued.
|
||||
while (!queued_tasks_.empty()) {
|
||||
PostTaskInternal(queued_tasks_.front());
|
||||
queued_tasks_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
HACCEL hAccelTable =
|
||||
LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CEFCLIENT));
|
||||
|
||||
MSG msg;
|
||||
|
||||
// Run the application message loop.
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
// Allow processing of dialog messages.
|
||||
if (dialog_hwnd_ && IsDialogMessage(dialog_hwnd_, &msg))
|
||||
continue;
|
||||
|
||||
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
base::AutoLock lock_scope(lock_);
|
||||
|
||||
// Destroy the message window.
|
||||
DestroyWindow(message_hwnd_);
|
||||
message_hwnd_ = NULL;
|
||||
}
|
||||
|
||||
return static_cast<int>(msg.wParam);
|
||||
}
|
||||
|
||||
void MainMessageLoopMultithreadedWin::Quit() {
|
||||
// Execute PostQuitMessage(0) on the main thread.
|
||||
PostClosure(base::Bind(::PostQuitMessage, 0));
|
||||
}
|
||||
|
||||
void MainMessageLoopMultithreadedWin::PostTask(CefRefPtr<CefTask> task) {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
PostTaskInternal(task);
|
||||
}
|
||||
|
||||
bool MainMessageLoopMultithreadedWin::RunsTasksOnCurrentThread() const {
|
||||
return (thread_id_ == base::PlatformThread::CurrentId());
|
||||
}
|
||||
|
||||
void MainMessageLoopMultithreadedWin::SetCurrentModelessDialog(
|
||||
HWND hWndDialog) {
|
||||
DCHECK(RunsTasksOnCurrentThread());
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (hWndDialog) {
|
||||
// A new dialog reference should not be set while one is currently set.
|
||||
DCHECK(!dialog_hwnd_);
|
||||
}
|
||||
#endif
|
||||
dialog_hwnd_ = hWndDialog;
|
||||
}
|
||||
|
||||
// static
|
||||
HWND MainMessageLoopMultithreadedWin::CreateMessageWindow(HINSTANCE hInstance) {
|
||||
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);
|
||||
}
|
||||
|
||||
// static
|
||||
LRESULT CALLBACK MainMessageLoopMultithreadedWin::MessageWndProc(
|
||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
MainMessageLoopMultithreadedWin* self =
|
||||
GetUserDataPtr<MainMessageLoopMultithreadedWin*>(hWnd);
|
||||
|
||||
if (self && message == self->task_message_id_) {
|
||||
// Execute the task.
|
||||
CefTask* task = reinterpret_cast<CefTask*>(wParam);
|
||||
task->Execute();
|
||||
|
||||
// Release the reference added in PostTaskInternal. This will likely result
|
||||
// in |task| being deleted.
|
||||
task->Release();
|
||||
} else switch (message) {
|
||||
case WM_DESTROY:
|
||||
// Clear the reference to |self|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void MainMessageLoopMultithreadedWin::PostTaskInternal(
|
||||
CefRefPtr<CefTask> task) {
|
||||
lock_.AssertAcquired();
|
||||
|
||||
if (!message_hwnd_) {
|
||||
// Queue the task until the message loop starts running.
|
||||
queued_tasks_.push(task);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a reference that will be released in MessageWndProc.
|
||||
task->AddRef();
|
||||
|
||||
// Post the task for execution by the message window.
|
||||
PostMessage(message_hwnd_, task_message_id_,
|
||||
reinterpret_cast<WPARAM>(task.get()), 0);
|
||||
}
|
||||
|
||||
} // namespace client
|
Reference in New Issue
Block a user