mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2025-01-13 07:33:53 +08:00
.
This commit is contained in:
parent
a4edf162fd
commit
905fe2b819
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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, ¶ms, 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
// 不需要free,free会崩溃
|
||||
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,
|
||||
¶ms, &result, &excepInfo, &nArgErr) != S_OK)
|
||||
{
|
||||
SysFreeString(arg.bstrVal);
|
||||
return;
|
||||
}
|
||||
SysFreeString(arg.bstrVal);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user