From dc597d70cef7202480eae6708e2142148e09356f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 23 Feb 2024 19:57:58 +0300 Subject: clipboard copy function is able now to copy in multiple formats at a time --- include/m_utils.h | 48 ++++++++- libs/win32/mir_core.lib | Bin 495172 -> 497794 bytes libs/win64/mir_core.lib | Bin 500432 -> 503114 bytes plugins/ChangeKeyboardLayout/src/hook_events.cpp | 4 +- .../ChangeKeyboardLayout/src/text_operations.cpp | 2 +- plugins/Console/src/Console.cpp | 2 +- plugins/CrashDumper/src/crshdmp.cpp | 2 +- plugins/CrashDumper/src/dumper.cpp | 2 +- plugins/FTPFileYM/src/utils.cpp | 2 +- plugins/HTTPServer/src/GuiElements.cpp | 2 +- plugins/HistoryLinkListPlus/src/linklist_dlg.cpp | 2 +- plugins/IEView/src/external_funcs.cpp | 2 +- plugins/Import/src/progress.cpp | 2 +- plugins/MenuItemEx/src/main.cpp | 8 +- plugins/MirOTR/src/options.cpp | 4 +- plugins/Msg_Export/src/FileViewer.cpp | 2 +- plugins/NewStory/src/history_control.cpp | 4 +- plugins/New_GPG/src/options.cpp | 2 +- plugins/New_GPG/src/ui.cpp | 2 +- plugins/Popup/src/popup_wnd2.cpp | 2 +- plugins/ProxySwitch/src/main.cpp | 2 +- plugins/QuickSearch/src/window_misc.cpp | 2 +- plugins/Scriver/src/msgdialog.cpp | 2 +- plugins/SecureIM/src/options.cpp | 2 +- plugins/SendScreenshotPlus/src/CSend.cpp | 2 +- plugins/SimpleStatusMsg/src/awaymsg.cpp | 4 +- plugins/SimpleStatusMsg/src/msgbox.cpp | 2 +- plugins/StatusManager/src/ss_options.cpp | 2 +- plugins/TabSRMM/src/generic_msghandlers.cpp | 2 +- plugins/TabSRMM/src/infopanel.cpp | 4 +- plugins/TabSRMM/src/msgdlgother.cpp | 2 +- plugins/TabSRMM/src/sendlater.cpp | 2 +- protocols/CloudFile/src/utils.cpp | 2 +- protocols/Gadu-Gadu/src/sessions.cpp | 2 +- protocols/JabberG/src/jabber_chat.cpp | 10 +- protocols/JabberG/src/jabber_disco.cpp | 6 +- protocols/JabberG/src/jabber_iqid_muc.cpp | 2 +- protocols/JabberG/src/jabber_userinfo.cpp | 6 +- protocols/Tox/src/tox_options.cpp | 2 +- protocols/Tox/src/tox_profile.cpp | 2 +- src/core/stdmsg/src/msgdialog.cpp | 2 +- src/core/stdpopup/src/yapp_history_dlg.cpp | 2 +- src/core/stduserinfo/src/stdinfo.cpp | 2 +- src/mir_app/src/file.h | 2 +- src/mir_app/src/srmm_log_rtf.cpp | 2 +- src/mir_core/mir_core.vcxproj | 3 + src/mir_core/mir_core.vcxproj.filters | 3 + src/mir_core/src/Windows/clipboard.cpp | 111 +++++++++++++++++++++ src/mir_core/src/Windows/winutil.cpp | 42 -------- src/mir_core/src/mir_core.def | 15 ++- src/mir_core/src/mir_core64.def | 15 ++- 51 files changed, 244 insertions(+), 109 deletions(-) create mode 100644 src/mir_core/src/Windows/clipboard.cpp diff --git a/include/m_utils.h b/include/m_utils.h index 776e087b37..7949e5dc60 100644 --- a/include/m_utils.h +++ b/include/m_utils.h @@ -53,12 +53,50 @@ EXTERN_C MIR_CORE_DLL(void) Utils_OpenUrlW(const wchar_t *pszUrl, bool bOpenInNe ///////////////////////////////////////////////////////////////////////////////////////// // copies a string into clipboard -MIR_CORE_DLL(void) Utils_ClipboardCopy(const char *pszText); -MIR_CORE_DLL(void) Utils_ClipboardCopy(const wchar_t *pszText); +struct MIR_CORE_EXPORT MClipData : public MNonCopyable +{ + const MClipData *m_pNext = 0; -__forceinline void Utils_ClipboardCopyU(const char *p) -{ Utils_ClipboardCopy(Utf2T(p)); -} + MClipData& operator+(const MClipData &); + + virtual void Copy() const = 0; +}; + +struct MIR_CORE_EXPORT MClipAnsi : public MClipData +{ + const char *m_szString; + + explicit MClipAnsi(const char *pszString); + + void Copy() const override; +}; + +struct MIR_CORE_EXPORT MClipUnicode : public MClipData +{ + const wchar_t *m_wszString; + + explicit MClipUnicode(const wchar_t *pwszString); + + void Copy() const override; +}; + +struct MClipUtf8 : public MClipUnicode +{ + explicit MClipUtf8(const char *pszString) : + MClipUnicode(Utf2T(pszString)) + {} +}; + +struct MIR_CORE_EXPORT MClipRtf : public MClipData +{ + const char *m_szString; + + explicit MClipRtf(const char *pszString); + + void Copy() const override; +}; + +MIR_CORE_DLL(void) Utils_ClipboardCopy(const MClipData &pData); ///////////////////////////////////////////////////////////////////////////////////////// // Resizes a dialog by calling a custom routine to move the individual diff --git a/libs/win32/mir_core.lib b/libs/win32/mir_core.lib index 22b9edf2a6..b6102f14f3 100644 Binary files a/libs/win32/mir_core.lib and b/libs/win32/mir_core.lib differ diff --git a/libs/win64/mir_core.lib b/libs/win64/mir_core.lib index 94e213729d..2568657177 100644 Binary files a/libs/win64/mir_core.lib and b/libs/win64/mir_core.lib differ diff --git a/plugins/ChangeKeyboardLayout/src/hook_events.cpp b/plugins/ChangeKeyboardLayout/src/hook_events.cpp index 88e9b0c08d..8dfb4f63ed 100644 --- a/plugins/ChangeKeyboardLayout/src/hook_events.cpp +++ b/plugins/ChangeKeyboardLayout/src/hook_events.cpp @@ -189,7 +189,7 @@ int CALLBACK CKLPopupDlgProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lP case WM_COMMAND: if (HIWORD(wParam) == STN_CLICKED) { if (!IsBadStringPtr(ptszPopupText, MaxTextSize)) - Utils_ClipboardCopy(ptszPopupText); + Utils_ClipboardCopy(MClipUnicode(ptszPopupText)); PUDeletePopup(hWnd); } break; @@ -200,7 +200,7 @@ int CALLBACK CKLPopupDlgProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lP case UM_POPUPACTION: if ((lParam == 0) && (!IsBadStringPtr(ptszPopupText, MaxTextSize))) - Utils_ClipboardCopy(ptszPopupText); + Utils_ClipboardCopy(MClipUnicode(ptszPopupText)); break; case UM_FREEPLUGINDATA: diff --git a/plugins/ChangeKeyboardLayout/src/text_operations.cpp b/plugins/ChangeKeyboardLayout/src/text_operations.cpp index 14d3d56894..4236fc1e67 100644 --- a/plugins/ChangeKeyboardLayout/src/text_operations.cpp +++ b/plugins/ChangeKeyboardLayout/src/text_operations.cpp @@ -424,7 +424,7 @@ int ChangeLayout(HWND hTextWnd, uint8_t TextOperation, BOOL CurrentWord) Skin_PlaySound(SND_ChangeCase); if (moOptions.CopyToClipboard) - Utils_ClipboardCopy(ptszMBox); + Utils_ClipboardCopy(MClipUnicode(ptszMBox)); //-------------------------------Покажем попапы------------------------------------------ if (moOptions.ShowPopup) { diff --git a/plugins/Console/src/Console.cpp b/plugins/Console/src/Console.cpp index d5f63645e5..f463739e9f 100644 --- a/plugins/Console/src/Console.cpp +++ b/plugins/Console/src/Console.cpp @@ -499,7 +499,7 @@ static INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LP } if (dst - buf > 0) - Utils_ClipboardCopy(buf); + Utils_ClipboardCopy(MClipUnicode(buf)); free(buf); break; diff --git a/plugins/CrashDumper/src/crshdmp.cpp b/plugins/CrashDumper/src/crshdmp.cpp index 5f0c12869b..ba611e24d7 100644 --- a/plugins/CrashDumper/src/crshdmp.cpp +++ b/plugins/CrashDumper/src/crshdmp.cpp @@ -92,7 +92,7 @@ INT_PTR StoreVersionInfoToClipboard(WPARAM, LPARAM lParam) PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR | VI_FLAG_FORMAT); WriteBBFile(buffer, false); - Utils_ClipboardCopy(buffer); + Utils_ClipboardCopy(MClipUnicode(buffer)); return 0; } diff --git a/plugins/CrashDumper/src/dumper.cpp b/plugins/CrashDumper/src/dumper.cpp index 86bf2ebf47..afd2fc566c 100644 --- a/plugins/CrashDumper/src/dumper.cpp +++ b/plugins/CrashDumper/src/dumper.cpp @@ -655,5 +655,5 @@ void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const wcha free(dst); if (g_plugin.getByte("ShowCrashMessageBox", 1) && msg && IDYES == MessageBox(nullptr, msg, L"Miranda Crash Dumper", MB_YESNO | MB_ICONERROR | MB_TASKMODAL | MB_DEFBUTTON2 | MB_TOPMOST)) - Utils_ClipboardCopy(buffer); + Utils_ClipboardCopy(MClipUnicode(buffer)); } diff --git a/plugins/FTPFileYM/src/utils.cpp b/plugins/FTPFileYM/src/utils.cpp index b38a095635..49cdd922af 100644 --- a/plugins/FTPFileYM/src/utils.cpp +++ b/plugins/FTPFileYM/src/utils.cpp @@ -64,7 +64,7 @@ wchar_t* Utils::getFileNameFromPath(wchar_t *stzPath) void Utils::copyToClipboard(char *szText) { - Utils_ClipboardCopy(szText); + Utils_ClipboardCopy(MClipAnsi(szText)); } void Utils::curlSetOpt(CURL *hCurl, ServerList::FTP *ftp, char *url, struct curl_slist *headerList, char *errorBuff) diff --git a/plugins/HTTPServer/src/GuiElements.cpp b/plugins/HTTPServer/src/GuiElements.cpp index 4fc36e40f2..56473e795f 100644 --- a/plugins/HTTPServer/src/GuiElements.cpp +++ b/plugins/HTTPServer/src/GuiElements.cpp @@ -888,7 +888,7 @@ static INT_PTR CALLBACK DlgProcStatsticView(HWND hwndDlg, UINT msg, WPARAM wPara return TRUE; if (LOWORD(wParam) == ID_SHARELIST_COPYLINK) - Utils_ClipboardCopy(sLink.c_str()); + Utils_ClipboardCopy(MClipAnsi(sLink.c_str())); else Utils_OpenUrl(sLink.c_str()); } diff --git a/plugins/HistoryLinkListPlus/src/linklist_dlg.cpp b/plugins/HistoryLinkListPlus/src/linklist_dlg.cpp index 269c3d3f48..fcda68205b 100644 --- a/plugins/HistoryLinkListPlus/src/linklist_dlg.cpp +++ b/plugins/HistoryLinkListPlus/src/linklist_dlg.cpp @@ -162,7 +162,7 @@ INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) break; case IDM_LINK_COPY: - Utils_ClipboardCopy(link); + Utils_ClipboardCopy(MClipUnicode(link)); break; case IDM_SHOWMESSAGE: diff --git a/plugins/IEView/src/external_funcs.cpp b/plugins/IEView/src/external_funcs.cpp index 57e4c8f5cf..0809e07afb 100644 --- a/plugins/IEView/src/external_funcs.cpp +++ b/plugins/IEView/src/external_funcs.cpp @@ -203,7 +203,7 @@ namespace External if (p == nullptr || p->cArgs < 1) return E_INVALIDARG; - Utils_ClipboardCopy(p->rgvarg[0].bstrVal); + Utils_ClipboardCopy(MClipUnicode(p->rgvarg[0].bstrVal)); return S_OK; } } diff --git a/plugins/Import/src/progress.cpp b/plugins/Import/src/progress.cpp index 853c075ee7..eabdf13594 100644 --- a/plugins/Import/src/progress.cpp +++ b/plugins/Import/src/progress.cpp @@ -88,7 +88,7 @@ void CProgressPageDlg::OnContextMenu(CCtrlBase*) } } - Utils_ClipboardCopy(wszText); + Utils_ClipboardCopy(MClipUnicode(wszText)); break; } diff --git a/plugins/MenuItemEx/src/main.cpp b/plugins/MenuItemEx/src/main.cpp index 4cbf357fbd..eada043836 100644 --- a/plugins/MenuItemEx/src/main.cpp +++ b/plugins/MenuItemEx/src/main.cpp @@ -428,7 +428,7 @@ static INT_PTR onCopyID(WPARAM hContact, LPARAM) } else buf = wszId; - Utils_ClipboardCopy(buf); + Utils_ClipboardCopy(MClipUnicode(buf)); if (CTRL_IS_PRESSED) ShowPopup(buf, hContact); @@ -464,7 +464,7 @@ static INT_PTR onCopyStatusMsg(WPARAM hContact, LPARAM) } } - Utils_ClipboardCopy(wszBuffer); + Utils_ClipboardCopy(MClipUnicode(wszBuffer)); if (CTRL_IS_PRESSED) ShowPopup(wszBuffer, hContact); @@ -484,7 +484,7 @@ static INT_PTR onCopyIP(WPARAM hContact, LPARAM) if (rIP) wszBuffer.AppendFormat(L"Internal IP: %d.%d.%d.%d\r\n", rIP >> 24, (rIP >> 16) & 0xFF, (rIP >> 8) & 0xFF, rIP & 0xFF); - Utils_ClipboardCopy(wszBuffer); + Utils_ClipboardCopy(MClipUnicode(wszBuffer)); if (CTRL_IS_PRESSED) ShowPopup(wszBuffer, hContact); @@ -495,7 +495,7 @@ static INT_PTR onCopyMirVer(WPARAM hContact, LPARAM) { LPWSTR msg = getMirVer(hContact); if (msg) { - Utils_ClipboardCopy(msg); + Utils_ClipboardCopy(MClipUnicode(msg)); if (CTRL_IS_PRESSED) ShowPopup(msg, hContact); diff --git a/plugins/MirOTR/src/options.cpp b/plugins/MirOTR/src/options.cpp index 8ef718f6ae..1f73e2df08 100644 --- a/plugins/MirOTR/src/options.cpp +++ b/plugins/MirOTR/src/options.cpp @@ -410,7 +410,7 @@ public: if (proto) { char fprint[45]; if (otrl_privkey_fingerprint(otr_user_state, fprint, proto, proto)) - Utils_ClipboardCopy(fprint); + Utils_ClipboardCopy(MClipAnsi(fprint)); } break; @@ -795,7 +795,7 @@ public: case IDM_OPT_COPY: wchar_t hash[45]; otrl_privkey_hash_to_humanT(hash, fp->fingerprint); - Utils_ClipboardCopy(hash); + Utils_ClipboardCopy(MClipUnicode(hash)); break; case IDM_OPT_FINGER_FORGET: diff --git a/plugins/Msg_Export/src/FileViewer.cpp b/plugins/Msg_Export/src/FileViewer.cpp index f6f018936b..1ab7eebdcc 100644 --- a/plugins/Msg_Export/src/FileViewer.cpp +++ b/plugins/Msg_Export/src/FileViewer.cpp @@ -572,7 +572,7 @@ bool bAdvancedCopy(HWND hwnd) pszCurDec++; } pszCurDec[0] = 0; - Utils_ClipboardCopy(pszSrcBuf); + Utils_ClipboardCopy(MClipUnicode(pszSrcBuf)); delete[] pszSrcBuf; return true; } diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index d035320ddb..a9c543a9f8 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.cpp @@ -284,7 +284,7 @@ void NewstoryListData::ClearSelection(int iFirst, int iLast) void NewstoryListData::Copy(bool bTextOnly) { - Utils_ClipboardCopy(GatherSelected(bTextOnly)); + Utils_ClipboardCopy(MClipUnicode(GatherSelected(bTextOnly))); } void NewstoryListData::CopyPath() @@ -293,7 +293,7 @@ void NewstoryListData::CopyPath() if (pItem->completed()) { DB::EventInfo dbei(pItem->hEvent); DB::FILE_BLOB blob(dbei); - Utils_ClipboardCopy(blob.getLocalName()); + Utils_ClipboardCopy(MClipUnicode(blob.getLocalName())); } } diff --git a/plugins/New_GPG/src/options.cpp b/plugins/New_GPG/src/options.cpp index d219fff6bf..53a690aef4 100644 --- a/plugins/New_GPG/src/options.cpp +++ b/plugins/New_GPG/src/options.cpp @@ -449,7 +449,7 @@ public: { CMStringW str(g_plugin.getMStringW("GPGPubKey")); str.Replace(L"\n", L"\r\n"); - Utils_ClipboardCopy(str); + Utils_ClipboardCopy(MClipUnicode(str)); } void onClick_LOG_FILE_SET(CCtrlButton*) diff --git a/plugins/New_GPG/src/ui.cpp b/plugins/New_GPG/src/ui.cpp index fdcfd86195..766978e7e1 100644 --- a/plugins/New_GPG/src/ui.cpp +++ b/plugins/New_GPG/src/ui.cpp @@ -551,7 +551,7 @@ public: return; params.out.Remove('\r'); - Utils_ClipboardCopy(params.out); + Utils_ClipboardCopy(MClipAnsi(params.out)); } void onClick_EXPORT_PRIVATE(CCtrlButton *) diff --git a/plugins/Popup/src/popup_wnd2.cpp b/plugins/Popup/src/popup_wnd2.cpp index 8a4c95ce08..f711ca041d 100644 --- a/plugins/Popup/src/popup_wnd2.cpp +++ b/plugins/Popup/src/popup_wnd2.cpp @@ -952,7 +952,7 @@ LRESULT CALLBACK PopupWnd2::WindowProc(UINT message, WPARAM wParam, LPARAM lPara case ACT_DEF_COPY: if (m_lptzText || m_lptzTitle) { CMStringW tszText(FORMAT, L"%s\n\n%s", (m_lptzTitle) ? m_lptzTitle : L"", (m_lptzText) ? m_lptzText : L""); - Utils_ClipboardCopy(tszText); + Utils_ClipboardCopy(MClipUnicode(tszText)); } PUDeletePopup(m_hwnd); break; diff --git a/plugins/ProxySwitch/src/main.cpp b/plugins/ProxySwitch/src/main.cpp index 3b08113a3a..2db415334a 100644 --- a/plugins/ProxySwitch/src/main.cpp +++ b/plugins/ProxySwitch/src/main.cpp @@ -105,7 +105,7 @@ static INT_PTR CopyIP2Clipboard(WPARAM, LPARAM, LPARAM idx) { mir_cslock lck(csNIF_List); if (g_arNIF[idx].IPcount != 0) - Utils_ClipboardCopy(g_arNIF[idx].IPstr); + Utils_ClipboardCopy(MClipAnsi(g_arNIF[idx].IPstr)); return 0; } diff --git a/plugins/QuickSearch/src/window_misc.cpp b/plugins/QuickSearch/src/window_misc.cpp index a8e8bb32b9..bd377b09dd 100644 --- a/plugins/QuickSearch/src/window_misc.cpp +++ b/plugins/QuickSearch/src/window_misc.cpp @@ -211,7 +211,7 @@ void QSMainDlg::CopyMultiLines() buf.Append(L"\r\n"); } - Utils_ClipboardCopy(buf); + Utils_ClipboardCopy(MClipUnicode(buf)); } void QSMainDlg::DeleteByList() diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index b75ab78c42..145e7500ee 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -354,7 +354,7 @@ void CMsgDialog::onClick_UserMenu(CCtrlButton *pButton) { if (GetKeyState(VK_SHIFT) & 0x8000) { // copy user name ptrW id(Contact::GetInfo(CNF_UNIQUEID, m_hContact, m_szProto)); - Utils_ClipboardCopy(id); + Utils_ClipboardCopy(MClipUnicode(id)); } else { RECT rc; diff --git a/plugins/SecureIM/src/options.cpp b/plugins/SecureIM/src/options.cpp index 9fe86edcda..11092d0729 100644 --- a/plugins/SecureIM/src/options.cpp +++ b/plugins/SecureIM/src/options.cpp @@ -1039,7 +1039,7 @@ static INT_PTR CALLBACK DlgProcOptionsProto(HWND hDlg, UINT wMsg, WPARAM wParam, case IDC_RSA_COPY: wchar_t txt[128]; GetDlgItemTextW(hDlg, IDC_RSA_SHA, txt, _countof(txt)); - Utils_ClipboardCopy(txt); + Utils_ClipboardCopy(MClipUnicode(txt)); return TRUE; case IDC_RSA_EXP: diff --git a/plugins/SendScreenshotPlus/src/CSend.cpp b/plugins/SendScreenshotPlus/src/CSend.cpp index a06829a422..6321215b1d 100644 --- a/plugins/SendScreenshotPlus/src/CSend.cpp +++ b/plugins/SendScreenshotPlus/src/CSend.cpp @@ -165,7 +165,7 @@ INT_PTR CALLBACK CSend::ResultDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, } else len = GetDlgItemText(hwndDlg, edtID, tmp, _countof(tmp)); - Utils_ClipboardCopy(CMStringW(tmp, len + 1)); + Utils_ClipboardCopy(MClipUnicode(CMStringW(tmp, len + 1))); if (LOWORD(wParam) == IDOK) DestroyWindow(hwndDlg); diff --git a/plugins/SimpleStatusMsg/src/awaymsg.cpp b/plugins/SimpleStatusMsg/src/awaymsg.cpp index 612e3d6e19..b4c8474bad 100644 --- a/plugins/SimpleStatusMsg/src/awaymsg.cpp +++ b/plugins/SimpleStatusMsg/src/awaymsg.cpp @@ -117,7 +117,7 @@ public: { wchar_t msg[1024]; GetDlgItemText(m_hwnd, IDC_MSG, msg, _countof(msg)); - Utils_ClipboardCopy(msg); + Utils_ClipboardCopy(MClipUnicode(msg)); } }; @@ -186,7 +186,7 @@ public: CMStringW wszMsg((wchar_t *)ack->lParam); wszMsg.Replace(L"\n", L"\r\n"); - Utils_ClipboardCopy(wszMsg); + Utils_ClipboardCopy(MClipUnicode(wszMsg)); Close(); } diff --git a/plugins/SimpleStatusMsg/src/msgbox.cpp b/plugins/SimpleStatusMsg/src/msgbox.cpp index 6c21e44ef9..fadb35b176 100644 --- a/plugins/SimpleStatusMsg/src/msgbox.cpp +++ b/plugins/SimpleStatusMsg/src/msgbox.cpp @@ -463,7 +463,7 @@ VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, HWND edit_control) default: wchar_t item_string[128]; GetMenuString(hmenu, m_selection, (LPTSTR)&item_string, 128, MF_BYCOMMAND); - Utils_ClipboardCopy(item_string); + Utils_ClipboardCopy(MClipUnicode(item_string)); SendMessage(edit_control, WM_PASTE, 0, 0); break; } diff --git a/plugins/StatusManager/src/ss_options.cpp b/plugins/StatusManager/src/ss_options.cpp index 5274c9f6fb..3f9e37d69b 100644 --- a/plugins/StatusManager/src/ss_options.cpp +++ b/plugins/StatusManager/src/ss_options.cpp @@ -161,7 +161,7 @@ public: { wchar_t cmdl[2048]; GetDlgItemText(m_hwnd, IDC_CMDL, cmdl, _countof(cmdl)); - Utils_ClipboardCopy(cmdl); + Utils_ClipboardCopy(MClipUnicode(cmdl)); } void onClick_Link(CCtrlButton*) diff --git a/plugins/TabSRMM/src/generic_msghandlers.cpp b/plugins/TabSRMM/src/generic_msghandlers.cpp index 51a81a5bdf..030053400e 100644 --- a/plugins/TabSRMM/src/generic_msghandlers.cpp +++ b/plugins/TabSRMM/src/generic_msghandlers.cpp @@ -211,7 +211,7 @@ LRESULT CMsgDialog::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lPara case IDC_NAME: if (GetKeyState(VK_SHIFT) & 0x8000) // copy UIN - Utils_ClipboardCopy(m_cache->getUIN()); + Utils_ClipboardCopy(MClipUnicode(m_cache->getUIN())); else CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)(m_cache->getActiveContact()), 0); break; diff --git a/plugins/TabSRMM/src/infopanel.cpp b/plugins/TabSRMM/src/infopanel.cpp index 38bf1ffbe1..2704436c87 100644 --- a/plugins/TabSRMM/src/infopanel.cpp +++ b/plugins/TabSRMM/src/infopanel.cpp @@ -739,11 +739,11 @@ LRESULT CInfoPanel::cmdHandler(UINT cmd) switch (cmd) { case CMD_IP_COPY: if (m_hoverFlags & HOVER_NICK) { - Utils_ClipboardCopy(m_dat->m_cache->getNick()); + Utils_ClipboardCopy(MClipUnicode(m_dat->m_cache->getNick())); return(S_OK); } if (m_hoverFlags & HOVER_UIN) { - Utils_ClipboardCopy(m_isChat ? m_dat->m_si->ptszTopic : m_dat->m_cache->getUIN()); + Utils_ClipboardCopy(MClipUnicode(m_isChat ? m_dat->m_si->ptszTopic : m_dat->m_cache->getUIN())); return(S_OK); } break; diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp index 4f8d7cbdf5..2d9bd9b669 100644 --- a/plugins/TabSRMM/src/msgdlgother.cpp +++ b/plugins/TabSRMM/src/msgdlgother.cpp @@ -3029,7 +3029,7 @@ LRESULT CMsgDialog::WMCopyHandler(UINT msg, WPARAM wParam, LPARAM lParam) ptrW converted(mir_utf8decodeW(szFromStream)); if (converted != nullptr) { Utils::FilterEventMarkers(converted); - Utils_ClipboardCopy(converted); + Utils_ClipboardCopy(MClipUnicode(converted)); } } diff --git a/plugins/TabSRMM/src/sendlater.cpp b/plugins/TabSRMM/src/sendlater.cpp index 342dc7b06f..cfea821386 100644 --- a/plugins/TabSRMM/src/sendlater.cpp +++ b/plugins/TabSRMM/src/sendlater.cpp @@ -443,7 +443,7 @@ public: job->writeFlags(); break; case ID_QUEUEMANAGER_COPYMESSAGETOCLIPBOARD: - Utils_ClipboardCopy(ptrW(mir_utf8decodeW(job->sendBuffer))); + Utils_ClipboardCopy(MClipUnicode(ptrW(mir_utf8decodeW(job->sendBuffer)))); break; case ID_QUEUEMANAGER_RESETSELECTED: if (job->bCode == CSendLaterJob::JOB_DEFERRED) { diff --git a/protocols/CloudFile/src/utils.cpp b/protocols/CloudFile/src/utils.cpp index d241918c2f..755746f197 100644 --- a/protocols/CloudFile/src/utils.cpp +++ b/protocols/CloudFile/src/utils.cpp @@ -91,5 +91,5 @@ void Report(MCONTACT hContact, const wchar_t *data) PasteToInputArea(hContact, data); if (g_plugin.getByte("UrlCopyToClipboard", 0)) - Utils_ClipboardCopy(data); + Utils_ClipboardCopy(MClipUnicode(data)); } diff --git a/protocols/Gadu-Gadu/src/sessions.cpp b/protocols/Gadu-Gadu/src/sessions.cpp index 080882053e..c9664a726f 100644 --- a/protocols/Gadu-Gadu/src/sessions.cpp +++ b/protocols/Gadu-Gadu/src/sessions.cpp @@ -324,7 +324,7 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w ListView_GetItemText(hList, lvhti.iItem, 1, szIP, _countof(szIP)); ListView_GetItemText(hList, lvhti.iItem, 2, szLoginTime, _countof(szLoginTime)); mir_snwprintf(szText, L"%s\t%s\t%s", szClientName, szIP, szLoginTime); - Utils_ClipboardCopy(szText); + Utils_ClipboardCopy(MClipUnicode(szText)); } break; diff --git a/protocols/JabberG/src/jabber_chat.cpp b/protocols/JabberG/src/jabber_chat.cpp index 8e88a86346..b61953a9ca 100644 --- a/protocols/JabberG/src/jabber_chat.cpp +++ b/protocols/JabberG/src/jabber_chat.cpp @@ -1125,16 +1125,16 @@ static void sttNickListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK* break; case IDM_CPY_NICK: - Utils_ClipboardCopyU(him->m_szResourceName); + Utils_ClipboardCopy(MClipUtf8(him->m_szResourceName)); break; case IDM_RJID_COPY: case IDM_CPY_RJID: - Utils_ClipboardCopyU(him->m_szRealJid); + Utils_ClipboardCopy(MClipUtf8(him->m_szRealJid)); break; case IDM_CPY_INROOMJID: - Utils_ClipboardCopyU(MakeJid(item->jid, him->m_szResourceName)); + Utils_ClipboardCopy(MClipUtf8(MakeJid(item->jid, him->m_szResourceName))); break; case IDM_RJID_VCARD: @@ -1299,11 +1299,11 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK *g break; case IDM_CPY_RJID: - Utils_ClipboardCopyU(item->jid); + Utils_ClipboardCopy(MClipUtf8(item->jid)); break; case IDM_CPY_TOPIC: - Utils_ClipboardCopyU(item->getTemp()->m_szStatusMessage); + Utils_ClipboardCopy(MClipUtf8(item->getTemp()->m_szStatusMessage)); break; } } diff --git a/protocols/JabberG/src/jabber_disco.cpp b/protocols/JabberG/src/jabber_disco.cpp index fbca7ba7e2..709ca45e72 100644 --- a/protocols/JabberG/src/jabber_disco.cpp +++ b/protocols/JabberG/src/jabber_disco.cpp @@ -1054,15 +1054,15 @@ public: break; case SD_ACT_COPYJID: - Utils_ClipboardCopyU(pNode->GetJid()); + Utils_ClipboardCopy(MClipUtf8(pNode->GetJid())); break; case SD_ACT_COPYNODE: - Utils_ClipboardCopyU(pNode->GetNode()); + Utils_ClipboardCopy(MClipUtf8(pNode->GetNode())); break; case SD_ACT_COPYINFO: - Utils_ClipboardCopyU(pNode->GetTooltipText()); + Utils_ClipboardCopy(MClipUtf8(pNode->GetTooltipText())); break; case SD_ACT_FAVORITE: diff --git a/protocols/JabberG/src/jabber_iqid_muc.cpp b/protocols/JabberG/src/jabber_iqid_muc.cpp index 9b41da8414..ba0c9622aa 100644 --- a/protocols/JabberG/src/jabber_iqid_muc.cpp +++ b/protocols/JabberG/src/jabber_iqid_muc.cpp @@ -335,7 +335,7 @@ public: if (TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_BOTTOMALIGN, pos->pt.x, pos->pt.y, 0, m_hwnd, nullptr)) { wchar_t buf[JABBER_MAX_JID_LEN]; m_list.GetItemText(pos->iCurr, 0, buf, _countof(buf)); - Utils_ClipboardCopy(buf); + Utils_ClipboardCopy(MClipUnicode(buf)); } DestroyMenu(hMenu); diff --git a/protocols/JabberG/src/jabber_userinfo.cpp b/protocols/JabberG/src/jabber_userinfo.cpp index a6017785c0..25325165d2 100644 --- a/protocols/JabberG/src/jabber_userinfo.cpp +++ b/protocols/JabberG/src/jabber_userinfo.cpp @@ -483,7 +483,7 @@ public: if (nReturnCmd == 1) { CMStringW buf; GetNodeText(pos->hItem, buf); - Utils_ClipboardCopy(buf); + Utils_ClipboardCopy(MClipUnicode(buf)); } else if (nReturnCmd == 2) { wchar_t szBuffer[1024]; @@ -494,9 +494,9 @@ public: tvi.pszText = szBuffer; if (m_tree.GetItem(&tvi)) { if (wchar_t *str = wcsstr(szBuffer, L": ")) - Utils_ClipboardCopy(str + 2); + Utils_ClipboardCopy(MClipUnicode(str + 2)); else - Utils_ClipboardCopy(szBuffer); + Utils_ClipboardCopy(MClipUnicode(szBuffer)); } } DestroyMenu(hMenu); diff --git a/protocols/Tox/src/tox_options.cpp b/protocols/Tox/src/tox_options.cpp index 330872e6f2..345e5e6c81 100644 --- a/protocols/Tox/src/tox_options.cpp +++ b/protocols/Tox/src/tox_options.cpp @@ -95,7 +95,7 @@ void CToxOptionsMain::EnableUdp_OnClick(CCtrlBase*) void CToxOptionsMain::ToxAddressCopy_OnClick(CCtrlButton*) { - Utils_ClipboardCopy(ptrW(m_toxAddress.GetText())); + Utils_ClipboardCopy(MClipUnicode(ptrW(m_toxAddress.GetText()))); } void CToxOptionsMain::ProfileCreate_OnClick(CCtrlButton*) diff --git a/protocols/Tox/src/tox_profile.cpp b/protocols/Tox/src/tox_profile.cpp index d6b53fb0e9..92b6104e89 100644 --- a/protocols/Tox/src/tox_profile.cpp +++ b/protocols/Tox/src/tox_profile.cpp @@ -186,7 +186,7 @@ void CToxProto::OnErase() INT_PTR CToxProto::OnCopyToxID(WPARAM, LPARAM) { - Utils_ClipboardCopy(ptrW(getWStringA(TOX_SETTINGS_ID))); + Utils_ClipboardCopy(MClipUnicode(ptrW(getWStringA(TOX_SETTINGS_ID)))); return 0; } diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index 6f17354162..5b808c4ee9 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -662,7 +662,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_USERMENU: if (GetKeyState(VK_SHIFT) & 0x8000) { // copy user name ptrW id(Contact::GetInfo(CNF_UNIQUEID, m_hContact, m_szProto)); - Utils_ClipboardCopy(id); + Utils_ClipboardCopy(MClipUnicode(id)); } else { HMENU hMenu = Menu_BuildContactMenu(m_hContact); diff --git a/src/core/stdpopup/src/yapp_history_dlg.cpp b/src/core/stdpopup/src/yapp_history_dlg.cpp index dc6a5775ad..8b6e1b7506 100644 --- a/src/core/stdpopup/src/yapp_history_dlg.cpp +++ b/src/core/stdpopup/src/yapp_history_dlg.cpp @@ -422,7 +422,7 @@ void CopyPopupDataToClipboard(HWND hList, int selection) if (ListView_GetItemState(hList, i, LVIS_SELECTED)) { wchar_t buffer[2048]; buffer[0] = '\0'; ListView_GetItemText(hList, i, selection - 100, buffer, _countof(buffer)); - Utils_ClipboardCopy(buffer); + Utils_ClipboardCopy(MClipUnicode(buffer)); break; } } diff --git a/src/core/stduserinfo/src/stdinfo.cpp b/src/core/stduserinfo/src/stdinfo.cpp index b2fed06847..a2a72e1d80 100644 --- a/src/core/stduserinfo/src/stdinfo.cpp +++ b/src/core/stduserinfo/src/stdinfo.cpp @@ -130,7 +130,7 @@ public: { wchar_t buf[1024]; if (GetDlgItemText(m_hwnd, IDC_ADDR, buf, _countof(buf))) - Utils_ClipboardCopy(buf); + Utils_ClipboardCopy(MClipUnicode(buf)); } int Resizer(UTILRESIZECONTROL *urc) override diff --git a/src/mir_app/src/file.h b/src/mir_app/src/file.h index 01b7b47fab..677222615e 100644 --- a/src/mir_app/src/file.h +++ b/src/mir_app/src/file.h @@ -145,7 +145,7 @@ struct OFD_CopyUrl : public OFD_Callback void Invoke(const OFDTHREAD &ofd) override { - Utils_ClipboardCopy(ofd.wszPath.IsEmpty() ? wszUrl : ofd.wszPath); + Utils_ClipboardCopy(MClipUnicode(ofd.wszPath.IsEmpty() ? wszUrl : ofd.wszPath)); } }; diff --git a/src/mir_app/src/srmm_log_rtf.cpp b/src/mir_app/src/srmm_log_rtf.cpp index 6b81c438d0..709d173c74 100644 --- a/src/mir_app/src/srmm_log_rtf.cpp +++ b/src/mir_app/src/srmm_log_rtf.cpp @@ -278,7 +278,7 @@ INT_PTR CRtfLogWindow::Notify(WPARAM, LPARAM lParam) break; case IDM_COPYLINK: - Utils_ClipboardCopy(wszText); + Utils_ClipboardCopy(MClipUnicode(wszText)); break; } diff --git a/src/mir_core/mir_core.vcxproj b/src/mir_core/mir_core.vcxproj index 5926603bf0..fa4f5b08c3 100644 --- a/src/mir_core/mir_core.vcxproj +++ b/src/mir_core/mir_core.vcxproj @@ -125,6 +125,9 @@ ../stdafx.h + + ../stdafx.h + ../stdafx.h diff --git a/src/mir_core/mir_core.vcxproj.filters b/src/mir_core/mir_core.vcxproj.filters index 1b936d0685..1ead550a86 100644 --- a/src/mir_core/mir_core.vcxproj.filters +++ b/src/mir_core/mir_core.vcxproj.filters @@ -185,6 +185,9 @@ Source Files\Windows + + Source Files\Windows + diff --git a/src/mir_core/src/Windows/clipboard.cpp b/src/mir_core/src/Windows/clipboard.cpp new file mode 100644 index 0000000000..13c52a5c44 --- /dev/null +++ b/src/mir_core/src/Windows/clipboard.cpp @@ -0,0 +1,111 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "../stdafx.h" + +static UINT g_iRtf = 0; + +MClipAnsi::MClipAnsi(const char *pszString) : + m_szString(pszString) +{} + +void MClipAnsi::Copy() const +{ + size_t cbLen = mir_strlen(m_szString); + if (!cbLen) + return; + + HGLOBAL hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, cbLen + 1); + if (hData) { + mir_strcpy((char *)GlobalLock(hData), m_szString); + GlobalUnlock(hData); + SetClipboardData(CF_TEXT, hData); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MClipRtf::MClipRtf(const char *pszString) : + m_szString(pszString) +{} + +void MClipRtf::Copy() const +{ + size_t cbLen = mir_strlen(m_szString); + if (!cbLen) + return; + + if (g_iRtf == 0) + g_iRtf = RegisterClipboardFormatW(CF_RTF); + + HGLOBAL hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, cbLen + 1); + if (hData) { + mir_strcpy((char *)GlobalLock(hData), m_szString); + GlobalUnlock(hData); + SetClipboardData(g_iRtf, hData); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MClipUnicode::MClipUnicode(const wchar_t *pwszString) : + m_wszString(pwszString) +{} + +void MClipUnicode::Copy() const +{ + size_t cbLen = mir_wstrlen(m_wszString); + if (!cbLen) + return; + + HGLOBAL hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (cbLen + 1) * sizeof(wchar_t)); + if (hData) { + mir_wstrcpy((wchar_t *)GlobalLock(hData), m_wszString); + GlobalUnlock(hData); + SetClipboardData(CF_UNICODETEXT, hData); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MClipData& MClipData::operator+(const MClipData &p2) +{ + m_pNext = &p2; + return *this; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(void) Utils_ClipboardCopy(const MClipData &pData) +{ + if (!OpenClipboard(nullptr)) + return; + + EmptyClipboard(); + + for (const MClipData *p = &pData; p; p = p->m_pNext) + p->Copy(); + + CloseClipboard(); +} diff --git a/src/mir_core/src/Windows/winutil.cpp b/src/mir_core/src/Windows/winutil.cpp index b0bdc915ee..6320622ada 100644 --- a/src/mir_core/src/Windows/winutil.cpp +++ b/src/mir_core/src/Windows/winutil.cpp @@ -133,45 +133,3 @@ MIR_CORE_DLL(int) Utils_CorrectFontSize(int size) return size * ncm.lfMessageFont.lfHeight / -12; } - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(void) Utils_ClipboardCopy(const char *pszText) -{ - size_t cbLen = mir_strlen(pszText); - if (!cbLen) - return; - - if (!OpenClipboard(nullptr)) - return; - - EmptyClipboard(); - - HGLOBAL hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, cbLen+1); - if (hData) { - mir_strcpy((char *)GlobalLock(hData), pszText); - GlobalUnlock(hData); - SetClipboardData(CF_TEXT, hData); - } - CloseClipboard(); -} - -MIR_CORE_DLL(void) Utils_ClipboardCopy(const wchar_t *pwszText) -{ - size_t cbLen = mir_wstrlen(pwszText); - if (!cbLen) - return; - - if (!OpenClipboard(nullptr)) - return; - - EmptyClipboard(); - - HGLOBAL hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (cbLen + 1) * sizeof(wchar_t)); - if (hData) { - mir_wstrcpy((wchar_t *)GlobalLock(hData), pwszText); - GlobalUnlock(hData); - SetClipboardData(CF_UNICODETEXT, hData); - } - CloseClipboard(); -} diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def index 66d2dda017..dc56ef8ee3 100644 --- a/src/mir_core/src/mir_core.def +++ b/src/mir_core/src/mir_core.def @@ -1539,8 +1539,7 @@ _Utils_CorrectFontSize@4 @1762 NONAME ?OnResize@CDlgBase@@MAEXXZ @1763 NONAME ??0MBinBuffer@@QAE@ABV0@@Z @1764 NONAME ??0MBinBuffer@@QAE@I@Z @1765 NONAME -?Utils_ClipboardCopy@@YGXPBD@Z @1766 NONAME -?Utils_ClipboardCopy@@YGXPB_W@Z @1767 NONAME +?Utils_ClipboardCopy@@YGXABUMClipData@@@Z @1766 NONAME ?mir_base64_encode@@YGPADABVMBinBuffer@@@Z @1768 NONAME ?append@MBinBuffer@@QAEXABV1@@Z @1769 NONAME ?appendBefore@MBinBuffer@@QAEXABV1@@Z @1770 NONAME @@ -1565,3 +1564,15 @@ _EventExists@4 @1787 NONAME _newStr@4 @1789 NONAME ?ChildElementCount@XMLNode@tinyxml2@@QBEHPBD@Z @1790 NONAME ?ChildElementCount@XMLNode@tinyxml2@@QBEHXZ @1791 NONAME +??0MClipAnsi@@QAE@PBD@Z @1792 NONAME +??0MClipData@@QAE@XZ @1793 NONAME +??0MClipRtf@@QAE@PBD@Z @1794 NONAME +??0MClipUnicode@@QAE@PB_W@Z @1795 NONAME +??HMClipData@@QAEAAU0@ABU0@@Z @1796 NONAME +??_7MClipAnsi@@6B@ @1797 NONAME +??_7MClipData@@6B@ @1798 NONAME +??_7MClipRtf@@6B@ @1799 NONAME +??_7MClipUnicode@@6B@ @1800 NONAME +?Copy@MClipAnsi@@UBEXXZ @1801 NONAME +?Copy@MClipRtf@@UBEXXZ @1802 NONAME +?Copy@MClipUnicode@@UBEXXZ @1803 NONAME diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def index 061063c7d1..7d9885b02d 100644 --- a/src/mir_core/src/mir_core64.def +++ b/src/mir_core/src/mir_core64.def @@ -1539,8 +1539,7 @@ Utils_CorrectFontSize @1762 NONAME ?OnResize@CDlgBase@@MEAAXXZ @1763 NONAME ??0MBinBuffer@@QEAA@AEBV0@@Z @1764 NONAME ??0MBinBuffer@@QEAA@_K@Z @1765 NONAME -?Utils_ClipboardCopy@@YAXPEBD@Z @1766 NONAME -?Utils_ClipboardCopy@@YAXPEB_W@Z @1767 NONAME +?Utils_ClipboardCopy@@YAXAEBUMClipData@@@Z @1766 NONAME ?mir_base64_encode@@YAPEADAEBVMBinBuffer@@@Z @1768 NONAME ?append@MBinBuffer@@QEAAXAEBV1@@Z @1769 NONAME ?appendBefore@MBinBuffer@@QEAAXAEBV1@@Z @1770 NONAME @@ -1565,3 +1564,15 @@ EventExists @1787 NONAME newStr @1789 NONAME ?ChildElementCount@XMLNode@tinyxml2@@QEBAHPEBD@Z @1790 NONAME ?ChildElementCount@XMLNode@tinyxml2@@QEBAHXZ @1791 NONAME +??0MClipAnsi@@QEAA@PEBD@Z @1792 NONAME +??0MClipData@@QEAA@XZ @1793 NONAME +??0MClipRtf@@QEAA@PEBD@Z @1794 NONAME +??0MClipUnicode@@QEAA@PEB_W@Z @1795 NONAME +??HMClipData@@QEAAAEAU0@AEBU0@@Z @1796 NONAME +??_7MClipAnsi@@6B@ @1797 NONAME +??_7MClipData@@6B@ @1798 NONAME +??_7MClipRtf@@6B@ @1799 NONAME +??_7MClipUnicode@@6B@ @1800 NONAME +?Copy@MClipAnsi@@UEBAXXZ @1801 NONAME +?Copy@MClipRtf@@UEBAXXZ @1802 NONAME +?Copy@MClipUnicode@@UEBAXXZ @1803 NONAME -- cgit v1.2.3