summaryrefslogtreecommitdiff
path: root/plugins/SendScreenshotPlus/src
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2023-01-02 21:10:29 +0300
committerdartraiden <wowemuh@gmail.com>2023-01-02 21:10:29 +0300
commit1979fd80424d16b2e489f9b57d01d9c7811d25a2 (patch)
tree960d42c5fe4a51f0fe2850bea91256e226bce221 /plugins/SendScreenshotPlus/src
parentadfbbb217d4f4a05acf198755f219a5223d31c27 (diff)
Update copyrights
Diffstat (limited to 'plugins/SendScreenshotPlus/src')
-rw-r--r--plugins/SendScreenshotPlus/src/CSend.cpp1226
-rw-r--r--plugins/SendScreenshotPlus/src/CSend.h274
-rw-r--r--plugins/SendScreenshotPlus/src/CSendCloduFile.h100
-rw-r--r--plugins/SendScreenshotPlus/src/CSendCloudFile.cpp156
-rw-r--r--plugins/SendScreenshotPlus/src/CSendEmail.cpp402
-rw-r--r--plugins/SendScreenshotPlus/src/CSendEmail.h106
-rw-r--r--plugins/SendScreenshotPlus/src/CSendFTPFile.cpp186
-rw-r--r--plugins/SendScreenshotPlus/src/CSendFTPFile.h96
-rw-r--r--plugins/SendScreenshotPlus/src/CSendFile.cpp100
-rw-r--r--plugins/SendScreenshotPlus/src/CSendFile.h86
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHTTPServer.cpp234
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHTTPServer.h110
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp236
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h98
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp172
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_imgur.h60
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp210
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h60
-rw-r--r--plugins/SendScreenshotPlus/src/Main.cpp672
-rw-r--r--plugins/SendScreenshotPlus/src/UMainForm.cpp2248
-rw-r--r--plugins/SendScreenshotPlus/src/UMainForm.h292
-rw-r--r--plugins/SendScreenshotPlus/src/Utils.cpp824
-rw-r--r--plugins/SendScreenshotPlus/src/Utils.h146
-rw-r--r--plugins/SendScreenshotPlus/src/ctrl_button.h66
-rw-r--r--plugins/SendScreenshotPlus/src/dlg_msgbox.cpp1428
-rw-r--r--plugins/SendScreenshotPlus/src/dlg_msgbox.h2
-rw-r--r--plugins/SendScreenshotPlus/src/stdafx.cxx2
-rw-r--r--plugins/SendScreenshotPlus/src/stdafx.h372
28 files changed, 4982 insertions, 4982 deletions
diff --git a/plugins/SendScreenshotPlus/src/CSend.cpp b/plugins/SendScreenshotPlus/src/CSend.cpp
index 5a5e72e03e..3e83d4b6c6 100644
--- a/plugins/SendScreenshotPlus/src/CSend.cpp
+++ b/plugins/SendScreenshotPlus/src/CSend.cpp
@@ -1,613 +1,613 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-#define CSEND_DIALOG 8800
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSend::CSend(HWND /*Owner*/, MCONTACT hContact, bool bAsync, bool bSilent) :
- m_bDeleteAfterSend(false),
- m_bAsync(bAsync),
- m_bSilent(bSilent),
- m_pszFile(nullptr),
- m_pszFileDesc(nullptr),
- m_pszSendTyp(nullptr),
- m_pszProto(nullptr),
- m_EnableItem(0),
- m_ChatRoom(0),
- m_cbEventMsg(0),
- m_hSend(nullptr),
- m_hOnSend(nullptr),
- m_ErrorMsg(nullptr),
- m_ErrorTitle(nullptr)
-{
- SetContact(hContact);
-}
-
-CSend::~CSend()
-{
- mir_free(m_pszFile);
- mir_free(m_pszFileDesc);
- mir_free(m_ErrorMsg);
- mir_free(m_ErrorTitle);
- if (m_hOnSend) UnhookEvent(m_hOnSend);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CSend::SetContact(MCONTACT hContact)
-{
- m_hContact = hContact;
- if (hContact) {
- m_pszProto = Proto_GetBaseAccountName(hContact);
- m_ChatRoom = Contact::IsGroupChat(hContact, m_pszProto);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR CALLBACK CSend::ResultDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- Window_SetIcon_IcoLib(hwndDlg, GetIconHandle(ICO_MAIN));
- {
- CSend *self = (CSend*)lParam;
- SetDlgItemText(hwndDlg, IDC_HEADERBAR, CMStringW(TranslateT("Resulting URL from\n")) + self->m_pszSendTyp);
-
- SendDlgItemMessage(hwndDlg, IDC_HEADERBAR, WM_SETICON, ICON_BIG, (LPARAM)GetIconBtn(ICO_BTN_ARROWR));
- SetDlgItemTextA(hwndDlg, ID_edtURL, self->m_URL);
- if (self->m_URLthumb) {
- SetDlgItemTextA(hwndDlg, ID_edtURLthumb, self->m_URLthumb);
- }
- else {
- SetDlgItemTextA(hwndDlg, ID_edtURLthumb, "-");
- for (int i = ID_btnThumbCopy; i <= ID_edtURLthumb; ++i) {
- EnableWindow(GetDlgItem(hwndDlg, i), FALSE);
- }
- }
- if (!self->m_pszFileDesc)
- SetDlgItemText(hwndDlg, ID_bvlDesc, self->m_ErrorTitle);
- else
- SetDlgItemText(hwndDlg, ID_bvlDesc, self->m_pszFileDesc);
- SendDlgItemMessage(hwndDlg, IDOK, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_COPY));
- SendDlgItemMessage(hwndDlg, IDOK, BUTTONTRANSLATE, 0, 0);
- SendDlgItemMessage(hwndDlg, IDCANCEL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_CANCEL));
- SendDlgItemMessage(hwndDlg, IDCANCEL, BUTTONTRANSLATE, 0, 0);
- for (int i = ID_btnCopy; i <= ID_btnThumbBBC2; ++i) {
- SendDlgItemMessage(hwndDlg, i, BUTTONSETASTHEMEDBTN, 0, 0);
- SendDlgItemMessage(hwndDlg, i, BUTTONSETASFLATBTN, 1, 0);
- switch (i) {
- case ID_btnCopy:
- case ID_btnThumbCopy:
- SendDlgItemMessage(hwndDlg, i, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_COPY));
- SendDlgItemMessage(hwndDlg, i, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Copy"), BATF_UNICODE);
- break;
- case ID_btnBBC:
- case ID_btnThumbBBC:
- SendDlgItemMessage(hwndDlg, i, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_BBC));
- SendDlgItemMessage(hwndDlg, i, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Copy BBCode"), BATF_UNICODE);
- break;
- default:
- SendDlgItemMessage(hwndDlg, i, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_BBCLNK));
- SendDlgItemMessage(hwndDlg, i, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Copy BBCode w/ link"), BATF_UNICODE);
- }
- }
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- DestroyWindow(hwndDlg);
- return TRUE;
-
- case IDOK:
- case ID_btnCopy:
- case ID_btnThumbCopy:
- case ID_btnBBC:
- case ID_btnThumbBBC:
- case ID_btnThumbBBC2:
- wchar_t tmp[2048];
- int edtID = ID_edtURL;
- int bbc = 0;
- switch (LOWORD(wParam)) {
- case ID_btnThumbBBC2: ++bbc;
- case ID_btnThumbBBC: ++bbc;
- case ID_btnThumbCopy:
- edtID = ID_edtURLthumb;
- break;
- case ID_btnBBC: ++bbc;
- break;
- }
- size_t len;
- if (bbc) {
- if (bbc == 1) {
- memcpy(tmp, L"[img]", 5 * sizeof(wchar_t)); len = 5;
- len += GetDlgItemText(hwndDlg, edtID, tmp + len, 2048 - 11);
- memcpy(tmp + len, L"[/img]", 7 * sizeof(wchar_t)); len += 7;
- }
- else {
- memcpy(tmp, L"[url=", 5 * sizeof(wchar_t)); len = 5;
- len += GetDlgItemText(hwndDlg, ID_edtURL, tmp + len, 1024);
- memcpy(tmp + len, L"][img]", 6 * sizeof(wchar_t)); len += 6;
- len += GetDlgItemText(hwndDlg, edtID, tmp + len, 1024);
- memcpy(tmp + len, L"[/img][/url]", 13 * sizeof(wchar_t)); len += 12;
- }
- }
- else len = GetDlgItemText(hwndDlg, edtID, tmp, _countof(tmp));
-
- Utils_ClipboardCopy(CMStringW(tmp, len + 1));
-
- if (LOWORD(wParam) == IDOK)
- DestroyWindow(hwndDlg);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void CSend::svcSendMsgExit(const char* szMessage)
-{
- if (m_bSilent) {
- Exit(ACKRESULT_SUCCESS); return;
- }
- if (!m_hContact) {
- if (!m_pszFileDesc)
- m_pszFileDesc = mir_a2u(szMessage);
- Exit(CSEND_DIALOG); return;
- }
-
- if (m_ChatRoom) {
- CMStringW tmp(szMessage);
- if (m_pszFileDesc) {
- tmp.Append(L"\r\n");
- tmp.Append(m_pszFileDesc);
- }
-
- int res = GC_RESULT_NOSESSION;
- int cnt = g_chatApi.SM_GetCount(m_pszProto);
-
- // loop on all gc session to get the right (save) ptszID for the chatroom from m_hContact
- GC_INFO gci = { 0 };
- gci.pszModule = m_pszProto;
- for (int i = 0; i < cnt; i++) {
- gci.iItem = i;
- gci.Flags = GCF_BYINDEX | GCF_HCONTACT | GCF_ID;
- Chat_GetInfo(&gci);
- if (gci.hContact == m_hContact) {
- Chat_SendUserMessage(m_pszProto, gci.pszID, tmp);
- res = 200;
- break;
- }
- }
- Exit(res); return;
- }
- else {
- m_szEventMsg = szMessage;
- if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
- m_szEventMsg.Append("\r\n");
- m_szEventMsg.Append(_T2A(m_pszFileDesc));
- m_cbEventMsg = m_szEventMsg.GetLength() + 1;
- }
-
- // create a HookEventObj on ME_PROTO_ACK
- if (!m_hOnSend)
- m_hOnSend = HookEventObj(ME_PROTO_ACK, OnSend, this);
-
- // start PSS_MESSAGE service
- m_hSend = (HANDLE)ProtoChainSend(m_hContact, PSS_MESSAGE, NULL, ptrA(mir_utf8encode(m_szEventMsg)));
-
- // check we actually got an ft handle back from the protocol
- if (!m_hSend) {
- Unhook();
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED); return;
- }
- }
-}
-
-void CSend::svcSendFileExit()
-{
- // szMessage should be encoded as the File followed by the description, the
- // separator being a single nul (\0). If there is no description, do not forget
- // to end the File with two nuls.
- if (m_bSilent) {
- Exit(ACKRESULT_SUCCESS); return;
- }
-
- if (!m_hContact) {
- Error(LPGENW("%s requires a valid contact!"), m_pszSendTyp);
- Exit(ACKRESULT_FAILED); return;
- }
-
- m_szEventMsg = _T2A(m_pszFile);
-
- if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
- m_szEventMsg.AppendChar(0);
- m_szEventMsg.Append(_T2A(m_pszFileDesc));
- }
-
- m_cbEventMsg = m_szEventMsg.GetLength() + 1;
-
- // Сreate a HookEventObj on ME_PROTO_ACK
- if (!m_hOnSend) {
- m_hOnSend = HookEventObj(ME_PROTO_ACK, OnSend, this);
- }
-
- // Start miranda PSS_FILE based on mir ver (T)
- wchar_t* ppFile[2] = { nullptr, nullptr };
- wchar_t* pDesc = mir_wstrdup(m_pszFileDesc);
- ppFile[0] = mir_wstrdup(m_pszFile);
- ppFile[1] = nullptr;
- m_hSend = (HANDLE)ProtoChainSend(m_hContact, PSS_FILE, (WPARAM)pDesc, (LPARAM)ppFile);
- mir_free(pDesc);
- mir_free(ppFile[0]);
-
- // check we actually got an ft handle back from the protocol
- if (!m_hSend) {
- Unhook();
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED); return;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSend::OnSend(void *obj, WPARAM, LPARAM lParam)
-{
- CSend* self = (CSend*)obj;
- ACKDATA *ack = (ACKDATA*)lParam;
- if (ack->hProcess != self->m_hSend)
- return 0;
-
- switch (ack->result) {
- case ACKRESULT_INITIALISING: // SetFtStatus(hwndDlg, LPGENW("Initialising..."), FTS_TEXT); break;
- case ACKRESULT_CONNECTING: // SetFtStatus(hwndDlg, LPGENW("Connecting..."), FTS_TEXT); break;
- case ACKRESULT_CONNECTPROXY: // SetFtStatus(hwndDlg, LPGENW("Connecting to proxy..."), FTS_TEXT); break;
- case ACKRESULT_LISTENING: // SetFtStatus(hwndDlg, LPGENW("Waiting for connection..."), FTS_TEXT); break;
- case ACKRESULT_CONNECTED: // SetFtStatus(hwndDlg, LPGENW("Connected"), FTS_TEXT); break;
- case ACKRESULT_SENTREQUEST: // SetFtStatus(hwndDlg, LPGENW("Decision sent"), FTS_TEXT); break;
- case ACKRESULT_NEXTFILE: // SetFtStatus(hwndDlg, LPGENW("Moving to next file..."), FTS_TEXT);
- case ACKRESULT_FILERESUME:
- case ACKRESULT_DATA: // transfer is on progress
- break;
- case ACKRESULT_DENIED:
- self->Unhook();
- self->Exit(ack->result);
- break;
- case ACKRESULT_FAILED:
- self->Unhook();
- self->Exit(ack->result);
- // type=ACKTYPE_MESSAGE, result=success/failure, (char*)lParam=error message or NULL.
- // type=ACKTYPE_FILE, result=ACKRESULT_FAILED then lParam=(LPARAM)(const char*)szReason
- break;
- case ACKRESULT_SUCCESS:
- self->Unhook();
- switch (ack->type) {
- case ACKTYPE_CHAT:
- break;
- case ACKTYPE_MESSAGE:
- self->DB_EventAdd((uint16_t)EVENTTYPE_MESSAGE);
- break;
- case ACKTYPE_FILE:
- self->m_szEventMsg.Insert(0, "aaaa");
- self->m_cbEventMsg += sizeof(uint32_t);
- self->DB_EventAdd((uint16_t)EVENTTYPE_FILE);
- break;
- }
- self->Exit(ack->result);
- break;
- }
- return 0;
-}
-
-void CSend::DB_EventAdd(uint16_t EventType)
-{
- DBEVENTINFO dbei = {};
- dbei.szModule = m_pszProto;
- dbei.eventType = EventType;
- dbei.flags = DBEF_SENT;
- dbei.timestamp = time(0);
- dbei.flags |= DBEF_UTF;
- dbei.cbBlob = m_cbEventMsg;
- dbei.pBlob = (uint8_t*)m_szEventMsg.GetString();
- db_event_add(m_hContact, &dbei);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CSend::Error(LPCTSTR pszFormat, ...)
-{
- wchar_t tszMsg[MAX_SECONDLINE];
-
- mir_snwprintf(tszMsg, L"%s - %s", _A2W(MODULENAME), TranslateT("Error"));
- mir_free(m_ErrorTitle), m_ErrorTitle = mir_wstrdup(tszMsg);
-
- va_list vl;
- va_start(vl, pszFormat);
- mir_vsnwprintf(tszMsg, _countof(tszMsg), TranslateW(pszFormat), vl);
- va_end(vl);
- mir_free(m_ErrorMsg), m_ErrorMsg = mir_wstrdup(tszMsg);
-
- memset(&m_box, 0, sizeof(MSGBOX));
- m_box.cbSize = sizeof(MSGBOX);
- m_box.hParent = nullptr;
- m_box.hiLogo = GetIcon(ICO_MAIN);
- m_box.hiMsg = nullptr;
- m_box.ptszTitle = m_ErrorTitle;
- m_box.ptszMsg = m_ErrorMsg;
- m_box.uType = MB_OK | MB_ICON_ERROR;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CSend::Exit(unsigned int Result)
-{
- if (!m_bSilent) {
- bool err = true;
- switch (Result) {
- case CSEND_DIALOG:
- Skin_PlaySound("FileDone");
- DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UResultForm), nullptr, ResultDialogProc, (LPARAM)this);
- err = false;
- break;
- case ACKRESULT_SUCCESS:
- case GC_RESULT_SUCCESS:
- Skin_PlaySound("FileDone");
- err = false;
- break;
- case ACKRESULT_DENIED:
- Skin_PlaySound("FileDenied");
- Error(L"%s (%i):\nFile transfer denied.", TranslateW(m_pszSendTyp), Result);
- MsgBoxService(NULL, (LPARAM)&m_box);
- err = false;
- break;
- case GC_RESULT_WRONGVER: // You appear to be using the wrong version of GC API.
- Error(L"%s (%i):\nYou appear to be using the wrong version of GC API", TranslateT("GCHAT error"), Result);
- break;
- case GC_RESULT_ERROR: // An internal GC error occurred.
- Error(L"%s (%i):\nAn internal GC error occurred.", TranslateT("GCHAT error"), Result);
- break;
- case GC_RESULT_NOSESSION: // contact has no open GC session
- Error(L"%s (%i):\nContact has no open GC session.", TranslateT("GCHAT error"), Result);
- break;
- case ACKRESULT_FAILED:
- default:
- break;
- }
- if (err) {
- Skin_PlaySound("FileFailed");
- if (m_ErrorMsg) MsgBoxService(NULL, (LPARAM)&m_box);
- else MsgErr(nullptr, LPGENW("An unknown error has occurred."));
- }
- }
- if (m_pszFile && *m_pszFile && m_bDeleteAfterSend && m_EnableItem&SS_DLG_DELETEAFTERSSEND) {
- DeleteFile(m_pszFile), m_pszFile = nullptr;
- }
- if (m_bAsync)
- delete this; // deletes derived class since destructor is virtual (which also auto-calls base dtor)
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// helper functions used for HTTP uploads
-
-#define snprintf _snprintf
-
-const char* CSend::GetHTMLContent(char* str, const char* startTag, const char* endTag)
-{
- char* begin = strstr(str, startTag);
- if (!begin) return nullptr;
- begin += mir_strlen(startTag) - 1;
- for (; *begin != '>' && *begin; ++begin);
- if (*begin) {
- char* end = strstr(++begin, endTag);
- if (end) *end = 0;
- }
- return begin;
-}
-
-static void HTTPFormAppendData(NETLIBHTTPREQUEST* nlhr, size_t* dataMax, char** dataPos, const char* data, size_t len)
-{
- nlhr->dataLength = (*dataPos - nlhr->pData);
- if (nlhr->dataLength + len >= *dataMax) {
- *dataPos = nlhr->pData;
- *dataMax += 0x1000 + 0x1000 * (len >> 12);
- nlhr->pData = (char*)mir_realloc(nlhr->pData, *dataMax);
- if (!nlhr->pData) mir_free(*dataPos);
- *dataPos = nlhr->pData;
- if (!*dataPos)
- return;
- *dataPos += nlhr->dataLength;
- }
- if (data) {
- memcpy(*dataPos, data, sizeof(char)*len); *dataPos += len;
- nlhr->dataLength += (int)len; // not necessary
- }
-}
-
-void CSend::HTTPFormDestroy(NETLIBHTTPREQUEST* nlhr)
-{
- mir_free(nlhr->headers[0].szValue), nlhr->headers[0].szValue = nullptr;
- mir_free(nlhr->headers), nlhr->headers = nullptr;
- mir_free(nlhr->pData), nlhr->pData = nullptr;
-}
-
-int CSend::HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum)
-{
- char boundary[16];
- memcpy(boundary, "--M461C/", 8);
- {
- union
- {
- uint32_t num;
- unsigned char cr[4];
- }; num = GetTickCount() ^ 0x8000;
- for (int i = 0; i < 4; ++i) {
- unsigned char chcode = cr[i] >> 4;
- boundary[8 + i * 2] = (chcode < 0x0a ? '0' : 'a' - 0x0a) + chcode;
- chcode = cr[i] & 0x0f;
- boundary[9 + i * 2] = (chcode < 0x0a ? '0' : 'a' - 0x0a) + chcode;
- }
- }
- nlhr->cbSize = sizeof(NETLIBHTTPREQUEST);
- nlhr->requestType = requestType;
- nlhr->flags = NLHRF_HTTP11;
- if (!strncmp(url, "https://", 8)) nlhr->flags |= NLHRF_SSL;
- nlhr->szUrl = (char*)url;
- nlhr->headersCount = 3;
- for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
- if (!(iter->flags&HTTPFF_HEADER)) break;
- ++nlhr->headersCount;
- }
- nlhr->headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr->headersCount);
- {
- char* contenttype = (char*)mir_alloc(sizeof(char)*(30 + 1 + sizeof(boundary)));
- memcpy(contenttype, "multipart/form-data; boundary=", 30);
- memcpy(contenttype + 30, boundary, sizeof(boundary));
- contenttype[30 + sizeof(boundary)] = '\0';
- nlhr->headers[0].szName = "Content-Type";
- nlhr->headers[0].szValue = contenttype;
- nlhr->headers[1].szName = "User-Agent";
- nlhr->headers[1].szValue = __USER_AGENT_STRING;
- nlhr->headers[2].szName = "Accept-Language";
- nlhr->headers[2].szValue = "en-us,en;q=0.8";
- int i = 3;
- for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
- if (!(iter->flags&HTTPFF_HEADER)) break;
- nlhr->headers[i].szName = (char*)iter->name;
- nlhr->headers[i++].szValue = (char*)iter->value_str;
- }
- }
- char* dataPos = nlhr->pData;
- size_t dataMax = 0;
- for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
- if (iter->flags&HTTPFF_HEADER) continue;
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, 2 + sizeof(boundary) + 40);
- memset(dataPos, '-', 2); dataPos += 2;
- memcpy(dataPos, boundary, sizeof(boundary)); dataPos += sizeof(boundary);
- memcpy(dataPos, "\r\nContent-Disposition: form-data; name=\"", 40); dataPos += 40;
- size_t namelen = mir_strlen(iter->name), valuelen = 0;
- if (!(iter->flags&HTTPFF_INT))
- valuelen = mir_strlen(iter->value_str);
- if (iter->flags&HTTPFF_FILE) {
- const char* filename = strrchr(iter->value_str, '\\');
- if (!filename) filename = strrchr(iter->value_str, '/');
- if (!filename) filename = iter->value_str;
- else ++filename;
- valuelen = mir_strlen(filename);
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 13 + valuelen + 17);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"; filename=\"", 13); dataPos += 13;
- memcpy(dataPos, filename, valuelen); dataPos += valuelen;
- memcpy(dataPos, "\"\r\nContent-Type: ", 17); dataPos += 17;
- /// add mime type
- const char* mime = "application/octet-stream";
- const char* fileext = strrchr(filename, '.');
- if (fileext) {
- if (!mir_strcmp(fileext, ".jpg") || !mir_strcmp(fileext, ".jpeg") || !mir_strcmp(fileext, ".jpe"))
- mime = "image/jpeg";
- else if (!mir_strcmp(fileext, ".bmp"))
- mime = "image/bmp";
- else if (!mir_strcmp(fileext, ".png"))
- mime = "image/png";
- else if (!mir_strcmp(fileext, ".gif"))
- mime = "image/gif";
- else if (!mir_strcmp(fileext, ".tif") || !mir_strcmp(fileext, ".tiff"))
- mime = "image/tiff";
- }
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, mime, mir_strlen(mime));
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, "\r\n\r\n", 4);
- /// add file content
- size_t filesize = 0;
- FILE* fp = fopen(iter->value_str, "rb");
- if (fp) {
- fseek(fp, 0, SEEK_END);
- filesize = ftell(fp); fseek(fp, 0, SEEK_SET);
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, filesize + 2);
- if (fread(dataPos, 1, filesize, fp) != filesize) {
- fclose(fp), fp = nullptr;
- }
- }
- if (!fp) {
- HTTPFormDestroy(nlhr);
- Error(L"Error occurred when opening local file.\nAborting file upload...");
- Exit(ACKRESULT_FAILED);
- return 1;
- }
- else
- fclose(fp);
- dataPos += filesize;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
- }
- else if (iter->flags&HTTPFF_8BIT) {
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 38 + valuelen + 2);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n", 38); dataPos += 38;
- memcpy(dataPos, iter->value_str, valuelen); dataPos += valuelen;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
- }
- else if (iter->flags&HTTPFF_INT) {
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 5 + 17/*max numbers*/ + 2);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"\r\n\r\n", 5); dataPos += 5;
- int ret = snprintf(dataPos, 17, "%Id", iter->value_int);
- if (ret < 17 && ret>0) dataPos += ret;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
- }
- else {
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 5 + valuelen + 2);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"\r\n\r\n", 5); dataPos += 5;
- memcpy(dataPos, iter->value_str, valuelen); dataPos += valuelen;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
- }
- }
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, 2 + sizeof(boundary) + 4);
- memset(dataPos, '-', 2); dataPos += 2;
- memcpy(dataPos, boundary, sizeof(boundary)); dataPos += sizeof(boundary);
- memcpy(dataPos, "--\r\n", 4); dataPos += 4;
- nlhr->dataLength = dataPos - nlhr->pData;
-#ifdef _DEBUG /// print request content to "_sendss_tmp" file for debugging
- {
- FILE* fp = fopen("_sendss_tmp", "wb");
- if (fp) {
- fprintf(fp, "--Target-- %s\n", nlhr->szUrl);
- for (int i = 0; i < nlhr->headersCount; ++i) {
- fprintf(fp, "%s: %s\n", nlhr->headers[i].szName, nlhr->headers[i].szValue);
- }
- fprintf(fp, "\n\n");
- fwrite(nlhr->pData, 1, nlhr->dataLength, fp);
- fclose(fp);
- }
- }
-#endif // _DEBUG
- return 0;
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+#define CSEND_DIALOG 8800
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSend::CSend(HWND /*Owner*/, MCONTACT hContact, bool bAsync, bool bSilent) :
+ m_bDeleteAfterSend(false),
+ m_bAsync(bAsync),
+ m_bSilent(bSilent),
+ m_pszFile(nullptr),
+ m_pszFileDesc(nullptr),
+ m_pszSendTyp(nullptr),
+ m_pszProto(nullptr),
+ m_EnableItem(0),
+ m_ChatRoom(0),
+ m_cbEventMsg(0),
+ m_hSend(nullptr),
+ m_hOnSend(nullptr),
+ m_ErrorMsg(nullptr),
+ m_ErrorTitle(nullptr)
+{
+ SetContact(hContact);
+}
+
+CSend::~CSend()
+{
+ mir_free(m_pszFile);
+ mir_free(m_pszFileDesc);
+ mir_free(m_ErrorMsg);
+ mir_free(m_ErrorTitle);
+ if (m_hOnSend) UnhookEvent(m_hOnSend);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSend::SetContact(MCONTACT hContact)
+{
+ m_hContact = hContact;
+ if (hContact) {
+ m_pszProto = Proto_GetBaseAccountName(hContact);
+ m_ChatRoom = Contact::IsGroupChat(hContact, m_pszProto);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR CALLBACK CSend::ResultDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ Window_SetIcon_IcoLib(hwndDlg, GetIconHandle(ICO_MAIN));
+ {
+ CSend *self = (CSend*)lParam;
+ SetDlgItemText(hwndDlg, IDC_HEADERBAR, CMStringW(TranslateT("Resulting URL from\n")) + self->m_pszSendTyp);
+
+ SendDlgItemMessage(hwndDlg, IDC_HEADERBAR, WM_SETICON, ICON_BIG, (LPARAM)GetIconBtn(ICO_BTN_ARROWR));
+ SetDlgItemTextA(hwndDlg, ID_edtURL, self->m_URL);
+ if (self->m_URLthumb) {
+ SetDlgItemTextA(hwndDlg, ID_edtURLthumb, self->m_URLthumb);
+ }
+ else {
+ SetDlgItemTextA(hwndDlg, ID_edtURLthumb, "-");
+ for (int i = ID_btnThumbCopy; i <= ID_edtURLthumb; ++i) {
+ EnableWindow(GetDlgItem(hwndDlg, i), FALSE);
+ }
+ }
+ if (!self->m_pszFileDesc)
+ SetDlgItemText(hwndDlg, ID_bvlDesc, self->m_ErrorTitle);
+ else
+ SetDlgItemText(hwndDlg, ID_bvlDesc, self->m_pszFileDesc);
+ SendDlgItemMessage(hwndDlg, IDOK, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_COPY));
+ SendDlgItemMessage(hwndDlg, IDOK, BUTTONTRANSLATE, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDCANCEL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_CANCEL));
+ SendDlgItemMessage(hwndDlg, IDCANCEL, BUTTONTRANSLATE, 0, 0);
+ for (int i = ID_btnCopy; i <= ID_btnThumbBBC2; ++i) {
+ SendDlgItemMessage(hwndDlg, i, BUTTONSETASTHEMEDBTN, 0, 0);
+ SendDlgItemMessage(hwndDlg, i, BUTTONSETASFLATBTN, 1, 0);
+ switch (i) {
+ case ID_btnCopy:
+ case ID_btnThumbCopy:
+ SendDlgItemMessage(hwndDlg, i, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_COPY));
+ SendDlgItemMessage(hwndDlg, i, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Copy"), BATF_UNICODE);
+ break;
+ case ID_btnBBC:
+ case ID_btnThumbBBC:
+ SendDlgItemMessage(hwndDlg, i, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_BBC));
+ SendDlgItemMessage(hwndDlg, i, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Copy BBCode"), BATF_UNICODE);
+ break;
+ default:
+ SendDlgItemMessage(hwndDlg, i, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetIconBtn(ICO_BTN_BBCLNK));
+ SendDlgItemMessage(hwndDlg, i, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Copy BBCode w/ link"), BATF_UNICODE);
+ }
+ }
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+
+ case IDOK:
+ case ID_btnCopy:
+ case ID_btnThumbCopy:
+ case ID_btnBBC:
+ case ID_btnThumbBBC:
+ case ID_btnThumbBBC2:
+ wchar_t tmp[2048];
+ int edtID = ID_edtURL;
+ int bbc = 0;
+ switch (LOWORD(wParam)) {
+ case ID_btnThumbBBC2: ++bbc;
+ case ID_btnThumbBBC: ++bbc;
+ case ID_btnThumbCopy:
+ edtID = ID_edtURLthumb;
+ break;
+ case ID_btnBBC: ++bbc;
+ break;
+ }
+ size_t len;
+ if (bbc) {
+ if (bbc == 1) {
+ memcpy(tmp, L"[img]", 5 * sizeof(wchar_t)); len = 5;
+ len += GetDlgItemText(hwndDlg, edtID, tmp + len, 2048 - 11);
+ memcpy(tmp + len, L"[/img]", 7 * sizeof(wchar_t)); len += 7;
+ }
+ else {
+ memcpy(tmp, L"[url=", 5 * sizeof(wchar_t)); len = 5;
+ len += GetDlgItemText(hwndDlg, ID_edtURL, tmp + len, 1024);
+ memcpy(tmp + len, L"][img]", 6 * sizeof(wchar_t)); len += 6;
+ len += GetDlgItemText(hwndDlg, edtID, tmp + len, 1024);
+ memcpy(tmp + len, L"[/img][/url]", 13 * sizeof(wchar_t)); len += 12;
+ }
+ }
+ else len = GetDlgItemText(hwndDlg, edtID, tmp, _countof(tmp));
+
+ Utils_ClipboardCopy(CMStringW(tmp, len + 1));
+
+ if (LOWORD(wParam) == IDOK)
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void CSend::svcSendMsgExit(const char* szMessage)
+{
+ if (m_bSilent) {
+ Exit(ACKRESULT_SUCCESS); return;
+ }
+ if (!m_hContact) {
+ if (!m_pszFileDesc)
+ m_pszFileDesc = mir_a2u(szMessage);
+ Exit(CSEND_DIALOG); return;
+ }
+
+ if (m_ChatRoom) {
+ CMStringW tmp(szMessage);
+ if (m_pszFileDesc) {
+ tmp.Append(L"\r\n");
+ tmp.Append(m_pszFileDesc);
+ }
+
+ int res = GC_RESULT_NOSESSION;
+ int cnt = g_chatApi.SM_GetCount(m_pszProto);
+
+ // loop on all gc session to get the right (save) ptszID for the chatroom from m_hContact
+ GC_INFO gci = { 0 };
+ gci.pszModule = m_pszProto;
+ for (int i = 0; i < cnt; i++) {
+ gci.iItem = i;
+ gci.Flags = GCF_BYINDEX | GCF_HCONTACT | GCF_ID;
+ Chat_GetInfo(&gci);
+ if (gci.hContact == m_hContact) {
+ Chat_SendUserMessage(m_pszProto, gci.pszID, tmp);
+ res = 200;
+ break;
+ }
+ }
+ Exit(res); return;
+ }
+ else {
+ m_szEventMsg = szMessage;
+ if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
+ m_szEventMsg.Append("\r\n");
+ m_szEventMsg.Append(_T2A(m_pszFileDesc));
+ m_cbEventMsg = m_szEventMsg.GetLength() + 1;
+ }
+
+ // create a HookEventObj on ME_PROTO_ACK
+ if (!m_hOnSend)
+ m_hOnSend = HookEventObj(ME_PROTO_ACK, OnSend, this);
+
+ // start PSS_MESSAGE service
+ m_hSend = (HANDLE)ProtoChainSend(m_hContact, PSS_MESSAGE, NULL, ptrA(mir_utf8encode(m_szEventMsg)));
+
+ // check we actually got an ft handle back from the protocol
+ if (!m_hSend) {
+ Unhook();
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED); return;
+ }
+ }
+}
+
+void CSend::svcSendFileExit()
+{
+ // szMessage should be encoded as the File followed by the description, the
+ // separator being a single nul (\0). If there is no description, do not forget
+ // to end the File with two nuls.
+ if (m_bSilent) {
+ Exit(ACKRESULT_SUCCESS); return;
+ }
+
+ if (!m_hContact) {
+ Error(LPGENW("%s requires a valid contact!"), m_pszSendTyp);
+ Exit(ACKRESULT_FAILED); return;
+ }
+
+ m_szEventMsg = _T2A(m_pszFile);
+
+ if (m_pszFileDesc && m_pszFileDesc[0] != NULL) {
+ m_szEventMsg.AppendChar(0);
+ m_szEventMsg.Append(_T2A(m_pszFileDesc));
+ }
+
+ m_cbEventMsg = m_szEventMsg.GetLength() + 1;
+
+ // Сreate a HookEventObj on ME_PROTO_ACK
+ if (!m_hOnSend) {
+ m_hOnSend = HookEventObj(ME_PROTO_ACK, OnSend, this);
+ }
+
+ // Start miranda PSS_FILE based on mir ver (T)
+ wchar_t* ppFile[2] = { nullptr, nullptr };
+ wchar_t* pDesc = mir_wstrdup(m_pszFileDesc);
+ ppFile[0] = mir_wstrdup(m_pszFile);
+ ppFile[1] = nullptr;
+ m_hSend = (HANDLE)ProtoChainSend(m_hContact, PSS_FILE, (WPARAM)pDesc, (LPARAM)ppFile);
+ mir_free(pDesc);
+ mir_free(ppFile[0]);
+
+ // check we actually got an ft handle back from the protocol
+ if (!m_hSend) {
+ Unhook();
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED); return;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSend::OnSend(void *obj, WPARAM, LPARAM lParam)
+{
+ CSend* self = (CSend*)obj;
+ ACKDATA *ack = (ACKDATA*)lParam;
+ if (ack->hProcess != self->m_hSend)
+ return 0;
+
+ switch (ack->result) {
+ case ACKRESULT_INITIALISING: // SetFtStatus(hwndDlg, LPGENW("Initialising..."), FTS_TEXT); break;
+ case ACKRESULT_CONNECTING: // SetFtStatus(hwndDlg, LPGENW("Connecting..."), FTS_TEXT); break;
+ case ACKRESULT_CONNECTPROXY: // SetFtStatus(hwndDlg, LPGENW("Connecting to proxy..."), FTS_TEXT); break;
+ case ACKRESULT_LISTENING: // SetFtStatus(hwndDlg, LPGENW("Waiting for connection..."), FTS_TEXT); break;
+ case ACKRESULT_CONNECTED: // SetFtStatus(hwndDlg, LPGENW("Connected"), FTS_TEXT); break;
+ case ACKRESULT_SENTREQUEST: // SetFtStatus(hwndDlg, LPGENW("Decision sent"), FTS_TEXT); break;
+ case ACKRESULT_NEXTFILE: // SetFtStatus(hwndDlg, LPGENW("Moving to next file..."), FTS_TEXT);
+ case ACKRESULT_FILERESUME:
+ case ACKRESULT_DATA: // transfer is on progress
+ break;
+ case ACKRESULT_DENIED:
+ self->Unhook();
+ self->Exit(ack->result);
+ break;
+ case ACKRESULT_FAILED:
+ self->Unhook();
+ self->Exit(ack->result);
+ // type=ACKTYPE_MESSAGE, result=success/failure, (char*)lParam=error message or NULL.
+ // type=ACKTYPE_FILE, result=ACKRESULT_FAILED then lParam=(LPARAM)(const char*)szReason
+ break;
+ case ACKRESULT_SUCCESS:
+ self->Unhook();
+ switch (ack->type) {
+ case ACKTYPE_CHAT:
+ break;
+ case ACKTYPE_MESSAGE:
+ self->DB_EventAdd((uint16_t)EVENTTYPE_MESSAGE);
+ break;
+ case ACKTYPE_FILE:
+ self->m_szEventMsg.Insert(0, "aaaa");
+ self->m_cbEventMsg += sizeof(uint32_t);
+ self->DB_EventAdd((uint16_t)EVENTTYPE_FILE);
+ break;
+ }
+ self->Exit(ack->result);
+ break;
+ }
+ return 0;
+}
+
+void CSend::DB_EventAdd(uint16_t EventType)
+{
+ DBEVENTINFO dbei = {};
+ dbei.szModule = m_pszProto;
+ dbei.eventType = EventType;
+ dbei.flags = DBEF_SENT;
+ dbei.timestamp = time(0);
+ dbei.flags |= DBEF_UTF;
+ dbei.cbBlob = m_cbEventMsg;
+ dbei.pBlob = (uint8_t*)m_szEventMsg.GetString();
+ db_event_add(m_hContact, &dbei);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSend::Error(LPCTSTR pszFormat, ...)
+{
+ wchar_t tszMsg[MAX_SECONDLINE];
+
+ mir_snwprintf(tszMsg, L"%s - %s", _A2W(MODULENAME), TranslateT("Error"));
+ mir_free(m_ErrorTitle), m_ErrorTitle = mir_wstrdup(tszMsg);
+
+ va_list vl;
+ va_start(vl, pszFormat);
+ mir_vsnwprintf(tszMsg, _countof(tszMsg), TranslateW(pszFormat), vl);
+ va_end(vl);
+ mir_free(m_ErrorMsg), m_ErrorMsg = mir_wstrdup(tszMsg);
+
+ memset(&m_box, 0, sizeof(MSGBOX));
+ m_box.cbSize = sizeof(MSGBOX);
+ m_box.hParent = nullptr;
+ m_box.hiLogo = GetIcon(ICO_MAIN);
+ m_box.hiMsg = nullptr;
+ m_box.ptszTitle = m_ErrorTitle;
+ m_box.ptszMsg = m_ErrorMsg;
+ m_box.uType = MB_OK | MB_ICON_ERROR;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSend::Exit(unsigned int Result)
+{
+ if (!m_bSilent) {
+ bool err = true;
+ switch (Result) {
+ case CSEND_DIALOG:
+ Skin_PlaySound("FileDone");
+ DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UResultForm), nullptr, ResultDialogProc, (LPARAM)this);
+ err = false;
+ break;
+ case ACKRESULT_SUCCESS:
+ case GC_RESULT_SUCCESS:
+ Skin_PlaySound("FileDone");
+ err = false;
+ break;
+ case ACKRESULT_DENIED:
+ Skin_PlaySound("FileDenied");
+ Error(L"%s (%i):\nFile transfer denied.", TranslateW(m_pszSendTyp), Result);
+ MsgBoxService(NULL, (LPARAM)&m_box);
+ err = false;
+ break;
+ case GC_RESULT_WRONGVER: // You appear to be using the wrong version of GC API.
+ Error(L"%s (%i):\nYou appear to be using the wrong version of GC API", TranslateT("GCHAT error"), Result);
+ break;
+ case GC_RESULT_ERROR: // An internal GC error occurred.
+ Error(L"%s (%i):\nAn internal GC error occurred.", TranslateT("GCHAT error"), Result);
+ break;
+ case GC_RESULT_NOSESSION: // contact has no open GC session
+ Error(L"%s (%i):\nContact has no open GC session.", TranslateT("GCHAT error"), Result);
+ break;
+ case ACKRESULT_FAILED:
+ default:
+ break;
+ }
+ if (err) {
+ Skin_PlaySound("FileFailed");
+ if (m_ErrorMsg) MsgBoxService(NULL, (LPARAM)&m_box);
+ else MsgErr(nullptr, LPGENW("An unknown error has occurred."));
+ }
+ }
+ if (m_pszFile && *m_pszFile && m_bDeleteAfterSend && m_EnableItem&SS_DLG_DELETEAFTERSSEND) {
+ DeleteFile(m_pszFile), m_pszFile = nullptr;
+ }
+ if (m_bAsync)
+ delete this; // deletes derived class since destructor is virtual (which also auto-calls base dtor)
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// helper functions used for HTTP uploads
+
+#define snprintf _snprintf
+
+const char* CSend::GetHTMLContent(char* str, const char* startTag, const char* endTag)
+{
+ char* begin = strstr(str, startTag);
+ if (!begin) return nullptr;
+ begin += mir_strlen(startTag) - 1;
+ for (; *begin != '>' && *begin; ++begin);
+ if (*begin) {
+ char* end = strstr(++begin, endTag);
+ if (end) *end = 0;
+ }
+ return begin;
+}
+
+static void HTTPFormAppendData(NETLIBHTTPREQUEST* nlhr, size_t* dataMax, char** dataPos, const char* data, size_t len)
+{
+ nlhr->dataLength = (*dataPos - nlhr->pData);
+ if (nlhr->dataLength + len >= *dataMax) {
+ *dataPos = nlhr->pData;
+ *dataMax += 0x1000 + 0x1000 * (len >> 12);
+ nlhr->pData = (char*)mir_realloc(nlhr->pData, *dataMax);
+ if (!nlhr->pData) mir_free(*dataPos);
+ *dataPos = nlhr->pData;
+ if (!*dataPos)
+ return;
+ *dataPos += nlhr->dataLength;
+ }
+ if (data) {
+ memcpy(*dataPos, data, sizeof(char)*len); *dataPos += len;
+ nlhr->dataLength += (int)len; // not necessary
+ }
+}
+
+void CSend::HTTPFormDestroy(NETLIBHTTPREQUEST* nlhr)
+{
+ mir_free(nlhr->headers[0].szValue), nlhr->headers[0].szValue = nullptr;
+ mir_free(nlhr->headers), nlhr->headers = nullptr;
+ mir_free(nlhr->pData), nlhr->pData = nullptr;
+}
+
+int CSend::HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum)
+{
+ char boundary[16];
+ memcpy(boundary, "--M461C/", 8);
+ {
+ union
+ {
+ uint32_t num;
+ unsigned char cr[4];
+ }; num = GetTickCount() ^ 0x8000;
+ for (int i = 0; i < 4; ++i) {
+ unsigned char chcode = cr[i] >> 4;
+ boundary[8 + i * 2] = (chcode < 0x0a ? '0' : 'a' - 0x0a) + chcode;
+ chcode = cr[i] & 0x0f;
+ boundary[9 + i * 2] = (chcode < 0x0a ? '0' : 'a' - 0x0a) + chcode;
+ }
+ }
+ nlhr->cbSize = sizeof(NETLIBHTTPREQUEST);
+ nlhr->requestType = requestType;
+ nlhr->flags = NLHRF_HTTP11;
+ if (!strncmp(url, "https://", 8)) nlhr->flags |= NLHRF_SSL;
+ nlhr->szUrl = (char*)url;
+ nlhr->headersCount = 3;
+ for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
+ if (!(iter->flags&HTTPFF_HEADER)) break;
+ ++nlhr->headersCount;
+ }
+ nlhr->headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr->headersCount);
+ {
+ char* contenttype = (char*)mir_alloc(sizeof(char)*(30 + 1 + sizeof(boundary)));
+ memcpy(contenttype, "multipart/form-data; boundary=", 30);
+ memcpy(contenttype + 30, boundary, sizeof(boundary));
+ contenttype[30 + sizeof(boundary)] = '\0';
+ nlhr->headers[0].szName = "Content-Type";
+ nlhr->headers[0].szValue = contenttype;
+ nlhr->headers[1].szName = "User-Agent";
+ nlhr->headers[1].szValue = __USER_AGENT_STRING;
+ nlhr->headers[2].szName = "Accept-Language";
+ nlhr->headers[2].szValue = "en-us,en;q=0.8";
+ int i = 3;
+ for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
+ if (!(iter->flags&HTTPFF_HEADER)) break;
+ nlhr->headers[i].szName = (char*)iter->name;
+ nlhr->headers[i++].szValue = (char*)iter->value_str;
+ }
+ }
+ char* dataPos = nlhr->pData;
+ size_t dataMax = 0;
+ for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
+ if (iter->flags&HTTPFF_HEADER) continue;
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, 2 + sizeof(boundary) + 40);
+ memset(dataPos, '-', 2); dataPos += 2;
+ memcpy(dataPos, boundary, sizeof(boundary)); dataPos += sizeof(boundary);
+ memcpy(dataPos, "\r\nContent-Disposition: form-data; name=\"", 40); dataPos += 40;
+ size_t namelen = mir_strlen(iter->name), valuelen = 0;
+ if (!(iter->flags&HTTPFF_INT))
+ valuelen = mir_strlen(iter->value_str);
+ if (iter->flags&HTTPFF_FILE) {
+ const char* filename = strrchr(iter->value_str, '\\');
+ if (!filename) filename = strrchr(iter->value_str, '/');
+ if (!filename) filename = iter->value_str;
+ else ++filename;
+ valuelen = mir_strlen(filename);
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 13 + valuelen + 17);
+ memcpy(dataPos, iter->name, namelen); dataPos += namelen;
+ memcpy(dataPos, "\"; filename=\"", 13); dataPos += 13;
+ memcpy(dataPos, filename, valuelen); dataPos += valuelen;
+ memcpy(dataPos, "\"\r\nContent-Type: ", 17); dataPos += 17;
+ /// add mime type
+ const char* mime = "application/octet-stream";
+ const char* fileext = strrchr(filename, '.');
+ if (fileext) {
+ if (!mir_strcmp(fileext, ".jpg") || !mir_strcmp(fileext, ".jpeg") || !mir_strcmp(fileext, ".jpe"))
+ mime = "image/jpeg";
+ else if (!mir_strcmp(fileext, ".bmp"))
+ mime = "image/bmp";
+ else if (!mir_strcmp(fileext, ".png"))
+ mime = "image/png";
+ else if (!mir_strcmp(fileext, ".gif"))
+ mime = "image/gif";
+ else if (!mir_strcmp(fileext, ".tif") || !mir_strcmp(fileext, ".tiff"))
+ mime = "image/tiff";
+ }
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, mime, mir_strlen(mime));
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, "\r\n\r\n", 4);
+ /// add file content
+ size_t filesize = 0;
+ FILE* fp = fopen(iter->value_str, "rb");
+ if (fp) {
+ fseek(fp, 0, SEEK_END);
+ filesize = ftell(fp); fseek(fp, 0, SEEK_SET);
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, filesize + 2);
+ if (fread(dataPos, 1, filesize, fp) != filesize) {
+ fclose(fp), fp = nullptr;
+ }
+ }
+ if (!fp) {
+ HTTPFormDestroy(nlhr);
+ Error(L"Error occurred when opening local file.\nAborting file upload...");
+ Exit(ACKRESULT_FAILED);
+ return 1;
+ }
+ else
+ fclose(fp);
+ dataPos += filesize;
+ memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ }
+ else if (iter->flags&HTTPFF_8BIT) {
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 38 + valuelen + 2);
+ memcpy(dataPos, iter->name, namelen); dataPos += namelen;
+ memcpy(dataPos, "\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n", 38); dataPos += 38;
+ memcpy(dataPos, iter->value_str, valuelen); dataPos += valuelen;
+ memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ }
+ else if (iter->flags&HTTPFF_INT) {
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 5 + 17/*max numbers*/ + 2);
+ memcpy(dataPos, iter->name, namelen); dataPos += namelen;
+ memcpy(dataPos, "\"\r\n\r\n", 5); dataPos += 5;
+ int ret = snprintf(dataPos, 17, "%Id", iter->value_int);
+ if (ret < 17 && ret>0) dataPos += ret;
+ memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ }
+ else {
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 5 + valuelen + 2);
+ memcpy(dataPos, iter->name, namelen); dataPos += namelen;
+ memcpy(dataPos, "\"\r\n\r\n", 5); dataPos += 5;
+ memcpy(dataPos, iter->value_str, valuelen); dataPos += valuelen;
+ memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ }
+ }
+ HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, 2 + sizeof(boundary) + 4);
+ memset(dataPos, '-', 2); dataPos += 2;
+ memcpy(dataPos, boundary, sizeof(boundary)); dataPos += sizeof(boundary);
+ memcpy(dataPos, "--\r\n", 4); dataPos += 4;
+ nlhr->dataLength = dataPos - nlhr->pData;
+#ifdef _DEBUG /// print request content to "_sendss_tmp" file for debugging
+ {
+ FILE* fp = fopen("_sendss_tmp", "wb");
+ if (fp) {
+ fprintf(fp, "--Target-- %s\n", nlhr->szUrl);
+ for (int i = 0; i < nlhr->headersCount; ++i) {
+ fprintf(fp, "%s: %s\n", nlhr->headers[i].szName, nlhr->headers[i].szValue);
+ }
+ fprintf(fp, "\n\n");
+ fwrite(nlhr->pData, 1, nlhr->dataLength, fp);
+ fclose(fp);
+ }
+ }
+#endif // _DEBUG
+ return 0;
+}
diff --git a/plugins/SendScreenshotPlus/src/CSend.h b/plugins/SendScreenshotPlus/src/CSend.h
index 630222b69e..9301811f17 100644
--- a/plugins/SendScreenshotPlus/src/CSend.h
+++ b/plugins/SendScreenshotPlus/src/CSend.h
@@ -1,137 +1,137 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_H
-#define _CSEND_H
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define SS_AUTOSEND 1
-#define SS_DELETEAFTERSSEND 2
-
-#define SS_DLG_AUTOSEND 1 // Button_Enable(GetDlgItem(Owner, ID_chkEmulateClick), TRUE);
-#define SS_DLG_DELETEAFTERSSEND 2 // Button_Enable(GetDlgItem(Owner, ID_chkDeleteAfterSend), TRUE);
-#define SS_DLG_DESCRIPTION 4 // Button_Enable(GetDlgItem(Owner, ID_chkDesc), TRUE);
-
-#define GC_RESULT_SUCCESS 200
-#define GC_RESULT_WRONGVER 201
-#define GC_RESULT_ERROR 202
-#define GC_RESULT_NOSESSION 209
-
-const wchar_t SS_ERR_INIT[] = LPGENW("Unable to initiate %s.");
-const wchar_t SS_ERR_MAPI[] = LPGENW("MAPI error (%i):\n%s.");
-const wchar_t SS_ERR_RESPONSE[] = LPGENW("Unknown response from %s (%i)");
-const wchar_t SS_ERR_NORESPONSE[] = LPGENW("Got no response from %s (%i)");
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class CSend
-{
-public:
- CSend(HWND Owner, MCONTACT hContact, bool bAsync, bool bSilent=false); // oder (TfrmMain & Owner)
- virtual ~CSend();
-
- virtual int Send() = 0; // returns 1 if sent (you must delete class) and 0 when still sending (class deletes itself)
- int SendSilent() { m_bAsync = m_bSilent = true; return Send(); }
-
- void SetFile(const wchar_t* file) { replaceStrW(m_pszFile, file); }
- void SetFile(const char* file) { mir_free(m_pszFile), m_pszFile=mir_a2u(file); }
- void SetDescription(const wchar_t* descr){ replaceStrW(m_pszFileDesc, descr); }
- void SetContact(MCONTACT hContact);
- const char* GetURL() { return m_URL; }
- const char* GetURLthumbnail() {return m_URLthumb; }
- uint8_t GetEnableItem() {return m_EnableItem;};
- wchar_t* GetErrorMsg() {return m_ErrorMsg;};
-
- bool m_bDeleteAfterSend;
-
-protected:
- bool m_bAsync;
- bool m_bSilent;
- wchar_t* m_pszFile;
- wchar_t* m_pszFileDesc;
- CMStringA m_URL;
- CMStringA m_URLthumb;
- static int OnSend(void *obj, WPARAM wParam, LPARAM lParam);
- wchar_t* m_pszSendTyp; // hold string for error mess
- char* m_pszProto; // Contact Proto Module
- MCONTACT m_hContact; // Contact handle
- uint8_t m_EnableItem; // hold flag for send type
- uint8_t m_ChatRoom; // is Contact chatroom
-
- void Error(LPCTSTR pszFormat, ...);
- void svcSendFileExit();
- void svcSendMsgExit(const char* szMessage);
- void Exit(unsigned int Result);
-
- uint32_t m_cbEventMsg; // sizeof EventMsg(T) buffer
- CMStringA m_szEventMsg; // EventMsg char*
- HANDLE m_hSend; // protocol send handle
- HANDLE m_hOnSend; // HookEventObj on ME_PROTO_ACK
-
- MSGBOX m_box;
- wchar_t* m_ErrorMsg;
- wchar_t* m_ErrorTitle;
-
- void Unhook(){if(m_hOnSend) {UnhookEvent(m_hOnSend);m_hOnSend = nullptr;}}
- void DB_EventAdd(uint16_t EventType);
-
- static INT_PTR CALLBACK ResultDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
-
- /// HTTP upload helper stuff
- enum HTTPFormFlags
- {
- HTTPFF_HEADER = 0x80,
- HTTPFF_TEXT = 0x00,
- HTTPFF_8BIT = 0x01,
- HTTPFF_FILE = 0x02,
- HTTPFF_INT = 0x04,
- };
-
- #define HTTPFORM_HEADER(str) str,HTTPFF_HEADER
- #define HTTPFORM_TEXT(str) str,HTTPFF_TEXT
- #define HTTPFORM_8BIT(str) str,HTTPFF_8BIT
- #define HTTPFORM_FILE(str) str,HTTPFF_FILE
- #define HTTPFORM_INT(int) (const char*)(int),HTTPFF_INT
-
- struct HTTPFormData
- {
- const char *name;
- union{
- const char* value_str;
- intptr_t value_int;
- };
- int flags;
- };
-
- static const char* GetHTMLContent(char* str, const char* startTag, const char* endTag); // changes "str", can be successfully used only once
- void HTTPFormDestroy(NETLIBHTTPREQUEST* nlhr); // use to free data inside "nlhr" created by HTTPFormCreate
- int HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum); // returns "0" on success, Exit() will be called on failure (stop processing)
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_H
+#define _CSEND_H
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define SS_AUTOSEND 1
+#define SS_DELETEAFTERSSEND 2
+
+#define SS_DLG_AUTOSEND 1 // Button_Enable(GetDlgItem(Owner, ID_chkEmulateClick), TRUE);
+#define SS_DLG_DELETEAFTERSSEND 2 // Button_Enable(GetDlgItem(Owner, ID_chkDeleteAfterSend), TRUE);
+#define SS_DLG_DESCRIPTION 4 // Button_Enable(GetDlgItem(Owner, ID_chkDesc), TRUE);
+
+#define GC_RESULT_SUCCESS 200
+#define GC_RESULT_WRONGVER 201
+#define GC_RESULT_ERROR 202
+#define GC_RESULT_NOSESSION 209
+
+const wchar_t SS_ERR_INIT[] = LPGENW("Unable to initiate %s.");
+const wchar_t SS_ERR_MAPI[] = LPGENW("MAPI error (%i):\n%s.");
+const wchar_t SS_ERR_RESPONSE[] = LPGENW("Unknown response from %s (%i)");
+const wchar_t SS_ERR_NORESPONSE[] = LPGENW("Got no response from %s (%i)");
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+class CSend
+{
+public:
+ CSend(HWND Owner, MCONTACT hContact, bool bAsync, bool bSilent=false); // oder (TfrmMain & Owner)
+ virtual ~CSend();
+
+ virtual int Send() = 0; // returns 1 if sent (you must delete class) and 0 when still sending (class deletes itself)
+ int SendSilent() { m_bAsync = m_bSilent = true; return Send(); }
+
+ void SetFile(const wchar_t* file) { replaceStrW(m_pszFile, file); }
+ void SetFile(const char* file) { mir_free(m_pszFile), m_pszFile=mir_a2u(file); }
+ void SetDescription(const wchar_t* descr){ replaceStrW(m_pszFileDesc, descr); }
+ void SetContact(MCONTACT hContact);
+ const char* GetURL() { return m_URL; }
+ const char* GetURLthumbnail() {return m_URLthumb; }
+ uint8_t GetEnableItem() {return m_EnableItem;};
+ wchar_t* GetErrorMsg() {return m_ErrorMsg;};
+
+ bool m_bDeleteAfterSend;
+
+protected:
+ bool m_bAsync;
+ bool m_bSilent;
+ wchar_t* m_pszFile;
+ wchar_t* m_pszFileDesc;
+ CMStringA m_URL;
+ CMStringA m_URLthumb;
+ static int OnSend(void *obj, WPARAM wParam, LPARAM lParam);
+ wchar_t* m_pszSendTyp; // hold string for error mess
+ char* m_pszProto; // Contact Proto Module
+ MCONTACT m_hContact; // Contact handle
+ uint8_t m_EnableItem; // hold flag for send type
+ uint8_t m_ChatRoom; // is Contact chatroom
+
+ void Error(LPCTSTR pszFormat, ...);
+ void svcSendFileExit();
+ void svcSendMsgExit(const char* szMessage);
+ void Exit(unsigned int Result);
+
+ uint32_t m_cbEventMsg; // sizeof EventMsg(T) buffer
+ CMStringA m_szEventMsg; // EventMsg char*
+ HANDLE m_hSend; // protocol send handle
+ HANDLE m_hOnSend; // HookEventObj on ME_PROTO_ACK
+
+ MSGBOX m_box;
+ wchar_t* m_ErrorMsg;
+ wchar_t* m_ErrorTitle;
+
+ void Unhook(){if(m_hOnSend) {UnhookEvent(m_hOnSend);m_hOnSend = nullptr;}}
+ void DB_EventAdd(uint16_t EventType);
+
+ static INT_PTR CALLBACK ResultDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
+
+ /// HTTP upload helper stuff
+ enum HTTPFormFlags
+ {
+ HTTPFF_HEADER = 0x80,
+ HTTPFF_TEXT = 0x00,
+ HTTPFF_8BIT = 0x01,
+ HTTPFF_FILE = 0x02,
+ HTTPFF_INT = 0x04,
+ };
+
+ #define HTTPFORM_HEADER(str) str,HTTPFF_HEADER
+ #define HTTPFORM_TEXT(str) str,HTTPFF_TEXT
+ #define HTTPFORM_8BIT(str) str,HTTPFF_8BIT
+ #define HTTPFORM_FILE(str) str,HTTPFF_FILE
+ #define HTTPFORM_INT(int) (const char*)(int),HTTPFF_INT
+
+ struct HTTPFormData
+ {
+ const char *name;
+ union{
+ const char* value_str;
+ intptr_t value_int;
+ };
+ int flags;
+ };
+
+ static const char* GetHTMLContent(char* str, const char* startTag, const char* endTag); // changes "str", can be successfully used only once
+ void HTTPFormDestroy(NETLIBHTTPREQUEST* nlhr); // use to free data inside "nlhr" created by HTTPFormCreate
+ int HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum); // returns "0" on success, Exit() will be called on failure (stop processing)
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendCloduFile.h b/plugins/SendScreenshotPlus/src/CSendCloduFile.h
index 663bbf526c..f5f0c221db 100644
--- a/plugins/SendScreenshotPlus/src/CSendCloduFile.h
+++ b/plugins/SendScreenshotPlus/src/CSendCloduFile.h
@@ -1,50 +1,50 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_CLOUD_FILE_H
-#define _CSEND_CLOUD_FILE_H
-
-#include "Utils.h"
-
-class CSendCloudFile : public CSend
-{
-
-public:
- CSendCloudFile(HWND Owner, MCONTACT hContact, bool bAsync, const char *service);
- ~CSendCloudFile();
-
- int Send() override;
-
-protected:
- const char *m_service;
-
- void SendThread();
- static void SendThreadWrapper(void *Obj);
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_CLOUD_FILE_H
+#define _CSEND_CLOUD_FILE_H
+
+#include "Utils.h"
+
+class CSendCloudFile : public CSend
+{
+
+public:
+ CSendCloudFile(HWND Owner, MCONTACT hContact, bool bAsync, const char *service);
+ ~CSendCloudFile();
+
+ int Send() override;
+
+protected:
+ const char *m_service;
+
+ void SendThread();
+ static void SendThreadWrapper(void *Obj);
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendCloudFile.cpp b/plugins/SendScreenshotPlus/src/CSendCloudFile.cpp
index ddcdb3b0a5..88f5da4dac 100644
--- a/plugins/SendScreenshotPlus/src/CSendCloudFile.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendCloudFile.cpp
@@ -1,78 +1,78 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSendCloudFile::CSendCloudFile(HWND Owner, MCONTACT hContact, bool bAsync, const char *service)
- : CSend(Owner, hContact, bAsync), m_service(service)
-{
- // @todo : re-enable SS_DLG_DELETEAFTERSSEND with full implemention of Dropbox upload with progress, msg and sounds
- m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
- m_pszSendTyp = TranslateT("CloudFile transfer");
-}
-
-CSendCloudFile::~CSendCloudFile()
-{
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendCloudFile::Send()
-{
- mir_forkthread(&CSendCloudFile::SendThreadWrapper, this);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CSendCloudFile::SendThread()
-{
- // @todo : SS_DLG_DESCRIPTION and SS_DLG_DELETEAFTERSSEND are of no use as of now since we don't track upload progress
-
- CFUPLOADDATA ud = { m_service, m_pszFile, L"SendSS" };
- CFUPLOADRESULT ur = { };
-
- if (CallService(MS_CLOUDFILE_UPLOAD, (WPARAM)&ud, (LPARAM)&ur)) {
- Error(LPGENW("%s (%i):\nCould not add a share to the CloudFile plugin."), TranslateW(m_pszSendTyp), 0);
- Exit(ACKRESULT_FAILED);
- return;
- }
-
- m_URL = ur.link;
- if (m_URL)
- svcSendMsgExit(m_URL);
- else
- Exit(ACKRESULT_FAILED);
-}
-
-void CSendCloudFile::SendThreadWrapper(void * Obj)
-{
- reinterpret_cast<CSendCloudFile*>(Obj)->SendThread();
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSendCloudFile::CSendCloudFile(HWND Owner, MCONTACT hContact, bool bAsync, const char *service)
+ : CSend(Owner, hContact, bAsync), m_service(service)
+{
+ // @todo : re-enable SS_DLG_DELETEAFTERSSEND with full implemention of Dropbox upload with progress, msg and sounds
+ m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
+ m_pszSendTyp = TranslateT("CloudFile transfer");
+}
+
+CSendCloudFile::~CSendCloudFile()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendCloudFile::Send()
+{
+ mir_forkthread(&CSendCloudFile::SendThreadWrapper, this);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSendCloudFile::SendThread()
+{
+ // @todo : SS_DLG_DESCRIPTION and SS_DLG_DELETEAFTERSSEND are of no use as of now since we don't track upload progress
+
+ CFUPLOADDATA ud = { m_service, m_pszFile, L"SendSS" };
+ CFUPLOADRESULT ur = { };
+
+ if (CallService(MS_CLOUDFILE_UPLOAD, (WPARAM)&ud, (LPARAM)&ur)) {
+ Error(LPGENW("%s (%i):\nCould not add a share to the CloudFile plugin."), TranslateW(m_pszSendTyp), 0);
+ Exit(ACKRESULT_FAILED);
+ return;
+ }
+
+ m_URL = ur.link;
+ if (m_URL)
+ svcSendMsgExit(m_URL);
+ else
+ Exit(ACKRESULT_FAILED);
+}
+
+void CSendCloudFile::SendThreadWrapper(void * Obj)
+{
+ reinterpret_cast<CSendCloudFile*>(Obj)->SendThread();
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendEmail.cpp b/plugins/SendScreenshotPlus/src/CSendEmail.cpp
index 8490004f21..2af6b0b174 100644
--- a/plugins/SendScreenshotPlus/src/CSendEmail.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendEmail.cpp
@@ -1,201 +1,201 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSendEmail::CSendEmail(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
- : CSend(Owner, hContact, true)
-{
- m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_DELETEAFTERSSEND; // SS_DLG_AUTOSEND | ;
- m_pszSendTyp = LPGENW("Email transfer");
- m_pszFileA = nullptr;
- m_pszFileName = nullptr;
- m_Email = nullptr;
- m_FriendlyName = nullptr;
- m_Subject = nullptr;
-}
-
-CSendEmail::~CSendEmail()
-{
- mir_free(m_pszFileA);
- mir_free(m_pszFileName);
- mir_free(m_Email);
- mir_free(m_FriendlyName);
- mir_free(m_Subject);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendEmail::Send()
-{
- if (!m_hContact) return 1;
- mir_free(m_pszFileName);
- m_pszFileName = GetFileNameA(m_pszFile);
-
- mir_free(m_pszFileA);
- m_pszFileA = mir_u2a(m_pszFile);
-
- m_Email = mir_u2a(ptrW(Contact::GetInfo(CNF_EMAIL, m_hContact, m_pszProto)));
- m_FriendlyName = mir_u2a(ptrW(Contact::GetInfo(CNF_DISPLAY, m_hContact, m_pszProto)));
- m_Subject = mir_u2a(m_pszFileDesc);
-
- // SendByEmail(m_pszFileA, "", m_FriendlyName, m_Email, m_Subject);
-
- // start Send thread
- mir_forkthread(&CSendEmail::SendThreadWrapper, this);
- return 0;
-}
-
-void CSendEmail::SendThread()
-{
- // This code based on SentTo.exe application.
- // The default mail client for Simple MAPI or MAPI calls is defined by the
- // HKLM\Software\Clients\Mail::(default) registry value.
-
- MapiFileDesc arrfileDesc[1];
-
- typedef ULONG(FAR PASCAL *MAPIFUNC)(LHANDLE, ULONG, lpMapiMessage, FLAGS, ULONG);
- MapiMessage Msg;
- MAPIFUNC lpMAPISendMail;
-
- HINSTANCE hMAPILib = ::LoadLibrary(L"MAPI32.DLL");
- if (hMAPILib == nullptr) {
- // return -1;
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED); return;
- }
-
- lpMAPISendMail = (MAPIFUNC)GetProcAddress(hMAPILib, "MAPISendMail");
- if (lpMAPISendMail == nullptr) {
- ::FreeLibrary(hMAPILib);
- // return -2;
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED); return;
- }
-
- memset(&Msg, 0, sizeof(Msg));
-
- arrfileDesc[0].ulReserved = 0;
- arrfileDesc[0].flFlags = 0;
- arrfileDesc[0].lpFileType = nullptr;
- arrfileDesc[0].nPosition = -1;
- arrfileDesc[0].lpszPathName = m_pszFileA;
- arrfileDesc[0].lpszFileName = nullptr;
-
- Msg.nFileCount = 1;
- Msg.lpFiles = arrfileDesc;
- Msg.lpszNoteText = ""; // body
- Msg.lpszSubject = m_Subject; // subject
-
- Msg.nRecipCount = 1;
- MapiRecipDesc recip;
- recip.ulReserved = 0;
- recip.ulRecipClass = MAPI_TO;
-
- if (m_FriendlyName && m_FriendlyName[0] != NULL) {
- recip.lpszName = m_FriendlyName; // friendly name set to contact's name
- }
- else {
- recip.lpszName = m_Email; // friendly name set to contact's email
- }
-
- recip.lpszAddress = m_Email; // email
- recip.ulEIDSize = 0;
- recip.lpEntryID = nullptr;
- Msg.lpRecips = &recip;
-
- try {
- int res = lpMAPISendMail(NULL, NULL, &Msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);
- ::FreeLibrary(hMAPILib);
-
- wchar_t* err;
- switch (res) {
- case SUCCESS_SUCCESS:
- // The call succeeded and the message was sent.
- Exit(ACKRESULT_SUCCESS); return;
- // No message was sent
- case MAPI_E_AMBIGUOUS_RECIPIENT:
- err = LPGENW("A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set");
- break;
- case MAPI_E_ATTACHMENT_NOT_FOUND:
- err = LPGENW("The specified attachment was not found");
- break;
- case MAPI_E_ATTACHMENT_OPEN_FAILURE:
- err = LPGENW("The specified attachment could not be opened");
- break;
- case MAPI_E_BAD_RECIPTYPE:
- err = LPGENW("The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC");
- break;
- case MAPI_E_FAILURE:
- err = LPGENW("One or more unspecified errors occurred");
- break;
- case MAPI_E_INSUFFICIENT_MEMORY:
- err = LPGENW("There was insufficient memory to proceed");
- break;
- case MAPI_E_INVALID_RECIPS:
- err = LPGENW("One or more recipients were invalid or did not resolve to any address");
- break;
- case MAPI_E_LOGIN_FAILURE:
- err = LPGENW("There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed");
- break;
- case MAPI_E_TEXT_TOO_LARGE:
- err = LPGENW("The text in the message was too large");
- break;
- case MAPI_E_TOO_MANY_FILES:
- err = LPGENW("There were too many file attachments");
- break;
- case MAPI_E_TOO_MANY_RECIPIENTS:
- err = LPGENW("There were too many recipients");
- break;
- case MAPI_E_UNKNOWN_RECIPIENT:
- err = LPGENW("A recipient did not appear in the address list");
- break;
- case MAPI_E_USER_ABORT:
- err = LPGENW("The user canceled one of the dialog boxes");
- break;
- default:
- err = LPGENW("Unknown Error");
- break;
- }
- Error(SS_ERR_MAPI, res, err);
- Exit(ACKRESULT_FAILED);
- }
- catch (...) {
- ::FreeLibrary(hMAPILib);
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED);
- return;
- }
-}
-
-void CSendEmail::SendThreadWrapper(void * Obj)
-{
- reinterpret_cast<CSendEmail*>(Obj)->SendThread();
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSendEmail::CSendEmail(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
+ : CSend(Owner, hContact, true)
+{
+ m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_DELETEAFTERSSEND; // SS_DLG_AUTOSEND | ;
+ m_pszSendTyp = LPGENW("Email transfer");
+ m_pszFileA = nullptr;
+ m_pszFileName = nullptr;
+ m_Email = nullptr;
+ m_FriendlyName = nullptr;
+ m_Subject = nullptr;
+}
+
+CSendEmail::~CSendEmail()
+{
+ mir_free(m_pszFileA);
+ mir_free(m_pszFileName);
+ mir_free(m_Email);
+ mir_free(m_FriendlyName);
+ mir_free(m_Subject);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendEmail::Send()
+{
+ if (!m_hContact) return 1;
+ mir_free(m_pszFileName);
+ m_pszFileName = GetFileNameA(m_pszFile);
+
+ mir_free(m_pszFileA);
+ m_pszFileA = mir_u2a(m_pszFile);
+
+ m_Email = mir_u2a(ptrW(Contact::GetInfo(CNF_EMAIL, m_hContact, m_pszProto)));
+ m_FriendlyName = mir_u2a(ptrW(Contact::GetInfo(CNF_DISPLAY, m_hContact, m_pszProto)));
+ m_Subject = mir_u2a(m_pszFileDesc);
+
+ // SendByEmail(m_pszFileA, "", m_FriendlyName, m_Email, m_Subject);
+
+ // start Send thread
+ mir_forkthread(&CSendEmail::SendThreadWrapper, this);
+ return 0;
+}
+
+void CSendEmail::SendThread()
+{
+ // This code based on SentTo.exe application.
+ // The default mail client for Simple MAPI or MAPI calls is defined by the
+ // HKLM\Software\Clients\Mail::(default) registry value.
+
+ MapiFileDesc arrfileDesc[1];
+
+ typedef ULONG(FAR PASCAL *MAPIFUNC)(LHANDLE, ULONG, lpMapiMessage, FLAGS, ULONG);
+ MapiMessage Msg;
+ MAPIFUNC lpMAPISendMail;
+
+ HINSTANCE hMAPILib = ::LoadLibrary(L"MAPI32.DLL");
+ if (hMAPILib == nullptr) {
+ // return -1;
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED); return;
+ }
+
+ lpMAPISendMail = (MAPIFUNC)GetProcAddress(hMAPILib, "MAPISendMail");
+ if (lpMAPISendMail == nullptr) {
+ ::FreeLibrary(hMAPILib);
+ // return -2;
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED); return;
+ }
+
+ memset(&Msg, 0, sizeof(Msg));
+
+ arrfileDesc[0].ulReserved = 0;
+ arrfileDesc[0].flFlags = 0;
+ arrfileDesc[0].lpFileType = nullptr;
+ arrfileDesc[0].nPosition = -1;
+ arrfileDesc[0].lpszPathName = m_pszFileA;
+ arrfileDesc[0].lpszFileName = nullptr;
+
+ Msg.nFileCount = 1;
+ Msg.lpFiles = arrfileDesc;
+ Msg.lpszNoteText = ""; // body
+ Msg.lpszSubject = m_Subject; // subject
+
+ Msg.nRecipCount = 1;
+ MapiRecipDesc recip;
+ recip.ulReserved = 0;
+ recip.ulRecipClass = MAPI_TO;
+
+ if (m_FriendlyName && m_FriendlyName[0] != NULL) {
+ recip.lpszName = m_FriendlyName; // friendly name set to contact's name
+ }
+ else {
+ recip.lpszName = m_Email; // friendly name set to contact's email
+ }
+
+ recip.lpszAddress = m_Email; // email
+ recip.ulEIDSize = 0;
+ recip.lpEntryID = nullptr;
+ Msg.lpRecips = &recip;
+
+ try {
+ int res = lpMAPISendMail(NULL, NULL, &Msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);
+ ::FreeLibrary(hMAPILib);
+
+ wchar_t* err;
+ switch (res) {
+ case SUCCESS_SUCCESS:
+ // The call succeeded and the message was sent.
+ Exit(ACKRESULT_SUCCESS); return;
+ // No message was sent
+ case MAPI_E_AMBIGUOUS_RECIPIENT:
+ err = LPGENW("A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set");
+ break;
+ case MAPI_E_ATTACHMENT_NOT_FOUND:
+ err = LPGENW("The specified attachment was not found");
+ break;
+ case MAPI_E_ATTACHMENT_OPEN_FAILURE:
+ err = LPGENW("The specified attachment could not be opened");
+ break;
+ case MAPI_E_BAD_RECIPTYPE:
+ err = LPGENW("The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC");
+ break;
+ case MAPI_E_FAILURE:
+ err = LPGENW("One or more unspecified errors occurred");
+ break;
+ case MAPI_E_INSUFFICIENT_MEMORY:
+ err = LPGENW("There was insufficient memory to proceed");
+ break;
+ case MAPI_E_INVALID_RECIPS:
+ err = LPGENW("One or more recipients were invalid or did not resolve to any address");
+ break;
+ case MAPI_E_LOGIN_FAILURE:
+ err = LPGENW("There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed");
+ break;
+ case MAPI_E_TEXT_TOO_LARGE:
+ err = LPGENW("The text in the message was too large");
+ break;
+ case MAPI_E_TOO_MANY_FILES:
+ err = LPGENW("There were too many file attachments");
+ break;
+ case MAPI_E_TOO_MANY_RECIPIENTS:
+ err = LPGENW("There were too many recipients");
+ break;
+ case MAPI_E_UNKNOWN_RECIPIENT:
+ err = LPGENW("A recipient did not appear in the address list");
+ break;
+ case MAPI_E_USER_ABORT:
+ err = LPGENW("The user canceled one of the dialog boxes");
+ break;
+ default:
+ err = LPGENW("Unknown Error");
+ break;
+ }
+ Error(SS_ERR_MAPI, res, err);
+ Exit(ACKRESULT_FAILED);
+ }
+ catch (...) {
+ ::FreeLibrary(hMAPILib);
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED);
+ return;
+ }
+}
+
+void CSendEmail::SendThreadWrapper(void * Obj)
+{
+ reinterpret_cast<CSendEmail*>(Obj)->SendThread();
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendEmail.h b/plugins/SendScreenshotPlus/src/CSendEmail.h
index 7e765f747f..1bc852975e 100644
--- a/plugins/SendScreenshotPlus/src/CSendEmail.h
+++ b/plugins/SendScreenshotPlus/src/CSendEmail.h
@@ -1,53 +1,53 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_EMAIL_H
-#define _CSEND_EMAIL_H
-
-class CSendEmail : public CSend
-{
-
-public:
- // Deklaration Standardkonstruktor/Standarddestructor
- CSendEmail(HWND Owner, MCONTACT hContact, bool bAsync);
- ~CSendEmail();
-
- int Send() override;
-
-protected:
- char* m_pszFileA;
- char* m_pszFileName;
- char* m_Email;
- char* m_FriendlyName;
- char* m_Subject;
-
- void SendThread();
- static void SendThreadWrapper(void * Obj);
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_EMAIL_H
+#define _CSEND_EMAIL_H
+
+class CSendEmail : public CSend
+{
+
+public:
+ // Deklaration Standardkonstruktor/Standarddestructor
+ CSendEmail(HWND Owner, MCONTACT hContact, bool bAsync);
+ ~CSendEmail();
+
+ int Send() override;
+
+protected:
+ char* m_pszFileA;
+ char* m_pszFileName;
+ char* m_Email;
+ char* m_FriendlyName;
+ char* m_Subject;
+
+ void SendThread();
+ static void SendThreadWrapper(void * Obj);
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendFTPFile.cpp b/plugins/SendScreenshotPlus/src/CSendFTPFile.cpp
index e4f5cc11d1..1e4ae57e2c 100644
--- a/plugins/SendScreenshotPlus/src/CSendFTPFile.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendFTPFile.cpp
@@ -1,93 +1,93 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSendFTPFile::CSendFTPFile(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
- : CSend(Owner, hContact, true)
-{
- m_EnableItem = 0; //SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
- m_pszSendTyp = LPGENW("FTPFile transfer");
- m_pszFileName = nullptr;
-}
-
-CSendFTPFile::~CSendFTPFile()
-{
- mir_free(m_pszFileName);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendFTPFile::Send()
-{
- if (!m_hContact) return 1;
- /*********************************************************************************************
- * Send file (files) to the FTP server and copy file URL
- * to message log or clipboard (according to plugin setting)
- * wParam = (HANDLE)hContact
- * lParam = (char *)filename
- * Filename format is same as GetOpenFileName (OPENFILENAME.lpstrFile) returns,
- * see http://msdn2.microsoft.com/en-us/library/ms646839.aspx
- * Returns 0 on success or nonzero on failure
- * if (!wParam || !lParam) return 1
- ********************************************************************************************/
- mir_free(m_pszFileName);
- m_pszFileName = GetFileNameA(m_pszFile);
- size_t size = sizeof(char)*(mir_strlen(m_pszFileName) + 2);
- m_pszFileName = (char*)mir_realloc(m_pszFileName, size);
- m_pszFileName[size - 1] = NULL;
-
- // start Send thread
- mir_forkthread(&CSendFTPFile::SendThreadWrapper, this);
- return 0;
-}
-
-void CSendFTPFile::SendThread()
-{
-
- INT_PTR ret = FTPFileUploadA(m_hContact, FNUM_DEFAULT, FMODE_RAWFILE, &m_pszFileName, 1);
- if (ret != 0) {
- Error(LPGENW("%s (%i):\nCould not add a share to the FTP File plugin."), TranslateW(m_pszSendTyp), ret);
- Exit(ret); return;
- }
-
- // Can't delete the file since FTP File plugin will use it
- m_bDeleteAfterSend = false;
-
- if (m_URL && *m_URL) {/// @fixme : m_URL never set
- svcSendMsgExit(m_URL); return;
- }
- Exit(ACKRESULT_FAILED);
-}
-
-void CSendFTPFile::SendThreadWrapper(void * Obj)
-{
- reinterpret_cast<CSendFTPFile*>(Obj)->SendThread();
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSendFTPFile::CSendFTPFile(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
+ : CSend(Owner, hContact, true)
+{
+ m_EnableItem = 0; //SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
+ m_pszSendTyp = LPGENW("FTPFile transfer");
+ m_pszFileName = nullptr;
+}
+
+CSendFTPFile::~CSendFTPFile()
+{
+ mir_free(m_pszFileName);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendFTPFile::Send()
+{
+ if (!m_hContact) return 1;
+ /*********************************************************************************************
+ * Send file (files) to the FTP server and copy file URL
+ * to message log or clipboard (according to plugin setting)
+ * wParam = (HANDLE)hContact
+ * lParam = (char *)filename
+ * Filename format is same as GetOpenFileName (OPENFILENAME.lpstrFile) returns,
+ * see http://msdn2.microsoft.com/en-us/library/ms646839.aspx
+ * Returns 0 on success or nonzero on failure
+ * if (!wParam || !lParam) return 1
+ ********************************************************************************************/
+ mir_free(m_pszFileName);
+ m_pszFileName = GetFileNameA(m_pszFile);
+ size_t size = sizeof(char)*(mir_strlen(m_pszFileName) + 2);
+ m_pszFileName = (char*)mir_realloc(m_pszFileName, size);
+ m_pszFileName[size - 1] = NULL;
+
+ // start Send thread
+ mir_forkthread(&CSendFTPFile::SendThreadWrapper, this);
+ return 0;
+}
+
+void CSendFTPFile::SendThread()
+{
+
+ INT_PTR ret = FTPFileUploadA(m_hContact, FNUM_DEFAULT, FMODE_RAWFILE, &m_pszFileName, 1);
+ if (ret != 0) {
+ Error(LPGENW("%s (%i):\nCould not add a share to the FTP File plugin."), TranslateW(m_pszSendTyp), ret);
+ Exit(ret); return;
+ }
+
+ // Can't delete the file since FTP File plugin will use it
+ m_bDeleteAfterSend = false;
+
+ if (m_URL && *m_URL) {/// @fixme : m_URL never set
+ svcSendMsgExit(m_URL); return;
+ }
+ Exit(ACKRESULT_FAILED);
+}
+
+void CSendFTPFile::SendThreadWrapper(void * Obj)
+{
+ reinterpret_cast<CSendFTPFile*>(Obj)->SendThread();
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendFTPFile.h b/plugins/SendScreenshotPlus/src/CSendFTPFile.h
index 9094f3f4f7..b57f9243b2 100644
--- a/plugins/SendScreenshotPlus/src/CSendFTPFile.h
+++ b/plugins/SendScreenshotPlus/src/CSendFTPFile.h
@@ -1,48 +1,48 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_FTP_FILE_H
-#define _CSEND_FTP_FILE_H
-
-class CSendFTPFile : public CSend
-{
-
-public:
- // Deklaration Standardkonstruktor/Standarddestructor
- CSendFTPFile(HWND Owner, MCONTACT hContact, bool bAsync);
- ~CSendFTPFile();
-
- int Send() override;
-
-protected:
- char* m_pszFileName;
- void SendThread();
- static void SendThreadWrapper(void * Obj);
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_FTP_FILE_H
+#define _CSEND_FTP_FILE_H
+
+class CSendFTPFile : public CSend
+{
+
+public:
+ // Deklaration Standardkonstruktor/Standarddestructor
+ CSendFTPFile(HWND Owner, MCONTACT hContact, bool bAsync);
+ ~CSendFTPFile();
+
+ int Send() override;
+
+protected:
+ char* m_pszFileName;
+ void SendThread();
+ static void SendThreadWrapper(void * Obj);
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendFile.cpp b/plugins/SendScreenshotPlus/src/CSendFile.cpp
index 550ad4bda4..ed1500a03f 100644
--- a/plugins/SendScreenshotPlus/src/CSendFile.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendFile.cpp
@@ -1,50 +1,50 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSendFile::CSendFile(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
- : CSend(Owner, hContact, true)
-{
- m_EnableItem = SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND | SS_DLG_DESCRIPTION;
- m_pszSendTyp = LPGENW("File transfer");
-}
-
-CSendFile::~CSendFile()
-{
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendFile::Send()
-{
- svcSendFileExit();
- return 0;
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSendFile::CSendFile(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
+ : CSend(Owner, hContact, true)
+{
+ m_EnableItem = SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND | SS_DLG_DESCRIPTION;
+ m_pszSendTyp = LPGENW("File transfer");
+}
+
+CSendFile::~CSendFile()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendFile::Send()
+{
+ svcSendFileExit();
+ return 0;
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendFile.h b/plugins/SendScreenshotPlus/src/CSendFile.h
index b30a1ce6e3..e2b7462725 100644
--- a/plugins/SendScreenshotPlus/src/CSendFile.h
+++ b/plugins/SendScreenshotPlus/src/CSendFile.h
@@ -1,43 +1,43 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_FILE_H
-#define _CSEND_FILE_H
-
-class CSendFile : public CSend
-{
-
-public:
- // Deklaration Standardkonstruktor/Standarddestructor
- CSendFile(HWND Owner, MCONTACT hContact, bool bAsync);
- ~CSendFile();
-
- int Send() override;
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_FILE_H
+#define _CSEND_FILE_H
+
+class CSendFile : public CSend
+{
+
+public:
+ // Deklaration Standardkonstruktor/Standarddestructor
+ CSendFile(HWND Owner, MCONTACT hContact, bool bAsync);
+ ~CSendFile();
+
+ int Send() override;
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendHTTPServer.cpp b/plugins/SendScreenshotPlus/src/CSendHTTPServer.cpp
index 9075d70951..7815d49bfb 100644
--- a/plugins/SendScreenshotPlus/src/CSendHTTPServer.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHTTPServer.cpp
@@ -1,117 +1,117 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-INT_PTR(*g_MirCallService)(const char *, WPARAM, LPARAM) = nullptr;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSendHTTPServer::CSendHTTPServer(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
- : CSend(Owner, hContact, true)
-{
- m_EnableItem = SS_DLG_DESCRIPTION; //| SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
- m_pszSendTyp = LPGENW("HTTPServer transfer");
- m_pszFileName = nullptr;
- m_fsi_pszRealPath = nullptr;
-}
-
-CSendHTTPServer::~CSendHTTPServer()
-{
- mir_free(m_pszFileName);
- mir_free(m_fsi_pszRealPath);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendHTTPServer::Send()
-{
- if (!m_hContact) return 1;
- if (CallService(MS_HTTP_ACCEPT_CONNECTIONS, TRUE, 0) != 0) {
- Error(LPGENW("Could not start the HTTP Server plugin."));
- Exit(ACKRESULT_FAILED);
- return !m_bAsync;
- }
-
- if (!m_pszFileName) {
- m_pszFileName = GetFileNameA(m_pszFile);
- }
-
- m_fsi_pszSrvPath.Empty();
- m_fsi_pszSrvPath.AppendChar('/');
- m_fsi_pszSrvPath.Append(m_pszFileName);
-
- replaceStr(m_fsi_pszRealPath, _T2A(m_pszFile));
-
- memset(&m_fsi, 0, sizeof(m_fsi));
- m_fsi.lStructSize = sizeof(STFileShareInfo);
- m_fsi.nMaxDownloads = -1; // -1 = infinite
- m_fsi.pszRealPath = m_fsi_pszRealPath;
-
- // start Send thread
- mir_forkthread(&CSendHTTPServer::SendThreadWrapper, this);
- return 0;
-}
-
-void CSendHTTPServer::SendThread()
-{
- INT_PTR ret;
-
- if (ServiceExists(MS_HTTP_GET_LINK)) {
- // patched plugin version
- ret = CallService(MS_HTTP_ADD_CHANGE_REMOVE, (WPARAM)m_hContact, (LPARAM)&m_fsi);
- if (!ret) {
- m_URL = ptrA((char*)CallService(MS_HTTP_GET_LINK, (WPARAM)m_fsi.pszSrvPath, 0));
- }
- }
- else {
- // original plugin
- m_fsi.dwOptions = OPT_SEND_LINK;
-
- // send DATA and wait for reply
- ret = CallService(MS_HTTP_ADD_CHANGE_REMOVE, (WPARAM)m_hContact, (LPARAM)&m_fsi);
- }
-
- if (ret != 0) {
- Error(LPGENW("%s (%i):\nCould not add a share to the HTTP Server plugin."), TranslateW(m_pszSendTyp), ret);
- Exit(ret); return;
- }
-
- // Share the file by HTTP Server plugin, SendSS does not own the file anymore = auto-delete won't work
- m_bDeleteAfterSend = false;
-
- if (m_URL && *m_URL) {
- svcSendMsgExit(m_URL); return;
- }
- Exit(ACKRESULT_FAILED);
-}
-
-void CSendHTTPServer::SendThreadWrapper(void * Obj)
-{
- reinterpret_cast<CSendHTTPServer*>(Obj)->SendThread();
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+INT_PTR(*g_MirCallService)(const char *, WPARAM, LPARAM) = nullptr;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSendHTTPServer::CSendHTTPServer(HWND Owner, MCONTACT hContact, bool /*bAsync*/)
+ : CSend(Owner, hContact, true)
+{
+ m_EnableItem = SS_DLG_DESCRIPTION; //| SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
+ m_pszSendTyp = LPGENW("HTTPServer transfer");
+ m_pszFileName = nullptr;
+ m_fsi_pszRealPath = nullptr;
+}
+
+CSendHTTPServer::~CSendHTTPServer()
+{
+ mir_free(m_pszFileName);
+ mir_free(m_fsi_pszRealPath);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendHTTPServer::Send()
+{
+ if (!m_hContact) return 1;
+ if (CallService(MS_HTTP_ACCEPT_CONNECTIONS, TRUE, 0) != 0) {
+ Error(LPGENW("Could not start the HTTP Server plugin."));
+ Exit(ACKRESULT_FAILED);
+ return !m_bAsync;
+ }
+
+ if (!m_pszFileName) {
+ m_pszFileName = GetFileNameA(m_pszFile);
+ }
+
+ m_fsi_pszSrvPath.Empty();
+ m_fsi_pszSrvPath.AppendChar('/');
+ m_fsi_pszSrvPath.Append(m_pszFileName);
+
+ replaceStr(m_fsi_pszRealPath, _T2A(m_pszFile));
+
+ memset(&m_fsi, 0, sizeof(m_fsi));
+ m_fsi.lStructSize = sizeof(STFileShareInfo);
+ m_fsi.nMaxDownloads = -1; // -1 = infinite
+ m_fsi.pszRealPath = m_fsi_pszRealPath;
+
+ // start Send thread
+ mir_forkthread(&CSendHTTPServer::SendThreadWrapper, this);
+ return 0;
+}
+
+void CSendHTTPServer::SendThread()
+{
+ INT_PTR ret;
+
+ if (ServiceExists(MS_HTTP_GET_LINK)) {
+ // patched plugin version
+ ret = CallService(MS_HTTP_ADD_CHANGE_REMOVE, (WPARAM)m_hContact, (LPARAM)&m_fsi);
+ if (!ret) {
+ m_URL = ptrA((char*)CallService(MS_HTTP_GET_LINK, (WPARAM)m_fsi.pszSrvPath, 0));
+ }
+ }
+ else {
+ // original plugin
+ m_fsi.dwOptions = OPT_SEND_LINK;
+
+ // send DATA and wait for reply
+ ret = CallService(MS_HTTP_ADD_CHANGE_REMOVE, (WPARAM)m_hContact, (LPARAM)&m_fsi);
+ }
+
+ if (ret != 0) {
+ Error(LPGENW("%s (%i):\nCould not add a share to the HTTP Server plugin."), TranslateW(m_pszSendTyp), ret);
+ Exit(ret); return;
+ }
+
+ // Share the file by HTTP Server plugin, SendSS does not own the file anymore = auto-delete won't work
+ m_bDeleteAfterSend = false;
+
+ if (m_URL && *m_URL) {
+ svcSendMsgExit(m_URL); return;
+ }
+ Exit(ACKRESULT_FAILED);
+}
+
+void CSendHTTPServer::SendThreadWrapper(void * Obj)
+{
+ reinterpret_cast<CSendHTTPServer*>(Obj)->SendThread();
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendHTTPServer.h b/plugins/SendScreenshotPlus/src/CSendHTTPServer.h
index e11ac3fae0..aa5dec4030 100644
--- a/plugins/SendScreenshotPlus/src/CSendHTTPServer.h
+++ b/plugins/SendScreenshotPlus/src/CSendHTTPServer.h
@@ -1,55 +1,55 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_HTTP_SERVER_H
-#define _CSEND_HTTP_SERVER_H
-
-class CSendHTTPServer : public CSend
-{
-public:
- // Deklaration Standardkonstruktor/Standarddestructor
- CSendHTTPServer(HWND Owner, MCONTACT hContact, bool bAsync);
- ~CSendHTTPServer();
-
- int Send() override;
-
-protected:
- char* m_pszFileName;
- CMStringA m_fsi_pszSrvPath;
- char* m_fsi_pszRealPath;
-
- STFileShareInfo m_fsi;
-
- void SendThread();
- static void SendThreadWrapper(void * Obj);
-
- typedef std::map<HANDLE, CSendHTTPServer *> CContactMapping;
- static CContactMapping _CContactMapping;
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_HTTP_SERVER_H
+#define _CSEND_HTTP_SERVER_H
+
+class CSendHTTPServer : public CSend
+{
+public:
+ // Deklaration Standardkonstruktor/Standarddestructor
+ CSendHTTPServer(HWND Owner, MCONTACT hContact, bool bAsync);
+ ~CSendHTTPServer();
+
+ int Send() override;
+
+protected:
+ char* m_pszFileName;
+ CMStringA m_fsi_pszSrvPath;
+ char* m_fsi_pszRealPath;
+
+ STFileShareInfo m_fsi;
+
+ void SendThread();
+ static void SendThreadWrapper(void * Obj);
+
+ typedef std::map<HANDLE, CSendHTTPServer *> CContactMapping;
+ static CContactMapping _CContactMapping;
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp
index 7940487e88..5a2a4d8a34 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp
@@ -1,118 +1,118 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CSendHost_ImageShack::CSendHost_ImageShack(HWND Owner, MCONTACT hContact, bool bAsync)
- : CSend(Owner, hContact, bAsync)
-{
- m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
- m_pszSendTyp = LPGENW("Image upload");
-}
-
-CSendHost_ImageShack::~CSendHost_ImageShack()
-{
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendHost_ImageShack::Send()
-{
- if (!g_hNetlibUser) { // check Netlib
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED);
- return !m_bAsync;
- }
- memset(&m_nlhr, 0, sizeof(m_nlhr));
- char* tmp; tmp = mir_u2a(m_pszFile);
- HTTPFormData frm[] = {
- // { "Referer", HTTPFORM_HEADER("http://www.imageshack.us/upload_api.php") },
- { "fileupload", HTTPFORM_FILE(tmp) },
- // { "rembar", "yes" },// no info bar on thumb
- { "public", "no" },
- { "key", HTTPFORM_8BIT(DEVKEY_IMAGESHACK) },
- };
- int error = HTTPFormCreate(&m_nlhr, REQUEST_POST, "http://imageshack.us/upload_api.php", frm, sizeof(frm) / sizeof(HTTPFormData));
- mir_free(tmp);
- if (error)
- return !m_bAsync;
- // start upload thread
- if (m_bAsync) {
- mir_forkthread(&CSendHost_ImageShack::SendThreadWrapper, this);
- return 0;
- }
- SendThread();
- return 1;
-}
-
-void CSendHost_ImageShack::SendThread()
-{
- // send DATA and wait for m_nlreply
- NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &m_nlhr));
- HTTPFormDestroy(&m_nlhr);
- if (reply) {
- if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->dataLength) {
- reply->pData[reply->dataLength - 1] = '\0'; // make sure its null terminated
- const char* url = nullptr;
- url = GetHTMLContent(reply->pData, "<image_link>", "</image_link>");
- if (url && *url) {
- m_URLthumb = m_URL = url;
-
- int idx = m_URLthumb.ReverseFind('.');
- if (idx != -1 && m_URLthumb.GetLength() - idx > 2)
- m_URLthumb.Insert(idx + 1, "th");
- else
- m_URLthumb.Empty();
-
- svcSendMsgExit(url);
- return;
- }
-
- url = GetHTMLContent(reply->pData, "<error ", "</error>");
- wchar_t* err = nullptr;
- if (url) err = mir_a2u(url);
- if (!err || !*err) { // fallback to server response mess
- mir_free(err);
- err = mir_a2u(reply->pData);
- }
- Error(L"%s", err);
- mir_free(err);
- }
- else Error(SS_ERR_RESPONSE, m_pszSendTyp, reply->resultCode);
- }
- else Error(SS_ERR_NORESPONSE, m_pszSendTyp, m_nlhr.resultCode);
-
- Exit(ACKRESULT_FAILED);
-}
-
-void CSendHost_ImageShack::SendThreadWrapper(void * Obj)
-{
- reinterpret_cast<CSendHost_ImageShack*>(Obj)->SendThread();
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CSendHost_ImageShack::CSendHost_ImageShack(HWND Owner, MCONTACT hContact, bool bAsync)
+ : CSend(Owner, hContact, bAsync)
+{
+ m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
+ m_pszSendTyp = LPGENW("Image upload");
+}
+
+CSendHost_ImageShack::~CSendHost_ImageShack()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendHost_ImageShack::Send()
+{
+ if (!g_hNetlibUser) { // check Netlib
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED);
+ return !m_bAsync;
+ }
+ memset(&m_nlhr, 0, sizeof(m_nlhr));
+ char* tmp; tmp = mir_u2a(m_pszFile);
+ HTTPFormData frm[] = {
+ // { "Referer", HTTPFORM_HEADER("http://www.imageshack.us/upload_api.php") },
+ { "fileupload", HTTPFORM_FILE(tmp) },
+ // { "rembar", "yes" },// no info bar on thumb
+ { "public", "no" },
+ { "key", HTTPFORM_8BIT(DEVKEY_IMAGESHACK) },
+ };
+ int error = HTTPFormCreate(&m_nlhr, REQUEST_POST, "http://imageshack.us/upload_api.php", frm, sizeof(frm) / sizeof(HTTPFormData));
+ mir_free(tmp);
+ if (error)
+ return !m_bAsync;
+ // start upload thread
+ if (m_bAsync) {
+ mir_forkthread(&CSendHost_ImageShack::SendThreadWrapper, this);
+ return 0;
+ }
+ SendThread();
+ return 1;
+}
+
+void CSendHost_ImageShack::SendThread()
+{
+ // send DATA and wait for m_nlreply
+ NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &m_nlhr));
+ HTTPFormDestroy(&m_nlhr);
+ if (reply) {
+ if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->dataLength) {
+ reply->pData[reply->dataLength - 1] = '\0'; // make sure its null terminated
+ const char* url = nullptr;
+ url = GetHTMLContent(reply->pData, "<image_link>", "</image_link>");
+ if (url && *url) {
+ m_URLthumb = m_URL = url;
+
+ int idx = m_URLthumb.ReverseFind('.');
+ if (idx != -1 && m_URLthumb.GetLength() - idx > 2)
+ m_URLthumb.Insert(idx + 1, "th");
+ else
+ m_URLthumb.Empty();
+
+ svcSendMsgExit(url);
+ return;
+ }
+
+ url = GetHTMLContent(reply->pData, "<error ", "</error>");
+ wchar_t* err = nullptr;
+ if (url) err = mir_a2u(url);
+ if (!err || !*err) { // fallback to server response mess
+ mir_free(err);
+ err = mir_a2u(reply->pData);
+ }
+ Error(L"%s", err);
+ mir_free(err);
+ }
+ else Error(SS_ERR_RESPONSE, m_pszSendTyp, reply->resultCode);
+ }
+ else Error(SS_ERR_NORESPONSE, m_pszSendTyp, m_nlhr.resultCode);
+
+ Exit(ACKRESULT_FAILED);
+}
+
+void CSendHost_ImageShack::SendThreadWrapper(void * Obj)
+{
+ reinterpret_cast<CSendHost_ImageShack*>(Obj)->SendThread();
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h
index a03647c063..7c58094aac 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h
+++ b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h
@@ -1,49 +1,49 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef _CSEND_IMAGESHACK_H
-#define _CSEND_IMAGESHACK_H
-
-class CSendHost_ImageShack : public CSend
-{
-
-public:
- // Deklaration Standardkonstruktor/Standarddestructor
- CSendHost_ImageShack(HWND Owner, MCONTACT hContact, bool bAsync);
- ~CSendHost_ImageShack();
-
- int Send() override;
-
-protected:
- NETLIBHTTPREQUEST m_nlhr;
-
- void SendThread();
- static void SendThreadWrapper(void * Obj);
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef _CSEND_IMAGESHACK_H
+#define _CSEND_IMAGESHACK_H
+
+class CSendHost_ImageShack : public CSend
+{
+
+public:
+ // Deklaration Standardkonstruktor/Standarddestructor
+ CSendHost_ImageShack(HWND Owner, MCONTACT hContact, bool bAsync);
+ ~CSendHost_ImageShack();
+
+ int Send() override;
+
+protected:
+ NETLIBHTTPREQUEST m_nlhr;
+
+ void SendThread();
+ static void SendThreadWrapper(void * Obj);
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp b/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp
index 4aa5ccc44f..bde9f158bb 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp
@@ -1,86 +1,86 @@
-/*
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- Version 2, December 2004
-
- Copyright (C) 2014-22 Miranda NG team (https://miranda-ng.org)
-
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
-
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. You just DO WHAT THE FUCK YOU WANT TO.
-*/
-#include "stdafx.h"
-
-CSendHost_Imgur::CSendHost_Imgur(HWND Owner, MCONTACT hContact, bool bAsync)
- : CSend(Owner, hContact, bAsync)
-{
- m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
- m_pszSendTyp = LPGENW("Image upload");
-}
-
-CSendHost_Imgur::~CSendHost_Imgur()
-{
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CSendHost_Imgur::Send()
-{
- if (!g_hNetlibUser) { // check Netlib
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED);
- return !m_bAsync;
- }
- memset(&m_nlhr, 0, sizeof(m_nlhr));
- char* tmp; tmp = mir_u2a(m_pszFile);
- HTTPFormData frm[] = {
- { "Authorization", HTTPFORM_HEADER("Client-ID 2a7303d78abe041") },
- { "image", HTTPFORM_FILE(tmp) },
- };
-
- int error = HTTPFormCreate(&m_nlhr, REQUEST_POST, "https://api.imgur.com/3/image", frm, _countof(frm));
- mir_free(tmp);
- if (error)
- return !m_bAsync;
- // start upload thread
- if (m_bAsync) {
- mir_forkthread(&CSendHost_Imgur::SendThread, this);
- return 0;
- }
- SendThread(this);
- return 1;
-}
-
-void CSendHost_Imgur::SendThread(void* obj)
-{
- CSendHost_Imgur *self = (CSendHost_Imgur*)obj;
- // send DATA and wait for m_nlreply
- NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &self->m_nlhr));
- self->HTTPFormDestroy(&self->m_nlhr);
- if (reply) {
- if (reply->dataLength) {
- JSONROOT root(reply->pData);
- if (root) {
- if ((*root)["success"].as_bool()) {
- self->m_URL = (*root)["data"]["link"].as_mstring();
- int idx = self->m_URL.ReverseFind('.');
- if (idx != -1) {
- self->m_URLthumb = self->m_URL;
- self->m_URLthumb.Insert(idx, 'm');
- }
- self->svcSendMsgExit(self->m_URL); return;
- }
- else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, (*root)["status"].as_int(), 0);
- }
- else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
- }
- else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
- }
- else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, self->m_nlhr.resultCode);
-
- self->Exit(ACKRESULT_FAILED);
-}
+/*
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2014-23 Miranda NG team (https://miranda-ng.org)
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+*/
+#include "stdafx.h"
+
+CSendHost_Imgur::CSendHost_Imgur(HWND Owner, MCONTACT hContact, bool bAsync)
+ : CSend(Owner, hContact, bAsync)
+{
+ m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
+ m_pszSendTyp = LPGENW("Image upload");
+}
+
+CSendHost_Imgur::~CSendHost_Imgur()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CSendHost_Imgur::Send()
+{
+ if (!g_hNetlibUser) { // check Netlib
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED);
+ return !m_bAsync;
+ }
+ memset(&m_nlhr, 0, sizeof(m_nlhr));
+ char* tmp; tmp = mir_u2a(m_pszFile);
+ HTTPFormData frm[] = {
+ { "Authorization", HTTPFORM_HEADER("Client-ID 2a7303d78abe041") },
+ { "image", HTTPFORM_FILE(tmp) },
+ };
+
+ int error = HTTPFormCreate(&m_nlhr, REQUEST_POST, "https://api.imgur.com/3/image", frm, _countof(frm));
+ mir_free(tmp);
+ if (error)
+ return !m_bAsync;
+ // start upload thread
+ if (m_bAsync) {
+ mir_forkthread(&CSendHost_Imgur::SendThread, this);
+ return 0;
+ }
+ SendThread(this);
+ return 1;
+}
+
+void CSendHost_Imgur::SendThread(void* obj)
+{
+ CSendHost_Imgur *self = (CSendHost_Imgur*)obj;
+ // send DATA and wait for m_nlreply
+ NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &self->m_nlhr));
+ self->HTTPFormDestroy(&self->m_nlhr);
+ if (reply) {
+ if (reply->dataLength) {
+ JSONROOT root(reply->pData);
+ if (root) {
+ if ((*root)["success"].as_bool()) {
+ self->m_URL = (*root)["data"]["link"].as_mstring();
+ int idx = self->m_URL.ReverseFind('.');
+ if (idx != -1) {
+ self->m_URLthumb = self->m_URL;
+ self->m_URLthumb.Insert(idx, 'm');
+ }
+ self->svcSendMsgExit(self->m_URL); return;
+ }
+ else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, (*root)["status"].as_int(), 0);
+ }
+ else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
+ }
+ else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
+ }
+ else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, self->m_nlhr.resultCode);
+
+ self->Exit(ACKRESULT_FAILED);
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_imgur.h b/plugins/SendScreenshotPlus/src/CSendHost_imgur.h
index b64b118391..544afecd53 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_imgur.h
+++ b/plugins/SendScreenshotPlus/src/CSendHost_imgur.h
@@ -1,30 +1,30 @@
-/*
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- Version 2, December 2004
-
- Copyright (C) 2014-22 Miranda NG team (https://miranda-ng.org)
-
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
-
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. You just DO WHAT THE FUCK YOU WANT TO.
-*/
-#ifndef _CSEND_HOST_IMGUR_H
-#define _CSEND_HOST_IMGUR_H
-class CSendHost_Imgur : public CSend {
-// API: http://api.imgur.com/endpoints/image
- public:
- CSendHost_Imgur(HWND Owner, MCONTACT hContact, bool bAsync);
- ~CSendHost_Imgur();
-
- int Send() override;
-
- protected:
- NETLIBHTTPREQUEST m_nlhr;
- static void SendThread(void* obj);
-};
-#endif
+/*
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2014-23 Miranda NG team (https://miranda-ng.org)
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+*/
+#ifndef _CSEND_HOST_IMGUR_H
+#define _CSEND_HOST_IMGUR_H
+class CSendHost_Imgur : public CSend {
+// API: http://api.imgur.com/endpoints/image
+ public:
+ CSendHost_Imgur(HWND Owner, MCONTACT hContact, bool bAsync);
+ ~CSendHost_Imgur();
+
+ int Send() override;
+
+ protected:
+ NETLIBHTTPREQUEST m_nlhr;
+ static void SendThread(void* obj);
+};
+#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp
index 0b6c6c2311..58651ae85d 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp
@@ -1,105 +1,105 @@
-/*
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- Version 2, December 2004
-
- Copyright (C) 2014-22 Miranda NG team (https://miranda-ng.org)
-
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
-
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. You just DO WHAT THE FUCK YOU WANT TO.
-*/
-#include "stdafx.h"
-
-CSendHost_UploadPie::CSendHost_UploadPie(HWND Owner, MCONTACT hContact, bool bAsync, int expire)
- : m_expire(expire), CSend(Owner, hContact, bAsync)
-{
- m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
- m_pszSendTyp = LPGENW("Image upload");
-}
-
-CSendHost_UploadPie::~CSendHost_UploadPie()
-{
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static const char kHostURL[] = "https://uploadpie.com/";
-
-int CSendHost_UploadPie::Send()
-{
- if (!g_hNetlibUser) { // check Netlib
- Error(SS_ERR_INIT, m_pszSendTyp);
- Exit(ACKRESULT_FAILED);
- return !m_bAsync;
- }
- memset(&m_nlhr, 0, sizeof(m_nlhr));
- char* tmp; tmp = mir_u2a(m_pszFile);
- HTTPFormData frm[] = {
- { "MAX_FILE_SIZE", HTTPFORM_INT(3145728) },
- { "upload", HTTPFORM_INT(1) },
- { "uploadedfile", HTTPFORM_FILE(tmp) },
- { "expire", HTTPFORM_INT(m_expire) },
- };
-
- int error = HTTPFormCreate(&m_nlhr, REQUEST_POST, kHostURL, frm, _countof(frm));
- mir_free(tmp);
- if (error)
- return !m_bAsync;
-
- // start upload thread
- if (m_bAsync) {
- mir_forkthread(&CSendHost_UploadPie::SendThread, this);
- return 0;
- }
- SendThread(this);
- return 1;
-}
-
-void CSendHost_UploadPie::SendThread(void* obj)
-{
- CSendHost_UploadPie* self = (CSendHost_UploadPie*)obj;
- // send DATA and wait for m_nlreply
- NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &self->m_nlhr));
- self->HTTPFormDestroy(&self->m_nlhr);
- if (reply) {
- if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->dataLength) {
- reply->pData[reply->dataLength - 1] = '\0'; // make sure its null terminated
- char* url = reply->pData;
- do {
- char* pos;
- if ((url = strstr(url, kHostURL))) {
- for (pos = url + _countof(kHostURL)-1; (*pos >= '0'&&*pos <= '9') || (*pos >= 'a'&&*pos <= 'z') || (*pos >= 'A'&&*pos <= 'Z') || *pos == '_' || *pos == '-' || *pos == '"' || *pos == '\''; ++pos) {
- if (*pos == '"' || *pos == '\'') break;
- }
- if (url + _countof(kHostURL)-1 != pos && (*pos == '"' || *pos == '\'')) {
- *pos = '\0';
- break;
- }
- ++url;
- }
- } while (url);
-
- if (url) {
- self->m_URL = url;
- self->svcSendMsgExit(url); return;
- }
- else { // check error mess from server
- const char* err = GetHTMLContent(reply->pData, "<p id=\"error\"", "</p>");
- wchar_t* werr;
- if (err) werr = mir_a2u(err);
- else werr = mir_a2u(reply->pData);
- self->Error(L"%s", werr);
- mir_free(werr);
- }
- }
- else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
- }
- else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, self->m_nlhr.resultCode);
-
- self->Exit(ACKRESULT_FAILED);
-}
+/*
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2014-23 Miranda NG team (https://miranda-ng.org)
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+*/
+#include "stdafx.h"
+
+CSendHost_UploadPie::CSendHost_UploadPie(HWND Owner, MCONTACT hContact, bool bAsync, int expire)
+ : m_expire(expire), CSend(Owner, hContact, bAsync)
+{
+ m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
+ m_pszSendTyp = LPGENW("Image upload");
+}
+
+CSendHost_UploadPie::~CSendHost_UploadPie()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static const char kHostURL[] = "https://uploadpie.com/";
+
+int CSendHost_UploadPie::Send()
+{
+ if (!g_hNetlibUser) { // check Netlib
+ Error(SS_ERR_INIT, m_pszSendTyp);
+ Exit(ACKRESULT_FAILED);
+ return !m_bAsync;
+ }
+ memset(&m_nlhr, 0, sizeof(m_nlhr));
+ char* tmp; tmp = mir_u2a(m_pszFile);
+ HTTPFormData frm[] = {
+ { "MAX_FILE_SIZE", HTTPFORM_INT(3145728) },
+ { "upload", HTTPFORM_INT(1) },
+ { "uploadedfile", HTTPFORM_FILE(tmp) },
+ { "expire", HTTPFORM_INT(m_expire) },
+ };
+
+ int error = HTTPFormCreate(&m_nlhr, REQUEST_POST, kHostURL, frm, _countof(frm));
+ mir_free(tmp);
+ if (error)
+ return !m_bAsync;
+
+ // start upload thread
+ if (m_bAsync) {
+ mir_forkthread(&CSendHost_UploadPie::SendThread, this);
+ return 0;
+ }
+ SendThread(this);
+ return 1;
+}
+
+void CSendHost_UploadPie::SendThread(void* obj)
+{
+ CSendHost_UploadPie* self = (CSendHost_UploadPie*)obj;
+ // send DATA and wait for m_nlreply
+ NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &self->m_nlhr));
+ self->HTTPFormDestroy(&self->m_nlhr);
+ if (reply) {
+ if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->dataLength) {
+ reply->pData[reply->dataLength - 1] = '\0'; // make sure its null terminated
+ char* url = reply->pData;
+ do {
+ char* pos;
+ if ((url = strstr(url, kHostURL))) {
+ for (pos = url + _countof(kHostURL)-1; (*pos >= '0'&&*pos <= '9') || (*pos >= 'a'&&*pos <= 'z') || (*pos >= 'A'&&*pos <= 'Z') || *pos == '_' || *pos == '-' || *pos == '"' || *pos == '\''; ++pos) {
+ if (*pos == '"' || *pos == '\'') break;
+ }
+ if (url + _countof(kHostURL)-1 != pos && (*pos == '"' || *pos == '\'')) {
+ *pos = '\0';
+ break;
+ }
+ ++url;
+ }
+ } while (url);
+
+ if (url) {
+ self->m_URL = url;
+ self->svcSendMsgExit(url); return;
+ }
+ else { // check error mess from server
+ const char* err = GetHTMLContent(reply->pData, "<p id=\"error\"", "</p>");
+ wchar_t* werr;
+ if (err) werr = mir_a2u(err);
+ else werr = mir_a2u(reply->pData);
+ self->Error(L"%s", werr);
+ mir_free(werr);
+ }
+ }
+ else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
+ }
+ else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, self->m_nlhr.resultCode);
+
+ self->Exit(ACKRESULT_FAILED);
+}
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h
index b1defe20c2..94cfdf1fbc 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h
+++ b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h
@@ -1,30 +1,30 @@
-/*
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- Version 2, December 2004
-
- Copyright (C) 2014-22 Miranda NG team (https://miranda-ng.org)
-
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
-
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. You just DO WHAT THE FUCK YOU WANT TO.
-*/
-#ifndef _CSEND_HOST_UPLOADPIE_H
-#define _CSEND_HOST_UPLOADPIE_H
-class CSendHost_UploadPie : public CSend {
- public:
- CSendHost_UploadPie(HWND Owner, MCONTACT hContact, bool bAsync, int expire);
- ~CSendHost_UploadPie();
-
- int Send() override;
-
- protected:
- int m_expire;
- NETLIBHTTPREQUEST m_nlhr;
- static void SendThread(void* obj);
-};
-#endif
+/*
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2014-23 Miranda NG team (https://miranda-ng.org)
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+*/
+#ifndef _CSEND_HOST_UPLOADPIE_H
+#define _CSEND_HOST_UPLOADPIE_H
+class CSendHost_UploadPie : public CSend {
+ public:
+ CSendHost_UploadPie(HWND Owner, MCONTACT hContact, bool bAsync, int expire);
+ ~CSendHost_UploadPie();
+
+ int Send() override;
+
+ protected:
+ int m_expire;
+ NETLIBHTTPREQUEST m_nlhr;
+ static void SendThread(void* obj);
+};
+#endif
diff --git a/plugins/SendScreenshotPlus/src/Main.cpp b/plugins/SendScreenshotPlus/src/Main.cpp
index e3223f43cc..f2455932b2 100644
--- a/plugins/SendScreenshotPlus/src/Main.cpp
+++ b/plugins/SendScreenshotPlus/src/Main.cpp
@@ -1,336 +1,336 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original source code
-(c) 2004-2006 Sérgio Vieira Rolanski (ported from Borland C++)
-
-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"
-
-// Prototypes ///////////////////////////////////////////////////////////////////////////
-
-CMPlugin g_plugin;
-HGENMENU g_hMenu1, g_hMenu2;
-
-ATOM g_clsTargetHighlighter = 0;
-MGLOBAL g_myGlobals;
-HNETLIBUSER g_hNetlibUser;
-
-IconItem ICONS[ICO_END_] =
-{
- { LPGEN("Main Icon"), "main", IDI_MAIN, 32 },
- { LPGEN("Main Icon"), "mainxs", IDI_MAIN },
- { LPGEN("Target Cursor"), "target", IDI_TARGET, 32 },
- { LPGEN("Target Desktop"), "monitor", IDI_MONITOR, 32 },
-};
-
-IconItem ICONS_BTN[ICO_BTN_END_] =
-{
- { LPGEN("Help"), "help", IDI_HELP },
- { LPGEN("Open Folder"), "folder", IDI_FOLDER },
- { LPGEN("Description off"), "desc", IDI_DESC },
- { LPGEN("Description on"), "descon", IDI_DESCON },
- { LPGEN("Delete off"), "del", IDI_DEL },
- { LPGEN("Delete on"), "delon", IDI_DELON },
- { LPGEN("Prev"), "arrowl", IDI_ARROWL },
- { LPGEN("Next"), "arrowr", IDI_ARROWR },
- { LPGEN("Update"), "update", IDI_UPDATE },
- { LPGEN("OK"), "ok", IDI_OK },
- { LPGEN("Cancel"), "cancel", IDI_CANCEL },
- { LPGEN("Edit"), "edit", IDI_EDIT },
- { LPGEN("Edit on"), "editon", IDI_EDITON },
- { LPGEN("Copy"), "copy", IDI_COPY },
- { LPGEN("BBCode"), "bbc", IDI_BBC },
- { LPGEN("BBCode link"), "bbclnk", IDI_BBC2 },
- { LPGEN("Down arrow"), "downarrow", IDI_DOWNARROW },
-};
-
-static HANDLE m_hFolderScreenshot = nullptr;
-wchar_t* GetCustomPath()
-{
- wchar_t *pszPath = Utils_ReplaceVarsW(L"%miranda_userdata%\\Screenshots");
- if (m_hFolderScreenshot) {
- wchar_t szPath[1024] = { 0 };
- FoldersGetCustomPathW(m_hFolderScreenshot, szPath, 1024, pszPath);
- mir_free(pszPath);
- pszPath = mir_wstrdup(szPath);
- }
- if (!pszPath) {
- MessageBox(nullptr, L"Can not retrieve screenshot path.", L"SendSS", MB_OK | MB_ICONERROR | MB_APPLMODAL);
- return nullptr;
- }
- int result = CreateDirectoryTreeW(pszPath);
- if (result) {
- wchar_t szError[MAX_PATH];
- mir_snwprintf(szError, MAX_PATH, TranslateT("Could not create screenshot folder (error code: %d):\n%s\nDo you have write permissions?"), result, pszPath);
- MessageBox(nullptr, szError, L"SendSS", MB_OK | MB_ICONERROR | MB_APPLMODAL);
- mir_free(pszPath);
- return nullptr;
- }
- return pszPath;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Callback function of service for contact menu and main menu
-// wParam = contact handle
-// lParam = 0 (or 0xFFFF to preselect window under cursor)
-
-INT_PTR service_OpenCaptureDialog(WPARAM wParam, LPARAM lParam)
-{
- TfrmMain *frmMain = new TfrmMain();
- if (!frmMain) {
- MessageBox(nullptr, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL);
- return -1;
- }
- wchar_t *pszPath = GetCustomPath();
- if (!pszPath) {
- delete frmMain;
- return -1;
- }
- frmMain->Init(pszPath, wParam);
- mir_free(pszPath);
- if (lParam == 0xFFFF) {
- frmMain->SetTargetWindow(nullptr);
- }
- frmMain->Show();
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Callback function of service
-// 1. Send a screenshot of the desktop to the selected contact
-// wParam = contact handle
-// lParam = 0
-// 2. Open the capture dialog in take screenshot only mode (it will not be sent)
-// wParam = 0
-// lParam = anything but 0
-
-INT_PTR service_SendDesktop(WPARAM wParam, LPARAM)
-{
- TfrmMain *frmMain = new TfrmMain();
- if (!frmMain) {
- MessageBox(nullptr, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL);
- return -1;
- }
- wchar_t *pszPath = GetCustomPath();
- if (!pszPath) {
- delete frmMain;
- return -1;
- }
-
- MCONTACT hContact = (MCONTACT)wParam;
- frmMain->m_opt_chkTimed = false;
- frmMain->m_opt_tabCapture = 1;
- frmMain->m_opt_cboxDesktop = 0;
- frmMain->m_opt_chkEditor = false;
- frmMain->m_opt_cboxSendBy = Contact::IsGroupChat(hContact) ? SS_IMAGESHACK : SS_FILESEND;
- frmMain->Init(pszPath, hContact); // this method create the window hidden.
- mir_free(pszPath);
- frmMain->btnCaptureClick(); // this method will call Close()
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Callback function of service for sending image to imageshack.us
-// wParam = (char*)filename
-// lParam = (HANDLE)contact (can be null)
-
-INT_PTR service_Send2ImageShack(WPARAM wParam, LPARAM lParam)
-{
- char *result = nullptr;
- CSendHost_ImageShack *cSend = new CSendHost_ImageShack(nullptr, lParam, false);
- cSend->m_bDeleteAfterSend = false;
- cSend->SetFile((char *)wParam);
- if (lParam != NULL) {
- if (cSend->Send()) delete cSend;
- return NULL;
- }
- cSend->SendSilent();
- if (cSend->GetURL()) {
- result = mir_strdup(cSend->GetURL());
- }
- else {
- result = mir_u2a(cSend->GetErrorMsg());
- }
- delete cSend;
- return (INT_PTR)result;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static PLUGININFOEX pluginInfoEx =
-{
- sizeof(PLUGININFOEX),
- __PLUGIN_NAME,
- PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
- __DESCRIPTION,
- __AUTHOR,
- __COPYRIGHT,
- __AUTHORWEB,
- UNICODE_AWARE,
- // {ED39AF7C-BECD-404E-9499-4D04F711B9CB}
- { 0xed39af7c, 0xbecd, 0x404e, { 0x94, 0x99, 0x4d, 0x04, 0xf7, 0x11, 0xb9, 0xcb } }
-};
-
-CMPlugin::CMPlugin() :
- PLUGIN<CMPlugin>(MODULENAME, pluginInfoEx)
-{}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// hooks
-
-int hook_ModulesLoaded(WPARAM, LPARAM)
-{
- g_myGlobals.PluginHTTPExist = ServiceExists(MS_HTTP_ACCEPT_CONNECTIONS);
- g_myGlobals.PluginFTPExist = ServiceExists(MS_FTPFILE_UPLOAD);
- g_myGlobals.PluginCloudFileExist = ServiceExists(MS_CLOUDFILE_UPLOAD);
-
- // Netlib register
- NETLIBUSER nlu = {};
- nlu.szSettingsModule = __PLUGIN_NAME;
- nlu.szDescriptiveName.w = TranslateT("SendSS");
- nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE; //|NUF_NOHTTPSOPTION;
- g_hNetlibUser = Netlib_RegisterUser(&nlu);
-
- // load my button class / or use UInfoEx
- CtrlButtonLoadModule();
-
- // Folders plugin support
- m_hFolderScreenshot = FoldersRegisterCustomPathW(LPGEN("SendSS"), LPGEN("Screenshots"),
- PROFILE_PATHW L"\\" CURRENT_PROFILEW L"\\Screenshots");
- return 0;
-}
-
-int hook_SystemPreShutdown(WPARAM, LPARAM)
-{
- TfrmMain::Unload();
-
- // Netlib unregister
- Netlib_CloseHandle(g_hNetlibUser);
-
- // uninitialize classes
- CtrlButtonUnloadModule();
- return 0;
-}
-
-int hook_PrebuildContactMenu(WPARAM hContact, LPARAM)
-{
- INT_PTR flags = CallProtoService(Proto_GetBaseAccountName(hContact), PS_GETCAPS, PFLAGNUM_1, 0);
- bool bEnabled = (flags != CALLSERVICE_NOTFOUND) && (flags & PF1_FILE) != 0;
- Menu_ShowItem(g_hMenu1, bEnabled);
- Menu_ShowItem(g_hMenu2, bEnabled);
- return 0;
-}
-
-static int TabsrmmButtonsInit(WPARAM, LPARAM)
-{
- // SRMM toolbar button
- BBButton bbd = {};
- bbd.pszModuleName = MODULENAME;
- bbd.dwButtonID = 1;
- bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON;
- bbd.dwDefPos = 201;
- bbd.hIcon = GetIconHandle(ICO_MAINXS);
- Srmm_AddButton(&bbd, &g_plugin);
- return 0;
-}
-
-static int TabsrmmButtonPressed(WPARAM hContact, LPARAM lParam)
-{
- CustomButtonClickData *cbcd = (CustomButtonClickData *)lParam;
- if (!mir_strcmp(cbcd->pszModule, MODULENAME) && cbcd->dwButtonId == 1)
- CallService(MS_SENDSS_OPENDIALOG, hContact, 0);
-
- return 0;
-}
-
-int CMPlugin::Load()
-{
- // hook events
- HookEvent(ME_SYSTEM_MODULESLOADED, hook_ModulesLoaded);
- HookEvent(ME_SYSTEM_PRESHUTDOWN, hook_SystemPreShutdown);
- HookEvent(ME_CLIST_PREBUILDCONTACTMENU, hook_PrebuildContactMenu);
-
- HookEvent(ME_MSG_BUTTONPRESSED, TabsrmmButtonPressed);
- HookTemporaryEvent(ME_MSG_TOOLBARLOADED, TabsrmmButtonsInit);
-
- // icons
- g_plugin.registerIcon(MODULENAME, ICONS, MODULENAME);
- g_plugin.registerIcon(MODULENAME "/" LPGEN("Buttons"), ICONS_BTN, MODULENAME);
-
- // services
-#define srv_reg(name) CreateServiceFunction(MODULENAME "/" #name, service_##name);
- srv_reg(OpenCaptureDialog);
- srv_reg(SendDesktop);
- srv_reg(Send2ImageShack);
-
- // menu items
- CMenuItem mi(&g_plugin);
- mi.flags = CMIF_UNICODE;
- mi.hIcolibItem = GetIconHandle(ICO_MAINXS);
-
- SET_UID(mi, 0xa559a22e, 0xd0f9, 0x4553, 0x8e, 0x68, 0x55, 0xb3, 0xae, 0xc4, 0x5d, 0x93);
- mi.name.w = LPGENW("Take a screenshot");
- mi.pszService = MS_SENDSS_OPENDIALOG;
- mi.position = 1000001;
- Menu_AddMainMenuItem(&mi);
-
- SET_UID(mi, 0xfea0a84, 0x1767, 0x4605, 0x99, 0xf0, 0xa9, 0x48, 0x1a, 0xa6, 0x6f, 0xce);
- mi.name.w = LPGENW("Send screenshot");
- mi.pszService = MS_SENDSS_OPENDIALOG;
- mi.position = 1000000;
- g_hMenu1 = Menu_AddContactMenuItem(&mi);
-
- SET_UID(mi, 0x8d5b0d9a, 0x68d4, 0x4594, 0x9f, 0x41, 0x0, 0x64, 0x20, 0xe7, 0xf8, 0x9f);
- mi.name.w = LPGENW("Send desktop screenshot");
- mi.pszService = MS_SENDSS_SENDDESKTOP;
- mi.position = 1000001;
- g_hMenu2 = Menu_AddContactMenuItem(&mi);
-
- // hotkey's
- HOTKEYDESC hkd = {};
- hkd.pszName = "Open SendSS+";
- hkd.szDescription.w = LPGENW("Open SendSS+");
- hkd.szSection.w = L"SendSS+";
- hkd.pszService = MS_SENDSS_OPENDIALOG;
- hkd.lParam = 0xFFFF;
- hkd.dwFlags = HKD_UNICODE;
- g_plugin.addHotkey(&hkd);
-
- // register highlighter window class
- HBRUSH brush = CreateSolidBrush(0x0000FF00); // owned by class
- WNDCLASS wndclass = { CS_HREDRAW | CS_VREDRAW, DefWindowProc, 0, 0, g_plugin.getInst(), nullptr, nullptr, brush, nullptr, L"SendSSHighlighter" };
- g_clsTargetHighlighter = RegisterClass(&wndclass);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Prepare the plugin to stop
-
-int CMPlugin::Unload()
-{
- if (g_clsTargetHighlighter)
- UnregisterClass((wchar_t *)g_clsTargetHighlighter, g_plugin.getInst()), g_clsTargetHighlighter = 0;
- return 0;
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original source code
+(c) 2004-2006 Sérgio Vieira Rolanski (ported from Borland C++)
+
+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"
+
+// Prototypes ///////////////////////////////////////////////////////////////////////////
+
+CMPlugin g_plugin;
+HGENMENU g_hMenu1, g_hMenu2;
+
+ATOM g_clsTargetHighlighter = 0;
+MGLOBAL g_myGlobals;
+HNETLIBUSER g_hNetlibUser;
+
+IconItem ICONS[ICO_END_] =
+{
+ { LPGEN("Main Icon"), "main", IDI_MAIN, 32 },
+ { LPGEN("Main Icon"), "mainxs", IDI_MAIN },
+ { LPGEN("Target Cursor"), "target", IDI_TARGET, 32 },
+ { LPGEN("Target Desktop"), "monitor", IDI_MONITOR, 32 },
+};
+
+IconItem ICONS_BTN[ICO_BTN_END_] =
+{
+ { LPGEN("Help"), "help", IDI_HELP },
+ { LPGEN("Open Folder"), "folder", IDI_FOLDER },
+ { LPGEN("Description off"), "desc", IDI_DESC },
+ { LPGEN("Description on"), "descon", IDI_DESCON },
+ { LPGEN("Delete off"), "del", IDI_DEL },
+ { LPGEN("Delete on"), "delon", IDI_DELON },
+ { LPGEN("Prev"), "arrowl", IDI_ARROWL },
+ { LPGEN("Next"), "arrowr", IDI_ARROWR },
+ { LPGEN("Update"), "update", IDI_UPDATE },
+ { LPGEN("OK"), "ok", IDI_OK },
+ { LPGEN("Cancel"), "cancel", IDI_CANCEL },
+ { LPGEN("Edit"), "edit", IDI_EDIT },
+ { LPGEN("Edit on"), "editon", IDI_EDITON },
+ { LPGEN("Copy"), "copy", IDI_COPY },
+ { LPGEN("BBCode"), "bbc", IDI_BBC },
+ { LPGEN("BBCode link"), "bbclnk", IDI_BBC2 },
+ { LPGEN("Down arrow"), "downarrow", IDI_DOWNARROW },
+};
+
+static HANDLE m_hFolderScreenshot = nullptr;
+wchar_t* GetCustomPath()
+{
+ wchar_t *pszPath = Utils_ReplaceVarsW(L"%miranda_userdata%\\Screenshots");
+ if (m_hFolderScreenshot) {
+ wchar_t szPath[1024] = { 0 };
+ FoldersGetCustomPathW(m_hFolderScreenshot, szPath, 1024, pszPath);
+ mir_free(pszPath);
+ pszPath = mir_wstrdup(szPath);
+ }
+ if (!pszPath) {
+ MessageBox(nullptr, L"Can not retrieve screenshot path.", L"SendSS", MB_OK | MB_ICONERROR | MB_APPLMODAL);
+ return nullptr;
+ }
+ int result = CreateDirectoryTreeW(pszPath);
+ if (result) {
+ wchar_t szError[MAX_PATH];
+ mir_snwprintf(szError, MAX_PATH, TranslateT("Could not create screenshot folder (error code: %d):\n%s\nDo you have write permissions?"), result, pszPath);
+ MessageBox(nullptr, szError, L"SendSS", MB_OK | MB_ICONERROR | MB_APPLMODAL);
+ mir_free(pszPath);
+ return nullptr;
+ }
+ return pszPath;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Callback function of service for contact menu and main menu
+// wParam = contact handle
+// lParam = 0 (or 0xFFFF to preselect window under cursor)
+
+INT_PTR service_OpenCaptureDialog(WPARAM wParam, LPARAM lParam)
+{
+ TfrmMain *frmMain = new TfrmMain();
+ if (!frmMain) {
+ MessageBox(nullptr, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL);
+ return -1;
+ }
+ wchar_t *pszPath = GetCustomPath();
+ if (!pszPath) {
+ delete frmMain;
+ return -1;
+ }
+ frmMain->Init(pszPath, wParam);
+ mir_free(pszPath);
+ if (lParam == 0xFFFF) {
+ frmMain->SetTargetWindow(nullptr);
+ }
+ frmMain->Show();
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Callback function of service
+// 1. Send a screenshot of the desktop to the selected contact
+// wParam = contact handle
+// lParam = 0
+// 2. Open the capture dialog in take screenshot only mode (it will not be sent)
+// wParam = 0
+// lParam = anything but 0
+
+INT_PTR service_SendDesktop(WPARAM wParam, LPARAM)
+{
+ TfrmMain *frmMain = new TfrmMain();
+ if (!frmMain) {
+ MessageBox(nullptr, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL);
+ return -1;
+ }
+ wchar_t *pszPath = GetCustomPath();
+ if (!pszPath) {
+ delete frmMain;
+ return -1;
+ }
+
+ MCONTACT hContact = (MCONTACT)wParam;
+ frmMain->m_opt_chkTimed = false;
+ frmMain->m_opt_tabCapture = 1;
+ frmMain->m_opt_cboxDesktop = 0;
+ frmMain->m_opt_chkEditor = false;
+ frmMain->m_opt_cboxSendBy = Contact::IsGroupChat(hContact) ? SS_IMAGESHACK : SS_FILESEND;
+ frmMain->Init(pszPath, hContact); // this method create the window hidden.
+ mir_free(pszPath);
+ frmMain->btnCaptureClick(); // this method will call Close()
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Callback function of service for sending image to imageshack.us
+// wParam = (char*)filename
+// lParam = (HANDLE)contact (can be null)
+
+INT_PTR service_Send2ImageShack(WPARAM wParam, LPARAM lParam)
+{
+ char *result = nullptr;
+ CSendHost_ImageShack *cSend = new CSendHost_ImageShack(nullptr, lParam, false);
+ cSend->m_bDeleteAfterSend = false;
+ cSend->SetFile((char *)wParam);
+ if (lParam != NULL) {
+ if (cSend->Send()) delete cSend;
+ return NULL;
+ }
+ cSend->SendSilent();
+ if (cSend->GetURL()) {
+ result = mir_strdup(cSend->GetURL());
+ }
+ else {
+ result = mir_u2a(cSend->GetErrorMsg());
+ }
+ delete cSend;
+ return (INT_PTR)result;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static PLUGININFOEX pluginInfoEx =
+{
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESCRIPTION,
+ __AUTHOR,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ // {ED39AF7C-BECD-404E-9499-4D04F711B9CB}
+ { 0xed39af7c, 0xbecd, 0x404e, { 0x94, 0x99, 0x4d, 0x04, 0xf7, 0x11, 0xb9, 0xcb } }
+};
+
+CMPlugin::CMPlugin() :
+ PLUGIN<CMPlugin>(MODULENAME, pluginInfoEx)
+{}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// hooks
+
+int hook_ModulesLoaded(WPARAM, LPARAM)
+{
+ g_myGlobals.PluginHTTPExist = ServiceExists(MS_HTTP_ACCEPT_CONNECTIONS);
+ g_myGlobals.PluginFTPExist = ServiceExists(MS_FTPFILE_UPLOAD);
+ g_myGlobals.PluginCloudFileExist = ServiceExists(MS_CLOUDFILE_UPLOAD);
+
+ // Netlib register
+ NETLIBUSER nlu = {};
+ nlu.szSettingsModule = __PLUGIN_NAME;
+ nlu.szDescriptiveName.w = TranslateT("SendSS");
+ nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE; //|NUF_NOHTTPSOPTION;
+ g_hNetlibUser = Netlib_RegisterUser(&nlu);
+
+ // load my button class / or use UInfoEx
+ CtrlButtonLoadModule();
+
+ // Folders plugin support
+ m_hFolderScreenshot = FoldersRegisterCustomPathW(LPGEN("SendSS"), LPGEN("Screenshots"),
+ PROFILE_PATHW L"\\" CURRENT_PROFILEW L"\\Screenshots");
+ return 0;
+}
+
+int hook_SystemPreShutdown(WPARAM, LPARAM)
+{
+ TfrmMain::Unload();
+
+ // Netlib unregister
+ Netlib_CloseHandle(g_hNetlibUser);
+
+ // uninitialize classes
+ CtrlButtonUnloadModule();
+ return 0;
+}
+
+int hook_PrebuildContactMenu(WPARAM hContact, LPARAM)
+{
+ INT_PTR flags = CallProtoService(Proto_GetBaseAccountName(hContact), PS_GETCAPS, PFLAGNUM_1, 0);
+ bool bEnabled = (flags != CALLSERVICE_NOTFOUND) && (flags & PF1_FILE) != 0;
+ Menu_ShowItem(g_hMenu1, bEnabled);
+ Menu_ShowItem(g_hMenu2, bEnabled);
+ return 0;
+}
+
+static int TabsrmmButtonsInit(WPARAM, LPARAM)
+{
+ // SRMM toolbar button
+ BBButton bbd = {};
+ bbd.pszModuleName = MODULENAME;
+ bbd.dwButtonID = 1;
+ bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON;
+ bbd.dwDefPos = 201;
+ bbd.hIcon = GetIconHandle(ICO_MAINXS);
+ Srmm_AddButton(&bbd, &g_plugin);
+ return 0;
+}
+
+static int TabsrmmButtonPressed(WPARAM hContact, LPARAM lParam)
+{
+ CustomButtonClickData *cbcd = (CustomButtonClickData *)lParam;
+ if (!mir_strcmp(cbcd->pszModule, MODULENAME) && cbcd->dwButtonId == 1)
+ CallService(MS_SENDSS_OPENDIALOG, hContact, 0);
+
+ return 0;
+}
+
+int CMPlugin::Load()
+{
+ // hook events
+ HookEvent(ME_SYSTEM_MODULESLOADED, hook_ModulesLoaded);
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, hook_SystemPreShutdown);
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU, hook_PrebuildContactMenu);
+
+ HookEvent(ME_MSG_BUTTONPRESSED, TabsrmmButtonPressed);
+ HookTemporaryEvent(ME_MSG_TOOLBARLOADED, TabsrmmButtonsInit);
+
+ // icons
+ g_plugin.registerIcon(MODULENAME, ICONS, MODULENAME);
+ g_plugin.registerIcon(MODULENAME "/" LPGEN("Buttons"), ICONS_BTN, MODULENAME);
+
+ // services
+#define srv_reg(name) CreateServiceFunction(MODULENAME "/" #name, service_##name);
+ srv_reg(OpenCaptureDialog);
+ srv_reg(SendDesktop);
+ srv_reg(Send2ImageShack);
+
+ // menu items
+ CMenuItem mi(&g_plugin);
+ mi.flags = CMIF_UNICODE;
+ mi.hIcolibItem = GetIconHandle(ICO_MAINXS);
+
+ SET_UID(mi, 0xa559a22e, 0xd0f9, 0x4553, 0x8e, 0x68, 0x55, 0xb3, 0xae, 0xc4, 0x5d, 0x93);
+ mi.name.w = LPGENW("Take a screenshot");
+ mi.pszService = MS_SENDSS_OPENDIALOG;
+ mi.position = 1000001;
+ Menu_AddMainMenuItem(&mi);
+
+ SET_UID(mi, 0xfea0a84, 0x1767, 0x4605, 0x99, 0xf0, 0xa9, 0x48, 0x1a, 0xa6, 0x6f, 0xce);
+ mi.name.w = LPGENW("Send screenshot");
+ mi.pszService = MS_SENDSS_OPENDIALOG;
+ mi.position = 1000000;
+ g_hMenu1 = Menu_AddContactMenuItem(&mi);
+
+ SET_UID(mi, 0x8d5b0d9a, 0x68d4, 0x4594, 0x9f, 0x41, 0x0, 0x64, 0x20, 0xe7, 0xf8, 0x9f);
+ mi.name.w = LPGENW("Send desktop screenshot");
+ mi.pszService = MS_SENDSS_SENDDESKTOP;
+ mi.position = 1000001;
+ g_hMenu2 = Menu_AddContactMenuItem(&mi);
+
+ // hotkey's
+ HOTKEYDESC hkd = {};
+ hkd.pszName = "Open SendSS+";
+ hkd.szDescription.w = LPGENW("Open SendSS+");
+ hkd.szSection.w = L"SendSS+";
+ hkd.pszService = MS_SENDSS_OPENDIALOG;
+ hkd.lParam = 0xFFFF;
+ hkd.dwFlags = HKD_UNICODE;
+ g_plugin.addHotkey(&hkd);
+
+ // register highlighter window class
+ HBRUSH brush = CreateSolidBrush(0x0000FF00); // owned by class
+ WNDCLASS wndclass = { CS_HREDRAW | CS_VREDRAW, DefWindowProc, 0, 0, g_plugin.getInst(), nullptr, nullptr, brush, nullptr, L"SendSSHighlighter" };
+ g_clsTargetHighlighter = RegisterClass(&wndclass);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Prepare the plugin to stop
+
+int CMPlugin::Unload()
+{
+ if (g_clsTargetHighlighter)
+ UnregisterClass((wchar_t *)g_clsTargetHighlighter, g_plugin.getInst()), g_clsTargetHighlighter = 0;
+ return 0;
+}
diff --git a/plugins/SendScreenshotPlus/src/UMainForm.cpp b/plugins/SendScreenshotPlus/src/UMainForm.cpp
index 86b53ffef7..d67ebe3de0 100644
--- a/plugins/SendScreenshotPlus/src/UMainForm.cpp
+++ b/plugins/SendScreenshotPlus/src/UMainForm.cpp
@@ -1,1124 +1,1124 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-#include <list>
-
-void TfrmMain::Unload()
-{
- std::list<TfrmMain*> lst;
- for (auto &it : _HandleMapping)
- lst.push_back(it.second); // we can't delete inside loop.. not MT compatible
-
- while (!lst.empty()) {
- DestroyWindow(lst.front()->m_hWnd); // deletes class
- lst.pop_front();
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR CALLBACK TfrmMain::DlgProc_CaptureTabPage(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- // main message handling is done inside TfrmMain::DlgTfrmMain
- switch (uMsg) {
- case WM_INITDIALOG:
- switch (lParam) {
- case IDD_UMain_CaptureWindow:
- Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), GetIcon(ICO_TARGET));
- SetDlgItemText(hDlg, ID_edtCaption, TranslateT("Drag&Drop the target on the desired window."));
- break;
- case IDD_UMain_CaptureDesktop:
- Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), GetIcon(ICO_MONITOR));
- break;
- case IDD_UMain_CaptureFile:
- Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), GetIcon(ICO_MAIN));
- break;
- }
- SetFocus(GetDlgItem(hDlg, ID_imgTarget));
- return FALSE;
-
- case WM_CTLCOLORDLG:
- case WM_CTLCOLOREDIT:
- case WM_CTLCOLORSTATIC:
- SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
- return (INT_PTR)GetStockObject(WHITE_BRUSH);
-
- case WM_COMMAND:
- if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == ID_btnExplore) { // local file tab
- OPENFILENAME ofn = { sizeof(OPENFILENAME) };
- wchar_t filename[MAX_PATH];
- GetDlgItemText(hDlg, ID_edtSize, filename, _countof(filename));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hDlg;
- ofn.lpstrFilter = L"Images\0*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tif;*.tiff\0";
- ofn.nFilterIndex = 1;
- ofn.lpstrFile = filename;
- ofn.nMaxFile = MAX_PATH;
- ofn.Flags = OFN_FILEMUSTEXIST | OFN_READONLY;
- if (GetOpenFileName(&ofn)) {
- SetDlgItemText(hDlg, ID_edtSize, filename);
- }
- break;
- }
- SendMessage(GetParent(hDlg), uMsg, wParam, lParam);
- break;
- case WM_NOTIFY:
- SendMessage(GetParent(hDlg), uMsg, wParam, lParam);
- break;
- case WM_DESTROY:
- break;
- }
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-TfrmMain::CHandleMapping TfrmMain::_HandleMapping;
-
-INT_PTR CALLBACK TfrmMain::DlgTfrmMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (msg == WM_CTLCOLOREDIT || msg == WM_CTLCOLORSTATIC) {
- switch (GetWindowLongPtr((HWND)lParam, GWL_ID)) {
- case IDC_HEADERBAR:
- SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
- break;
- default:
- return 0;
- }
- SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
- return (INT_PTR)GetStockObject(WHITE_BRUSH);
- }
-
- CHandleMapping::iterator wnd;
- if (msg == WM_INITDIALOG) {
- wnd = _HandleMapping.insert(CHandleMapping::value_type(hWnd, reinterpret_cast<TfrmMain*>(lParam))).first;
- wnd->second->m_hWnd = hWnd;
- wnd->second->wmInitdialog(wParam, lParam);
- return 0;
- }
- wnd = _HandleMapping.find(hWnd);
- if (wnd == _HandleMapping.end())
- return 0;
-
- switch (msg) {
- case WM_DROPFILES:
- // Drag&Drop of local files
- {
- wchar_t filename[MAX_PATH];
- if (!DragQueryFile((HDROP)wParam, 0, filename, MAX_PATH))
- *filename = '\0';
- DragFinish((HDROP)wParam);
- if (wnd->second->m_hwndTabPage)
- ShowWindow(wnd->second->m_hwndTabPage, SW_HIDE);
-
- wnd->second->m_opt_tabCapture = 2; // activate file tab
- TabCtrl_SetCurSel(wnd->second->m_hwndTab, wnd->second->m_opt_tabCapture);
-
- TAB_INFO itab = { TCIF_PARAM };
- TabCtrl_GetItem(wnd->second->m_hwndTab, wnd->second->m_opt_tabCapture, &itab);
- wnd->second->m_hwndTabPage = itab.hwndTabPage;
-
- ShowWindow(wnd->second->m_hwndTabPage, SW_SHOW);
- SetDlgItemText(wnd->second->m_hwndTabPage, ID_edtSize, filename);
- }
- break;
- case WM_COMMAND:
- wnd->second->wmCommand(wParam, lParam);
- break;
- case WM_CLOSE:
- wnd->second->wmClose(wParam, lParam);
- break;
- case WM_DESTROY:
- delete wnd->second;
- break;
- case WM_NOTIFY:
- wnd->second->wmNotify(wParam, lParam);
- break;
- case WM_TIMER:
- wnd->second->wmTimer(wParam, lParam);
- break;
- case UM_EVENT:
- wnd->second->UMevent(wParam, lParam);
- break;
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// WM_INITDIALOG:
-
-int EnumCloudFileServices(const CFSERVICEINFO *serviceInfo, void *param)
-{
- HWND hCtrl = (HWND)param;
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, serviceInfo->userName), new UPLOAD_INFO(SS_CLOUDFILE, (void*)serviceInfo->accountName));
- return 0;
-}
-
-void TfrmMain::wmInitdialog(WPARAM, LPARAM)
-{
- HWND hCtrl;
- // Taskbar and Window icon
- Window_SetIcon_IcoLib(m_hWnd, GetIconHandle(ICO_MAIN));
-
- wchar_t *pt = mir_wstrdup(Clist_GetContactDisplayName(m_hContact));
- if (pt && (m_hContact != 0)) {
- CMStringW string;
- string.AppendFormat(TranslateT("Send screenshot to %s"), pt);
- SetWindowText(m_hWnd, string);
- }
- mir_free(pt);
-
- // Headerbar
- SendDlgItemMessage(m_hWnd, IDC_HEADERBAR, WM_SETICON, ICON_BIG, (LPARAM)GetIcon(ICO_MAIN));
-
- // Timed controls
- CheckDlgButton(m_hWnd, ID_chkTimed, m_opt_chkTimed ? BST_CHECKED : BST_UNCHECKED);
- SetDlgItemInt(m_hWnd, ID_edtTimed, (UINT)m_opt_edtTimed, FALSE);
- SendDlgItemMessage(m_hWnd, ID_upTimed, UDM_SETRANGE, 0, (LPARAM)MAKELONG(250, 1));
- chkTimedClick(); // enable disable Timed controls
-
- // create Image list for tab control
- if (!m_himlTab) {
- m_himlTab = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1);
- ImageList_AddIcon(m_himlTab, GetIcon(ICO_TARGET));
- ImageList_AddIcon(m_himlTab, GetIcon(ICO_MONITOR));
- ImageList_AddIcon(m_himlTab, GetIconBtn(ICO_BTN_FOLDER));
- }
-
- // create the tab control.
- {
- m_hwndTab = GetDlgItem(m_hWnd, IDC_CAPTURETAB);
- TabCtrl_SetImageList(m_hwndTab, m_himlTab);
- TabCtrl_SetItemExtra(m_hwndTab, sizeof(TAB_INFO) - sizeof(TCITEMHEADER));
- RECT rcTab;
- TAB_INFO itab;
- itab.hwndMain = m_hWnd;
- itab.hwndTab = m_hwndTab;
- itab.tcih.mask = TCIF_PARAM | TCIF_TEXT | TCIF_IMAGE;
-
- // Add a tab for each of the three child dialog boxes.
- itab.tcih.pszText = TranslateT("Window");
- itab.tcih.iImage = 0;
- itab.hwndTabPage = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMain_CaptureWindow), m_hWnd, DlgProc_CaptureTabPage, IDD_UMain_CaptureWindow);
- TabCtrl_InsertItem(m_hwndTab, 0, &itab);
-
- // get tab boundaries (required after 1st tab)
- GetClientRect(m_hwndTab, &rcTab);
- MapWindowPoints(m_hwndTab, m_hWnd, (POINT*)&rcTab, 2);
- TabCtrl_AdjustRect(m_hwndTab, 0, &rcTab);
- rcTab.bottom -= rcTab.top; rcTab.right -= rcTab.left;
-
- SetWindowPos(itab.hwndTabPage, HWND_TOP, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom, 0);
- CheckDlgButton(itab.hwndTabPage, ID_chkIndirectCapture, m_opt_chkIndirectCapture ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(itab.hwndTabPage, ID_chkClientArea, m_opt_chkClientArea ? BST_CHECKED : BST_UNCHECKED);
-
- itab.tcih.pszText = TranslateT("Desktop");
- itab.tcih.iImage = 1;
- itab.hwndTabPage = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMain_CaptureDesktop), m_hWnd, DlgProc_CaptureTabPage, IDD_UMain_CaptureDesktop);
- TabCtrl_InsertItem(m_hwndTab, 1, &itab);
- SetWindowPos(itab.hwndTabPage, HWND_TOP, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom, 0);
-
- hCtrl = GetDlgItem(itab.hwndTabPage, ID_edtCaption);
- ComboBox_ResetContent(hCtrl);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Entire Desktop>")), 0);
- ComboBox_SetCurSel(hCtrl, 0);
- if (m_MonitorCount > 1) {
- wchar_t tszTemp[120];
- for (size_t mon = 0; mon < m_MonitorCount; ++mon) { // @todo : fix format for non MSVC compilers
- mir_snwprintf(tszTemp, L"%Iu. %s%s",
- mon + 1, TranslateT("Monitor"),
- (m_Monitors[mon].dwFlags & MONITORINFOF_PRIMARY) ? TranslateT(" (primary)") : L""
- );
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, tszTemp), mon + 1);
- }
- ComboBox_SelectItem(hCtrl, m_opt_cboxDesktop);
- }
- PostMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(ID_edtCaption, CBN_SELCHANGE), (LPARAM)hCtrl);
-
- itab.tcih.pszText = TranslateT("File");
- itab.tcih.iImage = 2;
- itab.hwndTabPage = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMain_CaptureFile), m_hWnd, DlgProc_CaptureTabPage, IDD_UMain_CaptureFile);
- TabCtrl_InsertItem(m_hwndTab, 2, &itab);
- SetWindowPos(itab.hwndTabPage, HWND_TOP, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom, 0);
-
- // select tab and set m_hwndTabPage
- TabCtrl_SetCurSel(m_hwndTab, m_opt_tabCapture);
- itab.tcih.mask = TCIF_PARAM;
- TabCtrl_GetItem(m_hwndTab, m_opt_tabCapture, &itab);
- m_hwndTabPage = itab.hwndTabPage;
- ShowWindow(m_hwndTabPage, SW_SHOW);
-
- // enable Drag&Drop for local file pane
- typedef BOOL(WINAPI *ChangeWindowMessageFilterEx_t)(HWND hwnd, UINT message, uint32_t action, PCHANGEFILTERSTRUCT pChangeFilterStruct);
- ChangeWindowMessageFilterEx_t pChangeWindowMessageFilterEx;
- pChangeWindowMessageFilterEx = (ChangeWindowMessageFilterEx_t)GetProcAddress(GetModuleHandleA("user32"), "ChangeWindowMessageFilterEx");
- if (pChangeWindowMessageFilterEx) { // Win7+, UAC fix
- pChangeWindowMessageFilterEx(m_hWnd, WM_DROPFILES, MSGFLT_ALLOW, nullptr);
- pChangeWindowMessageFilterEx(m_hWnd, WM_COPYDATA, MSGFLT_ALLOW, nullptr);
- pChangeWindowMessageFilterEx(m_hWnd, 0x0049/*WM_COPYGLOBALDATA*/, MSGFLT_ALLOW, nullptr);
- }
- DragAcceptFiles(m_hWnd, 1);
- }
-
- // init Format combo box
- {
- hCtrl = GetDlgItem(m_hWnd, ID_cboxFormat);
- ComboBox_ResetContent(hCtrl);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"PNG"), 0);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"JPG"), 1);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"BMP"), 2);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"TIF"), 3);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"GIF"), 4);
- ComboBox_SelectItem(hCtrl, m_opt_cboxFormat);
- }
-
- // init SendBy combo box
- UPLOAD_INFO *pDefault = nullptr;
- {
- hCtrl = GetDlgItem(m_hWnd, ID_cboxSendBy);
- ComboBox_ResetContent(hCtrl);
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Only save>")), new UPLOAD_INFO(SS_JUSTSAVE));
- if (m_hContact) {
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("File Transfer")), new UPLOAD_INFO(SS_FILESEND));
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("E-mail")), new UPLOAD_INFO(SS_EMAIL));
- if (g_myGlobals.PluginHTTPExist) {
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"HTTP Server"), new UPLOAD_INFO(SS_HTTPSERVER));
- }
- else if (m_opt_cboxSendBy == SS_HTTPSERVER) {
- m_opt_cboxSendBy = SS_IMAGESHACK;
- }
- if (g_myGlobals.PluginFTPExist) {
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("FTP File")), new UPLOAD_INFO(SS_FTPFILE));
- }
- else if (m_opt_cboxSendBy == SS_FTPFILE) {
- m_opt_cboxSendBy = SS_IMAGESHACK;
- }
- }
- else if (m_opt_cboxSendBy == SS_FILESEND || m_opt_cboxSendBy == SS_EMAIL || m_opt_cboxSendBy == SS_HTTPSERVER || m_opt_cboxSendBy == SS_FTPFILE) {
- m_opt_cboxSendBy = SS_IMAGESHACK;
- }
- if (g_myGlobals.PluginCloudFileExist) {
- CallService(MS_CLOUDFILE_ENUMSERVICES, (WPARAM)EnumCloudFileServices, (LPARAM)hCtrl);
- }
- else if (m_opt_cboxSendBy == SS_CLOUDFILE) {
- m_opt_cboxSendBy = SS_IMAGESHACK;
- }
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"ImageShack"), new UPLOAD_INFO(SS_IMAGESHACK));
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upload Pie (30m)")), new UPLOAD_INFO(SS_UPLOADPIE, (void*)1));
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upload Pie (1d)")), new UPLOAD_INFO(SS_UPLOADPIE, (void*)4));
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upload Pie (1w)")), new UPLOAD_INFO(SS_UPLOADPIE, (void*)5));
- ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"Imgur"), new UPLOAD_INFO(SS_IMGUR));
-
- for (int i = 0; i < ComboBox_GetCount(hCtrl); i++) {
- UPLOAD_INFO *p = (UPLOAD_INFO*)ComboBox_GetItemData(hCtrl, i);
- if (p && p->sendBy == m_opt_cboxSendBy) {
- pDefault = p;
- ComboBox_SetCurSel(hCtrl, i);
- break;
- }
- }
- }
-
- // init footer options
- CheckDlgButton(m_hWnd, ID_chkOpenAgain, m_opt_chkOpenAgain ? BST_CHECKED : BST_UNCHECKED);
-
- if (hCtrl = GetDlgItem(m_hWnd, ID_btnExplore)) {
- SendDlgItemMessage(m_hWnd, ID_btnExplore, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open Folder"), MBBF_TCHAR);
- HICON hIcon = GetIconBtn(ICO_BTN_FOLDER);
- SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- SetWindowText(hCtrl, hIcon ? L"" : L"...");
- }
-
- if (hCtrl = GetDlgItem(m_hWnd, ID_chkDesc)) {
- SendDlgItemMessage(m_hWnd, ID_chkDesc, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Fill description textbox."), MBBF_TCHAR);
- HICON hIcon = GetIconBtn(m_opt_btnDesc ? ICO_BTN_DESCON : ICO_BTN_DESC);
- SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- SetWindowText(hCtrl, hIcon ? L"" : L"D");
- SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDesc ? BST_CHECKED : BST_UNCHECKED, NULL);
- }
-
- if (hCtrl = GetDlgItem(m_hWnd, ID_chkDeleteAfterSend)) {
- SendDlgItemMessage(m_hWnd, ID_chkDeleteAfterSend, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete after send"), MBBF_TCHAR);
- HICON hIcon = GetIconBtn(m_opt_btnDeleteAfterSend ? ICO_BTN_DELON : ICO_BTN_DEL);
- SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- SetWindowText(hCtrl, hIcon ? L"" : L"X");
- SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDeleteAfterSend ? BST_CHECKED : BST_UNCHECKED, NULL);
- }
-
- if (hCtrl = GetDlgItem(m_hWnd, ID_chkEditor)) {
- SendDlgItemMessage(m_hWnd, ID_chkEditor, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open editor before sending"), MBBF_TCHAR);
- HICON hIcon = GetIconBtn(m_opt_chkEditor ? ICO_BTN_EDITON : ICO_BTN_EDIT);
- SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- SetWindowText(hCtrl, hIcon ? L"" : L"E");
- SendMessage(hCtrl, BM_SETCHECK, m_opt_chkEditor ? BST_CHECKED : BST_UNCHECKED, NULL);
- }
-
- if (hCtrl = GetDlgItem(m_hWnd, ID_btnCapture)) {
- SendMessage(hCtrl, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Capture"), MBBF_TCHAR);
- HICON hIcon = GetIconBtn(ICO_BTN_OK);
- SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- SetWindowText(hCtrl, TranslateT("&Capture"));
- SendMessage(hCtrl, BUTTONSETDEFAULT, 1, NULL);
- }
- cboxSendByChange((pDefault) ? pDefault->param : nullptr); // enable disable controls
-
- TranslateDialogDefault(m_hWnd);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// WM_COMMAND:
-
-void TfrmMain::wmCommand(WPARAM wParam, LPARAM lParam)
-{
- HICON hIcon;
-
- int IDControl = LOWORD(wParam);
- switch (HIWORD(wParam)) {
- case BN_CLICKED: // Button controls
- switch (IDControl) {
- case IDCANCEL: // ESC pressed
- this->Close();
- break;
- case ID_chkTimed:
- m_opt_chkTimed = (uint8_t)Button_GetCheck((HWND)lParam);
- TfrmMain::chkTimedClick();
- break;
- case ID_chkIndirectCapture:
- m_opt_chkIndirectCapture = (uint8_t)Button_GetCheck((HWND)lParam);
- break;
- case ID_chkClientArea:
- m_opt_chkClientArea = (uint8_t)Button_GetCheck((HWND)lParam);
- if (m_hTargetWindow)
- edtSizeUpdate(m_hTargetWindow, m_opt_chkClientArea, GetParent((HWND)lParam), ID_edtSize);
- break;
- case ID_imgTarget:
- if (m_opt_tabCapture != 0) break;
- m_hLastWin = nullptr;
- SetTimer(m_hWnd, ID_imgTarget, BUTTON_POLLDELAY, nullptr);
- break;
- case ID_btnExplore:
- TfrmMain::btnExploreClick();
- break;
- case ID_chkDesc:
- m_opt_btnDesc = !m_opt_btnDesc;
- hIcon = GetIconBtn(m_opt_btnDesc ? ICO_BTN_DESCON : ICO_BTN_DESC);
- SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- break;
- case ID_chkDeleteAfterSend:
- m_opt_btnDeleteAfterSend = !m_opt_btnDeleteAfterSend;
- hIcon = GetIconBtn(m_opt_btnDeleteAfterSend ? ICO_BTN_DELON : ICO_BTN_DEL);
- SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- if (m_cSend) m_cSend->m_bDeleteAfterSend = m_opt_btnDeleteAfterSend;
- break;
- case ID_chkEditor:
- m_opt_chkEditor = !m_opt_chkEditor;
- hIcon = GetIconBtn(m_opt_chkEditor ? ICO_BTN_EDITON : ICO_BTN_EDIT);
- SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- break;
- case ID_chkOpenAgain:
- m_opt_chkOpenAgain = Button_GetCheck((HWND)lParam);
- break;
- case ID_btnCapture:
- TfrmMain::btnCaptureClick();
- break;
- }
- break;
-
- case CBN_SELCHANGE: // ComboBox controls
- switch (IDControl) { // lParam = Handle to the control
- case ID_cboxFormat: // not finish
- m_opt_cboxFormat = (uint8_t)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
- break;
- case ID_cboxSendBy:
- {
- UPLOAD_INFO *upload = (UPLOAD_INFO*)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
- m_opt_cboxSendBy = upload->sendBy;
- cboxSendByChange(upload->param);
- }
- break;
-
- case ID_edtCaption: // cboxDesktopChange
- m_opt_cboxDesktop = (uint8_t)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
- m_hTargetWindow = nullptr;
- if (m_opt_cboxDesktop > 0) {
- edtSizeUpdate(m_Monitors[m_opt_cboxDesktop - 1].rcMonitor, GetParent((HWND)lParam), ID_edtSize);
- }
- else {
- edtSizeUpdate(m_VirtualScreen, GetParent((HWND)lParam), ID_edtSize);
- }
- break;
- }
- break;
-
- case EN_CHANGE: // Edit controls
- switch (IDControl) { // lParam = Handle to the control
- case ID_edtQuality:
- m_opt_edtQuality = (uint8_t)GetDlgItemInt(m_hWnd, ID_edtQuality, nullptr, FALSE);
- break;
- case ID_edtTimed:
- m_opt_edtTimed = (uint8_t)GetDlgItemInt(m_hWnd, ID_edtTimed, nullptr, FALSE);
- break;
- }
- break;
- }
-}
-
-// WM_CLOSE:
-void TfrmMain::wmClose(WPARAM, LPARAM)
-{
- HWND hCtrl = GetDlgItem(m_hWnd, ID_cboxSendBy);
- size_t count = ComboBox_GetCount(hCtrl);
- for (size_t i = 0; i < count; i++) {
- UPLOAD_INFO *ui = (UPLOAD_INFO*)ComboBox_GetItemData(hCtrl, i);
- delete ui;
- }
- DestroyWindow(m_hWnd);
- return;
-}
-
-// WM_TIMER:
-const int g_iTargetBorder = 7;
-void TfrmMain::SetTargetWindow(HWND hwnd)
-{
- if (!hwnd) {
- POINT point; GetCursorPos(&point);
- hwnd = WindowFromPoint(point);
- for (HWND hTMP; (hTMP = GetParent(hwnd)); hwnd = hTMP)
- ;
- }
- m_hTargetWindow = hwnd;
- int len = GetWindowTextLength(m_hTargetWindow) + 1;
- wchar_t *lpTitle;
- if (len > 1) {
- lpTitle = (wchar_t*)mir_alloc(len*sizeof(wchar_t));
- GetWindowText(m_hTargetWindow, lpTitle, len);
- }
- else { // no WindowText present, use WindowClass
- lpTitle = (wchar_t*)mir_alloc(64 * sizeof(wchar_t));
- RealGetWindowClass(m_hTargetWindow, lpTitle, 64);
- }
- SetDlgItemText(m_hwndTabPage, ID_edtCaption, lpTitle);
- mir_free(lpTitle);
- edtSizeUpdate(m_hTargetWindow, m_opt_chkClientArea, m_hwndTabPage, ID_edtSize);
-}
-
-void TfrmMain::wmTimer(WPARAM wParam, LPARAM)
-{
- if (wParam == ID_imgTarget) { // Timer for Target selector
- static int primarymouse;
- if (!m_hTargetHighlighter) {
- primarymouse = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
- m_hTargetHighlighter = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, (wchar_t*)g_clsTargetHighlighter, nullptr, WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, g_plugin.getInst(), nullptr);
- if (!m_hTargetHighlighter) return;
- SetLayeredWindowAttributes(m_hTargetHighlighter, 0, 123, LWA_ALPHA);
- SetSystemCursor(CopyCursor(GetIcon(ICO_TARGET)), OCR_IBEAM); // text cursor
- SetSystemCursor(CopyCursor(GetIcon(ICO_TARGET)), OCR_NORMAL);
- SetActiveWindow(m_hTargetHighlighter); // activate highlighter to fix focus problems with UAC (unelevated GetAsyncKeyState() fails if an elevated app got focus)
- Hide();
- }
- if (!(GetAsyncKeyState(primarymouse) & 0x8000)) {
- KillTimer(m_hWnd, ID_imgTarget);
- SystemParametersInfo(SPI_SETCURSORS, 0, nullptr, 0);
- DestroyWindow(m_hTargetHighlighter), m_hTargetHighlighter = nullptr;
- SetTargetWindow(m_hLastWin);
- Show();
- return;
- }
- POINT point; GetCursorPos(&point);
- HWND hwnd = WindowFromPoint(point);
- if (!((GetAsyncKeyState(VK_SHIFT) | GetAsyncKeyState(VK_MENU)) & 0x8000))
- for (HWND hTMP; (hTMP = GetAncestor(hwnd, GA_PARENT)) && IsChild(hTMP, hwnd); hwnd = hTMP);
- else {
- ScreenToClient(hwnd, &point);
- HWND hTMP; if ((hTMP = RealChildWindowFromPoint(hwnd, point)))
- hwnd = hTMP;
- }
- if (hwnd != m_hLastWin) {
- m_hLastWin = hwnd;
- RECT rect;
- if (m_opt_chkClientArea) {
- GetClientRect(hwnd, &rect);
- ClientToScreen(hwnd, (POINT*)&rect);
- rect.right = rect.left + rect.right;
- rect.bottom = rect.top + rect.bottom;
- }
- else
- GetWindowRect(hwnd, &rect);
- int width = rect.right - rect.left;
- int height = rect.bottom - rect.top;
- if (g_iTargetBorder) {
- SetWindowPos(m_hTargetHighlighter, nullptr, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE);
- if (width > g_iTargetBorder * 2 && height > g_iTargetBorder * 2) {
- HRGN hRegnNew = CreateRectRgn(0, 0, width, height);
- HRGN hRgnHole = CreateRectRgn(g_iTargetBorder, g_iTargetBorder, width - g_iTargetBorder, height - g_iTargetBorder);
- CombineRgn(hRegnNew, hRegnNew, hRgnHole, RGN_XOR);
- DeleteObject(hRgnHole);
- SetWindowRgn(m_hTargetHighlighter, hRegnNew, FALSE); // cleans up hRegnNew
- }
- else SetWindowRgn(m_hTargetHighlighter, nullptr, FALSE);
- }
- SetWindowPos(m_hTargetHighlighter, HWND_TOPMOST, rect.left, rect.top, width, height, SWP_SHOWWINDOW | SWP_NOACTIVATE);
- }
- return;
- }
- if (wParam == ID_chkTimed) { // Timer for Screenshot
-#ifdef _DEBUG
- OutputDebugStringA("SS Bitmap Timer Start\r\n");
-#endif
- if (!m_bCapture) { // only start once
- if (m_Screenshot) {
- FreeImage_Unload(m_Screenshot);
- m_Screenshot = nullptr;
- }
- m_bCapture = true;
- switch (m_opt_tabCapture) {
- case 0:
- m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea, m_opt_chkIndirectCapture);
- break;
- case 1:
- m_Screenshot = CaptureMonitor((m_opt_cboxDesktop > 0) ? m_Monitors[m_opt_cboxDesktop - 1].szDevice : nullptr);
- break;
- case 2: // edge case, existing local file
- break;
-#ifdef _DEBUG
- default:
- OutputDebugStringA("SS Bitmap Timer Stop (no tabCapture)\r\n");
-#endif
- }
- m_bCapture = false;
- if (m_Screenshot || m_opt_tabCapture == 2) { // @note : test without "if"
- KillTimer(m_hWnd, ID_chkTimed);
-#ifdef _DEBUG
- OutputDebugStringA("SS Bitmap Timer Stop (CaptureDone)\r\n");
-#endif
- SendMessage(m_hWnd, UM_EVENT, 0, (LPARAM)EVT_CaptureDone);
- }
- }
- }
-}
-
-// WM_NOTIFY:
-void TfrmMain::wmNotify(WPARAM, LPARAM lParam)
-{
- switch (((LPNMHDR)lParam)->idFrom) {
- case IDC_CAPTURETAB:
- // HWND hwndFrom; = member is handle to the tab control
- // UINT_PTR idFrom; = member is the child window identifier of the tab control.
- // UINT code; = member is TCN_SELCHANGE
- switch (((LPNMHDR)lParam)->code) {
- case TCN_SELCHANGING:
- if (m_hwndTabPage) {
- ShowWindow(m_hwndTabPage, SW_HIDE);
- m_hwndTabPage = nullptr;
- }
- break;
-
- case TCN_SELCHANGE:
- {
- TAB_INFO itab = { TCIF_PARAM };
- m_opt_tabCapture = TabCtrl_GetCurSel(m_hwndTab);
- TabCtrl_GetItem(m_hwndTab, m_opt_tabCapture, &itab);
- m_hwndTabPage = itab.hwndTabPage;
- }
- ShowWindow(m_hwndTabPage, SW_SHOW);
- break;
- }
- break;
- }
-}
-
-// UM_EVENT:
-void TfrmMain::UMevent(WPARAM, LPARAM lParam)
-{
- // HWND hWnd = (HWND)wParam;
- switch (lParam) {
- case EVT_CaptureDone:
- if (!m_Screenshot && m_opt_tabCapture != 2) {
- wchar_t *err = TranslateT("Couldn't take a screenshot");
- MessageBox(nullptr, err, ERROR_TITLE, MB_OK | MB_ICONWARNING);
- Show();
- return;
- }
- FormClose();
- break;
-
- case EVT_SendFileDone:
- break;
-
- case EVT_CheckOpenAgain:
- if (m_opt_chkOpenAgain) {
- if (m_Screenshot) {
- FreeImage_Unload(m_Screenshot);
- m_Screenshot = nullptr;
- }
- Show();
- }
- else {// Saving Options and close
- SaveOptions();
- Close();
- }
- break;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Standard konstruktor/destruktor
-
-TfrmMain::TfrmMain()
-{
- /* m_opt_XXX */
- m_bOnExitSave = TRUE;
-
- m_hWnd = nullptr;
- m_hContact = NULL;
- m_hTargetWindow = m_hLastWin = nullptr;
- m_hTargetHighlighter = nullptr;
- m_FDestFolder = m_pszFile = nullptr;
- m_Screenshot = nullptr;
- /* m_AlphaColor */
- m_cSend = nullptr;
-
- m_Monitors = nullptr;
- m_MonitorCount = MonitorInfoEnum(m_Monitors, m_VirtualScreen);
- /* m_opt_XXX */ LoadOptions();
- m_bCapture = false;
- /* m_hwndTab,m_hwndTabPage */
- m_himlTab = nullptr;
-}
-
-TfrmMain::~TfrmMain()
-{
- _HandleMapping.erase(m_hWnd);
- mir_free(m_pszFile);
- mir_free(m_FDestFolder);
- mir_free(m_Monitors);
- if (m_Screenshot) FreeImage_Unload(m_Screenshot);
- if (m_cSend) delete m_cSend;
- if (m_hTargetHighlighter) {
- DestroyWindow(m_hTargetHighlighter), m_hTargetHighlighter = nullptr;
- SystemParametersInfo(SPI_SETCURSORS, 0, nullptr, 0);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Load / Saving options from miranda's database
-
-void TfrmMain::LoadOptions(void)
-{
- uint32_t rgb = g_plugin.getDword("AlphaColor", 16777215);
- m_AlphaColor.rgbRed = GetRValue(rgb);
- m_AlphaColor.rgbGreen = GetGValue(rgb);
- m_AlphaColor.rgbBlue = GetBValue(rgb);
- m_AlphaColor.rgbReserved = 0;
-
- m_opt_edtQuality = g_plugin.getByte("JpegQuality", 75);
-
- m_opt_tabCapture = g_plugin.getByte("Capture", 0);
- m_opt_chkIndirectCapture = g_plugin.getByte("IndirectCapture", 0);
- m_opt_chkClientArea = g_plugin.getByte("ClientArea", 0);
- m_opt_cboxDesktop = g_plugin.getByte("Desktop", 0);
-
- m_opt_chkTimed = g_plugin.getByte("TimedCap", 0);
- m_opt_edtTimed = g_plugin.getByte("CapTime", 3);
- m_opt_cboxFormat = g_plugin.getByte("OutputFormat", 0);
- m_opt_cboxSendBy = g_plugin.getByte("SendBy", 0);
-
- m_opt_btnDesc = g_plugin.getByte("AutoDescription", 1);
- m_opt_btnDeleteAfterSend = g_plugin.getByte("DelAfterSend", 1) != 0;
- m_opt_chkEditor = g_plugin.getByte("Preview", 0);
- m_opt_chkOpenAgain = g_plugin.getByte("OpenAgain", 0);
-}
-
-void TfrmMain::SaveOptions(void)
-{
- if (m_bOnExitSave) {
- g_plugin.setDword("AlphaColor",
- (uint32_t)RGB(m_AlphaColor.rgbRed, m_AlphaColor.rgbGreen, m_AlphaColor.rgbBlue));
-
- g_plugin.setByte("JpegQuality", m_opt_edtQuality);
-
- g_plugin.setByte("Capture", m_opt_tabCapture);
- g_plugin.setByte("IndirectCapture", m_opt_chkIndirectCapture);
- g_plugin.setByte("ClientArea", m_opt_chkClientArea);
- g_plugin.setByte("Desktop", m_opt_cboxDesktop);
-
- g_plugin.setByte("TimedCap", m_opt_chkTimed);
- g_plugin.setByte("CapTime", m_opt_edtTimed);
- g_plugin.setByte("OutputFormat", m_opt_cboxFormat);
- g_plugin.setByte("SendBy", m_opt_cboxSendBy);
-
- g_plugin.setByte("AutoDescription", m_opt_btnDesc);
- g_plugin.setByte("DelAfterSend", m_opt_btnDeleteAfterSend);
- g_plugin.setByte("Preview", m_opt_chkEditor);
- g_plugin.setByte("OpenAgain", m_opt_chkOpenAgain);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::Init(wchar_t *DestFolder, MCONTACT Contact)
-{
- m_FDestFolder = mir_wstrdup(DestFolder);
- m_hContact = Contact;
-
- // create window
- m_hWnd = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMainForm), nullptr, DlgTfrmMain, (LPARAM)this);
-
- // register object
- _HandleMapping.insert(CHandleMapping::value_type(m_hWnd, this));
-
- // check Contact
- if (m_cSend)
- m_cSend->SetContact(Contact);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::btnCaptureClick()
-{
- if (m_opt_tabCapture == 1) m_hTargetWindow = GetDesktopWindow();
- else if (m_opt_tabCapture == 2) {
- wchar_t filename[MAX_PATH];
- GetDlgItemText(m_hwndTabPage, ID_edtSize, filename, _countof(filename));
- FILE *fp = _wfopen(filename, L"rb");
- if (!fp) {
- wchar_t *err = TranslateT("Select a file");
- MessageBox(m_hWnd, err, ERROR_TITLE, MB_OK | MB_ICONWARNING);
- return;
- }
- fclose(fp);
- mir_free(m_pszFile); m_pszFile = mir_wstrdup(filename);
- }
- else if (!m_hTargetWindow) {
- wchar_t *err = TranslateT("Select a target window.");
- MessageBox(m_hWnd, err, ERROR_TITLE, MB_OK | MB_ICONWARNING);
- return;
- }
- TfrmMain::Hide();
-
- if (m_opt_chkTimed) {
- SetTimer(m_hWnd, ID_chkTimed, m_opt_edtTimed ? m_opt_edtTimed * 1000 : 500, nullptr); // calls EVT_CaptureDone
- return;
- }
- if (m_opt_tabCapture == 1) { // desktop needs always time to update from TfrmMain::Hide()
- SetTimer(m_hWnd, ID_chkTimed, 500, nullptr); // calls EVT_CaptureDone
- return;
- }
- if (m_opt_tabCapture != 2) {
- m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea, m_opt_chkIndirectCapture);
- }
- SendMessage(m_hWnd, UM_EVENT, 0, (LPARAM)EVT_CaptureDone);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::chkTimedClick()
-{
- Button_Enable(GetDlgItem(m_hWnd, ID_edtTimedLabel), (BOOL)m_opt_chkTimed);
- Button_Enable(GetDlgItem(m_hWnd, ID_edtTimed), (BOOL)m_opt_chkTimed);
- Button_Enable(GetDlgItem(m_hWnd, ID_upTimed), (BOOL)m_opt_chkTimed);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::cboxSendByChange(void *param)
-{
- BOOL bState;
- HICON hIcon;
- uint8_t itemFlag = SS_DLG_DESCRIPTION;
- if (m_cSend)
- delete m_cSend;
- switch (m_opt_cboxSendBy) {
- case SS_FILESEND: // "File Transfer"
- m_cSend = new CSendFile(m_hWnd, m_hContact, true);
- break;
- case SS_EMAIL: // "E-mail"
- m_cSend = new CSendEmail(m_hWnd, m_hContact, true);
- break;
- case SS_HTTPSERVER: // "HTTP Server"
- m_cSend = new CSendHTTPServer(m_hWnd, m_hContact, true);
- break;
- case SS_FTPFILE: // "FTP File"
- m_cSend = new CSendFTPFile(m_hWnd, m_hContact, true);
- break;
- case SS_CLOUDFILE: // "CloudFile"
- m_cSend = new CSendCloudFile(m_hWnd, m_hContact, false, (char*)param);
- break;
- case SS_IMAGESHACK: // "ImageShack"
- m_cSend = new CSendHost_ImageShack(m_hWnd, m_hContact, true);
- break;
- case SS_UPLOADPIE: // "Upload Pie"
- m_cSend = new CSendHost_UploadPie(m_hWnd, m_hContact, true, (INT_PTR)param);
- break;
- case SS_IMGUR:
- m_cSend = new CSendHost_Imgur(m_hWnd, m_hContact, true);
- break;
- default:
- m_cSend = nullptr;
- break;
- }
- if (m_cSend) {
- itemFlag = m_cSend->GetEnableItem();
- m_cSend->m_bDeleteAfterSend = m_opt_btnDeleteAfterSend;
- }
- bState = (itemFlag & SS_DLG_DELETEAFTERSSEND);
- hIcon = GetIconBtn(m_opt_btnDeleteAfterSend ? ICO_BTN_DELON : ICO_BTN_DEL);
- SendDlgItemMessage(m_hWnd, ID_chkDeleteAfterSend, BM_SETIMAGE, IMAGE_ICON, (LPARAM)(bState ? hIcon : nullptr));
- Button_Enable(GetDlgItem(m_hWnd, ID_chkDeleteAfterSend), bState);
-
- bState = (itemFlag & SS_DLG_DESCRIPTION);
- hIcon = GetIconBtn(m_opt_btnDesc ? ICO_BTN_DESCON : ICO_BTN_DESC);
- SendDlgItemMessage(m_hWnd, ID_chkDesc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)(bState ? hIcon : nullptr));
- Button_Enable(GetDlgItem(m_hWnd, ID_chkDesc), bState);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::btnExploreClick()
-{
- if (m_FDestFolder)
- ShellExecute(nullptr, L"explore", m_FDestFolder, nullptr, nullptr, SW_SHOW);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::edtSizeUpdate(HWND hWnd, BOOL ClientArea, HWND hTarget, UINT Ctrl)
-{
- // get window dimensions
- RECT rect = { 0 };
- RECT cliRect = { 0 };
- wchar_t B[33], H[16];
- GetWindowRect(hWnd, &rect);
- if (ClientArea) {
- POINT pt = { 0 };
- GetClientRect(hWnd, &cliRect);
- pt.x = cliRect.left;
- pt.y = cliRect.top;
- ClientToScreen(hWnd, &pt);
- pt.x = pt.x - rect.left; // offset x for client area
- pt.y = pt.y - rect.top; // offset y for client area
- rect = cliRect;
- }
-
- _itow(rect.right - rect.left, B, 10);
- _itow(rect.bottom - rect.top, H, 10);
- mir_wstrncat(B, L"x", _countof(B) - mir_wstrlen(B));
- mir_wstrncat(B, H, _countof(B) - mir_wstrlen(B));
- SetDlgItemText(hTarget, Ctrl, B);
-}
-
-void TfrmMain::edtSizeUpdate(RECT rect, HWND hTarget, UINT Ctrl)
-{
- wchar_t B[33], H[16];
- _itow(ABS(rect.right - rect.left), B, 10);
- _itow(ABS(rect.bottom - rect.top), H, 10);
- mir_wstrncat(B, L"x", _countof(B) - mir_wstrlen(B));
- mir_wstrncat(B, H, _countof(B) - mir_wstrlen(B));
- SetDlgItemText(hTarget, Ctrl, B);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR TfrmMain::SaveScreenshot(FIBITMAP *dib)
-{
- if (!dib)
- return 1;
-
- // generate file name
- unsigned FileNumber = g_plugin.getDword("FileNumber", 0) + 1;
- if (FileNumber > 99999)
- FileNumber = 1;
-
- CMStringW wszFileName(m_FDestFolder);
- if (wszFileName.Right(1) != L"\\")
- wszFileName.Append(L"\\");
- wszFileName.AppendFormat(L"shot%.5u", FileNumber);
-
- // generate a description according to the screenshot
- wchar_t winText[1024];
- GetDlgItemText(m_hwndTabPage, ID_edtCaption, winText, _countof(winText));
-
- CMStringW wszFileDesc;
- if (m_opt_tabCapture)
- wszFileDesc.Format(TranslateT("Screenshot of \"%s\""), winText);
- else {
- if (m_opt_chkClientArea)
- wszFileDesc.Format(TranslateT("Screenshot for client area of \"%s\" window"), winText);
- else
- wszFileDesc.Format(TranslateT("Screenshot of \"%s\" window"), winText);
- }
-
- // convert to 32Bits (make sure it is 32bit)
- FIBITMAP *dib_new = FreeImage_ConvertTo32Bits(dib);
- FreeImage_SetTransparent(dib_new, TRUE);
-
- BOOL ret = FALSE;
- HWND hwndCombo = GetDlgItem(m_hWnd, ID_cboxFormat);
- switch (ComboBox_GetItemData(hwndCombo, ComboBox_GetCurSel(hwndCombo))) {
- case 0: // PNG
- wszFileName.Append(L".png");
- ret = FreeImage_SaveU(FIF_PNG, dib_new, wszFileName, 0);
- break;
-
- case 1: // JPG
- wszFileName.Append(L".jpg");
- {
- FIBITMAP *dib32 = FreeImage_Composite(dib_new, FALSE, &m_AlphaColor, nullptr);
- FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib32);
- FreeImage_Unload(dib32);
- ret = FreeImage_SaveU(FIF_JPEG, dib24, wszFileName, 0);
- FreeImage_Unload(dib24);
- }
- break;
-
- case 2: // BMP
- wszFileName.Append(L".bmp");
- {
- FIBITMAP *dib32 = FreeImage_Composite(dib_new, FALSE, &m_AlphaColor, nullptr);
- FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib32);
- FreeImage_Unload(dib32);
- ret = FreeImage_SaveU(FIF_BMP, dib24, wszFileName, 0);
- FreeImage_Unload(dib24);
- }
- break;
-
- case 3: // TIFF (miranda freeimage interface do not support save tiff, we udse GDI+)
- wszFileName.Append(L".tif");
- {
- FIBITMAP *dib32 = FreeImage_Composite(dib_new, FALSE, &m_AlphaColor, nullptr);
- FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib32);
- FreeImage_Unload(dib32);
-
- HBITMAP hBmp = FreeImage_CreateHBITMAPFromDIB(dib24);
- FreeImage_Unload(dib24);
- SaveTIF(hBmp, wszFileName);
- DeleteObject(hBmp);
- }
- ret = TRUE;
- break;
-
- case 4: // GIF
- wszFileName.Append(L".gif");
- {
- HBITMAP hBmp = FreeImage_CreateHBITMAPFromDIB(dib_new);
- SaveGIF(hBmp, wszFileName);
- DeleteObject(hBmp);
- }
- ret = TRUE;
- break;
- }
-
- FreeImage_Unload(dib_new);
-
- if (!ret)
- return 1;
-
- g_plugin.setDword("FileNumber", FileNumber);
- replaceStrW(m_pszFile, wszFileName);
-
- if (!IsWindowEnabled(GetDlgItem(m_hWnd, ID_chkDesc)) || !m_opt_btnDesc)
- wszFileDesc.Empty();
-
- if (m_cSend) {
- m_cSend->SetFile(m_pszFile);
- m_cSend->SetDescription(wszFileDesc);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void TfrmMain::FormClose()
-{
- bool bCanDelete = m_opt_btnDeleteAfterSend;
- if (m_opt_tabCapture == 2) { // existing file
- wchar_t description[1024];
- GetDlgItemText(m_hwndTabPage, ID_edtCaption, description, _countof(description));
- if (!IsWindowEnabled(GetDlgItem(m_hWnd, ID_chkDesc)) || !m_opt_btnDesc)
- *description = '\0';
- if (m_cSend) {
- m_cSend->m_bDeleteAfterSend = false; // well... guess it's better to not delete existing files for now...
- m_cSend->SetFile(m_pszFile);
- m_cSend->SetDescription(description);
- }
- bCanDelete = false;
- }
- else if (SaveScreenshot(m_Screenshot)) { // Saving the screenshot
- Show(); // Error from SaveScreenshot
- return;
- }
-
- bool send = true;
- if (m_opt_chkEditor) {
- SHELLEXECUTEINFO shex = { sizeof(SHELLEXECUTEINFO) };
- shex.fMask = SEE_MASK_NOCLOSEPROCESS;
- shex.lpVerb = L"edit";
- shex.lpFile = m_pszFile;
- shex.nShow = SW_SHOWNORMAL;
- ShellExecuteEx(&shex);
- if (shex.hProcess) {
- uint32_t res;
- MSG msg;
- do {
- // wait for editor exit or messages/input
- res = MsgWaitForMultipleObjects(1, &shex.hProcess, 0, INFINITE, QS_ALLINPUT);
- while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT) {
- res = WAIT_OBJECT_0;
- PostMessage(nullptr, WM_QUIT, 0, 0); // forward for outer message loops
- break;
- }
-
- // process dialog messages (of unknown dialogs)
- HWND hwndDlgModeless = GetActiveWindow();
- if (hwndDlgModeless != nullptr && IsDialogMessage(hwndDlgModeless, &msg)) /* Wine fix. */
- continue;
-
- // process messages
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- } while (res == WAIT_OBJECT_0 + 1);
- CloseHandle(shex.hProcess);
- }
- if (MessageBox(m_hWnd, TranslateT("Send screenshot?"), L"SendSS", MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL) != IDYES)
- send = false;
- }
-
- if (send && m_cSend && m_pszFile) {
- if (!m_cSend->Send()) // not sent now, class deletes itself later
- m_cSend = nullptr;
- cboxSendByChange(nullptr);
- }
- else if (!send && bCanDelete)
- DeleteFile(m_pszFile);
-
- SendMessage(m_hWnd, UM_EVENT, 0, (LPARAM)EVT_CheckOpenAgain);
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+#include <list>
+
+void TfrmMain::Unload()
+{
+ std::list<TfrmMain*> lst;
+ for (auto &it : _HandleMapping)
+ lst.push_back(it.second); // we can't delete inside loop.. not MT compatible
+
+ while (!lst.empty()) {
+ DestroyWindow(lst.front()->m_hWnd); // deletes class
+ lst.pop_front();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR CALLBACK TfrmMain::DlgProc_CaptureTabPage(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ // main message handling is done inside TfrmMain::DlgTfrmMain
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ switch (lParam) {
+ case IDD_UMain_CaptureWindow:
+ Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), GetIcon(ICO_TARGET));
+ SetDlgItemText(hDlg, ID_edtCaption, TranslateT("Drag&Drop the target on the desired window."));
+ break;
+ case IDD_UMain_CaptureDesktop:
+ Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), GetIcon(ICO_MONITOR));
+ break;
+ case IDD_UMain_CaptureFile:
+ Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), GetIcon(ICO_MAIN));
+ break;
+ }
+ SetFocus(GetDlgItem(hDlg, ID_imgTarget));
+ return FALSE;
+
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
+ return (INT_PTR)GetStockObject(WHITE_BRUSH);
+
+ case WM_COMMAND:
+ if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == ID_btnExplore) { // local file tab
+ OPENFILENAME ofn = { sizeof(OPENFILENAME) };
+ wchar_t filename[MAX_PATH];
+ GetDlgItemText(hDlg, ID_edtSize, filename, _countof(filename));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = hDlg;
+ ofn.lpstrFilter = L"Images\0*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tif;*.tiff\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_READONLY;
+ if (GetOpenFileName(&ofn)) {
+ SetDlgItemText(hDlg, ID_edtSize, filename);
+ }
+ break;
+ }
+ SendMessage(GetParent(hDlg), uMsg, wParam, lParam);
+ break;
+ case WM_NOTIFY:
+ SendMessage(GetParent(hDlg), uMsg, wParam, lParam);
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+TfrmMain::CHandleMapping TfrmMain::_HandleMapping;
+
+INT_PTR CALLBACK TfrmMain::DlgTfrmMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_CTLCOLOREDIT || msg == WM_CTLCOLORSTATIC) {
+ switch (GetWindowLongPtr((HWND)lParam, GWL_ID)) {
+ case IDC_HEADERBAR:
+ SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
+ break;
+ default:
+ return 0;
+ }
+ SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
+ return (INT_PTR)GetStockObject(WHITE_BRUSH);
+ }
+
+ CHandleMapping::iterator wnd;
+ if (msg == WM_INITDIALOG) {
+ wnd = _HandleMapping.insert(CHandleMapping::value_type(hWnd, reinterpret_cast<TfrmMain*>(lParam))).first;
+ wnd->second->m_hWnd = hWnd;
+ wnd->second->wmInitdialog(wParam, lParam);
+ return 0;
+ }
+ wnd = _HandleMapping.find(hWnd);
+ if (wnd == _HandleMapping.end())
+ return 0;
+
+ switch (msg) {
+ case WM_DROPFILES:
+ // Drag&Drop of local files
+ {
+ wchar_t filename[MAX_PATH];
+ if (!DragQueryFile((HDROP)wParam, 0, filename, MAX_PATH))
+ *filename = '\0';
+ DragFinish((HDROP)wParam);
+ if (wnd->second->m_hwndTabPage)
+ ShowWindow(wnd->second->m_hwndTabPage, SW_HIDE);
+
+ wnd->second->m_opt_tabCapture = 2; // activate file tab
+ TabCtrl_SetCurSel(wnd->second->m_hwndTab, wnd->second->m_opt_tabCapture);
+
+ TAB_INFO itab = { TCIF_PARAM };
+ TabCtrl_GetItem(wnd->second->m_hwndTab, wnd->second->m_opt_tabCapture, &itab);
+ wnd->second->m_hwndTabPage = itab.hwndTabPage;
+
+ ShowWindow(wnd->second->m_hwndTabPage, SW_SHOW);
+ SetDlgItemText(wnd->second->m_hwndTabPage, ID_edtSize, filename);
+ }
+ break;
+ case WM_COMMAND:
+ wnd->second->wmCommand(wParam, lParam);
+ break;
+ case WM_CLOSE:
+ wnd->second->wmClose(wParam, lParam);
+ break;
+ case WM_DESTROY:
+ delete wnd->second;
+ break;
+ case WM_NOTIFY:
+ wnd->second->wmNotify(wParam, lParam);
+ break;
+ case WM_TIMER:
+ wnd->second->wmTimer(wParam, lParam);
+ break;
+ case UM_EVENT:
+ wnd->second->UMevent(wParam, lParam);
+ break;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// WM_INITDIALOG:
+
+int EnumCloudFileServices(const CFSERVICEINFO *serviceInfo, void *param)
+{
+ HWND hCtrl = (HWND)param;
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, serviceInfo->userName), new UPLOAD_INFO(SS_CLOUDFILE, (void*)serviceInfo->accountName));
+ return 0;
+}
+
+void TfrmMain::wmInitdialog(WPARAM, LPARAM)
+{
+ HWND hCtrl;
+ // Taskbar and Window icon
+ Window_SetIcon_IcoLib(m_hWnd, GetIconHandle(ICO_MAIN));
+
+ wchar_t *pt = mir_wstrdup(Clist_GetContactDisplayName(m_hContact));
+ if (pt && (m_hContact != 0)) {
+ CMStringW string;
+ string.AppendFormat(TranslateT("Send screenshot to %s"), pt);
+ SetWindowText(m_hWnd, string);
+ }
+ mir_free(pt);
+
+ // Headerbar
+ SendDlgItemMessage(m_hWnd, IDC_HEADERBAR, WM_SETICON, ICON_BIG, (LPARAM)GetIcon(ICO_MAIN));
+
+ // Timed controls
+ CheckDlgButton(m_hWnd, ID_chkTimed, m_opt_chkTimed ? BST_CHECKED : BST_UNCHECKED);
+ SetDlgItemInt(m_hWnd, ID_edtTimed, (UINT)m_opt_edtTimed, FALSE);
+ SendDlgItemMessage(m_hWnd, ID_upTimed, UDM_SETRANGE, 0, (LPARAM)MAKELONG(250, 1));
+ chkTimedClick(); // enable disable Timed controls
+
+ // create Image list for tab control
+ if (!m_himlTab) {
+ m_himlTab = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1);
+ ImageList_AddIcon(m_himlTab, GetIcon(ICO_TARGET));
+ ImageList_AddIcon(m_himlTab, GetIcon(ICO_MONITOR));
+ ImageList_AddIcon(m_himlTab, GetIconBtn(ICO_BTN_FOLDER));
+ }
+
+ // create the tab control.
+ {
+ m_hwndTab = GetDlgItem(m_hWnd, IDC_CAPTURETAB);
+ TabCtrl_SetImageList(m_hwndTab, m_himlTab);
+ TabCtrl_SetItemExtra(m_hwndTab, sizeof(TAB_INFO) - sizeof(TCITEMHEADER));
+ RECT rcTab;
+ TAB_INFO itab;
+ itab.hwndMain = m_hWnd;
+ itab.hwndTab = m_hwndTab;
+ itab.tcih.mask = TCIF_PARAM | TCIF_TEXT | TCIF_IMAGE;
+
+ // Add a tab for each of the three child dialog boxes.
+ itab.tcih.pszText = TranslateT("Window");
+ itab.tcih.iImage = 0;
+ itab.hwndTabPage = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMain_CaptureWindow), m_hWnd, DlgProc_CaptureTabPage, IDD_UMain_CaptureWindow);
+ TabCtrl_InsertItem(m_hwndTab, 0, &itab);
+
+ // get tab boundaries (required after 1st tab)
+ GetClientRect(m_hwndTab, &rcTab);
+ MapWindowPoints(m_hwndTab, m_hWnd, (POINT*)&rcTab, 2);
+ TabCtrl_AdjustRect(m_hwndTab, 0, &rcTab);
+ rcTab.bottom -= rcTab.top; rcTab.right -= rcTab.left;
+
+ SetWindowPos(itab.hwndTabPage, HWND_TOP, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom, 0);
+ CheckDlgButton(itab.hwndTabPage, ID_chkIndirectCapture, m_opt_chkIndirectCapture ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(itab.hwndTabPage, ID_chkClientArea, m_opt_chkClientArea ? BST_CHECKED : BST_UNCHECKED);
+
+ itab.tcih.pszText = TranslateT("Desktop");
+ itab.tcih.iImage = 1;
+ itab.hwndTabPage = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMain_CaptureDesktop), m_hWnd, DlgProc_CaptureTabPage, IDD_UMain_CaptureDesktop);
+ TabCtrl_InsertItem(m_hwndTab, 1, &itab);
+ SetWindowPos(itab.hwndTabPage, HWND_TOP, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom, 0);
+
+ hCtrl = GetDlgItem(itab.hwndTabPage, ID_edtCaption);
+ ComboBox_ResetContent(hCtrl);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Entire Desktop>")), 0);
+ ComboBox_SetCurSel(hCtrl, 0);
+ if (m_MonitorCount > 1) {
+ wchar_t tszTemp[120];
+ for (size_t mon = 0; mon < m_MonitorCount; ++mon) { // @todo : fix format for non MSVC compilers
+ mir_snwprintf(tszTemp, L"%Iu. %s%s",
+ mon + 1, TranslateT("Monitor"),
+ (m_Monitors[mon].dwFlags & MONITORINFOF_PRIMARY) ? TranslateT(" (primary)") : L""
+ );
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, tszTemp), mon + 1);
+ }
+ ComboBox_SelectItem(hCtrl, m_opt_cboxDesktop);
+ }
+ PostMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(ID_edtCaption, CBN_SELCHANGE), (LPARAM)hCtrl);
+
+ itab.tcih.pszText = TranslateT("File");
+ itab.tcih.iImage = 2;
+ itab.hwndTabPage = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMain_CaptureFile), m_hWnd, DlgProc_CaptureTabPage, IDD_UMain_CaptureFile);
+ TabCtrl_InsertItem(m_hwndTab, 2, &itab);
+ SetWindowPos(itab.hwndTabPage, HWND_TOP, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom, 0);
+
+ // select tab and set m_hwndTabPage
+ TabCtrl_SetCurSel(m_hwndTab, m_opt_tabCapture);
+ itab.tcih.mask = TCIF_PARAM;
+ TabCtrl_GetItem(m_hwndTab, m_opt_tabCapture, &itab);
+ m_hwndTabPage = itab.hwndTabPage;
+ ShowWindow(m_hwndTabPage, SW_SHOW);
+
+ // enable Drag&Drop for local file pane
+ typedef BOOL(WINAPI *ChangeWindowMessageFilterEx_t)(HWND hwnd, UINT message, uint32_t action, PCHANGEFILTERSTRUCT pChangeFilterStruct);
+ ChangeWindowMessageFilterEx_t pChangeWindowMessageFilterEx;
+ pChangeWindowMessageFilterEx = (ChangeWindowMessageFilterEx_t)GetProcAddress(GetModuleHandleA("user32"), "ChangeWindowMessageFilterEx");
+ if (pChangeWindowMessageFilterEx) { // Win7+, UAC fix
+ pChangeWindowMessageFilterEx(m_hWnd, WM_DROPFILES, MSGFLT_ALLOW, nullptr);
+ pChangeWindowMessageFilterEx(m_hWnd, WM_COPYDATA, MSGFLT_ALLOW, nullptr);
+ pChangeWindowMessageFilterEx(m_hWnd, 0x0049/*WM_COPYGLOBALDATA*/, MSGFLT_ALLOW, nullptr);
+ }
+ DragAcceptFiles(m_hWnd, 1);
+ }
+
+ // init Format combo box
+ {
+ hCtrl = GetDlgItem(m_hWnd, ID_cboxFormat);
+ ComboBox_ResetContent(hCtrl);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"PNG"), 0);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"JPG"), 1);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"BMP"), 2);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"TIF"), 3);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"GIF"), 4);
+ ComboBox_SelectItem(hCtrl, m_opt_cboxFormat);
+ }
+
+ // init SendBy combo box
+ UPLOAD_INFO *pDefault = nullptr;
+ {
+ hCtrl = GetDlgItem(m_hWnd, ID_cboxSendBy);
+ ComboBox_ResetContent(hCtrl);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Only save>")), new UPLOAD_INFO(SS_JUSTSAVE));
+ if (m_hContact) {
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("File Transfer")), new UPLOAD_INFO(SS_FILESEND));
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("E-mail")), new UPLOAD_INFO(SS_EMAIL));
+ if (g_myGlobals.PluginHTTPExist) {
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"HTTP Server"), new UPLOAD_INFO(SS_HTTPSERVER));
+ }
+ else if (m_opt_cboxSendBy == SS_HTTPSERVER) {
+ m_opt_cboxSendBy = SS_IMAGESHACK;
+ }
+ if (g_myGlobals.PluginFTPExist) {
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("FTP File")), new UPLOAD_INFO(SS_FTPFILE));
+ }
+ else if (m_opt_cboxSendBy == SS_FTPFILE) {
+ m_opt_cboxSendBy = SS_IMAGESHACK;
+ }
+ }
+ else if (m_opt_cboxSendBy == SS_FILESEND || m_opt_cboxSendBy == SS_EMAIL || m_opt_cboxSendBy == SS_HTTPSERVER || m_opt_cboxSendBy == SS_FTPFILE) {
+ m_opt_cboxSendBy = SS_IMAGESHACK;
+ }
+ if (g_myGlobals.PluginCloudFileExist) {
+ CallService(MS_CLOUDFILE_ENUMSERVICES, (WPARAM)EnumCloudFileServices, (LPARAM)hCtrl);
+ }
+ else if (m_opt_cboxSendBy == SS_CLOUDFILE) {
+ m_opt_cboxSendBy = SS_IMAGESHACK;
+ }
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"ImageShack"), new UPLOAD_INFO(SS_IMAGESHACK));
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upload Pie (30m)")), new UPLOAD_INFO(SS_UPLOADPIE, (void*)1));
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upload Pie (1d)")), new UPLOAD_INFO(SS_UPLOADPIE, (void*)4));
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upload Pie (1w)")), new UPLOAD_INFO(SS_UPLOADPIE, (void*)5));
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, L"Imgur"), new UPLOAD_INFO(SS_IMGUR));
+
+ for (int i = 0; i < ComboBox_GetCount(hCtrl); i++) {
+ UPLOAD_INFO *p = (UPLOAD_INFO*)ComboBox_GetItemData(hCtrl, i);
+ if (p && p->sendBy == m_opt_cboxSendBy) {
+ pDefault = p;
+ ComboBox_SetCurSel(hCtrl, i);
+ break;
+ }
+ }
+ }
+
+ // init footer options
+ CheckDlgButton(m_hWnd, ID_chkOpenAgain, m_opt_chkOpenAgain ? BST_CHECKED : BST_UNCHECKED);
+
+ if (hCtrl = GetDlgItem(m_hWnd, ID_btnExplore)) {
+ SendDlgItemMessage(m_hWnd, ID_btnExplore, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open Folder"), MBBF_TCHAR);
+ HICON hIcon = GetIconBtn(ICO_BTN_FOLDER);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ SetWindowText(hCtrl, hIcon ? L"" : L"...");
+ }
+
+ if (hCtrl = GetDlgItem(m_hWnd, ID_chkDesc)) {
+ SendDlgItemMessage(m_hWnd, ID_chkDesc, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Fill description textbox."), MBBF_TCHAR);
+ HICON hIcon = GetIconBtn(m_opt_btnDesc ? ICO_BTN_DESCON : ICO_BTN_DESC);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ SetWindowText(hCtrl, hIcon ? L"" : L"D");
+ SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDesc ? BST_CHECKED : BST_UNCHECKED, NULL);
+ }
+
+ if (hCtrl = GetDlgItem(m_hWnd, ID_chkDeleteAfterSend)) {
+ SendDlgItemMessage(m_hWnd, ID_chkDeleteAfterSend, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete after send"), MBBF_TCHAR);
+ HICON hIcon = GetIconBtn(m_opt_btnDeleteAfterSend ? ICO_BTN_DELON : ICO_BTN_DEL);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ SetWindowText(hCtrl, hIcon ? L"" : L"X");
+ SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDeleteAfterSend ? BST_CHECKED : BST_UNCHECKED, NULL);
+ }
+
+ if (hCtrl = GetDlgItem(m_hWnd, ID_chkEditor)) {
+ SendDlgItemMessage(m_hWnd, ID_chkEditor, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open editor before sending"), MBBF_TCHAR);
+ HICON hIcon = GetIconBtn(m_opt_chkEditor ? ICO_BTN_EDITON : ICO_BTN_EDIT);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ SetWindowText(hCtrl, hIcon ? L"" : L"E");
+ SendMessage(hCtrl, BM_SETCHECK, m_opt_chkEditor ? BST_CHECKED : BST_UNCHECKED, NULL);
+ }
+
+ if (hCtrl = GetDlgItem(m_hWnd, ID_btnCapture)) {
+ SendMessage(hCtrl, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Capture"), MBBF_TCHAR);
+ HICON hIcon = GetIconBtn(ICO_BTN_OK);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ SetWindowText(hCtrl, TranslateT("&Capture"));
+ SendMessage(hCtrl, BUTTONSETDEFAULT, 1, NULL);
+ }
+ cboxSendByChange((pDefault) ? pDefault->param : nullptr); // enable disable controls
+
+ TranslateDialogDefault(m_hWnd);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// WM_COMMAND:
+
+void TfrmMain::wmCommand(WPARAM wParam, LPARAM lParam)
+{
+ HICON hIcon;
+
+ int IDControl = LOWORD(wParam);
+ switch (HIWORD(wParam)) {
+ case BN_CLICKED: // Button controls
+ switch (IDControl) {
+ case IDCANCEL: // ESC pressed
+ this->Close();
+ break;
+ case ID_chkTimed:
+ m_opt_chkTimed = (uint8_t)Button_GetCheck((HWND)lParam);
+ TfrmMain::chkTimedClick();
+ break;
+ case ID_chkIndirectCapture:
+ m_opt_chkIndirectCapture = (uint8_t)Button_GetCheck((HWND)lParam);
+ break;
+ case ID_chkClientArea:
+ m_opt_chkClientArea = (uint8_t)Button_GetCheck((HWND)lParam);
+ if (m_hTargetWindow)
+ edtSizeUpdate(m_hTargetWindow, m_opt_chkClientArea, GetParent((HWND)lParam), ID_edtSize);
+ break;
+ case ID_imgTarget:
+ if (m_opt_tabCapture != 0) break;
+ m_hLastWin = nullptr;
+ SetTimer(m_hWnd, ID_imgTarget, BUTTON_POLLDELAY, nullptr);
+ break;
+ case ID_btnExplore:
+ TfrmMain::btnExploreClick();
+ break;
+ case ID_chkDesc:
+ m_opt_btnDesc = !m_opt_btnDesc;
+ hIcon = GetIconBtn(m_opt_btnDesc ? ICO_BTN_DESCON : ICO_BTN_DESC);
+ SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ break;
+ case ID_chkDeleteAfterSend:
+ m_opt_btnDeleteAfterSend = !m_opt_btnDeleteAfterSend;
+ hIcon = GetIconBtn(m_opt_btnDeleteAfterSend ? ICO_BTN_DELON : ICO_BTN_DEL);
+ SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ if (m_cSend) m_cSend->m_bDeleteAfterSend = m_opt_btnDeleteAfterSend;
+ break;
+ case ID_chkEditor:
+ m_opt_chkEditor = !m_opt_chkEditor;
+ hIcon = GetIconBtn(m_opt_chkEditor ? ICO_BTN_EDITON : ICO_BTN_EDIT);
+ SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ break;
+ case ID_chkOpenAgain:
+ m_opt_chkOpenAgain = Button_GetCheck((HWND)lParam);
+ break;
+ case ID_btnCapture:
+ TfrmMain::btnCaptureClick();
+ break;
+ }
+ break;
+
+ case CBN_SELCHANGE: // ComboBox controls
+ switch (IDControl) { // lParam = Handle to the control
+ case ID_cboxFormat: // not finish
+ m_opt_cboxFormat = (uint8_t)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
+ break;
+ case ID_cboxSendBy:
+ {
+ UPLOAD_INFO *upload = (UPLOAD_INFO*)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
+ m_opt_cboxSendBy = upload->sendBy;
+ cboxSendByChange(upload->param);
+ }
+ break;
+
+ case ID_edtCaption: // cboxDesktopChange
+ m_opt_cboxDesktop = (uint8_t)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
+ m_hTargetWindow = nullptr;
+ if (m_opt_cboxDesktop > 0) {
+ edtSizeUpdate(m_Monitors[m_opt_cboxDesktop - 1].rcMonitor, GetParent((HWND)lParam), ID_edtSize);
+ }
+ else {
+ edtSizeUpdate(m_VirtualScreen, GetParent((HWND)lParam), ID_edtSize);
+ }
+ break;
+ }
+ break;
+
+ case EN_CHANGE: // Edit controls
+ switch (IDControl) { // lParam = Handle to the control
+ case ID_edtQuality:
+ m_opt_edtQuality = (uint8_t)GetDlgItemInt(m_hWnd, ID_edtQuality, nullptr, FALSE);
+ break;
+ case ID_edtTimed:
+ m_opt_edtTimed = (uint8_t)GetDlgItemInt(m_hWnd, ID_edtTimed, nullptr, FALSE);
+ break;
+ }
+ break;
+ }
+}
+
+// WM_CLOSE:
+void TfrmMain::wmClose(WPARAM, LPARAM)
+{
+ HWND hCtrl = GetDlgItem(m_hWnd, ID_cboxSendBy);
+ size_t count = ComboBox_GetCount(hCtrl);
+ for (size_t i = 0; i < count; i++) {
+ UPLOAD_INFO *ui = (UPLOAD_INFO*)ComboBox_GetItemData(hCtrl, i);
+ delete ui;
+ }
+ DestroyWindow(m_hWnd);
+ return;
+}
+
+// WM_TIMER:
+const int g_iTargetBorder = 7;
+void TfrmMain::SetTargetWindow(HWND hwnd)
+{
+ if (!hwnd) {
+ POINT point; GetCursorPos(&point);
+ hwnd = WindowFromPoint(point);
+ for (HWND hTMP; (hTMP = GetParent(hwnd)); hwnd = hTMP)
+ ;
+ }
+ m_hTargetWindow = hwnd;
+ int len = GetWindowTextLength(m_hTargetWindow) + 1;
+ wchar_t *lpTitle;
+ if (len > 1) {
+ lpTitle = (wchar_t*)mir_alloc(len*sizeof(wchar_t));
+ GetWindowText(m_hTargetWindow, lpTitle, len);
+ }
+ else { // no WindowText present, use WindowClass
+ lpTitle = (wchar_t*)mir_alloc(64 * sizeof(wchar_t));
+ RealGetWindowClass(m_hTargetWindow, lpTitle, 64);
+ }
+ SetDlgItemText(m_hwndTabPage, ID_edtCaption, lpTitle);
+ mir_free(lpTitle);
+ edtSizeUpdate(m_hTargetWindow, m_opt_chkClientArea, m_hwndTabPage, ID_edtSize);
+}
+
+void TfrmMain::wmTimer(WPARAM wParam, LPARAM)
+{
+ if (wParam == ID_imgTarget) { // Timer for Target selector
+ static int primarymouse;
+ if (!m_hTargetHighlighter) {
+ primarymouse = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
+ m_hTargetHighlighter = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, (wchar_t*)g_clsTargetHighlighter, nullptr, WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, g_plugin.getInst(), nullptr);
+ if (!m_hTargetHighlighter) return;
+ SetLayeredWindowAttributes(m_hTargetHighlighter, 0, 123, LWA_ALPHA);
+ SetSystemCursor(CopyCursor(GetIcon(ICO_TARGET)), OCR_IBEAM); // text cursor
+ SetSystemCursor(CopyCursor(GetIcon(ICO_TARGET)), OCR_NORMAL);
+ SetActiveWindow(m_hTargetHighlighter); // activate highlighter to fix focus problems with UAC (unelevated GetAsyncKeyState() fails if an elevated app got focus)
+ Hide();
+ }
+ if (!(GetAsyncKeyState(primarymouse) & 0x8000)) {
+ KillTimer(m_hWnd, ID_imgTarget);
+ SystemParametersInfo(SPI_SETCURSORS, 0, nullptr, 0);
+ DestroyWindow(m_hTargetHighlighter), m_hTargetHighlighter = nullptr;
+ SetTargetWindow(m_hLastWin);
+ Show();
+ return;
+ }
+ POINT point; GetCursorPos(&point);
+ HWND hwnd = WindowFromPoint(point);
+ if (!((GetAsyncKeyState(VK_SHIFT) | GetAsyncKeyState(VK_MENU)) & 0x8000))
+ for (HWND hTMP; (hTMP = GetAncestor(hwnd, GA_PARENT)) && IsChild(hTMP, hwnd); hwnd = hTMP);
+ else {
+ ScreenToClient(hwnd, &point);
+ HWND hTMP; if ((hTMP = RealChildWindowFromPoint(hwnd, point)))
+ hwnd = hTMP;
+ }
+ if (hwnd != m_hLastWin) {
+ m_hLastWin = hwnd;
+ RECT rect;
+ if (m_opt_chkClientArea) {
+ GetClientRect(hwnd, &rect);
+ ClientToScreen(hwnd, (POINT*)&rect);
+ rect.right = rect.left + rect.right;
+ rect.bottom = rect.top + rect.bottom;
+ }
+ else
+ GetWindowRect(hwnd, &rect);
+ int width = rect.right - rect.left;
+ int height = rect.bottom - rect.top;
+ if (g_iTargetBorder) {
+ SetWindowPos(m_hTargetHighlighter, nullptr, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE);
+ if (width > g_iTargetBorder * 2 && height > g_iTargetBorder * 2) {
+ HRGN hRegnNew = CreateRectRgn(0, 0, width, height);
+ HRGN hRgnHole = CreateRectRgn(g_iTargetBorder, g_iTargetBorder, width - g_iTargetBorder, height - g_iTargetBorder);
+ CombineRgn(hRegnNew, hRegnNew, hRgnHole, RGN_XOR);
+ DeleteObject(hRgnHole);
+ SetWindowRgn(m_hTargetHighlighter, hRegnNew, FALSE); // cleans up hRegnNew
+ }
+ else SetWindowRgn(m_hTargetHighlighter, nullptr, FALSE);
+ }
+ SetWindowPos(m_hTargetHighlighter, HWND_TOPMOST, rect.left, rect.top, width, height, SWP_SHOWWINDOW | SWP_NOACTIVATE);
+ }
+ return;
+ }
+ if (wParam == ID_chkTimed) { // Timer for Screenshot
+#ifdef _DEBUG
+ OutputDebugStringA("SS Bitmap Timer Start\r\n");
+#endif
+ if (!m_bCapture) { // only start once
+ if (m_Screenshot) {
+ FreeImage_Unload(m_Screenshot);
+ m_Screenshot = nullptr;
+ }
+ m_bCapture = true;
+ switch (m_opt_tabCapture) {
+ case 0:
+ m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea, m_opt_chkIndirectCapture);
+ break;
+ case 1:
+ m_Screenshot = CaptureMonitor((m_opt_cboxDesktop > 0) ? m_Monitors[m_opt_cboxDesktop - 1].szDevice : nullptr);
+ break;
+ case 2: // edge case, existing local file
+ break;
+#ifdef _DEBUG
+ default:
+ OutputDebugStringA("SS Bitmap Timer Stop (no tabCapture)\r\n");
+#endif
+ }
+ m_bCapture = false;
+ if (m_Screenshot || m_opt_tabCapture == 2) { // @note : test without "if"
+ KillTimer(m_hWnd, ID_chkTimed);
+#ifdef _DEBUG
+ OutputDebugStringA("SS Bitmap Timer Stop (CaptureDone)\r\n");
+#endif
+ SendMessage(m_hWnd, UM_EVENT, 0, (LPARAM)EVT_CaptureDone);
+ }
+ }
+ }
+}
+
+// WM_NOTIFY:
+void TfrmMain::wmNotify(WPARAM, LPARAM lParam)
+{
+ switch (((LPNMHDR)lParam)->idFrom) {
+ case IDC_CAPTURETAB:
+ // HWND hwndFrom; = member is handle to the tab control
+ // UINT_PTR idFrom; = member is the child window identifier of the tab control.
+ // UINT code; = member is TCN_SELCHANGE
+ switch (((LPNMHDR)lParam)->code) {
+ case TCN_SELCHANGING:
+ if (m_hwndTabPage) {
+ ShowWindow(m_hwndTabPage, SW_HIDE);
+ m_hwndTabPage = nullptr;
+ }
+ break;
+
+ case TCN_SELCHANGE:
+ {
+ TAB_INFO itab = { TCIF_PARAM };
+ m_opt_tabCapture = TabCtrl_GetCurSel(m_hwndTab);
+ TabCtrl_GetItem(m_hwndTab, m_opt_tabCapture, &itab);
+ m_hwndTabPage = itab.hwndTabPage;
+ }
+ ShowWindow(m_hwndTabPage, SW_SHOW);
+ break;
+ }
+ break;
+ }
+}
+
+// UM_EVENT:
+void TfrmMain::UMevent(WPARAM, LPARAM lParam)
+{
+ // HWND hWnd = (HWND)wParam;
+ switch (lParam) {
+ case EVT_CaptureDone:
+ if (!m_Screenshot && m_opt_tabCapture != 2) {
+ wchar_t *err = TranslateT("Couldn't take a screenshot");
+ MessageBox(nullptr, err, ERROR_TITLE, MB_OK | MB_ICONWARNING);
+ Show();
+ return;
+ }
+ FormClose();
+ break;
+
+ case EVT_SendFileDone:
+ break;
+
+ case EVT_CheckOpenAgain:
+ if (m_opt_chkOpenAgain) {
+ if (m_Screenshot) {
+ FreeImage_Unload(m_Screenshot);
+ m_Screenshot = nullptr;
+ }
+ Show();
+ }
+ else {// Saving Options and close
+ SaveOptions();
+ Close();
+ }
+ break;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Standard konstruktor/destruktor
+
+TfrmMain::TfrmMain()
+{
+ /* m_opt_XXX */
+ m_bOnExitSave = TRUE;
+
+ m_hWnd = nullptr;
+ m_hContact = NULL;
+ m_hTargetWindow = m_hLastWin = nullptr;
+ m_hTargetHighlighter = nullptr;
+ m_FDestFolder = m_pszFile = nullptr;
+ m_Screenshot = nullptr;
+ /* m_AlphaColor */
+ m_cSend = nullptr;
+
+ m_Monitors = nullptr;
+ m_MonitorCount = MonitorInfoEnum(m_Monitors, m_VirtualScreen);
+ /* m_opt_XXX */ LoadOptions();
+ m_bCapture = false;
+ /* m_hwndTab,m_hwndTabPage */
+ m_himlTab = nullptr;
+}
+
+TfrmMain::~TfrmMain()
+{
+ _HandleMapping.erase(m_hWnd);
+ mir_free(m_pszFile);
+ mir_free(m_FDestFolder);
+ mir_free(m_Monitors);
+ if (m_Screenshot) FreeImage_Unload(m_Screenshot);
+ if (m_cSend) delete m_cSend;
+ if (m_hTargetHighlighter) {
+ DestroyWindow(m_hTargetHighlighter), m_hTargetHighlighter = nullptr;
+ SystemParametersInfo(SPI_SETCURSORS, 0, nullptr, 0);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Load / Saving options from miranda's database
+
+void TfrmMain::LoadOptions(void)
+{
+ uint32_t rgb = g_plugin.getDword("AlphaColor", 16777215);
+ m_AlphaColor.rgbRed = GetRValue(rgb);
+ m_AlphaColor.rgbGreen = GetGValue(rgb);
+ m_AlphaColor.rgbBlue = GetBValue(rgb);
+ m_AlphaColor.rgbReserved = 0;
+
+ m_opt_edtQuality = g_plugin.getByte("JpegQuality", 75);
+
+ m_opt_tabCapture = g_plugin.getByte("Capture", 0);
+ m_opt_chkIndirectCapture = g_plugin.getByte("IndirectCapture", 0);
+ m_opt_chkClientArea = g_plugin.getByte("ClientArea", 0);
+ m_opt_cboxDesktop = g_plugin.getByte("Desktop", 0);
+
+ m_opt_chkTimed = g_plugin.getByte("TimedCap", 0);
+ m_opt_edtTimed = g_plugin.getByte("CapTime", 3);
+ m_opt_cboxFormat = g_plugin.getByte("OutputFormat", 0);
+ m_opt_cboxSendBy = g_plugin.getByte("SendBy", 0);
+
+ m_opt_btnDesc = g_plugin.getByte("AutoDescription", 1);
+ m_opt_btnDeleteAfterSend = g_plugin.getByte("DelAfterSend", 1) != 0;
+ m_opt_chkEditor = g_plugin.getByte("Preview", 0);
+ m_opt_chkOpenAgain = g_plugin.getByte("OpenAgain", 0);
+}
+
+void TfrmMain::SaveOptions(void)
+{
+ if (m_bOnExitSave) {
+ g_plugin.setDword("AlphaColor",
+ (uint32_t)RGB(m_AlphaColor.rgbRed, m_AlphaColor.rgbGreen, m_AlphaColor.rgbBlue));
+
+ g_plugin.setByte("JpegQuality", m_opt_edtQuality);
+
+ g_plugin.setByte("Capture", m_opt_tabCapture);
+ g_plugin.setByte("IndirectCapture", m_opt_chkIndirectCapture);
+ g_plugin.setByte("ClientArea", m_opt_chkClientArea);
+ g_plugin.setByte("Desktop", m_opt_cboxDesktop);
+
+ g_plugin.setByte("TimedCap", m_opt_chkTimed);
+ g_plugin.setByte("CapTime", m_opt_edtTimed);
+ g_plugin.setByte("OutputFormat", m_opt_cboxFormat);
+ g_plugin.setByte("SendBy", m_opt_cboxSendBy);
+
+ g_plugin.setByte("AutoDescription", m_opt_btnDesc);
+ g_plugin.setByte("DelAfterSend", m_opt_btnDeleteAfterSend);
+ g_plugin.setByte("Preview", m_opt_chkEditor);
+ g_plugin.setByte("OpenAgain", m_opt_chkOpenAgain);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::Init(wchar_t *DestFolder, MCONTACT Contact)
+{
+ m_FDestFolder = mir_wstrdup(DestFolder);
+ m_hContact = Contact;
+
+ // create window
+ m_hWnd = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_UMainForm), nullptr, DlgTfrmMain, (LPARAM)this);
+
+ // register object
+ _HandleMapping.insert(CHandleMapping::value_type(m_hWnd, this));
+
+ // check Contact
+ if (m_cSend)
+ m_cSend->SetContact(Contact);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::btnCaptureClick()
+{
+ if (m_opt_tabCapture == 1) m_hTargetWindow = GetDesktopWindow();
+ else if (m_opt_tabCapture == 2) {
+ wchar_t filename[MAX_PATH];
+ GetDlgItemText(m_hwndTabPage, ID_edtSize, filename, _countof(filename));
+ FILE *fp = _wfopen(filename, L"rb");
+ if (!fp) {
+ wchar_t *err = TranslateT("Select a file");
+ MessageBox(m_hWnd, err, ERROR_TITLE, MB_OK | MB_ICONWARNING);
+ return;
+ }
+ fclose(fp);
+ mir_free(m_pszFile); m_pszFile = mir_wstrdup(filename);
+ }
+ else if (!m_hTargetWindow) {
+ wchar_t *err = TranslateT("Select a target window.");
+ MessageBox(m_hWnd, err, ERROR_TITLE, MB_OK | MB_ICONWARNING);
+ return;
+ }
+ TfrmMain::Hide();
+
+ if (m_opt_chkTimed) {
+ SetTimer(m_hWnd, ID_chkTimed, m_opt_edtTimed ? m_opt_edtTimed * 1000 : 500, nullptr); // calls EVT_CaptureDone
+ return;
+ }
+ if (m_opt_tabCapture == 1) { // desktop needs always time to update from TfrmMain::Hide()
+ SetTimer(m_hWnd, ID_chkTimed, 500, nullptr); // calls EVT_CaptureDone
+ return;
+ }
+ if (m_opt_tabCapture != 2) {
+ m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea, m_opt_chkIndirectCapture);
+ }
+ SendMessage(m_hWnd, UM_EVENT, 0, (LPARAM)EVT_CaptureDone);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::chkTimedClick()
+{
+ Button_Enable(GetDlgItem(m_hWnd, ID_edtTimedLabel), (BOOL)m_opt_chkTimed);
+ Button_Enable(GetDlgItem(m_hWnd, ID_edtTimed), (BOOL)m_opt_chkTimed);
+ Button_Enable(GetDlgItem(m_hWnd, ID_upTimed), (BOOL)m_opt_chkTimed);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::cboxSendByChange(void *param)
+{
+ BOOL bState;
+ HICON hIcon;
+ uint8_t itemFlag = SS_DLG_DESCRIPTION;
+ if (m_cSend)
+ delete m_cSend;
+ switch (m_opt_cboxSendBy) {
+ case SS_FILESEND: // "File Transfer"
+ m_cSend = new CSendFile(m_hWnd, m_hContact, true);
+ break;
+ case SS_EMAIL: // "E-mail"
+ m_cSend = new CSendEmail(m_hWnd, m_hContact, true);
+ break;
+ case SS_HTTPSERVER: // "HTTP Server"
+ m_cSend = new CSendHTTPServer(m_hWnd, m_hContact, true);
+ break;
+ case SS_FTPFILE: // "FTP File"
+ m_cSend = new CSendFTPFile(m_hWnd, m_hContact, true);
+ break;
+ case SS_CLOUDFILE: // "CloudFile"
+ m_cSend = new CSendCloudFile(m_hWnd, m_hContact, false, (char*)param);
+ break;
+ case SS_IMAGESHACK: // "ImageShack"
+ m_cSend = new CSendHost_ImageShack(m_hWnd, m_hContact, true);
+ break;
+ case SS_UPLOADPIE: // "Upload Pie"
+ m_cSend = new CSendHost_UploadPie(m_hWnd, m_hContact, true, (INT_PTR)param);
+ break;
+ case SS_IMGUR:
+ m_cSend = new CSendHost_Imgur(m_hWnd, m_hContact, true);
+ break;
+ default:
+ m_cSend = nullptr;
+ break;
+ }
+ if (m_cSend) {
+ itemFlag = m_cSend->GetEnableItem();
+ m_cSend->m_bDeleteAfterSend = m_opt_btnDeleteAfterSend;
+ }
+ bState = (itemFlag & SS_DLG_DELETEAFTERSSEND);
+ hIcon = GetIconBtn(m_opt_btnDeleteAfterSend ? ICO_BTN_DELON : ICO_BTN_DEL);
+ SendDlgItemMessage(m_hWnd, ID_chkDeleteAfterSend, BM_SETIMAGE, IMAGE_ICON, (LPARAM)(bState ? hIcon : nullptr));
+ Button_Enable(GetDlgItem(m_hWnd, ID_chkDeleteAfterSend), bState);
+
+ bState = (itemFlag & SS_DLG_DESCRIPTION);
+ hIcon = GetIconBtn(m_opt_btnDesc ? ICO_BTN_DESCON : ICO_BTN_DESC);
+ SendDlgItemMessage(m_hWnd, ID_chkDesc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)(bState ? hIcon : nullptr));
+ Button_Enable(GetDlgItem(m_hWnd, ID_chkDesc), bState);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::btnExploreClick()
+{
+ if (m_FDestFolder)
+ ShellExecute(nullptr, L"explore", m_FDestFolder, nullptr, nullptr, SW_SHOW);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::edtSizeUpdate(HWND hWnd, BOOL ClientArea, HWND hTarget, UINT Ctrl)
+{
+ // get window dimensions
+ RECT rect = { 0 };
+ RECT cliRect = { 0 };
+ wchar_t B[33], H[16];
+ GetWindowRect(hWnd, &rect);
+ if (ClientArea) {
+ POINT pt = { 0 };
+ GetClientRect(hWnd, &cliRect);
+ pt.x = cliRect.left;
+ pt.y = cliRect.top;
+ ClientToScreen(hWnd, &pt);
+ pt.x = pt.x - rect.left; // offset x for client area
+ pt.y = pt.y - rect.top; // offset y for client area
+ rect = cliRect;
+ }
+
+ _itow(rect.right - rect.left, B, 10);
+ _itow(rect.bottom - rect.top, H, 10);
+ mir_wstrncat(B, L"x", _countof(B) - mir_wstrlen(B));
+ mir_wstrncat(B, H, _countof(B) - mir_wstrlen(B));
+ SetDlgItemText(hTarget, Ctrl, B);
+}
+
+void TfrmMain::edtSizeUpdate(RECT rect, HWND hTarget, UINT Ctrl)
+{
+ wchar_t B[33], H[16];
+ _itow(ABS(rect.right - rect.left), B, 10);
+ _itow(ABS(rect.bottom - rect.top), H, 10);
+ mir_wstrncat(B, L"x", _countof(B) - mir_wstrlen(B));
+ mir_wstrncat(B, H, _countof(B) - mir_wstrlen(B));
+ SetDlgItemText(hTarget, Ctrl, B);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR TfrmMain::SaveScreenshot(FIBITMAP *dib)
+{
+ if (!dib)
+ return 1;
+
+ // generate file name
+ unsigned FileNumber = g_plugin.getDword("FileNumber", 0) + 1;
+ if (FileNumber > 99999)
+ FileNumber = 1;
+
+ CMStringW wszFileName(m_FDestFolder);
+ if (wszFileName.Right(1) != L"\\")
+ wszFileName.Append(L"\\");
+ wszFileName.AppendFormat(L"shot%.5u", FileNumber);
+
+ // generate a description according to the screenshot
+ wchar_t winText[1024];
+ GetDlgItemText(m_hwndTabPage, ID_edtCaption, winText, _countof(winText));
+
+ CMStringW wszFileDesc;
+ if (m_opt_tabCapture)
+ wszFileDesc.Format(TranslateT("Screenshot of \"%s\""), winText);
+ else {
+ if (m_opt_chkClientArea)
+ wszFileDesc.Format(TranslateT("Screenshot for client area of \"%s\" window"), winText);
+ else
+ wszFileDesc.Format(TranslateT("Screenshot of \"%s\" window"), winText);
+ }
+
+ // convert to 32Bits (make sure it is 32bit)
+ FIBITMAP *dib_new = FreeImage_ConvertTo32Bits(dib);
+ FreeImage_SetTransparent(dib_new, TRUE);
+
+ BOOL ret = FALSE;
+ HWND hwndCombo = GetDlgItem(m_hWnd, ID_cboxFormat);
+ switch (ComboBox_GetItemData(hwndCombo, ComboBox_GetCurSel(hwndCombo))) {
+ case 0: // PNG
+ wszFileName.Append(L".png");
+ ret = FreeImage_SaveU(FIF_PNG, dib_new, wszFileName, 0);
+ break;
+
+ case 1: // JPG
+ wszFileName.Append(L".jpg");
+ {
+ FIBITMAP *dib32 = FreeImage_Composite(dib_new, FALSE, &m_AlphaColor, nullptr);
+ FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib32);
+ FreeImage_Unload(dib32);
+ ret = FreeImage_SaveU(FIF_JPEG, dib24, wszFileName, 0);
+ FreeImage_Unload(dib24);
+ }
+ break;
+
+ case 2: // BMP
+ wszFileName.Append(L".bmp");
+ {
+ FIBITMAP *dib32 = FreeImage_Composite(dib_new, FALSE, &m_AlphaColor, nullptr);
+ FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib32);
+ FreeImage_Unload(dib32);
+ ret = FreeImage_SaveU(FIF_BMP, dib24, wszFileName, 0);
+ FreeImage_Unload(dib24);
+ }
+ break;
+
+ case 3: // TIFF (miranda freeimage interface do not support save tiff, we udse GDI+)
+ wszFileName.Append(L".tif");
+ {
+ FIBITMAP *dib32 = FreeImage_Composite(dib_new, FALSE, &m_AlphaColor, nullptr);
+ FIBITMAP *dib24 = FreeImage_ConvertTo24Bits(dib32);
+ FreeImage_Unload(dib32);
+
+ HBITMAP hBmp = FreeImage_CreateHBITMAPFromDIB(dib24);
+ FreeImage_Unload(dib24);
+ SaveTIF(hBmp, wszFileName);
+ DeleteObject(hBmp);
+ }
+ ret = TRUE;
+ break;
+
+ case 4: // GIF
+ wszFileName.Append(L".gif");
+ {
+ HBITMAP hBmp = FreeImage_CreateHBITMAPFromDIB(dib_new);
+ SaveGIF(hBmp, wszFileName);
+ DeleteObject(hBmp);
+ }
+ ret = TRUE;
+ break;
+ }
+
+ FreeImage_Unload(dib_new);
+
+ if (!ret)
+ return 1;
+
+ g_plugin.setDword("FileNumber", FileNumber);
+ replaceStrW(m_pszFile, wszFileName);
+
+ if (!IsWindowEnabled(GetDlgItem(m_hWnd, ID_chkDesc)) || !m_opt_btnDesc)
+ wszFileDesc.Empty();
+
+ if (m_cSend) {
+ m_cSend->SetFile(m_pszFile);
+ m_cSend->SetDescription(wszFileDesc);
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TfrmMain::FormClose()
+{
+ bool bCanDelete = m_opt_btnDeleteAfterSend;
+ if (m_opt_tabCapture == 2) { // existing file
+ wchar_t description[1024];
+ GetDlgItemText(m_hwndTabPage, ID_edtCaption, description, _countof(description));
+ if (!IsWindowEnabled(GetDlgItem(m_hWnd, ID_chkDesc)) || !m_opt_btnDesc)
+ *description = '\0';
+ if (m_cSend) {
+ m_cSend->m_bDeleteAfterSend = false; // well... guess it's better to not delete existing files for now...
+ m_cSend->SetFile(m_pszFile);
+ m_cSend->SetDescription(description);
+ }
+ bCanDelete = false;
+ }
+ else if (SaveScreenshot(m_Screenshot)) { // Saving the screenshot
+ Show(); // Error from SaveScreenshot
+ return;
+ }
+
+ bool send = true;
+ if (m_opt_chkEditor) {
+ SHELLEXECUTEINFO shex = { sizeof(SHELLEXECUTEINFO) };
+ shex.fMask = SEE_MASK_NOCLOSEPROCESS;
+ shex.lpVerb = L"edit";
+ shex.lpFile = m_pszFile;
+ shex.nShow = SW_SHOWNORMAL;
+ ShellExecuteEx(&shex);
+ if (shex.hProcess) {
+ uint32_t res;
+ MSG msg;
+ do {
+ // wait for editor exit or messages/input
+ res = MsgWaitForMultipleObjects(1, &shex.hProcess, 0, INFINITE, QS_ALLINPUT);
+ while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_QUIT) {
+ res = WAIT_OBJECT_0;
+ PostMessage(nullptr, WM_QUIT, 0, 0); // forward for outer message loops
+ break;
+ }
+
+ // process dialog messages (of unknown dialogs)
+ HWND hwndDlgModeless = GetActiveWindow();
+ if (hwndDlgModeless != nullptr && IsDialogMessage(hwndDlgModeless, &msg)) /* Wine fix. */
+ continue;
+
+ // process messages
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ } while (res == WAIT_OBJECT_0 + 1);
+ CloseHandle(shex.hProcess);
+ }
+ if (MessageBox(m_hWnd, TranslateT("Send screenshot?"), L"SendSS", MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL) != IDYES)
+ send = false;
+ }
+
+ if (send && m_cSend && m_pszFile) {
+ if (!m_cSend->Send()) // not sent now, class deletes itself later
+ m_cSend = nullptr;
+ cboxSendByChange(nullptr);
+ }
+ else if (!send && bCanDelete)
+ DeleteFile(m_pszFile);
+
+ SendMessage(m_hWnd, UM_EVENT, 0, (LPARAM)EVT_CheckOpenAgain);
+}
diff --git a/plugins/SendScreenshotPlus/src/UMainForm.h b/plugins/SendScreenshotPlus/src/UMainForm.h
index 55b75e2373..fbe8a6a50b 100644
--- a/plugins/SendScreenshotPlus/src/UMainForm.h
+++ b/plugins/SendScreenshotPlus/src/UMainForm.h
@@ -1,146 +1,146 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef UMainFormH
-#define UMainFormH
-
-#define SS_JUSTSAVE 0
-#define SS_FILESEND 1
-#define SS_EMAIL 2
-#define SS_HTTPSERVER 3
-#define SS_FTPFILE 4
-#define SS_CLOUDFILE 5
-#define SS_IMAGESHACK 6
-#define SS_UPLOADPIE 7
-#define SS_IMGUR 8
-
-struct UPLOAD_INFO
-{
- uint8_t sendBy; //SS_*
- void *param;
-
- UPLOAD_INFO(uint8_t sb) : sendBy(sb), param(nullptr) { }
- UPLOAD_INFO(uint8_t sb, void *p) : sendBy(sb), param(p) { }
-};
-
-// Used for our own cheap TrackMouseEvent
-#define BUTTON_POLLDELAY 50
-
-// User Events
-#define EVT_CaptureDone 1
-#define EVT_SendFileDone 2
-#define EVT_CheckOpenAgain 3
-
-struct TAB_INFO
-{
- TCITEMHEADER tcih;
- HWND hwndMain; // main window
- HWND hwndTab; // tab control
- HWND hwndTabPage; // current child dialog box
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class TfrmMain
-{
-
-public:
- // Deklaration Standardkonstruktor/Standarddestructor
- TfrmMain();
- ~TfrmMain();
-
- uint8_t m_opt_tabCapture; // capture tab page
- uint8_t m_opt_cboxDesktop; // TRadioButton *rbtnDesktop;
- uint8_t m_opt_chkTimed; // TCheckBox *chkTimed;
- uint8_t m_opt_cboxSendBy; // TComboBox *cboxSendBy;
- uint8_t m_opt_btnDesc; // TCheckBox *chkDesc;
- uint8_t m_opt_chkEditor; // TCheckBox *chkEditor;
- bool m_bOnExitSave;
-
- static void Unload();
- void Init(wchar_t* DestFolder, MCONTACT Contact);
- void Close(){ SendMessage(m_hWnd, WM_CLOSE, 0, 0); }
- void Show(){ ShowWindow(m_hWnd, SW_SHOW); }
- void Hide(){ ShowWindow(m_hWnd, SW_HIDE); }
- void SetTargetWindow(HWND hwnd = nullptr);
- void btnCaptureClick();
- void cboxSendByChange(void *param);
-
-private:
- HWND m_hWnd;
- MCONTACT m_hContact;
- HWND m_hTargetWindow, m_hLastWin;
- HWND m_hTargetHighlighter;
- wchar_t* m_FDestFolder;
- wchar_t* m_pszFile;
- FIBITMAP* m_Screenshot;
- RGBQUAD m_AlphaColor;
- CSend* m_cSend;
-
- void chkTimedClick();
- void btnExploreClick();
- void LoadOptions(void);
- void SaveOptions(void);
- INT_PTR SaveScreenshot(FIBITMAP* dib);
- void FormClose();
- static void edtSizeUpdate(HWND hWnd, BOOL ClientArea, HWND hTarget, UINT Ctrl);
- static void edtSizeUpdate(RECT rect, HWND hTarget, UINT Ctrl);
-
-protected:
- MONITORINFOEX* m_Monitors;
- size_t m_MonitorCount;
- RECT m_VirtualScreen;
-
- uint8_t m_opt_chkOpenAgain; // TCheckBox *chkOpenAgain;
- uint8_t m_opt_chkIndirectCapture; // TCheckBox *chkIndirectCapture;
- uint8_t m_opt_chkClientArea; // TCheckBox *chkClientArea;
- uint8_t m_opt_edtQuality; // TLabeledEdit *edtQuality;
- bool m_opt_btnDeleteAfterSend; // TCheckBox *chkDeleteAfterSend;
- uint8_t m_opt_cboxFormat; // TComboBox *cboxFormat;
- uint8_t m_opt_edtTimed; // TLabeledEdit *edtTimed;
- bool m_bCapture; // is capture active
- HWND m_hwndTab; // TabControl handle
- HWND m_hwndTabPage; // TabControl activ page handle
- HIMAGELIST m_himlTab; // TabControl imagelist
-
- typedef std::map<HWND, TfrmMain *> CHandleMapping;
- static CHandleMapping _HandleMapping;
- static INT_PTR CALLBACK DlgTfrmMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
- void wmInitdialog(WPARAM wParam, LPARAM lParam);
- void wmCommand(WPARAM wParam, LPARAM lParam);
- void wmClose(WPARAM wParam, LPARAM lParam);
- void wmNotify(WPARAM wParam, LPARAM lParam);
- void wmTimer(WPARAM wParam, LPARAM lParam);
-
- void UMevent(WPARAM wParam, LPARAM lParam);
-
- static INT_PTR CALLBACK DlgProc_CaptureTabPage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef UMainFormH
+#define UMainFormH
+
+#define SS_JUSTSAVE 0
+#define SS_FILESEND 1
+#define SS_EMAIL 2
+#define SS_HTTPSERVER 3
+#define SS_FTPFILE 4
+#define SS_CLOUDFILE 5
+#define SS_IMAGESHACK 6
+#define SS_UPLOADPIE 7
+#define SS_IMGUR 8
+
+struct UPLOAD_INFO
+{
+ uint8_t sendBy; //SS_*
+ void *param;
+
+ UPLOAD_INFO(uint8_t sb) : sendBy(sb), param(nullptr) { }
+ UPLOAD_INFO(uint8_t sb, void *p) : sendBy(sb), param(p) { }
+};
+
+// Used for our own cheap TrackMouseEvent
+#define BUTTON_POLLDELAY 50
+
+// User Events
+#define EVT_CaptureDone 1
+#define EVT_SendFileDone 2
+#define EVT_CheckOpenAgain 3
+
+struct TAB_INFO
+{
+ TCITEMHEADER tcih;
+ HWND hwndMain; // main window
+ HWND hwndTab; // tab control
+ HWND hwndTabPage; // current child dialog box
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+class TfrmMain
+{
+
+public:
+ // Deklaration Standardkonstruktor/Standarddestructor
+ TfrmMain();
+ ~TfrmMain();
+
+ uint8_t m_opt_tabCapture; // capture tab page
+ uint8_t m_opt_cboxDesktop; // TRadioButton *rbtnDesktop;
+ uint8_t m_opt_chkTimed; // TCheckBox *chkTimed;
+ uint8_t m_opt_cboxSendBy; // TComboBox *cboxSendBy;
+ uint8_t m_opt_btnDesc; // TCheckBox *chkDesc;
+ uint8_t m_opt_chkEditor; // TCheckBox *chkEditor;
+ bool m_bOnExitSave;
+
+ static void Unload();
+ void Init(wchar_t* DestFolder, MCONTACT Contact);
+ void Close(){ SendMessage(m_hWnd, WM_CLOSE, 0, 0); }
+ void Show(){ ShowWindow(m_hWnd, SW_SHOW); }
+ void Hide(){ ShowWindow(m_hWnd, SW_HIDE); }
+ void SetTargetWindow(HWND hwnd = nullptr);
+ void btnCaptureClick();
+ void cboxSendByChange(void *param);
+
+private:
+ HWND m_hWnd;
+ MCONTACT m_hContact;
+ HWND m_hTargetWindow, m_hLastWin;
+ HWND m_hTargetHighlighter;
+ wchar_t* m_FDestFolder;
+ wchar_t* m_pszFile;
+ FIBITMAP* m_Screenshot;
+ RGBQUAD m_AlphaColor;
+ CSend* m_cSend;
+
+ void chkTimedClick();
+ void btnExploreClick();
+ void LoadOptions(void);
+ void SaveOptions(void);
+ INT_PTR SaveScreenshot(FIBITMAP* dib);
+ void FormClose();
+ static void edtSizeUpdate(HWND hWnd, BOOL ClientArea, HWND hTarget, UINT Ctrl);
+ static void edtSizeUpdate(RECT rect, HWND hTarget, UINT Ctrl);
+
+protected:
+ MONITORINFOEX* m_Monitors;
+ size_t m_MonitorCount;
+ RECT m_VirtualScreen;
+
+ uint8_t m_opt_chkOpenAgain; // TCheckBox *chkOpenAgain;
+ uint8_t m_opt_chkIndirectCapture; // TCheckBox *chkIndirectCapture;
+ uint8_t m_opt_chkClientArea; // TCheckBox *chkClientArea;
+ uint8_t m_opt_edtQuality; // TLabeledEdit *edtQuality;
+ bool m_opt_btnDeleteAfterSend; // TCheckBox *chkDeleteAfterSend;
+ uint8_t m_opt_cboxFormat; // TComboBox *cboxFormat;
+ uint8_t m_opt_edtTimed; // TLabeledEdit *edtTimed;
+ bool m_bCapture; // is capture active
+ HWND m_hwndTab; // TabControl handle
+ HWND m_hwndTabPage; // TabControl activ page handle
+ HIMAGELIST m_himlTab; // TabControl imagelist
+
+ typedef std::map<HWND, TfrmMain *> CHandleMapping;
+ static CHandleMapping _HandleMapping;
+ static INT_PTR CALLBACK DlgTfrmMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ void wmInitdialog(WPARAM wParam, LPARAM lParam);
+ void wmCommand(WPARAM wParam, LPARAM lParam);
+ void wmClose(WPARAM wParam, LPARAM lParam);
+ void wmNotify(WPARAM wParam, LPARAM lParam);
+ void wmTimer(WPARAM wParam, LPARAM lParam);
+
+ void UMevent(WPARAM wParam, LPARAM lParam);
+
+ static INT_PTR CALLBACK DlgProc_CaptureTabPage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/Utils.cpp b/plugins/SendScreenshotPlus/src/Utils.cpp
index 1d0d92f5ea..bc543d1024 100644
--- a/plugins/SendScreenshotPlus/src/Utils.cpp
+++ b/plugins/SendScreenshotPlus/src/Utils.cpp
@@ -1,412 +1,412 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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"
-
-void ComboBox_SelectItem(HWND hCombo, LPARAM data)
-{
- for (int i = 0;; i++) {
- LPARAM itemData = ComboBox_GetItemData(hCombo, i);
- if (itemData == data) {
- ComboBox_SetCurSel(hCombo, i);
- return;
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// MonitorInfoEnum
-
-static BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
-{
- MONITORS* monitors = (MONITORS*)dwData;
- ++monitors->count;
- monitors->info = (MONITORINFOEX*)mir_realloc(monitors->info, sizeof(MONITORINFOEX)*monitors->count);
- monitors->info[monitors->count - 1].cbSize = sizeof(MONITORINFOEX);
- if (!GetMonitorInfo(hMonitor, (LPMONITORINFO)(monitors->info + monitors->count - 1)))
- return FALSE; // stop enumeration if error
-
- return TRUE;
-}
-
-size_t MonitorInfoEnum(MONITORINFOEX* &myMonitors, RECT &virtualScreen)
-{
- MONITORS tmp = { 0, nullptr };
- if (EnumDisplayMonitors(nullptr, nullptr, MonitorInfoEnumProc, (LPARAM)&tmp)) {
- myMonitors = tmp.info;
- memset(&virtualScreen, 0, sizeof(virtualScreen));
- for (size_t i = 0; i < tmp.count; ++i) {
- UnionRect(&virtualScreen, &virtualScreen, &tmp.info[i].rcMonitor);
- }
- return tmp.count;
- }
-
- mir_free(tmp.info);
- return 0;
-}
-
-FIBITMAP* CreateDIBFromDC(HDC hDC, const RECT* rect, HWND hCapture = nullptr);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// capture window as FIBITMAP - caller must FreeImage_Unload(dib)
-
-FIBITMAP* CaptureWindow(HWND hCapture, BOOL bClientArea, BOOL bIndirectCapture)
-{
- FIBITMAP* dib;
- HWND hForegroundWin;
- RECT rect; // cropping rect
-
- if (!hCapture || !IsWindow(hCapture))
- return nullptr;
-
- hForegroundWin = GetForegroundWindow(); // old foreground window
- SetForegroundWindow(hCapture); // force target foreground
- BringWindowToTop(hCapture); // bring it to top as well
-
- // redraw window to prevent runtime artifacts in picture
- UpdateWindow(hCapture);
-
- HWND hParent = GetAncestor(hCapture, GA_PARENT);
- if (hParent && !IsChild(hParent, hCapture))
- hParent = nullptr;
- if (bIndirectCapture) {
- intptr_t wastopmost = GetWindowLongPtr(hCapture, GWL_EXSTYLE)&WS_EX_TOPMOST;
- if (!wastopmost)
- SetWindowPos(hCapture, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- if (bClientArea) {
- GetClientRect(hCapture, &rect);
- ClientToScreen(hCapture, (POINT*)&rect);
- rect.right += rect.left; rect.bottom += rect.top;
- }
- else
- GetWindowRect(hCapture, &rect);
- dib = CaptureMonitor(nullptr, &rect);
- if (!wastopmost)
- SetWindowPos(hCapture, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- }
- else {
- HDC hDCsrc;
- GetWindowRect(hCapture, &rect);
- if (hParent)
- hDCsrc = GetDC(hCapture); // hCapture is part of a window, capture that
- else
- hDCsrc = GetWindowDC(hCapture); // entire window w/ title bar
- rect.right = ABS(rect.right - rect.left);
- rect.bottom = ABS(rect.bottom - rect.top);
- rect.left = rect.top = 0;
- // capture window and get FIBITMAP
- dib = CreateDIBFromDC(hDCsrc, &rect, hCapture);
- ReleaseDC(hCapture, hDCsrc);
-
- // we could capture directly, but doing so breaks GetWindowRgn() and also includes artifacts...
- if (bClientArea) {
- GetWindowRect(hCapture, &rect);
- RECT rectCA; GetClientRect(hCapture, &rectCA);
- ClientToScreen(hCapture, (POINT*)&rectCA);
- rectCA.left = ABS(rectCA.left - rect.left);
- rectCA.top = ABS(rectCA.top - rect.top);
- rectCA.right += rectCA.left; rectCA.bottom += rectCA.top;
-
- // crop the window to ClientArea
- FIBITMAP* dibClient = FreeImage_Copy(dib, rectCA.left, rectCA.top, rectCA.right, rectCA.bottom);
- FreeImage_Unload(dib);
- dib = dibClient;
- }
- }
-
- // restore previous foreground window
- if (hForegroundWin) {
- SetForegroundWindow(hForegroundWin);
- BringWindowToTop(hForegroundWin);
- }
- return dib;
-}
-
-FIBITMAP* CaptureMonitor(const wchar_t* szDevice, const RECT* cropRect/*=NULL*/)
-{
- HDC hScrDC;
- RECT rect;
-
- // get screen resolution
- if (!szDevice) {
- hScrDC = CreateDC(L"DISPLAY", nullptr, nullptr, nullptr);
- rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
- rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
- rect.right = GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN);
- rect.bottom = GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN);
- }
- else {
- hScrDC = CreateDC(szDevice, nullptr, nullptr, nullptr);
- rect.left = rect.top = 0;
- rect.right = GetDeviceCaps(hScrDC, HORZRES);
- rect.bottom = GetDeviceCaps(hScrDC, VERTRES);
- }
- if (cropRect) {
- if (cropRect->left > rect.left) rect.left = cropRect->left;
- if (cropRect->top > rect.top) rect.top = cropRect->top;
- if (cropRect->right < rect.right) rect.right = cropRect->right;
- if (cropRect->bottom < rect.bottom) rect.bottom = cropRect->bottom;
- }
-
- FIBITMAP *dib = CreateDIBFromDC(hScrDC, &rect);
- ReleaseDC(nullptr, hScrDC);
- return dib;
-}
-
-FIBITMAP* CreateDIBFromDC(HDC hDC, const RECT* rect, HWND hCapture/*=NULL*/)
-{
- long width = rect->right - rect->left;
- long height = rect->bottom - rect->top;
-
- // create a DC for the screen and create
- // a memory DC compatible to screen DC
- HDC hScrDC = hDC;
- if (!hScrDC)
- hScrDC = GetDC(hCapture);
- HDC hMemDC = CreateCompatibleDC(hScrDC);
- // create a bitmap compatible with the screen DC
- HBITMAP hBitmap = CreateCompatibleBitmap(hScrDC, width, height);
- // select new bitmap into memory DC
- SelectObject(hMemDC, hBitmap);
-
- if (hCapture && hDC)
- PrintWindow(hCapture, hMemDC, 0);
- else // bitblt screen DC to memory DC
- BitBlt(hMemDC, 0, 0, width, height, hScrDC, rect->left, rect->top, CAPTUREBLT | SRCCOPY);
-
- FIBITMAP *dib = FreeImage_CreateDIBFromHBITMAP(hBitmap);
-
- // alpha channel from window is always wrong and sometimes even for desktop (Win7, no aero)
- // coz GDI do not draw all in alpha mode.
- // we have to create our own new alpha channel.
- bool bFixAlpha = true;
- bool bInvert = false;
- HBRUSH hBr = CreateSolidBrush(RGB(255, 255, 255)); // Create a SolidBrush object for non transparent area
- HBITMAP hMask = CreateBitmap(width, height, 1, 1, nullptr); // Create monochrome (1 bit) B+W mask bitmap.
- HDC hMaskDC = CreateCompatibleDC(nullptr);
- SelectBitmap(hMaskDC, hMask);
- HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
- if (hCapture && GetWindowRgn(hCapture, hRgn) == ERROR) {
- if ((GetWindowLongPtr(hCapture, GWL_EXSTYLE)&WS_EX_LAYERED)) {
- uint8_t bAlpha = 0;
- COLORREF crKey = 0x00000000;
- DWORD dwFlags = 0;
- if (GetLayeredWindowAttributes(hCapture, &crKey, &bAlpha, &dwFlags)) {
- // per window transparency (like fading in a whole window)
- if ((dwFlags&LWA_COLORKEY)) {
- SetBkColor(hMemDC, crKey);
- BitBlt(hMaskDC, 0, 0, width, height, hMemDC, rect->left, rect->top, SRCCOPY);
- bInvert = true;
- }
- else if ((dwFlags&LWA_ALPHA)) {
- bFixAlpha = false;
- }
- }
- else { // per-pixel transparency (won't use the WM_PAINT)
- bFixAlpha = false;
- }
- }
- else { // not layered - fill the window region
- SetRectRgn(hRgn, 0, 0, width, height);
- FillRgn(hMaskDC, hRgn, hBr);
- }
- }
- else {
- if (!hCapture) SetRectRgn(hRgn, 0, 0, width, height); // client area only, no transparency
- FillRgn(hMaskDC, hRgn, hBr);
- }
- DeleteObject(hRgn);
- if (bFixAlpha) {
- FIBITMAP* dibMask = FreeImage_CreateDIBFromHBITMAP(hMask);
- if (bInvert) FreeImage_Invert(dibMask);
- FIBITMAP* dib8 = FreeImage_ConvertTo8Bits(dibMask);
- // copy the dib8 alpha mask to dib32 main bitmap
- FreeImage_SetChannel(dib, dib8, FICC_ALPHA);
- FreeImage_Unload(dibMask);
- FreeImage_Unload(dib8);
- }
- DeleteDC(hMaskDC);
- DeleteObject(hMask);
- DeleteObject(hBr);
-
- // clean up
- DeleteDC(hMemDC);
- DeleteObject(hBitmap);
- if (!hDC)
- ReleaseDC(nullptr, hScrDC);
-
-#ifdef _DEBUG
- switch (FreeImage_GetImageType(dib)) {
- case FIT_UNKNOWN:
- OutputDebugStringA("FIBITMAP Type: FIT_UNKNOWN\r\n");
- break;
- case FIT_BITMAP:
- OutputDebugStringA("FIBITMAP Type: FIT_BITMAP\r\n");
- break;
- case FIT_UINT16:
- OutputDebugStringA("FIBITMAP Type: FIT_UINT16\r\n");
- break;
- case FIT_INT16:
- OutputDebugStringA("FIBITMAP Type: FIT_INT16\r\n");
- break;
- case FIT_UINT32:
- OutputDebugStringA("FIBITMAP Type: FIT_UINT32\r\n");
- break;
- case FIT_INT32:
- OutputDebugStringA("FIBITMAP Type: FIT_INT32\r\n");
- break;
- case FIT_FLOAT:
- OutputDebugStringA("FIBITMAP Type: FIT_FLOAT\r\n");
- break;
- case FIT_DOUBLE:
- OutputDebugStringA("FIBITMAP Type: FIT_DOUBLE\r\n");
- break;
- case FIT_COMPLEX:
- OutputDebugStringA("FIBITMAP Type: FIT_COMPLEX\r\n");
- break;
- case FIT_RGB16:
- OutputDebugStringA("FIBITMAP Type: FIT_RGB16\r\n");
- break;
- case FIT_RGBA16:
- OutputDebugStringA("FIBITMAP Type: FIT_RGBA16\r\n");
- break;
- case FIT_RGBF:
- OutputDebugStringA("FIBITMAP Type: FIT_RGBF\r\n");
- break;
- case FIT_RGBAF:
- OutputDebugStringA("FIBITMAP Type: FIT_RGBAF\r\n");
- break;
- default:
- OutputDebugStringA("FIBITMAP Type: non detectable image type (error)\r\n");
- break;
- }
- BOOL inf = FreeImage_IsTransparent(dib);
- OutputDebugStringA(inf ? "FIBITMAP Transparent: true\r\n" : "FIBITMAP Transparent: false\r\n");
-#endif
- return dib;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-char* GetFileNameA(const wchar_t* pszPath)
-{
- const wchar_t* slash = wcsrchr(pszPath, '\\');
- if (!slash) slash = wcsrchr(pszPath, '/');
- if (slash)
- return mir_u2a(slash + 1);
- else
- return mir_u2a(pszPath);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-BOOL GetEncoderClsid(wchar_t *wchMimeType, CLSID &clsidEncoder)
-{
- UINT uiNum = 0;
- UINT uiSize = 0;
- BOOL bOk = FALSE;
- Gdiplus::GetImageEncodersSize(&uiNum, &uiSize);
- if (uiSize > 0) {
- Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)mir_alloc(uiSize);
- if (pImageCodecInfo) {
- Gdiplus::GetImageEncoders(uiNum, uiSize, pImageCodecInfo);
- for (UINT i = 0; i < uiNum; ++i) {
- if (!mir_wstrcmp(pImageCodecInfo[i].MimeType, wchMimeType)) {
- clsidEncoder = pImageCodecInfo[i].Clsid;
- bOk = TRUE;
- }
- }
- mir_free(pImageCodecInfo);
- }
- }
- return bOk;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void SaveGIF(HBITMAP hBmp, const wchar_t *szFilename)
-{
- Gdiplus::GdiplusStartupInput gdiplusStartupInput;
- ULONG_PTR gdiplusToken;
- Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
-
- Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE));
- if (pBitmap) {
- // Get the CLSID of the GIF encoder.
- CLSID clsidEncoder;
- if (GetEncoderClsid(L"image/gif", clsidEncoder)) {
- LPWSTR pswFile = mir_wstrdup(szFilename);
- pBitmap->Save((const wchar_t*)pswFile, &clsidEncoder, nullptr);
- mir_free(pswFile);
- }
- delete pBitmap;
- }
- Gdiplus::GdiplusShutdown(gdiplusToken);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void SaveTIF(HBITMAP hBmp, const wchar_t *szFilename)
-{
- // http://www.codeproject.com/Messages/1406708/How-to-reduce-the-size-of-an-Image-using-GDIplus.aspx
- ULONG_PTR gdiplusToken;
- Gdiplus::GdiplusStartupInput gdiplusStartupInput;
- Gdiplus::Status stat;
- Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
-
- Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE));
- if (pBitmap) {
- // Get the CLSID of the GIF encoder.
- CLSID EncCLSID;
- if (GetEncoderClsid(L"image/tiff", EncCLSID)) {
- //--- Create a 2-parameter array, for Compression and for Color Bit depth
- Gdiplus::EncoderParameters* EncParams = (Gdiplus::EncoderParameters*) malloc(sizeof(Gdiplus::EncoderParameters) + 1 * sizeof(Gdiplus::EncoderParameter));
- // Gdiplus::EncoderParameters pEncoderParameters;
- //--- Use LZW Compression instead of Group 4, since it works for color and G4 doesn't
- ULONG ulCompression = Gdiplus::EncoderValueCompressionLZW;
- ULONG ulColorDepth = 24L;
-
- EncParams->Count = 2;
- EncParams->Parameter[0].Guid = Gdiplus::EncoderCompression;
- EncParams->Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
- EncParams->Parameter[0].NumberOfValues = 1;
- EncParams->Parameter[0].Value = &ulCompression;
- EncParams->Parameter[1].Guid = Gdiplus::EncoderColorDepth;
- EncParams->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;
- EncParams->Parameter[1].NumberOfValues = 1;
- EncParams->Parameter[1].Value = &ulColorDepth;
-
- LPWSTR pswFile = mir_wstrdup(szFilename);
- stat = pBitmap->Save((const wchar_t*)pswFile, &EncCLSID, EncParams);
- mir_free(pswFile);
- free(EncParams);
- }
- delete pBitmap;
- }
- Gdiplus::GdiplusShutdown(gdiplusToken);
-}
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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"
+
+void ComboBox_SelectItem(HWND hCombo, LPARAM data)
+{
+ for (int i = 0;; i++) {
+ LPARAM itemData = ComboBox_GetItemData(hCombo, i);
+ if (itemData == data) {
+ ComboBox_SetCurSel(hCombo, i);
+ return;
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MonitorInfoEnum
+
+static BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
+{
+ MONITORS* monitors = (MONITORS*)dwData;
+ ++monitors->count;
+ monitors->info = (MONITORINFOEX*)mir_realloc(monitors->info, sizeof(MONITORINFOEX)*monitors->count);
+ monitors->info[monitors->count - 1].cbSize = sizeof(MONITORINFOEX);
+ if (!GetMonitorInfo(hMonitor, (LPMONITORINFO)(monitors->info + monitors->count - 1)))
+ return FALSE; // stop enumeration if error
+
+ return TRUE;
+}
+
+size_t MonitorInfoEnum(MONITORINFOEX* &myMonitors, RECT &virtualScreen)
+{
+ MONITORS tmp = { 0, nullptr };
+ if (EnumDisplayMonitors(nullptr, nullptr, MonitorInfoEnumProc, (LPARAM)&tmp)) {
+ myMonitors = tmp.info;
+ memset(&virtualScreen, 0, sizeof(virtualScreen));
+ for (size_t i = 0; i < tmp.count; ++i) {
+ UnionRect(&virtualScreen, &virtualScreen, &tmp.info[i].rcMonitor);
+ }
+ return tmp.count;
+ }
+
+ mir_free(tmp.info);
+ return 0;
+}
+
+FIBITMAP* CreateDIBFromDC(HDC hDC, const RECT* rect, HWND hCapture = nullptr);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// capture window as FIBITMAP - caller must FreeImage_Unload(dib)
+
+FIBITMAP* CaptureWindow(HWND hCapture, BOOL bClientArea, BOOL bIndirectCapture)
+{
+ FIBITMAP* dib;
+ HWND hForegroundWin;
+ RECT rect; // cropping rect
+
+ if (!hCapture || !IsWindow(hCapture))
+ return nullptr;
+
+ hForegroundWin = GetForegroundWindow(); // old foreground window
+ SetForegroundWindow(hCapture); // force target foreground
+ BringWindowToTop(hCapture); // bring it to top as well
+
+ // redraw window to prevent runtime artifacts in picture
+ UpdateWindow(hCapture);
+
+ HWND hParent = GetAncestor(hCapture, GA_PARENT);
+ if (hParent && !IsChild(hParent, hCapture))
+ hParent = nullptr;
+ if (bIndirectCapture) {
+ intptr_t wastopmost = GetWindowLongPtr(hCapture, GWL_EXSTYLE)&WS_EX_TOPMOST;
+ if (!wastopmost)
+ SetWindowPos(hCapture, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ if (bClientArea) {
+ GetClientRect(hCapture, &rect);
+ ClientToScreen(hCapture, (POINT*)&rect);
+ rect.right += rect.left; rect.bottom += rect.top;
+ }
+ else
+ GetWindowRect(hCapture, &rect);
+ dib = CaptureMonitor(nullptr, &rect);
+ if (!wastopmost)
+ SetWindowPos(hCapture, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ }
+ else {
+ HDC hDCsrc;
+ GetWindowRect(hCapture, &rect);
+ if (hParent)
+ hDCsrc = GetDC(hCapture); // hCapture is part of a window, capture that
+ else
+ hDCsrc = GetWindowDC(hCapture); // entire window w/ title bar
+ rect.right = ABS(rect.right - rect.left);
+ rect.bottom = ABS(rect.bottom - rect.top);
+ rect.left = rect.top = 0;
+ // capture window and get FIBITMAP
+ dib = CreateDIBFromDC(hDCsrc, &rect, hCapture);
+ ReleaseDC(hCapture, hDCsrc);
+
+ // we could capture directly, but doing so breaks GetWindowRgn() and also includes artifacts...
+ if (bClientArea) {
+ GetWindowRect(hCapture, &rect);
+ RECT rectCA; GetClientRect(hCapture, &rectCA);
+ ClientToScreen(hCapture, (POINT*)&rectCA);
+ rectCA.left = ABS(rectCA.left - rect.left);
+ rectCA.top = ABS(rectCA.top - rect.top);
+ rectCA.right += rectCA.left; rectCA.bottom += rectCA.top;
+
+ // crop the window to ClientArea
+ FIBITMAP* dibClient = FreeImage_Copy(dib, rectCA.left, rectCA.top, rectCA.right, rectCA.bottom);
+ FreeImage_Unload(dib);
+ dib = dibClient;
+ }
+ }
+
+ // restore previous foreground window
+ if (hForegroundWin) {
+ SetForegroundWindow(hForegroundWin);
+ BringWindowToTop(hForegroundWin);
+ }
+ return dib;
+}
+
+FIBITMAP* CaptureMonitor(const wchar_t* szDevice, const RECT* cropRect/*=NULL*/)
+{
+ HDC hScrDC;
+ RECT rect;
+
+ // get screen resolution
+ if (!szDevice) {
+ hScrDC = CreateDC(L"DISPLAY", nullptr, nullptr, nullptr);
+ rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
+ rect.right = GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ rect.bottom = GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ }
+ else {
+ hScrDC = CreateDC(szDevice, nullptr, nullptr, nullptr);
+ rect.left = rect.top = 0;
+ rect.right = GetDeviceCaps(hScrDC, HORZRES);
+ rect.bottom = GetDeviceCaps(hScrDC, VERTRES);
+ }
+ if (cropRect) {
+ if (cropRect->left > rect.left) rect.left = cropRect->left;
+ if (cropRect->top > rect.top) rect.top = cropRect->top;
+ if (cropRect->right < rect.right) rect.right = cropRect->right;
+ if (cropRect->bottom < rect.bottom) rect.bottom = cropRect->bottom;
+ }
+
+ FIBITMAP *dib = CreateDIBFromDC(hScrDC, &rect);
+ ReleaseDC(nullptr, hScrDC);
+ return dib;
+}
+
+FIBITMAP* CreateDIBFromDC(HDC hDC, const RECT* rect, HWND hCapture/*=NULL*/)
+{
+ long width = rect->right - rect->left;
+ long height = rect->bottom - rect->top;
+
+ // create a DC for the screen and create
+ // a memory DC compatible to screen DC
+ HDC hScrDC = hDC;
+ if (!hScrDC)
+ hScrDC = GetDC(hCapture);
+ HDC hMemDC = CreateCompatibleDC(hScrDC);
+ // create a bitmap compatible with the screen DC
+ HBITMAP hBitmap = CreateCompatibleBitmap(hScrDC, width, height);
+ // select new bitmap into memory DC
+ SelectObject(hMemDC, hBitmap);
+
+ if (hCapture && hDC)
+ PrintWindow(hCapture, hMemDC, 0);
+ else // bitblt screen DC to memory DC
+ BitBlt(hMemDC, 0, 0, width, height, hScrDC, rect->left, rect->top, CAPTUREBLT | SRCCOPY);
+
+ FIBITMAP *dib = FreeImage_CreateDIBFromHBITMAP(hBitmap);
+
+ // alpha channel from window is always wrong and sometimes even for desktop (Win7, no aero)
+ // coz GDI do not draw all in alpha mode.
+ // we have to create our own new alpha channel.
+ bool bFixAlpha = true;
+ bool bInvert = false;
+ HBRUSH hBr = CreateSolidBrush(RGB(255, 255, 255)); // Create a SolidBrush object for non transparent area
+ HBITMAP hMask = CreateBitmap(width, height, 1, 1, nullptr); // Create monochrome (1 bit) B+W mask bitmap.
+ HDC hMaskDC = CreateCompatibleDC(nullptr);
+ SelectBitmap(hMaskDC, hMask);
+ HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
+ if (hCapture && GetWindowRgn(hCapture, hRgn) == ERROR) {
+ if ((GetWindowLongPtr(hCapture, GWL_EXSTYLE)&WS_EX_LAYERED)) {
+ uint8_t bAlpha = 0;
+ COLORREF crKey = 0x00000000;
+ DWORD dwFlags = 0;
+ if (GetLayeredWindowAttributes(hCapture, &crKey, &bAlpha, &dwFlags)) {
+ // per window transparency (like fading in a whole window)
+ if ((dwFlags&LWA_COLORKEY)) {
+ SetBkColor(hMemDC, crKey);
+ BitBlt(hMaskDC, 0, 0, width, height, hMemDC, rect->left, rect->top, SRCCOPY);
+ bInvert = true;
+ }
+ else if ((dwFlags&LWA_ALPHA)) {
+ bFixAlpha = false;
+ }
+ }
+ else { // per-pixel transparency (won't use the WM_PAINT)
+ bFixAlpha = false;
+ }
+ }
+ else { // not layered - fill the window region
+ SetRectRgn(hRgn, 0, 0, width, height);
+ FillRgn(hMaskDC, hRgn, hBr);
+ }
+ }
+ else {
+ if (!hCapture) SetRectRgn(hRgn, 0, 0, width, height); // client area only, no transparency
+ FillRgn(hMaskDC, hRgn, hBr);
+ }
+ DeleteObject(hRgn);
+ if (bFixAlpha) {
+ FIBITMAP* dibMask = FreeImage_CreateDIBFromHBITMAP(hMask);
+ if (bInvert) FreeImage_Invert(dibMask);
+ FIBITMAP* dib8 = FreeImage_ConvertTo8Bits(dibMask);
+ // copy the dib8 alpha mask to dib32 main bitmap
+ FreeImage_SetChannel(dib, dib8, FICC_ALPHA);
+ FreeImage_Unload(dibMask);
+ FreeImage_Unload(dib8);
+ }
+ DeleteDC(hMaskDC);
+ DeleteObject(hMask);
+ DeleteObject(hBr);
+
+ // clean up
+ DeleteDC(hMemDC);
+ DeleteObject(hBitmap);
+ if (!hDC)
+ ReleaseDC(nullptr, hScrDC);
+
+#ifdef _DEBUG
+ switch (FreeImage_GetImageType(dib)) {
+ case FIT_UNKNOWN:
+ OutputDebugStringA("FIBITMAP Type: FIT_UNKNOWN\r\n");
+ break;
+ case FIT_BITMAP:
+ OutputDebugStringA("FIBITMAP Type: FIT_BITMAP\r\n");
+ break;
+ case FIT_UINT16:
+ OutputDebugStringA("FIBITMAP Type: FIT_UINT16\r\n");
+ break;
+ case FIT_INT16:
+ OutputDebugStringA("FIBITMAP Type: FIT_INT16\r\n");
+ break;
+ case FIT_UINT32:
+ OutputDebugStringA("FIBITMAP Type: FIT_UINT32\r\n");
+ break;
+ case FIT_INT32:
+ OutputDebugStringA("FIBITMAP Type: FIT_INT32\r\n");
+ break;
+ case FIT_FLOAT:
+ OutputDebugStringA("FIBITMAP Type: FIT_FLOAT\r\n");
+ break;
+ case FIT_DOUBLE:
+ OutputDebugStringA("FIBITMAP Type: FIT_DOUBLE\r\n");
+ break;
+ case FIT_COMPLEX:
+ OutputDebugStringA("FIBITMAP Type: FIT_COMPLEX\r\n");
+ break;
+ case FIT_RGB16:
+ OutputDebugStringA("FIBITMAP Type: FIT_RGB16\r\n");
+ break;
+ case FIT_RGBA16:
+ OutputDebugStringA("FIBITMAP Type: FIT_RGBA16\r\n");
+ break;
+ case FIT_RGBF:
+ OutputDebugStringA("FIBITMAP Type: FIT_RGBF\r\n");
+ break;
+ case FIT_RGBAF:
+ OutputDebugStringA("FIBITMAP Type: FIT_RGBAF\r\n");
+ break;
+ default:
+ OutputDebugStringA("FIBITMAP Type: non detectable image type (error)\r\n");
+ break;
+ }
+ BOOL inf = FreeImage_IsTransparent(dib);
+ OutputDebugStringA(inf ? "FIBITMAP Transparent: true\r\n" : "FIBITMAP Transparent: false\r\n");
+#endif
+ return dib;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+char* GetFileNameA(const wchar_t* pszPath)
+{
+ const wchar_t* slash = wcsrchr(pszPath, '\\');
+ if (!slash) slash = wcsrchr(pszPath, '/');
+ if (slash)
+ return mir_u2a(slash + 1);
+ else
+ return mir_u2a(pszPath);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL GetEncoderClsid(wchar_t *wchMimeType, CLSID &clsidEncoder)
+{
+ UINT uiNum = 0;
+ UINT uiSize = 0;
+ BOOL bOk = FALSE;
+ Gdiplus::GetImageEncodersSize(&uiNum, &uiSize);
+ if (uiSize > 0) {
+ Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)mir_alloc(uiSize);
+ if (pImageCodecInfo) {
+ Gdiplus::GetImageEncoders(uiNum, uiSize, pImageCodecInfo);
+ for (UINT i = 0; i < uiNum; ++i) {
+ if (!mir_wstrcmp(pImageCodecInfo[i].MimeType, wchMimeType)) {
+ clsidEncoder = pImageCodecInfo[i].Clsid;
+ bOk = TRUE;
+ }
+ }
+ mir_free(pImageCodecInfo);
+ }
+ }
+ return bOk;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void SaveGIF(HBITMAP hBmp, const wchar_t *szFilename)
+{
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ ULONG_PTR gdiplusToken;
+ Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
+
+ Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE));
+ if (pBitmap) {
+ // Get the CLSID of the GIF encoder.
+ CLSID clsidEncoder;
+ if (GetEncoderClsid(L"image/gif", clsidEncoder)) {
+ LPWSTR pswFile = mir_wstrdup(szFilename);
+ pBitmap->Save((const wchar_t*)pswFile, &clsidEncoder, nullptr);
+ mir_free(pswFile);
+ }
+ delete pBitmap;
+ }
+ Gdiplus::GdiplusShutdown(gdiplusToken);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void SaveTIF(HBITMAP hBmp, const wchar_t *szFilename)
+{
+ // http://www.codeproject.com/Messages/1406708/How-to-reduce-the-size-of-an-Image-using-GDIplus.aspx
+ ULONG_PTR gdiplusToken;
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ Gdiplus::Status stat;
+ Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
+
+ Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE));
+ if (pBitmap) {
+ // Get the CLSID of the GIF encoder.
+ CLSID EncCLSID;
+ if (GetEncoderClsid(L"image/tiff", EncCLSID)) {
+ //--- Create a 2-parameter array, for Compression and for Color Bit depth
+ Gdiplus::EncoderParameters* EncParams = (Gdiplus::EncoderParameters*) malloc(sizeof(Gdiplus::EncoderParameters) + 1 * sizeof(Gdiplus::EncoderParameter));
+ // Gdiplus::EncoderParameters pEncoderParameters;
+ //--- Use LZW Compression instead of Group 4, since it works for color and G4 doesn't
+ ULONG ulCompression = Gdiplus::EncoderValueCompressionLZW;
+ ULONG ulColorDepth = 24L;
+
+ EncParams->Count = 2;
+ EncParams->Parameter[0].Guid = Gdiplus::EncoderCompression;
+ EncParams->Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
+ EncParams->Parameter[0].NumberOfValues = 1;
+ EncParams->Parameter[0].Value = &ulCompression;
+ EncParams->Parameter[1].Guid = Gdiplus::EncoderColorDepth;
+ EncParams->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;
+ EncParams->Parameter[1].NumberOfValues = 1;
+ EncParams->Parameter[1].Value = &ulColorDepth;
+
+ LPWSTR pswFile = mir_wstrdup(szFilename);
+ stat = pBitmap->Save((const wchar_t*)pswFile, &EncCLSID, EncParams);
+ mir_free(pswFile);
+ free(EncParams);
+ }
+ delete pBitmap;
+ }
+ Gdiplus::GdiplusShutdown(gdiplusToken);
+}
diff --git a/plugins/SendScreenshotPlus/src/Utils.h b/plugins/SendScreenshotPlus/src/Utils.h
index 89dd2f614e..df736da08f 100644
--- a/plugins/SendScreenshotPlus/src/Utils.h
+++ b/plugins/SendScreenshotPlus/src/Utils.h
@@ -1,73 +1,73 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-
-#ifndef UTILSH
-#define UTILSH
-
-#define SPP_USERPANE 1
-
-#define ABS(x) ((x)<0?-(x):(x))
-
-struct MONITORS
-{
- size_t count;
- MONITORINFOEX* info;
-};
-
-extern HWND g_hCapture;
-extern HBITMAP g_hBitmap, g_hbmMask;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-size_t MonitorInfoEnum(MONITORINFOEX* &myMonitors, RECT &virtualScreen);
-
-FIBITMAP* CaptureWindow(HWND hCapture, BOOL bClientArea, BOOL bIndirectCapture);
-FIBITMAP* CaptureMonitor(const wchar_t *pwszDevice, const RECT *cropRect = nullptr);
-
-char* GetFileNameA(const wchar_t *pwszPath);
-
-BOOL GetEncoderClsid(wchar_t *wchMimeType, CLSID &clsidEncoder);
-
-void SaveGIF(HBITMAP hBmp, const wchar_t *pwszFilename);
-void SaveTIF(HBITMAP hBmp, const wchar_t *pwszFilename);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class EventHandle
-{
- HANDLE _hEvent;
-public:
- inline EventHandle() { _hEvent = CreateEvent(nullptr, 0, 0, nullptr); }
- inline ~EventHandle() { CloseHandle(_hEvent); }
- inline void Set() { SetEvent(_hEvent); }
- inline void Wait() { WaitForSingleObject(_hEvent, INFINITE); }
- inline void Wait(uint32_t dwMilliseconds) { WaitForSingleObject(_hEvent, dwMilliseconds); }
- inline operator HANDLE() { return _hEvent; }
-};
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+
+#ifndef UTILSH
+#define UTILSH
+
+#define SPP_USERPANE 1
+
+#define ABS(x) ((x)<0?-(x):(x))
+
+struct MONITORS
+{
+ size_t count;
+ MONITORINFOEX* info;
+};
+
+extern HWND g_hCapture;
+extern HBITMAP g_hBitmap, g_hbmMask;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+size_t MonitorInfoEnum(MONITORINFOEX* &myMonitors, RECT &virtualScreen);
+
+FIBITMAP* CaptureWindow(HWND hCapture, BOOL bClientArea, BOOL bIndirectCapture);
+FIBITMAP* CaptureMonitor(const wchar_t *pwszDevice, const RECT *cropRect = nullptr);
+
+char* GetFileNameA(const wchar_t *pwszPath);
+
+BOOL GetEncoderClsid(wchar_t *wchMimeType, CLSID &clsidEncoder);
+
+void SaveGIF(HBITMAP hBmp, const wchar_t *pwszFilename);
+void SaveTIF(HBITMAP hBmp, const wchar_t *pwszFilename);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+class EventHandle
+{
+ HANDLE _hEvent;
+public:
+ inline EventHandle() { _hEvent = CreateEvent(nullptr, 0, 0, nullptr); }
+ inline ~EventHandle() { CloseHandle(_hEvent); }
+ inline void Set() { SetEvent(_hEvent); }
+ inline void Wait() { WaitForSingleObject(_hEvent, INFINITE); }
+ inline void Wait(uint32_t dwMilliseconds) { WaitForSingleObject(_hEvent, dwMilliseconds); }
+ inline operator HANDLE() { return _hEvent; }
+};
+
+#endif
diff --git a/plugins/SendScreenshotPlus/src/ctrl_button.h b/plugins/SendScreenshotPlus/src/ctrl_button.h
index 42ac4762a7..d2672c79d7 100644
--- a/plugins/SendScreenshotPlus/src/ctrl_button.h
+++ b/plugins/SendScreenshotPlus/src/ctrl_button.h
@@ -1,34 +1,34 @@
-/*
-imported from UserinfoEx plugin for Miranda NG
-Copyright:
-© 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/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.
-*/
-
-#ifndef _UINFOEX_BOTTONS_H_INCLUDED_
-#define _UINFOEX_BOTTONS_H_INCLUDED_ 1
-
-void CtrlButtonLoadModule();
-void CtrlButtonUnloadModule();
-
+/*
+imported from UserinfoEx plugin for Miranda NG
+Copyright:
+© 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/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.
+*/
+
+#ifndef _UINFOEX_BOTTONS_H_INCLUDED_
+#define _UINFOEX_BOTTONS_H_INCLUDED_ 1
+
+void CtrlButtonLoadModule();
+void CtrlButtonUnloadModule();
+
#endif /* _UINFOEX_BOTTONS_H_INCLUDED_ */ \ No newline at end of file
diff --git a/plugins/SendScreenshotPlus/src/dlg_msgbox.cpp b/plugins/SendScreenshotPlus/src/dlg_msgbox.cpp
index e64e686215..b0aa0bc04d 100644
--- a/plugins/SendScreenshotPlus/src/dlg_msgbox.cpp
+++ b/plugins/SendScreenshotPlus/src/dlg_msgbox.cpp
@@ -1,714 +1,714 @@
-/*
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright:
-© 2012-22 Miranda NG team (https://miranda-ng.org)
-© 2006-10 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
-
-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.
-*/
-
-// SendSS compatibility:
-#include "stdafx.h"
-#define ghInst g_plugin.getInst()
-#define myGlobals g_myGlobals
-#define MODNAME MODULENAME
-#define ICO_COMMON_MAIN 0xFFFF
-#define ICO_DLG_DETAILS 0xFFFF
-
-HICON Skin_GetIcon_SendSS(unsigned short id)
-{
- if(id==0xFFFF)
- return GetIcon(ICO_MAIN);
- return GetIconBtn(id);
-}
-#define IcoLib_GetIcon Skin_GetIcon_SendSS
-// original UserInfoEx codebase (almost):
-
-typedef struct _MSGPOPUPDATA
-{
- POPUPACTION pa[3];
- HWND hDialog;
-} MSGPOPUPDATA, *LPMSGPOPUPDATA;
-
-/**
- * This helper function moves and resizes a dialog box's control element.
- *
- * @param hDlg - the dialog box's window handle
- * @param idCtrl - the identication number of the control to move
- * @param dx -´number of pixels to horizontal move the control
- * @param dy - number of pixels to vertical move the control
- * @param dw - number of pixels to horizontal resize the control
- * @param dh - number of pixels to vertical resize the control
- *
- * @return nothing
- **/
-static FORCEINLINE void MoveCtrl(HWND hDlg, int idCtrl, int dx, int dy, int dw, int dh)
-{
- RECT ws;
- HWND hCtrl = GetDlgItem(hDlg, idCtrl);
- GetWindowRect(hCtrl, &ws);
- OffsetRect(&ws, dx, dy);
- MoveWindow(hCtrl, ws.left, ws.top, ws.right - ws.left + dw, ws.bottom - ws.top + dh, FALSE);
-}
-
-/**
-* This function loads the icon to display for the current message.
-*
-* @param pMsgBox - pointer to a MSGBOX structure, with information about the message to display.
-*
-* @retval HICON - The function returns an icon to display with the message.
-* @retval NULL - There is no icon for the message.
-**/
-static HICON MsgLoadIcon(LPMSGBOX pMsgBox)
-{
- HICON hIcon;
-
- // load the desired status icon
- switch (pMsgBox->uType & MB_ICONMASK) {
- case MB_ICON_OTHER: // custom icon defined by caller function
- hIcon = pMsgBox->hiMsg;
- break;
-
- // default windows icons
- case MB_ICON_ERROR:
- case MB_ICON_QUESTION:
- case MB_ICON_WARNING:
- case MB_ICON_INFO:
- {
- LPCTSTR ico[] = { nullptr, IDI_ERROR, IDI_QUESTION, IDI_WARNING, IDI_INFORMATION };
- hIcon = LoadIcon(nullptr, ico[MB_ICON_INDEX(pMsgBox->uType)]);
- }
- break;
-
- // no icon
- default:
- hIcon = nullptr;
- }
- return hIcon;
-}
-
-/**
- * This function fills a given POPUPACTION structure with the data of a given message id,
- * which is normally used by the message box. This is required to let the user interact
- * with a popup in the same way as with a normal message dialog box.
- *
- * @param pa - reference to a POPUPACTION structure to fill
- * @param id - the message id
- * @param result - This parameter is passed to the POPUPACTION structure as is.
- *
- * @return nothing
- **/
-static void MakePopupAction(POPUPACTION &pa, int id)
-{
- pa.cbSize = sizeof(POPUPACTION);
- pa.flags = PAF_ENABLED;
- pa.wParam = MAKEWORD(id, BN_CLICKED);
- pa.lParam = 0;
-
- switch (id) {
- case IDOK:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
- mir_strcpy(pa.lpzTitle, MODNAME"/Ok");
- break;
-
- case IDCLOSE:
- case IDCANCEL:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
- mir_strcpy(pa.lpzTitle, MODNAME"/Cancel");
- break;
-
- case IDABORT:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
- mir_strcpy(pa.lpzTitle, MODNAME"/Abort");
- break;
-
- case IDRETRY:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_UPDATE);
- mir_strcpy(pa.lpzTitle, MODNAME"/Retry");
- break;
-
- case IDIGNORE:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
- mir_strcpy(pa.lpzTitle, MODNAME"/Ignore");
- break;
-
- case IDYES:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
- mir_strcpy(pa.lpzTitle, MODNAME"/Yes");
- break;
-
- case IDNO:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
- mir_strcpy(pa.lpzTitle, MODNAME"/No");
- break;
-
- case IDHELP:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
- mir_strcpy(pa.lpzTitle, MODNAME"/Help");
- break;
-
- case IDALL:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
- mir_strcpy(pa.lpzTitle, MODNAME"/All");
- break;
-
- case IDNONE:
- pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
- mir_strcpy(pa.lpzTitle, MODNAME"/None");
- }
-}
-
-/**
- * This is the message procedure for my nice looking message box
- *
- * @param hDlg - window handle
- * @param uMsg - message to handle
- * @param wParam - message specific parameter
- * @param lParam - message specific parameter
- *
- * @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL
- **/
-static INT_PTR CALLBACK MsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static int retOk = IDOK;
- static int retAll = IDALL;
- static int retNon = IDNONE;
- static int retCancel = IDCANCEL;
-
- switch (uMsg) {
- case WM_INITDIALOG:
- {
- LPMSGBOX pMsgBox = (LPMSGBOX)lParam;
- if (PtrIsValid(pMsgBox)) {
- int icoWidth = 0;
- int InfoBarHeight = 0;
- HFONT hNormalFont;
-
- hNormalFont = (HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0);
- if (pMsgBox->uType & MB_INFOBAR) {
- LOGFONT lf;
-
- // set bold font for name in description area
- GetObject(hNormalFont, sizeof(lf), &lf);
- lf.lfWeight = FW_BOLD;
- hNormalFont = CreateFontIndirect(&lf);
-
- // set infobar's textfont
- SendDlgItemMessage(hDlg, TXT_NAME, WM_SETFONT, (WPARAM)hNormalFont, 0);
-
- // set infobar's logo icon
- SendDlgItemMessage(hDlg, ICO_DLGLOGO, STM_SETIMAGE, IMAGE_ICON,
- (pMsgBox->hiLogo ? (LPARAM)pMsgBox->hiLogo : (LPARAM)IcoLib_GetIcon(ICO_DLG_DETAILS)));
-
- // enable headerbar
- ShowWindow(GetDlgItem(hDlg, TXT_NAME), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, ICO_DLGLOGO), SW_SHOW);
- }
- else {
- RECT rc;
- GetClientRect(GetDlgItem(hDlg, TXT_NAME), &rc);
- InfoBarHeight = rc.bottom;
-
- if (pMsgBox->hiLogo)
- SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)pMsgBox->hiLogo);
- }
-
- // draw the desired status icon
- HICON hIcon = MsgLoadIcon(pMsgBox);
- if (hIcon)
- SendDlgItemMessage(hDlg, ICO_MSGDLG, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- else {
- RECT ws;
- GetWindowRect(GetDlgItem(hDlg, ICO_MSGDLG), &ws);
- icoWidth = ws.right - ws.left;
- ShowWindow(GetDlgItem(hDlg, ICO_MSGDLG), SW_HIDE);
- }
-
- // resize the messagebox and reorganize the buttons
- if (HDC hDC = GetDC(hDlg)) {
- POINT mpt = { 0, 0 };
- RECT ws = { 0, 0, 0, 0 };
- int txtWidth = 0, txtHeight = 0, needX, needY;
- RECT rcDlg;
- SIZE ts;
- LPTSTR h, rs;
-
- SelectObject(hDC, hNormalFont);
- // get message text width and height
- if (pMsgBox->ptszMsg) for (rs = h = pMsgBox->ptszMsg;; ++h) {
- if (*h == '\n' || !*h) {
- GetTextExtentPoint32(hDC, rs, h - rs, &ts);
- if (ts.cx > txtWidth)
- txtWidth = ts.cx;
- txtHeight += ts.cy;
- if (!*h)
- break;
- rs = h + 1;
- }
- }
- // increase width if info text requires more
- if ((pMsgBox->uType&MB_INFOBAR) && pMsgBox->ptszInfoText && *pMsgBox->ptszInfoText) {
- int multiline = 0;
- RECT rcico; GetClientRect(GetDlgItem(hDlg, ICO_DLGLOGO), &rcico);
- rcico.right = rcico.right * 100 / 66; // padding
- for (rs = h = pMsgBox->ptszInfoText;; ++h) {
- if (*h == '\n' || !*h) {
- GetTextExtentPoint32(hDC, rs, h - rs, &ts);
- ts.cx += rcico.right;
- if (ts.cx > txtWidth)
- txtWidth = ts.cx;
- if (!*h)
- break;
- rs = h + 1;
- ++multiline;
- }
- }
- if (!multiline)
- SetWindowLongPtr(GetDlgItem(hDlg, TXT_NAME), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hDlg, TXT_NAME), GWL_STYLE) | SS_CENTERIMAGE);
- }
- ReleaseDC(hDlg, hDC);
-
- // calc new dialog size
- GetWindowRect(hDlg, &rcDlg);
- GetWindowRect(GetDlgItem(hDlg, TXT_MESSAGE), &ws);
- needX = txtWidth - (ws.right - ws.left) - icoWidth;
- needY = max(0, txtHeight - (ws.bottom - ws.top) + 5);
- rcDlg.left -= needX / 2; rcDlg.right += needX / 2;
- rcDlg.top -= (needY - InfoBarHeight) / 2; rcDlg.bottom += (needY - InfoBarHeight) / 2;
-
- // resize dialog window
- MoveWindow(hDlg, rcDlg.left, rcDlg.top, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, FALSE);
- ClientToScreen(hDlg, &mpt);
-
- MoveCtrl(hDlg, STATIC_WHITERECT, -mpt.x, -mpt.y, needX, needY - InfoBarHeight);
- MoveCtrl(hDlg, TXT_NAME, -mpt.x, -mpt.y, needX, 0);
- MoveCtrl(hDlg, ICO_DLGLOGO, -mpt.x + needX, -mpt.y, 0, 0);
- MoveCtrl(hDlg, ICO_MSGDLG, -mpt.x, -mpt.y - InfoBarHeight, 0, 0);
- MoveCtrl(hDlg, TXT_MESSAGE, -mpt.x - icoWidth, -mpt.y - InfoBarHeight, needX, needY);
- MoveCtrl(hDlg, STATIC_LINE2, -mpt.x, -mpt.y + needY - InfoBarHeight, needX, 0);
-
- // Do pushbutton positioning
- RECT rcOk, rcAll, rcNone, rcCancel;
-
- // get button rectangles
- GetWindowRect(GetDlgItem(hDlg, IDOK), &rcOk);
- OffsetRect(&rcOk, -mpt.x, -mpt.y + needY - InfoBarHeight);
-
- GetWindowRect(GetDlgItem(hDlg, IDALL), &rcAll);
- OffsetRect(&rcAll, -mpt.x, -mpt.y + needY - InfoBarHeight);
-
- GetWindowRect(GetDlgItem(hDlg, IDNONE), &rcNone);
- OffsetRect(&rcNone, -mpt.x, -mpt.y + needY - InfoBarHeight);
-
- GetWindowRect(GetDlgItem(hDlg, IDCANCEL), &rcCancel);
- OffsetRect(&rcCancel, -mpt.x, -mpt.y + needY - InfoBarHeight);
-
- LONG okWidth = rcOk.right - rcOk.left;
- LONG allWidth = rcAll.right - rcAll.left;
- LONG noneWidth = rcNone.right - rcNone.left;
- LONG caWidth = rcCancel.right - rcCancel.left;
- LONG dlgMid = (rcDlg.right - rcDlg.left) / 2;
-
- // load button configuration
- switch (MB_TYPE(pMsgBox->uType)) {
- case MB_OK:
- rcOk.left = dlgMid - (okWidth / 2);
- rcOk.right = rcOk.left + okWidth;
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- break;
-
- case MB_OKCANCEL:
- retOk = IDRETRY;
- SetDlgItemText(hDlg, IDOK, LPGENW("OK"));
- retCancel = IDCANCEL;
- SetDlgItemText(hDlg, IDCANCEL, LPGENW("Cancel"));
- rcOk.left = dlgMid - okWidth - 10;
- rcOk.right = rcOk.left + okWidth;
- rcCancel.left = dlgMid + 10;
- rcCancel.right = rcCancel.left + caWidth;
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
- break;
-
- case MB_RETRYCANCEL:
- retOk = IDRETRY;
- SetDlgItemText(hDlg, IDOK, LPGENW("Retry"));
- retCancel = IDCANCEL;
- SetDlgItemText(hDlg, IDCANCEL, LPGENW("Cancel"));
- rcOk.left = dlgMid - okWidth - 10;
- rcOk.right = rcOk.left + okWidth;
- rcCancel.left = dlgMid + 10;
- rcCancel.right = rcCancel.left + caWidth;
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
- break;
-
- case MB_YESNO:
- retOk = IDYES;
- SetDlgItemText(hDlg, IDOK, LPGENW("Yes"));
- retCancel = IDNO;
- SetDlgItemText(hDlg, IDCANCEL, LPGENW("No"));
- rcOk.left = dlgMid - okWidth - 10;
- rcOk.right = rcOk.left + okWidth;
- rcCancel.left = dlgMid + 10;
- rcCancel.right = rcCancel.left + caWidth;
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
- break;
-
- case MB_ABORTRETRYIGNORE:
- retOk = IDABORT;
- SetDlgItemText(hDlg, IDOK, LPGENW("Abort"));
- retAll = IDABORT;
- SetDlgItemText(hDlg, IDALL, LPGENW("Retry"));
- retCancel = IDCANCEL;
- SetDlgItemText(hDlg, IDCANCEL, LPGENW("Ignore"));
- rcAll.left = dlgMid - (allWidth / 2);
- rcAll.right = rcAll.left + allWidth;
- rcOk.left = rcAll.left - okWidth - 5;
- rcOk.right = rcOk.left + okWidth;
- rcCancel.left = rcAll.right + 5;
- rcCancel.right = rcCancel.left + caWidth;
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
- break;
-
- case MB_YESNOCANCEL:
- retOk = IDYES;
- SetDlgItemText(hDlg, IDOK, LPGENW("Yes"));
- retAll = IDNO;
- SetDlgItemText(hDlg, IDALL, LPGENW("No"));
- retCancel = IDCANCEL;
- SetDlgItemText(hDlg, IDCANCEL, LPGENW("Cancel"));
- rcAll.left = dlgMid - (allWidth / 2);
- rcAll.right = rcAll.left + allWidth;
- rcOk.left = rcAll.left - okWidth - 5;
- rcOk.right = rcOk.left + okWidth;
- rcCancel.left = rcAll.right + 5;
- rcCancel.right = rcCancel.left + caWidth;
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
- break;
-
- case MB_YESALLNO:
- retOk = IDYES;
- SetDlgItemText(hDlg, IDOK, LPGENW("Yes"));
- retAll = IDALL;
- SetDlgItemText(hDlg, IDALL, LPGENW("All"));
- SetDlgItemText(hDlg, IDNONE, LPGENW("None"));
- retCancel = IDNO;
- SetDlgItemText(hDlg, IDCANCEL, LPGENW("No"));
- rcCancel.right = rcDlg.right - rcDlg.left - 10;
- rcCancel.left = rcCancel.right - caWidth;
- rcNone.right = rcCancel.left - 5;
- rcNone.left = rcNone.right - noneWidth;
- rcAll.right = rcNone.left - 5;
- rcAll.left = rcAll.right - allWidth;
- rcOk.right = rcAll.left - 5;
- rcOk.left = rcOk.right - okWidth;
- // show buttons
- ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDNONE), SW_SHOW);
- ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
- break;
-
- default:
- rcOk.left = dlgMid - (okWidth / 2);
- rcOk.right = rcOk.left + okWidth;
- }
-
- MoveWindow(GetDlgItem(hDlg, IDOK), rcOk.left, rcOk.top, rcOk.right - rcOk.left, rcOk.bottom - rcOk.top, FALSE);
- MoveWindow(GetDlgItem(hDlg, IDALL), rcAll.left, rcAll.top, rcAll.right - rcAll.left, rcAll.bottom - rcAll.top, FALSE);
- MoveWindow(GetDlgItem(hDlg, IDNONE), rcNone.left, rcNone.top, rcNone.right - rcNone.left, rcNone.bottom - rcNone.top, FALSE);
- MoveWindow(GetDlgItem(hDlg, IDCANCEL), rcCancel.left, rcCancel.top, rcCancel.right - rcCancel.left, rcCancel.bottom - rcCancel.top, FALSE);
- }
-
- // set text's
- SetWindowText(hDlg, pMsgBox->ptszTitle);
- SetDlgItemText(hDlg, TXT_NAME, pMsgBox->ptszInfoText);
- SetDlgItemText(hDlg, TXT_MESSAGE, pMsgBox->ptszMsg);
-
- TranslateDialogDefault(hDlg);
- return TRUE;
- }
- }
- break;
-
- case WM_CTLCOLORSTATIC:
- switch (GetWindowLongPtr((HWND)lParam, GWLP_ID)) {
- case STATIC_WHITERECT:
- case ICO_DLGLOGO:
- case ICO_MSGDLG:
- case TXT_MESSAGE:
- case TXT_NAME:
- SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
- return GetSysColor(COLOR_WINDOW);
- }
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- EndDialog(hDlg, retOk);
- break;
- case IDCANCEL:
- EndDialog(hDlg, retCancel);
- break;
- case IDALL:
- EndDialog(hDlg, retAll);
- break;
- case IDNONE:
- EndDialog(hDlg, retNon);
- }
- break;
-
- case WM_DESTROY:
- DeleteObject((HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0));
- break;
- }
- return FALSE;
-}
-
-/**
-* Dummi modal MsgBox for popup,
-* this set call function in wait stait and do not freece miranda main thread
-* the window is outside the desktop
-*/
-static INT_PTR CALLBACK MsgBoxPop(HWND hDlg, UINT uMsg, WPARAM, LPARAM lParam)
-{
- switch (uMsg) {
- case WM_INITDIALOG:
- LPMSGBOX pMsgBox = (LPMSGBOX)lParam;
-
- MoveWindow(hDlg, -10, -10, 0, 0, FALSE);
- LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)mir_alloc(sizeof(MSGPOPUPDATA));
- if (pmpd) {
- POPUPDATAW ppd;
- ppd.lchContact = NULL; // (HANDLE)wParam;
- // icon
- ppd.lchIcon = MsgLoadIcon(pMsgBox);
- mir_wstrncpy(ppd.lpwzContactName, pMsgBox->ptszTitle, _countof(ppd.lpwzContactName));
- mir_wstrncpy(ppd.lpwzText, pMsgBox->ptszMsg, _countof(ppd.lpwzText));
-
- // CALLBAC Proc
- ppd.PluginWindowProc = PopupProc;
- ppd.PluginData = pmpd;
- ppd.iSeconds = -1;
- ppd.lpActions = pmpd->pa;
-
- // set color of popup
- switch (pMsgBox->uType & MB_ICONMASK) {
- case MB_ICON_ERROR:
- ppd.colorBack = RGB(200, 10, 0);
- ppd.colorText = RGB(255, 255, 255);
- break;
-
- case MB_ICON_WARNING:
- ppd.colorBack = RGB(200, 100, 0);
- ppd.colorText = RGB(255, 255, 255);
- break;
-
- default:
- if (pMsgBox->uType & MB_CUSTOMCOLOR) {
- ppd.colorBack = pMsgBox->colorBack;
- ppd.colorText = pMsgBox->colorText;
- }
- }
-
- // handle for MakePopupAction
- pmpd->hDialog = hDlg;
-
- // active buttons
- switch (MB_TYPE(pMsgBox->uType)) {
- case MB_OK:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDOK);
- break;
-
- case MB_OKCANCEL:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDOK);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDCANCEL);
- break;
-
- case MB_RETRYCANCEL:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDRETRY);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDCANCEL);
- break;
-
- case MB_YESNO:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDYES);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDNO);
- break;
-
- case MB_ABORTRETRYIGNORE:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDABORT);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDRETRY);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDIGNORE);
- break;
-
- case MB_YESNOCANCEL:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDYES);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDNO);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDCANCEL);
- break;
-
- case MB_YESALLNO:
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDYES);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDALL);
- MakePopupAction(pmpd->pa[ppd.actionCount++], IDNO);
- break;
- }
-
- // create popup
- PUAddPopupW(&ppd);
- if (MB_TYPE(pMsgBox->uType) == MB_OK)
- EndDialog(hDlg, IDOK);
- }
- break;
- }
- return FALSE;
-}
-
-/**
-* This is the message procedure for popup
-*
-* @param hDlg - window handle
-* @param uMsg - message to handle
-* @param wParam - message specific parameter
-* @param lParam - message specific parameter
-*
-* @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL
-**/
-
-LRESULT CALLBACK PopupProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg) {
- case UM_POPUPACTION:
- if (HIWORD(wParam) == BN_CLICKED) {
- LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
- if (pmpd) {
- switch (LOWORD(wParam)) {
- case IDOK:
- case IDCANCEL:
- case IDABORT:
- case IDRETRY:
- case IDIGNORE:
- case IDYES:
- case IDNO:
- case IDALL:
- case IDNONE:
- if (IsWindow(pmpd->hDialog))
- EndDialog(pmpd->hDialog, LOWORD(wParam));
- break;
-
- default:
- if (IsWindow(pmpd->hDialog))
- EndDialog(pmpd->hDialog, IDCANCEL);
- }
- }
- PUDeletePopup(hDlg);
- }
- break;
-
- case UM_FREEPLUGINDATA:
- LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
- if (pmpd > 0)
- MIR_FREE(pmpd);
- return TRUE;
- }
- return DefWindowProc(hDlg, uMsg, wParam, lParam);
-}
-
-/**
-* This is the service function for external plugins to use the nice messagebox
-*
-* @param wParam - MCONTACT hContact which can display an avatar for popups
-* @param lParam - MSGBOX structure holding parameters
-*
-* @return The function returns the ID of the clicked button (IDOK, IDCANCEL, ...)
-* or -1 on error.
-**/
-INT_PTR MsgBoxService(WPARAM, LPARAM lParam)
-{
- LPMSGBOX pMsgBox = (LPMSGBOX)lParam;
-
- // check input
- if (PtrIsValid(pMsgBox) && pMsgBox->cbSize == sizeof(MSGBOX)) {
- // Shall the MessageBox displayed as popup?
- if (!(pMsgBox->uType & (MB_INFOBAR | MB_NOPOPUP)) // message box can be a popup?
- && myGlobals.PopupActionsExist == 1 // popup support ext stuct?
- && (db_get_dw(0, "Popup", "Actions", 0) & 1) // popup++ actions on?
- && db_get_b(0, MODNAME, SET_POPUPMSGBOX, DEFVAL_POPUPMSGBOX)) // user likes popups?
- return DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_MSGBOXDUMMI), pMsgBox->hParent, MsgBoxPop, lParam);
-
- return DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_MSGBOX), pMsgBox->hParent, MsgBoxProc, lParam);
- }
- return -1;
-}
-
-/**
-* name: MsgBox
-* desc: calls a messagebox
-* param:
-**/
-INT_PTR CALLBACK MsgBox(HWND hParent, UINT uType, LPCTSTR pszTitle, LPCTSTR pszInfo, LPCTSTR pszFormat, ...)
-{
- wchar_t tszMsg[MAX_SECONDLINE];
-
- va_list vl;
- va_start(vl, pszFormat);
- mir_vsnwprintf(tszMsg, _countof(tszMsg), TranslateW(pszFormat), vl);
- va_end(vl);
-
- MSGBOX mb = { 0 };
- mb.cbSize = sizeof(MSGBOX);
- mb.hParent = hParent;
- mb.hiLogo = IcoLib_GetIcon(ICO_COMMON_MAIN);
- mb.hiMsg = nullptr;
- mb.ptszTitle = TranslateW(pszTitle);
- mb.ptszInfoText = TranslateW(pszInfo);
- mb.ptszMsg = tszMsg;
- mb.uType = uType;
- return MsgBoxService(NULL, (LPARAM)&mb);
-}
-
-/**
-* name: MsgErr
-* desc: calls a messagebox
-* param:
-**/
-INT_PTR CALLBACK MsgErr(HWND hParent, LPCTSTR pszFormat, ...)
-{
- wchar_t tszTitle[MAX_SECONDLINE], tszMsg[MAX_SECONDLINE];
- mir_snwprintf(tszTitle, L"%s - %s", _A2W(MODNAME), TranslateT("Error"));
-
- va_list vl;
- va_start(vl, pszFormat);
- mir_vsnwprintf(tszMsg, TranslateW(pszFormat), vl);
- va_end(vl);
-
- MSGBOX mb = { 0 };
- mb.cbSize = sizeof(MSGBOX);
- mb.hParent = hParent;
- mb.hiLogo = IcoLib_GetIcon(ICO_COMMON_MAIN);
- mb.hiMsg = nullptr;
- mb.ptszTitle = tszTitle;
- mb.ptszMsg = tszMsg;
- mb.uType = MB_OK | MB_ICON_ERROR;
- return MsgBoxService(NULL, (LPARAM)&mb);
-}
+/*
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright:
+© 2012-23 Miranda NG team (https://miranda-ng.org)
+© 2006-10 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
+
+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.
+*/
+
+// SendSS compatibility:
+#include "stdafx.h"
+#define ghInst g_plugin.getInst()
+#define myGlobals g_myGlobals
+#define MODNAME MODULENAME
+#define ICO_COMMON_MAIN 0xFFFF
+#define ICO_DLG_DETAILS 0xFFFF
+
+HICON Skin_GetIcon_SendSS(unsigned short id)
+{
+ if(id==0xFFFF)
+ return GetIcon(ICO_MAIN);
+ return GetIconBtn(id);
+}
+#define IcoLib_GetIcon Skin_GetIcon_SendSS
+// original UserInfoEx codebase (almost):
+
+typedef struct _MSGPOPUPDATA
+{
+ POPUPACTION pa[3];
+ HWND hDialog;
+} MSGPOPUPDATA, *LPMSGPOPUPDATA;
+
+/**
+ * This helper function moves and resizes a dialog box's control element.
+ *
+ * @param hDlg - the dialog box's window handle
+ * @param idCtrl - the identication number of the control to move
+ * @param dx -´number of pixels to horizontal move the control
+ * @param dy - number of pixels to vertical move the control
+ * @param dw - number of pixels to horizontal resize the control
+ * @param dh - number of pixels to vertical resize the control
+ *
+ * @return nothing
+ **/
+static FORCEINLINE void MoveCtrl(HWND hDlg, int idCtrl, int dx, int dy, int dw, int dh)
+{
+ RECT ws;
+ HWND hCtrl = GetDlgItem(hDlg, idCtrl);
+ GetWindowRect(hCtrl, &ws);
+ OffsetRect(&ws, dx, dy);
+ MoveWindow(hCtrl, ws.left, ws.top, ws.right - ws.left + dw, ws.bottom - ws.top + dh, FALSE);
+}
+
+/**
+* This function loads the icon to display for the current message.
+*
+* @param pMsgBox - pointer to a MSGBOX structure, with information about the message to display.
+*
+* @retval HICON - The function returns an icon to display with the message.
+* @retval NULL - There is no icon for the message.
+**/
+static HICON MsgLoadIcon(LPMSGBOX pMsgBox)
+{
+ HICON hIcon;
+
+ // load the desired status icon
+ switch (pMsgBox->uType & MB_ICONMASK) {
+ case MB_ICON_OTHER: // custom icon defined by caller function
+ hIcon = pMsgBox->hiMsg;
+ break;
+
+ // default windows icons
+ case MB_ICON_ERROR:
+ case MB_ICON_QUESTION:
+ case MB_ICON_WARNING:
+ case MB_ICON_INFO:
+ {
+ LPCTSTR ico[] = { nullptr, IDI_ERROR, IDI_QUESTION, IDI_WARNING, IDI_INFORMATION };
+ hIcon = LoadIcon(nullptr, ico[MB_ICON_INDEX(pMsgBox->uType)]);
+ }
+ break;
+
+ // no icon
+ default:
+ hIcon = nullptr;
+ }
+ return hIcon;
+}
+
+/**
+ * This function fills a given POPUPACTION structure with the data of a given message id,
+ * which is normally used by the message box. This is required to let the user interact
+ * with a popup in the same way as with a normal message dialog box.
+ *
+ * @param pa - reference to a POPUPACTION structure to fill
+ * @param id - the message id
+ * @param result - This parameter is passed to the POPUPACTION structure as is.
+ *
+ * @return nothing
+ **/
+static void MakePopupAction(POPUPACTION &pa, int id)
+{
+ pa.cbSize = sizeof(POPUPACTION);
+ pa.flags = PAF_ENABLED;
+ pa.wParam = MAKEWORD(id, BN_CLICKED);
+ pa.lParam = 0;
+
+ switch (id) {
+ case IDOK:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Ok");
+ break;
+
+ case IDCLOSE:
+ case IDCANCEL:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Cancel");
+ break;
+
+ case IDABORT:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Abort");
+ break;
+
+ case IDRETRY:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_UPDATE);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Retry");
+ break;
+
+ case IDIGNORE:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Ignore");
+ break;
+
+ case IDYES:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Yes");
+ break;
+
+ case IDNO:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
+ mir_strcpy(pa.lpzTitle, MODNAME"/No");
+ break;
+
+ case IDHELP:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
+ mir_strcpy(pa.lpzTitle, MODNAME"/Help");
+ break;
+
+ case IDALL:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK);
+ mir_strcpy(pa.lpzTitle, MODNAME"/All");
+ break;
+
+ case IDNONE:
+ pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL);
+ mir_strcpy(pa.lpzTitle, MODNAME"/None");
+ }
+}
+
+/**
+ * This is the message procedure for my nice looking message box
+ *
+ * @param hDlg - window handle
+ * @param uMsg - message to handle
+ * @param wParam - message specific parameter
+ * @param lParam - message specific parameter
+ *
+ * @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL
+ **/
+static INT_PTR CALLBACK MsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static int retOk = IDOK;
+ static int retAll = IDALL;
+ static int retNon = IDNONE;
+ static int retCancel = IDCANCEL;
+
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ {
+ LPMSGBOX pMsgBox = (LPMSGBOX)lParam;
+ if (PtrIsValid(pMsgBox)) {
+ int icoWidth = 0;
+ int InfoBarHeight = 0;
+ HFONT hNormalFont;
+
+ hNormalFont = (HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0);
+ if (pMsgBox->uType & MB_INFOBAR) {
+ LOGFONT lf;
+
+ // set bold font for name in description area
+ GetObject(hNormalFont, sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ hNormalFont = CreateFontIndirect(&lf);
+
+ // set infobar's textfont
+ SendDlgItemMessage(hDlg, TXT_NAME, WM_SETFONT, (WPARAM)hNormalFont, 0);
+
+ // set infobar's logo icon
+ SendDlgItemMessage(hDlg, ICO_DLGLOGO, STM_SETIMAGE, IMAGE_ICON,
+ (pMsgBox->hiLogo ? (LPARAM)pMsgBox->hiLogo : (LPARAM)IcoLib_GetIcon(ICO_DLG_DETAILS)));
+
+ // enable headerbar
+ ShowWindow(GetDlgItem(hDlg, TXT_NAME), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, ICO_DLGLOGO), SW_SHOW);
+ }
+ else {
+ RECT rc;
+ GetClientRect(GetDlgItem(hDlg, TXT_NAME), &rc);
+ InfoBarHeight = rc.bottom;
+
+ if (pMsgBox->hiLogo)
+ SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)pMsgBox->hiLogo);
+ }
+
+ // draw the desired status icon
+ HICON hIcon = MsgLoadIcon(pMsgBox);
+ if (hIcon)
+ SendDlgItemMessage(hDlg, ICO_MSGDLG, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ else {
+ RECT ws;
+ GetWindowRect(GetDlgItem(hDlg, ICO_MSGDLG), &ws);
+ icoWidth = ws.right - ws.left;
+ ShowWindow(GetDlgItem(hDlg, ICO_MSGDLG), SW_HIDE);
+ }
+
+ // resize the messagebox and reorganize the buttons
+ if (HDC hDC = GetDC(hDlg)) {
+ POINT mpt = { 0, 0 };
+ RECT ws = { 0, 0, 0, 0 };
+ int txtWidth = 0, txtHeight = 0, needX, needY;
+ RECT rcDlg;
+ SIZE ts;
+ LPTSTR h, rs;
+
+ SelectObject(hDC, hNormalFont);
+ // get message text width and height
+ if (pMsgBox->ptszMsg) for (rs = h = pMsgBox->ptszMsg;; ++h) {
+ if (*h == '\n' || !*h) {
+ GetTextExtentPoint32(hDC, rs, h - rs, &ts);
+ if (ts.cx > txtWidth)
+ txtWidth = ts.cx;
+ txtHeight += ts.cy;
+ if (!*h)
+ break;
+ rs = h + 1;
+ }
+ }
+ // increase width if info text requires more
+ if ((pMsgBox->uType&MB_INFOBAR) && pMsgBox->ptszInfoText && *pMsgBox->ptszInfoText) {
+ int multiline = 0;
+ RECT rcico; GetClientRect(GetDlgItem(hDlg, ICO_DLGLOGO), &rcico);
+ rcico.right = rcico.right * 100 / 66; // padding
+ for (rs = h = pMsgBox->ptszInfoText;; ++h) {
+ if (*h == '\n' || !*h) {
+ GetTextExtentPoint32(hDC, rs, h - rs, &ts);
+ ts.cx += rcico.right;
+ if (ts.cx > txtWidth)
+ txtWidth = ts.cx;
+ if (!*h)
+ break;
+ rs = h + 1;
+ ++multiline;
+ }
+ }
+ if (!multiline)
+ SetWindowLongPtr(GetDlgItem(hDlg, TXT_NAME), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hDlg, TXT_NAME), GWL_STYLE) | SS_CENTERIMAGE);
+ }
+ ReleaseDC(hDlg, hDC);
+
+ // calc new dialog size
+ GetWindowRect(hDlg, &rcDlg);
+ GetWindowRect(GetDlgItem(hDlg, TXT_MESSAGE), &ws);
+ needX = txtWidth - (ws.right - ws.left) - icoWidth;
+ needY = max(0, txtHeight - (ws.bottom - ws.top) + 5);
+ rcDlg.left -= needX / 2; rcDlg.right += needX / 2;
+ rcDlg.top -= (needY - InfoBarHeight) / 2; rcDlg.bottom += (needY - InfoBarHeight) / 2;
+
+ // resize dialog window
+ MoveWindow(hDlg, rcDlg.left, rcDlg.top, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, FALSE);
+ ClientToScreen(hDlg, &mpt);
+
+ MoveCtrl(hDlg, STATIC_WHITERECT, -mpt.x, -mpt.y, needX, needY - InfoBarHeight);
+ MoveCtrl(hDlg, TXT_NAME, -mpt.x, -mpt.y, needX, 0);
+ MoveCtrl(hDlg, ICO_DLGLOGO, -mpt.x + needX, -mpt.y, 0, 0);
+ MoveCtrl(hDlg, ICO_MSGDLG, -mpt.x, -mpt.y - InfoBarHeight, 0, 0);
+ MoveCtrl(hDlg, TXT_MESSAGE, -mpt.x - icoWidth, -mpt.y - InfoBarHeight, needX, needY);
+ MoveCtrl(hDlg, STATIC_LINE2, -mpt.x, -mpt.y + needY - InfoBarHeight, needX, 0);
+
+ // Do pushbutton positioning
+ RECT rcOk, rcAll, rcNone, rcCancel;
+
+ // get button rectangles
+ GetWindowRect(GetDlgItem(hDlg, IDOK), &rcOk);
+ OffsetRect(&rcOk, -mpt.x, -mpt.y + needY - InfoBarHeight);
+
+ GetWindowRect(GetDlgItem(hDlg, IDALL), &rcAll);
+ OffsetRect(&rcAll, -mpt.x, -mpt.y + needY - InfoBarHeight);
+
+ GetWindowRect(GetDlgItem(hDlg, IDNONE), &rcNone);
+ OffsetRect(&rcNone, -mpt.x, -mpt.y + needY - InfoBarHeight);
+
+ GetWindowRect(GetDlgItem(hDlg, IDCANCEL), &rcCancel);
+ OffsetRect(&rcCancel, -mpt.x, -mpt.y + needY - InfoBarHeight);
+
+ LONG okWidth = rcOk.right - rcOk.left;
+ LONG allWidth = rcAll.right - rcAll.left;
+ LONG noneWidth = rcNone.right - rcNone.left;
+ LONG caWidth = rcCancel.right - rcCancel.left;
+ LONG dlgMid = (rcDlg.right - rcDlg.left) / 2;
+
+ // load button configuration
+ switch (MB_TYPE(pMsgBox->uType)) {
+ case MB_OK:
+ rcOk.left = dlgMid - (okWidth / 2);
+ rcOk.right = rcOk.left + okWidth;
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ break;
+
+ case MB_OKCANCEL:
+ retOk = IDRETRY;
+ SetDlgItemText(hDlg, IDOK, LPGENW("OK"));
+ retCancel = IDCANCEL;
+ SetDlgItemText(hDlg, IDCANCEL, LPGENW("Cancel"));
+ rcOk.left = dlgMid - okWidth - 10;
+ rcOk.right = rcOk.left + okWidth;
+ rcCancel.left = dlgMid + 10;
+ rcCancel.right = rcCancel.left + caWidth;
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
+ break;
+
+ case MB_RETRYCANCEL:
+ retOk = IDRETRY;
+ SetDlgItemText(hDlg, IDOK, LPGENW("Retry"));
+ retCancel = IDCANCEL;
+ SetDlgItemText(hDlg, IDCANCEL, LPGENW("Cancel"));
+ rcOk.left = dlgMid - okWidth - 10;
+ rcOk.right = rcOk.left + okWidth;
+ rcCancel.left = dlgMid + 10;
+ rcCancel.right = rcCancel.left + caWidth;
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
+ break;
+
+ case MB_YESNO:
+ retOk = IDYES;
+ SetDlgItemText(hDlg, IDOK, LPGENW("Yes"));
+ retCancel = IDNO;
+ SetDlgItemText(hDlg, IDCANCEL, LPGENW("No"));
+ rcOk.left = dlgMid - okWidth - 10;
+ rcOk.right = rcOk.left + okWidth;
+ rcCancel.left = dlgMid + 10;
+ rcCancel.right = rcCancel.left + caWidth;
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
+ break;
+
+ case MB_ABORTRETRYIGNORE:
+ retOk = IDABORT;
+ SetDlgItemText(hDlg, IDOK, LPGENW("Abort"));
+ retAll = IDABORT;
+ SetDlgItemText(hDlg, IDALL, LPGENW("Retry"));
+ retCancel = IDCANCEL;
+ SetDlgItemText(hDlg, IDCANCEL, LPGENW("Ignore"));
+ rcAll.left = dlgMid - (allWidth / 2);
+ rcAll.right = rcAll.left + allWidth;
+ rcOk.left = rcAll.left - okWidth - 5;
+ rcOk.right = rcOk.left + okWidth;
+ rcCancel.left = rcAll.right + 5;
+ rcCancel.right = rcCancel.left + caWidth;
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
+ break;
+
+ case MB_YESNOCANCEL:
+ retOk = IDYES;
+ SetDlgItemText(hDlg, IDOK, LPGENW("Yes"));
+ retAll = IDNO;
+ SetDlgItemText(hDlg, IDALL, LPGENW("No"));
+ retCancel = IDCANCEL;
+ SetDlgItemText(hDlg, IDCANCEL, LPGENW("Cancel"));
+ rcAll.left = dlgMid - (allWidth / 2);
+ rcAll.right = rcAll.left + allWidth;
+ rcOk.left = rcAll.left - okWidth - 5;
+ rcOk.right = rcOk.left + okWidth;
+ rcCancel.left = rcAll.right + 5;
+ rcCancel.right = rcCancel.left + caWidth;
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
+ break;
+
+ case MB_YESALLNO:
+ retOk = IDYES;
+ SetDlgItemText(hDlg, IDOK, LPGENW("Yes"));
+ retAll = IDALL;
+ SetDlgItemText(hDlg, IDALL, LPGENW("All"));
+ SetDlgItemText(hDlg, IDNONE, LPGENW("None"));
+ retCancel = IDNO;
+ SetDlgItemText(hDlg, IDCANCEL, LPGENW("No"));
+ rcCancel.right = rcDlg.right - rcDlg.left - 10;
+ rcCancel.left = rcCancel.right - caWidth;
+ rcNone.right = rcCancel.left - 5;
+ rcNone.left = rcNone.right - noneWidth;
+ rcAll.right = rcNone.left - 5;
+ rcAll.left = rcAll.right - allWidth;
+ rcOk.right = rcAll.left - 5;
+ rcOk.left = rcOk.right - okWidth;
+ // show buttons
+ ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDNONE), SW_SHOW);
+ ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);
+ break;
+
+ default:
+ rcOk.left = dlgMid - (okWidth / 2);
+ rcOk.right = rcOk.left + okWidth;
+ }
+
+ MoveWindow(GetDlgItem(hDlg, IDOK), rcOk.left, rcOk.top, rcOk.right - rcOk.left, rcOk.bottom - rcOk.top, FALSE);
+ MoveWindow(GetDlgItem(hDlg, IDALL), rcAll.left, rcAll.top, rcAll.right - rcAll.left, rcAll.bottom - rcAll.top, FALSE);
+ MoveWindow(GetDlgItem(hDlg, IDNONE), rcNone.left, rcNone.top, rcNone.right - rcNone.left, rcNone.bottom - rcNone.top, FALSE);
+ MoveWindow(GetDlgItem(hDlg, IDCANCEL), rcCancel.left, rcCancel.top, rcCancel.right - rcCancel.left, rcCancel.bottom - rcCancel.top, FALSE);
+ }
+
+ // set text's
+ SetWindowText(hDlg, pMsgBox->ptszTitle);
+ SetDlgItemText(hDlg, TXT_NAME, pMsgBox->ptszInfoText);
+ SetDlgItemText(hDlg, TXT_MESSAGE, pMsgBox->ptszMsg);
+
+ TranslateDialogDefault(hDlg);
+ return TRUE;
+ }
+ }
+ break;
+
+ case WM_CTLCOLORSTATIC:
+ switch (GetWindowLongPtr((HWND)lParam, GWLP_ID)) {
+ case STATIC_WHITERECT:
+ case ICO_DLGLOGO:
+ case ICO_MSGDLG:
+ case TXT_MESSAGE:
+ case TXT_NAME:
+ SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
+ return GetSysColor(COLOR_WINDOW);
+ }
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ EndDialog(hDlg, retOk);
+ break;
+ case IDCANCEL:
+ EndDialog(hDlg, retCancel);
+ break;
+ case IDALL:
+ EndDialog(hDlg, retAll);
+ break;
+ case IDNONE:
+ EndDialog(hDlg, retNon);
+ }
+ break;
+
+ case WM_DESTROY:
+ DeleteObject((HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0));
+ break;
+ }
+ return FALSE;
+}
+
+/**
+* Dummi modal MsgBox for popup,
+* this set call function in wait stait and do not freece miranda main thread
+* the window is outside the desktop
+*/
+static INT_PTR CALLBACK MsgBoxPop(HWND hDlg, UINT uMsg, WPARAM, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ LPMSGBOX pMsgBox = (LPMSGBOX)lParam;
+
+ MoveWindow(hDlg, -10, -10, 0, 0, FALSE);
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)mir_alloc(sizeof(MSGPOPUPDATA));
+ if (pmpd) {
+ POPUPDATAW ppd;
+ ppd.lchContact = NULL; // (HANDLE)wParam;
+ // icon
+ ppd.lchIcon = MsgLoadIcon(pMsgBox);
+ mir_wstrncpy(ppd.lpwzContactName, pMsgBox->ptszTitle, _countof(ppd.lpwzContactName));
+ mir_wstrncpy(ppd.lpwzText, pMsgBox->ptszMsg, _countof(ppd.lpwzText));
+
+ // CALLBAC Proc
+ ppd.PluginWindowProc = PopupProc;
+ ppd.PluginData = pmpd;
+ ppd.iSeconds = -1;
+ ppd.lpActions = pmpd->pa;
+
+ // set color of popup
+ switch (pMsgBox->uType & MB_ICONMASK) {
+ case MB_ICON_ERROR:
+ ppd.colorBack = RGB(200, 10, 0);
+ ppd.colorText = RGB(255, 255, 255);
+ break;
+
+ case MB_ICON_WARNING:
+ ppd.colorBack = RGB(200, 100, 0);
+ ppd.colorText = RGB(255, 255, 255);
+ break;
+
+ default:
+ if (pMsgBox->uType & MB_CUSTOMCOLOR) {
+ ppd.colorBack = pMsgBox->colorBack;
+ ppd.colorText = pMsgBox->colorText;
+ }
+ }
+
+ // handle for MakePopupAction
+ pmpd->hDialog = hDlg;
+
+ // active buttons
+ switch (MB_TYPE(pMsgBox->uType)) {
+ case MB_OK:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDOK);
+ break;
+
+ case MB_OKCANCEL:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDOK);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDCANCEL);
+ break;
+
+ case MB_RETRYCANCEL:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDRETRY);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDCANCEL);
+ break;
+
+ case MB_YESNO:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDYES);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDNO);
+ break;
+
+ case MB_ABORTRETRYIGNORE:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDABORT);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDRETRY);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDIGNORE);
+ break;
+
+ case MB_YESNOCANCEL:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDYES);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDNO);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDCANCEL);
+ break;
+
+ case MB_YESALLNO:
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDYES);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDALL);
+ MakePopupAction(pmpd->pa[ppd.actionCount++], IDNO);
+ break;
+ }
+
+ // create popup
+ PUAddPopupW(&ppd);
+ if (MB_TYPE(pMsgBox->uType) == MB_OK)
+ EndDialog(hDlg, IDOK);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/**
+* This is the message procedure for popup
+*
+* @param hDlg - window handle
+* @param uMsg - message to handle
+* @param wParam - message specific parameter
+* @param lParam - message specific parameter
+*
+* @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL
+**/
+
+LRESULT CALLBACK PopupProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case UM_POPUPACTION:
+ if (HIWORD(wParam) == BN_CLICKED) {
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
+ if (pmpd) {
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ case IDCANCEL:
+ case IDABORT:
+ case IDRETRY:
+ case IDIGNORE:
+ case IDYES:
+ case IDNO:
+ case IDALL:
+ case IDNONE:
+ if (IsWindow(pmpd->hDialog))
+ EndDialog(pmpd->hDialog, LOWORD(wParam));
+ break;
+
+ default:
+ if (IsWindow(pmpd->hDialog))
+ EndDialog(pmpd->hDialog, IDCANCEL);
+ }
+ }
+ PUDeletePopup(hDlg);
+ }
+ break;
+
+ case UM_FREEPLUGINDATA:
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
+ if (pmpd > 0)
+ MIR_FREE(pmpd);
+ return TRUE;
+ }
+ return DefWindowProc(hDlg, uMsg, wParam, lParam);
+}
+
+/**
+* This is the service function for external plugins to use the nice messagebox
+*
+* @param wParam - MCONTACT hContact which can display an avatar for popups
+* @param lParam - MSGBOX structure holding parameters
+*
+* @return The function returns the ID of the clicked button (IDOK, IDCANCEL, ...)
+* or -1 on error.
+**/
+INT_PTR MsgBoxService(WPARAM, LPARAM lParam)
+{
+ LPMSGBOX pMsgBox = (LPMSGBOX)lParam;
+
+ // check input
+ if (PtrIsValid(pMsgBox) && pMsgBox->cbSize == sizeof(MSGBOX)) {
+ // Shall the MessageBox displayed as popup?
+ if (!(pMsgBox->uType & (MB_INFOBAR | MB_NOPOPUP)) // message box can be a popup?
+ && myGlobals.PopupActionsExist == 1 // popup support ext stuct?
+ && (db_get_dw(0, "Popup", "Actions", 0) & 1) // popup++ actions on?
+ && db_get_b(0, MODNAME, SET_POPUPMSGBOX, DEFVAL_POPUPMSGBOX)) // user likes popups?
+ return DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_MSGBOXDUMMI), pMsgBox->hParent, MsgBoxPop, lParam);
+
+ return DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_MSGBOX), pMsgBox->hParent, MsgBoxProc, lParam);
+ }
+ return -1;
+}
+
+/**
+* name: MsgBox
+* desc: calls a messagebox
+* param:
+**/
+INT_PTR CALLBACK MsgBox(HWND hParent, UINT uType, LPCTSTR pszTitle, LPCTSTR pszInfo, LPCTSTR pszFormat, ...)
+{
+ wchar_t tszMsg[MAX_SECONDLINE];
+
+ va_list vl;
+ va_start(vl, pszFormat);
+ mir_vsnwprintf(tszMsg, _countof(tszMsg), TranslateW(pszFormat), vl);
+ va_end(vl);
+
+ MSGBOX mb = { 0 };
+ mb.cbSize = sizeof(MSGBOX);
+ mb.hParent = hParent;
+ mb.hiLogo = IcoLib_GetIcon(ICO_COMMON_MAIN);
+ mb.hiMsg = nullptr;
+ mb.ptszTitle = TranslateW(pszTitle);
+ mb.ptszInfoText = TranslateW(pszInfo);
+ mb.ptszMsg = tszMsg;
+ mb.uType = uType;
+ return MsgBoxService(NULL, (LPARAM)&mb);
+}
+
+/**
+* name: MsgErr
+* desc: calls a messagebox
+* param:
+**/
+INT_PTR CALLBACK MsgErr(HWND hParent, LPCTSTR pszFormat, ...)
+{
+ wchar_t tszTitle[MAX_SECONDLINE], tszMsg[MAX_SECONDLINE];
+ mir_snwprintf(tszTitle, L"%s - %s", _A2W(MODNAME), TranslateT("Error"));
+
+ va_list vl;
+ va_start(vl, pszFormat);
+ mir_vsnwprintf(tszMsg, TranslateW(pszFormat), vl);
+ va_end(vl);
+
+ MSGBOX mb = { 0 };
+ mb.cbSize = sizeof(MSGBOX);
+ mb.hParent = hParent;
+ mb.hiLogo = IcoLib_GetIcon(ICO_COMMON_MAIN);
+ mb.hiMsg = nullptr;
+ mb.ptszTitle = tszTitle;
+ mb.ptszMsg = tszMsg;
+ mb.uType = MB_OK | MB_ICON_ERROR;
+ return MsgBoxService(NULL, (LPARAM)&mb);
+}
diff --git a/plugins/SendScreenshotPlus/src/dlg_msgbox.h b/plugins/SendScreenshotPlus/src/dlg_msgbox.h
index 68f40ea6b3..d1b31e6538 100644
--- a/plugins/SendScreenshotPlus/src/dlg_msgbox.h
+++ b/plugins/SendScreenshotPlus/src/dlg_msgbox.h
@@ -2,7 +2,7 @@
Miranda NG: the free IM client for Microsoft* Windows*
Copyright:
-© 2012-22 Miranda NG team (https://miranda-ng.org)
+© 2012-23 Miranda NG team (https://miranda-ng.org)
© 2006-10 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol
This program is free software; you can redistribute it and/or
diff --git a/plugins/SendScreenshotPlus/src/stdafx.cxx b/plugins/SendScreenshotPlus/src/stdafx.cxx
index f64d25234b..ebbde0ade1 100644
--- a/plugins/SendScreenshotPlus/src/stdafx.cxx
+++ b/plugins/SendScreenshotPlus/src/stdafx.cxx
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/SendScreenshotPlus/src/stdafx.h b/plugins/SendScreenshotPlus/src/stdafx.h
index bdf13cef1f..ecad2333c8 100644
--- a/plugins/SendScreenshotPlus/src/stdafx.h
+++ b/plugins/SendScreenshotPlus/src/stdafx.h
@@ -1,186 +1,186 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-09 Miranda ICQ/IM project,
-
-This file is part of Send Screenshot Plus, a Miranda IM plugin.
-Copyright (c) 2010 Ing.U.Horn
-
-Parts of this file based on original sorce code
-(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
-
-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.
-*/
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-
-#define OEMRESOURCE
-
-#include <windows.h>
-#include <Windowsx.h>
-#include <commctrl.h>
-#include <time.h>
-#include <Shlwapi.h>
-#include <gdiplus.h>
-#include <mapi.h>
-#include <UxTheme.h>
-
-#include <map>
-#include <string>
-using namespace std;
-
-#include <msapi/vsstyle.h>
-#include <msapi/vssym32.h>
-
-#include <newpluginapi.h>
-#include <m_button.h>
-#include <m_chat_int.h>
-#include <m_clist.h>
-#include <m_contacts.h>
-#include <m_database.h>
-#include <m_hotkeys.h>
-#include <m_imgsrvc.h>
-#include <m_langpack.h>
-#include <m_netlib.h>
-#include <m_protosvc.h>
-#include <m_skin.h>
-#include <m_json.h>
-#include <m_popup.h>
-#include <m_icolib.h>
-#include <m_message.h>
-
-#include <m_folders.h>
-#include <m_HTTPServer.h>
-#include <m_ftpfile.h>
-#include <m_sendss.h>
-#include <m_userinfoex.h>
-#include <m_cloudfile.h>
-
-#include "ctrl_button.h"
-#include "dlg_msgbox.h"
-#include "resource.h"
-#include "version.h"
-#include "CSend.h"
-#include "CSendEmail.h"
-#include "CSendFile.h"
-#include "CSendFTPFile.h"
-#include "CSendHTTPServer.h"
-#include "CSendCloduFile.h"
-#include "CSendHost_ImageShack.h"
-#include "CSendHost_uploadpie.h"
-#include "CSendHost_imgur.h"
-#include "DevKey.h"
-#include "UMainForm.h"
-#include "Utils.h"
-
-#define UM_CLOSING WM_USER+1
-#define UM_EVENT WM_USER+2
-
-// Generic Message Box for Errors
-#define MSGERROR(text) MessageBox(NULL, text, L"SendSS", MB_OK | MB_ICONERROR)
-#define MSGINFO (text) MessageBox(NULL, text, L"SendSS", MB_OK | MB_ICONINFORMATION)
-
-typedef struct _MGLOBAL {
- uint32_t mirandaVersion; // mirandaVersion
- BOOLEAN PopupActionsExist : 1; // Popup+ or MS_POPUP_REGISTERACTIONS exist
- BOOLEAN PluginHTTPExist : 1; // HTTPServer or MS_HTTP_ACCEPT_CONNECTIONS exist
- BOOLEAN PluginFTPExist : 1; // FTPFile or MS_FTPFILE_UPLOAD exist
- BOOLEAN PluginCloudFileExist: 1; // CloudFile or MS_CLOUDFILE_UPLOAD exists
-
-} MGLOBAL, *LPMGLOBAL;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define ERROR_TITLE TranslateT("SendScreenshot - Error")
-
-// Miranda Database Key
-#define MODULENAME "SendSS"
-
-struct CMPlugin : public PLUGIN<CMPlugin>
-{
- CMPlugin();
-
- int Load() override;
- int Unload() override;
-};
-
-extern ATOM g_clsTargetHighlighter;
-extern MGLOBAL g_myGlobals;
-extern HNETLIBUSER g_hNetlibUser;
-
-enum
-{
- ICO_MAIN = 0,
- ICO_MAINXS,
- ICO_TARGET,
- ICO_MONITOR,
- ICO_END_,
- ICO_BTN_HELP = 0,
- ICO_BTN_FOLDER,
- ICO_BTN_DESC,
- ICO_BTN_DESCON,
- ICO_BTN_DEL,
- ICO_BTN_DELON,
- ICO_BTN_ARROWL,
- ICO_BTN_ARROWR,
- ICO_BTN_UPDATE,
- ICO_BTN_OK,
- ICO_BTN_CANCEL,
- ICO_BTN_EDIT,
- ICO_BTN_EDITON,
- ICO_BTN_COPY,
- ICO_BTN_BBC,
- ICO_BTN_BBCLNK,
- ICO_BTN_DOWNARROW,
- ICO_BTN_END_,
-};
-#define GetIconHandle(ico) ICONS[ico].hIcolib
-#define GetIcon(ico) IcoLib_GetIconByHandle(GetIconHandle(ico))
-extern IconItem ICONS[ICO_END_];
-#define GetIconBtnHandle(ico) ICONS_BTN[ico].hIcolib
-#define GetIconBtn(ico) IcoLib_GetIconByHandle(GetIconBtnHandle(ico))
-extern IconItem ICONS_BTN[ICO_BTN_END_];
-
-#define PtrIsValid(p) (((p)!=0)&&(((HANDLE)(p))!=INVALID_HANDLE_VALUE))
-#define MIR_FREE(p) {if (PtrIsValid(p)){mir_free((void*)p);(p)=NULL;}}
-#ifdef _DEBUG
-# define DBGMSG(str,...) do{char tmp[1024];sprintf(tmp,str,##__VA_ARGS__);OutputDebugStringA(tmp);}while(0)
-#else
-# define DBGMSG(str,...)
-#endif
-
-void ComboBox_SelectItem(HWND hCombo, LPARAM data);
-
-template<class _Elem>
-std::basic_string<_Elem> replace(const std::basic_string<_Elem> & Origninal, const std::basic_string<_Elem> & What, const std::basic_string<_Elem> & With)
-{
- std::basic_string<_Elem> res;
- size_t l = 0;
- for (size_t p = Origninal.find(What.c_str(), 0); p != std::basic_string<_Elem>::npos; p = Origninal.find(What.c_str(), l))
- {
- if (l != p)
- res.append(Origninal.c_str() + l, p - l);
- res.append(With);
- l = p + What.length();
- }
- if (l < Origninal.length())
- res.append(Origninal.c_str() + l);
-
- return res;
-}
-
-#endif
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
+Copyright (c) 2000-09 Miranda ICQ/IM project,
+
+This file is part of Send Screenshot Plus, a Miranda IM plugin.
+Copyright (c) 2010 Ing.U.Horn
+
+Parts of this file based on original sorce code
+(c) 2004-2006 Sérgio Vieira Rolanski (portet from Borland C++)
+
+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.
+*/
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_
+
+#define OEMRESOURCE
+
+#include <windows.h>
+#include <Windowsx.h>
+#include <commctrl.h>
+#include <time.h>
+#include <Shlwapi.h>
+#include <gdiplus.h>
+#include <mapi.h>
+#include <UxTheme.h>
+
+#include <map>
+#include <string>
+using namespace std;
+
+#include <msapi/vsstyle.h>
+#include <msapi/vssym32.h>
+
+#include <newpluginapi.h>
+#include <m_button.h>
+#include <m_chat_int.h>
+#include <m_clist.h>
+#include <m_contacts.h>
+#include <m_database.h>
+#include <m_hotkeys.h>
+#include <m_imgsrvc.h>
+#include <m_langpack.h>
+#include <m_netlib.h>
+#include <m_protosvc.h>
+#include <m_skin.h>
+#include <m_json.h>
+#include <m_popup.h>
+#include <m_icolib.h>
+#include <m_message.h>
+
+#include <m_folders.h>
+#include <m_HTTPServer.h>
+#include <m_ftpfile.h>
+#include <m_sendss.h>
+#include <m_userinfoex.h>
+#include <m_cloudfile.h>
+
+#include "ctrl_button.h"
+#include "dlg_msgbox.h"
+#include "resource.h"
+#include "version.h"
+#include "CSend.h"
+#include "CSendEmail.h"
+#include "CSendFile.h"
+#include "CSendFTPFile.h"
+#include "CSendHTTPServer.h"
+#include "CSendCloduFile.h"
+#include "CSendHost_ImageShack.h"
+#include "CSendHost_uploadpie.h"
+#include "CSendHost_imgur.h"
+#include "DevKey.h"
+#include "UMainForm.h"
+#include "Utils.h"
+
+#define UM_CLOSING WM_USER+1
+#define UM_EVENT WM_USER+2
+
+// Generic Message Box for Errors
+#define MSGERROR(text) MessageBox(NULL, text, L"SendSS", MB_OK | MB_ICONERROR)
+#define MSGINFO (text) MessageBox(NULL, text, L"SendSS", MB_OK | MB_ICONINFORMATION)
+
+typedef struct _MGLOBAL {
+ uint32_t mirandaVersion; // mirandaVersion
+ BOOLEAN PopupActionsExist : 1; // Popup+ or MS_POPUP_REGISTERACTIONS exist
+ BOOLEAN PluginHTTPExist : 1; // HTTPServer or MS_HTTP_ACCEPT_CONNECTIONS exist
+ BOOLEAN PluginFTPExist : 1; // FTPFile or MS_FTPFILE_UPLOAD exist
+ BOOLEAN PluginCloudFileExist: 1; // CloudFile or MS_CLOUDFILE_UPLOAD exists
+
+} MGLOBAL, *LPMGLOBAL;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define ERROR_TITLE TranslateT("SendScreenshot - Error")
+
+// Miranda Database Key
+#define MODULENAME "SendSS"
+
+struct CMPlugin : public PLUGIN<CMPlugin>
+{
+ CMPlugin();
+
+ int Load() override;
+ int Unload() override;
+};
+
+extern ATOM g_clsTargetHighlighter;
+extern MGLOBAL g_myGlobals;
+extern HNETLIBUSER g_hNetlibUser;
+
+enum
+{
+ ICO_MAIN = 0,
+ ICO_MAINXS,
+ ICO_TARGET,
+ ICO_MONITOR,
+ ICO_END_,
+ ICO_BTN_HELP = 0,
+ ICO_BTN_FOLDER,
+ ICO_BTN_DESC,
+ ICO_BTN_DESCON,
+ ICO_BTN_DEL,
+ ICO_BTN_DELON,
+ ICO_BTN_ARROWL,
+ ICO_BTN_ARROWR,
+ ICO_BTN_UPDATE,
+ ICO_BTN_OK,
+ ICO_BTN_CANCEL,
+ ICO_BTN_EDIT,
+ ICO_BTN_EDITON,
+ ICO_BTN_COPY,
+ ICO_BTN_BBC,
+ ICO_BTN_BBCLNK,
+ ICO_BTN_DOWNARROW,
+ ICO_BTN_END_,
+};
+#define GetIconHandle(ico) ICONS[ico].hIcolib
+#define GetIcon(ico) IcoLib_GetIconByHandle(GetIconHandle(ico))
+extern IconItem ICONS[ICO_END_];
+#define GetIconBtnHandle(ico) ICONS_BTN[ico].hIcolib
+#define GetIconBtn(ico) IcoLib_GetIconByHandle(GetIconBtnHandle(ico))
+extern IconItem ICONS_BTN[ICO_BTN_END_];
+
+#define PtrIsValid(p) (((p)!=0)&&(((HANDLE)(p))!=INVALID_HANDLE_VALUE))
+#define MIR_FREE(p) {if (PtrIsValid(p)){mir_free((void*)p);(p)=NULL;}}
+#ifdef _DEBUG
+# define DBGMSG(str,...) do{char tmp[1024];sprintf(tmp,str,##__VA_ARGS__);OutputDebugStringA(tmp);}while(0)
+#else
+# define DBGMSG(str,...)
+#endif
+
+void ComboBox_SelectItem(HWND hCombo, LPARAM data);
+
+template<class _Elem>
+std::basic_string<_Elem> replace(const std::basic_string<_Elem> & Origninal, const std::basic_string<_Elem> & What, const std::basic_string<_Elem> & With)
+{
+ std::basic_string<_Elem> res;
+ size_t l = 0;
+ for (size_t p = Origninal.find(What.c_str(), 0); p != std::basic_string<_Elem>::npos; p = Origninal.find(What.c_str(), l))
+ {
+ if (l != p)
+ res.append(Origninal.c_str() + l, p - l);
+ res.append(With);
+ l = p + What.length();
+ }
+ if (l < Origninal.length())
+ res.append(Origninal.c_str() + l);
+
+ return res;
+}
+
+#endif