@@ -346,3 +346,128 @@ BOOL ImeSetOpen(HWND hWnd, BOOL bOpen, BOOL* pBackup)
346346 bRet &= ImmReleaseContext (hWnd, hIMC);
347347 return bRet;
348348}
349+
350+ namespace cxx {
351+
352+ GlobalDropFiles MakeDropFiles (std::span<const std::filesystem::path> files)
353+ {
354+ assert (!files.empty ());
355+
356+ auto strFiles = std::accumulate (files.begin () + 1 , files.end (), std::wstring (files.front ()), [](const std::wstring& a, const std::filesystem::path& b) { return a + L' \0 ' + b.native (); }) + L' \0 ' + L' \0 ' ;
357+
358+ const size_t allocSize = sizeof (DROPFILES ) + std::size (strFiles) * sizeof (WCHAR );
359+ GlobalDropFiles drop (allocSize);
360+ drop.Lock ([strFiles](DROPFILES * p) {
361+ p->pFiles = DWORD (sizeof (DROPFILES ));
362+ p->fWide = TRUE ;
363+ std::ranges::copy (strFiles, LPWSTR (LPBYTE (p) + p->pFiles ));
364+ });
365+ return drop;
366+ }
367+
368+ // 文字列を指定して構築(指定した文字列を確保したメモリにコピーする)
369+ GlobalWString::GlobalWString (std::wstring_view text)
370+ : GlobalWString(text.size())
371+ {
372+ SetText (text);
373+ }
374+
375+ // 文字列を指定して更新する
376+ void GlobalWString::SetText (std::wstring_view text) const
377+ {
378+ Lock ([text](LPWSTR pStr, size_t cbSize) {
379+ if (cbSize / sizeof (WCHAR ) <= std::size (text)) throw std::length_error (" text length is too long." );
380+ std::ranges::copy (text, pStr);
381+ return true ;
382+ });
383+ }
384+
385+ // 格納されている文字列データのコピーを取得する
386+ std::wstring GlobalWString::wstring () const & {
387+ return Lock ([](LPCWSTR pStr, size_t cbSize) {
388+ return std::wstring (pStr, ::wcsnlen (pStr, cbSize / sizeof (WCHAR )));
389+ });
390+ }
391+
392+ // 文字列を指定して構築(指定した文字列を確保したメモリにコピーする)
393+ GlobalString::GlobalString (std::string_view text)
394+ : GlobalString(text.size())
395+ {
396+ SetText (text);
397+ }
398+
399+ // 文字列を指定して更新する
400+ void GlobalString::SetText (std::string_view text) const
401+ {
402+ Lock ([text](LPSTR pStr, size_t cbSize) {
403+ if (cbSize <= std::size (text)) throw std::length_error (" text length is too long." );
404+ std::ranges::copy (text, pStr);
405+ return true ;
406+ });
407+ }
408+
409+ // 格納されている文字列データのコピーを取得する
410+ std::string GlobalString::string () const & {
411+ return Lock ([](LPCSTR pStr, size_t cbSize) {
412+ return std::string (pStr, ::strnlen (pStr, cbSize));
413+ });
414+ }
415+
416+ // 格納されているデータのコピーを取得する
417+ std::vector<std::filesystem::path> GlobalDropFiles::data () const & {
418+ const auto hDrop = static_cast <HDROP >(get ());
419+ return Lock ([hDrop](const DROPFILES * p [[maybe_unused]] , size_t cbSize [[maybe_unused]] ) {
420+ std::vector<std::filesystem::path> files;
421+ std::wstring buffer (_MAX_PATH, L' \0 ' );
422+ const auto uFiles = ::DragQueryFileW (hDrop, 0xFFFFFFFF , nullptr , 0 );
423+ for (UINT i = 0 ; i < uFiles; ++i) {
424+ // 必要サイズを取得する
425+ const auto required = ::DragQueryFileW (hDrop, i, nullptr , 0 );
426+
427+ // バッファを確保して取得する
428+ buffer.resize (required);
429+ ::DragQueryFileW (hDrop, i, std::data(buffer), UINT(std::size(buffer) + 1));
430+
431+ // パスリストに追加する
432+ files.emplace_back (buffer);
433+ }
434+
435+ return files;
436+ });
437+ }
438+
439+ // 文字列を指定して必要サイズを計算する
440+ /* static */ size_t GlobalSakura::CalcSize (std::wstring_view text) noexcept
441+ {
442+ return sizeof (size_type) + (std::size (text) + 1 ) * sizeof (WCHAR );
443+ }
444+
445+ // 文字列を指定して構築(指定した文字列を確保したメモリにコピーする)
446+ GlobalSakura::GlobalSakura (std::wstring_view text)
447+ : GlobalMemory(CalcSize(text))
448+ {
449+ SetText (text);
450+ }
451+
452+ // 文字列を指定して更新する
453+ void GlobalSakura::SetText (std::wstring_view text) const
454+ {
455+ Lock ([text](LPWSTR pStr, size_t cbSize) {
456+ if (cbSize < CalcSize (text)) throw std::length_error (" text length is too long." );
457+ *(size_type*)pStr = size_type (std::size (text));
458+ std::ranges::copy (text, LPWSTR (pStr + sizeof (size_type) / sizeof (WCHAR )));
459+ return true ;
460+ });
461+ }
462+
463+ // 格納されている文字列データのコピーを取得する
464+ std::wstring GlobalSakura::wstring () const & {
465+ return Lock ([](LPCWSTR pStr, size_t cbSize) -> std::wstring {
466+ if (cbSize < sizeof (size_type) + sizeof (WCHAR )) return L" " ;
467+ const auto length = *(const size_type*)pStr;
468+ if (cbSize < sizeof (size_type) + (length + 1 ) * sizeof (WCHAR )) return L" " ;
469+ return std::wstring (LPCWSTR (pStr + sizeof (size_type) / sizeof (WCHAR )), length);
470+ });
471+ }
472+
473+ } // namespace cxx
0 commit comments