diff options
author | dartraiden <wowemuh@gmail.com> | 2023-01-02 21:10:29 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2023-01-02 21:10:29 +0300 |
commit | 1979fd80424d16b2e489f9b57d01d9c7811d25a2 (patch) | |
tree | 960d42c5fe4a51f0fe2850bea91256e226bce221 /plugins/SendScreenshotPlus/src | |
parent | adfbbb217d4f4a05acf198755f219a5223d31c27 (diff) |
Update copyrights
Diffstat (limited to 'plugins/SendScreenshotPlus/src')
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
|