/*
Quick Messages plugin for Miranda IM
Copyright (C) 2008 Danil Mozhar
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 3 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, see .
*/
#include "quickmessages.h"
HINSTANCE hinstance;
WNDPROC mainProc;
HANDLE hEventCBButtonPressed, hEventCBInit,hEventInputMenu, hEventDbOptionsInit, hEventDbPluginsLoaded,
hEventDbPreShutdown, hIcon ;
int g_iButtonsCount=0;
int g_bShutDown=0;
int g_bStartup=0;
BOOL g_bRClickAuto=0;
BOOL g_bLClickAuto=0;
BOOL g_bQuickMenu=0;
struct MM_INTERFACE mmi;
struct LIST_INTERFACE li;
PLUGINLINK *pluginLink;
int hLangpack;
PLUGININFOEX pluginInfo = {
sizeof(PLUGININFOEX),
MODULENAME,
PLUGIN_MAKE_VERSION(0,0,4,2),
"Plugin for quick insert pre-defined messages in message input area.",
"MaD_CLuSTeR",
"daniok@yandex.ru",
"© 2008 Danil Mozhar",
"http://miranda.radicaled.ru/index.php?plugin=3",
UNICODE_AWARE,
0,
#ifdef _UNICODE
// {37ED754B-6CF9-40ed-9EB6-0FEF8E822475}
{ 0x37ed754b, 0x6cf9, 0x40ed, { 0x9e, 0xb6, 0xf, 0xef, 0x8e, 0x82, 0x24, 0x75 } }
#else
// {A15C6605-75F3-4be2-9193-6D3DDD0A13B7}
{ 0xa15c6605, 0x75f3, 0x4be2, { 0x91, 0x93, 0x6d, 0x3d, 0xdd, 0xa, 0x13, 0xb7 } }
#endif
};
int PreShutdown(WPARAM wparam,LPARAM lparam)
{
g_bShutDown=1;
DestructButtonsList();
if(hEventCBButtonPressed) UnhookEvent(hEventCBButtonPressed);
if(hEventCBInit) UnhookEvent(hEventCBInit);
if(hEventInputMenu) UnhookEvent(hEventInputMenu);
UnhookEvent(hEventDbPluginsLoaded);
UnhookEvent(hEventDbOptionsInit);
UnhookEvent(hEventDbPreShutdown);
return 0;
}
static int InputMenuPopup(WPARAM wParam,LPARAM lParam)
{
HMENU hSubMenu=NULL;
int i=0;
MessageWindowPopupData * mwpd = (MessageWindowPopupData *)lParam;
if(mwpd->uFlags==MSG_WINDOWPOPUP_LOG||!g_bQuickMenu||!QuickList->realCount) return 0;
if(mwpd->uType==MSG_WINDOWPOPUP_SHOWING)
{
hSubMenu = CreatePopupMenu();
InsertMenu((HMENU)mwpd->hMenu,6,MF_STRING|MF_POPUP|MF_BYPOSITION,(UINT_PTR)hSubMenu,TranslateT("Quick Messages"));
InsertMenu((HMENU)mwpd->hMenu,7,MF_SEPARATOR|MF_BYPOSITION,0,0);
qsort(QuickList->items,QuickList->realCount,sizeof(QuickData *),sstQuickSortButtons);
for(i=0;irealCount;i++)
{
QuickData* qd= (QuickData *)QuickList->items[i];
if(qd->fEntryType&QMF_EX_SEPARATOR)
AppendMenu(hSubMenu,MF_SEPARATOR,0,NULL);
else
AppendMenu(hSubMenu,MF_STRING,qd->dwPos+254,qd->ptszValueName);
}
}
else if(mwpd->uType==MSG_WINDOWPOPUP_SELECTED&&mwpd->selection>=254)
{
for(i=0;irealCount;i++)
{
QuickData* qd= (QuickData *)QuickList->items[i];
if((qd->dwPos+254)==mwpd->selection)
{
CHARRANGE cr;
UINT textlenght=0;
TCHAR* pszText=NULL;
TCHAR* ptszQValue=NULL;
TCHAR* pszCBText=NULL;
BOOL bIsService=0;
if(IsClipboardFormatAvailable(CF_TEXT)){
if (OpenClipboard(mwpd->hwnd)){
HANDLE hData=NULL;
TCHAR* chBuffer=NULL;
int textLength=0;
#ifdef _UNICODE
hData= GetClipboardData(CF_UNICODETEXT);
#else
hData = GetClipboardData(CF_TEXT);
#endif
chBuffer= (TCHAR*)GlobalLock(hData);
textLength=(int)_tcslen(chBuffer);
pszCBText=mir_tstrdup(chBuffer);
GlobalUnlock(hData);
CloseClipboard();
}
}
SendMessage(mwpd->hwnd, EM_EXGETSEL, 0, (LPARAM)&cr);
textlenght=cr.cpMax-cr.cpMin;
if(textlenght)
{
pszText=mir_alloc((textlenght+10)*sizeof(TCHAR));
ZeroMemory(pszText,(textlenght+10)*sizeof(TCHAR));
SendMessage(mwpd->hwnd,EM_GETSELTEXT, 0, (LPARAM)pszText);
}
if(qd->ptszValue){
ptszQValue=ParseString(mwpd->hContact,qd->ptszValue,pszText?pszText:_T(""),pszCBText?pszCBText:_T(""),(int)_tcslen(qd->ptszValue),textlenght,pszCBText?(int)_tcslen(pszCBText):0);
if((bIsService=qd->bIsService)&&ptszQValue)
#ifdef _UNICODE
CallService(mir_u2a(ptszQValue),(WPARAM)mwpd->hContact,0);
#else
CallService(ptszQValue,(WPARAM)mwpd->hContact,0);
#endif
}
if(ptszQValue)
SendMessage(mwpd->hwnd, EM_REPLACESEL, TRUE, (LPARAM)ptszQValue);
if(pszText) mir_free(pszText);
if(ptszQValue) free(ptszQValue);
if(pszCBText) mir_free(pszCBText);
break;
}
}
return 1;
}
return 0;
}
static int CustomButtonPressed(WPARAM wParam,LPARAM lParam)
{
CustomButtonClickData *cbcd=(CustomButtonClickData *)lParam;
CHARRANGE cr;
HWND hEdit=NULL;
int i=0;
BOOL bCTRL=0;
BOOL bIsService=0;
TCHAR* pszText=NULL;
TCHAR* pszCBText=NULL;
TCHAR* pszFormatedText=NULL;
TCHAR* ptszQValue=NULL;
int cblenght=0,qvlenght=0;
int count=0,mode=0;
UINT textlenght=0;
BBButton bbd={0};
SortedList* sl=NULL;
int state=0;
if(strcmp(cbcd->pszModule,PLGNAME)) return 0;
if(!ButtonsList[cbcd->dwButtonId]) return 1;
sl=ButtonsList[cbcd->dwButtonId]->sl;
if(!sl) return 1;
if(IsClipboardFormatAvailable(CF_TEXT)){
if (OpenClipboard(cbcd->hwndFrom)){
HANDLE hData=NULL;
TCHAR* chBuffer=NULL;
int textLength=0;
#ifdef _UNICODE
hData= GetClipboardData(CF_UNICODETEXT);
#else
hData = GetClipboardData(CF_TEXT);
#endif
chBuffer= (TCHAR*)GlobalLock(hData);
textLength=(int)_tcslen(chBuffer);
pszCBText=mir_tstrdup(chBuffer);
GlobalUnlock(hData);
CloseClipboard();
}
}
qsort(sl->items,sl->realCount,sizeof(ButtonData *),sstSortButtons);
hEdit=GetDlgItem(cbcd->hwndFrom,IDC_MESSAGE);
if(!hEdit) hEdit=GetDlgItem(cbcd->hwndFrom,IDC_CHATMESSAGE);
cr.cpMin = cr.cpMax = 0;
SendMessage(hEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
textlenght=cr.cpMax-cr.cpMin;
if(textlenght)
{
pszText=mir_alloc((textlenght+10)*sizeof(TCHAR));
ZeroMemory(pszText,(textlenght+10)*sizeof(TCHAR));
SendMessage(hEdit,EM_GETSELTEXT, 0, (LPARAM)pszText);
}
if(cbcd->flags&BBCF_RIGHTBUTTON)
state=1;
else if(sl->realCount==1)
state=2;
else
state=3;
switch(state)
{
case 1:
if(ButtonsList[cbcd->dwButtonId]->ptszQValue)
ptszQValue=ParseString(cbcd->hContact,ButtonsList[cbcd->dwButtonId]->ptszQValue,pszText?pszText:_T(""),pszCBText?pszCBText:_T(""),(int)_tcslen(ButtonsList[cbcd->dwButtonId]->ptszQValue),textlenght,pszCBText?(int)_tcslen(pszCBText):0);
if((bIsService=ButtonsList[cbcd->dwButtonId]->bIsServName)&&ptszQValue)
#ifdef _UNICODE
CallService(mir_u2a(ptszQValue),(WPARAM)cbcd->hContact,0);
#else
CallService(ptszQValue,(WPARAM)cbcd->hContact,0);
#endif
break;
case 2:
{
ButtonData * bd=NULL;
bd=(ButtonData *)sl->items[0];
if(bd&&bd->pszValue){
ptszQValue=ParseString(cbcd->hContact,bd->pszValue,pszText?pszText:_T(""),pszCBText?pszCBText:_T(""),(int)_tcslen(bd->pszValue),textlenght,pszCBText?(int)_tcslen(pszCBText):0);
if((bIsService=bd->bIsServName)&&ptszQValue)
#ifdef _UNICODE
CallService(mir_u2a(ptszQValue),(WPARAM)cbcd->hContact,0);
#else
CallService(ptszQValue,(WPARAM)cbcd->hContact,0);
#endif
}
}
break;
case 3:{
int res=0;
int menunum;
ButtonData * bd=NULL;
HMENU hMenu=NULL,hSubMenu=NULL;
BOOL bSetPopUpMark=FALSE;
if(g_iButtonsCount){
hMenu = CreatePopupMenu();
}
else break;
for(menunum=0;menunumrealCount;menunum++)
{
bd=(ButtonData *)sl->items[menunum];
if(bd->dwOPFlags&QMF_NEW)
continue;
bSetPopUpMark=FALSE;
if(bd->pszValue==0&&bd->fEntryType==0)
{
hSubMenu = CreatePopupMenu();
bSetPopUpMark=TRUE;
}
if(bd->pszValue&&bd->fEntryType==0)
hSubMenu=NULL;
if(bd->fEntryType&QMF_EX_SEPARATOR)
AppendMenu((HMENU)((hSubMenu&&!bSetPopUpMark)?hSubMenu:hMenu),MF_SEPARATOR,0,NULL);
else
AppendMenu((HMENU)((hSubMenu&&!bSetPopUpMark)?hSubMenu:hMenu),
MF_STRING|(bSetPopUpMark?MF_POPUP:0),
(bSetPopUpMark?(UINT_PTR)hSubMenu:(menunum+1)), bd->pszName);
}
res = TrackPopupMenu(hMenu, TPM_RETURNCMD, cbcd->pt.x, cbcd->pt.y, 0, cbcd->hwndFrom, NULL);
if(res==0) break;
bd= (ButtonData *)sl->items[res-1];
bCTRL=(GetKeyState(VK_CONTROL)&0x8000)?1:0;
if(bd->pszValue){
ptszQValue=ParseString(cbcd->hContact,bd->pszValue,pszText?pszText:_T(""),pszCBText?pszCBText:_T(""),(int)_tcslen(bd->pszValue),textlenght,pszCBText?(int)_tcslen(pszCBText):0);
if((bIsService=bd->bIsServName)&&ptszQValue)
#ifdef _UNICODE
CallService(mir_u2a(ptszQValue),(WPARAM)cbcd->hContact,0);
#else
CallService(ptszQValue,(WPARAM)cbcd->hContact,0);
#endif
}
}break;
}
if(ptszQValue){
if(!bIsService){
SendMessage(hEdit, EM_REPLACESEL, TRUE, (LPARAM)ptszQValue);
if((g_bLClickAuto&&state!=1)||(g_bRClickAuto&&state==1)||cbcd->flags&BBCF_CONTROLPRESSED||bCTRL)
SendMessage(cbcd->hwndFrom, WM_COMMAND,IDOK,0);
}
free(ptszQValue);
}
if(pszText) mir_free(pszText);
if(pszCBText) mir_free(pszCBText);
return 1;
}
static int PluginInit(WPARAM wparam,LPARAM lparam)
{
g_bStartup=1;
hEventDbOptionsInit=HookEvent(ME_OPT_INITIALISE,OptionsInit);
hEventCBButtonPressed=HookEvent(ME_MSG_BUTTONPRESSED,CustomButtonPressed);
hEventCBInit=HookEvent(ME_MSG_TOOLBARLOADED,RegisterCustomButton);
hEventInputMenu=HookEvent(ME_MSG_WINDOWPOPUP,InputMenuPopup);
g_bRClickAuto=DBGetContactSettingByte(NULL,PLGNAME,"RClickAuto",0);
g_bLClickAuto=DBGetContactSettingByte(NULL,PLGNAME,"LClickAuto",0);
g_iButtonsCount=DBGetContactSettingByte(NULL, PLGNAME,"ButtonsCount", 0);
g_bQuickMenu=DBGetContactSettingByte(NULL, PLGNAME,"QuickMenu", 1);
if(ServiceExists(MS_UPDATE_REGISTER)) {
char buffer[1024];
Update update = {0};
update.cbSize = sizeof(Update);
update.szComponentName = pluginInfo.shortName;
update.pbVersion = (BYTE *) CreateVersionString(pluginInfo.version, buffer);
update.cpbVersion = (int)strlen((char *) update.pbVersion);
//update.szUpdateURL = UPDATER_AUTOREGISTER;
update.szBetaVersionURL = QMESSAGES_VERSION_URL;
update.szBetaUpdateURL = QMESSAGES_UPDATE_URL;
update.pbBetaVersionPrefix = (BYTE *) QMESSAGES_VERSION_PREFIX;
update.cpbBetaVersionPrefix = (int)strlen(QMESSAGES_VERSION_PREFIX);
update.szBetaChangelogURL=QMESSAGES_CHAGELOG_URL;
CallService(MS_UPDATE_REGISTER, 0, (LPARAM) &update);
}
hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_QICON));
InitButtonsList();
g_bStartup=0;
return 0;
}
// {651EAD6E-00C6-47e4-94A3-C63789ED89F9}
static const MUUID interfaces[] = {{ 0x651ead6e, 0xc6, 0x47e4, { 0x94, 0xa3, 0xc6, 0x37, 0x89, 0xed, 0x89, 0xf9 } }, MIID_LAST};
const __declspec(dllexport) MUUID* MirandaPluginInterfaces(void){
return interfaces;}
__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
{
if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 0))
return NULL;
return &pluginInfo;
}
__declspec(dllexport)int Unload(void)
{
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinst,DWORD fdwReason,LPVOID lpvReserved)
{
hinstance=hinst;
return 1;
}
int __declspec(dllexport)Load(PLUGINLINK *link)
{
pluginLink=link;
mir_getMMI(&mmi);
mir_getLI(&li);
mir_getLP(&pluginInfoEx);
hEventDbPluginsLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,PluginInit);
hEventDbPreShutdown=HookEvent(ME_SYSTEM_PRESHUTDOWN,PreShutdown);
return 0;
}