This commit is contained in:
恍兮惚兮 2025-01-02 17:47:21 +08:00
parent 642aac26e9
commit 25f580680c
6 changed files with 66 additions and 59 deletions

View File

@ -1,7 +1,7 @@
set(VERSION_MAJOR 6) set(VERSION_MAJOR 6)
set(VERSION_MINOR 16) set(VERSION_MINOR 16)
set(VERSION_PATCH 15) set(VERSION_PATCH 16)
set(VERSION_REVISION 0) set(VERSION_REVISION 0)
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")
add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp) add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp)

View File

@ -89,6 +89,8 @@ class MWebBrowserEx : public MWebBrowser
public: public:
std::vector<std::tuple<std::optional<std::wstring>, int>> menuitems; std::vector<std::tuple<std::optional<std::wstring>, int>> menuitems;
std::map<int, void (*)(LPCWSTR)> menucallbacks;
UINT CommandBase = 10086;
static MWebBrowserEx *Create(HWND _hwndParent); static MWebBrowserEx *Create(HWND _hwndParent);
// IDocHostUIHandler interface // IDocHostUIHandler interface
STDMETHODIMP ShowContextMenu( STDMETHODIMP ShowContextMenu(
@ -96,6 +98,19 @@ public:
POINT *ppt, POINT *ppt,
IUnknown *pcmdtReserved, IUnknown *pcmdtReserved,
IDispatch *pdispReserved); IDispatch *pdispReserved);
HRESULT getselectedtext(LPWSTR *selectedText)
{
CComPtr<IHTMLDocument2> pDocument;
CHECK_FAILURE(GetIHTMLDocument2(&pDocument));
CComPtr<IHTMLSelectionObject> pSelectionObj;
CHECK_FAILURE(pDocument->get_selection(&pSelectionObj));
CComPtr<IHTMLTxtRange> pTxtRange;
CHECK_FAILURE(pSelectionObj->createRange((IDispatch **)&pTxtRange));
CHECK_FAILURE(pTxtRange->get_text(selectedText));
if (!*selectedText)
return -1;
return S_OK;
}
protected: protected:
MWebBrowserEx(HWND _hwndParent); MWebBrowserEx(HWND _hwndParent);
@ -103,6 +118,25 @@ protected:
MWebBrowserEx::MWebBrowserEx(HWND _hwndParent) : MWebBrowser(_hwndParent), hwndParent(_hwndParent) MWebBrowserEx::MWebBrowserEx(HWND _hwndParent) : MWebBrowser(_hwndParent), hwndParent(_hwndParent)
{ {
} }
LRESULT CALLBACK Extra_Menu_Handle(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
auto proc = (WNDPROC)GetProp(hwnd, L"GWLP_WNDPROC");
auto thisptr = (MWebBrowserEx *)GetProp(hwnd, L"THIS_PTR");
if (msg == WM_COMMAND)
{
if (thisptr->menucallbacks.find((int)wp) != thisptr->menucallbacks.end())
{
[&]()
{
CComBSTR selectedText;
CHECK_FAILURE_NORET(thisptr->getselectedtext(&selectedText));
thisptr->menucallbacks[(int)wp](selectedText);
}();
}
}
return proc(hwnd, msg, wp, lp);
}
MWebBrowserEx *MWebBrowserEx::Create(HWND _hwndParent) MWebBrowserEx *MWebBrowserEx::Create(HWND _hwndParent)
{ {
MWebBrowserEx *pBrowser = new MWebBrowserEx(_hwndParent); MWebBrowserEx *pBrowser = new MWebBrowserEx(_hwndParent);
@ -111,6 +145,10 @@ MWebBrowserEx *MWebBrowserEx::Create(HWND _hwndParent)
pBrowser->Release(); pBrowser->Release();
pBrowser = NULL; pBrowser = NULL;
} }
auto hwnd = pBrowser->GetControlWindow();
SetProp(_hwndParent, L"GWLP_WNDPROC", (HANDLE)GetWindowLongPtr(_hwndParent, GWLP_WNDPROC));
SetProp(_hwndParent, L"THIS_PTR", (HANDLE)pBrowser);
SetWindowLongPtr(_hwndParent, GWLP_WNDPROC, (ULONG_PTR)Extra_Menu_Handle);
return pBrowser; return pBrowser;
} }
STDMETHODIMP MWebBrowserEx::ShowContextMenu( STDMETHODIMP MWebBrowserEx::ShowContextMenu(
@ -209,7 +247,7 @@ DECLARE_API void html_set_html(void *web, wchar_t *html)
auto ww = static_cast<MWebBrowserEx *>(web); auto ww = static_cast<MWebBrowserEx *>(web);
ww->SetHtml(html); ww->SetHtml(html);
} }
DECLARE_API void html_add_menu(void *web, int index, int command, const wchar_t *label) DECLARE_API void html_add_menu(void *web, int index, const wchar_t *label, void (*callback)(const wchar_t *))
{ {
if (!web) if (!web)
return; return;
@ -218,21 +256,17 @@ DECLARE_API void html_add_menu(void *web, int index, int command, const wchar_t
if (label) if (label)
_label = label; _label = label;
auto ptr = ww->menuitems.begin() + index; auto ptr = ww->menuitems.begin() + index;
auto command = ww->CommandBase++;
ww->menuitems.insert(ptr, {_label, command}); ww->menuitems.insert(ptr, {_label, command});
ww->menucallbacks[command] = callback;
} }
DECLARE_API void html_get_select_text(void *web, void (*cb)(LPCWSTR)) DECLARE_API void html_get_select_text(void *web, void (*cb)(LPCWSTR))
{ {
if (!web) if (!web)
return; return;
auto ww = static_cast<MWebBrowserEx *>(web); auto ww = static_cast<MWebBrowserEx *>(web);
CComPtr<IHTMLDocument2> pDocument;
CHECK_FAILURE_NORET(ww->GetIHTMLDocument2(&pDocument));
CComPtr<IHTMLSelectionObject> pSelectionObj;
CHECK_FAILURE_NORET(pDocument->get_selection(&pSelectionObj));
CComPtr<IHTMLTxtRange> pTxtRange;
CHECK_FAILURE_NORET(pSelectionObj->createRange((IDispatch **)&pTxtRange));
CComBSTR selectedText; CComBSTR selectedText;
CHECK_FAILURE_NORET(pTxtRange->get_text(&selectedText)); CHECK_FAILURE_NORET(ww->getselectedtext(&selectedText));
cb(selectedText); cb(selectedText);
} }

View File

@ -164,7 +164,7 @@ DECLARE_API HWND clipboard_callback(void (*callback)(const wchar_t *, bool))
HANDLE hsema = CreateSemaphoreW(0, 0, 10, 0); HANDLE hsema = CreateSemaphoreW(0, 0, 10, 0);
HWND hwnd; HWND hwnd;
std::thread(std::bind(clipboard_callback_1, callback, hsema, &hwnd)).detach(); std::thread(clipboard_callback_1, callback, hsema, &hwnd).detach();
WaitForSingleObject(hsema, INFINITE); WaitForSingleObject(hsema, INFINITE);
CloseHandle(hsema); CloseHandle(hsema);

View File

@ -56,7 +56,7 @@ void globalmessagelistener_1(void *callback)
DECLARE_API void globalmessagelistener(void *callback) DECLARE_API void globalmessagelistener(void *callback)
{ {
#ifndef WINXP #ifndef WINXP
std::thread(std::bind(globalmessagelistener_1, callback)).detach(); std::thread(globalmessagelistener_1, callback).detach();
#endif #endif
} }

View File

@ -1397,7 +1397,6 @@ class QWebWrap(abstractwebview):
class mshtmlWidget(abstractwebview): class mshtmlWidget(abstractwebview):
CommandBase = 10086
def eval(self, js): def eval(self, js):
winsharedutils.html_eval(self.browser, js) winsharedutils.html_eval(self.browser, js)
@ -1422,7 +1421,7 @@ class mshtmlWidget(abstractwebview):
def __init__(self, parent=None) -> None: def __init__(self, parent=None) -> None:
super().__init__(parent) super().__init__(parent)
self.callbacks = {} self.callbacks = []
self.bindfs = [] self.bindfs = []
iswine = checkisusingwine() iswine = checkisusingwine()
if iswine or (winsharedutils.html_version() < 10001): # ie10之前sethtml会乱码 if iswine or (winsharedutils.html_version() < 10001): # ie10之前sethtml会乱码
@ -1437,34 +1436,22 @@ class mshtmlWidget(abstractwebview):
self.add_menu(0, _TR("复制"), winsharedutils.clipboard_set) self.add_menu(0, _TR("复制"), winsharedutils.clipboard_set)
self.add_menu(0, None, lambda: 1) self.add_menu(0, None, lambda: 1)
self.wndproc = windows.WNDPROCTYPE(
functools.partial(
self.extrahandle,
windows.GetWindowLongPtr(int(self.winId()), windows.GWLP_WNDPROC),
)
)
windows.SetWindowLongPtr(int(self.winId()), windows.GWLP_WNDPROC, self.wndproc)
def extrahandle(self, orig, hwnd, msg, wp, lp):
if msg == windows.WM_COMMAND:
func = self.callbacks.get(wp)
if func:
func(winsharedutils.html_get_select_text(self.browser))
return windows.WNDPROCTYPE(orig)(hwnd, msg, wp, lp)
def __getcurrent(self): def __getcurrent(self):
_u = winsharedutils.html_get_current_url(self.browser) def __(_u):
if self.curr_url != _u: if self.curr_url != _u:
self.curr_url = _u self.curr_url = _u
self.on_load.emit(_u) self.on_load.emit(_u)
cb = winsharedutils.html_get_select_text_cb(__)
winsharedutils.html_get_current_url(self.browser, cb)
if ( if (
windows.GetAsyncKeyState(windows.VK_CONTROL) windows.GetAsyncKeyState(windows.VK_CONTROL)
and windows.GetAsyncKeyState(67) and windows.GetAsyncKeyState(67)
and winsharedutils.html_get_ie(self.browser) == windows.GetFocus() and winsharedutils.html_get_ie(self.browser) == windows.GetFocus()
): ):
winsharedutils.clipboard_set( cb = winsharedutils.html_get_select_text_cb(winsharedutils.clipboard_set)
winsharedutils.html_get_select_text(self.browser) winsharedutils.html_get_select_text(self.browser, cb)
)
def navigate(self, url): def navigate(self, url):
winsharedutils.html_navigate(self.browser, url) winsharedutils.html_navigate(self.browser, url)
@ -1480,9 +1467,9 @@ class mshtmlWidget(abstractwebview):
return self._parsehtml_codec(self._parsehtml_font(self._parsehtml_dark(html))) return self._parsehtml_codec(self._parsehtml_font(self._parsehtml_dark(html)))
def add_menu(self, index, label, callback): def add_menu(self, index, label, callback):
command = mshtmlWidget.CommandBase + len(self.callbacks) cb = winsharedutils.html_add_menu_cb(callback)
self.callbacks[command] = callback self.callbacks.append(cb)
winsharedutils.html_add_menu(self.browser, index, command, label) winsharedutils.html_add_menu(self.browser, index, label, cb)
class CustomKeySequenceEdit(QKeySequenceEdit): class CustomKeySequenceEdit(QKeySequenceEdit):

View File

@ -123,30 +123,16 @@ html_resize = utilsdll.html_resize
html_resize.argtypes = c_void_p, c_uint, c_uint, c_uint, c_uint html_resize.argtypes = c_void_p, c_uint, c_uint, c_uint, c_uint
html_release = utilsdll.html_release html_release = utilsdll.html_release
html_release.argtypes = (c_void_p,) html_release.argtypes = (c_void_p,)
_html_get_current_url = utilsdll.html_get_current_url html_get_current_url = utilsdll.html_get_current_url
_html_get_current_url.argtypes = (c_void_p, c_void_p) html_get_current_url.argtypes = (c_void_p, c_void_p)
html_set_html = utilsdll.html_set_html html_set_html = utilsdll.html_set_html
html_set_html.argtypes = (c_void_p, c_wchar_p) html_set_html.argtypes = (c_void_p, c_wchar_p)
html_add_menu = utilsdll.html_add_menu html_add_menu = utilsdll.html_add_menu
html_add_menu.argtypes = (c_void_p, c_int, c_int, c_wchar_p) html_add_menu_cb = CFUNCTYPE(c_void_p, c_wchar_p)
_html_get_select_text = utilsdll.html_get_select_text html_add_menu.argtypes = (c_void_p, c_int, c_wchar_p, html_add_menu_cb)
_html_get_select_text.argtypes = (c_void_p, c_void_p) html_get_select_text = utilsdll.html_get_select_text
html_get_select_text_cb = CFUNCTYPE(None, c_wchar_p)
html_get_select_text.argtypes = (c_void_p, c_void_p)
def html_get_current_url(__):
_ = []
_html_get_current_url(__, CFUNCTYPE(None, c_wchar_p)(_.append))
if _:
return _[0]
return ""
def html_get_select_text(__):
_ = []
_html_get_select_text(__, CFUNCTYPE(None, c_wchar_p)(_.append))
if _:
return _[0]
return ""
html_bind_function_FT = CFUNCTYPE(None, POINTER(c_wchar_p), c_int) html_bind_function_FT = CFUNCTYPE(None, POINTER(c_wchar_p), c_int)