mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			153 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (c) 2016 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 "tests/shared/browser/main_message_loop_external_pump.h"
 | |
| 
 | |
| #include <CommCtrl.h>
 | |
| 
 | |
| #include "include/cef_app.h"
 | |
| #include "tests/shared/browser/util_win.h"
 | |
| 
 | |
| namespace client {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| // Message sent to get an additional time slice for pumping (processing) another
 | |
| // task (a series of such messages creates a continuous task pump).
 | |
| static const int kMsgHaveWork = WM_USER + 1;
 | |
| 
 | |
| class MainMessageLoopExternalPumpWin : public MainMessageLoopExternalPump {
 | |
|  public:
 | |
|   MainMessageLoopExternalPumpWin();
 | |
|   ~MainMessageLoopExternalPumpWin();
 | |
| 
 | |
|   // MainMessageLoopStd methods:
 | |
|   void Quit() OVERRIDE;
 | |
|   int Run() OVERRIDE;
 | |
| 
 | |
|   // MainMessageLoopExternalPump methods:
 | |
|   void OnScheduleMessagePumpWork(int64 delay_ms) OVERRIDE;
 | |
| 
 | |
|  protected:
 | |
|   // MainMessageLoopExternalPump methods:
 | |
|   void SetTimer(int64 delay_ms) OVERRIDE;
 | |
|   void KillTimer() OVERRIDE;
 | |
|   bool IsTimerPending() OVERRIDE { return timer_pending_; }
 | |
| 
 | |
|  private:
 | |
|   static LRESULT CALLBACK WndProc(HWND hwnd,
 | |
|                                   UINT msg,
 | |
|                                   WPARAM wparam,
 | |
|                                   LPARAM lparam);
 | |
| 
 | |
|   // True if a timer event is currently pending.
 | |
|   bool timer_pending_;
 | |
| 
 | |
|   // HWND owned by the thread that CefDoMessageLoopWork should be invoked on.
 | |
|   HWND main_thread_target_;
 | |
| };
 | |
| 
 | |
| MainMessageLoopExternalPumpWin::MainMessageLoopExternalPumpWin()
 | |
|     : timer_pending_(false), main_thread_target_(NULL) {
 | |
|   HINSTANCE hInstance = GetModuleHandle(NULL);
 | |
|   const wchar_t* const kClassName = L"CEFMainTargetHWND";
 | |
| 
 | |
|   WNDCLASSEX wcex = {};
 | |
|   wcex.cbSize = sizeof(WNDCLASSEX);
 | |
|   wcex.lpfnWndProc = WndProc;
 | |
|   wcex.hInstance = hInstance;
 | |
|   wcex.lpszClassName = kClassName;
 | |
|   RegisterClassEx(&wcex);
 | |
| 
 | |
|   // Create the message handling window.
 | |
|   main_thread_target_ =
 | |
|       CreateWindowW(kClassName, NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
 | |
|                     HWND_MESSAGE, NULL, hInstance, NULL);
 | |
|   DCHECK(main_thread_target_);
 | |
|   SetUserDataPtr(main_thread_target_, this);
 | |
| }
 | |
| 
 | |
| MainMessageLoopExternalPumpWin::~MainMessageLoopExternalPumpWin() {
 | |
|   KillTimer();
 | |
|   if (main_thread_target_)
 | |
|     DestroyWindow(main_thread_target_);
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPumpWin::Quit() {
 | |
|   PostMessage(NULL, WM_QUIT, 0, 0);
 | |
| }
 | |
| 
 | |
| int MainMessageLoopExternalPumpWin::Run() {
 | |
|   // Run the message loop.
 | |
|   MSG msg;
 | |
|   while (GetMessage(&msg, NULL, 0, 0)) {
 | |
|     TranslateMessage(&msg);
 | |
|     DispatchMessage(&msg);
 | |
|   }
 | |
| 
 | |
|   KillTimer();
 | |
| 
 | |
|   // We need to run the message pump until it is idle. However we don't have
 | |
|   // that information here so we run the message loop "for a while".
 | |
|   for (int i = 0; i < 10; ++i) {
 | |
|     // Do some work.
 | |
|     CefDoMessageLoopWork();
 | |
| 
 | |
|     // Sleep to allow the CEF proc to do work.
 | |
|     Sleep(50);
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPumpWin::OnScheduleMessagePumpWork(int64 delay_ms) {
 | |
|   // This method may be called on any thread.
 | |
|   PostMessage(main_thread_target_, kMsgHaveWork, 0,
 | |
|               static_cast<LPARAM>(delay_ms));
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPumpWin::SetTimer(int64 delay_ms) {
 | |
|   DCHECK(!timer_pending_);
 | |
|   DCHECK_GT(delay_ms, 0);
 | |
|   timer_pending_ = true;
 | |
|   ::SetTimer(main_thread_target_, 1, static_cast<UINT>(delay_ms), NULL);
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPumpWin::KillTimer() {
 | |
|   if (timer_pending_) {
 | |
|     ::KillTimer(main_thread_target_, 1);
 | |
|     timer_pending_ = false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // static
 | |
| LRESULT CALLBACK MainMessageLoopExternalPumpWin::WndProc(HWND hwnd,
 | |
|                                                          UINT msg,
 | |
|                                                          WPARAM wparam,
 | |
|                                                          LPARAM lparam) {
 | |
|   if (msg == WM_TIMER || msg == kMsgHaveWork) {
 | |
|     MainMessageLoopExternalPumpWin* message_loop =
 | |
|         GetUserDataPtr<MainMessageLoopExternalPumpWin*>(hwnd);
 | |
|     if (msg == kMsgHaveWork) {
 | |
|       // OnScheduleMessagePumpWork() request.
 | |
|       const int64 delay_ms = static_cast<int64>(lparam);
 | |
|       message_loop->OnScheduleWork(delay_ms);
 | |
|     } else {
 | |
|       // Timer timed out.
 | |
|       message_loop->OnTimerTimeout();
 | |
|     }
 | |
|   }
 | |
|   return DefWindowProc(hwnd, msg, wparam, lparam);
 | |
| }
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| // static
 | |
| scoped_ptr<MainMessageLoopExternalPump> MainMessageLoopExternalPump::Create() {
 | |
|   return scoped_ptr<MainMessageLoopExternalPump>(
 | |
|       new MainMessageLoopExternalPumpWin());
 | |
| }
 | |
| 
 | |
| }  // namespace client
 |