chrome ppapi插件,pp::Instance的HandleMessage未响应

metamatrix 2016-12-06 03:29:48
C++端代码如下,只在原有例子基础上加了HandleMessage的处理,但怎么调用都进不去:
本人C++开发,js这块相对较弱,也不知道是否写错了什么,总是无法调到HandleMessage

// Copyright (c) 2012 The Chromium 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 <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <cstdlib>

#include <algorithm>
// #include <afxwin.h>
// #include <windows.h>

#include "mouse_lock.h"

#ifdef WIN32
#undef min
#undef max
#undef PostMessage
#endif

// Indicate the direction of the mouse location relative to the center of the
// view. These values are used to determine which 2D quadrant the needle lies
// in.
typedef enum {
kLeft = 0,
kRight = 1,
kUp = 2,
kDown = 3
} MouseDirection;

namespace {
const int kCentralSpotRadius = 5;
const uint32_t kReturnKeyCode = 13;
const uint32_t kBackgroundColor = 0xff606060;
const uint32_t kForegroundColor = 0xfff08080;
} // namespace

MouseLockInstance::~MouseLockInstance() {
free(background_scanline_);
background_scanline_ = NULL;
}

bool MouseLockInstance::Init(uint32_t argc,
const char* argn[],
const char* argv[]) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD);
return true;
}

bool MouseLockInstance::HandleInputEvent(const pp::InputEvent& event) {
switch (event.GetType()) {
case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
if (mouse_locked_) {
UnlockMouse();
}
else {
LockMouse(
callback_factory_.NewCallback(&MouseLockInstance::DidLockMouse));
}
return true;
}

case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
pp::MouseInputEvent mouse_event(event);
mouse_movement_ = mouse_event.GetMovement();
Paint();
return true;
}

case PP_INPUTEVENT_TYPE_KEYDOWN: {
pp::KeyboardInputEvent key_event(event);

// Switch in and out of fullscreen when 'Enter' is hit
if (key_event.GetKeyCode() == kReturnKeyCode) {
// Ignore switch if in transition
if (!is_context_bound_)
return true;

if (fullscreen_.IsFullscreen()) {
if (!fullscreen_.SetFullscreen(false)) {
Log("Could not leave fullscreen mode\n");
}
else {
is_context_bound_ = false;
}
}
else {
if (!fullscreen_.SetFullscreen(true)) {
Log("Could not enter fullscreen mode\n");
}
else {
is_context_bound_ = false;
}
}
}
return true;
}

case PP_INPUTEVENT_TYPE_MOUSEUP:
case PP_INPUTEVENT_TYPE_MOUSEENTER:
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
case PP_INPUTEVENT_TYPE_WHEEL:
case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
case PP_INPUTEVENT_TYPE_KEYUP:
case PP_INPUTEVENT_TYPE_CHAR:
case PP_INPUTEVENT_TYPE_CONTEXTMENU:
case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
case PP_INPUTEVENT_TYPE_IME_TEXT:
case PP_INPUTEVENT_TYPE_UNDEFINED:
case PP_INPUTEVENT_TYPE_TOUCHSTART:
case PP_INPUTEVENT_TYPE_TOUCHMOVE:
case PP_INPUTEVENT_TYPE_TOUCHEND:
case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
default:
return false;
}
}

void MouseLockInstance::DidChangeView(const pp::View& view) {
// DidChangeView can get called for many reasons, so we only want to
// rebuild the device context if we really need to.

PostMessage("test Post Message DidChangeView");

if ((size_ == view.GetRect().size()) &&
(was_fullscreen_ == view.IsFullscreen()) && is_context_bound_) {
Log("DidChangeView SKIP %d,%d FULL=%s CTX Bound=%s",
view.GetRect().width(),
view.GetRect().height(),
view.IsFullscreen() ? "true" : "false",
is_context_bound_ ? "true" : "false");
return;
}

Log("DidChangeView DO %d,%d FULL=%s CTX Bound=%s",
view.GetRect().width(),
view.GetRect().height(),
view.IsFullscreen() ? "true" : "false",
is_context_bound_ ? "true" : "false");

size_ = view.GetRect().size();
device_context_ = pp::Graphics2D(this, size_, false);
waiting_for_flush_completion_ = false;

is_context_bound_ = BindGraphics(device_context_);
if (!is_context_bound_) {
Log("Could not bind to 2D context\n.");
return;
}
else {
Log("Bound to 2D context size %d,%d.\n", size_.width(), size_.height());
}

// Create a scanline for fill.
delete[] background_scanline_;
background_scanline_ = new uint32_t[size_.width()];
uint32_t* bg_pixel = background_scanline_;
for (int x = 0; x < size_.width(); ++x) {
*bg_pixel++ = kBackgroundColor;
}

// Remember if we are fullscreen or not
was_fullscreen_ = view.IsFullscreen();

// Paint this context
Paint();
}

