/* Miranda NG: the free IM client for Microsoft* Windows* Copyright (с) 2012-15 Miranda NG project (http://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 "Main.h" // Prototypes /////////////////////////////////////////////////////////////////////////// CLIST_INTERFACE *pcli; HINSTANCE g_hSendSS; MGLOBAL g_myGlobals; HANDLE g_hNetlibUser=0;//!< Netlib Register User FI_INTERFACE* FIP=NULL; int hLangpack;//Miranda NG langpack used by translate functions, filled by mir_getLP() 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("Apply"),"apply",IDI_APPLY}, { LPGEN("Edit"), "edit", IDI_EDIT }, { LPGEN("Edit on"), "editon", IDI_EDITON }, { LPGEN("Copy"), "copy", IDI_COPY }, { LPGEN("BBC"), "bbc", IDI_BBC }, { LPGEN("BBC link"), "bbclnk", IDI_BBC2 }, { LPGEN("Down arrow"), "downarrow", IDI_DOWNARROW }, }; static HANDLE m_hFolderScreenshot = 0; TCHAR* GetCustomPath() { TCHAR* pszPath = Utils_ReplaceVarsT(_T("%miranda_userdata%\\Screenshots")); if (m_hFolderScreenshot) { TCHAR szPath[1024] = { 0 }; FoldersGetCustomPathT(m_hFolderScreenshot, szPath, 1024, pszPath); mir_free(pszPath); pszPath = mir_tstrdup(szPath); } if (!pszPath) { MessageBox(NULL, _T("Can not retrieve screenshot path."), _T("SendSS"), MB_OK | MB_ICONERROR | MB_APPLMODAL); return 0; } int result = CreateDirectoryTreeT(pszPath); if (result) { TCHAR szError[MAX_PATH]; mir_sntprintf(szError, MAX_PATH, TranslateT("Could not create screenshot folder (error code: %d):\n%s\nDo you have write permissions?"), result, pszPath); MessageBox(NULL, szError, _T("SendSS"), MB_OK | MB_ICONERROR | MB_APPLMODAL); mir_free(pszPath); return 0; } return pszPath; } /// services static HANDLE m_hOpenCaptureDialog = 0; static HANDLE m_hSendDesktop = 0; static HANDLE m_hEditBitmap = 0; static HANDLE m_hSend2ImageShack = 0; //--------------------------------------------------------------------------- // 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(NULL, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL); return -1; } TCHAR* pszPath = GetCustomPath(); if (!pszPath) { delete frmMain; return -1; } frmMain->Init(pszPath, wParam); mir_free(pszPath); if (lParam == 0xFFFF) { frmMain->SetTargetWindow(NULL); } 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(NULL, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL); return -1; } TCHAR* pszPath = GetCustomPath(); if (!pszPath) { delete frmMain; return -1; } MCONTACT hContact = (MCONTACT)wParam; char* pszProto = GetContactProto(hContact); bool bChatRoom = db_get_b(hContact, pszProto, "ChatRoom", 0) != 0; frmMain->m_opt_chkTimed = false; frmMain->m_opt_tabCapture = 1; frmMain->m_opt_cboxDesktop = 0; frmMain->m_opt_chkEditor = false; frmMain->m_opt_cboxSendBy = bChatRoom ? 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; } //--------------------------------------------------------------------------- // Edit a in-memory bitmap on the edit window // wParam = (SENDSSCB) callback function address to call when editing is done // lParam = (HBITMAP) bitmap handle, a copy is made so the calling function can free this handle after the service function returns // Returns: INT_PTR service_EditBitmap(WPARAM, LPARAM) { /* TfrmEdit *frmEdit=new TfrmEdit(NULL); if (!frmEdit) return -1; Graphics::TBitmap *bitmap=new Graphics::TBitmap(); if (!bitmap) return -2; bitmap->Handle = (void*)lParam; frmEdit->InitEditor(bitmap); // a copy of the bitmap is made inside this function frmEdit->Show(); delete bitmap; */ 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 = NULL; CSendHost_ImageShack* cSend = new CSendHost_ImageShack(NULL, 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_t2a(cSend->GetErrorMsg()); } delete cSend; return (INT_PTR)result; } // Functions //////////////////////////////////////////////////////////////////////////// BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD, LPVOID) { g_hSendSS = hinstDLL; return TRUE; } static const PLUGININFOEX pluginInfo = { sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), __DESCRIPTION, __AUTHOR, __AUTHOREMAIL, __COPYRIGHT, __AUTHORWEB, UNICODE_AWARE, // {ED39AF7C-BECD-404E-9499-4D04F711B9CB} { 0xed39af7c, 0xbecd, 0x404e, { 0x94, 0x99, 0x4d, 0x04, 0xf7, 0x11, 0xb9, 0xcb } } }; DLL_EXPORT PLUGININFOEX* MirandaPluginInfoEx(DWORD) { return const_cast(&pluginInfo); } /// hooks static HANDLE m_hookModulesLoaded = 0; static HANDLE m_hookSystemPreShutdown = 0; int hook_ModulesLoaded(WPARAM, LPARAM) { g_myGlobals.PopupExist = ServiceExists(MS_POPUP_ADDPOPUPT); g_myGlobals.PopupActionsExist = ServiceExists(MS_POPUP_REGISTERACTIONS); g_myGlobals.PluginHTTPExist = ServiceExists(MS_HTTP_ACCEPT_CONNECTIONS); g_myGlobals.PluginFTPExist = ServiceExists(MS_FTPFILE_SHAREFILE); g_myGlobals.PluginDropboxExist = ServiceExists(MS_DROPBOX_SEND_FILE); // Netlib register NETLIBUSER nlu = { sizeof(nlu) }; nlu.szSettingsModule = __PLUGIN_NAME; nlu.ptszDescriptiveName = TranslateT("SendSS HTTP connections"); nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; //|NUF_NOHTTPSOPTION; g_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); // load my button class / or use UInfoEx CtrlButtonLoadModule(); // Folders plugin support m_hFolderScreenshot = FoldersRegisterCustomPathT(LPGEN("SendSS"), LPGEN("Screenshots"), _T(PROFILE_PATH)_T("\\")_T(CURRENT_PROFILE)_T("\\Screenshots")); return 0; } int hook_SystemPreShutdown(WPARAM, LPARAM) { TfrmAbout::Unload();//crashes if done from "Unload" because of dependencies TfrmMain::Unload();// " // Netlib unregister Netlib_CloseHandle(g_hNetlibUser); // uninitialize classes CtrlButtonUnloadModule(); return 0; } ATOM g_clsTargetHighlighter = 0; DLL_EXPORT int Load(void) { mir_getLP(&pluginInfo); mir_getCLI(); INT_PTR result = CallService(MS_IMG_GETINTERFACE, FI_IF_VERSION, (LPARAM)&FIP); if (FIP == NULL || result != S_OK) { MessageBox(NULL, TranslateT("Image services (AdvaImg) not found.\nSendSS disabled."), TranslateT("SendSS"), MB_OK | MB_ICONERROR | MB_APPLMODAL); return 1; } /// hook events m_hookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, hook_ModulesLoaded); m_hookSystemPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, hook_SystemPreShutdown); /// icons Icon_Register(g_hSendSS, SZ_SENDSS, ICONS, sizeof(ICONS) / sizeof(IconItem), SZ_SENDSS); Icon_Register(g_hSendSS, SZ_SENDSS "/" LPGEN("Buttons"), ICONS_BTN, sizeof(ICONS_BTN) / sizeof(IconItem), SZ_SENDSS); /// services #define srv_reg(name) do{\ m_h##name=CreateServiceFunction(SZ_SENDSS "/" #name, service_##name);\ if(!m_h##name) MessageBoxA(NULL,Translate("Could not register Miranda service."),SZ_SENDSS "/" #name,MB_OK|MB_ICONERROR|MB_APPLMODAL);\ }while(0) srv_reg(OpenCaptureDialog); srv_reg(SendDesktop); srv_reg(EditBitmap); srv_reg(Send2ImageShack); // menu items CMenuItem mi; mi.flags = CMIF_TCHAR; mi.hIcolibItem = GetIconHandle(ICO_MAINXS); mi.name.t = LPGENT("Take a screenshot"); mi.pszService = MS_SENDSS_OPENDIALOG; mi.position = 1000001; Menu_AddMainMenuItem(&mi); mi.name.t = LPGENT("Send screenshot"); mi.pszService = MS_SENDSS_OPENDIALOG; mi.position = 1000000; Menu_AddContactMenuItem(&mi); mi.name.t = LPGENT("Send desktop screenshot"); mi.pszService = MS_SENDSS_SENDDESKTOP; mi.position = 1000001; Menu_AddContactMenuItem(&mi); /// hotkey's HOTKEYDESC hkd = { sizeof(hkd) }; hkd.pszName = "Open SendSS+"; hkd.ptszDescription = LPGENT("Open SendSS+"); hkd.ptszSection = _T("SendSS+"); hkd.pszService = MS_SENDSS_OPENDIALOG; //hkd.DefHotKey=HOTKEYCODE(HOTKEYF_CONTROL, VK_F10) | HKF_MIRANDA_LOCAL; hkd.lParam = 0xFFFF; hkd.dwFlags = HKD_TCHAR; Hotkey_Register(&hkd); /// register highlighter window class HBRUSH brush = CreateSolidBrush(0x0000FF00);//owned by class WNDCLASS wndclass = { CS_HREDRAW | CS_VREDRAW, DefWindowProc, 0, 0, g_hSendSS, NULL, NULL, brush, NULL, L"SendSSHighlighter" }; g_clsTargetHighlighter = RegisterClass(&wndclass); return 0; } /*--------------------------------------------------------------------------- * Prepare the plugin to stop * Called by Miranda when it will exit or when the plugin gets deselected */ DLL_EXPORT int Unload(void) {//as "ghazan" says, it's useless to unregister services or unhook events, let's still do it for now :P CallService(MS_HOTKEY_UNREGISTER, 0, (LPARAM)"Open SendSS+"); /// deregister services #define srv_dereg(name) do{ if(m_h##name) DestroyServiceFunction(m_h##name),m_h##name=0; }while(0) srv_dereg(OpenCaptureDialog); srv_dereg(SendDesktop); srv_dereg(EditBitmap); srv_dereg(Send2ImageShack); if (m_hookModulesLoaded) UnhookEvent(m_hookModulesLoaded), m_hookModulesLoaded = 0; if (m_hookSystemPreShutdown) UnhookEvent(m_hookSystemPreShutdown), m_hookSystemPreShutdown = 0; if (g_clsTargetHighlighter) UnregisterClass((TCHAR*)g_clsTargetHighlighter, g_hSendSS), g_clsTargetHighlighter = 0; return 0; }