From 3a0f44449c52c49f60a8467afe406275af180625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <1173718158@qq.com> Date: Sun, 29 Dec 2024 18:09:35 +0800 Subject: [PATCH] . --- cpp/common.hpp | 34 ++++- cpp/implsapi.cpp | 207 +++++++++----------------- cpp/winsharedutils/MWebBrowser.cpp | 43 +----- cpp/winsharedutils/hwnd.cpp | 4 +- cpp/winsharedutils/lnk.cpp | 56 +++---- cpp/winsharedutils/webview2_extra.cpp | 3 - 6 files changed, 128 insertions(+), 219 deletions(-) diff --git a/cpp/common.hpp b/cpp/common.hpp index 18464c1a..17560b1d 100644 --- a/cpp/common.hpp +++ b/cpp/common.hpp @@ -1,7 +1,7 @@ struct AutoHandle { HANDLE _handle; - AutoHandle(HANDLE handle) : _handle(handle){}; + AutoHandle(HANDLE handle) : _handle(handle) {}; ~AutoHandle() { CloseHandle(_handle); @@ -16,12 +16,11 @@ struct AutoHandle } }; inline SECURITY_ATTRIBUTES allAccess = std::invoke([] // allows non-admin processes to access kernel objects made by admin processes -{ + { static SECURITY_DESCRIPTOR sd = {}; InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); - return SECURITY_ATTRIBUTES{ sizeof(SECURITY_ATTRIBUTES), &sd, FALSE }; -}); + return SECURITY_ATTRIBUTES{ sizeof(SECURITY_ATTRIBUTES), &sd, FALSE }; }); inline std::wstring StringToWideString(const std::string &text, UINT encoding = CP_UTF8) { @@ -35,4 +34,29 @@ inline std::string WideStringToString(const std::wstring &text, UINT cp = CP_UTF WideCharToMultiByte(cp, 0, text.c_str(), -1, buffer.data(), buffer.size(), nullptr, nullptr); return buffer.data(); -} \ No newline at end of file +} + +#define CHECK_FAILURE(x) \ + if (FAILED((x))) \ + return (HRESULT)x; +#define CHECK_FAILURE_NORET(x) \ + if (FAILED((x))) \ + return ; + +struct CO_INIT +{ + HRESULT hr; + CO_INIT() + { + HRESULT hr = ::CoInitialize(NULL); + } + operator HRESULT() + { + return hr; + } + ~CO_INIT() + { + if (SUCCEEDED(hr)) + CoUninitialize(); + } +}; \ No newline at end of file diff --git a/cpp/implsapi.cpp b/cpp/implsapi.cpp index 5db79a6d..53e59bd4 100644 --- a/cpp/implsapi.cpp +++ b/cpp/implsapi.cpp @@ -1,173 +1,112 @@ std::optional> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume) { - if (FAILED(::CoInitialize(NULL))) - return {}; - CComPtr pVoice = NULL; std::optional> ret = {}; - do + [&]() { - HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); - if (FAILED(hr) || (NULL == pVoice)) - { - ret = {}; - break; - } + CO_INIT co; + CHECK_FAILURE_NORET(co); + CComPtr pVoice = NULL; + CHECK_FAILURE_NORET(pVoice.CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL)); CComPtr pSpEnumTokens = NULL; - if (SUCCEEDED(SpEnumTokens(token, NULL, NULL, &pSpEnumTokens))) - { - ULONG ulTokensNumber = 0; - pSpEnumTokens->GetCount(&ulTokensNumber); - ISpObjectToken *m_pISpObjectToken; + CHECK_FAILURE_NORET(SpEnumTokens(token, NULL, NULL, &pSpEnumTokens)); + ULONG ulTokensNumber = 0; + pSpEnumTokens->GetCount(&ulTokensNumber); + ISpObjectToken *m_pISpObjectToken; - pSpEnumTokens->Item(voiceid, &m_pISpObjectToken); - pVoice->SetVoice(m_pISpObjectToken); - pVoice->SetRate(rate); - pVoice->SetVolume(volume); + pSpEnumTokens->Item(voiceid, &m_pISpObjectToken); + pVoice->SetVoice(m_pISpObjectToken); + pVoice->SetRate(rate); + pVoice->SetVolume(volume); - CComPtr cpWavStream; - CComPtr cpOldStream; - CSpStreamFormat originalFmt; - CComPtr pMemStream; - hr = pVoice->GetOutputStream(&cpOldStream); - if (FAILED(hr) || (NULL == cpOldStream)) - { - ret = {}; - break; - } - originalFmt.AssignFormat(cpOldStream); - // hr = SPBindToFile(FileName.c_str(), SPFM_CREATE_ALWAYS, &cpWavStream, &originalFmt.FormatId(), originalFmt.WaveFormatExPtr()); - // if (FAILED(hr)) - // { - // ret = false; - // break; - // } - { - hr = ::CreateStreamOnHGlobal(NULL, TRUE, &pMemStream); - if (SUCCEEDED(hr)) - { - hr = cpWavStream.CoCreateInstance(CLSID_SpStream); - if (SUCCEEDED(hr)) - { - hr = cpWavStream->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, originalFmt.WaveFormatExPtr()); - if (FAILED(hr)) - { - ret = {}; - break; - } - } - } - } - pVoice->SetOutput(cpWavStream, TRUE); - pVoice->Speak(Content.c_str(), SPF_IS_XML, NULL); + CComPtr cpWavStream; + CComPtr cpOldStream; + CSpStreamFormat originalFmt; + CComPtr pMemStream; + CHECK_FAILURE_NORET(pVoice->GetOutputStream(&cpOldStream)); + originalFmt.AssignFormat(cpOldStream); + CHECK_FAILURE_NORET(CreateStreamOnHGlobal(NULL, TRUE, &pMemStream)); + CHECK_FAILURE_NORET(cpWavStream.CoCreateInstance(CLSID_SpStream)); + CHECK_FAILURE_NORET(cpWavStream->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, originalFmt.WaveFormatExPtr())); + pVoice->SetOutput(cpWavStream, TRUE); + pVoice->Speak(Content.c_str(), SPF_IS_XML, NULL); - /*To verify that the data has been written correctly, uncomment this, you should hear the voice. - cpVoice->SetOutput(NULL, FALSE); - cpVoice->SpeakStream(cpStream, SPF_DEFAULT, NULL); - */ + /*To verify that the data has been written correctly, uncomment this, you should hear the voice. + cpVoice->SetOutput(NULL, FALSE); + cpVoice->SpeakStream(cpStream, SPF_DEFAULT, NULL); + */ - // After SAPI writes the stream, the stream position is at the end, so we need to set it to the beginning. - _LARGE_INTEGER a = {0}; - hr = cpWavStream->Seek(a, STREAM_SEEK_SET, NULL); + // After SAPI writes the stream, the stream position is at the end, so we need to set it to the beginning. + _LARGE_INTEGER a = {0}; + CHECK_FAILURE_NORET(cpWavStream->Seek(a, STREAM_SEEK_SET, NULL)); - // get the base istream from the ispstream - CComPtr pIstream; - cpWavStream->GetBaseStream(&pIstream); + // get the base istream from the ispstream + CComPtr pIstream; + cpWavStream->GetBaseStream(&pIstream); - // calculate the size that is to be read - STATSTG stats; - pIstream->Stat(&stats, STATFLAG_NONAME); + // calculate the size that is to be read + STATSTG stats; + pIstream->Stat(&stats, STATFLAG_NONAME); - ULONG sSize = stats.cbSize.QuadPart; // size of the data to be read - auto wavfmt = *originalFmt.WaveFormatExPtr(); + ULONG sSize = stats.cbSize.QuadPart; // size of the data to be read - ULONG bytesRead; // this will tell the number of bytes that have been read - std::vector datas; - datas.resize(sSize + 0x3ea); - auto pBuffer = datas.data(); // buffer to read the data - // memcpy(pBuffer,&wavHeader,sizeof(WAV_HEADER)); - int fsize = sSize + 0x3ea; - int ptr = 0; - memcpy(pBuffer, "RIFF", 4); - ptr += 4; - memcpy(pBuffer + ptr, &fsize, 4); - ptr += 4; - memcpy(pBuffer + ptr, "WAVEfmt ", 8); - ptr += 8; - memcpy(pBuffer + ptr, "\x12\x00\x00\x00", 4); - ptr += 4; - memcpy(pBuffer + ptr, &wavfmt.wFormatTag, 2); - ptr += 2; - memcpy(pBuffer + ptr, &wavfmt.nChannels, 2); - ptr += 2; - int freq = wavfmt.nSamplesPerSec; - memcpy(pBuffer + ptr, &freq, 4); - ptr += 4; - freq = wavfmt.nAvgBytesPerSec; - memcpy(pBuffer + ptr, &freq, 4); - ptr += 4; - memcpy(pBuffer + ptr, &wavfmt.nBlockAlign, 4); - ptr += 2; - memcpy(pBuffer + ptr, &wavfmt.wBitsPerSample, 2); - ptr += 2; - WORD _0 = 0; + ULONG bytesRead; // this will tell the number of bytes that have been read + std::vector datas; + datas.resize(sSize + 0x3ea); + auto pBuffer = datas.data(); // buffer to read the data + // memcpy(pBuffer,&wavHeader,sizeof(WAV_HEADER)); + int fsize = sSize + 0x3ea; + int ptr = 0; + memcpy(pBuffer, "RIFF", 4); + ptr += 4; + memcpy(pBuffer + ptr, &fsize, 4); + ptr += 4; + memcpy(pBuffer + ptr, "WAVEfmt ", 8); + ptr += 8; + memcpy(pBuffer + ptr, "\x12\x00\x00\x00", 4); + ptr += 4; + memcpy(pBuffer + ptr, originalFmt.WaveFormatExPtr(), sizeof(WAVEFORMATEX)); + ptr += sizeof(WAVEFORMATEX); + memcpy(pBuffer + ptr, "data", 4); + ptr += 4; + memcpy(pBuffer + ptr, &sSize, 4); + ptr += 4; + // read the data into the buffer + pIstream->Read(pBuffer + ptr, sSize, &bytesRead); - memcpy(pBuffer + ptr, &_0, 2); - ptr += 2; - memcpy(pBuffer + ptr, "data", 4); - ptr += 4; - memcpy(pBuffer + ptr, &sSize, 4); + ret = std::move(datas); + }(); - // read the data into the buffer - pIstream->Read(pBuffer + 46, sSize, &bytesRead); - - /*uncomment the following to print the contents of the buffer - cout << "following data read \n"; - for (int i = 0; i < sSize; i++) - cout << pBuffer[i] << " "; - cout << endl; - */ - ret = std::move(datas); - } - - } while (0); - - ::CoUninitialize(); return ret; } std::vector _List(const wchar_t *token) { - if (FAILED(::CoInitialize(NULL))) - return {}; - CComPtr pSpVoice = NULL; std::vector ret; - CComPtr pSpEnumTokens = NULL; - if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pSpVoice))) - { - return {}; - } - if (SUCCEEDED(SpEnumTokens(token, NULL, NULL, &pSpEnumTokens))) + [&]() { + CO_INIT co; + CHECK_FAILURE_NORET(co); + CComPtr pSpVoice = NULL; + CComPtr pSpEnumTokens = NULL; + CHECK_FAILURE_NORET(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pSpVoice)); + CHECK_FAILURE_NORET(SpEnumTokens(token, NULL, NULL, &pSpEnumTokens)); ULONG ulTokensNumber = 0; pSpEnumTokens->GetCount(&ulTokensNumber); CComPtr m_pISpObjectToken; for (ULONG i = 0; i < ulTokensNumber; i++) { pSpEnumTokens->Item(i, &m_pISpObjectToken); - WCHAR *pszVoiceId = NULL; - LPWSTR pszVoiceName; + CComHeapPtr pszVoiceId; + CComHeapPtr pszVoiceName; if (SUCCEEDED(m_pISpObjectToken->GetId(&pszVoiceId))) { if (SUCCEEDED(m_pISpObjectToken->GetStringValue(NULL, &pszVoiceName))) { ret.emplace_back(pszVoiceName); - CoTaskMemFree(pszVoiceName); } - CoTaskMemFree(pszVoiceId); } } - } - ::CoUninitialize(); + }(); return ret; } \ No newline at end of file diff --git a/cpp/winsharedutils/MWebBrowser.cpp b/cpp/winsharedutils/MWebBrowser.cpp index eb64bbec..2f1aec0e 100644 --- a/cpp/winsharedutils/MWebBrowser.cpp +++ b/cpp/winsharedutils/MWebBrowser.cpp @@ -211,48 +211,19 @@ HRESULT MWebBrowser::CreateBrowser(HWND hwndParent) { m_hwndParent = hwndParent; - HRESULT hr; - hr = ::OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, NULL, - this, this, (void **)&m_ole_object); - if (FAILED(hr)) - { - assert(0); - return hr; - } + CHECK_FAILURE(OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, NULL, + this, this, (void **)&m_ole_object)); m_ole_object.QueryInterface(&m_pDocHostUIHandler); - hr = m_ole_object->SetClientSite(this); - if (FAILED(hr)) - { - assert(0); - return hr; - } - - hr = ::OleSetContainedObject(m_ole_object, TRUE); - if (FAILED(hr)) - { - assert(0); - return hr; - } - + CHECK_FAILURE(m_ole_object->SetClientSite(this)); + CHECK_FAILURE(OleSetContainedObject(m_ole_object, TRUE)); RECT rc; ::SetRectEmpty(&rc); - hr = m_ole_object->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0, - m_hwndParent, &rc); - if (FAILED(hr)) - { - assert(0); - return hr; - } - - hr = m_ole_object.QueryInterface(&m_web_browser2); - if (FAILED(hr)) - { - assert(0); - return hr; - } + CHECK_FAILURE(m_ole_object->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0, + m_hwndParent, &rc)); + CHECK_FAILURE(m_ole_object.QueryInterface(&m_web_browser2)); HWND hwnd = GetControlWindow(); DWORD exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); diff --git a/cpp/winsharedutils/hwnd.cpp b/cpp/winsharedutils/hwnd.cpp index 8a494540..aa44ec92 100644 --- a/cpp/winsharedutils/hwnd.cpp +++ b/cpp/winsharedutils/hwnd.cpp @@ -162,7 +162,8 @@ DECLARE_API bool check_window_viewable(HWND hwnd) DECLARE_API void GetSelectedText(void (*cb)(const wchar_t *)) { #ifndef WINXP - CoInitialize(nullptr); + CO_INIT co; + CHECK_FAILURE_NORET(co); try { // 初始化 COM @@ -212,6 +213,5 @@ DECLARE_API void GetSelectedText(void (*cb)(const wchar_t *)) { printf(e.what()); } - CoUninitialize(); #endif } diff --git a/cpp/winsharedutils/lnk.cpp b/cpp/winsharedutils/lnk.cpp index ca708489..4018b202 100644 --- a/cpp/winsharedutils/lnk.cpp +++ b/cpp/winsharedutils/lnk.cpp @@ -1,50 +1,28 @@ -DECLARE_API void GetLnkTargetPath(wchar_t *lnkFilePath, wchar_t *path, wchar_t *tgtpath, wchar_t *iconpath, wchar_t *dirpath) +DECLARE_API void GetLnkTargetPath(const wchar_t *lnkFilePath, wchar_t *path, wchar_t *tgtpath, wchar_t *iconpath, wchar_t *dirpath) { wcscpy(path, L""); wcscpy(tgtpath, L""); wcscpy(iconpath, L""); - CoInitialize(NULL); - + wcscpy(dirpath, L""); + CO_INIT co; + CHECK_FAILURE_NORET(co); CComPtr shellLink; - HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&shellLink); + CHECK_FAILURE_NORET(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&shellLink)); - if (SUCCEEDED(hr)) - { - CComPtr persistFile; - auto hr = shellLink.QueryInterface(&persistFile); - if (SUCCEEDED(hr)) - { - WCHAR wsz[MAX_PATH]; - StringCchCopy(wsz, MAX_PATH, lnkFilePath); + CComPtr persistFile; + CHECK_FAILURE_NORET(shellLink.QueryInterface(&persistFile)); + WCHAR wsz[MAX_PATH]; + StringCchCopy(wsz, MAX_PATH, lnkFilePath); - hr = persistFile->Load(wsz, STGM_READ); + CHECK_FAILURE_NORET(persistFile->Load(lnkFilePath, STGM_READ)); - if (SUCCEEDED(hr)) - { - hr = shellLink->Resolve(NULL, SLR_NO_UI); + CHECK_FAILURE_NORET(shellLink->Resolve(NULL, SLR_NO_UI)); - if (SUCCEEDED(hr)) - { - WIN32_FIND_DATA findData; - int x; - hr = shellLink->GetIconLocation(iconpath, MAX_PATH, &x); - if (FAILED(hr)) - wcscpy(iconpath, L""); - hr = shellLink->GetArguments(tgtpath, MAX_PATH); - if (FAILED(hr)) - wcscpy(tgtpath, L""); - hr = shellLink->GetPath(path, MAX_PATH, &findData, SLGP_RAWPATH); - - if (FAILED(hr)) - wcscpy(path, L""); - hr = shellLink->GetWorkingDirectory(dirpath, MAX_PATH); - if (FAILED(hr)) - wcscpy(path, L""); - } - } - } - } - - CoUninitialize(); + WIN32_FIND_DATA findData; + int x; + shellLink->GetIconLocation(iconpath, MAX_PATH, &x); + shellLink->GetArguments(tgtpath, MAX_PATH); + shellLink->GetPath(path, MAX_PATH, &findData, SLGP_RAWPATH); + shellLink->GetWorkingDirectory(dirpath, MAX_PATH); } \ No newline at end of file diff --git a/cpp/winsharedutils/webview2_extra.cpp b/cpp/winsharedutils/webview2_extra.cpp index 45a9dd56..a141f039 100644 --- a/cpp/winsharedutils/webview2_extra.cpp +++ b/cpp/winsharedutils/webview2_extra.cpp @@ -7,9 +7,6 @@ #include using namespace Microsoft::WRL; #include -#define CHECK_FAILURE(x) \ - if (FAILED((x))) \ - return x; #endif DECLARE_API void set_transparent_background(void *m_host)