void MouseLockInstance::MouseLockLost() {
if (mouse_locked_) {
Log("Mouselock unlocked.\n");
mouse_locked_ = false;
Paint();
}
}

void MouseLockInstance::DidLockMouse(int32_t result) {
mouse_locked_ = result == PP_OK;
if (result != PP_OK) {
Log("Mouselock failed with failed with error number %d.\n", result);
}
mouse_movement_.set_x(0);
mouse_movement_.set_y(0);
Paint();
}

void MouseLockInstance::DidFlush(int32_t result) {
if (result != 0)
Log("Flushed failed with error number %d.\n", result);
waiting_for_flush_completion_ = false;
}

void MouseLockInstance::Paint() {
// If we are already waiting to paint...
if (waiting_for_flush_completion_) {
return;
}

pp::ImageData image = PaintImage(size_);
if (image.is_null()) {
Log("Could not create image data\n");
return;
}

device_context_.ReplaceContents(&image);
waiting_for_flush_completion_ = true;
device_context_.Flush(
callback_factory_.NewCallback(&MouseLockInstance::DidFlush));
}

pp::ImageData MouseLockInstance::PaintImage(const pp::Size& size) {
pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, false);
if (image.is_null() || image.data() == NULL) {
Log("Skipping image.\n");
return image;
}

ClearToBackground(&image);

DrawCenterSpot(&image, kForegroundColor);
DrawNeedle(&image, kForegroundColor);
return image;
}

void MouseLockInstance::ClearToBackground(pp::ImageData* image) {
if (image == NULL) {
Log("ClearToBackground with NULL image.");
return;
}
if (background_scanline_ == NULL) {
Log("ClearToBackground with no scanline.");
return;
}
int image_height = image->size().height();
int image_width = image->size().width();

for (int y = 0; y < image_height; ++y) {
uint32_t* scanline = image->GetAddr32(pp::Point(0, y));
memcpy(scanline,
background_scanline_,
image_width * sizeof(*background_scanline_));
}
}

void MouseLockInstance::DrawCenterSpot(pp::ImageData* image,
uint32_t spot_color) {
if (image == NULL) {
Log("DrawCenterSpot with NULL image");
return;
}
// Draw the center spot. The ROI is bounded by the size of the spot, plus
// one pixel.
int center_x = image->size().width() / 2;
int center_y = image->size().height() / 2;
int region_of_interest_radius = kCentralSpotRadius + 1;

pp::Point left_top(std::max(0, center_x - region_of_interest_radius),
std::max(0, center_y - region_of_interest_radius));
pp::Point right_bottom(
std::min(image->size().width(), center_x + region_of_interest_radius),
std::min(image->size().height(), center_y + region_of_interest_radius));
for (int y = left_top.y(); y < right_bottom.y(); ++y) {
for (int x = left_top.x(); x < right_bottom.x(); ++x) {
if (GetDistance(x, y, center_x, center_y) < kCentralSpotRadius) {
*image->GetAddr32(pp::Point(x, y)) = spot_color;
}
}
}
}

