cef-mixer icon indicating copy to clipboard operation
cef-mixer copied to clipboard

Key Event and Typing on OSR MIXER

Open mirufa1121 opened this issue 5 years ago • 3 comments

Excuse me ! can you help me press key event on mixer as default browser ? me using PreTranslateMessage(MSG* pMsg) on C++/MFC for KEY_DOWN,KEY_UP and broadcast key event for all Layer by code void Composition::key_press(KeyPress key_event, char key_code) { decltype(layers_) layers; { lock_guard guard(lock_); layers.assign(layers_.begin(), layers_.end()); } for (auto const& layer : layers) { layer->key_press(key_event,key_code); } }

WebView class me Using void WebView::key_press(KeyPress key_event, char key_code) { auto const browser = safe_browser();

if (browser)
{
	CefKeyEvent keyEvent;
	keyEvent.type = cef_key_event_type_t::KEYEVENT_CHAR;
	keyEvent.windows_key_code = key_code;
	browser->GetHost()->SendKeyEvent(keyEvent);

	switch (key_event)
	{
	case KeyPress::Up: keyEvent.type = cef_key_event_type_t::KEYEVENT_KEYUP; break;
	case KeyPress::Down: keyEvent.type = cef_key_event_type_t::KEYEVENT_KEYDOWN; break;
	case KeyPress::Char: keyEvent.type = cef_key_event_type_t::KEYEVENT_CHAR;
	default:break;
	}
	browser->GetHost()->SendKeyEvent(keyEvent);
}

} but me press key value is double , and can't using special key same Ctrl+... Shift + ...

mirufa1121 avatar Jan 06 '19 16:01 mirufa1121

I might be able to assist if I can see the code for your project. It's hard to know what is going on without seeing more of the MFC side.

I have done something similar to the following where I ignore WM_KEYDOWN forwarding when the message simply represents the modifier key:

auto const key = static_cast<uint16_t>(virtkey & 0x0000ffff);

// ignore when modifier keys are the only key sent
if (key == VK_CONTROL || key == VK_SHIFT || key == VK_MENU) {
   return;
}

// are the shift and/or ctrls down as well?
// fill out a structure representing all key information

KeyEvent kevent;
kevent.set_type(KeyPress::Down);
kevent.set_code(key);
kevent.set_alt(GetKeyState(VK_MENU) < 0);
kevent.set_ctrl(GetKeyState(VK_CONTROL) < 0);
kevent.set_shift(GetKeyState(VK_SHIFT) < 0);

composition->key_press(kevent);

wesselsga avatar Jan 07 '19 14:01 wesselsga

thanks you answer ! i was able to use by sample code on https://bitbucket.org/chromiumembedded/cef/src/aefb5ccce879f308f0bcc3ac719c86defe2f9715/tests/cefclient/browser/osr_window_win.cc?at=master&fileviewer=file-view-default

but i not understand browser can't input by lostfocus . if me click other windows and use Ctrl + Tab for target ==> ok input .if me using Tab button for change text input is ok ,but if me click change input by mouse ... can't input :)

Code in my Dialog `BOOL CVIEBrowserDlg::PreTranslateMessage(MSG* pMsg) { switch (pMsg->message) { case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_MOUSEMOVE: case WM_MOUSELEAVE: case WM_MOUSEWHEEL: OnMouseEvent(pMsg->message, pMsg->wParam, pMsg->lParam); break;

	case WM_SIZE:
		//OnSize();
		break;

/*	case WM_SETFOCUS:
	case WM_KILLFOCUS:
		OnFocus(pMsg->message == WM_SETFOCUS);
		break;*/

	case WM_CAPTURECHANGED:
	case WM_CANCELMODE:
		//OnCaptureLost();
		break;

	case WM_SYSCHAR:
	case WM_SYSKEYDOWN:
	case WM_SYSKEYUP:
	case WM_KEYDOWN:
	case WM_KEYUP:
	case WM_CHAR:
		OnKeyEvent(pMsg->message, pMsg->wParam, pMsg->lParam);
		break;

	case WM_PAINT:
		//self->OnPaint();
		return 0;

	case WM_ERASEBKGND:
		//if (OnEraseBkgnd())
			break;
		// Don't erase the background.
		return 0;

	//case WM_NCDESTROY:
		// Clear the reference to |self|.
		//SetUserDataPtr(hWnd, NULL);
		//self->hwnd_ = NULL;
		//break;
}

// Chặn sự kiện keyDown
if (pMsg->message == WM_KEYDOWN)
{
	if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
	{
		if (GetWindowLong(pMsg->hwnd, GWL_STYLE) & ES_MULTILINE) {
			return CDialog::PreTranslateMessage(pMsg);
		}
		::SendMessage(::GetFocus(), pMsg->message, pMsg->wParam, pMsg->lParam);
		return TRUE;
	}
}

return 0;

} `

