/*
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 "stdafx.h"
CMPlugin g_plugin;
WNDPROC mainProc;
int g_iButtonsCount = 0;
int g_bStartup = 0;
BOOL g_bRClickAuto = 0;
BOOL g_bLClickAuto = 0;
BOOL g_bQuickMenu = 0;
/////////////////////////////////////////////////////////////////////////////////////////
PLUGININFOEX pluginInfoEx =
{
sizeof(PLUGININFOEX),
__PLUGIN_NAME,
PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
__DESCRIPTION,
__AUTHOR,
__COPYRIGHT,
__AUTHORWEB,
UNICODE_AWARE,
// {37ED754B-6CF9-40ED-9EB6-0FEF8E822475}
{ 0x37ed754b, 0x6cf9, 0x40ed, { 0x9e, 0xb6, 0xf, 0xef, 0x8e, 0x82, 0x24, 0x75 } }
};
CMPlugin::CMPlugin() :
PLUGIN(MODULENAME, pluginInfoEx)
{}
/////////////////////////////////////////////////////////////////////////////////////////
int PreShutdown(WPARAM, LPARAM)
{
DestructButtonsList();
return 0;
}
static int InputMenuPopup(WPARAM, LPARAM lParam)
{
HMENU hSubMenu = nullptr;
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, nullptr);
qsort(QuickList->items, QuickList->realCount, sizeof(QuickData *), sstQuickSortButtons);
for (i = 0; i < QuickList->realCount; i++) {
QuickData *qd = (QuickData*)QuickList->items[i];
if (qd->fEntryType & QMF_EX_SEPARATOR)
AppendMenu(hSubMenu, MF_SEPARATOR, 0, nullptr);
else
AppendMenu(hSubMenu, MF_STRING, qd->dwPos + 254, qd->ptszValueName);
}
}
else if (mwpd->uType == MSG_WINDOWPOPUP_SELECTED && mwpd->selection >= 254) {
for (i = 0; i < QuickList->realCount; i++) {
QuickData *qd = (QuickData *)QuickList->items[i];
if ((qd->dwPos + 254) == mwpd->selection) {
CHARRANGE cr;
UINT textlenght = 0;
ptrW pszText, pszCBText;
BOOL bIsService = 0;
wchar_t *ptszQValue = nullptr;
if (IsClipboardFormatAvailable(CF_TEXT)) {
if (OpenClipboard(mwpd->hwnd)) {
HANDLE hData = nullptr;
wchar_t* chBuffer = nullptr;
int textLength = 0;
hData = GetClipboardData(CF_UNICODETEXT);
chBuffer = (wchar_t*)GlobalLock(hData);
textLength = (int)mir_wstrlen(chBuffer);
pszCBText = mir_wstrdup(chBuffer);
GlobalUnlock(hData);
CloseClipboard();
}
}
SendMessage(mwpd->hwnd, EM_EXGETSEL, 0, (LPARAM)&cr);
textlenght = cr.cpMax - cr.cpMin;
if (textlenght) {
pszText = (wchar_t *)mir_alloc((textlenght + 10) * sizeof(wchar_t));
memset(pszText, 0, ((textlenght + 10) * sizeof(wchar_t)));
SendMessage(mwpd->hwnd, EM_GETSELTEXT, 0, (LPARAM)pszText);
}
if (qd->ptszValue) {
ptszQValue = ParseString(mwpd->hContact, qd->ptszValue, pszText ? pszText : L"", pszCBText ? pszCBText : L"", (int)mir_wstrlen(qd->ptszValue), textlenght, pszCBText ? (int)mir_wstrlen(pszCBText) : 0);
if ((bIsService = qd->bIsService) && ptszQValue)
CallService(mir_u2a(ptszQValue), (WPARAM)mwpd->hContact, 0);
}
if (ptszQValue) {
SendMessage(mwpd->hwnd, EM_REPLACESEL, TRUE, (LPARAM)ptszQValue);
free(ptszQValue);
}
break;
}
}
return 1;
}
return 0;
}
static int CustomButtonPressed(WPARAM, LPARAM lParam)
{
CustomButtonClickData *cbcd = (CustomButtonClickData *)lParam;
if (mir_strcmp(cbcd->pszModule, MODULENAME))
return 0;
if (!ButtonsList[cbcd->dwButtonId])
return 1;
SortedList *sl = ButtonsList[cbcd->dwButtonId]->sl;
if (!sl)
return 1;
BOOL bCTRL = 0;
BOOL bIsService = 0;
ptrW pszText, pszCBText;
wchar_t *ptszQValue = nullptr;
if (IsClipboardFormatAvailable(CF_TEXT)) {
if (OpenClipboard(cbcd->hwndFrom)) {
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
pszCBText = mir_wstrdup((wchar_t*)GlobalLock(hData));
GlobalUnlock(hData);
CloseClipboard();
}
}
qsort(sl->items, sl->realCount, sizeof(ButtonData *), sstSortButtons);
HWND hEdit = GetDlgItem(cbcd->hwndFrom, IDC_SRMM_MESSAGE);
CHARRANGE cr;
cr.cpMin = cr.cpMax = 0;
SendMessage(hEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
UINT textlenght = cr.cpMax - cr.cpMin;
if (textlenght) {
pszText = (wchar_t *)mir_alloc((textlenght + 10) * sizeof(wchar_t));
memset(pszText, 0, ((textlenght + 10) * sizeof(wchar_t)));
SendMessage(hEdit, EM_GETSELTEXT, 0, (LPARAM)pszText);
}
int state;
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 : L"", pszCBText ? pszCBText : L"", (int)mir_wstrlen(ButtonsList[cbcd->dwButtonId]->ptszQValue), textlenght, pszCBText ? (int)mir_wstrlen(pszCBText) : 0);
if ((bIsService = ButtonsList[cbcd->dwButtonId]->bIsServName) && ptszQValue)
CallService(mir_u2a(ptszQValue), (WPARAM)cbcd->hContact, 0);
break;
case 2:
{
ButtonData *bd = (ButtonData *)sl->items[0];
if (bd && bd->pszValue) {
ptszQValue = ParseString(cbcd->hContact, bd->pszValue, pszText ? pszText : L"", pszCBText ? pszCBText : L"", (int)mir_wstrlen(bd->pszValue), textlenght, pszCBText ? (int)mir_wstrlen(pszCBText) : 0);
if ((bIsService = bd->bIsServName) && ptszQValue)
CallService(mir_u2a(ptszQValue), (WPARAM)cbcd->hContact, 0);
}
}
break;
case 3:
if (!g_iButtonsCount)
break;
HMENU hMenu = CreatePopupMenu(), hSubMenu = nullptr;
for (int menunum = 0; menunum < sl->realCount; menunum++) {
ButtonData *bd = (ButtonData *)sl->items[menunum];
if (bd->dwOPFlags & QMF_NEW)
continue;
BOOL bSetPopupMark = FALSE;
if (bd->pszValue == nullptr && bd->fEntryType == 0) {
hSubMenu = CreatePopupMenu();
bSetPopupMark = TRUE;
}
if (bd->pszValue && bd->fEntryType == 0)
hSubMenu = nullptr;
if (bd->fEntryType & QMF_EX_SEPARATOR)
AppendMenu((HMENU)((hSubMenu && !bSetPopupMark) ? hSubMenu : hMenu), MF_SEPARATOR, 0, nullptr);
else
AppendMenu((HMENU)((hSubMenu && !bSetPopupMark) ? hSubMenu : hMenu),
MF_STRING | (bSetPopupMark ? MF_POPUP : 0),
(bSetPopupMark ? (UINT_PTR)hSubMenu : (menunum + 1)), bd->pszName);
}
int res = TrackPopupMenu(hMenu, TPM_RETURNCMD, cbcd->pt.x, cbcd->pt.y, 0, cbcd->hwndFrom, nullptr);
if (res == 0)
break;
ButtonData *bd = (ButtonData *)sl->items[res - 1];
bCTRL = (GetKeyState(VK_CONTROL) & 0x8000) ? 1 : 0;
if (bd->pszValue) {
ptszQValue = ParseString(cbcd->hContact, bd->pszValue, pszText ? pszText : L"", pszCBText ? pszCBText : L"", (int)mir_wstrlen(bd->pszValue), textlenght, pszCBText ? (int)mir_wstrlen(pszCBText) : 0);
if ((bIsService = bd->bIsServName) && ptszQValue)
CallService(mir_u2a(ptszQValue), (WPARAM)cbcd->hContact, 0);
}
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);
}
return 1;
}
static int PluginInit(WPARAM, LPARAM)
{
g_bStartup = 1;
HookEvent(ME_MSG_BUTTONPRESSED, CustomButtonPressed);
HookEvent(ME_MSG_WINDOWPOPUP, InputMenuPopup);
HookTemporaryEvent(ME_MSG_TOOLBARLOADED, RegisterCustomButton);
g_bRClickAuto = g_plugin.getByte("RClickAuto", 0);
g_bLClickAuto = g_plugin.getByte("LClickAuto", 0);
g_iButtonsCount = g_plugin.getByte("ButtonsCount", 0);
g_bQuickMenu = g_plugin.getByte("QuickMenu", 1);
InitButtonsList();
g_bStartup = 0;
return 0;
}
int CMPlugin::Load()
{
HookEvent(ME_SYSTEM_MODULESLOADED, PluginInit);
HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
HookEvent(ME_OPT_INITIALISE, OptionsInit);
return 0;
}