void MouseLockInstance::DrawNeedle(pp::ImageData* image,
uint32_t needle_color) {
if (image == NULL) {
Log("DrawNeedle with NULL image");
return;
}
if (GetDistance(mouse_movement_.x(), mouse_movement_.y(), 0, 0) <=
kCentralSpotRadius) {
return;
}

int abs_mouse_x = std::abs(mouse_movement_.x());
int abs_mouse_y = std::abs(mouse_movement_.y());
int center_x = image->size().width() / 2;
int center_y = image->size().height() / 2;
pp::Point vertex(mouse_movement_.x() + center_x,
mouse_movement_.y() + center_y);
pp::Point anchor_1;
pp::Point anchor_2;
MouseDirection direction = kLeft;

if (abs_mouse_x >= abs_mouse_y) {
anchor_1.set_x(center_x);
anchor_1.set_y(center_y - kCentralSpotRadius);
anchor_2.set_x(center_x);
anchor_2.set_y(center_y + kCentralSpotRadius);
direction = (mouse_movement_.x() < 0) ? kLeft : kRight;
if (direction == kLeft)
anchor_1.swap(anchor_2);
}
else {
anchor_1.set_x(center_x + kCentralSpotRadius);
anchor_1.set_y(center_y);
anchor_2.set_x(center_x - kCentralSpotRadius);
anchor_2.set_y(center_y);
direction = (mouse_movement_.y() < 0) ? kUp : kDown;
if (direction == kUp)
anchor_1.swap(anchor_2);
}

pp::Point left_top(std::max(0, center_x - abs_mouse_x),
std::max(0, center_y - abs_mouse_y));
pp::Point right_bottom(
std::min(image->size().width(), center_x + abs_mouse_x),
std::min(image->size().height(), center_y + abs_mouse_y));
for (int y = left_top.y(); y < right_bottom.y(); ++y) {
for (int x = left_top.x(); x < right_bottom.x(); ++x) {
bool within_bound_1 = ((y - anchor_1.y()) * (vertex.x() - anchor_1.x())) >
((vertex.y() - anchor_1.y()) * (x - anchor_1.x()));
bool within_bound_2 = ((y - anchor_2.y()) * (vertex.x() - anchor_2.x())) <
((vertex.y() - anchor_2.y()) * (x - anchor_2.x()));
bool within_bound_3 = (direction == kUp && y < center_y) ||
(direction == kDown && y > center_y) ||
(direction == kLeft && x < center_x) ||
(direction == kRight && x > center_x);

if (within_bound_1 && within_bound_2 && within_bound_3) {
*image->GetAddr32(pp::Point(x, y)) = needle_color;
}
}
}
}



...全文
789 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
metamatrix 2016-12-07
  • 打赏
  • 举报
回复
已解决,关键在于需要运行参数ppapi-out-of-process
业余草 2016-12-06
  • 打赏
  • 举报
回复
C++ 真不懂!! 谢邀! http://www.xttblog.com/?p=1006
metamatrix 2016-12-06
  • 打赏
  • 举报
回复

void MouseLockInstance::Log(const char* format, ...) {
	static PPB_Console* console =
		(PPB_Console*)pp::Module::Get()->GetBrowserInterface(
		PPB_CONSOLE_INTERFACE);

	if (NULL == console)
		return;
	va_list args;
	va_start(args, format);
	char buf[512];
	vsnprintf_s(buf, sizeof(buf)-1, format, args);
	buf[sizeof(buf)-1] = '\0';
	va_end(args);

	pp::Var value(buf);
	console->Log(pp_instance(), PP_LOGLEVEL_ERROR, value.pp_var());
}

void MouseLockInstance::HandleMessage(const pp::Var& message)
{
	PostMessage("test Post Message");
// 	::MessageBox(NULL, L"HandleMessage", L"info", MB_OK);
}

// This object is the global object representing this plugin library as long
// as it is loaded.
class MouseLockModule : public pp::Module {
public:
	MouseLockModule() : pp::Module() {}
	virtual ~MouseLockModule() {}

	// Override CreateInstance to create your customized Instance object.
	virtual pp::Instance* CreateInstance(PP_Instance instance) {
		return new MouseLockInstance(instance);
	}
};

namespace pp {

	// Factory function for your specialization of the Module object.
	Module* CreateModule() { return new MouseLockModule(); }

}  // namespace pp
头文件:

// Copyright (c) 2012 The Chromium 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 <cmath>

#include "ppapi/c/ppb_fullscreen.h"
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/fullscreen.h"
#include "ppapi/cpp/graphics_2d.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/mouse_lock.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/size.h"
#include "ppapi/cpp/var.h"
#include "ppapi/utility/completion_callback_factory.h"

#ifdef _MSC_VER
// Allow 'this' in initializer list
#pragma warning(disable : 4355)
#endif

class MouseLockInstance : public pp::Instance, public pp::MouseLock {
public:
	explicit MouseLockInstance(PP_Instance instance)
		: pp::Instance(instance),
		pp::MouseLock(this),
		mouse_locked_(false),
		waiting_for_flush_completion_(false),
		callback_factory_(this),
		fullscreen_(this),
		is_context_bound_(false),
		was_fullscreen_(false),
		background_scanline_(NULL) {}
	virtual ~MouseLockInstance();