Code in WebView class: `void WebView::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {

auto const browser = safe_browser();

CefRefPtr<CefBrowserHost> browser_host;
if (browser)
	browser_host = browser->GetHost();

LONG currentTime = 0;
bool cancelPreviousClick = false;

if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN ||
	message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE ||
	message == WM_MOUSELEAVE) {
	currentTime = GetMessageTime();
	int x = GET_X_LPARAM(lParam);
	int y = GET_Y_LPARAM(lParam);
	cancelPreviousClick =
		(abs(last_click_x_ - x) > (GetSystemMetrics(SM_CXDOUBLECLK) / 2))
		|| (abs(last_click_y_ - y) > (GetSystemMetrics(SM_CYDOUBLECLK) / 2))
		|| ((currentTime - last_click_time_) > GetDoubleClickTime());
	if (cancelPreviousClick &&
		(message == WM_MOUSEMOVE || message == WM_MOUSELEAVE)) {
		last_click_count_ = 0;
		last_click_x_ = 0;
		last_click_y_ = 0;
		last_click_time_ = 0;
	}
}

switch (message) {
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN: {
	::SetCapture(browser_host->GetWindowHandle());
	::SetFocus(browser_host->GetWindowHandle());
	int x = GET_X_LPARAM(lParam);
	int y = GET_Y_LPARAM(lParam);
	if (wParam & MK_SHIFT) {
		// Start rotation effect.
		last_mouse_pos_.x = current_mouse_pos_.x = x;
		last_mouse_pos_.y = current_mouse_pos_.y = y;
		mouse_rotation_ = true;
	}
	else {
		CefBrowserHost::MouseButtonType btnType =
			(message == WM_LBUTTONDOWN ? MBT_LEFT : (
				message == WM_RBUTTONDOWN ? MBT_RIGHT : MBT_MIDDLE));
		if (!cancelPreviousClick && (btnType == last_click_button_)) {
			++last_click_count_;
		}
		else {
			last_click_count_ = 1;
			last_click_x_ = x;
			last_click_y_ = y;
		}
		last_click_time_ = currentTime;
		last_click_button_ = btnType;

		CefRefPtr<CefBrowserHost> browser_host = browser->GetHost();
		if (browser_host) {
			CefMouseEvent mouse_event;
			mouse_event.x = x;
			mouse_event.y = y;
			last_mouse_down_on_view_ = !IsOverPopupWidget(x, y);
			ApplyPopupOffset(mouse_event.x, mouse_event.y);
			mouse_event.modifiers = client::GetCefMouseModifiers(wParam);
			browser_host->SendMouseClickEvent(mouse_event, btnType, false,
				last_click_count_);
		}
	}
} break;

case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
	if (GetCapture() == browser->GetHost()->GetWindowHandle())
		ReleaseCapture();
	if (mouse_rotation_) {
		// End rotation effect.
		/*mouse_rotation_ = false;
		renderer_.SetSpin(0, 0);
		Invalidate();*/
	}
	else {
		int x = GET_X_LPARAM(lParam);
		int y = GET_Y_LPARAM(lParam);
		CefBrowserHost::MouseButtonType btnType =
			(message == WM_LBUTTONUP ? MBT_LEFT : (
				message == WM_RBUTTONUP ? MBT_RIGHT : MBT_MIDDLE));
		if (browser_host) {
			CefMouseEvent mouse_event;
			mouse_event.x = x;
			mouse_event.y = y;
			if (last_mouse_down_on_view_ &&
				IsOverPopupWidget(x, y) &&
				(GetPopupXOffset() || GetPopupYOffset())) {
				break;
			}
			ApplyPopupOffset(mouse_event.x, mouse_event.y);
			mouse_event.modifiers = client::GetCefMouseModifiers(wParam);
			browser_host->SendMouseClickEvent(mouse_event, btnType, true,
				last_click_count_);
		}
	}
	break;

case WM_MOUSEMOVE: {
	int x = GET_X_LPARAM(lParam);
	int y = GET_Y_LPARAM(lParam);
	if (mouse_rotation_) {
		// Apply rotation effect.
		current_mouse_pos_.x = x;
		current_mouse_pos_.y = y;
	/*	renderer_.IncrementSpin(
			current_mouse_pos_.x - last_mouse_pos_.x,
			current_mouse_pos_.y - last_mouse_pos_.y);*/
		last_mouse_pos_.x = current_mouse_pos_.x;
		last_mouse_pos_.y = current_mouse_pos_.y;
		//Invalidate();
	}
	else {
		if (!mouse_tracking_) {
			// Start tracking mouse leave. Required for the WM_MOUSELEAVE event to
			// be generated.
			TRACKMOUSEEVENT tme;
			tme.cbSize = sizeof(TRACKMOUSEEVENT);
			tme.dwFlags = TME_LEAVE;
			tme.hwndTrack = browser->GetHost()->GetWindowHandle();
			TrackMouseEvent(&tme);
			mouse_tracking_ = true;
		}

		if (browser_host) {
			CefMouseEvent mouse_event;
			mouse_event.x = x;
			mouse_event.y = y;
			ApplyPopupOffset(mouse_event.x, mouse_event.y);
			mouse_event.modifiers = client::GetCefMouseModifiers(wParam);
			browser_host->SendMouseMoveEvent(mouse_event, false);
		}
	}
	break;
}

case WM_MOUSELEAVE: {
	if (mouse_tracking_) {
		// Stop tracking mouse leave.
		TRACKMOUSEEVENT tme;
		tme.cbSize = sizeof(TRACKMOUSEEVENT);
		tme.dwFlags = TME_LEAVE & TME_CANCEL;
		tme.hwndTrack = browser->GetHost()->GetWindowHandle();
		TrackMouseEvent(&tme);
		mouse_tracking_ = false;
	}

	if (browser_host) {
		// Determine the cursor position in screen coordinates.
		POINT p;
		::GetCursorPos(&p);
		::ScreenToClient(browser->GetHost()->GetWindowHandle(), &p);

		CefMouseEvent mouse_event;
		mouse_event.x = p.x;
		mouse_event.y = p.y;
		mouse_event.modifiers = client::GetCefMouseModifiers(wParam);
		browser_host->SendMouseMoveEvent(mouse_event, true);
	}
} break;

case WM_MOUSEWHEEL:
	if (browser_host) {
		POINT screen_point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		HWND scrolled_wnd = ::WindowFromPoint(screen_point);
		if (scrolled_wnd != browser->GetHost()->GetWindowHandle())
			break;

		ScreenToClient(browser->GetHost()->GetWindowHandle(), &screen_point);
		int delta = GET_WHEEL_DELTA_WPARAM(wParam);

		CefMouseEvent mouse_event;
		mouse_event.x = screen_point.x;
		mouse_event.y = screen_point.y;
		ApplyPopupOffset(mouse_event.x, mouse_event.y);
		mouse_event.modifiers = client::GetCefMouseModifiers(wParam);

		browser_host->SendMouseWheelEvent(mouse_event,
			client::IsKeyDown(VK_SHIFT) ? delta : 0,
			!client::IsKeyDown(VK_SHIFT) ? delta : 0);
	}
	break;
}

} void WebView::OnKeyEvent(UINT message, WPARAM wParam, LPARAM lParam) {

auto const browser = safe_browser();

if (browser)
{
	CefKeyEvent event;
	event.windows_key_code = wParam;
	event.native_key_code  = lParam;
	event.is_system_key = message == WM_SYSCHAR ||
		message == WM_SYSKEYDOWN ||
		message == WM_SYSKEYUP;

	if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
		event.type = KEYEVENT_RAWKEYDOWN;
	else if (message == WM_KEYUP || message == WM_SYSKEYUP)
		event.type = KEYEVENT_KEYUP;
	else
		event.type = KEYEVENT_CHAR;

	event.modifiers = client::GetCefKeyboardModifiers(wParam, lParam);

	browser->GetHost()->SendKeyEvent(event);
}

}`

mirufa1121 avatar Jan 10 '19 00:01 mirufa1121

if possible ! Can you help me with the capture screen problem with the on paint function or not ! i want using screen image for computer vision but capture on windows . I used to capture it via Handler windows but could not take a picture when the window was overlaid in windows 7 but windows 10 is ok.

mirufa1121 avatar Jan 10 '19 00:01 mirufa1121