/* 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 "global.h" #include "Main.h" // Prototypes /////////////////////////////////////////////////////////////////////////// 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 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 wParam, LPARAM 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 fdwReason, LPVOID lpvReserved) { 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 mirandaVersion) { 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 wParam, LPARAM 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); 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 CLISTMENUITEM mi = { 0 }; mi.flags=CMIF_ROOTHANDLE|CMIF_TCHAR/*|CMIF_ICONFROMICOLIB*/; mi.hParentMenu=HGENMENU_ROOT; mi.icolibItem=GetIconHandle(ICO_MAINXS); #define _Menu_AddMainMenuItemEx(name,srv,pos) do{mi.ptszName=name;mi.pszService=srv;mi.position=pos;Menu_AddMainMenuItem(&mi);}while(0) #define _Menu_AddContactMenuItemEx(name,srv,pos) do{mi.ptszName=name;mi.pszService=srv;mi.position=pos;Menu_AddContactMenuItem(&mi);}while(0) _Menu_AddMainMenuItemEx(LPGENT("Take a screenshot"),MS_SENDSS_OPENDIALOG,1000001); _Menu_AddContactMenuItemEx(LPGENT("Send screenshot"),MS_SENDSS_OPENDIALOG,1000000); _Menu_AddContactMenuItemEx(LPGENT("Send desktop screenshot"),MS_SENDSS_SENDDESKTOP,1000001); /// 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; }