	// Called by the browser when the NaCl module is loaded and all ready to go.
	virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);

	// Called by the browser to handle incoming input events.
	virtual bool HandleInputEvent(const pp::InputEvent& event);

	// Called whenever the in-browser window changes size.
	virtual void DidChangeView(const pp::View& view);

	// Called by the browser when mouselock is lost.  This happens when the NaCl
	// module exits fullscreen mode.
	virtual void MouseLockLost();

	virtual void HandleMessage(const pp::Var& message);
private:
	// Return the Cartesian distance between two points.
	double GetDistance(int point_1_x,
		int point_1_y,
		int point_2_x,
		int point_2_y) {
		return sqrt(pow(static_cast<double>(point_1_x - point_2_x), 2) +
			pow(static_cast<double>(point_1_y - point_2_y), 2));
	}

	// Called when mouse lock has been acquired.  Used as a callback to
	// pp::MouseLock.LockMouse().
	void DidLockMouse(int32_t result);

	// Called when the 2D context has been flushed to the browser window.  Used
	// as a callback to pp::Graphics2D.Flush().
	void DidFlush(int32_t result);

	// Creates a new paint buffer, paints it then flush it to the 2D context.  If
	// a flush is pending, this does nothing.
	void Paint();

	// Create a new pp::ImageData and paint the graphics that represent the mouse
	// movement in it.  Return the new pp::ImageData.
	pp::ImageData PaintImage(const pp::Size& size);

	// Fill the image with the background color.
	void ClearToBackground(pp::ImageData* image);

	void DrawCenterSpot(pp::ImageData* image, uint32_t spot_color);

	void DrawNeedle(pp::ImageData* image, uint32_t needle_color);

	// Print the printf-style format to the "console" via PostMessage.
	void Log(const char* format, ...);

	pp::Size size_;

	bool mouse_locked_;
	pp::Point mouse_movement_;
	bool waiting_for_flush_completion_;
	pp::CompletionCallbackFactory<MouseLockInstance> callback_factory_;

	pp::Fullscreen fullscreen_;
	pp::Graphics2D device_context_;
	bool is_context_bound_;
	bool was_fullscreen_;
	uint32_t* background_scanline_;
};
web端js调用:

<!DOCTYPE html>
<html>
  <!--
  Copyright (c) 2012 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
  -->
<head>
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Expires" content="-1">
  <script type="text/javascript">
    function pageDidLoad() {
	  alert("pageDidLoad");
      appendStatus('Page loaded');

    }

    function appendStatus(opt_message) {
      var statusField = document.getElementById('statusField');
      if (statusField) {
        var newElt = document.createElement("opt_message");
        newElt.innerHTML = "<br>" + opt_message;
        statusField.appendChild(newElt);
      }
    }

    function handleMessage(message_event) {
     alert(message_event.data);
     appendStatus(message_event.data);
    }
/*
	function focus()
	{
		alert("focus");
	}
*/
	function onVisibilityChange()
	{
//		alert("onVisibilityChange");
		plugin = document.getElementById('mapbase');

//		alert(plugin);
		if (!document['webkitHidden'])
		{
			plugin.focus();
//			plugin.postMessageAndAwaitResponse("Hello world");
			alert("页面激活");
			plugin.postMessage("Hello world");
//			plugin.postMessage({command:"activatePage", value:"1"});
		}
		else
		{
			plugin.blur();
//			plugin.postMessageAndAwaitResponse("Hello world");
			alert("页面非激活");
//			plugin.postMessage("Hello world");
			plugin.postMessage({command:"activatePage", value:"0"});
		}

	}
	document.addEventListener('webkitvisibilitychange', onVisibilityChange);
//	document.getElementById('mapbase').postMessage("Hello world!");
 </script>
</head>
<body onload="pageDidLoad()">
  <div id="listener">
    <script type="text/javascript">
        var listener = document.getElementById('listener');
        listener.addEventListener('message', handleMessage, true);

    </script>
    <h2>NaCl Module</h2>
      <embed
      id="mapbase"
	  title="mapbase"
	  type="application/x-ppapi-mapbase_cpp_fortest"/>
	<script type="text/javascript">
		var plugin = document.getElementById('mapbase');
		plugin.postMessage("hello world");
	</script>
  </div>

  <div>
  <h2>Messages: <code id="statusField"></code></h2>
  </div>


</body>
</html>

5,006

社区成员

发帖
与我相关
我的任务
社区描述
解读Web 标准、分析和讨论实际问题、推动网络标准化发展和跨浏览器开发进程,解决各种兼容性问题。
社区管理员
  • 跨浏览器开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