📄 eventsender.cpp
字号:
return; } if (msgQueue[startOfQueue].delay) { ::Sleep(msgQueue[startOfQueue].delay); msgQueue[startOfQueue].delay = 0; } ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0); while (::GetMessage(&msg, webViewWindow, 0, 0)) { // FIXME: Why do we get a WM_MOUSELEAVE? it breaks tests if (msg.message == WM_MOUSELEAVE) continue; if (msg.message != WM_DRT_SEND_QUEUED_EVENT) { dispatchMessage(&msg); continue; } msg = msgQueue[startOfQueue++].msg; switch (msg.message) { case WM_LBUTTONUP: doMouseUp(msg); break; case WM_MOUSEMOVE: doMouseMove(msg); break; case WM_LBUTTONDOWN: dispatchMessage(&msg); break; default: // Not reached break; } if (startOfQueue >= endOfQueue) break; ::Sleep(msgQueue[startOfQueue].delay); msgQueue[startOfQueue].delay = 0; ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0); } startOfQueue = 0; endOfQueue = 0; replayingSavedEvents = false;}static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ if (argumentCount < 1) return JSValueMakeUndefined(context); static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length"); COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); JSStringRef character = JSValueToStringCopy(context, arguments[0], exception); ASSERT(!*exception); int virtualKeyCode; int charCode = 0; int keyData = 1; bool needsShiftKeyModifier = false; if (JSStringIsEqualToUTF8CString(character, "leftArrow")) { virtualKeyCode = VK_LEFT; keyData += KF_EXTENDED << 16; // In this case, extended means "not keypad". } else if (JSStringIsEqualToUTF8CString(character, "rightArrow")) { virtualKeyCode = VK_RIGHT; keyData += KF_EXTENDED << 16; } else if (JSStringIsEqualToUTF8CString(character, "upArrow")) { virtualKeyCode = VK_UP; keyData += KF_EXTENDED << 16; } else if (JSStringIsEqualToUTF8CString(character, "downArrow")) { virtualKeyCode = VK_DOWN; keyData += KF_EXTENDED << 16; } else if (JSStringIsEqualToUTF8CString(character, "pageUp")) virtualKeyCode = VK_PRIOR; else if (JSStringIsEqualToUTF8CString(character, "pageDown")) virtualKeyCode = VK_NEXT; else if (JSStringIsEqualToUTF8CString(character, "home")) virtualKeyCode = VK_HOME; else if (JSStringIsEqualToUTF8CString(character, "end")) virtualKeyCode = VK_END; else if (JSStringIsEqualToUTF8CString(character, "delete")) virtualKeyCode = VK_BACK; else { charCode = JSStringGetCharactersPtr(character)[0]; virtualKeyCode = LOBYTE(VkKeyScan(charCode)); if (WTF::isASCIIUpper(charCode)) needsShiftKeyModifier = true; } JSStringRelease(character); BYTE keyState[256]; if (argumentCount > 1 || needsShiftKeyModifier) { ::GetKeyboardState(keyState); BYTE newKeyState[256]; memcpy(newKeyState, keyState, sizeof(keyState)); if (needsShiftKeyModifier) newKeyState[VK_SHIFT] = 0x80; if (argumentCount > 1) { JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception); if (modifiersArray) { int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); for (int i = 0; i < modifiersCount; ++i) { JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0); JSStringRef string = JSValueToStringCopy(context, value, 0); if (JSStringIsEqualToUTF8CString(string, "ctrlKey")) newKeyState[VK_CONTROL] = 0x80; else if (JSStringIsEqualToUTF8CString(string, "shiftKey")) newKeyState[VK_SHIFT] = 0x80; else if (JSStringIsEqualToUTF8CString(string, "altKey")) newKeyState[VK_MENU] = 0x80; JSStringRelease(string); } } } ::SetKeyboardState(newKeyState); } MSG msg = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData); if (virtualKeyCode != 255) dispatchMessage(&msg); else { // For characters that do not exist in the active keyboard layout, // ::Translate will not work, so we post an WM_CHAR event ourselves. ::PostMessage(webViewWindow, WM_CHAR, charCode, 0); } // Tests expect that all messages are processed by the time keyDown() returns. if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE) || ::PeekMessage(&msg, webViewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) ::DispatchMessage(&msg); MSG msgUp = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData); ::DispatchMessage(&msgUp); if (argumentCount > 1 || needsShiftKeyModifier) ::SetKeyboardState(keyState); return JSValueMakeUndefined(context);}// eventSender.dispatchMessage(message, wParam, lParam, time = currentEventTime(), x = lastMousePosition.x, y = lastMousePosition.y)static JSValueRef dispatchMessageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ if (argumentCount < 3) return JSValueMakeUndefined(context); COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); MSG msg = {}; msg.hwnd = webViewWindow; msg.message = JSValueToNumber(context, arguments[0], exception); ASSERT(!*exception); msg.wParam = JSValueToNumber(context, arguments[1], exception); ASSERT(!*exception); msg.lParam = static_cast<ULONG_PTR>(JSValueToNumber(context, arguments[2], exception)); ASSERT(!*exception); if (argumentCount >= 4) { msg.time = JSValueToNumber(context, arguments[3], exception); ASSERT(!*exception); } if (!msg.time) msg.time = currentEventTime(); if (argumentCount >= 6) { msg.pt.x = JSValueToNumber(context, arguments[4], exception); ASSERT(!*exception); msg.pt.y = JSValueToNumber(context, arguments[5], exception); ASSERT(!*exception); } else msg.pt = lastMousePosition; ::DispatchMessage(&msg); return JSValueMakeUndefined(context);}static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ COMPtr<IWebView> webView; if (FAILED(frame->webView(&webView))) return JSValueMakeUndefined(context); COMPtr<IWebIBActions> webIBActions(Query, webView); if (!webIBActions) return JSValueMakeUndefined(context); webIBActions->makeTextLarger(0); return JSValueMakeUndefined(context);}static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ COMPtr<IWebView> webView; if (FAILED(frame->webView(&webView))) return JSValueMakeUndefined(context); COMPtr<IWebIBActions> webIBActions(Query, webView); if (!webIBActions) return JSValueMakeUndefined(context); webIBActions->makeTextSmaller(0); return JSValueMakeUndefined(context);}static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ COMPtr<IWebView> webView; if (FAILED(frame->webView(&webView))) return JSValueMakeUndefined(context); COMPtr<IWebIBActions> webIBActions(Query, webView); if (!webIBActions) return JSValueMakeUndefined(context); webIBActions->zoomPageIn(0); return JSValueMakeUndefined(context);}static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ COMPtr<IWebView> webView; if (FAILED(frame->webView(&webView))) return JSValueMakeUndefined(context); COMPtr<IWebIBActions> webIBActions(Query, webView); if (!webIBActions) return JSValueMakeUndefined(context); webIBActions->zoomPageOut(0); return JSValueMakeUndefined(context);}static JSStaticFunction staticFunctions[] = { { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dispatchMessage", dispatchMessageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0 }};static JSStaticValue staticValues[] = { { "dragMode", getDragModeCallback, setDragModeCallback, kJSPropertyAttributeNone }, { "WM_KEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_KEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_CHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_DEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_SYSKEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_SYSKEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_SYSCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { "WM_SYSDEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone }, { 0, 0, 0, 0 }};static JSClassRef getClass(JSContextRef context){ static JSClassRef eventSenderClass = 0; if (!eventSenderClass) { JSClassDefinition classDefinition = {0}; classDefinition.staticFunctions = staticFunctions; classDefinition.staticValues = staticValues; eventSenderClass = JSClassCreate(&classDefinition); } return eventSenderClass;}JSObjectRef makeEventSender(JSContextRef context){ down = false; dragMode = true; replayingSavedEvents = false; timeOffset = 0; lastMousePosition.x = 0; lastMousePosition.y = 0; endOfQueue = 0; startOfQueue = 0; didDragEnter = false; draggingInfo = 0; return JSObjectMake(context, getClass(context), 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -