This commit is contained in:
恍兮惚兮 2024-12-29 15:35:27 +08:00
parent a4edf162fd
commit 905fe2b819
9 changed files with 124 additions and 241 deletions

View File

@ -1,5 +1,6 @@
#include "python.h"
#include <dwrite.h>
#include <atlbase.h>
extern "C" __declspec(dllexport) const wchar_t *luna_internal_renpy_call_host(const wchar_t *text, int split)
{
return text;
@ -139,23 +140,17 @@ namespace
_COM_Outptr_ IUnknown **factory);
std::list<WCHAR *> get_fonts_path(LPCWSTR family_name, BOOL is_bold, BOOL is_italic, BYTE charset)
{
std::list<WCHAR *> fonts_filename_list;
HRESULT hr;
IDWriteFactory *dwrite_factory;
CComPtr<IDWriteFactory> dwrite_factory;
hr = fnDWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory));
if (FAILED(hr))
{
return fonts_filename_list;
}
return {};
IDWriteGdiInterop *gdi_interop;
CComPtr<IDWriteGdiInterop> gdi_interop;
hr = dwrite_factory->GetGdiInterop(&gdi_interop);
if (FAILED(hr))
{
dwrite_factory->Release();
return fonts_filename_list;
}
return {};
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
@ -172,98 +167,57 @@ namespace
HDC hdc = CreateCompatibleDC(NULL);
HFONT hOldFont = SelectFont(hdc, hFont);
IDWriteFontFace *font_face;
CComPtr<IDWriteFontFace> font_face;
hr = gdi_interop->CreateFontFaceFromHdc(hdc, &font_face);
if (FAILED(hr))
{
gdi_interop->Release();
dwrite_factory->Release();
return fonts_filename_list;
}
return {};
UINT file_count;
hr = font_face->GetFiles(&file_count, NULL);
if (FAILED(hr))
{
font_face->Release();
gdi_interop->Release();
dwrite_factory->Release();
return fonts_filename_list;
}
return {};
IDWriteFontFile **font_files = new IDWriteFontFile *[file_count];
hr = font_face->GetFiles(&file_count, font_files);
auto font_files_1 = std::make_unique<IDWriteFontFile *[]>(file_count);
hr = font_face->GetFiles(&file_count, font_files_1.get());
if (FAILED(hr))
{
font_face->Release();
gdi_interop->Release();
dwrite_factory->Release();
return fonts_filename_list;
}
return {};
auto font_files = std::make_unique<CComPtr<IDWriteFontFile>[]>(file_count);
for (auto i = 0; i < file_count; i++)
font_files[i].Attach(font_files_1[i]);
std::list<WCHAR *> fonts_filename_list;
for (int i = 0; i < file_count; i++)
{
LPCVOID font_file_reference_key;
UINT font_file_reference_key_size;
hr = font_files[i]->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size);
if (FAILED(hr))
{
font_files[i]->Release();
continue;
}
IDWriteFontFileLoader *loader;
CComPtr<IDWriteFontFileLoader> loader;
hr = font_files[i]->GetLoader(&loader);
if (FAILED(hr))
{
font_files[i]->Release();
continue;
}
IDWriteLocalFontFileLoader *local_loader;
hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), (void **)&local_loader);
CComPtr<IDWriteLocalFontFileLoader> local_loader;
hr = loader.QueryInterface(&local_loader);
if (FAILED(hr))
{
loader->Release();
font_files[i]->Release();
continue;
}
UINT32 path_length;
hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length);
if (FAILED(hr))
{
local_loader->Release();
loader->Release();
font_files[i]->Release();
continue;
}
WCHAR *path = new WCHAR[path_length + 1];
hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, path, path_length + 1);
if (FAILED(hr))
{
local_loader->Release();
loader->Release();
font_files[i]->Release();
continue;
}
fonts_filename_list.push_back(path);
local_loader->Release();
loader->Release();
font_files[i]->Release();
}
font_face->Release();
gdi_interop->Release();
SelectObject(hdc, hOldFont);
ReleaseDC(NULL, hdc);
DeleteObject(hFont);
dwrite_factory->Release();
return fonts_filename_list;
}

View File

@ -1,9 +1,9 @@
std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume)
{
ISpVoice *pVoice = NULL;
if (FAILED(::CoInitialize(NULL)))
return {};
CComPtr<ISpVoice> pVoice = NULL;
std::optional<std::vector<byte>> ret = {};
do
{
@ -13,7 +13,7 @@ std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *to
ret = {};
break;
}
IEnumSpObjectTokens *pSpEnumTokens = NULL;
CComPtr<IEnumSpObjectTokens> pSpEnumTokens = NULL;
if (SUCCEEDED(SpEnumTokens(token, NULL, NULL, &pSpEnumTokens)))
{
ULONG ulTokensNumber = 0;
@ -60,9 +60,6 @@ std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *to
}
pVoice->SetOutput(cpWavStream, TRUE);
pVoice->Speak(Content.c_str(), SPF_IS_XML, NULL);
pVoice->Release();
pSpEnumTokens->Release();
pVoice = NULL;
/*To verify that the data has been written correctly, uncomment this, you should hear the voice.
cpVoice->SetOutput(NULL, FALSE);
@ -74,7 +71,7 @@ std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *to
hr = cpWavStream->Seek(a, STREAM_SEEK_SET, NULL);
// get the base istream from the ispstream
IStream *pIstream;
CComPtr<IStream> pIstream;
cpWavStream->GetBaseStream(&pIstream);
// calculate the size that is to be read
@ -131,7 +128,6 @@ std::optional<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *to
cout << endl;
*/
ret = std::move(datas);
pIstream->Release();
}
} while (0);
@ -144,9 +140,9 @@ std::vector<std::wstring> _List(const wchar_t *token)
{
if (FAILED(::CoInitialize(NULL)))
return {};
ISpVoice *pSpVoice = NULL;
CComPtr<ISpVoice> pSpVoice = NULL;
std::vector<std::wstring> ret;
IEnumSpObjectTokens *pSpEnumTokens = NULL;
CComPtr<IEnumSpObjectTokens> pSpEnumTokens = NULL;
if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pSpVoice)))
{
return {};
@ -155,7 +151,7 @@ std::vector<std::wstring> _List(const wchar_t *token)
{
ULONG ulTokensNumber = 0;
pSpEnumTokens->GetCount(&ulTokensNumber);
ISpObjectToken *m_pISpObjectToken;
CComPtr<ISpObjectToken> m_pISpObjectToken;
for (ULONG i = 0; i < ulTokensNumber; i++)
{
pSpEnumTokens->Item(i, &m_pISpObjectToken);
@ -168,15 +164,10 @@ std::vector<std::wstring> _List(const wchar_t *token)
ret.emplace_back(pszVoiceName);
CoTaskMemFree(pszVoiceName);
}
CoTaskMemFree(pszVoiceId);
}
}
m_pISpObjectToken->Release();
pSpEnumTokens->Release();
}
pSpVoice->Release();
::CoUninitialize();
return ret;
}

View File

@ -133,14 +133,12 @@ MWebBrowser::MWebBrowser(HWND hwndParent) : m_nRefCount(0),
m_hr = CreateBrowser(hwndParent);
htmlSource = L"";
IConnectionPointContainer *container = nullptr;
m_web_browser2->QueryInterface(IID_IConnectionPointContainer, (void **)&container);
CComPtr<IConnectionPointContainer> container = nullptr;
m_web_browser2.QueryInterface(&container);
container->FindConnectionPoint(__uuidof(DWebBrowserEvents2), &callback);
IUnknown *punk = nullptr;
CComPtr<IUnknown> punk = nullptr;
QueryInterface(IID_IUnknown, (void **)&punk);
callback->Advise(punk, &eventCookie);
punk->Release();
container->Release();
jsobj = new JSObject();
jsobj->AddRef();
}
@ -152,26 +150,6 @@ BOOL MWebBrowser::IsCreated() const
MWebBrowser::~MWebBrowser()
{
if (m_pDocHostUIHandler)
{
m_pDocHostUIHandler->Release();
m_pDocHostUIHandler = NULL;
}
if (m_ole_object)
{
m_ole_object->Release();
m_ole_object = NULL;
}
if (m_ole_inplace_object)
{
m_ole_inplace_object->Release();
m_ole_inplace_object = NULL;
}
if (m_web_browser2)
{
m_web_browser2->Release();
m_web_browser2 = NULL;
}
if (jsobj)
{
jsobj->Release();
@ -242,12 +220,7 @@ HRESULT MWebBrowser::CreateBrowser(HWND hwndParent)
return hr;
}
if (m_pDocHostUIHandler)
{
m_pDocHostUIHandler->Release();
m_pDocHostUIHandler = NULL;
}
m_ole_object->QueryInterface(&m_pDocHostUIHandler);
m_ole_object.QueryInterface(&m_pDocHostUIHandler);
hr = m_ole_object->SetClientSite(this);
if (FAILED(hr))
@ -273,7 +246,7 @@ HRESULT MWebBrowser::CreateBrowser(HWND hwndParent)
return hr;
}
hr = m_ole_object->QueryInterface(&m_web_browser2);
hr = m_ole_object.QueryInterface(&m_web_browser2);
if (FAILED(hr))
{
assert(0);
@ -361,19 +334,17 @@ void MWebBrowser::StopDownload()
if (!m_web_browser2)
return;
IDispatch *pDisp;
CComPtr<IDispatch> pDisp;
m_web_browser2->get_Document(&pDisp);
if (pDisp)
{
IOleCommandTarget *pCmdTarget = NULL;
pDisp->QueryInterface(&pCmdTarget);
CComPtr<IOleCommandTarget> pCmdTarget = NULL;
pDisp.QueryInterface(&pCmdTarget);
if (pCmdTarget)
{
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
pCmdTarget->Exec(NULL, OLECMDID_STOPDOWNLOAD, option, NULL, NULL);
pCmdTarget->Release();
}
pDisp->Release();
}
}
@ -430,12 +401,12 @@ void MWebBrowser::Print(BOOL bBang)
if (!m_web_browser2)
return;
IDispatch *pDisp;
CComPtr<IDispatch> pDisp;
m_web_browser2->get_Document(&pDisp);
if (pDisp)
{
IOleCommandTarget *pCmdTarget = NULL;
pDisp->QueryInterface(&pCmdTarget);
CComPtr<IOleCommandTarget> pCmdTarget = NULL;
pDisp.QueryInterface(&pCmdTarget);
if (pCmdTarget)
{
OLECMDEXECOPT option;
@ -444,9 +415,7 @@ void MWebBrowser::Print(BOOL bBang)
else
option = OLECMDEXECOPT_PROMPTUSER;
pCmdTarget->Exec(NULL, OLECMDID_PRINT, option, NULL, NULL);
pCmdTarget->Release();
}
pDisp->Release();
}
}
@ -455,19 +424,17 @@ void MWebBrowser::PrintPreview()
if (!m_web_browser2)
return;
IDispatch *pDisp;
CComPtr<IDispatch> pDisp;
m_web_browser2->get_Document(&pDisp);
if (pDisp)
{
IOleCommandTarget *pCmdTarget = NULL;
pDisp->QueryInterface(&pCmdTarget);
CComPtr<IOleCommandTarget> pCmdTarget = NULL;
pDisp.QueryInterface(&pCmdTarget);
if (pCmdTarget)
{
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
pCmdTarget->Exec(NULL, OLECMDID_PRINTPREVIEW, option, NULL, NULL);
pCmdTarget->Release();
}
pDisp->Release();
}
}
@ -476,19 +443,17 @@ void MWebBrowser::PageSetup()
if (!m_web_browser2)
return;
IDispatch *pDisp;
CComPtr<IDispatch> pDisp;
m_web_browser2->get_Document(&pDisp);
if (pDisp)
{
IOleCommandTarget *pCmdTarget = NULL;
pDisp->QueryInterface(&pCmdTarget);
CComPtr<IOleCommandTarget> pCmdTarget;
pDisp.QueryInterface(&pCmdTarget);
if (pCmdTarget)
{
OLECMDEXECOPT option = OLECMDEXECOPT_DONTPROMPTUSER;
pCmdTarget->Exec(NULL, OLECMDID_PAGESETUP, option, NULL, NULL);
pCmdTarget->Release();
}
pDisp->Release();
}
}
@ -497,12 +462,11 @@ BOOL MWebBrowser::TranslateAccelerator(LPMSG pMsg)
if (!m_web_browser2)
return FALSE;
IOleInPlaceActiveObject *pOIPAO = NULL;
HRESULT hr = m_web_browser2->QueryInterface(&pOIPAO);
CComPtr<IOleInPlaceActiveObject> pOIPAO = NULL;
HRESULT hr = m_web_browser2.QueryInterface(&pOIPAO);
if (SUCCEEDED(hr))
{
hr = pOIPAO->TranslateAccelerator(pMsg);
pOIPAO->Release();
return hr == S_OK;
}
return FALSE;
@ -519,27 +483,6 @@ HRESULT MWebBrowser::get_LocationURL(BSTR *bstrURL) const
return m_web_browser2->get_LocationURL(bstrURL);
}
HRESULT MWebBrowser::get_mimeType(BSTR *bstrMIME) const
{
if (!m_web_browser2)
{
*bstrMIME = NULL;
return E_FAIL;
}
HRESULT hr = E_FAIL;
IDispatch *pDisp;
m_web_browser2->get_Document(&pDisp);
if (pDisp)
{
IHTMLDocument2 *pDocument = static_cast<IHTMLDocument2 *>(pDisp);
hr = pDocument->get_mimeType(bstrMIME);
pDisp->Release();
}
return hr;
}
BOOL MWebBrowser::is_busy() const
{
if (!m_web_browser2)
@ -704,7 +647,7 @@ STDMETHODIMP MWebBrowser::CanInPlaceActivate()
STDMETHODIMP MWebBrowser::OnInPlaceActivate()
{
::OleLockRunning(m_ole_object, TRUE, FALSE);
m_ole_object->QueryInterface(&m_ole_inplace_object);
m_ole_object.QueryInterface(&m_ole_inplace_object);
m_ole_inplace_object->SetObjectRects(&m_rc, &m_rc);
return S_OK;
}
@ -956,27 +899,10 @@ STDMETHODIMP MWebBrowser::GetWindow(REFGUID rguidReason, HWND *phwnd)
}
STDMETHODIMP MWebBrowser::OnSecurityProblem(DWORD dwProblem)
{
printf("MWebBrowser::OnSecurityProblem\n");
BSTR url = NULL;
get_LocationURL(&url);
if (url)
{
SysFreeString(url);
}
{
return S_OK;
}
{
return S_OK;
}
return E_ABORT;
}
// IDocHostUIHandler interface
STDMETHODIMP MWebBrowser::ShowContextMenu(
@ -1105,45 +1031,29 @@ HRESULT MWebBrowser::GetTypeInfoCount(UINT *pctinfo) { return E_FAIL; }
HRESULT MWebBrowser::GetTypeInfo(UINT, LCID, ITypeInfo **) { return E_FAIL; }
HRESULT MWebBrowser::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_FAIL; }
void AddCustomObject(IHTMLDocument2 *doc, IDispatch *custObj, std::string name)
void AddCustomObject(IHTMLDocument2 *doc, IDispatch *custObj, std::wstring name)
{
CComPtr<IHTMLDocument2> _doc = doc;
if (doc == NULL)
{
return;
}
IHTMLWindow2 *win = NULL;
doc->get_parentWindow(&win);
doc->Release();
CComPtr<IHTMLWindow2> win = NULL;
_doc->get_parentWindow(&win);
if (win == NULL)
{
if (!win)
return;
}
IDispatchEx *winEx;
win->QueryInterface(&winEx);
win->Release();
CComPtr<IDispatchEx> winEx;
HRESULT hr = win.QueryInterface(&winEx);
if (winEx == NULL)
{
if (FAILED(hr) || !winEx)
return;
}
int lenW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name.c_str(), -1, NULL, 0);
BSTR objName = SysAllocStringLen(0, lenW);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name.c_str(), -1, objName, lenW);
DISPID dispid;
HRESULT hr = winEx->GetDispID(objName, fdexNameEnsure, &dispid);
SysFreeString(objName);
hr = winEx->GetDispID(name.data(), fdexNameEnsure, &dispid);
if (FAILED(hr))
{
return;
}
DISPID namedArgs[] = {DISPID_PROPERTYPUT};
DISPPARAMS params;
@ -1155,13 +1065,10 @@ void AddCustomObject(IHTMLDocument2 *doc, IDispatch *custObj, std::string name)
params.cNamedArgs = 1;
hr = winEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
winEx->Release();
if (FAILED(hr))
{
return;
}
}
HRESULT MWebBrowser::Invoke(DISPID dispIdMember, REFIID, LCID, WORD,
DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *, UINT *)
@ -1169,7 +1076,7 @@ HRESULT MWebBrowser::Invoke(DISPID dispIdMember, REFIID, LCID, WORD,
if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
return OnCompleted(pDispParams);
else if (dispIdMember == DISPID_NAVIGATECOMPLETE2)
return AddCustomObject(GetIHTMLDocument2(), jsobj, "LUNAJSObject"), S_OK;
return AddCustomObject(GetIHTMLDocument2(), jsobj, L"LUNAJSObject"), S_OK;
else
return S_OK;
}
@ -1177,19 +1084,19 @@ HRESULT MWebBrowser::OnCompleted(DISPPARAMS *args)
{
HRESULT hr;
IDispatch *pDispatch = 0;
IHTMLDocument2 *pHtmlDoc2 = 0;
IPersistStreamInit *pPSI = 0;
IStream *pStream = 0;
CComPtr<IDispatch> pDispatch;
CComPtr<IHTMLDocument2> pHtmlDoc2 = 0;
CComPtr<IPersistStreamInit> pPSI = 0;
CComPtr<IStream> pStream = 0;
HGLOBAL hHTMLContent;
if (htmlSource.empty())
return S_OK;
hr = m_web_browser2->get_Document(&pDispatch);
if (SUCCEEDED(hr) && pDispatch)
hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void **)&pHtmlDoc2);
hr = pDispatch.QueryInterface(&pHtmlDoc2);
if (SUCCEEDED(hr) && pHtmlDoc2)
hr = pHtmlDoc2->QueryInterface(IID_IPersistStreamInit, (void **)&pPSI);
hr = pHtmlDoc2.QueryInterface(&pPSI);
// allocate global memory to copy the HTML content to
hHTMLContent = ::GlobalAlloc(GMEM_MOVEABLE, (htmlSource.size() + 1) * sizeof(TCHAR));
@ -1208,14 +1115,6 @@ HRESULT MWebBrowser::OnCompleted(DISPPARAMS *args)
if (SUCCEEDED(hr))
hr = pPSI->Load(pStream);
}
if (pStream)
pStream->Release();
if (pPSI)
pPSI->Release();
if (pHtmlDoc2)
pHtmlDoc2->Release();
if (pDispatch)
pDispatch->Release();
htmlSource = L"";
return S_OK;
}

View File

@ -84,7 +84,6 @@ public:
HRESULT get_Application(IDispatch **ppApplication) const;
HRESULT get_LocationURL(BSTR *bstrURL) const;
HRESULT get_mimeType(BSTR *bstrMIME) const;
HRESULT put_Silent(VARIANT_BOOL bSilent);
BOOL is_busy() const;
HRESULT ZoomUp();
@ -241,10 +240,10 @@ protected:
HWND m_hwndParent;
HWND m_hwndCtrl;
HWND m_hwndIEServer;
IWebBrowser2 *m_web_browser2;
IOleObject *m_ole_object;
IOleInPlaceObject *m_ole_inplace_object;
IDocHostUIHandler *m_pDocHostUIHandler;
CComPtr<IWebBrowser2> m_web_browser2;
CComPtr<IOleObject> m_ole_object;
CComPtr<IOleInPlaceObject> m_ole_inplace_object;
CComPtr<IDocHostUIHandler> m_pDocHostUIHandler;
RECT m_rc;
HRESULT m_hr;
BOOL m_bAllowInsecure;

View File

@ -245,16 +245,15 @@ DECLARE_API void html_add_menu(void *web, int index, int command, const wchar_t
}
BSTR GetSelectedText(IHTMLDocument2 *pHTMLDoc2)
{
IHTMLSelectionObject *pSelectionObj = nullptr;
CComPtr<IHTMLSelectionObject> pSelectionObj = nullptr;
HRESULT hr = pHTMLDoc2->get_selection(&pSelectionObj);
if (FAILED(hr) || pSelectionObj == nullptr)
{
return nullptr;
}
IHTMLTxtRange *pTxtRange = nullptr;
CComPtr<IHTMLTxtRange> pTxtRange = nullptr;
hr = pSelectionObj->createRange((IDispatch **)&pTxtRange);
pSelectionObj->Release();
if (FAILED(hr) || pTxtRange == nullptr)
{
return nullptr;
@ -262,7 +261,6 @@ BSTR GetSelectedText(IHTMLDocument2 *pHTMLDoc2)
BSTR selectedText = nullptr;
hr = pTxtRange->get_text(&selectedText);
pTxtRange->Release();
return selectedText;
}
@ -272,10 +270,9 @@ DECLARE_API const wchar_t *html_get_select_text(void *web)
return L"";
auto ww = static_cast<MWebBrowserEx *>(web);
if (IHTMLDocument2 *pDocument = ww->GetIHTMLDocument2())
if (CComPtr<IHTMLDocument2> pDocument = ww->GetIHTMLDocument2())
{
auto text = GetSelectedText(pDocument);
pDocument->Release();
// 不需要freefree会崩溃
return text;
}
@ -297,3 +294,49 @@ DECLARE_API HWND html_get_ie(void *web)
auto ww = static_cast<MWebBrowserEx *>(web);
return ww->GetIEServerWindow();
}
DECLARE_API void html_eval(void *web, const wchar_t *js)
{
if (!web)
return;
auto ww = static_cast<MWebBrowserEx *>(web);
CComPtr<IHTMLDocument2> pDocument = ww->GetIHTMLDocument2();
if (!pDocument)
return;
CComPtr<IDispatch> scriptDispatch;
if (FAILED(pDocument->get_Script(&scriptDispatch)))
return;
DISPID dispid;
BSTR evalStr = SysAllocString(L"eval");
if (scriptDispatch->GetIDsOfNames(IID_NULL, &evalStr, 1,
LOCALE_SYSTEM_DEFAULT, &dispid) != S_OK)
{
SysFreeString(evalStr);
return;
}
SysFreeString(evalStr);
DISPPARAMS params;
VARIANT arg;
VARIANT result;
EXCEPINFO excepInfo;
UINT nArgErr = (UINT)-1;
params.cArgs = 1;
params.cNamedArgs = 0;
params.rgvarg = &arg;
arg.vt = VT_BSTR;
static const wchar_t *prologue = L"(function(){";
static const wchar_t *epilogue = L";})();";
int n = wcslen(prologue) + wcslen(epilogue) + wcslen(js) + 1;
auto eval = std::make_unique<wchar_t[]>(n);
_snwprintf(eval.get(), n, L"%s%s%s", prologue, js, epilogue);
arg.bstrVal = SysAllocString(eval.get());
if (scriptDispatch->Invoke(
dispid, IID_NULL, 0, DISPATCH_METHOD,
&params, &result, &excepInfo, &nArgErr) != S_OK)
{
SysFreeString(arg.bstrVal);
return;
}
SysFreeString(arg.bstrVal);
}

View File

@ -201,14 +201,12 @@ DECLARE_API void GetSelectedText(void (*cb)(const wchar_t *))
}
// 提取文本
BSTR text;
wil::unique_bstr text;
if (FAILED(range->GetText(-1, &text)) || !text)
{
throw std::runtime_error("无法提取选定的文本.");
}
std::wstring selectedText(text, SysStringLen(text));
SysFreeString(text);
cb(selectedText.c_str());
cb(text.get());
}
catch (std::exception &e)
{

View File

@ -6,14 +6,13 @@ DECLARE_API void GetLnkTargetPath(wchar_t *lnkFilePath, wchar_t *path, wchar_t *
wcscpy(iconpath, L"");
CoInitialize(NULL);
IShellLink *shellLink;
CComPtr<IShellLink> shellLink;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&shellLink);
if (SUCCEEDED(hr))
{
IPersistFile *persistFile;
hr = shellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
CComPtr<IPersistFile> persistFile;
auto hr = shellLink.QueryInterface(&persistFile);
if (SUCCEEDED(hr))
{
WCHAR wsz[MAX_PATH];
@ -44,11 +43,7 @@ DECLARE_API void GetLnkTargetPath(wchar_t *lnkFilePath, wchar_t *path, wchar_t *
wcscpy(path, L"");
}
}
persistFile->Release();
}
shellLink->Release();
}
CoUninitialize();

View File

@ -1399,6 +1399,9 @@ class QWebWrap(abstractwebview):
class mshtmlWidget(abstractwebview):
CommandBase = 10086
def eval(self, js):
winsharedutils.html_eval(self.browser, js)
def bindhelper(self, func, ppwc, argc):
argv = []
for i in range(argc):

View File

@ -142,7 +142,8 @@ html_bind_function.argtypes = c_void_p, c_wchar_p, html_bind_function_FT
html_get_ie = utilsdll.html_get_ie
html_get_ie.argtypes = (c_void_p,)
html_get_ie.restype = HWND
html_eval = utilsdll.html_eval
html_eval.argtypes = c_void_p, c_wchar_p
_GetLnkTargetPath = utilsdll.GetLnkTargetPath
_GetLnkTargetPath.argtypes = c_wchar_p, c_wchar_p, c_wchar_p, c_wchar_p