summaryrefslogtreecommitdiff
path: root/plugins/Popup/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /plugins/Popup/src
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Popup/src')
-rw-r--r--plugins/Popup/src/actions.cpp440
-rw-r--r--plugins/Popup/src/actions.h46
-rw-r--r--plugins/Popup/src/avatars.cpp60
-rw-r--r--plugins/Popup/src/avatars.h57
-rw-r--r--plugins/Popup/src/avatars_flash.cpp34
-rw-r--r--plugins/Popup/src/avatars_flash.h45
-rw-r--r--plugins/Popup/src/avatars_gif.cpp143
-rw-r--r--plugins/Popup/src/avatars_gif.h55
-rw-r--r--plugins/Popup/src/avatars_simple.cpp149
-rw-r--r--plugins/Popup/src/avatars_simple.h49
-rw-r--r--plugins/Popup/src/bitmap_funcs.cpp1019
-rw-r--r--plugins/Popup/src/bitmap_funcs.h132
-rw-r--r--plugins/Popup/src/common.h296
-rw-r--r--plugins/Popup/src/config.cpp210
-rw-r--r--plugins/Popup/src/config.h249
-rw-r--r--plugins/Popup/src/def_settings.h156
-rw-r--r--plugins/Popup/src/defs.h52
-rw-r--r--plugins/Popup/src/effects.cpp94
-rw-r--r--plugins/Popup/src/effects.h38
-rw-r--r--plugins/Popup/src/font.cpp154
-rw-r--r--plugins/Popup/src/font.h81
-rw-r--r--plugins/Popup/src/formula.cpp177
-rw-r--r--plugins/Popup/src/formula.h98
-rw-r--r--plugins/Popup/src/headers.cpp34
-rw-r--r--plugins/Popup/src/headers.h190
-rw-r--r--plugins/Popup/src/history.cpp550
-rw-r--r--plugins/Popup/src/history.h43
-rw-r--r--plugins/Popup/src/icons.cpp145
-rw-r--r--plugins/Popup/src/icons.h79
-rw-r--r--plugins/Popup/src/main.cpp743
-rw-r--r--plugins/Popup/src/notifications.cpp349
-rw-r--r--plugins/Popup/src/notifications.h73
-rw-r--r--plugins/Popup/src/opt_adv.cpp762
-rw-r--r--plugins/Popup/src/opt_adv.h45
-rw-r--r--plugins/Popup/src/opt_class.cpp603
-rw-r--r--plugins/Popup/src/opt_class.h41
-rw-r--r--plugins/Popup/src/opt_contacts.cpp175
-rw-r--r--plugins/Popup/src/opt_contacts.h46
-rw-r--r--plugins/Popup/src/opt_gen.cpp761
-rw-r--r--plugins/Popup/src/opt_gen.h43
-rw-r--r--plugins/Popup/src/opt_skins.cpp695
-rw-r--r--plugins/Popup/src/opt_skins.h46
-rw-r--r--plugins/Popup/src/opttree.cpp442
-rw-r--r--plugins/Popup/src/opttree.h57
-rw-r--r--plugins/Popup/src/popup_gdiplus.cpp223
-rw-r--r--plugins/Popup/src/popup_gdiplus.h42
-rw-r--r--plugins/Popup/src/popup_thread.cpp372
-rw-r--r--plugins/Popup/src/popup_thread.h52
-rw-r--r--plugins/Popup/src/popup_wnd2.cpp1945
-rw-r--r--plugins/Popup/src/popup_wnd2.h273
-rw-r--r--plugins/Popup/src/services.cpp675
-rw-r--r--plugins/Popup/src/services.h67
-rw-r--r--plugins/Popup/src/skin.cpp1518
-rw-r--r--plugins/Popup/src/skin.h203
-rw-r--r--plugins/Popup/src/srmm_menu.cpp171
-rw-r--r--plugins/Popup/src/srmm_menu.h39
56 files changed, 15336 insertions, 0 deletions
diff --git a/plugins/Popup/src/actions.cpp b/plugins/Popup/src/actions.cpp
new file mode 100644
index 0000000000..32ad120bcd
--- /dev/null
+++ b/plugins/Popup/src/actions.cpp
@@ -0,0 +1,440 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/actions.cpp $
+Revision : $Revision: 1622 $
+Last change on : $Date: 2010-06-23 23:32:21 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static int ActionsSortFunc(const POPUPACTION *p1, const POPUPACTION *p2)
+{
+ return lstrcmpA(p1->lpzTitle, p2->lpzTitle);
+}
+
+static LIST<POPUPACTION> gActions(3, ActionsSortFunc);
+
+// interface
+void LoadActions()
+{
+ POPUPACTION actions[] =
+ {
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_REPLY,0), "General/Quick reply", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_MESS,0), "General/Send message", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_INFO,0), "General/User details", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_MENU,0), "General/Contact menu", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_ADD,0), "General/Add permanently", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_PIN,0), "General/Pin popup", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_CLOSE,0), "General/Dismiss popup", 0},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_COPY,0), "General/Copy to clipboard", 0},
+
+//remove popup action
+ #if defined(_DEBUG)
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_POPUP_ON,0), "Popup Plus/Test action", PAF_ENABLED},
+ { sizeof(POPUPACTION), IcoLib_GetIcon(ICO_ACT_CLOSE,0), "Popup Plus/Second test action", 0},
+ { sizeof(POPUPACTION), LoadSkinnedIcon(SKINICON_OTHER_MIRANDA), "Popup Plus/One more action", PAF_ENABLED},
+ #endif
+
+ };
+
+ for (int i = 0; i < SIZEOF(actions); ++i)
+ RegisterAction(&actions[i]);
+}
+
+void UnloadActions()
+{
+// for (int i = 0; i < gActions.getCount(); ++i)
+// delete gActions[i];
+ gActions.destroy();
+}
+
+void RegisterAction(POPUPACTION *action)
+{
+ int index;
+ if ((index = gActions.getIndex(action)) >= 0)
+ {
+ DWORD flags = gActions[index]->flags;
+ *gActions[index] = *action;
+ gActions[index]->flags = flags;
+ } else
+ {
+ POPUPACTION *actionCopy = (POPUPACTION *)mir_alloc(sizeof(POPUPACTION));
+ *actionCopy = *action;
+ actionCopy->flags =
+ DBGetContactSettingByte(NULL, "PopUpActions", actionCopy->lpzTitle, actionCopy->flags & PAF_ENABLED) ?
+ PAF_ENABLED : 0;
+ gActions.insert(actionCopy);
+ }
+}
+
+bool IsActionEnabled(POPUPACTION *action)
+{
+ if (!(action->flags & PAF_ENABLED))
+ return false;
+
+ int index;
+ if ((index = gActions.getIndex(action)) >= 0)
+ if (!(gActions[index]->flags & PAF_ENABLED))
+ return false;
+
+ return true;
+}
+
+bool IsActionEnabled(char *name)
+{
+ POPUPACTION action = {0};
+ action.flags = PAF_ENABLED;
+ lstrcpyA(action.lpzTitle, name);
+ return IsActionEnabled(&action);
+}
+
+DWORD MouseOverride(HWND hCombo, int number)
+{
+ DWORD dwItem = 0;
+ DWORD ItemActive = 0;
+ if(number<0 || number >7)
+ number = 0;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("no overwrite"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 0);
+ if(number == 0)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("Send message"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 1);
+ if(number == 1)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("Quick reply"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 2);
+ if(number == 2)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("User details"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 3);
+ if(number == 3)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("Contact menu"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 4);
+ if(number == 4)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("Dismiss popup"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 5);
+ if(number == 5)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("Pin popup"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 6);
+ if(number == 6)
+ ItemActive = dwItem;
+ dwItem = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("Copy to clipboard"));
+ SendMessage(hCombo, CB_SETITEMDATA, dwItem, 7);
+ if(number == 7)
+ ItemActive = dwItem;
+ return ItemActive;
+}
+
+// options
+#if defined(_UNICODE)
+#define ListView_InsertItemW(hwnd, pitem) \
+ (int)SendMessageW((hwnd), LVM_INSERTITEMW, 0, (LPARAM)(const LVITEMW *)(pitem))
+#else
+#define ListView_InsertItemW(hwnd, pitem) \
+ (int)MySendMessageW((hwnd), LVM_INSERTITEMW, 0, (LPARAM)(const LVITEMW *)(pitem))
+#endif
+
+void LoadOption_Actions() {
+ PopUpOptions.actions = DBGetContactSettingDword(NULL, MODULNAME, "Actions",
+ ACT_ENABLE|ACT_RIGHTICONS|ACT_DEF_KEEPWND|ACT_DEF_IMONLY|
+ ACT_DEF_NOGLOBAL|ACT_DEF_MESSAGE|ACT_DEF_DETAILS|ACT_DEF_MENU|
+ ACT_DEF_ADD|ACT_DEF_DISMISS|ACT_DEF_PIN);
+ PopUpOptions.overrideLeft = DBGetContactSettingDword(NULL,MODULNAME, "OverrideLeft", 0);
+ PopUpOptions.overrideMiddle = DBGetContactSettingDword(NULL,MODULNAME, "OverrideMiddle", 0);
+ PopUpOptions.overrideRight = DBGetContactSettingDword(NULL,MODULNAME, "OverrideRight", 0);
+}
+
+INT_PTR CALLBACK DlgProcPopupActions(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static bool windowInitialized = false;
+
+ static UINT controls[] =
+ {
+ IDC_GRP_CUSTOMACTIONS,
+ IDC_TXT_CUSTOMACTIONS,
+ IDC_CHK_IMCONTACTSONLY,
+ IDC_CHK_CONTACTSONLY,
+ IDC_CHK_DONTCLOSE,
+ IDC_GRP_SIZEPOSITION,
+ IDC_CHK_LARGEICONS,
+ IDC_TXT_POSITION,
+ IDC_RD_TEXT,
+ IDC_RD_LEFTICONS,
+ IDC_RD_RIGHTICONS,
+ IDC_GRP_ACTIONS,
+ IDC_ACTIONS,
+ IDC_GRP_SIZEPOSITION2,
+ IDC_TXT_POSITION2,
+ IDC_CB_LEFT,
+ IDC_TXT_MIDDLE,
+ IDC_CB_MIDDLE,
+ IDC_TXT_RIGHT,
+ IDC_CB_RIGHT
+ };
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int i;
+ windowInitialized = false;
+
+ TranslateDialogDefault(hwnd);
+
+ SendMessage(GetDlgItem(hwnd, IDC_ICO_INFO), STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_MISC_NOTIFY,0), 0);
+
+ CheckDlgButton(hwnd, IDC_CHK_ENABLEACTIONS, PopUpOptions.actions&ACT_ENABLE ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_CHK_IMCONTACTSONLY, PopUpOptions.actions&ACT_DEF_IMONLY ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_CHK_CONTACTSONLY, PopUpOptions.actions&ACT_DEF_NOGLOBAL ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_CHK_DONTCLOSE, PopUpOptions.actions&ACT_DEF_KEEPWND ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_CHK_LARGEICONS, PopUpOptions.actions&ACT_LARGE ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_RD_TEXT, PopUpOptions.actions&ACT_TEXT ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_RD_LEFTICONS, PopUpOptions.actions&ACT_LEFTICONS ? TRUE : FALSE);
+ CheckDlgButton(hwnd, IDC_RD_RIGHTICONS, PopUpOptions.actions&ACT_RIGHTICONS ? TRUE : FALSE);
+
+ {
+ DWORD dwActiveItem = 0;
+ HWND hCombo = GetDlgItem(hwnd, IDC_CB_LEFT);
+ dwActiveItem = MouseOverride(hCombo, PopUpOptions.overrideLeft);
+ SendDlgItemMessage(hwnd, IDC_CB_LEFT, CB_SETCURSEL, dwActiveItem, 0);
+
+ dwActiveItem = 0;
+ hCombo = GetDlgItem(hwnd, IDC_CB_MIDDLE);
+ dwActiveItem = MouseOverride(hCombo, PopUpOptions.overrideMiddle);
+ SendDlgItemMessage(hwnd, IDC_CB_MIDDLE, CB_SETCURSEL, dwActiveItem, 0);
+
+ dwActiveItem = 0;
+ hCombo = GetDlgItem(hwnd, IDC_CB_RIGHT);
+ dwActiveItem = MouseOverride(hCombo, PopUpOptions.overrideRight);
+ SendDlgItemMessage(hwnd, IDC_CB_RIGHT, CB_SETCURSEL, dwActiveItem, 0);
+ }
+
+ HWND hwndList = GetDlgItem(hwnd, IDC_ACTIONS);
+ ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_CHECKBOXES|LVS_EX_LABELTIP);
+ HIMAGELIST hImgList = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 10, 1);
+ ListView_SetImageList(hwndList, hImgList, LVSIL_SMALL);
+
+ LVCOLUMN column = {0};
+ column.mask = LVCF_TEXT|LVCF_WIDTH;
+ column.pszText = TranslateT("Action");
+ column.cx = 175;
+ ListView_InsertColumn(hwndList, 0, &column);
+
+ if (IsWinVerXPPlus())
+ ListView_EnableGroupView(hwndList, TRUE);
+
+ LIST<char> groups(1, strcmp);
+
+ for (i = 0; i < gActions.getCount(); ++i)
+ {
+ char szGroup[64];
+ char *szName = strchr(gActions[i]->lpzTitle, '/');
+ if (!szName) szName = gActions[i]->lpzTitle;
+ else ++szName;
+ lstrcpynA(szGroup, gActions[i]->lpzTitle, szName - gActions[i]->lpzTitle);
+
+ int grpId = 0;
+
+ if (IsWinVerXPPlus() && ((grpId = groups.getIndex(szGroup)) < 0))
+ {
+ LVGROUP group = {0};
+ group.cbSize = sizeof(group);
+ group.mask = LVGF_HEADER|LVGF_GROUPID;
+ LPWSTR wszGroup = mir_a2u(szGroup);
+ group.pszHeader = TranslateW(wszGroup);
+ group.cchHeader = lstrlenW(wszGroup);
+ grpId = group.iGroupId = groups.getCount();
+ int grpId = ListView_InsertGroup(hwndList, -1, &group);
+ mir_free(wszGroup);
+ groups.insert(mir_strdup(szGroup), groups.getCount());
+ }
+
+ if (g_popup.isOsUnicode)
+ {
+ LVITEMW item = {0};
+ item.mask = LVIF_IMAGE|LVIF_PARAM|LVIF_TEXT|LVIF_STATE|LVIF_INDENT;
+ item.iItem = i;
+ LPWSTR wszName = mir_a2u(szName);
+ item.pszText = TranslateW(wszName);
+ item.iImage = ImageList_AddIcon(hImgList, gActions[i]->lchIcon);
+ item.lParam = i;
+ if (IsWinVerXPPlus())
+ {
+ item.mask |= LVIF_GROUPID;
+ item.iGroupId = grpId;
+ }
+ item.iIndent = 0;
+ ListView_InsertItemW(hwndList, &item);
+ mir_free(wszName);
+ } else
+ {
+ LVITEMA item = {0};
+ item.mask = LVIF_IMAGE|LVIF_PARAM|LVIF_TEXT|LVIF_STATE|LVIF_GROUPID|LVIF_INDENT;
+ item.iItem = i;
+ item.pszText = Translate(szName);
+ item.iImage = ImageList_AddIcon(hImgList, gActions[i]->lchIcon);
+ item.lParam = i;
+ item.iGroupId = grpId;
+ item.iIndent = 0;
+ ListView_InsertItem(hwndList, &item);
+ }
+
+ ListView_SetItemState(hwndList, i, (gActions[i]->flags & PAF_ENABLED) ? 0x2000 : 0x1000, LVIS_STATEIMAGEMASK);
+ }
+
+ groups.destroy();
+
+ BOOL enabled = (PopUpOptions.actions&ACT_ENABLE) ? TRUE : FALSE;
+ for (i = 0; i < SIZEOF(controls); ++i)
+ EnableWindow(GetDlgItem(hwnd, controls[i]), enabled);
+
+ windowInitialized = true;
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHK_ENABLEACTIONS:
+ {
+ PopUpOptions.actions &= ~ACT_ENABLE;
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_ENABLEACTIONS) ? ACT_ENABLE : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+
+ BOOL enabled = (PopUpOptions.actions&ACT_ENABLE) ? TRUE : FALSE;
+ for (int i = 0; i < SIZEOF(controls); ++i)
+ EnableWindow(GetDlgItem(hwnd, controls[i]), enabled);
+ break;
+ }
+
+ case IDC_CHK_IMCONTACTSONLY:
+ PopUpOptions.actions &= ~ACT_DEF_IMONLY;
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_IMCONTACTSONLY) ? ACT_DEF_IMONLY : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_CHK_CONTACTSONLY:
+ PopUpOptions.actions &= ~ACT_DEF_NOGLOBAL;
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_CONTACTSONLY) ? ACT_DEF_NOGLOBAL : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_CHK_DONTCLOSE:
+ PopUpOptions.actions &= ~ACT_DEF_KEEPWND;
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_DONTCLOSE) ? ACT_DEF_KEEPWND : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_CHK_LARGEICONS:
+ PopUpOptions.actions &= ~ACT_LARGE;
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_LARGEICONS) ? ACT_LARGE : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_RD_TEXT:
+ PopUpOptions.actions &= ~(ACT_TEXT|ACT_LEFTICONS|ACT_RIGHTICONS);
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_ENABLEACTIONS) ? ACT_TEXT : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_RD_LEFTICONS:
+ PopUpOptions.actions &= ~(ACT_TEXT|ACT_LEFTICONS|ACT_RIGHTICONS);
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_RD_LEFTICONS) ? ACT_LEFTICONS : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_RD_RIGHTICONS:
+ PopUpOptions.actions &= ~(ACT_TEXT|ACT_LEFTICONS|ACT_RIGHTICONS);
+ PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_RD_RIGHTICONS) ? ACT_RIGHTICONS : 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ case IDC_PREVIEW:
+ PopUpPreview();
+ break;
+ case IDC_CB_LEFT:
+ case IDC_CB_MIDDLE:
+ case IDC_CB_RIGHT:
+ PopUpOptions.overrideLeft = SendDlgItemMessage(hwnd, IDC_CB_LEFT, CB_GETITEMDATA,
+ SendDlgItemMessage(hwnd, IDC_CB_LEFT, CB_GETCURSEL,0,0),0);
+ PopUpOptions.overrideMiddle = SendDlgItemMessage(hwnd, IDC_CB_MIDDLE, CB_GETITEMDATA,
+ SendDlgItemMessage(hwnd, IDC_CB_MIDDLE, CB_GETCURSEL,0,0),0);
+ PopUpOptions.overrideRight = SendDlgItemMessage(hwnd, IDC_CB_RIGHT, CB_GETITEMDATA,
+ SendDlgItemMessage(hwnd, IDC_CB_RIGHT, CB_GETCURSEL,0,0),0);
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ break;
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_RESET:
+ LoadOption_Actions();
+ break;
+ case PSN_APPLY:
+ {
+ DBWriteContactSettingDword(NULL, MODULNAME, "Actions", PopUpOptions.actions);
+ HWND hwndList = GetDlgItem(hwnd, IDC_ACTIONS);
+ for (int i = 0; i < gActions.getCount(); ++i)
+ {
+ gActions[i]->flags = (ListView_GetItemState(hwndList, i, LVIS_STATEIMAGEMASK) == 0x2000) ? PAF_ENABLED : 0;
+ DBWriteContactSettingByte(NULL, "PopUpActions", gActions[i]->lpzTitle, (gActions[i]->flags&PAF_ENABLED) ? 1 : 0);
+ }
+ //overrideActions
+ DBWriteContactSettingDword(NULL, MODULNAME, "OverrideLeft", PopUpOptions.overrideLeft);
+ DBWriteContactSettingDword(NULL, MODULNAME, "OverrideMiddle", PopUpOptions.overrideMiddle);
+ DBWriteContactSettingDword(NULL, MODULNAME, "OverrideRight", PopUpOptions.overrideRight);
+ break;
+ }
+ }
+ break;
+ }
+
+ case IDC_ACTIONS:
+ {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+ if (windowInitialized &&
+ nmlv && nmlv->hdr.code == LVN_ITEMCHANGED && nmlv->uOldState != 0 &&
+ (nmlv->uNewState == 0x1000 || nmlv->uNewState == 0x2000))
+ {
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ }
+ return FALSE;
+}
diff --git a/plugins/Popup/src/actions.h b/plugins/Popup/src/actions.h
new file mode 100644
index 0000000000..7938f1ea92
--- /dev/null
+++ b/plugins/Popup/src/actions.h
@@ -0,0 +1,46 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/actions.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __actions_h__
+#define __actions_h__
+
+void LoadActions();
+void UnloadActions();
+
+void RegisterAction(POPUPACTION *action);
+bool IsActionEnabled(POPUPACTION *action);
+bool IsActionEnabled(char *name);
+
+void LoadOption_Actions();
+INT_PTR CALLBACK DlgProcPopupActions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#endif // __actions_h__
diff --git a/plugins/Popup/src/avatars.cpp b/plugins/Popup/src/avatars.cpp
new file mode 100644
index 0000000000..68fbac58bb
--- /dev/null
+++ b/plugins/Popup/src/avatars.cpp
@@ -0,0 +1,60 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright � 2002 Luca Santarelli,
+ � 2004-2007 Victor Pavlychko
+ � 2010 MPK
+ � 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+PopupAvatar *PopupAvatar::create(HANDLE hContact)
+{
+ if (hContact)
+ {
+ if (ServiceExists(MS_AV_GETAVATARBITMAP))
+ {
+ avatarCacheEntry *av = (avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)hContact, 0);
+// MessageBox(NULL, _T("00"), _T(MODULNAME_LONG), MB_OK);
+ if (av && (_tcslen(av->szFilename) > 4))
+ {
+// MessageBox(NULL, _T("01"), _T(MODULNAME_LONG), MB_OK);
+ if (!_tcsicmp(av->szFilename+_tcslen(av->szFilename)-4, _T(".gif")))
+ {
+// MessageBox(NULL, _T("02"), _T(MODULNAME_LONG), MB_OK);
+ if (DBGetContactSettingByte(NULL, MODULNAME, "EnableGifAnimation", 1) && GDIPlus_IsAnimatedGIF(av->szFilename))
+ {
+// MessageBox(NULL, _T("03"), _T(MODULNAME_LONG), MB_OK);
+ return new GifAvatar(hContact);
+ }
+ }
+ }
+ }
+ }
+
+ return new SimpleAvatar(hContact);
+}
diff --git a/plugins/Popup/src/avatars.h b/plugins/Popup/src/avatars.h
new file mode 100644
index 0000000000..77d2461fe0
--- /dev/null
+++ b/plugins/Popup/src/avatars.h
@@ -0,0 +1,57 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __avatars_h__
+#define __avatars_h__
+
+class PopupAvatar
+{
+protected:
+ int width, height;
+ bool bIsAnimated, bIsValid;
+
+public:
+ PopupAvatar(HANDLE hContact) {}
+ virtual ~PopupAvatar() {}
+ virtual int activeFrameDelay() = 0;
+ virtual void draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options) = 0;
+
+ inline bool isValid() { return bIsValid; }
+ inline void invalidate() { bIsValid = false; }
+ inline bool isAnimated() { return bIsAnimated; }
+ inline int getWidth() { return width; }
+ inline int getHeight() { return height; }
+
+ static PopupAvatar *create(HANDLE hContact);
+};
+
+#endif // __avatars_h__
diff --git a/plugins/Popup/src/avatars_flash.cpp b/plugins/Popup/src/avatars_flash.cpp
new file mode 100644
index 0000000000..2cd95e2a8d
--- /dev/null
+++ b/plugins/Popup/src/avatars_flash.cpp
@@ -0,0 +1,34 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars_flash.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
diff --git a/plugins/Popup/src/avatars_flash.h b/plugins/Popup/src/avatars_flash.h
new file mode 100644
index 0000000000..9c5483064d
--- /dev/null
+++ b/plugins/Popup/src/avatars_flash.h
@@ -0,0 +1,45 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars_flash.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __avatars_flash_h__
+#define __avatars_flash_h__
+
+class FlashAvatar: public PopupAvatar
+{
+public:
+ FlashAvatar(HANDLE hContact);
+ virtual ~FlashAvatar();
+ virtual int activeFrameDelay() = 0;
+ virtual void draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options) = 0;
+};
+
+#endif // __avatars_flash_h__
diff --git a/plugins/Popup/src/avatars_gif.cpp b/plugins/Popup/src/avatars_gif.cpp
new file mode 100644
index 0000000000..24ee798e93
--- /dev/null
+++ b/plugins/Popup/src/avatars_gif.cpp
@@ -0,0 +1,143 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars_gif.cpp $
+Revision : $Revision: 1624 $
+Last change on : $Date: 2010-06-24 19:39:34 +0300 (Чт, 24 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+GifAvatar::GifAvatar(HANDLE hContact): PopupAvatar(hContact)
+{
+ av = (avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)hContact, 0);
+ bIsAnimated = true;
+ bIsValid = true;
+ GDIPlus_GetGIFSize(av->szFilename, &this->width, &this->height);
+
+ hBitmap = NULL;
+ frameDelays = NULL;
+ frameCount = 0;
+ frameSize.cx = frameSize.cy = 0;
+
+ cachedHeight = cachedWidth = -1;
+
+ activeFrame = 0;
+}
+
+GifAvatar::~GifAvatar()
+{
+ if (frameDelays) {
+ mir_free(frameDelays);
+ frameDelays = NULL;
+ }
+ if (hBitmap) DeleteObject(hBitmap);
+}
+
+int GifAvatar::activeFrameDelay()
+{
+ if (!av || !frameCount || !frameDelays || !hBitmap || (activeFrame < 0) || (activeFrame >= frameCount))
+ return -1;
+ return frameDelays[activeFrame];
+}
+
+void GifAvatar::draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options)
+{
+ if (!av || (w <= 0) || (h <= 0)) return;
+
+ if (!frameCount || !frameDelays || !hBitmap || (cachedWidth != w) || (cachedHeight != h))
+ {
+ cachedWidth = w;
+ cachedHeight = h;
+ if (frameDelays) {
+ mir_free(frameDelays);
+ frameDelays = NULL;
+ }
+ if (hBitmap) DeleteObject(hBitmap);
+ GDIPlus_ExtractAnimatedGIF(av->szFilename, w, h, &hBitmap, &frameDelays, &frameCount, &frameSize);
+ }
+
+ if (!frameCount) return;
+
+ HRGN rgn;
+ if (options->avatarRadius)
+ {
+ rgn = CreateRoundRectRgn(x, y, x+w, y+h, 2 * options->avatarRadius, 2 * options->avatarRadius);
+ SelectClipRgn(bmp->getDC(), rgn);
+ } else
+ {
+ rgn = CreateRectRgn(x, y, x+w, y+h);
+ }
+
+ HDC hdcTmp = CreateCompatibleDC(bmp->getDC());
+ SelectObject(hdcTmp, hBitmap);
+ SetStretchBltMode(bmp->getDC(), HALFTONE);
+
+#if defined(_UNICODE)
+ if (av->dwFlags & AVS_PREMULTIPLIED)
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, bf);
+#else
+ if (MyAlphaBlend && (av->dwFlags & AVS_PREMULTIPLIED))
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ MyAlphaBlend(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, bf);
+#endif
+ if (options->avatarBorders && options->avatarPNGBorders)
+ {
+ HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder);
+ bmp->saveAlpha(x, y, w, h);
+ FrameRgn(bmp->getDC(), rgn, hbr, 1, 1);
+ DeleteObject(hbr);
+ bmp->restoreAlpha(x, y, w, h);
+ }
+ }
+ else {
+ bmp->saveAlpha(x, y, w, h);
+ StretchBlt(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, SRCCOPY);
+ if (options->avatarBorders) {
+ HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder);
+ FrameRgn(bmp->getDC(), rgn, hbr, 1, 1);
+ DeleteObject(hbr);
+ }
+ bmp->restoreAlpha(x, y, w, h);
+ }
+ DeleteObject(rgn);
+ SelectClipRgn(bmp->getDC(), NULL);
+ DeleteDC(hdcTmp);
+
+ activeFrame = (activeFrame + 1) % frameCount;
+}
diff --git a/plugins/Popup/src/avatars_gif.h b/plugins/Popup/src/avatars_gif.h
new file mode 100644
index 0000000000..e7ec9057e3
--- /dev/null
+++ b/plugins/Popup/src/avatars_gif.h
@@ -0,0 +1,55 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars_gif.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __avatars_gif_h__
+#define __avatars_gif_h__
+
+class GifAvatar: public PopupAvatar
+{
+protected:
+ avatarCacheEntry *av;
+ int cachedWidth, cachedHeight;
+ int activeFrame;
+
+ HBITMAP hBitmap;
+ int *frameDelays;
+ int frameCount;
+ SIZE frameSize;
+
+public:
+ GifAvatar(HANDLE hContact);
+ virtual ~GifAvatar();
+ virtual int activeFrameDelay();
+ virtual void draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options);
+};
+
+#endif // __avatars_gif_h__
diff --git a/plugins/Popup/src/avatars_simple.cpp b/plugins/Popup/src/avatars_simple.cpp
new file mode 100644
index 0000000000..2c3b3341cb
--- /dev/null
+++ b/plugins/Popup/src/avatars_simple.cpp
@@ -0,0 +1,149 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars_simple.cpp $
+Revision : $Revision: 1624 $
+Last change on : $Date: 2010-06-24 19:39:34 +0300 (Чт, 24 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+SimpleAvatar::SimpleAvatar(HANDLE hContact, bool bUseBitmap): PopupAvatar(bUseBitmap ? 0 : hContact)
+{
+ bIsAnimated = false;
+ bIsValid = true;
+
+ if (bUseBitmap)
+ {
+ BITMAP bmp;
+ GetObject((HBITMAP)hContact, sizeof(bmp), &bmp);
+ width = abs(bmp.bmWidth);
+ height = abs(bmp.bmHeight);
+
+ avNeedFree = true;
+ av = new avatarCacheEntry;
+ av->bmHeight = abs(bmp.bmHeight);
+ av->bmWidth = abs(bmp.bmWidth);
+ av->hbmPic = (HBITMAP)hContact;
+ av->dwFlags = AVS_BITMAP_VALID;
+ return;
+ }
+
+ if (hContact && ServiceExists(MS_AV_GETAVATARBITMAP))
+ {
+ avNeedFree = false;
+ av = (avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)hContact, 0);
+ if (av)
+ {
+ if (av->hbmPic && (av->dwFlags&AVS_BITMAP_VALID) && !(av->dwFlags&AVS_HIDEONCLIST) && !(av->dwFlags&AVS_NOTREADY))
+ {
+ width = av->bmWidth;
+ height = av->bmHeight;
+ return;
+ }
+
+ if (av->dwFlags&AVS_NOTREADY)
+ bIsValid = false;
+ }
+ }
+
+ width = height = 0;
+ av = NULL;
+ avNeedFree = false;
+}
+
+SimpleAvatar::~SimpleAvatar()
+{
+ if (avNeedFree) delete av;
+}
+
+int SimpleAvatar::activeFrameDelay()
+{
+ return -1;
+}
+
+void SimpleAvatar::draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options)
+{
+ if (!av) return;
+
+ HRGN rgn;
+ if (options->avatarRadius)
+ {
+ rgn = CreateRoundRectRgn(x, y, x+w, y+h, 2 * options->avatarRadius, 2 * options->avatarRadius);
+ SelectClipRgn(bmp->getDC(), rgn);
+ } else
+ {
+ rgn = CreateRectRgn(x, y, x+w, y+h);
+ }
+
+ HDC hdcTmp = CreateCompatibleDC(bmp->getDC());
+ SelectObject(hdcTmp, av->hbmPic);
+ SetStretchBltMode(bmp->getDC(), HALFTONE);
+
+#if defined(_UNICODE)
+ if (av->dwFlags & AVS_HASTRANSPARENCY)
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(bmp->getDC(), x, y, w, h, hdcTmp, 0, 0, av->bmWidth, av->bmHeight, bf);
+#else
+// if (MyAlphaBlend && (av->dwFlags & AVS_PREMULTIPLIED))
+ if (MyAlphaBlend && (av->dwFlags & AVS_HASTRANSPARENCY))
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ MyAlphaBlend(bmp->getDC(), x, y, w, h, hdcTmp, 0, 0, av->bmWidth, av->bmHeight, bf);
+#endif
+ if (options->avatarBorders && options->avatarPNGBorders)
+ {
+ HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder);
+ bmp->saveAlpha(x, y, w, h);
+ FrameRgn(bmp->getDC(), rgn, hbr, 1, 1);
+ DeleteObject(hbr);
+ bmp->restoreAlpha(x, y, w, h);
+ }
+ }
+ else {
+ bmp->saveAlpha(x, y, w, h);
+ StretchBlt(bmp->getDC(), x, y, w, h, hdcTmp, 0, 0, av->bmWidth, av->bmHeight, SRCCOPY);
+ if (options->avatarBorders){
+ HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder);
+ FrameRgn(bmp->getDC(), rgn, hbr, 1, 1);
+ DeleteObject(hbr);
+ }
+ bmp->restoreAlpha(x, y, w, h);
+ }
+ DeleteObject(rgn);
+ SelectClipRgn(bmp->getDC(), NULL);
+ DeleteDC(hdcTmp);
+}
diff --git a/plugins/Popup/src/avatars_simple.h b/plugins/Popup/src/avatars_simple.h
new file mode 100644
index 0000000000..5cc8037a58
--- /dev/null
+++ b/plugins/Popup/src/avatars_simple.h
@@ -0,0 +1,49 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/avatars_simple.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __avatars_simple_h__
+#define __avatars_simple_h__
+
+class SimpleAvatar: public PopupAvatar
+{
+private:
+ avatarCacheEntry *av;
+ bool avNeedFree;
+
+public:
+ SimpleAvatar(HANDLE hContact, bool bUseBitmap = false);
+ virtual ~SimpleAvatar();
+ virtual int activeFrameDelay();
+ virtual void draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options);
+};
+
+#endif // __avatars_simple_h__
diff --git a/plugins/Popup/src/bitmap_funcs.cpp b/plugins/Popup/src/bitmap_funcs.cpp
new file mode 100644
index 0000000000..4cb013a378
--- /dev/null
+++ b/plugins/Popup/src/bitmap_funcs.cpp
@@ -0,0 +1,1019 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/bitmap_funcs.cpp $
+Revision : $Revision: 1627 $
+Last change on : $Date: 2010-06-29 10:34:46 +0300 (Вт, 29 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+#include "bitmap_funcs.h"
+
+#define PU_BMP_ACCURATE_ARITHMETICS
+
+#ifdef PU_BMP_ACCURATE_ARITHMETICS
+ #define PU_DIV255(x) ((x)/255)
+ #define PU_DIV128(x) ((x)/128)
+ typedef float pu_koef;
+#else
+ #define PU_DIV255(x) ((x)>>8)
+ #define PU_DIV128(x) ((x)>>7)
+ typedef long pu_koef;
+#endif
+
+MyBitmap::MyBitmap()
+{
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+ bitsSave = 0;
+}
+
+MyBitmap::MyBitmap(int w, int h)
+{
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+ bitsSave = 0;
+ allocate(w,h);
+}
+
+MyBitmap::MyBitmap(const char *fn, const char *fnAlpha)
+{
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+ bitsSave = 0;
+ loadFromFile(fn, fnAlpha);
+}
+
+MyBitmap::~MyBitmap()
+{
+ if (bitsSave)
+ delete [] bitsSave;
+ free();
+}
+
+void MyBitmap::makeOpaque()
+{
+ if (!bits) return;
+
+ GdiFlush();
+ for (int i = 0; i < width*height; i++)
+ bits[i] |= 0xff000000;
+}
+
+void MyBitmap::makeOpaqueRect(int x1, int y1, int x2, int y2)
+{
+ if (!bits) return;
+
+ GdiFlush();
+ for (int i = y1; i < y2; i++)
+ for (int j = x1; j < x2; j++)
+ {
+ int idx = i * width + j;
+ bits[idx] |= 0xff000000;
+ }
+}
+
+void MyBitmap::saveAlpha(int x, int y, int w, int h)
+{
+ if (bitsSave)
+ delete [] bitsSave;
+
+ GdiFlush();
+
+ if (!w) w = width;
+ if (!h) h = height;
+ if (!w || !h)
+ return;
+ if (x < 0 || y < 0)
+ return;
+
+ bitsSave = new COLOR32[w*h];
+ COLOR32 *p1 = bitsSave;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ COLOR32 *p2 = bits + (y+i)*width + x;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ *p1++ = *p2++;
+ }
+ }
+}
+
+void MyBitmap::restoreAlpha(int x, int y, int w, int h)
+{
+ if (!bitsSave)
+ return;
+
+ GdiFlush();
+
+ if (!w) w = width;
+ if (!h) h = height;
+
+ COLOR32 *p1 = bitsSave;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ COLOR32 *p2 = bits + (y+i)*width + x;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ if ((*p1&0x00ffffff) != (*p2&0x00ffffff))
+ {
+ *p2 |= 0xff000000;
+ } else
+ {
+ *p2 = (*p2&0x00ffffff) | (*p1&0xff000000);
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+
+ delete [] bitsSave;
+ bitsSave = 0;
+}
+
+void MyBitmap::DrawBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h)
+{
+ if (!(bits && inbits)) return;
+
+ GdiFlush();
+
+ float kx = (float)inw / w;
+ float ky = (float)inh / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = inbits[int(i*ky)*inw + int(j*kx)];
+ }
+ }
+}
+
+void MyBitmap::BlendBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h)
+{
+ if (!(bits && inbits)) return;
+
+ GdiFlush();
+
+ float kx = (float)inw / w;
+ float ky = (float)inh / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ COLOR32 src = inbits[int(i*ky)*inw + int(j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+ }
+ }
+}
+
+void MyBitmap::Blend(MyBitmap *bmp, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ COLOR32 src = bmp->bits[int(i*ky)*bmp->width + int(j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+ }
+ }
+}
+
+void MyBitmap::Draw(MyBitmap *bmp, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+
+ if (!x && !y && (w == width) && (h == height) && (w == bmp->width) && (h == bmp->height))
+ {
+ // fast bitmap copy is possible good for animated avatars
+ CopyMemory(bits, bmp->bits, width*height*sizeof(COLOR32));
+ return;
+ }
+
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = bmp->bits[int(i*ky)*bmp->width + int(j*kx)];
+ }
+ }
+}
+
+void MyBitmap::BlendColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ // we should swap B and R channels when working with win32 COLORREF
+ float koef1r = (255 - getb(color)) / 128.0;
+ float koef1g = (255 - getg(color)) / 128.0;
+ float koef1b = (255 - getr(color)) / 128.0;
+
+ int br = - 255 + 2 * getb(color);
+ int bg = - 255 + 2 * getg(color);
+ int bb = - 255 + 2 * getr(color);
+
+ float koef2r = (getb(color)) / 128.0;
+ float koef2g = (getg(color)) / 128.0;
+ float koef2b = (getr(color)) / 128.0;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// bits[(i+y)*width + (j+x)] = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]));
+
+ long alpha = geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+ COLOR32 cl = alpha ? getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])*255/alpha : 0;
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ COLOR32 src = (cl > 128) ?
+ rgba(
+ PU_DIV255((koef1r * cl + br)*alpha),
+ PU_DIV255((koef1g * cl + bg)*alpha),
+ PU_DIV255((koef1b * cl + bb)*alpha),
+ alpha):
+ rgba(
+ PU_DIV255(koef2r * cl * alpha),
+ PU_DIV255(koef2g * cl * alpha),
+ PU_DIV255(koef2b * cl * alpha),
+ alpha);
+#pragma warning(pop)
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 src = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, alpha):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, alpha);
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+// long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+
+ }
+ }
+}
+
+void MyBitmap::DrawColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ // we should swap B and R channels when working with win32 COLORREF
+ float koef1r = (255 - getb(color)) / 128.0;
+ float koef1g = (255 - getg(color)) / 128.0;
+ float koef1b = (255 - getr(color)) / 128.0;
+
+ int br = - 255 + 2 * getb(color);
+ int bg = - 255 + 2 * getg(color);
+ int bb = - 255 + 2 * getr(color);
+
+ float koef2r = (getb(color)) / 128.0;
+ float koef2g = (getg(color)) / 128.0;
+ float koef2b = (getr(color)) / 128.0;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+
+ long alpha = geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+ COLOR32 cl = alpha ? getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])*255/alpha : 0;
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ bits[(i+y)*width + (j+x)] = (cl > 128) ?
+ rgba(
+ PU_DIV255((koef1r * cl + br)*alpha),
+ PU_DIV255((koef1g * cl + bg)*alpha),
+ PU_DIV255((koef1b * cl + bb)*alpha),
+ alpha):
+ rgba(
+ PU_DIV255(koef2r * cl * alpha),
+ PU_DIV255(koef2g * cl * alpha),
+ PU_DIV255(koef2b * cl * alpha),
+ alpha);
+#pragma warning(pop)
+// bits[(i+y)*width + (j+x)] = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]));
+ }
+ }
+}
+
+void MyBitmap::BlendPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+ if (!win || !hin) return;
+
+ GdiFlush();
+
+ if (!w) w = win;
+ if (!h) h = hin;
+ float kx = (float)win / w;
+ float ky = (float)hin / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ COLOR32 src = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+// bits[(i+y)*width + (j+x)] = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ }
+ }
+}
+
+void MyBitmap::BlendPartColorized(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h, COLOR32 color)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+ if (!win || !hin) return;
+
+ GdiFlush();
+
+ if (!w) w = win;
+ if (!h) h = hin;
+ float kx = (float)win / w;
+ float ky = (float)hin / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ // we should swap B and R channels when working with win32 COLORREF
+ float koef1r = (255 - getb(color)) / 128.0;
+ float koef1g = (255 - getg(color)) / 128.0;
+ float koef1b = (255 - getr(color)) / 128.0;
+
+ int br = - 255 + 2 * getb(color);
+ int bg = - 255 + 2 * getg(color);
+ int bb = - 255 + 2 * getr(color);
+
+ float koef2r = (getb(color)) / 128.0;
+ float koef2g = (getg(color)) / 128.0;
+ float koef2b = (getr(color)) / 128.0;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+
+ long alpha = geta(bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)]);
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+ COLOR32 cl = alpha ? getr(bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)])*255/alpha : 0;
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ COLOR32 src = (cl > 128) ?
+ rgba(
+ PU_DIV255((koef1r * cl + br)*alpha),
+ PU_DIV255((koef1g * cl + bg)*alpha),
+ PU_DIV255((koef1b * cl + bb)*alpha),
+ alpha):
+ rgba(
+ PU_DIV255(koef2r * cl * alpha),
+ PU_DIV255(koef2g * cl * alpha),
+ PU_DIV255(koef2b * cl * alpha),
+ alpha);
+#pragma warning(pop)
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 src = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, alpha):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, alpha);
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+// long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+
+/* COLOR32 src = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+(255-alpha)*getr(dst)/255,
+ getg(src)+(255-alpha)*getg(dst)/255,
+ getb(src)+(255-alpha)*getb(dst)/255,
+ geta(src)+(255-alpha)*geta(dst)/255
+ );*/
+// bits[(i+y)*width + (j+x)] = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ }
+ }
+}
+
+void MyBitmap::DrawPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+ if (!win || !hin) return;
+
+ GdiFlush();
+
+ if (!w) w = win;
+ if (!h) h = hin;
+ float kx = (float)win / w;
+ float ky = (float)hin / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ }
+ }
+}
+
+void MyBitmap::DrawNoAlpha(MyBitmap *bmp, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ for (int i = 0; i < bmp->height; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < bmp->width; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = bmp->bits[i*bmp->width + j];
+ }
+ }
+}
+
+void MyBitmap::DrawIcon(HICON hic, int x, int y, int w, int h)
+{
+ GdiFlush();
+
+ ICONINFO info;
+ GetIconInfo(hic, &info);
+
+ BITMAP bmpColor, bmpMask;
+ GetObject(info.hbmMask, sizeof(bmpMask), &bmpMask);
+ GetObject(info.hbmColor, sizeof(bmpColor), &bmpColor);
+
+ if (!w) w = abs(bmpMask.bmWidth);
+ if (!h) h = abs(bmpMask.bmHeight);
+
+ if (bmpColor.bmBitsPixel == 32)
+ {
+ if ((w != abs(bmpMask.bmWidth)) || (h != abs(bmpMask.bmHeight)))
+ {
+ DeleteObject(info.hbmColor);
+ DeleteObject(info.hbmMask);
+ HICON hicTmp = (HICON)CopyImage(hic,IMAGE_ICON,w,h,LR_COPYFROMRESOURCE);
+ GetIconInfo(hicTmp, &info);
+ GetObject(info.hbmMask, sizeof(bmpMask), &bmpMask);
+ GetObject(info.hbmColor, sizeof(bmpColor), &bmpColor);
+ DestroyIcon(hicTmp);
+ }
+
+ BYTE *cbit = new BYTE[bmpColor.bmWidthBytes*bmpColor.bmHeight];
+ BYTE *mbit = new BYTE[bmpMask.bmWidthBytes*bmpMask.bmHeight];
+ GetBitmapBits(info.hbmColor, bmpColor.bmWidthBytes*bmpColor.bmHeight, cbit);
+ GetBitmapBits(info.hbmMask, bmpMask.bmWidthBytes*bmpMask.bmHeight, mbit);
+
+ for (int i = 0; i < bmpColor.bmHeight; i++)
+ {
+ for (int j = 0; j < bmpColor.bmWidth; j++)
+ {
+ BYTE *pixel = cbit + i*bmpColor.bmWidthBytes + j*4;
+ if (!pixel[3])
+ {
+ pixel[3] = (*(mbit + i*bmpMask.bmWidthBytes + j*bmpMask.bmBitsPixel/8) & (1<<(7-j%8))) ? 0 : 255;
+ }
+
+ if (pixel[3] != 255)
+ {
+ pixel[0] = PU_DIV255(pixel[0] * pixel[3]);
+ pixel[1] = PU_DIV255(pixel[1] * pixel[3]);
+ pixel[2] = PU_DIV255(pixel[2] * pixel[3]);
+ }
+ }
+ }
+
+ this->BlendBits((COLOR32 *)cbit, bmpColor.bmWidth, bmpColor.bmHeight, x, y, w, h);
+
+ delete [] mbit;
+ delete [] cbit;
+ } else
+ {
+ this->saveAlpha(x,y,w,h);
+ DrawIconEx(this->getDC(), x, y, hic, w, h, 0, NULL, DI_NORMAL);
+ this->restoreAlpha(x,y,w,h);
+ }
+
+ DeleteObject(info.hbmColor);
+ DeleteObject(info.hbmMask);
+}
+
+void MyBitmap::Draw_TextA(char *str, int x, int y)
+{
+ GdiFlush();
+
+ SIZE sz; GetTextExtentPoint32A(this->getDC(), str, lstrlenA(str), &sz);
+ RECT rc; SetRect(&rc, x, y, x+10000, y+10000);
+ this->saveAlpha(x-2,y-2,sz.cx+2,sz.cy+2);
+ ::DrawTextA(this->getDC(), str, (int)strlen(str), &rc, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOPREFIX);
+ this->restoreAlpha(x-2,y-2,sz.cx+2,sz.cy+2);
+ //(x,y,sz.cx,sz.cy);
+}
+
+void MyBitmap::Draw_TextW(WCHAR *str, int x, int y)
+{
+#if defined(_UNICODE)
+ SIZE sz; GetTextExtentPoint32W(this->getDC(), str, lstrlenW(str), &sz);
+ RECT rc; SetRect(&rc, x, y, x+10000, y+10000);
+ this->saveAlpha(x,y,sz.cx,sz.cy);
+ DrawTextW(this->getDC(), str, lstrlenW(str), &rc, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOPREFIX);
+ this->restoreAlpha(x,y,sz.cx,sz.cy);
+#else
+ if (MyGetTextExtentPoint32W && MyDrawTextW)
+ {
+ SIZE sz; MyGetTextExtentPoint32W(this->getDC(), str, lstrlenW(str), &sz);
+ RECT rc; SetRect(&rc, x, y, x+10000, y+10000);
+ this->saveAlpha(x,y,sz.cx,sz.cy);
+ MyDrawTextW(this->getDC(), str, lstrlenW(str), &rc, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOPREFIX);
+ this->restoreAlpha(x,y,sz.cx,sz.cy);
+ }
+#endif
+}
+
+// based on code by Yuriy Zaporozhets from:
+// http://www.codeproject.com/gdi/coolrgn.asp?df=100&forumid=739&exp=0&select=6341
+// slightly modified to integrate with MyBitmap class.
+HRGN MyBitmap::buildOpaqueRgn(int level, bool opaque)
+{
+ GdiFlush();
+
+ const int addRectsCount = 64;
+ int rectsCount = addRectsCount;
+ PRGNDATA pRgnData = (PRGNDATA)(new BYTE[sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT)]);
+ LPRECT pRects = (LPRECT)(&pRgnData->Buffer);
+
+ memset(pRgnData, 0, sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT));
+ pRgnData->rdh.dwSize = sizeof(RGNDATAHEADER);
+ pRgnData->rdh.iType = RDH_RECTANGLES;
+
+ int first = 0;
+ bool wasfirst = false;
+ bool ismask = false;
+ for (int i = 0; i < height; i++)
+ {
+ int j; // we will need j after the loop!
+ for (j = 0; j < width; j++)
+ {
+ ismask = opaque ? geta(this->getRow(i)[j]) > (DWORD)level : geta(this->getRow(i)[j]) < (DWORD)level;
+ if (wasfirst)
+ {
+ if (!ismask)
+ {
+ SetRect(&pRects[pRgnData->rdh.nCount++], first, i, j, i+1);
+ if (pRgnData->rdh.nCount >= (DWORD) rectsCount)
+ {
+ rectsCount += addRectsCount;
+ LPRGNDATA pRgnDataNew = (LPRGNDATA)(new BYTE[sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT)]);
+ memcpy(pRgnDataNew, pRgnData, sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT));
+ delete pRgnData;
+ pRgnData = pRgnDataNew;
+ pRects = (LPRECT)(&pRgnData->Buffer);
+ }
+ wasfirst = false;
+ }
+ } else
+ if (ismask) // set wasfirst when mask is found
+ {
+ first = j;
+ wasfirst = true;
+ }
+ }
+
+ if (wasfirst && ismask)
+ {
+ SetRect(&pRects[pRgnData->rdh.nCount++], first, i, j, i+1);
+ if (pRgnData->rdh.nCount >= (DWORD) rectsCount)
+ {
+ rectsCount += addRectsCount;
+ LPRGNDATA pRgnDataNew = (LPRGNDATA)(new BYTE[sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT)]);
+ memcpy(pRgnDataNew, pRgnData, sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT));
+ delete pRgnData;
+ pRgnData = pRgnDataNew;
+ pRects = (LPRECT)(&pRgnData->Buffer);
+ }
+ wasfirst = false;
+ }
+
+ }
+
+ HRGN hRgn = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount*sizeof(RECT), (LPRGNDATA)pRgnData);
+ delete pRgnData;
+ return hRgn;
+}
+
+static int hex2dec(char hex)
+{
+ if ((hex >= '0') && (hex <= '9'))
+ return hex - '0';
+ if ((hex >= 'a') && (hex <= 'f'))
+ return hex - 'a' + 0xa;
+ if ((hex >= 'A') && (hex <= 'F'))
+ return hex - 'A' + 0xa;
+ return 0;
+}
+
+bool MyBitmap::loadFromFile_pixel(const char *fn, const char *fnAlpha)
+{
+ allocate(1,1);
+ int r, g, b, a=255;
+ const char *p = fn + lstrlenA("pixel:");
+ r = (hex2dec(p[0]) << 4) + hex2dec(p[1]);
+ g = (hex2dec(p[2]) << 4) + hex2dec(p[3]);
+ b = (hex2dec(p[4]) << 4) + hex2dec(p[5]);
+ *bits = rgba(r,g,b,a);
+ return true;
+}
+
+bool MyBitmap::loadFromFile_gradient(const char *fn, const char *fnAlpha)
+{
+ const char *p = fn + lstrlenA("gradient:");
+
+ if (*p == 'h') allocate(256,1);
+ else allocate(1,256);
+
+ int r, g, b, a=255;
+
+ p += 2;
+ r = (hex2dec(p[0]) << 4) + hex2dec(p[1]);
+ g = (hex2dec(p[2]) << 4) + hex2dec(p[3]);
+ b = (hex2dec(p[4]) << 4) + hex2dec(p[5]);
+ COLOR32 from = rgba(r,g,b,a);
+
+ p += 7;
+ r = (hex2dec(p[0]) << 4) + hex2dec(p[1]);
+ g = (hex2dec(p[2]) << 4) + hex2dec(p[3]);
+ b = (hex2dec(p[4]) << 4) + hex2dec(p[5]);
+ COLOR32 to = rgba(r,g,b,a);
+
+ for (int i = 0; i < 256; ++i)
+ {
+ bits[i] = rgba(
+ ((255-i) * getr(from) + i * getr(to)) / 255,
+ ((255-i) * getg(from) + i * getg(to)) / 255,
+ ((255-i) * getb(from) + i * getb(to)) / 255,
+ 255
+ );
+ }
+
+ return true;
+}
+
+bool MyBitmap::loadFromFile_png(const char *fn, const char *fnAlpha)
+{
+ if (ServiceExists(MS_PNG2DIB))
+ {
+ HANDLE hFile, hMap = 0;
+ BYTE *ppMap = 0;
+ long cbFileSize = 0;
+ BITMAPINFOHEADER *pDib;
+ BYTE *pDibBits;
+ if ((hFile = CreateFileA(fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
+ if ((hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
+ if ((ppMap = (BYTE*)MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 )) != NULL)
+ cbFileSize = GetFileSize(hFile, NULL);
+ if (cbFileSize)
+ {
+ PNG2DIB param;
+ param.pSource = ppMap;
+ param.cbSourceSize = cbFileSize;
+ param.pResult = &pDib;
+ if (CallService(MS_PNG2DIB, 0, (LPARAM)&param))
+ pDibBits = (BYTE*)(pDib+1);
+ else
+ cbFileSize = 0;
+ }
+
+ if (ppMap) UnmapViewOfFile(ppMap);
+ if (hMap) CloseHandle(hMap);
+ if (hFile) CloseHandle(hFile);
+
+ if (!cbFileSize) return false;
+
+ BITMAPINFO *bi=(BITMAPINFO*)pDib;
+ BYTE *pt=(BYTE*)bi;
+ pt+=bi->bmiHeader.biSize;
+
+ if (bi->bmiHeader.biBitCount != 32)
+ {
+ allocate(abs(bi->bmiHeader.biWidth), abs(bi->bmiHeader.biHeight));
+ HDC hdcTmp = CreateCompatibleDC(getDC());
+ HBITMAP hBitmap = CreateDIBitmap(getDC(), pDib, CBM_INIT, pDibBits, bi, DIB_PAL_COLORS);
+ SelectObject(hdcTmp, hBitmap);
+ BitBlt(this->getDC(), 0, 0, abs(bi->bmiHeader.biWidth), abs(bi->bmiHeader.biHeight), hdcTmp, 0, 0, SRCCOPY);
+ this->makeOpaque();
+ DeleteDC(hdcTmp);
+ DeleteObject(hBitmap);
+ } else
+ {
+ allocate(abs(bi->bmiHeader.biWidth), abs(bi->bmiHeader.biHeight));
+ BYTE *p2=(BYTE *)pt;
+ for (int y=0; y<bi->bmiHeader.biHeight; ++y)
+ {
+ BYTE *p1=(BYTE *)bits + (bi->bmiHeader.biHeight-y-1)*bi->bmiHeader.biWidth*4;
+ for (int x=0; x<bi->bmiHeader.biWidth; ++x)
+ {
+ p1[0]= p2[0];
+ p1[1]= p2[1];
+ p1[2]= p2[2];
+ p1[3]= p2[3];
+ p1 += 4;
+ p2 += 4;
+ }
+ }
+// memcpy(bits, pt, bi->bmiHeader.biSizeImage);
+ premultipleChannels();
+ }
+
+ GlobalFree(pDib);
+ return true;
+ } else
+ {
+// MSGERROR(TranslateT("You need the png2dib plugin v. 0.1.3.x or later to process PNG images");
+ return false;
+ }
+}
+
+bool MyBitmap::loadFromFile_default(const char *fn, const char *fnAlpha)
+{
+ SIZE sz;
+ HBITMAP hBmpLoaded = (HBITMAP)LoadImageA(NULL, fn, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ if (!hBmpLoaded)
+ return false;
+
+ BITMAP bm; GetObject(hBmpLoaded, sizeof(bm), &bm);
+ SetBitmapDimensionEx(hBmpLoaded, bm.bmWidth, bm.bmHeight, NULL);
+
+ HDC dcTmp = CreateCompatibleDC(0);
+ GetBitmapDimensionEx(hBmpLoaded, &sz);
+ HBITMAP hBmpDcSave = (HBITMAP)SelectObject(dcTmp, hBmpLoaded);
+
+ allocate(sz.cx, sz.cy);
+ BitBlt(dcBmp, 0, 0, width, height, dcTmp, 0, 0, SRCCOPY);
+
+ DeleteObject(SelectObject(dcTmp, hBmpDcSave));
+ DeleteDC(dcTmp);
+
+ MyBitmap alpha;
+ if (fnAlpha && alpha.loadFromFile(fnAlpha) &&
+ (alpha.getWidth() == width) &&
+ (alpha.getHeight() == height) )
+ {
+ for (int i = 0; i < width*height; i++)
+ bits[i] = (bits[i] & 0x00ffffff) | ( (alpha.bits[i] & 0x000000ff) << 24 );
+ premultipleChannels();
+ } else
+ {
+ makeOpaque();
+ }
+ return true;
+}
+
+bool MyBitmap::loadFromFile(const char *fn, const char *fnAlpha)
+{
+ if (bits) free();
+
+ if (!strncmp(fn, "pixel:", lstrlenA("pixel:")))
+ {
+ return loadFromFile_pixel(fn, fnAlpha);
+ } else
+ if (!strncmp(fn, "gradient:", lstrlenA("gradient:")))
+ {
+ return loadFromFile_gradient(fn, fnAlpha);
+ } else
+ {
+ char ext[5];
+ memcpy(ext,fn+(strlen(fn)-4),5);
+ if (!lstrcmpiA(ext,".png"))
+ {
+ return loadFromFile_png(fn, fnAlpha);
+ } else
+ {
+ return loadFromFile_default(fn, fnAlpha);
+ }
+ }
+ // unreachable place
+ return false;
+}
+
+void MyBitmap::allocate(int w, int h)
+{
+ width = w;
+ height = h;
+
+ BITMAPINFO bi;
+
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = w;
+ bi.bmiHeader.biHeight = -h;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+
+ if (dcBmp)
+ {
+ DeleteObject(SelectObject(dcBmp, hBmpSave));
+ DeleteDC(dcBmp);
+ }
+
+ hBmp = (HBITMAP)CreateDIBSection(0, &bi, DIB_RGB_COLORS, (void **)&bits, 0, 0);
+ dcBmp = CreateCompatibleDC(0);
+ hBmpSave = (HBITMAP)SelectObject(dcBmp, hBmp);
+
+ GdiFlush();
+}
+
+void MyBitmap::free()
+{
+ GdiFlush();
+
+ DeleteObject(SelectObject(dcBmp, hBmpSave));
+ DeleteDC(dcBmp);
+
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+}
+
+void MyBitmap::premultipleChannels()
+{
+ GdiFlush();
+
+ for (int i = 0; i < width*height; i++)
+ bits[i] = rgba(getr(bits[i])*geta(bits[i])/255, getg(bits[i])*geta(bits[i])/255, getb(bits[i])*geta(bits[i])/255, geta(bits[i]));
+}
diff --git a/plugins/Popup/src/bitmap_funcs.h b/plugins/Popup/src/bitmap_funcs.h
new file mode 100644
index 0000000000..8a66c30f85
--- /dev/null
+++ b/plugins/Popup/src/bitmap_funcs.h
@@ -0,0 +1,132 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/bitmap_funcs.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __bitmap_funcs_h__
+#define __bitmap_funcs_h__
+
+// This should make bitmap manipulations much easier...
+class MyBitmap
+{
+public:
+ typedef unsigned long COLOR32;
+ static inline COLOR32 RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 0xff)
+ {
+ return (a << 24) | (r << 16) | (g << 8) | b;
+ };
+
+private:
+ HBITMAP hBmpSave, hBmp;
+ HDC dcBmp;
+ COLOR32 *bits;
+ COLOR32 *bitsSave;
+ int width, height;
+
+ void free();
+
+ bool loadFromFile_pixel(const char *fn, const char *fnAlpha = 0);
+ bool loadFromFile_gradient(const char *fn, const char *fnAlpha = 0);
+ bool loadFromFile_png(const char *fn, const char *fnAlpha = 0);
+ bool loadFromFile_default(const char *fn, const char *fnAlpha = 0);
+ void premultipleChannels();
+
+public:
+ MyBitmap();
+ MyBitmap(int w, int h);
+ MyBitmap(const char *fn, const char *fnAlpha = 0);
+ ~MyBitmap();
+ void allocate(int w, int h);
+
+ bool loadFromFile(const char *fn, const char *fnAlpha = 0);
+
+ int getWidth() { return width; }
+ int getHeight() { return height; }
+
+ HDC getDC() { return dcBmp; }
+ HBITMAP getBitmap() { return hBmp; }
+
+ void makeOpaque();
+ void makeOpaqueRect(int x1, int y1, int x2, int y2);
+ void makeOpaqueRect(RECT rc) { makeOpaqueRect(rc.left, rc.top, rc.right, rc.bottom); }
+
+ void saveAlpha(int x = 0, int y = 0, int w = 0, int h = 0);
+ void restoreAlpha(int x = 0, int y = 0, int w = 0, int h = 0);
+
+ void DrawBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h);
+ void BlendBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h);
+
+ void DrawNoAlpha(MyBitmap *bmp, int x, int y, int w, int h);
+
+ void Blend(MyBitmap *bmp, int x, int y, int w, int h);
+ void Draw(MyBitmap *bmp, int x, int y, int w, int h);
+
+ void BlendColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color);
+ void DrawColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color);
+
+ void BlendPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h);
+ void BlendPartColorized(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h, COLOR32 color);
+ void DrawPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h);
+// void DrawPartNoAlpha(MyBitmap *bmp, int x, int y, int w, int h);
+// void DrawPartColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color);
+
+ void DrawIcon(HICON hic, int x, int y, int w = 0, int h = 0);
+ void Draw_TextA(char *str, int x, int y);
+ void Draw_TextW(WCHAR *str, int x, int y);
+
+ __forceinline COLOR32 *getBits() { return bits; }
+ __forceinline COLOR32 *getRow(int row) { return bits + row * width; }
+ __forceinline COLOR32 *operator[] (int row) { return bits + row * width; }
+
+ static __forceinline COLOR32 rgba(COLOR32 r, COLOR32 g, COLOR32 b, COLOR32 a)
+ {
+ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
+ }
+ static __forceinline COLOR32 getr(COLOR32 c)
+ {
+ return (c >> 16) & 0xff;
+ }
+ static __forceinline COLOR32 getg(COLOR32 c)
+ {
+ return (c >> 8) & 0xff;
+ }
+ static __forceinline COLOR32 getb(COLOR32 c)
+ {
+ return c & 0xff;
+ }
+ static __forceinline COLOR32 geta(COLOR32 c)
+ {
+ return (c >> 24) & 0xff;
+ }
+
+ HRGN buildOpaqueRgn(int level = 64, bool opaque = true);
+};
+
+#endif // __bitmap_funcs_h__ \ No newline at end of file
diff --git a/plugins/Popup/src/common.h b/plugins/Popup/src/common.h
new file mode 100644
index 0000000000..d975e0df0c
--- /dev/null
+++ b/plugins/Popup/src/common.h
@@ -0,0 +1,296 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/common.h $
+Revision : $Revision: 1622 $
+Last change on : $Date: 2010-06-23 23:32:21 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef COMMON_H
+#define COMMON_H
+
+void PopUpPreview();
+
+#define MAX_POPUPS 48
+
+#define DB_READ_SUCCESS 0
+#define DB_READ_FAIL -1
+
+//===== Definitions =====
+#define LIGHTEN 24
+#define DARKEN 64
+
+inline void GetBmpSize(HBITMAP hbm, SIZE *sz)
+{
+ GetBitmapDimensionEx(hbm, sz);
+}
+
+inline void DebugMsg(LPTSTR msg){
+ if(PopUpOptions.debug){
+ MessageBox(NULL, msg, _T("debug"), MB_OK);
+ }
+}
+
+/* not used
+inline void GetDCBmpSize(HDC hdc, SIZE *sz)
+{
+ BITMAP bmp;
+ GetObject(GetCurrentObject(hdc, OBJ_BITMAP), sizeof(bmp), &bmp);
+ sz->cx = bmp.bmWidth;
+ sz->cy = bmp.bmHeight;
+}
+
+inline HBITMAP myLoadBitmap(LPCTSTR fn)
+{
+ HBITMAP res = (HBITMAP)LoadImage(NULL, fn, IMAGE_BITMAP, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_LOADFROMFILE);
+
+ BITMAPFILEHEADER bfh;
+ BITMAPINFOHEADER bih;
+ FILE *f = _tfopen (fn, _T("rb"));
+ fread(&bfh, sizeof(bfh), 1, f);
+ fread(&bih, sizeof(bih), 1, f);
+ fclose(f);
+ SetBitmapDimensionEx(res, bih.biWidth, bih.biHeight, NULL);
+
+ return res;
+}
+*/
+
+//===== Percentile to Byte and viceversa =====
+inline int Byte2Percentile(int vByte) { return (vByte*100)/255; }
+inline int Percentile2Byte(int vPerc) { return (vPerc*255)/100; }
+
+//===== Strings & MirandaDB ==================
+inline char *DBGetContactSettingString(HANDLE hContact, const char *ModuleName, const char *SettingName, const char *Default)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING dbcgs;
+ dbcgs.szModule = ModuleName;
+ dbcgs.pValue = &dbv;
+ dbcgs.szSetting = SettingName;
+
+ CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs);
+
+ char *result = 0;
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ result = mir_strdup(dbv.pszVal);
+ }
+ else if (Default)
+ {
+ result = mir_strdup(Default);
+ }
+
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ return result;
+}
+
+inline INT_PTR DBGetContactSettingStringX(HANDLE hContact, const char *ModuleName, const char *SettingName, const char *Default, const int retType)
+{
+ INT_PTR ret = NULL;
+ BOOL result = 0;
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING dbcgs;
+ dbcgs.szModule = ModuleName;
+ dbcgs.szSetting = SettingName;
+ dbcgs.pValue = &dbv;
+ dbv.type=(BYTE)retType;
+
+ result = CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&dbcgs);
+
+ switch(retType) {
+ case DBVT_ASCIIZ:
+ ret = (INT_PTR)mir_strdup(result ? Default : dbv.pszVal);
+ break;
+ case DBVT_WCHAR:
+ if(!result) {
+ ret = (INT_PTR)mir_wstrdup(dbv.pwszVal);
+ }
+ else {
+ ret = (INT_PTR)mir_a2u(Default);
+ }
+ break;
+ default:
+ break;
+ }
+ if(!result)
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ return ret;
+}
+
+/* not used
+#if !defined(_UNICODE)
+inline void SetWindowTextTraslated(HWND hwnd, const char *text)
+{
+ if (!(hwnd && text)) return;
+ if (g_popup.isOsUnicode && IsWindowUnicode(hwnd) && MySetWindowTextW)
+ {
+ UINT codepage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+ int size = MultiByteToWideChar(codepage, 0, text, lstrlenA(text), 0, 0);
+ WCHAR *wtext = new WCHAR[size+1];
+ MultiByteToWideChar(codepage, 0, text, lstrlenA(text), wtext, size+1); wtext[size]=0;
+ MySetWindowTextW(hwnd, TranslateW(wtext));
+ delete [] wtext;
+ } else
+ {
+ SetWindowTextA(hwnd, Translate(text));
+ }
+}
+#endif
+*/
+/*/dedrecatet (tricky thing to minimize memory fragmentation)
+inline wchar_t* a2u( char* src )
+{
+ int codepage = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 );
+
+ int cbLen = MultiByteToWideChar( codepage, 0, src, -1, NULL, 0 );
+ wchar_t* result = ( wchar_t* )mir_alloc( sizeof( wchar_t )*(cbLen+1));
+ if ( result == NULL )
+ return NULL;
+
+ MultiByteToWideChar( codepage, 0, src, -1, result, cbLen );
+ result[ cbLen ] = 0;
+ return result;
+}
+
+#define nb_a2u_init() \
+ int nb_a2u_codepage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0); \
+ int nb_a2u_len = 0; \
+
+#define nb_a2u(dst, src) \
+ bool dst##_free = false; \
+ WCHAR *dst = NULL; \
+ nb_a2u_len = MultiByteToWideChar(nb_a2u_codepage, 0, src, -1, NULL, 0); \
+ __try \
+ { \
+ dst = (WCHAR *)_alloca(sizeof(WCHAR)*(nb_a2u_len+1)); \
+ } \
+ __except( EXCEPTION_EXECUTE_HANDLER ) \
+ { \
+ dst = (WCHAR *)mir_alloc(sizeof(WCHAR)*(nb_a2u_len+1)); \
+ dst##_free = true; \
+ } \
+ MultiByteToWideChar(nb_a2u_codepage, 0, src, -1, dst, nb_a2u_len); \
+ dst[nb_a2u_len] = 0;
+
+#define nb_a2u_free(dst) \
+ if (dst##_free) \
+ mir_free(dst);
+*/
+
+inline void AddTooltipTranslated(HWND hwndToolTip, HWND hwnd, int id, RECT rc, char *text)
+{
+#if defined(_UNICODE)
+ TOOLINFO ti = {0};
+ ti.cbSize = sizeof(TOOLINFO);
+
+ ti.hwnd = hwnd;
+ ti.uId = id;
+ SendMessage(hwndToolTip, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+
+ LPWSTR wtext = mir_a2u(text);
+
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = hwnd;
+ ti.uId = id;
+ ti.hinst = hInst;
+ ti.lpszText = TranslateW(wtext);
+ ti.rect = rc;
+ SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+
+ mir_free(wtext);
+
+#else
+ if (g_popup.isOsUnicode && MySendMessageW)
+ {
+ TOOLINFOW ti = {0};
+ ti.cbSize = sizeof(TOOLINFO);
+
+ ti.hwnd = hwnd;
+ ti.uId = id;
+ MySendMessageW(hwndToolTip, TTM_DELTOOLW, 0, (LPARAM) (LPTOOLINFOW) &ti);
+
+ LPWSTR wtext = mir_a2u(text);
+
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = hwnd;
+ ti.uId = id;
+ ti.hinst = hInst;
+ ti.lpszText = TranslateW(wtext);
+ ti.rect = rc;
+ MySendMessageW(hwndToolTip, TTM_ADDTOOLW, 0, (LPARAM) (LPTOOLINFOW) &ti);
+
+ mir_free(wtext);
+ } else
+ {
+ TOOLINFOA ti = {0};
+ ti.cbSize = sizeof(TOOLINFO);
+
+ ti.hwnd = hwnd;
+ ti.uId = id;
+ SendMessage(hwndToolTip, TTM_DELTOOLA, 0, (LPARAM) (LPTOOLINFOA) &ti);
+
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = hwnd;
+ ti.uId = id;
+ ti.hinst = hInst;
+ ti.lpszText = Translate(text);
+ ti.rect = rc;
+ SendMessage(hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM) (LPTOOLINFOA) &ti);
+ }
+#endif
+}
+
+/* not used
+inline UINT getCodepageFromCharset(BYTE charset)
+{
+ switch (charset)
+ {
+ case ANSI_CHARSET: return 1252;
+ case BALTIC_CHARSET: return 1257;
+ case CHINESEBIG5_CHARSET: return 950;
+ case DEFAULT_CHARSET: return CP_ACP;
+ case EASTEUROPE_CHARSET: return 1250;
+ case GB2312_CHARSET: return 936;
+ case GREEK_CHARSET: return 1253;
+ case HANGUL_CHARSET: return 949;
+ case MAC_CHARSET: return CP_MACCP;
+ case OEM_CHARSET: return CP_OEMCP;
+ case RUSSIAN_CHARSET: return 1251;
+ case SHIFTJIS_CHARSET: return 932;
+// case SYMBOL_CHARSET: return ;
+ case TURKISH_CHARSET: return 1254;
+ case VIETNAMESE_CHARSET: return 1258;
+ case JOHAB_CHARSET: return 1361;
+ case ARABIC_CHARSET: return 1256;
+ case HEBREW_CHARSET: return 1255;
+ default: return CP_ACP;
+ }
+}
+*/
+
+#endif //COMMON_H
diff --git a/plugins/Popup/src/config.cpp b/plugins/Popup/src/config.cpp
new file mode 100644
index 0000000000..5831de512e
--- /dev/null
+++ b/plugins/Popup/src/config.cpp
@@ -0,0 +1,210 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/config.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+//===== General Plugin =====
+HINSTANCE hInst;
+HANDLE hMainThread;
+//MNOTIFYLINK *notifyLink; //deprecatet
+PLUGINLINK *pluginLink;
+HANDLE hSemaphore;
+BOOL closing = FALSE;
+MM_INTERFACE mmi;
+LIST_INTERFACE li;
+UTF8_INTERFACE utfi;
+MTEXT_INTERFACE MText = {0};
+HANDLE folderId;
+BOOL gbPopupLoaded = FALSE;
+BOOL gbHppInstalled = FALSE;
+LPCSTR gszMetaProto = "";
+
+//===== Brushes, Colours and Fonts =====
+HBITMAP hbmNoAvatar;
+
+//===== Options =====
+POPUPOPTIONS PopUpOptions;
+//SKINELEMENT *skin;
+//SKINELEMENT *w_skin;
+//SKINELEMENT *n_skin;
+
+
+//===== Plugin information =====
+
+PLUGININFOEX pluginInfoEx =
+{
+ sizeof(PLUGININFOEX),
+ POPUP_DISPLAYNAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM),
+ POPUP_DESCRIPTION,
+ POPUP_AUTHOR,
+ POPUP_EMAIL,
+ POPUP_COPYRIGHT,
+ POPUP_WEBPAGE,
+ 0,
+ 0,
+ POPUP_UUID
+};
+
+// MLU layer for ansi release
+#if !defined(_UNICODE)
+BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+BOOL (WINAPI *MyGetMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi);
+BOOL (WINAPI *MyUpdateLayeredWindow)
+ (HWND hwnd, HDC hdcDST, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc,
+ COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
+HMONITOR (WINAPI *MyMonitorFromWindow)(HWND hWnd, DWORD dwFlags);
+BOOL (WINAPI *MyTransparentBlt)(HDC, int, int, int, int, HDC, int, int, int, int, UINT);
+BOOL (WINAPI *MyAlphaBlend)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION);
+
+// gdi32.dll
+BOOL (WINAPI *MyGetTextExtentPoint32W)(HDC, LPCWSTR, int, LPSIZE);
+
+//user32.dll
+int (WINAPI *MyDrawTextW)(HDC, LPCWSTR, int, LPRECT, UINT);
+int (WINAPI *MyDrawTextExW)(HDC, LPCWSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);
+BOOL (WINAPI *MySetWindowTextW)(HWND, LPCWSTR);
+LRESULT (WINAPI *MySendMessageW)(HWND, UINT, WPARAM, LPARAM);
+LRESULT (WINAPI *MyCallWindowProcW)(WNDPROC, HWND, UINT, WPARAM, LPARAM);
+HWND (WINAPI *MyCreateWindowExW)(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
+
+#endif
+
+HRESULT (WINAPI *MyDwmEnableBlurBehindWindow)(HWND hWnd, DWM_BLURBEHIND *pBlurBehind);
+
+//====== Common Vars ========================
+
+// common funcs
+void LoadOptions() {
+ ZeroMemory(&PopUpOptions, sizeof(PopUpOptions));
+ #if defined(_DEBUG)
+ PopUpOptions.debug = DBGetContactSettingByte(NULL, MODULNAME, "debug", FALSE);
+ #endif
+
+ //Load PopUp Options
+ if(!OptionLoaded){
+ LoadOption_General();
+ LoadOption_Skins();
+ LoadOption_Actions();
+ LoadOption_AdvOpts();
+ }
+ Check_ReorderPopUps();
+ OptionLoaded = true;
+ return;
+}
+
+void PopUpPreview()
+{
+ TCHAR *lptzTitle1Eng = TranslateT("The Jabberwocky");
+ TCHAR *lptzText1Eng = TranslateTS(
+ _T("`Twas brillig, and the slithy toves\r\n")
+ _T("Did gyre and gimble in the wabe:\r\n")
+ _T("All mimsy were the borogoves,\r\n")
+ _T("And the mome raths outgrabe.\r\n")
+ _T("\t[b][i]Lewis Carroll, 1855[/i][/b]")
+ );
+
+ TCHAR *lptzTitle2 = TranslateT("Test preview for the popup plugin settings. This is supposed to be long enough not to fit in one line...");
+ TCHAR *lptzText2 = TranslateTS(
+ _T("This is a special test preview for the popup ")
+ _T("plugin settings. The text and title are quite ")
+ _T("long so you can tweak your skin and plugin ")
+ _T("settings to best fit your needs :)")
+ );
+
+ POPUPDATA2 ppd = {0};
+
+ ZeroMemory(&ppd, sizeof(ppd));
+ ppd.cbSize = sizeof(ppd);
+ ppd.flags = PU2_TCHAR;
+
+#if defined(_DEBUG)
+ // test per-contact popups
+ for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact;
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0))
+ {
+ if (DBGetContactSettingDword(hContact, "ICQ", "UIN", 0) == 256771455)
+ {
+ ppd.lchContact = hContact;
+ break;
+ }
+ }
+#endif
+ ppd.lptzTitle = lptzTitle1Eng;
+ ppd.lptzText = lptzText1Eng;
+ ppd.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ CallService(MS_POPUP_ADDPOPUP2, (WPARAM)&ppd, APF_NO_HISTORY);
+ if (PopUpOptions.UseAnimations || PopUpOptions.UseEffect) Sleep((ANIM_TIME*2)/3); //Pause
+
+ ZeroMemory(&ppd, sizeof(ppd));
+ ppd.cbSize = sizeof(ppd);
+ ppd.flags = PU2_TCHAR;
+ ppd.lptzTitle = lptzTitle2;
+ ppd.lptzText = lptzText2;
+ ppd.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ ppd.hbmAvatar = hbmNoAvatar;
+#if defined(_DEBUG)
+//remove testactions
+ POPUPACTION actions[3];
+ actions[0].cbSize = sizeof(POPUPACTION);
+ actions[0].flags = PAF_ENABLED;
+ lstrcpyA(actions[0].lpzTitle, "Popup Plus/Test action");
+ actions[0].lchIcon = IcoLib_GetIcon(ICO_POPUP_ON,0);
+ actions[0].wParam = actions[0].lParam = -1;
+
+ actions[1].cbSize = sizeof(POPUPACTION);
+ actions[1].flags = PAF_ENABLED;
+ lstrcpyA(actions[1].lpzTitle, "Popup Plus/Second test action");
+ actions[1].lchIcon = IcoLib_GetIcon(ICO_ACT_CLOSE,0);
+ actions[1].wParam = actions[1].lParam = -1;
+
+ actions[2].cbSize = sizeof(POPUPACTION);
+ actions[2].flags = PAF_ENABLED;
+ lstrcpyA(actions[2].lpzTitle, "Popup Plus/One more action");
+ actions[2].lchIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ actions[2].wParam = actions[2].lParam = -1;
+
+ ppd.lpActions = actions;
+ ppd.actionCount = SIZEOF(actions);
+#endif
+ CallService(MS_POPUP_ADDPOPUP2, (WPARAM)&ppd, APF_NO_HISTORY);
+ if (PopUpOptions.UseAnimations || PopUpOptions.UseEffect) Sleep((ANIM_TIME*2)/3); //Pause
+
+ PUShowMessageT(TranslateT("This is a notification message"), (DWORD)SM_NOTIFY|0x80000000);
+ if (PopUpOptions.UseAnimations || PopUpOptions.UseEffect) Sleep((ANIM_TIME*2)/3); //Pause
+
+ PUShowMessageT(TranslateT("This is a warning message"), (DWORD)SM_WARNING|0x80000000);
+ if (PopUpOptions.UseAnimations || PopUpOptions.UseEffect) Sleep((ANIM_TIME*2)/3); //Pause
+
+ PUShowMessageT(TranslateT("This is an error message"), (DWORD)SM_ERROR|0x80000000);
+} \ No newline at end of file
diff --git a/plugins/Popup/src/config.h b/plugins/Popup/src/config.h
new file mode 100644
index 0000000000..6b293ba10d
--- /dev/null
+++ b/plugins/Popup/src/config.h
@@ -0,0 +1,249 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/config.h $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __config_h__
+#define __config_h__
+
+typedef struct tagPOPUPOPTIONS {
+//==Page General====
+ //Timeout
+ BYTE InfiniteDelay;
+ int Seconds;
+ BYTE LeaveHovered;
+ //Size&Position
+ BYTE DynamicResize;
+ BYTE UseMinimumWidth;
+ WORD MinimumWidth;
+ BYTE UseMaximumWidth;
+ WORD MaximumWidth;
+ int Position;
+ int Spreading;
+ //position Popup
+ int gapTop;
+ int gapBottom;
+ int gapLeft;
+ int gapRight;
+ int spacing;
+ //Miscellaneous
+ BYTE ReorderPopUps;
+ BYTE ReorderPopUpsWarning;
+ //Disable when
+ BOOL ModuleIsEnabled;
+ BYTE DisableWhenFullscreen;
+ //others
+ BYTE debug;
+//==Page Skins====
+ LPTSTR SkinPack;
+ BYTE DisplayTime;
+ BYTE DropShadow;
+ BYTE EnableFreeformShadows;
+ BYTE EnableAeroGlass;
+ BYTE UseWinColors;
+ BYTE UseMText;
+//==Page Actions====
+ DWORD actions;
+ //Mouse Override
+ int overrideLeft;
+ int overrideRight;
+ int overrideMiddle;
+//==Page Advanced====
+ //History
+ BYTE EnableHistory;
+ WORD HistorySize;
+ BYTE UseHppHistoryLog;
+ //Avatars
+ BYTE avatarBorders;
+ BYTE avatarPNGBorders;
+ BYTE avatarRadius;
+ WORD avatarSize;
+ BYTE EnableAvatarUpdates;
+ //Monitor
+ BYTE Monitor;
+ //Transparency
+ BYTE Enable9xTransparency;
+ BYTE UseTransparency;
+ BYTE Alpha;
+ BYTE OpaqueOnHover;
+ //Effect
+ BYTE UseAnimations;
+ BYTE UseEffect;
+ LPTSTR Effect;
+ DWORD FadeIn;
+ DWORD FadeOut;
+ //Others
+ WORD MaxPopups;
+} POPUPOPTIONS;
+
+struct GLOBAL{
+ bool isOsUnicode;
+ bool isMirUnicode;
+ int MirVer;
+};
+extern GLOBAL g_popup;
+
+//===== User wnd class =====
+struct GLOBAL_WND_CLASSES{
+ ATOM cPopupWnd2;
+ ATOM cPopupEditBox;
+ ATOM cPopupMenuHostWnd;
+ ATOM cPopupThreadManagerWnd;
+ ATOM cPopupPreviewBoxWndclass;
+ ATOM cPopupPlusDlgBox;
+};
+extern GLOBAL_WND_CLASSES g_wndClass;
+
+#define ACT_ENABLE 0x00000001
+#define ACT_LARGE 0x00000002
+#define ACT_TEXT 0x00000004
+#define ACT_RIGHTICONS 0x00000008
+#define ACT_LEFTICONS 0x00000010
+#define ACT_DEF_NOGLOBAL 0x00000020
+#define ACT_DEF_KEEPWND 0x00000040
+#define ACT_DEF_IMONLY 0x00000080
+
+#define ACT_DEF_MESSAGE 0x00010000
+#define ACT_DEF_DETAILS 0x00020000
+#define ACT_DEF_MENU 0x00040000
+#define ACT_DEF_ADD 0x00080000
+#define ACT_DEF_DISMISS 0x00100000
+#define ACT_DEF_PIN 0x00200000
+#define ACT_DEF_REPLY 0x00400000
+#define ACT_DEF_COPY 0x00800000
+
+void LoadOptions();
+
+//===== General Plugin =====
+extern HINSTANCE hInst;
+extern HANDLE hMainThread;
+//extern MNOTIFYLINK *notifyLink; //deprecatet
+extern PLUGINLINK *pluginLink;
+extern HANDLE hSemaphore;
+extern BOOL closing;
+extern HANDLE folderId;
+extern UTF8_INTERFACE utfi;
+
+extern MTEXT_INTERFACE MText;
+extern HANDLE htuText;
+extern HANDLE htuTitle;
+
+extern BOOL gbPopupLoaded;
+extern BOOL gbHppInstalled;
+extern LPCSTR gszMetaProto;
+
+
+//===== Brushes, Colours and Fonts =====
+extern HBITMAP hbmNoAvatar;
+
+//===== Options =====
+extern POPUPOPTIONS PopUpOptions;
+extern bool OptionLoaded;
+//extern SKINELEMENT *skin;
+//extern SKINELEMENT *w_skin;
+//extern SKINELEMENT *n_skin;
+
+//===== Plugin informations struct =====
+extern PLUGININFOEX pluginInfoEx;
+
+//===== Transparency & APIs which are not supported by every OS =====
+#ifndef DWLP_MSGRESULT
+#define DWLP_MSGRESULT 0
+#endif
+#ifndef WS_EX_LAYERED
+#define WS_EX_LAYERED 0x00080000
+#endif
+#ifndef LWA_COLORKEY
+#define LWA_COLORKEY 0x00000001
+#endif
+#ifndef LWA_ALPHA
+#define LWA_ALPHA 0x00000002
+#endif
+#ifndef ULW_OPAQUE
+#define ULW_OPAQUE 0x00000004
+#endif
+#ifndef AC_SRC_ALPHA
+#define AC_SRC_ALPHA 0x01
+#endif
+#ifndef INVALID_FILE_ATTRIBUTES
+#define INVALID_FILE_ATTRIBUTES (DWORD (-1))
+#endif
+
+// MLU layer for ansi release
+#if !defined(_UNICODE)
+//===== DLLs =====
+extern HMODULE hUserDll;
+extern HMODULE hMsimgDll;
+extern HMODULE hKernelDll;
+extern HMODULE hGdiDll;
+extern HMODULE hDwmapiDll;
+
+extern BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+extern BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+extern BOOL (WINAPI *MyGetMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi);
+extern BOOL (WINAPI *MyUpdateLayeredWindow)
+ (HWND hwnd, HDC hdcDST, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc,
+ COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
+extern HMONITOR (WINAPI* MyMonitorFromWindow)(HWND hWnd, DWORD dwFlags);
+extern BOOL (WINAPI *MyTransparentBlt)(HDC, int, int, int, int, HDC, int, int, int, int, UINT);
+extern BOOL (WINAPI *MyAlphaBlend)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION);
+
+extern BOOL (WINAPI *MyGetTextExtentPoint32W)(HDC, LPCWSTR, int, LPSIZE);
+extern int (WINAPI *MyDrawTextW)(HDC, LPCWSTR, int, LPRECT, UINT);
+extern int (WINAPI *MyDrawTextExW)(HDC, LPCWSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);
+extern BOOL (WINAPI *MySetWindowTextW)(HWND, LPCWSTR);
+extern LRESULT (WINAPI *MySendMessageW)(HWND, UINT, WPARAM, LPARAM);
+extern LRESULT (WINAPI *MyCallWindowProcW)(WNDPROC, HWND, UINT, WPARAM, LPARAM);
+extern HWND (WINAPI *MyCreateWindowExW)(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
+
+#endif
+
+#define DWM_BB_ENABLE 0x00000001
+#define DWM_BB_BLURREGION 0x00000002
+#define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004
+struct DWM_BLURBEHIND
+{
+ DWORD dwFlags;
+ BOOL fEnable;
+ HRGN hRgnBlur;
+ BOOL fTransitionOnMaximized;
+};
+
+extern HRESULT (WINAPI *MyDwmEnableBlurBehindWindow)(HWND hWnd, DWM_BLURBEHIND *pBlurBehind);
+
+typedef struct TestStruct{
+ int cbSize;
+} TESTSIZE;
+
+// Generic Message Box for Errors
+#define MSGERROR(text) MessageBox(NULL, text, _T(MODULNAME_LONG), MB_OK | MB_ICONERROR)
+#define MSGINFO (text) MessageBox(NULL, text, _T(MODULNAME_LONG), MB_OK | MB_ICONINFORMATION)
+
+#endif // __config_h__
diff --git a/plugins/Popup/src/def_settings.h b/plugins/Popup/src/def_settings.h
new file mode 100644
index 0000000000..9fa02ff13c
--- /dev/null
+++ b/plugins/Popup/src/def_settings.h
@@ -0,0 +1,156 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+
+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 __def_settings_h__
+#define __def_settings_h__
+
+//===== Styles =====
+enum
+{
+ STYLE_FC_BEVELED,
+ STYLE_FC_FLAT,
+
+ //ranges:
+ STYLE_FC_MIN = STYLE_FC_BEVELED,
+ STYLE_FC_MAX = STYLE_FC_FLAT
+};
+
+//===== Sizes =====
+enum
+{
+ STYLE_SZ_GAP = 4,
+ STYLE_SZ_TEXTH = 14,
+ STYLE_SZ_NAMEH = 14,
+ STYLE_SZ_TIMEW = 35,
+ STYLE_SZ_TIMEH = 14,
+
+// STYLE_SZ_CLOCKH = 13,
+// STYLE_SZ_CLOCKW = 7,
+// STYLE_SZ_CLOCK = 2 + 3 + 4 * STYLE_SZ_CLOCKW + 2,
+
+ //Text and Name are style dependant.
+ STYLE_SZ_TEXTW_FLAT = 146,
+ STYLE_SZ_NAMEW_FLAT = 101,
+ STYLE_SZ_TEXTW_BEVELED = 125,
+ STYLE_SZ_NAMEW_BEVELED = 80,
+
+ // border size
+ STYLE_SZ_BORDER_BEVELED = 2,
+ STYLE_SZ_BORDER_FLAT = 2
+};
+
+//===== PopUp Positioning =====
+enum
+{
+ POS_UPPERLEFT,
+ POS_LOWERLEFT,
+ POS_LOWERRIGHT,
+ POS_UPPERRIGHT,
+ POS_CENTER,
+
+ //ranges
+ POS_MINVALUE = POS_UPPERLEFT,
+ POS_MAXVALUE = POS_CENTER
+};
+
+//===== Spreading =====
+enum
+{
+ SPREADING_HORIZONTAL,
+ SPREADING_VERTICAL,
+
+ SPREADING_MINVALUE = SPREADING_HORIZONTAL,
+ SPREADING_MAXVALUE = SPREADING_VERTICAL
+};
+
+//===== PopUp Options flags
+enum
+{
+ SPK_NONE,
+ SPK_SMILEYADD,
+ SPK_MSL,
+ SPK_XEP,
+ SPK_NCONVERS
+};
+enum
+{
+ TIMER_TIMETOLIVE = 26378, //My Birthday, send me something 8)
+ TIMER_TESTCHANGE = 60477, //You know who you are.
+
+ ANIM_TIME = 250,
+ FADE_TIME = (ANIM_TIME),
+ FADE_STEP = 10,
+
+ MN_MIRANDA = 0x01,
+ MN_ACTIVE = 0x02,
+
+ UM_SETDLGITEMINT = 5674
+};
+
+//Defaults:
+enum
+{
+ SETTING_BACKCOLOUR_DEFAULT = RGB(173,206,247),
+ SETTING_TEXTCOLOUR_DEFAULT = RGB(0,0,0),
+
+ SETTING_MONITOR_DEFAULT = MN_MIRANDA,
+ SETTING_USEMINIMUMWIDTH_DEFAULT = 1,
+ SETTING_USEMAXIMUMWIDTH_DEFAULT = 1,
+ SETTING_USINGTHREADS_DEFAULT = 1,
+ SETTING_MODULEISENABLED_DEFAULT = 1,
+ SETTING_MULTILINE_DEFAULT = 1,
+ SETTING_FADEINTIME_DEFAULT = (ANIM_TIME),
+ SETTING_FADEOUTTIME_DEFAULT = (ANIM_TIME),
+ SETTING_FADEOUTTIME_MIN = 0,
+ SETTING_FADEINTIME_MIN = 0,
+ SETTING_FADEOUTTIME_MAX = 10000,
+ SETTING_FADEINTIME_MAX = 10000,
+
+ SETTING_LIFETIME_MIN = 1,
+ SETTING_LIFETIME_MAX = 60,
+ SETTING_LIFETIME_DEFAULT = 4,
+ SETTING_LIFETIME_INFINITE = -1,
+
+ SETTING_ENLARGEMENT_MIN = 100,
+ SETTING_ENLARGEMENT_MAX = 200,
+ SETTING_ENLARGEMENT_DEFAULT = 120,
+
+ SETTING_HISTORYSIZE_MAX = 100,
+ SETTING_HISTORYSIZE_DEFAULT = 20,
+
+ SETTING_AVTSIZE_MIN = 16,
+ SETTING_AVTSIZE_MAX = 100,
+ SETTING_AVTSIZE_DEFAULT = 32,
+
+ SETTING_MINIMUMWIDTH_MIN = 80,
+ SETTING_MINIMUMWIDTH_MAX = 160,
+ SETTING_MINIMUMWIDTH_DEFAULT= 110,
+
+ SETTING_MAXIMUMWIDTH_MIN = 160,
+// SETTING_MAXIMUMWIDTH_MAX = 640,
+ SETTING_MAXIMUMWIDTH_DEFAULT= 310,
+
+ SETTING_SMILEPACKTYPE_DEFAULT = SPK_NONE
+};
+
+extern WORD SETTING_MAXIMUMWIDTH_MAX;
+
+#endif
diff --git a/plugins/Popup/src/defs.h b/plugins/Popup/src/defs.h
new file mode 100644
index 0000000000..3ff8d09cdc
--- /dev/null
+++ b/plugins/Popup/src/defs.h
@@ -0,0 +1,52 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/defs.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __defs_h__
+#define __defs_h__
+
+#ifdef __cplusplus
+ // in C++ files we should define everything inside extren "C"
+ #define EXTERNC extern "C"
+ #define BEGIN_EXTERNC extern "C" {
+ #define END_EXTERNC };
+
+ // in C++ all exported function must be extern "C"
+ #define MIRAPI extern "C" __declspec(dllexport)
+#else
+ #define EXTERNC
+ #define BEGIN_EXTERNC
+ #define END_EXTERNC
+
+ #define MIRAPI __declspec(dllexport)
+#endif
+
+#endif \ No newline at end of file
diff --git a/plugins/Popup/src/effects.cpp b/plugins/Popup/src/effects.cpp
new file mode 100644
index 0000000000..64ac46b16f
--- /dev/null
+++ b/plugins/Popup/src/effects.cpp
@@ -0,0 +1,94 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/effects.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+class MyTestEffect;
+HANDLE hSquareFad;
+
+class MyTestEffect: public IPopupPlusEffect
+{
+protected:
+ int w, h;
+ int alpha0, alpha1;
+ int frameCount;
+ int frame;
+
+ int stage;
+ int alpha;
+
+public:
+ virtual void beginEffect(int w, int h, int alpha0, int alpha1, int frameCount)
+ {
+ this->w = w;
+ this->h = h;
+ this->alpha0 = alpha0;
+ this->alpha1 = alpha1;
+ this->frameCount = frameCount;
+ }
+ virtual void beginFrame(int frame)
+ {
+ this->frame = frame;
+ stage = (frame*2 > frameCount) ? 1 : 0;
+ if (stage == 0)
+ {
+ alpha = alpha0 + (alpha1 - alpha0) * frame * 2 / frameCount;
+ } else
+ {
+ alpha = alpha0 + (alpha1 - alpha0) * (frame * 2 - frameCount) / frameCount;
+ }
+ }
+ virtual int getPixelAlpha(int x, int y)
+ {
+ if (stage == 0)
+ {
+ if ((x/16+y/16) % 2) return alpha0;
+ return alpha;
+ } else
+ {
+ if ((x/16+y/16) % 2) return alpha;
+ return alpha1;
+ }
+ }
+ virtual void endFrame() {}
+ virtual void endEffect() {}
+ virtual void destroy() { delete this; }
+};
+
+//template<class T> static int svcCreateEffect(WPARAM, LPARAM) { return (int)(new T); }
+static INT_PTR svcCreateEffect_MyTestEffect(WPARAM, LPARAM) { return (INT_PTR)(new MyTestEffect); }
+
+void PopupEfectsInitialize()
+{
+ hSquareFad = CreateServiceFunction(MS_POPUP_CREATEVFX "Square fading", svcCreateEffect_MyTestEffect);
+ CallService(MS_POPUP_REGISTERVFX, 0, (LPARAM)"Square fading");
+}
diff --git a/plugins/Popup/src/effects.h b/plugins/Popup/src/effects.h
new file mode 100644
index 0000000000..6196719f3f
--- /dev/null
+++ b/plugins/Popup/src/effects.h
@@ -0,0 +1,38 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/effects.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __effects_h__
+#define __effects_h__
+
+void PopupEfectsInitialize();
+
+#endif // __effects_h__
diff --git a/plugins/Popup/src/font.cpp b/plugins/Popup/src/font.cpp
new file mode 100644
index 0000000000..d9502eadac
--- /dev/null
+++ b/plugins/Popup/src/font.cpp
@@ -0,0 +1,154 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/font.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+PopupFonts fonts = {0};
+
+void InitFonts() {
+ // Fonts
+ FontIDT fid = {0};
+ fid.cbSize = sizeof(FontIDT);
+ lstrcpy(fid.group, _T(PU_FNT_AND_COLOR));
+ strcpy(fid.dbSettingsGroup, PU_FNT_AND_COLOR_DB);
+ fid.flags = FIDF_DEFAULTVALID;
+ fid.deffontsettings.charset = DEFAULT_CHARSET;
+ fid.deffontsettings.size = -11;
+ lstrcpy(fid.backgroundGroup,_T(PU_FNT_AND_COLOR));
+ lstrcpy(fid.backgroundName,_T(PU_COL_BACK_NAME));
+ lstrcpy(fid.deffontsettings.szFace, _T("Tahoma"));
+
+ lstrcpy(fid.name, _T(PU_FNT_NAME_TITLE));
+ mir_snprintf(fid.prefix, sizeof(fid.prefix), PU_FNT_PREFIX, PU_FNT_NAME_TITLE);
+ fid.deffontsettings.style = DBFONTF_BOLD;
+ fid.deffontsettings.colour = RGB(0,0,0);
+ FontRegisterT(&fid);
+
+ lstrcpy(fid.name, _T(PU_FNT_NAME_CLOCK));
+ mir_snprintf(fid.prefix, sizeof(fid.prefix), PU_FNT_PREFIX, PU_FNT_NAME_CLOCK);
+ //fid.deffontsettings.style = DBFONTF_BOLD;
+ //fid.deffontsettings.colour = RGB(0,0,0);
+ FontRegisterT(&fid);
+
+ lstrcpy(fid.name, _T(PU_FNT_NAME_TEXT));
+ mir_snprintf(fid.prefix, sizeof(fid.prefix), PU_FNT_PREFIX, PU_FNT_NAME_TEXT);
+ fid.deffontsettings.style = 0;
+ //fid.deffontsettings.colour = RGB(0,0,0);
+ FontRegisterT(&fid);
+
+ lstrcpy(fid.name, _T("Action"));
+ mir_snprintf(fid.prefix, sizeof(fid.prefix), PU_FNT_PREFIX, "Action");
+ //fid.deffontsettings.style = 0;
+ fid.deffontsettings.colour = RGB(0,0,255);
+ FontRegisterT(&fid);
+
+ lstrcpy(fid.name, _T("Hovered Action"));
+ mir_snprintf(fid.prefix, sizeof(fid.prefix), PU_FNT_PREFIX, "Hovered Action");
+ fid.deffontsettings.style = DBFONTF_UNDERLINE;
+ //fid.deffontsettings.colour = RGB(0,0,255);
+ FontRegisterT(&fid);
+
+ ColourIDT cid = {0};
+ cid.cbSize = sizeof(ColourIDT);
+ lstrcpy(cid.group, _T(PU_FNT_AND_COLOR));
+ strcpy(cid.dbSettingsGroup, PU_FNT_AND_COLOR_DB);
+
+ lstrcpy(cid.name, _T(PU_COL_BACK_NAME));
+ strcpy(cid.setting, PU_COL_BACK_SETTING);
+ cid.defcolour = SETTING_BACKCOLOUR_DEFAULT;
+ CallService(MS_COLOUR_REGISTERT, (WPARAM)&cid, 0);
+
+ lstrcpy(cid.name, _T(PU_COL_AVAT_NAME));
+ strcpy(cid.setting, PU_COL_AVAT_SETTING);
+ cid.defcolour = SETTING_TEXTCOLOUR_DEFAULT;
+ CallService(MS_COLOUR_REGISTERT, (WPARAM)&cid, 0);
+
+ ReloadFonts();
+}
+
+
+void ReloadFonts()
+{
+ if (fonts.title) DeleteObject(fonts.title);
+ if (fonts.clock) DeleteObject(fonts.clock);
+ if (fonts.text) DeleteObject(fonts.text);
+ if (fonts.action) DeleteObject(fonts.action);
+ if (fonts.actionHover) DeleteObject(fonts.actionHover);
+
+ LOGFONT lf = {0};
+ FontIDT fid = {0};
+ fid.cbSize = sizeof(FontIDT);
+ lstrcpy(fid.group, _T(PU_FNT_AND_COLOR));
+
+ lstrcpy(fid.name, _T(PU_FNT_NAME_TITLE));
+ fonts.clTitle = (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)&lf);
+ fonts.title = CreateFontIndirect(&lf);
+
+ lstrcpy(fid.name, _T(PU_FNT_NAME_CLOCK));
+ fonts.clClock = (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)&lf);
+ fonts.clock = CreateFontIndirect(&lf);
+
+ lstrcpy(fid.name, _T(PU_FNT_NAME_TEXT));
+ fonts.clText = (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)&lf);
+ fonts.text = CreateFontIndirect(&lf);
+
+ lstrcpy(fid.name, _T("Action"));
+ fonts.clAction = (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)&lf);
+ fonts.action = CreateFontIndirect(&lf);
+
+ lstrcpy(fid.name, _T("Hovered Action"));
+ fonts.clActionHover = (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)&lf);
+ fonts.actionHover = CreateFontIndirect(&lf);
+
+ ColourIDT cid = {0};
+ cid.cbSize = sizeof(ColourIDT);
+ lstrcpy(cid.group, _T(PU_FNT_AND_COLOR));
+ lstrcpy(cid.name, _T(PU_COL_BACK_NAME));
+ fonts.clBack = (COLORREF)CallService(MS_COLOUR_GETT, (WPARAM)&cid, (LPARAM)&lf);
+
+ lstrcpy(cid.group, _T(PU_FNT_AND_COLOR));
+ lstrcpy(cid.name, _T(PU_COL_AVAT_NAME));
+ fonts.clAvatarBorder = (COLORREF)CallService(MS_COLOUR_GETT, (WPARAM)&cid, (LPARAM)&lf);
+
+ //update class popupps(only temp at this point, must rework)
+ char setting[256];
+ for(int i = 0; i < gTreeData.getCount(); i++) {
+ if(gTreeData[i]->typ == 2) {
+ mir_snprintf(setting, 256, "%s/TextCol", gTreeData[i]->pupClass.pszName);
+ gTreeData[i]->colorText = gTreeData[i]->pupClass.colorText =
+ (COLORREF)DBGetContactSettingDword(0, PU_MODULCLASS, setting, (DWORD)fonts.clText);
+ mir_snprintf(setting, 256, "%s/BgCol", gTreeData[i]->pupClass.pszName);
+ gTreeData[i]->colorBack = gTreeData[i]->pupClass.colorBack =
+ (COLORREF)DBGetContactSettingDword(0, PU_MODULCLASS, setting, (DWORD)fonts.clBack/*pc->colorBack*/);
+ }
+ }
+}
diff --git a/plugins/Popup/src/font.h b/plugins/Popup/src/font.h
new file mode 100644
index 0000000000..db7b5d7dc1
--- /dev/null
+++ b/plugins/Popup/src/font.h
@@ -0,0 +1,81 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/font.h $
+Revision : $Revision: 1623 $
+Last change on : $Date: 2010-06-24 18:47:07 +0300 (Чт, 24 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __font_h__
+#define __font_h__
+
+//basic constants for all popup plugins
+#define PU_FNT_AND_COLOR "Popups" //common main group for customice\font&color
+#define PU_FNT_AND_COLOR_DB PU_COMMONMODUL //use eg strcpy(fid.dbSettingsGroup, PU_FNT_GROUP_DB);
+
+#define PU_FNT_PREFIX "fnt%s" //use eg mir_snprintf(fid.prefix, sizeof(fid.prefix), PU_FNT_PREFIX, PU_FNT_NAME_....);
+#define PU_FNT_NAME_TITLE "Title" //use eg lstrcpy(fid.name, _T(FNT_NAME_....)) for FontIDT
+#define PU_FNT_NAME_CLOCK "Clock"
+#define PU_FNT_NAME_TEXT "Text"
+
+#define PU_COL_BACK_NAME "Background"
+#define PU_COL_BACK_SETTING "ColourBg"
+#define PU_COL_BORD_NAME "Border"
+#define PU_COL_BORD_SETTING "ColourBorder"
+#define PU_COL_SIDE_NAME "Sidebar"
+#define PU_COL_SIDE_SETTING "ColourSidebar"
+#define PU_COL_LINE_NAME "Title underline"
+#define PU_COL_LINE_SETTING "ColourUnderline"
+#define PU_COL_AVAT_NAME "Avatar Border"
+#define PU_COL_AVAT_SETTING "ColourAvatarBorder"
+
+struct PopupFonts
+{
+ HFONT title;
+ HFONT text;
+ HFONT clock;
+ HFONT action;
+ HFONT actionHover;
+
+ COLORREF clTitle;
+ COLORREF clText;
+ COLORREF clClock;
+ COLORREF clBack;
+ COLORREF clAction;
+ COLORREF clActionHover;
+ COLORREF clAvatarBorder;
+
+};
+
+extern PopupFonts fonts;
+
+void InitFonts();
+
+void ReloadFonts();
+
+
+#endif // __font_h__
diff --git a/plugins/Popup/src/formula.cpp b/plugins/Popup/src/formula.cpp
new file mode 100644
index 0000000000..37002c9d18
--- /dev/null
+++ b/plugins/Popup/src/formula.cpp
@@ -0,0 +1,177 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/formula.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static inline bool myisspace(char ch)
+{
+ return (ch >= 0) && (ch <= 32);
+}
+
+int Formula::eval_neq(char *&s, Args *args, bool *vars) const
+{
+ int left = eval_sum(s, args, vars);
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if (*s == '<')
+ {
+ // this is needed due to side effects caused by min() macro...
+ int tmp = eval_sum(++s, args, vars);
+ left = min(left, tmp);
+ } else
+ if (*s == '>')
+ {
+ // this is needed due to side effects caused by max() macro...
+ int tmp = eval_sum(++s, args, vars);
+ left = max(left, tmp);
+ } else
+ {
+ break;
+ }
+ }
+ return left;
+}
+
+int Formula::eval_sum(char *&s, Args *args, bool *vars) const
+{
+ int left = eval_mul(s, args, vars);
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if (*s == '+')
+ {
+ left += eval_mul(++s, args, vars);
+ } else
+ if (*s == '-')
+ {
+ left -= eval_mul(++s, args, vars);
+ } else
+ {
+ break;
+ }
+ }
+ return left;
+}
+
+int Formula::eval_mul(char *&s, Args *args, bool *vars) const
+{
+ int left = eval_atom(s, args, vars);
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if(*s == '*')
+ {
+ left *= eval_atom(++s, args, vars);
+ } else
+ if(*s == '/')
+ {
+ if (int right = eval_atom(++s, args, vars))
+ left /= right;
+ } else
+ if(*s == '%')
+ {
+ if (int right = eval_atom(++s, args, vars))
+ left %= right;
+ } else
+ {
+ break;
+ }
+ }
+ return left;
+}
+
+int Formula::eval_atom(char *&s, Args *args, bool *vars) const
+{
+ while (*s)
+ {
+ if (myisspace(*s))
+ {
+ ++s;
+ } else
+ if (*s == '(')
+ {
+ int res = eval_neq(++s, args, vars);
+ if (*s == ')')
+ ++s;
+ return res;
+ } else
+ if ((*s == '+') || (*s == '-'))
+ {
+ int sign = 1;
+ if (*s == '-')
+ sign = -1;
+ return sign * eval_neq(++s, args, vars);
+ } else
+ if (*s == '!')
+ {
+ return !eval_neq(++s, args, vars);
+ } else
+ if ((*s >= '0') && (*s <= '9'))
+ {
+ int res = 0;
+ while ((*s >= '0') && (*s <= '9'))
+ res = res * 10 + *s++ - '0';
+ return res;
+ } else
+ {
+ if (!args)
+ return 0;
+ char buf[1024];
+ char *bufptr = buf;
+ while (((*s >= '0') && (*s <= '9')) || ((*s >= 'a') && (*s <= 'z')) || ((*s >= 'A') && (*s <= 'A')) || (*s == '_') || (*s == '.'))
+ *bufptr++ = *s++;
+ *bufptr = 0;
+ int res = args->get(buf);
+ if (vars) *vars = true;
+ return res;
+ }
+ }
+ return 0;
+}
+
+int Formula::eval(Args *args, bool *vars) const
+{
+ if (vars) *vars = false;
+ char *s = m_str;
+ int res = eval_neq(s, args, vars);
+ return res;
+}
diff --git a/plugins/Popup/src/formula.h b/plugins/Popup/src/formula.h
new file mode 100644
index 0000000000..b0239c5551
--- /dev/null
+++ b/plugins/Popup/src/formula.h
@@ -0,0 +1,98 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/formula.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __formula_h__
+#define __formula_h__
+
+class Formula
+{
+public:
+ class Args
+ {
+ private:
+ struct Item
+ {
+ char *name;
+ int value;
+ Item *next;
+
+ Item(char *aName, int aValue, Item *aNext): value(aValue), next(aNext) { name = aName ? mir_strdup(aName) : 0; }
+ ~Item() { if (name) mir_free(name); }
+ };
+ Item *items;
+ public:
+ Args():items(0){}
+ ~Args(){clear();}
+ void add(char *name, int value)
+ {
+ for (Item *p = items; p; p = p->next)
+ if (!lstrcmpA(p->name,name))
+ {
+ p->value = value;
+ return;
+ }
+ items = new Item(name, value, items);
+ }
+ int get(char *name)
+ {
+ for (Item *p = items; p; p = p->next)
+ if (!lstrcmpA(p->name,name))
+ return p->value;
+ return 0;
+ }
+ void clear()
+ {
+ while (items)
+ {
+ Item *p = items->next;
+ delete items;
+ items = p;
+ }
+ }
+ };
+
+private:
+ char *m_str;
+ int eval_neq (char *&s, Args *args, bool *vars) const;
+ int eval_sum (char *&s, Args *args, bool *vars) const;
+ int eval_mul (char *&s, Args *args, bool *vars) const;
+ int eval_atom(char *&s, Args *args, bool *vars) const;
+
+public:
+ Formula():m_str(mir_strdup("")){}
+ Formula(char *s):m_str(mir_strdup(s)){}
+ ~Formula() {mir_free(m_str);}
+ void set(char *s){mir_free(m_str);m_str=mir_strdup(s);}
+ int eval(Args *args, bool *vars = 0) const;
+};
+
+#endif // __formula_h__ \ No newline at end of file
diff --git a/plugins/Popup/src/headers.cpp b/plugins/Popup/src/headers.cpp
new file mode 100644
index 0000000000..abf3bad493
--- /dev/null
+++ b/plugins/Popup/src/headers.cpp
@@ -0,0 +1,34 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/headers.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
diff --git a/plugins/Popup/src/headers.h b/plugins/Popup/src/headers.h
new file mode 100644
index 0000000000..217424579d
--- /dev/null
+++ b/plugins/Popup/src/headers.h
@@ -0,0 +1,190 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+*/
+
+/*
+===============================================================================
+ PopUp plugin
+
+This plugin notifies you when a contact changes his/hers status with a PopUp.
+You can customize its look (style of popup, font, text...) and behaviour (the
+position in the screen, the time to live, the action on a mouse click).
+
+File name: "headers.h"
+This file has the purpose of becoming a precompiled header common to every
+project file.
+
+Written by: Hrk (Luca Santarelli)
+Updated by: Zazoo (Victor Pavlychko)
+
+Miranda IM can be found here:
+http://www.miranda-im.org/
+
+Miranda IM plugins and tools can be found here:
+http://addons.miranda-im.org/
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/headers.h $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef HEADERS_H
+#define HEADERS_H
+
+ // disable security warnings about "*_s" functions
+ #define _CRT_SECURE_NO_DEPRECATE
+
+ // disable warnings about underscore in stdc functions
+ #pragma warning(disable: 4996)
+
+ #define _WIN32_WINNT 0x0501
+ #define WINVER 0x0500
+ #define OEMRESOURCE
+
+ #include <windows.h>
+ #include <windowsx.h>
+ #include <winuser.h>
+
+ //Standard headers
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <time.h>
+ #include <malloc.h>
+
+ //Windows headers
+ #include <process.h>
+ #include <commctrl.h>
+ #include <commdlg.h>
+
+#ifdef ComboBox_SelectItemData
+ // use Workaround for MS bug ComboBox_SelectItemData;
+ #undef ComboBox_SelectItemData
+#endif
+
+ //Resources
+ #include "../resource.h"
+
+ #define NOWIN2K
+ #define MIRANDA_VER 0x0900
+ #define MIRANDA_CUSTOM_LP
+
+ //Miranda API (see Miranda svn)
+ #include <newpluginapi.h>
+ #include <win2k.h>
+ #include <m_system.h>
+ #include <m_plugins.h>
+ #include <m_clui.h>
+ #include <m_clist.h>
+ #include <m_options.h>
+ #include <m_skin.h>
+ #include <m_langpack.h>
+ #include <m_database.h>
+ #undef DBGetContactSettingString
+ #include <m_protocols.h>
+ #include <m_protosvc.h>
+ #include <m_utils.h>
+ #include <m_button.h>
+ #include <m_message.h>
+ #include <m_userinfo.h>
+ #include <m_addcontact.h>
+ #include <m_png.h>
+ #include <m_clc.h>
+ #include <m_icolib.h>
+ #include <m_hotkeys.h>
+ #include <m_fontservice.h>
+ #include <m_avatars.h>
+ #include <m_metacontacts.h>
+
+ #include <m_system_cpp.h>
+
+
+ // API for 3rd party plugins (\include_API folder)
+ // this folder contain always the latest API
+ #include <m_folders.h>
+ #include <m_hpp.h>
+ #include <m_ieview.h>
+ #include <m_nconvers.h>
+// #include <m_notify.h> //deprecatet
+ #include <m_notify_popup.h>
+ #include <m_smileyadd.h>
+ #ifndef MTEXT_NOHELPERS
+ #define MTEXT_NOHELPERS
+ #endif // MTEXT_NOHELPERS
+ #include <m_text.h>
+ #include <m_ticker.h>
+ #include <m_toolbar.h>
+ #include <m_toptoolbar.h>
+ #include <m_updater.h>
+ #include <m_popup.h> //core define see miranda\include\
+
+ // API for 3rd party plugins (.\api folder)
+ // this folder contain spetial edition API (not latest API !!!)
+ #include "m_mathmodule.h"
+ #include "m_popup2.h"
+
+ //PopUp common handlers
+ #include "defs.h"
+ #include "../version.h"
+ #include "config.h"
+ #include "common.h"
+ #include "def_settings.h"
+// #include "notify_imp.h" //deprecatet
+ #include "opttree.h"
+// #include "opt_old.h" //deprecatet
+ #include "opt_gen.h"
+// #include "opt_notify.h" //deprecatet
+ #include "opt_skins.h"
+ #include "opt_contacts.h"
+ #include "opt_adv.h"
+ #include "history.h"
+ #include "services.h"
+ #include "srmm_menu.h"
+ #include "bitmap_funcs.h"
+ #include "icons.h"
+ #include "font.h"
+ #include "formula.h"
+ #include "skin.h"
+ #include "popup_thread.h"
+ #include "actions.h"
+ #include "notifications.h"
+ #include "opt_class.h"
+ #include "popup_wnd2.h"
+ #include "effects.h"
+// #include "popup_queue.h"
+// #include "popup_list.h"
+
+ #include "avatars.h"
+ #include "avatars_simple.h"
+ #include "avatars_flash.h"
+ #include "avatars_gif.h"
+
+ #include "popup_gdiplus.h"
+
+INT_PTR svcEnableDisableMenuCommand(WPARAM, LPARAM);
+extern HANDLE hSquareFad;
+
+#endif //HEADERS_H
diff --git a/plugins/Popup/src/history.cpp b/plugins/Popup/src/history.cpp
new file mode 100644
index 0000000000..baf5e1797d
--- /dev/null
+++ b/plugins/Popup/src/history.cpp
@@ -0,0 +1,550 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/history.cpp $
+Revision : $Revision: 1631 $
+Last change on : $Date: 2010-07-08 08:22:12 +0300 (Чт, 08 июл 2010) $
+Last change by : $Author: MPK $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static POPUPDATA2 *popupHistory;
+static int popupHistoryStart = 0;
+static int popupHistorySize = 0;
+static int popupHistoryBuffer = 100;
+
+#define UM_RESIZELIST (WM_USER+100)
+#define UM_SELECTLAST (WM_USER+101)
+#define UM_ADDITEM (WM_USER+102)
+static HWND hwndHistory = NULL;
+
+static inline int getHistoryIndex(int idx)
+{
+ return (popupHistoryStart + idx) % popupHistoryBuffer;
+}
+
+static inline POPUPDATA2 *getHistoryItem(int idx)
+{
+ return popupHistory + (popupHistoryStart + idx) % popupHistoryBuffer;
+}
+
+static INT_PTR CALLBACK HistoryDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void PopupHistoryLoad()
+{
+ popupHistoryBuffer = DBGetContactSettingWord(NULL, MODULNAME, "HistorySize", SETTING_HISTORYSIZE_DEFAULT);
+ popupHistory = new POPUPDATA2[popupHistoryBuffer];
+}
+
+void PopupHistoryResize()
+{
+ int i;
+ int toDelete = 0;
+ int toCopy = popupHistorySize;
+ if (popupHistoryBuffer == PopUpOptions.HistorySize) return;
+ if (hwndHistory) PostMessage(hwndHistory, WM_CLOSE, 0, 0);
+ POPUPDATA2 *oldPopupHistory = popupHistory;
+ int oldStart = popupHistoryStart;
+ int oldBuffer = popupHistoryBuffer;
+ popupHistory = new POPUPDATA2[PopUpOptions.HistorySize];
+ popupHistoryStart = 0;
+ popupHistoryBuffer = PopUpOptions.HistorySize;
+ if(PopUpOptions.HistorySize < popupHistorySize){ //if old history bigger new one
+ toDelete = popupHistorySize - PopUpOptions.HistorySize;
+ toCopy = PopUpOptions.HistorySize;
+ popupHistorySize = PopUpOptions.HistorySize;
+ }
+ for(i = 0; i < toCopy; ++i){ //copy needed
+ popupHistory[i] = oldPopupHistory[(oldStart + toDelete + i)%oldBuffer];
+ }
+ for(i = 0; i < toDelete; ++i){//free too old ones
+ POPUPDATA2 *ppd = &oldPopupHistory[(oldStart + i)%oldBuffer];
+ if (ppd->flags & PU2_UNICODE)
+ {
+ mir_free(ppd->lpwzTitle);
+ mir_free(ppd->lpwzText);
+ } else
+ {
+ mir_free(ppd->lpzTitle);
+ mir_free(ppd->lpzText);
+ }
+ if (ppd->lpzSkin) mir_free(ppd->lpzSkin);
+ }
+ delete [] oldPopupHistory;
+}
+
+void PopupHistoryUnload()
+{
+ for (int i = 0; i < popupHistorySize; ++i)
+ {
+ POPUPDATA2 *ppd = &popupHistory[getHistoryIndex(i)];
+ if (ppd->flags & PU2_UNICODE)
+ {
+ mir_free(ppd->lpwzTitle);
+ mir_free(ppd->lpwzText);
+ } else
+ {
+ mir_free(ppd->lpzTitle);
+ mir_free(ppd->lpzText);
+ }
+ if (ppd->lpzSkin) mir_free(ppd->lpzSkin);
+ }
+ delete [] popupHistory;
+ popupHistory = NULL;
+}
+
+void PopupHistoryAdd(POPUPDATA2 *ppdNew)
+{
+ if (!PopUpOptions.EnableHistory)
+ return;
+
+ POPUPDATA2 *ppd;
+ if (popupHistorySize < popupHistoryBuffer)
+ {
+ ++popupHistorySize;
+ ppd = &popupHistory[getHistoryIndex(popupHistorySize-1)];
+ } else
+ {
+ popupHistoryStart = (popupHistoryStart+1)%popupHistoryBuffer;
+ ppd = &popupHistory[getHistoryIndex(popupHistorySize-1)];
+ if (ppd->flags & PU2_UNICODE)
+ {
+ mir_free(ppd->lpwzTitle);
+ mir_free(ppd->lpwzText);
+ } else
+ {
+ mir_free(ppd->lpzTitle);
+ mir_free(ppd->lpzText);
+ }
+ if (ppd->lpzSkin) mir_free(ppd->lpzSkin);
+ }
+
+ *ppd = *ppdNew;
+ if (ppd->flags&PU2_UNICODE)
+ {
+ ppd->lpwzTitle = mir_wstrdup(ppd->lpwzTitle);
+ ppd->lpwzText = mir_wstrdup(ppd->lpwzText);
+ } else
+ {
+ ppd->lpzTitle = mir_strdup(ppd->lpzTitle);
+ ppd->lpzText = mir_strdup(ppd->lpzText);
+ }
+ if (ppd->lpzSkin)
+ {
+ ppd->lpzSkin = mir_strdup(ppd->lpzSkin);
+ } else
+ {
+ ppd->lpzSkin = NULL;
+ }
+ ppd->dwTimestamp = time(NULL);
+// GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm", ppd->lpzTime, sizeof(ppd->lpzTime));
+ if (hwndHistory)
+ PostMessage(hwndHistory, UM_ADDITEM, 0, (LPARAM)ppd);
+}
+
+void PopupHistoryShow()
+{
+ if (!PopUpOptions.EnableHistory){
+ MessageBox(NULL, TranslateT("Popup History is disabled"), TranslateT("Popup History message"), MB_OK);
+ return;
+ }
+
+ if (hwndHistory)
+ {
+ ShowWindow(hwndHistory, SW_SHOW);
+ SetForegroundWindow(hwndHistory);
+ SetFocus(hwndHistory);
+ SetActiveWindow(hwndHistory);
+ } else
+ {
+ hwndHistory = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HISTORY), NULL, HistoryDlgProc);
+ SetWindowText(hwndHistory, TranslateT("Popup History"));
+ //ShowWindow(hwndHistory, SW_SHOW);
+ }
+}
+
+static INT_PTR CALLBACK HistoryDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int oldWidth = 0;
+ static int loadItem = -1;
+
+ static enum { LOG_NONE, LOG_DEFAULT, LOG_HPP } logType = LOG_NONE;
+ static HWND hwndLog = NULL;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ oldWidth = 0;
+ HWND hwndList = GetDlgItem(hwnd, IDC_POPUP_LIST);
+ for (int i = 0; i < popupHistorySize; ++i)
+ ListBox_SetItemData(hwndList, ListBox_AddString(hwndList, _T("")), 0);
+ SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)IcoLib_GetIcon(ICO_HISTORY,0));
+ SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)IcoLib_GetIcon(ICO_HISTORY,1));
+
+ if (gbHppInstalled && PopUpOptions.UseHppHistoryLog)
+ {
+ logType = LOG_HPP;
+ ShowWindow(GetDlgItem(hwnd, IDC_POPUP_LIST), SW_HIDE);
+
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_CREATE;
+ ieWindow.dwFlags = 0;
+ ieWindow.dwMode = IEWM_MUCC;
+// ieWindow.dwMode = IEWM_CHAT;
+ ieWindow.parent = hwnd;
+ ieWindow.x = 0;
+ ieWindow.y = 0;
+ ieWindow.cx = 100;
+ ieWindow.cy = 100;
+ CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
+ hwndLog = ieWindow.hwnd;
+ ShowWindow(hwndLog, SW_SHOW);
+
+ RECT rcLst; GetWindowRect(hwndList, &rcLst);
+ POINT pt;
+ pt.x = rcLst.left;
+ pt.y = rcLst.top;
+ ScreenToClient(hwnd, &pt);
+
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_SETPOS;
+ ieWindow.parent = hwnd;
+ ieWindow.hwnd = hwndLog;
+ ieWindow.x = pt.x;
+ ieWindow.y = pt.y;
+ ieWindow.cx = rcLst.right-rcLst.left;
+ ieWindow.cy = rcLst.bottom-rcLst.top;
+ CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
+
+ IEVIEWEVENTDATA ieData;
+
+ IEVIEWEVENT ieEvent;
+ ieEvent.cbSize = sizeof(ieEvent);
+ ieEvent.iType = IEE_LOG_MEM_EVENTS;
+ ieEvent.dwFlags = 0;
+ ieEvent.hwnd = hwndLog;
+ ieEvent.eventData = &ieData;
+ ieEvent.count = 1;
+ ieEvent.codepage = 0;
+ ieEvent.pszProto = NULL;
+
+ for (int i = 0; i < popupHistorySize; ++i)
+ {
+ ieData.cbSize = sizeof(ieData);
+ ieData.iType = IEED_EVENT_SYSTEM;
+ ieData.dwFlags = 0;
+ ieData.color = getHistoryItem(i)->colorText;
+ if (getHistoryItem(i)->flags & PU2_UNICODE)
+ {
+ ieData.dwFlags |= IEEDF_UNICODE_TEXT|IEEDF_UNICODE_NICK;
+ ieData.pszNickW = getHistoryItem(i)->lpwzTitle;
+ ieData.pszTextW = getHistoryItem(i)->lpwzText;
+ ieData.pszText2W = NULL;
+ } else
+ {
+ ieData.dwFlags |= 0;
+ ieData.pszNick = getHistoryItem(i)->lpzTitle;
+ ieData.pszText = getHistoryItem(i)->lpzText;
+ ieData.pszText2 = NULL;
+ }
+ ieData.bIsMe = FALSE;
+ ieData.time = getHistoryItem(i)->dwTimestamp;
+ ieData.dwData = 0;
+ ieData.next = NULL;
+ CallService(MS_HPP_EG_EVENT, 0, (WPARAM)&ieEvent);
+ }
+ } else
+ {
+ logType = LOG_DEFAULT;
+ hwndLog = hwndList;
+
+ ShowWindow(hwndLog, SW_SHOW);
+ }
+
+ Utils_RestoreWindowPosition(hwnd, NULL, MODULNAME, "popupHistory_");
+
+ if (logType == LOG_DEFAULT)
+ {
+ SendMessage(hwnd, UM_RESIZELIST, 0, 0);
+ ListBox_SetTopIndex(hwndLog, popupHistorySize-1);
+ }
+
+ return TRUE;
+ }
+ case WM_MEASUREITEM:
+ {
+ if (logType != LOG_DEFAULT)
+ return TRUE;
+
+ LPMEASUREITEMSTRUCT lpmis;
+ lpmis = (LPMEASUREITEMSTRUCT) lParam;
+ if (lpmis->itemID == -1)
+ return FALSE;
+ lpmis->itemHeight = 50;
+ return TRUE;
+ }
+ case WM_DRAWITEM:
+ {
+ if (logType != LOG_DEFAULT)
+ return TRUE;
+
+ LPDRAWITEMSTRUCT lpdis;
+ lpdis = (LPDRAWITEMSTRUCT) lParam;
+ if (lpdis->itemID == -1)
+ return FALSE;
+
+ HWND hwndList = GetDlgItem(hwnd, lpdis->CtlID);
+ PopupWnd2 *wndPreview = (PopupWnd2 *)ListBox_GetItemData(hwndList, lpdis->itemID);
+
+ if (!wndPreview)
+ {
+ RECT rc; GetWindowRect(hwndLog, &rc);
+
+ if (rc.right-rc.left <= 30)
+ return FALSE;
+
+ POPUPOPTIONS customOptions = PopUpOptions;
+ customOptions.DynamicResize = FALSE;
+ customOptions.MinimumWidth = customOptions.MaximumWidth = rc.right-rc.left-30;
+
+ POPUPDATA2 *ppd = &popupHistory[getHistoryIndex(lpdis->itemID)];
+ wndPreview = new PopupWnd2(ppd, &customOptions, true);
+ wndPreview->buildMText();
+ wndPreview->update();
+
+ ListBox_SetItemData(hwndLog, lpdis->itemID, wndPreview);
+ ListBox_SetItemHeight(hwndLog, lpdis->itemID, wndPreview->getSize().cy+6);
+ }
+
+ if (wndPreview)
+ {
+ if (lpdis->itemState & ODS_SELECTED)
+ {
+ HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
+ FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
+ DeleteObject(hbr);
+ } else
+ {
+ HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+ FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
+ DeleteObject(hbr);
+ }
+
+ int width = wndPreview->getContent()->getWidth();
+ int height = wndPreview->getContent()->getHeight();
+#if defined(_UNICODE)
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(lpdis->hDC, lpdis->rcItem.left+5, lpdis->rcItem.top+3, width, height,
+ wndPreview->getContent()->getDC(),
+ 0, 0, width, height, bf);
+ }
+#else
+ if (MyAlphaBlend)
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ MyAlphaBlend(lpdis->hDC, lpdis->rcItem.left+5, lpdis->rcItem.top+3, width, height,
+ wndPreview->getContent()->getDC(),
+ 0, 0, width, height, bf);
+ }
+ else {
+ BitBlt(lpdis->hDC,
+ lpdis->rcItem.left+5, lpdis->rcItem.top+5, lpdis->rcItem.left+5+width, lpdis->rcItem.top+3+height,
+ wndPreview->getContent()->getDC(),
+ 0, 0, SRCCOPY);
+ }
+#endif
+ }
+
+ return TRUE;
+ }
+ case WM_DELETEITEM:
+ {
+ if (logType != LOG_DEFAULT)
+ return TRUE;
+
+ DELETEITEMSTRUCT *lpdis = (DELETEITEMSTRUCT *)lParam;
+ PopupWnd2 *wnd = (PopupWnd2 *)ListBox_GetItemData(lpdis->hwndItem, lpdis->itemID);
+ if (wnd) delete wnd;
+ return TRUE;
+ }
+ case WM_SIZE:
+ {
+ RECT rcLst; GetClientRect(hwnd, &rcLst);
+ rcLst.left += 10;
+ rcLst.top += 10;
+ rcLst.right -= 10;
+ rcLst.bottom -= 10;
+ if (logType == LOG_HPP)
+ {
+// POINT pt;
+// pt.x = rcLst.left;
+// pt.y = rcLst.top;
+// ScreenToClient(hwnd, &pt);
+ SetWindowPos(hwndLog, NULL,
+ rcLst.left, rcLst.top, rcLst.right-rcLst.left, rcLst.bottom-rcLst.top,
+ SWP_NOZORDER|SWP_DEFERERASE|SWP_SHOWWINDOW);
+
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_SETPOS;
+ ieWindow.parent = hwnd;
+ ieWindow.hwnd = hwndLog;
+ ieWindow.x = rcLst.left;
+ ieWindow.y = rcLst.top;
+ ieWindow.cx = rcLst.right-rcLst.left;
+ ieWindow.cy = rcLst.bottom-rcLst.top;
+ CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
+ } else
+ if (logType == LOG_DEFAULT)
+ {
+ SetWindowPos(hwndLog, NULL,
+ rcLst.left, rcLst.top, rcLst.right-rcLst.left, rcLst.bottom-rcLst.top,
+ SWP_NOZORDER|SWP_DEFERERASE|SWP_SHOWWINDOW);
+ if (rcLst.right-rcLst.left != oldWidth)
+ {
+ oldWidth = rcLst.right-rcLst.left;
+ PostMessage(hwnd, UM_RESIZELIST, 0, 0);
+ }
+ }
+ return TRUE;
+ }
+ case UM_RESIZELIST:
+ {
+ if (logType != LOG_DEFAULT)
+ return TRUE;
+
+ RECT rc; GetWindowRect(GetDlgItem(hwnd, IDC_POPUP_LIST), &rc);
+
+ if (rc.right-rc.left <= 30)
+ return FALSE;
+
+ for (int i = 0; i < popupHistorySize; ++i)
+ {
+ PopupWnd2 *wndPreview = (PopupWnd2 *)ListBox_GetItemData(hwndLog, i);
+ if (wndPreview) delete wndPreview;
+
+ ListBox_SetItemData(hwndLog, i, 0);
+ ListBox_SetItemHeight(hwndLog, i, 50);
+ }
+ ScrollWindow(hwndLog, 0, 100000, NULL, NULL);
+ InvalidateRect(hwndLog, NULL, TRUE);
+
+ return TRUE;
+ }
+ case UM_ADDITEM:
+ {
+ if (logType == LOG_HPP)
+ {
+ POPUPDATA2 *ppd = (POPUPDATA2 *)lParam;
+
+ IEVIEWEVENTDATA ieData;
+
+ IEVIEWEVENT ieEvent;
+ ieEvent.cbSize = sizeof(ieEvent);
+ ieEvent.iType = IEE_LOG_MEM_EVENTS;
+ ieEvent.dwFlags = 0;
+ ieEvent.hwnd = hwndLog;
+ ieEvent.eventData = &ieData;
+ ieEvent.count = 1;
+ ieEvent.codepage = 0;
+ ieEvent.pszProto = NULL;
+
+ ieData.cbSize = sizeof(ieData);
+ ieData.dwFlags = 0;
+ ieData.iType = IEED_EVENT_SYSTEM;
+ ieData.color = ppd->colorText;
+ if (ppd->flags & PU2_UNICODE)
+ {
+ ieData.dwFlags |= IEEDF_UNICODE_TEXT|IEEDF_UNICODE_NICK;
+ ieData.pszNickW = ppd->lpwzTitle;
+ ieData.pszTextW = ppd->lpwzText;
+ ieData.pszText2W = NULL;
+ } else
+ {
+ ieData.dwFlags |= 0;
+ ieData.pszNick = ppd->lpzTitle;
+ ieData.pszText = ppd->lpzText;
+ ieData.pszText2 = NULL;
+ }
+ ieData.bIsMe = FALSE;
+ ieData.time = ppd->dwTimestamp;
+ ieData.dwData = 0;
+ ieData.next = NULL;
+ CallService(MS_HPP_EG_EVENT, 0, (WPARAM)&ieEvent);
+ } else
+ if(logType == LOG_DEFAULT)
+ {
+ if (popupHistorySize <= ListBox_GetCount(hwndLog))
+ {
+ loadItem = 0;
+ PostMessage(hwnd, UM_RESIZELIST, 0, 0);
+ return TRUE;
+ }
+ ListBox_SetItemData(hwndLog, ListBox_AddString(hwndLog, _T("")), 0);
+/* if (loadItem < 0)
+ {
+ loadItem = ListBox_GetCount(hwndList)-1;
+ SendMessage(hwnd, UM_RESIZEITEM, 0, 0);
+ }*/
+ }
+ return TRUE;
+ }
+ case WM_CLOSE:
+ {
+ Utils_SaveWindowPosition(hwnd, NULL, MODULNAME, "popupHistory_");
+ DestroyWindow(hwnd);
+ hwndHistory = NULL;
+ return TRUE;
+ }
+ case WM_DESTROY:
+ {
+ if (logType == LOG_HPP)
+ {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_DESTROY;
+ ieWindow.dwFlags = 0;
+ ieWindow.dwMode = IEWM_TABSRMM;
+ ieWindow.parent = hwnd;
+ ieWindow.hwnd = hwndLog;
+ CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
+ }
+ }
+ }
+ return FALSE; //DefWindowProc(hwnd, msg, wParam, lParam);
+}
diff --git a/plugins/Popup/src/history.h b/plugins/Popup/src/history.h
new file mode 100644
index 0000000000..ee7d4f4f8e
--- /dev/null
+++ b/plugins/Popup/src/history.h
@@ -0,0 +1,43 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/history.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __history_h__
+#define __history_h__
+
+void PopupHistoryLoad();
+void PopupHistoryResize();
+void PopupHistoryUnload();
+
+void PopupHistoryAdd(POPUPDATA2 *ppd);
+void PopupHistoryShow();
+
+#endif // __history_h__
diff --git a/plugins/Popup/src/icons.cpp b/plugins/Popup/src/icons.cpp
new file mode 100644
index 0000000000..cb6e87dcc7
--- /dev/null
+++ b/plugins/Popup/src/icons.cpp
@@ -0,0 +1,145 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/icons.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+typedef struct _ICODESC
+{
+ LPSTR pszName;
+ LPTSTR ptszDesc;
+ LPTSTR ptszSection;
+ BOOL bfromIconPack;
+ WORD idResource;
+ LPSTR pszIcon;
+ int size;
+} ICODESC;
+
+static ICODESC icoDesc[] =
+{
+ //toolbar
+ { ICO_TB_POPUP_ON, _T("Popups are enabled"), _T(SECT_TOLBAR), 0, IDI_POPUP, NULL, 0 },
+ { ICO_TB_POPUP_OFF, _T("Popups are disabled"), _T(SECT_TOLBAR), 0, IDI_NOPOPUP, NULL, 0 },
+ //common popup
+ { ICO_POPUP_ON, _T("Popups are enabled"), _T(SECT_POPUP), 0, IDI_POPUP, NULL, 0 },
+ { ICO_POPUP_OFF, _T("Popups are disabled"), _T(SECT_POPUP), 0, IDI_NOPOPUP, NULL, 0 },
+ { ICO_FAV, _T("With \"favourite\" overlay"), _T(SECT_POPUP), 0, IDI_PU_FAVOURITE, NULL, 0 },
+ { ICO_FULLSCREEN, _T("With \"fullscreen\" overlay"), _T(SECT_POPUP), 0, IDI_PU_FULLSCREEN, NULL, 0 },
+ { ICO_HISTORY, _T("Popup History"), _T(SECT_POPUP), 0, IDI_HISTORY, NULL, -1 },
+ //misc (register is done inside notification service)
+ //{ ICO_MISC_NOTIFY, _T("Notification"), _T(SECT_POPUP) _T(SECT_POPUP_MISC), 0, IDI_MB_INFO, NULL, 0 },
+ //{ ICO_MISC_WARNING, _T("Warning"), _T(SECT_POPUP) _T(SECT_POPUP_MISC), 0, IDI_MB_WARN, NULL, 0 },
+ //{ ICO_MISC_ERROR, _T("Error"), _T(SECT_POPUP) _T(SECT_POPUP_MISC), 0, IDI_MB_STOP, NULL, 0 },
+ //option
+ { ICO_OPT_RELOAD, _T("Refresh skin list"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_RELOAD, NULL, 0 },
+ { ICO_OPT_RESIZE, _T("Popup Placement"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_RESIZE, NULL, 0 },
+ { ICO_OPT_OK, _T("OK"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_ACT_OK, NULL, 0 },
+ { ICO_OPT_CANCEL, _T("Cancel"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_ACT_CLOSE, NULL, 0 },
+ { ICO_OPT_GROUP, _T("Popup Group"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_OPT_GROUP, NULL, 0 },
+ { ICO_OPT_DEF, _T("Show default"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_ACT_OK, NULL, 0 },
+ { ICO_OPT_FAV, _T("Favorite Contact"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_OPT_FAVORITE, NULL, 0 },
+ { ICO_OPT_FULLSCREEN, _T("Show in Fullscreen"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_OPT_FULLSCREEN, NULL, 0 },
+ { ICO_OPT_BLOCK, _T("Blocked Contact"), _T(SECT_POPUP) _T(SECT_POPUP_OPT), 0, IDI_OPT_BLOCK, NULL, 0 },
+ //action
+ { ICO_ACT_REPLY, _T("Quick Reply"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_REPLY, NULL, -1 },
+ { ICO_ACT_PIN, _T("Pin Popup"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_PIN, NULL, -1 },
+ { ICO_ACT_PINNED, _T("Pinned Popup"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_PINNED, NULL, -1 },
+ { ICO_ACT_MESS, _T("Send Message"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_MESSAGE, NULL, -1 },
+ { ICO_ACT_INFO, _T("User Details"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_INFO, NULL, -1 },
+ { ICO_ACT_MENU, _T("Contact Menu"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_MENU, NULL, -1 },
+ { ICO_ACT_ADD, _T("Add Contact Permanently"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_ADD, NULL, -1 },
+ { ICO_ACT_CLOSE, _T("Dismiss Popup"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_CLOSE, NULL, -1 },
+ { ICO_ACT_COPY, _T("Copy to clipboard"), _T(SECT_POPUP) _T(SECT_POPUP_ACT), 0, IDI_ACT_COPY, NULL, -1 }
+
+};
+
+/**
+ * Returns a icon, identified by a name
+ * @param pszIcon - name of the icon
+ * @param big - bool big icon (default = false)
+ * @return: HICON if the icon is loaded, NULL otherwise
+ **/
+HICON IcoLib_GetIcon(LPCSTR pszIcon, bool big)
+{
+ return (pszIcon) ? (HICON)CallService(MS_SKIN2_GETICON, (WPARAM)big, (LPARAM) pszIcon) : NULL;
+}
+
+void InitIcons()
+{
+ SKINICONDESC sid;
+ ZeroMemory(&sid, sizeof(sid));
+ sid.cbSize = sizeof(sid);
+ sid.flags = SIDF_ALL_TCHAR;
+ TCHAR selfDLL[1024];
+ GetModuleFileName(hInst, selfDLL, 1024);
+
+ for(int i = 0; i < SIZEOF(icoDesc); i++){
+ sid.pszName = icoDesc[i].pszName;
+ sid.ptszDescription = icoDesc[i].ptszDesc; // [TRANSLATED-BY-CORE]
+ sid.ptszSection = icoDesc[i].ptszSection; //must be always untranslatet !!!!!
+
+ if(icoDesc[i].idResource==0){
+ //use icon from icon lib
+ sid.hDefaultIcon = (HICON)CallService(MS_SKIN2_GETICON,0 , (LPARAM)icoDesc[i].pszIcon);
+ sid.ptszDefaultFile = NULL;
+ sid.iDefaultIndex = 0;
+ }else{
+ //load and register from popup.dll
+ sid.hDefaultIcon = 0;
+ sid.ptszDefaultFile = selfDLL;
+ sid.iDefaultIndex = -icoDesc[i].idResource;
+ }
+
+ switch (icoDesc[i].size){
+ // small and big icons
+ case -1:{
+ sid.cx = sid.cy = 0;
+ break;
+ }
+ // small icons (16x16)
+ case 0:{
+ sid.cx = sid.cy = 16;
+ break;
+ }
+ // normal icons (32x32)
+ case 1:{
+ sid.cx = sid.cy = 32;
+ break;
+ }
+ // custom icon size
+ default:{
+ sid.cx = sid.cy = icoDesc[i].size;
+ break;
+ }
+ }
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ }
+} \ No newline at end of file
diff --git a/plugins/Popup/src/icons.h b/plugins/Popup/src/icons.h
new file mode 100644
index 0000000000..532e7cecb4
--- /dev/null
+++ b/plugins/Popup/src/icons.h
@@ -0,0 +1,79 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/icons.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __icons_h__
+#define __icons_h__
+
+//ICONS
+#define SECT_TOLBAR "ToolBar"
+#define SECT_POPUP MODULNAME_PLU
+#define SECT_POPUP_ACT "/Actions"
+#define SECT_POPUP_OPT "/Options"
+#define SECT_POPUP_MISC "/Misc"
+
+#define ICO_TB_POPUP_ON "TBButton_popup_ToogleUp"
+#define ICO_TB_POPUP_OFF "TBButton_popup_ToogleDOWN"
+#define ICO_POPUP_ON MODULNAME"_enabled"
+#define ICO_POPUP_OFF MODULNAME"_disabled"
+#define ICO_FAV MODULNAME"_favourite"
+#define ICO_FULLSCREEN MODULNAME"_fullscreen"
+#define ICO_HISTORY MODULNAME"_history"
+
+#define ICO_MISC_NOTIFY MODULNAME"_Misc_Notification"
+#define ICO_MISC_WARNING MODULNAME"_Misc_Warning"
+#define ICO_MISC_ERROR MODULNAME"_Misc_Error"
+
+#define ICO_ACT_MESS MODULNAME"_act_message"
+#define ICO_ACT_INFO MODULNAME"_act_info"
+#define ICO_ACT_MENU MODULNAME"_act_menu"
+#define ICO_ACT_ADD MODULNAME"_act_add"
+#define ICO_ACT_REPLY MODULNAME"_act_reply"
+#define ICO_ACT_PIN MODULNAME"_act_pin"
+#define ICO_ACT_PINNED MODULNAME"_act_pinned"
+#define ICO_ACT_CLOSE MODULNAME"_act_close"
+#define ICO_ACT_COPY MODULNAME"_act_copy"
+
+#define ICO_OPT_RELOAD MODULNAME"_opt_reload"
+#define ICO_OPT_RESIZE MODULNAME"_opt_resize"
+#define ICO_OPT_GROUP MODULNAME"_opt_group"
+#define ICO_OPT_OK MODULNAME"_opt_ok"
+#define ICO_OPT_CANCEL MODULNAME"_opt_cancel"
+
+#define ICO_OPT_DEF MODULNAME"_opt_default"
+#define ICO_OPT_FAV MODULNAME"_opt_favorite"
+#define ICO_OPT_FULLSCREEN MODULNAME"_opt_fullscreen"
+#define ICO_OPT_BLOCK MODULNAME"_opt_block"
+
+void InitIcons();
+HICON IcoLib_GetIcon(LPCSTR pszIcon, bool big=false);
+
+#endif // __icons_h__
diff --git a/plugins/Popup/src/main.cpp b/plugins/Popup/src/main.cpp
new file mode 100644
index 0000000000..41ad1b56ce
--- /dev/null
+++ b/plugins/Popup/src/main.cpp
@@ -0,0 +1,743 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/main.cpp $
+Revision : $Revision: 1652 $
+Last change on : $Date: 2010-07-15 20:48:21 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+#include <shellapi.h>
+#include <malloc.h>
+
+WORD SETTING_MAXIMUMWIDTH_MAX = GetSystemMetrics(SM_CXSCREEN);
+
+#define MENUCOMMAND_HISTORY "PopUp/ShowHistory"
+#define MENUCOMMAND_SVC "PopUp/EnableDisableMenuCommand"
+
+
+//===== MessageBoxes =====
+//void MB(char*); //This one is for Debug purposes
+//void Log(char*); //This one is used to notify the user
+//void HigherLower(int, int); //Used for integer input boxes (out of bound values).
+//void NotifyError(DWORD, char*, int, char*); //Used to notify an error giving some error codes to report.
+
+//===== Options =====
+static int OptionsInitialize(WPARAM,LPARAM);
+
+//===== Initializations =====
+static int OkToExit(WPARAM,LPARAM);
+bool OptionLoaded = false;
+int hLangpack = 0;
+
+//===== Global variables =====
+//===== DLLs =====
+HMODULE hUserDll = 0;
+HMODULE hMsimgDll = 0;
+HMODULE hKernelDll = 0;
+HMODULE hGdiDll = 0;
+HMODULE hDwmapiDll = 0;
+
+//===== User wnd class =====
+GLOBAL_WND_CLASSES g_wndClass = {0};
+
+//===== MTextControl ====
+HANDLE htuText = NULL;
+HANDLE htuTitle = NULL;
+
+//===== Menu item =====
+HANDLE hMenuRoot = NULL;
+HANDLE hMenuItem = NULL;
+HANDLE hMenuItemHistory = NULL;
+
+//==== ServiceFunctions Handles ====
+HANDLE hShowHistory = NULL;
+HANDLE hTogglePopup = NULL;
+HANDLE hGetStatus = NULL;
+
+//===== Event Handles =====
+HANDLE hOptionsInitialize;
+//HANDLE hNotifyOptionsInitialize; deprecatet
+HANDLE hModulesLoaded;
+HANDLE hTTBLoaded;
+HANDLE hTBLoaded;
+HANDLE hOkToExit;
+HANDLE hIconsChanged, hFontsChanged;
+HANDLE hEventStatusChanged; //To automatically disable on status change.
+int hTTButton = -1;
+HANDLE hTButton = NULL;
+
+GLOBAL g_popup = {0};
+
+static struct {
+ char *name;
+ INT_PTR (*func)(WPARAM, LPARAM);
+ HANDLE handle;
+} popupServices[] =
+{
+ {MS_POPUP_ADDPOPUP, PopUp_AddPopUp, 0},
+ {MS_POPUP_ADDPOPUPEX, PopUp_AddPopUpEx, 0},
+ {MS_POPUP_ADDPOPUPW, PopUp_AddPopUpW, 0},
+ {MS_POPUP_ADDPOPUP2, PopUp_AddPopUp2, 0},
+
+ {MS_POPUP_CHANGETEXT, PopUp_ChangeText, 0},
+ {MS_POPUP_CHANGETEXTW, PopUp_ChangeTextW, 0},
+ {MS_POPUP_CHANGE, PopUp_Change, 0},
+ {MS_POPUP_CHANGEW, PopUp_ChangeW, 0},
+ {MS_POPUP_CHANGEPOPUP2, PopUp_Change2, 0},
+
+ {MS_POPUP_GETCONTACT, PopUp_GetContact, 0},
+ {MS_POPUP_GETPLUGINDATA, PopUp_GetPluginData, 0},
+ {MS_POPUP_ISSECONDLINESHOWN, PopUp_IsSecondLineShown, 0},
+
+ {MS_POPUP_SHOWMESSAGE, PopUp_ShowMessage, 0},
+ {MS_POPUP_SHOWMESSAGEW, PopUp_ShowMessageW, 0},
+ {MS_POPUP_QUERY, PopUp_Query, 0},
+
+ {MS_POPUP_REGISTERACTIONS, PopUp_RegisterActions, 0},
+ {MS_POPUP_REGISTERNOTIFICATION, PopUp_RegisterNotification, 0},
+
+ {MS_POPUP_UNHOOKEVENTASYNC, PopUp_UnhookEventAsync, 0},
+
+ {MS_POPUP_REGISTERVFX, PopUp_RegisterVfx, 0},
+
+ {MS_POPUP_REGISTERCLASS, PopUp_RegisterPopupClass, 0},
+ {MS_POPUP_ADDPOPUPCLASS, PopUp_CreateClassPopup, 0},
+
+};
+
+//===== Options pages =====
+static int OptionsInitialize(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.position = 100000000;
+ odp.groupPosition = 910000000;
+ odp.flags = ODPF_TCHAR | ODPF_BOLDGROUPS;
+ odp.ptszTitle = LPGENT(MODULNAME_PLU);
+
+ odp.ptszTab = LPGENT("General");
+ odp.pfnDlgProc = DlgProcPopUpGeneral;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUP_GENERAL);
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.ptszTab = LPGENT("Classes");
+ odp.pfnDlgProc = DlgProcOptsClasses;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_NOTIFICATIONS);
+ CallService( MS_OPT_ADDPAGE, wParam,(LPARAM)&odp );
+
+ odp.ptszTab = LPGENT("Actions");
+ odp.pfnDlgProc = DlgProcPopupActions;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ACTIONS);
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.ptszTab = LPGENT("Contacts");
+ odp.pfnDlgProc = DlgProcContactOpts;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CONTACTS);
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.ptszTab = LPGENT("Advanced");
+ odp.pfnDlgProc = DlgProcPopUpAdvOpts;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUP_ADVANCED);
+ odp.flags |= ODPF_EXPERTONLY;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.ptszGroup = LPGENT("Skins");
+ odp.ptszTab = LPGENT(MODULNAME_PLU);
+ odp.pfnDlgProc = DlgProcPopSkinsOpts;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SKIN2);
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ //Test page
+ //odp.ptszTab = LPGEN("General (old)");
+ //odp.pfnDlgProc = DlgProcPopUpOpts;
+ //odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_POPUP);
+ //CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+}
+
+static int FontsChanged(WPARAM wParam,LPARAM lParam)
+{
+ ReloadFonts();
+ return 0;
+}
+
+static int IconsChanged(WPARAM wParam,LPARAM lParam){
+ LoadActions();
+
+ CLISTMENUITEM mi = { 0 };
+ mi.cbSize = sizeof(mi);
+
+ if (PopUpOptions.ModuleIsEnabled == TRUE) { //The module is enabled.
+ //The action to do is "disable popups" (show disabled) and we must write "enable popup" in the new item.
+ mi.hIcon = IcoLib_GetIcon(ICO_POPUP_ON,0);
+ }
+ else { //The module is disabled.
+ //The action to do is enable popups (show enabled), then write "disable popup" in the new item.
+ mi.hIcon = IcoLib_GetIcon(ICO_POPUP_OFF,0);
+ }
+ mi.flags = CMIM_ICON;
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenuItem,(LPARAM)&mi);
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenuRoot,(LPARAM)&mi);
+
+ mi.hIcon = IcoLib_GetIcon(ICO_HISTORY,0);
+ mi.flags = CMIM_ICON;
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenuItemHistory,(LPARAM)&mi);
+
+ if (hTTButton >= 0) {
+ TTBButtonV2 btn = {0};
+ btn.cbSize = sizeof(btn);
+ btn.pszServiceUp = btn.pszServiceDown = MENUCOMMAND_SVC;
+ btn.lParamUp = 1;
+ btn.lParamDown = 0;
+ btn.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP;
+ btn.name = Translate("Toggle Popups");
+ btn.tooltipUp = Translate("Popups are disabled");
+ btn.tooltipDn = Translate("Popups are enabled");
+ btn.hIconUp = IcoLib_GetIcon(ICO_POPUP_OFF,0);
+ btn.hIconDn = IcoLib_GetIcon(ICO_POPUP_ON,0);
+ hTTButton = CallService(MS_TTB_SETBUTTONOPTIONS, MAKEWPARAM(TTBO_ALLDATA, hTTButton), (LPARAM)&btn);
+ }
+
+ return 0;
+}
+
+static int TTBLoaded(WPARAM wParam,LPARAM lParam){
+ if (hTTButton < 0) {
+ TTBButtonV2 btn = {0};
+ btn.cbSize = sizeof(btn);
+ btn.pszServiceUp = btn.pszServiceDown = MENUCOMMAND_SVC;
+ btn.lParamUp = 1;
+ btn.lParamDown = 0;
+ btn.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP;
+ btn.name = Translate("Toggle Popups");
+ btn.tooltipUp = Translate("Popups are disabled");
+ btn.tooltipDn = Translate("Popups are enabled");
+ btn.hIconUp = IcoLib_GetIcon(ICO_POPUP_OFF,0);
+ btn.hIconDn = IcoLib_GetIcon(ICO_POPUP_ON,0);
+ hTTButton = CallService(MS_TTB_ADDBUTTON, (WPARAM)&btn, 0);
+ }
+ CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTTButton, PopUpOptions.ModuleIsEnabled?TTBST_RELEASED:TTBST_PUSHED);
+ return 0;
+}
+
+//register Modern Toolbarbutton
+static int ToolbarSet(WPARAM, LPARAM){
+ if (hTButton == NULL){
+ TBButton tbb = {0};
+ tbb.cbSize = sizeof(TBButton);
+ tbb.pszButtonID = "PopupToogle";
+ tbb.pszButtonName = Translate("Toggle Popups");
+ tbb.pszServiceName = MENUCOMMAND_SVC;
+ tbb.pszTooltipUp = Translate("Popups are disabled");
+ tbb.pszTooltipDn = Translate("Popups are enabled");
+ tbb.hPrimaryIconHandle = (HANDLE)CallService(MS_SKIN2_GETICONHANDLE, 0, (LPARAM)ICO_TB_POPUP_OFF);
+ tbb.hSecondaryIconHandle = (HANDLE)CallService(MS_SKIN2_GETICONHANDLE, 0, (LPARAM)ICO_TB_POPUP_ON);
+ tbb.tbbFlags = TBBF_VISIBLE;
+ tbb.defPos = 10000;
+ hTButton = (HANDLE)CallService(MS_TB_ADDBUTTON,0, (LPARAM)&tbb);
+ }
+ CallService(MS_TB_SETBUTTONSTATEBYID, (WPARAM)"PopupToogle", PopUpOptions.ModuleIsEnabled?TBST_PUSHED:TBST_RELEASED);
+ return 0;
+}
+
+//===== EnableDisableMenuCommand =====
+INT_PTR svcEnableDisableMenuCommand(WPARAM wp, LPARAM lp)
+{
+ int iResult = 0;
+ int iResultRoot = 0;
+ CLISTMENUITEM mi = { 0 };
+ mi.cbSize = sizeof(mi);
+
+ if (PopUpOptions.ModuleIsEnabled)
+ { //The module is enabled.
+ //The action to do is "disable popups" (show disabled) and we must write "enable popup" in the new item.
+ PopUpOptions.ModuleIsEnabled = FALSE;
+ DBWriteContactSettingByte(NULL, MODULNAME, "ModuleIsEnabled", FALSE);
+ mi.ptszName = LPGENT("Enable &popup module");
+ mi.hIcon = IcoLib_GetIcon(ICO_POPUP_OFF,0);
+ } else
+ { //The module is disabled.
+ //The action to do is enable popups (show enabled), then write "disable popup" in the new item.
+ PopUpOptions.ModuleIsEnabled = TRUE;
+ DBWriteContactSettingByte(NULL, MODULNAME, "ModuleIsEnabled", TRUE);
+ mi.ptszName = LPGENT("Disable &popup module");
+ mi.hIcon = IcoLib_GetIcon(ICO_POPUP_ON,0);
+ }
+ mi.flags = CMIM_NAME | CMIM_ICON | CMIF_TCHAR;
+ iResult = CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenuItem,(LPARAM)&mi);
+ mi.flags = CMIM_ICON;
+ iResultRoot = CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenuRoot,(LPARAM)&mi);
+ TTBLoaded(0,0);
+ ToolbarSet(0,0);
+ if(iResult && iResultRoot)
+ return 1;
+ else
+ return 0;
+}
+
+INT_PTR svcShowHistory(WPARAM, LPARAM)
+{
+ PopupHistoryShow();
+ return 0;
+}
+
+void InitMenuItems(void) {
+ CLISTMENUITEM mi={0};
+
+ // Common
+ mi.cbSize = sizeof(mi);
+ // support new genmenu style
+ mi.flags = CMIF_ROOTHANDLE|CMIF_TCHAR;
+ mi.hParentMenu = HGENMENU_ROOT;
+
+ // Build main menu
+ mi.position = -1000000000 /*1000001*/;
+ mi.ptszName = LPGENT(MODULNAME_PLU);
+ mi.hIcon = IcoLib_GetIcon(PopUpOptions.ModuleIsEnabled ? ICO_POPUP_ON : ICO_POPUP_OFF ,0);
+ hMenuRoot = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi);
+
+ // Add item to main menu
+ mi.hParentMenu = (HGENMENU)hMenuRoot;
+
+ hTogglePopup = CreateServiceFunction(MENUCOMMAND_SVC, svcEnableDisableMenuCommand);
+ mi.ptszName = PopUpOptions.ModuleIsEnabled ? LPGENT("Disable &popup module") : LPGENT("Enable &popup module");
+ mi.pszService = MENUCOMMAND_SVC;
+ hMenuItem = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ // Popup History
+ hShowHistory = CreateServiceFunction(MENUCOMMAND_HISTORY, svcShowHistory);
+ mi.position = 1000000000;
+ mi.popupPosition = 1999990000;
+ mi.ptszName = LPGENT("Popup History");
+ mi.hIcon = IcoLib_GetIcon(ICO_HISTORY, 0);
+ mi.pszService = MENUCOMMAND_HISTORY;
+ hMenuItemHistory = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+}
+
+//===== GetStatus =====
+INT_PTR GetStatus(WPARAM wp, LPARAM lp)
+{
+ return PopUpOptions.ModuleIsEnabled;
+}
+
+//register Updatersupport
+void registerUpdate(){
+ Update update = {0};
+ char szVersion[16];
+ update.cbSize = sizeof(Update);
+ update.szComponentName = pluginInfoEx.shortName;
+ update.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfoEx, szVersion);
+ update.cpbVersion = (int)strlen((char *)update.pbVersion);
+
+ update.szUpdateURL = __FLUpdateURL /*UPDATER_AUTOREGISTER*/;
+ update.szVersionURL = __FLVersionURL;
+ update.pbVersionPrefix = (BYTE *)__FLVersionPrefix;
+ update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix);
+
+ update.szBetaUpdateURL = __BetaUpdateURL;
+ update.szBetaVersionURL = __BetaVersionURL;
+ // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ update.pbBetaVersionPrefix = (BYTE *)__BetaVersionPrefix;
+ update.cpbBetaVersionPrefix = (int)strlen((char *)update.pbBetaVersionPrefix);
+
+ update.szBetaChangelogURL = __BetaChangelogURL;
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM) &update);
+}
+
+//register Hotkey
+void LoadHotkey(){
+ HOTKEYDESC hk = {0};
+ hk.cbSize = sizeof(hk);
+ hk.dwFlags = HKD_TCHAR;
+ hk.pszName = "Toggle Popups";
+ hk.ptszDescription = LPGENT("Toggle Popups");
+ hk.ptszSection = LPGENT(MODULNAME_PLU);
+ hk.pszService = MENUCOMMAND_SVC;
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM) &hk);
+
+ // 'Popup History' Hotkey
+ hk.pszName = "Popup History";
+ hk.ptszDescription = LPGENT("Popup History");
+ hk.pszService = MENUCOMMAND_HISTORY;
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM) &hk);
+}
+
+//menu
+//Function which makes the initializations
+static int ModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ //check if 'Icon Library Manager' and 'FontService' exist (load icon and font later)
+ if (!ServiceExists(MS_FONT_REGISTER) || !ServiceExists(MS_SKIN2_ADDICON)) {
+ LPTSTR msg = TranslateTS(
+ _T("This version of Popup Plus requires\r\n")
+ _T("'Icon Library Manager' and 'FontService'\r\n")
+ _T("modules.\r\n")
+ _T("\r\n")
+ _T("You always can download them at\r\n")
+ _T("http://addons.miranda-im.org/\r\n")
+ _T("\r\n")
+ _T("Do you want to visit Miranda IM homepage now?\r\n") );
+ if (MessageBox(NULL, msg, _T("Popup Plus Error"), MB_YESNO|MB_ICONSTOP) == IDYES)
+ ShellExecute(NULL, _T("open"), _T("http://addons.miranda-im.org/"), NULL, NULL, SW_SHOWNORMAL);
+ return 0;
+ }
+
+ //check if History++ is installed
+ gbHppInstalled = ServiceExists(MS_HPP_GETVERSION) && ServiceExists(MS_HPP_EG_WINDOW) &&
+ (CallService(MS_HPP_GETVERSION, 0, 0) >= PLUGIN_MAKE_VERSION(1,5,0,112));
+ //check if MText plugin is installed
+ if (MText.Register) {
+ htuText = MText.Register("PopUp Plus/Text", MTEXT_FANCY_DEFAULT);
+ htuTitle = MText.Register("PopUp Plus/Title",MTEXT_FANCY_DEFAULT);
+ }
+ else {
+ htuTitle = htuText = NULL;
+ }
+ // init meta contacts
+ INT_PTR ptr = CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
+ if (ptr != CALLSERVICE_NOTFOUND) {
+ gszMetaProto = (LPCSTR)ptr;
+ }
+
+ //check if OptionLoaded
+ if(!OptionLoaded){
+ LoadOptions();
+ }
+/*/deprecatet stuff
+ notifyLink = ServiceExists(MS_NOTIFY_GETLINK) ? (MNOTIFYLINK *)CallService(MS_NOTIFY_GETLINK, 0, 0) : NULL;
+ LoadNotifyImp();
+ hNotifyOptionsInitialize = HookEvent(ME_NOTIFY_OPT_INITIALISE, NotifyOptionsInitialize);
+
+ HookEvent(ME_CONTACTSETTINGS_INITIALISE, ContactSettingsInitialise);
+*/
+ //Uninstalling purposes
+ if (ServiceExists("PluginSweeper/Add")) {
+ CallService("PluginSweeper/Add",(WPARAM)Translate(MODULNAME),(LPARAM)MODULNAME);
+ }
+ //load fonts / create hook
+ InitFonts();
+ hFontsChanged = HookEvent(ME_FONT_RELOAD,FontsChanged);
+
+ //load actions and notifications
+ LoadActions();
+ LoadNotifications();
+ //hook TopToolBar
+ hTTBLoaded = HookEvent(ME_TTB_MODULELOADED, TTBLoaded);
+ //Folder plugin support
+ LPTSTR pszPath = mir_a2t(MIRANDA_PATH "\\Skins\\PopUp");
+ folderId = FoldersRegisterCustomPathT(MODULNAME_LONG, "Skins", pszPath);
+ mir_free(pszPath);
+ //load skin
+ skins.load(_T("dir"));
+ const PopupSkin *skin;
+ if (skin = skins.getSkin(PopUpOptions.SkinPack)) {
+ mir_free(PopUpOptions.SkinPack);
+ PopUpOptions.SkinPack = mir_tstrdup(skin->getName());
+ skin->loadOpts();
+ }
+ //init PopupEfects
+ PopupEfectsInitialize();
+ //MessageAPI support
+ SrmmMenu_Load();
+ //Hotkey
+ LoadHotkey();
+ //Modern Toolbar support
+ if(ServiceExists(MS_TB_ADDBUTTON)) {
+ hTBLoaded = HookEvent(ME_TB_MODULELOADED, ToolbarSet);
+ ToolbarSet(0,0);
+ }
+ //Updater support
+ if(ServiceExists(MS_UPDATE_REGISTER)) registerUpdate();
+
+ gbPopupLoaded = TRUE;
+ return 0;
+}
+
+//=== DllMain =====
+//DLL entry point, Required to store the instance handle
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+//===== MirandaPluginInfo =====
+//Called by Miranda to get the information associated to this plugin.
+//It only returns the PLUGININFOEX structure, without any test on the version
+//@param mirandaVersion - The version of the application calling this function
+MIRAPI PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ g_popup.MirVer = mirandaVersion;
+
+#if defined(_UNICODE)
+ pluginInfoEx.flags = UNICODE_AWARE;
+#else
+ if (GetProcAddress(GetModuleHandle(_T("user32")), "DrawTextExW"))
+ pluginInfoEx.flags = 1; // dynamic UNICODE_AWARE
+#endif
+
+ return &pluginInfoEx;
+}
+
+//Miranda PluginInterfaces
+MIRAPI const MUUID *MirandaPluginInterfaces(void)
+{
+ static const MUUID interfaces[] = { MIID_POPUPS, MIID_LAST };
+ return interfaces;
+}
+
+//ME_SYSTEM_OKTOEXIT event
+//called before the app goes into shutdown routine to make sure everyone is happy to exit
+static int OkToExit(WPARAM wParam, LPARAM lParam)
+{
+ closing = TRUE;
+ StopPopupThread();
+ return 0;
+}
+
+//===== Load =====
+//Initializes the services provided and the link to those needed
+//Called when the plugin is loaded into Miranda
+MIRAPI int Load(PLUGINLINK *link)
+{
+ char ver[1024];
+ pluginLink=link;
+
+ g_popup.isOsUnicode = (GetVersion() & 0x80000000) == 0;
+
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM) sizeof(ver), (LPARAM) ver);
+ g_popup.isMirUnicode = strstr(ver, "Unicode") != NULL;
+
+ hGetStatus = CreateServiceFunction(MS_POPUP_GETSTATUS, GetStatus);
+
+ DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, FALSE, 0);
+
+ mir_getLI (&li);
+ mir_getMMI (&mmi);
+ mir_getUTFI (&utfi);
+ mir_getMTI (&MText);
+ mir_getLP(&pluginInfoEx);
+
+ #if defined(_DEBUG)
+ PopUpOptions.debug = DBGetContactSettingByte(NULL, MODULNAME, "debug", FALSE);
+ #else
+ PopUpOptions.debug = false;
+ #endif
+ LoadGDIPlus();
+
+ //Transparent and animation routines
+ OSVERSIONINFO osvi = { 0 };
+ BOOL bResult = FALSE;
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ bResult = GetVersionEx(&osvi);
+
+// MLU layer for ansi release
+#if !defined(_UNICODE)
+ MySetLayeredWindowAttributes = 0;
+ MyUpdateLayeredWindow = 0;
+ MyAnimateWindow = 0;
+ MyDrawTextW = 0;
+ MyDrawTextExW = 0;
+ MySetWindowTextW = 0;
+ MySendMessageW = 0;
+ MyCallWindowProcW = 0;
+ MyCreateWindowExW = 0;
+
+ MyGetMonitorInfo = 0;
+ MyMonitorFromWindow = 0;
+
+ hUserDll = LoadLibrary(_T("user32.dll"));
+ if (hUserDll) {
+ MySetLayeredWindowAttributes = (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
+ MyUpdateLayeredWindow = (BOOL (WINAPI *)(HWND, HDC, POINT *, SIZE *, HDC, POINT *, COLORREF, BLENDFUNCTION *, DWORD))GetProcAddress(hUserDll, "UpdateLayeredWindow");
+ MyAnimateWindow = (BOOL (WINAPI*)(HWND,DWORD,DWORD))GetProcAddress(hUserDll,"AnimateWindow");
+ MyDrawTextW = (int (WINAPI *)(HDC, LPCWSTR, int, LPRECT, UINT))GetProcAddress(hUserDll,"DrawTextW");
+ MyDrawTextExW = (int (WINAPI*)(HDC,LPCWSTR,int,LPRECT,UINT,LPDRAWTEXTPARAMS))GetProcAddress(hUserDll,"DrawTextExW");
+ MySetWindowTextW = (BOOL (WINAPI*)(HWND, LPCWSTR))GetProcAddress(hUserDll,"SetWindowTextW");
+ MySendMessageW = (LRESULT (WINAPI *)(HWND, UINT, WPARAM, LPARAM))GetProcAddress(hUserDll,"SendMessageW");
+ MyCallWindowProcW = (LRESULT (WINAPI *)(WNDPROC, HWND, UINT, WPARAM, LPARAM))GetProcAddress(hUserDll,"CallWindowProcW");
+ MyCreateWindowExW = (HWND (WINAPI*)(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID))GetProcAddress(hUserDll,"CreateWindowExW");
+
+ if (LOWORD(GetVersion())!=4) { //Windows 98, ME, 2000, XP, and later support multimonitor configuration.
+ if (bResult) {
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ { //2000 or XP
+ #ifdef UNICODE
+ MyGetMonitorInfo = (BOOL (WINAPI*)(HMONITOR,LPMONITORINFO))GetProcAddress(hUserDll,("GetMonitorInfoW"));
+ #else
+ MyGetMonitorInfo = (BOOL (WINAPI*)(HMONITOR,LPMONITORINFO))GetProcAddress(hUserDll,("GetMonitorInfoA"));
+ #endif //UNICODE
+ } else
+ { //98 or ME
+ // attempt to fix multimonitor on 9x
+ MyGetMonitorInfo = (BOOL (WINAPI*)(HMONITOR,LPMONITORINFO))GetProcAddress(hUserDll,("GetMonitorInfoA"));
+ if (!MyGetMonitorInfo)
+ MyGetMonitorInfo = (BOOL (WINAPI*)(HMONITOR,LPMONITORINFO))GetProcAddress(hUserDll,("GetMonitorInfo"));
+ }
+ } //There's no need for an else branch.
+ if (MyGetMonitorInfo)
+ MyMonitorFromWindow = (HMONITOR (WINAPI*)(HWND,DWORD))GetProcAddress(hUserDll, ("MonitorFromWindow"));
+ }
+ }
+
+ hGdiDll = LoadLibrary(_T("gdi32.dll"));
+ if (hGdiDll) {
+ MyGetTextExtentPoint32W = (BOOL (WINAPI *)(HDC, LPCWSTR, int, LPSIZE))GetProcAddress(hGdiDll,"GetTextExtentPoint32W");
+ }
+ else{
+ MyGetTextExtentPoint32W = 0;
+ }
+ hMsimgDll = LoadLibrary(_T("msimg32.dll"));
+ MyAlphaBlend = 0;
+ MyTransparentBlt = 0;
+ if (hMsimgDll)
+ {
+ MyTransparentBlt = (BOOL (WINAPI *)(HDC, int, int, int, int, HDC, int, int, int, int, UINT))
+ GetProcAddress(hMsimgDll, "TransparentBlt");
+ MyAlphaBlend = (BOOL (WINAPI *)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION))
+ GetProcAddress(hMsimgDll, "AlphaBlend");
+ }
+#endif
+
+ hDwmapiDll = LoadLibrary(_T("dwmapi.dll"));
+ MyDwmEnableBlurBehindWindow = 0;
+ if (hDwmapiDll) {
+ MyDwmEnableBlurBehindWindow = (HRESULT (WINAPI *)(HWND, DWM_BLURBEHIND *))
+ GetProcAddress(hDwmapiDll, "DwmEnableBlurBehindWindow");
+ }
+
+ PopupHistoryLoad();
+ LoadPopupThread();
+ if (!LoadPopupWnd2())
+ {
+ MessageBox(0, TranslateTS(
+ _T("Error: I could not register the PopUp Window class.\r\n")
+ _T("The plugin will not operate.")
+ ),
+ _T(MODULNAME_LONG), MB_ICONSTOP|MB_OK);
+ return 0; //We couldn't register our Window Class, don't hook any event: the plugin will act as if it was disabled.
+ }
+ RegisterOptPrevBox();
+
+ // Register in DBEditor++
+ DBVARIANT dbv;
+ if (DBGetContactSetting(NULL, "KnownModules", MODULNAME, &dbv))
+ DBWriteContactSettingString(NULL, "KnownModules", pluginInfoEx.shortName, MODULNAME);
+ DBFreeVariant(&dbv);
+
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+ hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OptionsInitialize);
+ hOkToExit = HookEvent(ME_SYSTEM_OKTOEXIT, OkToExit);
+// hEventStatusChanged = HookEvent(ME_CLIST_STATUSMODECHANGE,StatusModeChanged);
+
+ hbmNoAvatar = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_NOAVATAR));
+
+ if(!OptionLoaded){
+ LoadOptions();
+ }
+
+ //Service Functions
+ for (int i = SIZEOF(popupServices); i--; )
+ popupServices[i].handle = CreateServiceFunction(popupServices[i].name, popupServices[i].func);
+
+ //load icons / create hook
+ InitIcons();
+ hIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED,IconsChanged);
+ //add menu items
+ InitMenuItems();
+
+ return 0;
+}
+
+//===== Unload =====
+//Prepare the plugin to stop
+//Called by Miranda when it will exit or when the plugin gets deselected
+
+MIRAPI int Unload(void)
+{
+ int i;
+
+ for (i = SIZEOF(popupServices); i--; )
+ DestroyServiceFunction(popupServices[i].handle);
+
+ SrmmMenu_Unload();
+
+ UnhookEvent(hOptionsInitialize);
+ UnhookEvent(hModulesLoaded);
+ UnhookEvent(hOkToExit);
+ UnhookEvent(hEventStatusChanged);
+ UnhookEvent(hIconsChanged);
+ UnhookEvent(hFontsChanged);
+ UnhookEvent(hTBLoaded);
+
+ DestroyServiceFunction(hShowHistory);
+ DestroyServiceFunction(hTogglePopup);
+ DestroyServiceFunction(hGetStatus);
+ DestroyServiceFunction(hSquareFad);
+
+ DeleteObject(fonts.title);
+ DeleteObject(fonts.clock);
+ DeleteObject(fonts.text);
+ DeleteObject(fonts.action);
+ DeleteObject(fonts.actionHover);
+
+ DeleteObject(hbmNoAvatar);
+
+ FreeLibrary(hDwmapiDll);
+ FreeLibrary(hUserDll);
+ FreeLibrary(hMsimgDll);
+// FreeLibrary(hKernelDll);
+ FreeLibrary(hGdiDll);
+
+ if(PopUpOptions.SkinPack) mir_free(PopUpOptions.SkinPack);
+ mir_free(PopUpOptions.Effect);
+
+ OptAdv_UnregisterVfx();
+ UnloadPopupThread();
+ UnloadPopupWnd2();
+ PopupHistoryUnload();
+
+ UnregisterClass (MAKEINTATOM(g_wndClass.cPopupWnd2),hInst);
+ UnregisterClassW(L"PopupEditBox",hInst);
+ UnregisterClass (MAKEINTATOM(g_wndClass.cPopupMenuHostWnd),hInst);
+ UnregisterClass (MAKEINTATOM(g_wndClass.cPopupThreadManagerWnd),hInst);
+ UnregisterClass (MAKEINTATOM(g_wndClass.cPopupPreviewBoxWndclass),hInst);
+ UnregisterClass (MAKEINTATOM(g_wndClass.cPopupPlusDlgBox),hInst);
+
+ UnloadGDIPlus();
+
+ UnloadActions();
+
+ CloseHandle(hMainThread);
+
+ return 0;
+}
diff --git a/plugins/Popup/src/notifications.cpp b/plugins/Popup/src/notifications.cpp
new file mode 100644
index 0000000000..89cf7d8991
--- /dev/null
+++ b/plugins/Popup/src/notifications.cpp
@@ -0,0 +1,349 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/notifications.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+HANDLE g_hntfError, g_hntfWarning, g_hntfNotification;
+
+#define PopupNotificationData_SIGNATURE 0x11BEDA1A
+
+
+int TreeDataSortFunc(const POPUPTREEDATA *p1, const POPUPTREEDATA *p2)
+{
+ if (int cmp = lstrcmp(p1->pszTreeRoot, p2->pszTreeRoot))
+ return cmp;
+ return lstrcmp(p1->pszDescription, p2->pszDescription);
+
+}
+
+LIST<POPUPTREEDATA> gTreeData(20, TreeDataSortFunc);
+
+// interface
+void LoadNotifications()
+{
+ POPUPNOTIFICATION notification = {0};
+ notification.cbSize = sizeof(notification);
+ notification.actionCount = 0;
+ notification.lpActions = 0;
+
+ lstrcpynA(notification.lpzGroup, "Misc", sizeof(notification.lpzName));
+ lstrcpynA(notification.lpzName, "Warning", sizeof(notification.lpzName));
+ notification.lchIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_MB_WARN), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED);
+ notification.colorBack = RGB(210,210,150);
+ notification.colorText = RGB(0,0,0);
+ notification.iSeconds = 10;
+ g_hntfWarning = RegisterNotification(&notification);
+
+ lstrcpynA(notification.lpzGroup, "Misc", sizeof(notification.lpzName));
+ lstrcpynA(notification.lpzName, "Notification", sizeof(notification.lpzName));
+ notification.lchIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_MB_INFO), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED);
+ notification.colorBack = RGB(230,230,230);
+ notification.colorText = RGB(0,0,0);
+ notification.iSeconds = 7;
+ g_hntfNotification = RegisterNotification(&notification);
+
+ lstrcpynA(notification.lpzGroup, "Misc", sizeof(notification.lpzName));
+ lstrcpynA(notification.lpzName, "Error", sizeof(notification.lpzName));
+ notification.lchIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_MB_STOP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED);
+ notification.colorBack = RGB(191,0,0);
+ notification.colorText = RGB(255,245,225);
+ notification.iSeconds = -1;
+ g_hntfError = RegisterNotification(&notification);
+}
+
+void UnloadTreeData()
+{
+ for (int i = 0; i < gTreeData.getCount(); ++i) {
+ if(gTreeData[i]->typ == 2) {
+ mir_free(gTreeData[i]->pupClass.pszName);
+ mir_free(gTreeData[i]->pupClass.pszDescription);
+ }
+ mir_free(gTreeData[i]->pszTreeRoot);
+ mir_free(gTreeData[i]->pszDescription);
+ }
+ gTreeData.destroy();
+}
+
+void SaveNotificationSettings(POPUPTREEDATA *ptd, char* szModul)
+{
+ if(ptd->typ == 1) {
+ char setting[2*MAXMODULELABELLENGTH];
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}Timeout",
+ ptd->notification.lpzGroup,
+ ptd->notification.lpzName);
+ DBWriteContactSettingWord(NULL, szModul, setting, ptd->notification.iSeconds);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}enabled",
+ ptd->notification.lpzGroup,
+ ptd->notification.lpzName);
+ DBWriteContactSettingByte(NULL, szModul, setting, ptd->enabled);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}TimeoutVal",
+ ptd->notification.lpzGroup,
+ ptd->notification.lpzName);
+ DBWriteContactSettingWord(NULL, szModul, setting, ptd->timeoutValue);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}disableWhen",
+ ptd->notification.lpzGroup,
+ ptd->notification.lpzName);
+ DBWriteContactSettingByte(NULL, szModul, setting, ptd->disableWhen);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}leftAction",
+ ptd->notification.lpzGroup,
+ ptd->notification.lpzName);
+ DBWriteContactSettingString(NULL, szModul, setting, ptd->leftAction);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}rightAction",
+ ptd->notification.lpzGroup,
+ ptd->notification.lpzName);
+ DBWriteContactSettingString(NULL, szModul, setting, ptd->rightAction);
+
+ for (int i = 0; i < ptd->notification.actionCount; ++i)
+ {
+ if (!lstrcmpA(ptd->leftAction, ptd->notification.lpActions[i].lpzTitle))
+ {
+ DBCONTACTWRITESETTING dbcws = {0};
+ dbcws.szModule = ptd->notification.lpActions[i].lpzLModule;
+ dbcws.szModule = ptd->notification.lpActions[i].lpzLSetting;
+ dbcws.value = ptd->notification.lpActions[i].dbvLData;
+ CallService(MS_DB_CONTACT_WRITESETTING, 0, (LPARAM)&dbcws);
+ }
+ if (!lstrcmpA(ptd->rightAction, ptd->notification.lpActions[i].lpzTitle))
+ {
+ DBCONTACTWRITESETTING dbcws = {0};
+ dbcws.szModule = ptd->notification.lpActions[i].lpzRModule;
+ dbcws.szModule = ptd->notification.lpActions[i].lpzRSetting;
+ dbcws.value = ptd->notification.lpActions[i].dbvRData;
+ CallService(MS_DB_CONTACT_WRITESETTING, 0, (LPARAM)&dbcws);
+ }
+ }
+ }
+}
+
+void LoadNotificationSettings(POPUPTREEDATA *ptd, char* szModul)
+{
+ if(ptd->typ == 1) {
+ char setting[2*MAXMODULELABELLENGTH];
+ char *szTmp = NULL;
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}enabled", ptd->notification.lpzGroup, ptd->notification.lpzName);
+ ptd->enabled =
+ (signed char)DBGetContactSettingByte(NULL, szModul, setting, TRUE);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}Timeout", ptd->notification.lpzGroup, ptd->notification.lpzName);
+ ptd->notification.iSeconds =
+ (signed char)DBGetContactSettingWord(NULL, szModul, setting, ptd->notification.iSeconds);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}TimeoutVal", ptd->notification.lpzGroup, ptd->notification.lpzName);
+ ptd->timeoutValue =
+ (signed char)DBGetContactSettingWord(NULL, szModul, setting,
+ ptd->notification.iSeconds ? ptd->notification.iSeconds : 0);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}disableWhen", ptd->notification.lpzGroup, ptd->notification.lpzName);
+ ptd->disableWhen =
+ DBGetContactSettingByte(NULL, szModul, setting, 0);
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}leftAction", ptd->notification.lpzGroup, ptd->notification.lpzName);
+ szTmp = DBGetContactSettingString(NULL, szModul, setting, ptd->notification.lpzLAction);
+ lstrcpynA(ptd->leftAction, szTmp, sizeof(ptd->leftAction));
+ mir_free(szTmp); szTmp = NULL;
+
+ mir_snprintf(setting, sizeof(setting), "{%s/%s}rightAction", ptd->notification.lpzGroup, ptd->notification.lpzName);
+ szTmp = DBGetContactSettingString(NULL, szModul, setting, ptd->notification.lpzRAction);
+ lstrcpynA(ptd->rightAction, szTmp, sizeof(ptd->rightAction));
+ mir_free(szTmp); szTmp = NULL;
+ }
+}
+
+HANDLE RegisterNotification(POPUPNOTIFICATION *notification)
+{
+ POPUPTREEDATA *ptd = (POPUPTREEDATA *)mir_alloc(sizeof(POPUPTREEDATA));
+ ptd->signature = PopupNotificationData_SIGNATURE;
+ ptd->typ = 1;
+ ptd->pszTreeRoot = mir_a2t(notification->lpzGroup);
+ ptd->pszDescription = mir_a2t(notification->lpzName);
+ ptd->notification = *notification;
+ if (!ptd->notification.lpzLAction) ptd->notification.lpzLAction = POPUP_ACTION_NOTHING;
+ if (!ptd->notification.lpzRAction) ptd->notification.lpzRAction = POPUP_ACTION_DISMISS;
+ LoadNotificationSettings(ptd, "PopUpNotifications");
+
+ // ugly hack to make reset always possible
+ SaveNotificationSettings(ptd,"PopUpNotifications");
+
+ FontID fontid = {0};
+ fontid.cbSize = sizeof(fontid);
+ mir_snprintf(fontid.group, sizeof(fontid.group), "%s/%s", PU_FNT_AND_COLOR, notification->lpzGroup);
+ lstrcpyA(fontid.dbSettingsGroup, "PopUpNotifications");
+ fontid.flags = FIDF_DEFAULTVALID;
+ fontid.deffontsettings.charset = DEFAULT_CHARSET;
+ fontid.deffontsettings.colour = ptd->notification.colorText;
+ fontid.deffontsettings.size = -11;
+ lstrcpyA(fontid.deffontsettings.szFace, "MS Shell Dlg");
+ fontid.deffontsettings.style = 0;
+ mir_snprintf(fontid.name, SIZEOF(fontid.name), "%s (colors only)", notification->lpzName);
+ mir_snprintf(fontid.prefix, SIZEOF(fontid.prefix), "{%s/%s}text", notification->lpzGroup, notification->lpzName);
+ fontid.deffontsettings.style = 0;
+ CallService(MS_FONT_REGISTER, (WPARAM)&fontid, 0);
+
+ ColourID colourid = {0};
+ colourid.cbSize = sizeof(colourid);
+ mir_snprintf(colourid.group, sizeof(colourid.group), "%s/%s", PU_FNT_AND_COLOR, notification->lpzGroup);
+ lstrcpyA(colourid.dbSettingsGroup, "PopUpNotifications");
+ mir_snprintf(colourid.name, SIZEOF(colourid.name), "%s (colors only)", notification->lpzName);
+ mir_snprintf(colourid.setting, SIZEOF(colourid.setting), "{%s/%s}backColor", notification->lpzGroup, notification->lpzName);
+ colourid.defcolour = ptd->notification.colorBack;
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&colourid, 0);
+
+ char section[MAXMODULELABELLENGTH], setting[MAXMODULELABELLENGTH];
+ mir_snprintf(section, sizeof(section), "PopUps/%s", notification->lpzGroup);
+ mir_snprintf(setting, sizeof(setting), "%s_%s_%s", MODULNAME, notification->lpzGroup, notification->lpzName);
+
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(sid);
+ sid.pszSection = section;
+ sid.cx = sid.cy = 16;
+ sid.pszName = setting;
+ sid.pszDescription = notification->lpzName;
+ sid.hDefaultIcon = notification->lchIcon;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ gTreeData.insert(ptd);
+ return (HANDLE)ptd;
+}
+
+HANDLE FindTreeData(LPTSTR group, LPTSTR name, BYTE typ)
+{
+ for(int i = 0; i < gTreeData.getCount(); i++) {
+ if( gTreeData[i]->typ == typ &&
+ (!group || (_tcscmp(gTreeData[i]->pszTreeRoot, group) == 0)) &&
+ (!name || (_tcscmp(gTreeData[i]->pszDescription, name) == 0)) )
+ {
+ return gTreeData[i];
+ }
+ }
+ return NULL;
+}
+
+void FillNotificationData(POPUPDATA2 *ppd, DWORD *disableWhen)
+{
+ if (!IsValidNotification(ppd->lchNotification)) {
+ *disableWhen = 0;
+ return;
+ }
+
+ POPUPTREEDATA *ptd = (POPUPTREEDATA *)ppd->lchNotification;
+
+ ppd->iSeconds = ptd->timeoutValue;
+ *disableWhen = ptd->enabled ? ptd->disableWhen : 0xFFFFFFFF;
+
+ LOGFONTA lf; //dummy to make FS happy (use LOGFONTA coz we use MS_FONT_GET)
+ FontID fontid = {0}; //use ansi version of fontID coz POPUPNOTIFICATION use char
+ fontid.cbSize = sizeof(fontid);
+ mir_snprintf(fontid.group, sizeof(fontid.group), "%s/%s", PU_FNT_AND_COLOR, ptd->notification.lpzGroup);
+ mir_snprintf(fontid.name, SIZEOF(fontid.name), "%s (colors only)", ptd->notification.lpzName);
+ ppd->colorText = (COLORREF)CallService(MS_FONT_GET, (WPARAM)&fontid, (LPARAM)&lf);
+
+ ColourID colourid = {0}; //use ansi version of ColourID coz POPUPNOTIFICATION use char
+ colourid.cbSize = sizeof(colourid);
+ mir_snprintf(colourid.group, sizeof(colourid.group), "%s/%s", PU_FNT_AND_COLOR, ptd->notification.lpzGroup);
+ mir_snprintf(colourid.name, SIZEOF(colourid.name), "%s (colors only)", ptd->notification.lpzName);
+ ppd->colorBack = (COLORREF)CallService(MS_COLOUR_GET, (WPARAM)&colourid, 0);
+
+ char setting[MAXMODULELABELLENGTH];
+ mir_snprintf(setting, sizeof(setting), "%s_%s_%s", MODULNAME, ptd->notification.lpzGroup, ptd->notification.lpzName);
+ ppd->lchIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)setting);
+}
+
+bool IsValidNotification(HANDLE hNotification)
+{
+ if (!hNotification) return false;
+
+ bool res = false;
+ __try
+ {
+ if (((POPUPTREEDATA *)hNotification)->signature == PopupNotificationData_SIGNATURE)
+ res = true;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ res = false;
+ }
+ return res;
+}
+
+bool PerformAction(HANDLE hNotification, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ if (!IsValidNotification(hNotification))
+ return false;
+
+ POPUPTREEDATA *ptd = (POPUPTREEDATA *)hNotification;
+ char *lpzAction = NULL;
+ switch (message)
+ {
+ case WM_LBUTTONUP:
+ case WM_COMMAND:
+ lpzAction = ptd->leftAction;
+ break;
+
+ case WM_RBUTTONUP:
+ case WM_CONTEXTMENU:
+ lpzAction = ptd->rightAction;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (!lstrcmpA(lpzAction, POPUP_ACTION_NOTHING))
+ return true;
+
+ if (!lstrcmpA(lpzAction, POPUP_ACTION_DISMISS))
+ {
+ PUDeletePopUp(hwnd);
+ return true;
+ }
+
+ for (int i = 0; i < ptd->notification.actionCount; ++i)
+ {
+ if (!(ptd->notification.lpActions[i].dwFlags&PNAF_CALLBACK))
+ continue;
+ if (lstrcmpA(ptd->notification.lpActions[i].lpzTitle, lpzAction))
+ continue;
+
+ ptd->notification.lpActions[i].pfnCallback(hwnd, message, wparam, lparam,
+ ptd->notification.lpActions[i].dwCookie);
+ return true;
+ }
+
+ return false;
+}
diff --git a/plugins/Popup/src/notifications.h b/plugins/Popup/src/notifications.h
new file mode 100644
index 0000000000..24e6a63362
--- /dev/null
+++ b/plugins/Popup/src/notifications.h
@@ -0,0 +1,73 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/notifications.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __notifications_h__
+#define __notifications_h__
+
+struct POPUPTREEDATA
+{
+ int cbSize;
+ DWORD signature;
+ LPTSTR pszTreeRoot;
+ LPTSTR pszDescription;
+ BYTE typ;
+ union {
+ POPUPNOTIFICATION notification;
+ POPUPCLASS pupClass;
+ };
+ BYTE enabled;
+ DWORD disableWhen;
+ int timeoutValue;
+ char leftAction[MAXMODULELABELLENGTH];
+ char rightAction[MAXMODULELABELLENGTH];
+ COLORREF colorBack; //realy needet ??
+ COLORREF colorText; //realy needet ??
+};
+
+extern LIST<POPUPTREEDATA> gTreeData;
+extern HANDLE g_hntfError, g_hntfWarning, g_hntfNotification;
+
+int TreeDataSortFunc(const POPUPTREEDATA *p1, const POPUPTREEDATA *p2);
+HANDLE FindTreeData(LPTSTR group, LPTSTR name, BYTE typ);
+void UnloadTreeData();
+
+void LoadNotifications();
+HANDLE RegisterNotification(POPUPNOTIFICATION *notification);
+
+void FillNotificationData(POPUPDATA2 *ppd, DWORD *disableWhen);
+bool PerformAction(HANDLE hNotification, HWND hwnd, UINT message, WPARAM wparal, LPARAM lparam);
+bool IsValidNotification(HANDLE hNotification);
+
+void LoadNotificationSettings(POPUPTREEDATA *ptd, char* szModul);
+void SaveNotificationSettings(POPUPTREEDATA *ptd, char* szModul);
+
+#endif // __notifications_h__
diff --git a/plugins/Popup/src/opt_adv.cpp b/plugins/Popup/src/opt_adv.cpp
new file mode 100644
index 0000000000..f8fcd5f619
--- /dev/null
+++ b/plugins/Popup/src/opt_adv.cpp
@@ -0,0 +1,762 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_adv.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+HWND hwndBox = NULL;
+
+INT_PTR CALLBACK AvatarTrackBarWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK AlphaTrackBarWndProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//effekt name for drop down box
+LIST<TCHAR> g_lstPopupVfx(5, _tcsicmp);
+void OptAdv_RegisterVfx(char *name) {
+ g_lstPopupVfx.insert(mir_a2t(name));
+}
+
+void OptAdv_UnregisterVfx() {
+ for (int i = 0; i < g_lstPopupVfx.getCount(); ++i)
+ mir_free(g_lstPopupVfx[i]);
+ g_lstPopupVfx.destroy();
+}
+
+//Main Dialog Proc
+void LoadOption_AdvOpts() {
+ //History
+ PopUpOptions.EnableHistory = DBGetContactSettingByte (NULL,MODULNAME, "EnableHistory", TRUE);
+ PopUpOptions.HistorySize = DBGetContactSettingWord (NULL,MODULNAME, "HistorySize", SETTING_HISTORYSIZE_DEFAULT);
+ PopUpOptions.UseHppHistoryLog = DBGetContactSettingByte (NULL,MODULNAME, "UseHppHistoryLog", TRUE);
+ //Avatars
+ PopUpOptions.avatarBorders = DBGetContactSettingByte (NULL,MODULNAME, "AvatarBorders", TRUE);
+ PopUpOptions.avatarPNGBorders = DBGetContactSettingByte (NULL,MODULNAME, "AvatarPNGBorders", FALSE);
+ PopUpOptions.avatarRadius = DBGetContactSettingByte (NULL,MODULNAME, "AvatarRadius", 2);
+ PopUpOptions.avatarSize = DBGetContactSettingWord (NULL,MODULNAME, "AvatarSize", SETTING_AVTSIZE_DEFAULT);
+ PopUpOptions.EnableAvatarUpdates = DBGetContactSettingByte (NULL,MODULNAME, "EnableAvatarUpdates", FALSE);
+ //Monitor
+ PopUpOptions.Monitor = DBGetContactSettingByte (NULL,MODULNAME, "Monitor", SETTING_MONITOR_DEFAULT);
+ //Transparency
+ PopUpOptions.Enable9xTransparency = DBGetContactSettingByte (NULL,MODULNAME, "EnableRegionTransparency", TRUE);
+ PopUpOptions.UseTransparency = DBGetContactSettingByte (NULL,MODULNAME, "UseTransparency", TRUE);
+ PopUpOptions.Alpha = DBGetContactSettingByte (NULL,MODULNAME, "Alpha", SETTING_ALPHA_DEFAULT);
+ PopUpOptions.OpaqueOnHover = DBGetContactSettingByte (NULL,MODULNAME, "OpaqueOnHover", TRUE);
+ //Effects
+ PopUpOptions.UseAnimations = DBGetContactSettingByte (NULL,MODULNAME, "UseAnimations", TRUE);
+ PopUpOptions.UseEffect = DBGetContactSettingByte (NULL,MODULNAME, "Fade", TRUE);
+ PopUpOptions.Effect = (LPTSTR)DBGetContactSettingStringX(NULL,MODULNAME, "Effect", "", DBVT_TCHAR);
+ PopUpOptions.FadeIn = DBGetContactSettingDword(NULL,MODULNAME, "FadeInTime", SETTING_FADEINTIME_DEFAULT);
+ PopUpOptions.FadeOut = DBGetContactSettingDword(NULL,MODULNAME, "FadeOutTime",SETTING_FADEOUTTIME_DEFAULT);
+ //other old stuff
+ PopUpOptions.MaxPopups = DBGetContactSettingWord (NULL,MODULNAME, "MaxPopups", 20);
+}
+
+INT_PTR CALLBACK DlgProcPopUpAdvOpts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ TCHAR tstr[64];
+ static bool bDlgInit = false; //some controls send WM_COMMAND before or during WM_INITDIALOG
+
+ switch (msg) {
+ case WM_INITDIALOG: {
+ HWND hCtrl = NULL;
+
+ //Create preview box:
+ {
+ hwndBox = CreateWindowEx(
+ WS_EX_TOOLWINDOW|WS_EX_TOPMOST, // dwStyleEx
+ _T(BOXPREVIEW_WNDCLASS), // Class name
+ NULL, // Title
+ DS_SETFONT|DS_FIXEDSYS|WS_POPUP, // dwStyle
+ CW_USEDEFAULT, // x
+ CW_USEDEFAULT, // y
+ CW_USEDEFAULT, // Width
+ CW_USEDEFAULT, // Height
+ HWND_DESKTOP, // Parent
+ NULL, // menu handle
+ hInst, // Instance
+ (LPVOID)0);
+ ShowWindow(hwndBox, SW_HIDE);
+ }
+ //Group: History
+ {
+ CheckDlgButton(hwnd, IDC_ENABLE_HISTORY, PopUpOptions.EnableHistory);
+ SetDlgItemInt (hwnd, IDC_HISTORYSIZE, PopUpOptions.HistorySize, FALSE);
+ CheckDlgButton(hwnd, IDC_HPPLOG, PopUpOptions.UseHppHistoryLog);
+
+ hCtrl = GetDlgItem(hwnd, IDC_SHOWHISTORY);
+ SendMessage(hCtrl, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(hCtrl, BUTTONADDTOOLTIP, (WPARAM)Translate("Popup History"), 0);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_HISTORY,0));
+
+ EnableWindow(GetDlgItem(hwnd, IDC_HISTORY_STATIC1), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_HISTORYSIZE), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_HISTORY_STATIC2), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_SHOWHISTORY), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_HPPLOG), PopUpOptions.EnableHistory && gbHppInstalled);
+ }
+ //Group: Avatars
+ {
+ //Borders
+ CheckDlgButton(hwnd, IDC_AVT_BORDER, PopUpOptions.avatarBorders);
+ CheckDlgButton(hwnd, IDC_AVT_PNGBORDER, PopUpOptions.avatarPNGBorders);
+ EnableWindow(GetDlgItem(hwnd, IDC_AVT_PNGBORDER), PopUpOptions.avatarBorders);
+ //Radius
+ SetDlgItemInt(hwnd, IDC_AVT_RADIUS, PopUpOptions.avatarRadius, FALSE);
+ SendDlgItemMessage(hwnd, IDC_AVT_RADIUS_SPIN,UDM_SETRANGE, 0, (LPARAM)MAKELONG((PopUpOptions.avatarSize / 2),0));
+ //Size
+ SetWindowLongPtr(GetDlgItem(hwnd, IDC_AVT_SIZE_SLIDE), GWLP_USERDATA, GetWindowLongPtr(GetDlgItem(hwnd, IDC_AVT_SIZE_SLIDE), GWLP_WNDPROC));
+ SetWindowLongPtr(GetDlgItem(hwnd, IDC_AVT_SIZE_SLIDE), GWLP_WNDPROC, (LONG_PTR)AvatarTrackBarWndProc);
+
+ SendDlgItemMessage(hwnd, IDC_AVT_SIZE_SLIDE, TBM_SETRANGE,FALSE,
+ MAKELONG(SETTING_AVTSIZE_MIN, SETTING_AVTSIZE_MAX) );
+ SendDlgItemMessage(hwnd, IDC_AVT_SIZE_SLIDE, TBM_SETPOS, TRUE,
+ max(PopUpOptions.avatarSize, SETTING_AVTSIZE_MIN));
+ SetDlgItemInt(hwnd, IDC_AVT_SIZE, PopUpOptions.avatarSize, FALSE);
+ //Request avatars
+ CheckDlgButton(hwnd, IDC_AVT_REQUEST, PopUpOptions.EnableAvatarUpdates);
+ }
+ //Group: Monitor
+ {
+ BOOL bMonitor = 0;
+#if defined(_UNICODE)
+ bMonitor = GetSystemMetrics(SM_CMONITORS)>1;
+#else
+ if(MyGetMonitorInfo) {
+ //os support multimonitor, check if monitor > 1
+ bMonitor = GetSystemMetrics(SM_CMONITORS)>1;
+ }
+#endif
+ CheckDlgButton(hwnd, IDC_MIRANDAWND, bMonitor ? (PopUpOptions.Monitor == MN_MIRANDA) : TRUE);
+ CheckDlgButton(hwnd, IDC_ACTIVEWND, bMonitor ? (PopUpOptions.Monitor == MN_ACTIVE) : FALSE);
+ EnableWindow(GetDlgItem(hwnd, IDC_GRP_MULTIMONITOR), bMonitor);
+ EnableWindow(GetDlgItem(hwnd, IDC_MULTIMONITOR_DESC), bMonitor);
+ EnableWindow(GetDlgItem(hwnd, IDC_MIRANDAWND), bMonitor);
+ EnableWindow(GetDlgItem(hwnd, IDC_ACTIVEWND), bMonitor);
+ }
+ //Group: Transparency
+ {
+ //9x/ME
+ CheckDlgButton(hwnd, IDC_TRANS_9X, PopUpOptions.Enable9xTransparency);
+ //EnableWindow(GetDlgItem(hwnd, IDC_TRANS_9X), !IsWinVer2000Plus());
+ ShowWindow(GetDlgItem(hwnd, IDC_TRANS_9X), IsWinVer2000Plus() ? SW_HIDE : SW_SHOW);
+ //win2k+
+ CheckDlgButton(hwnd, IDC_TRANS, PopUpOptions.UseTransparency);
+ SendDlgItemMessage(hwnd, IDC_TRANS_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(1,255));
+ SendDlgItemMessage(hwnd, IDC_TRANS_SLIDER, TBM_SETPOS, TRUE, PopUpOptions.Alpha);
+ SetWindowLongPtr(GetDlgItem(hwnd, IDC_TRANS_SLIDER), GWLP_USERDATA, GetWindowLongPtr(GetDlgItem(hwnd, IDC_TRANS_SLIDER), GWLP_WNDPROC));
+ SetWindowLongPtr(GetDlgItem(hwnd, IDC_TRANS_SLIDER), GWLP_WNDPROC, (LONG_PTR)AlphaTrackBarWndProc);
+ wsprintf(tstr, _T("%d%%"), Byte2Percentile(PopUpOptions.Alpha));
+ SetDlgItemText(hwnd, IDC_TRANS_PERCENT, tstr);
+ CheckDlgButton(hwnd, IDC_TRANS_OPAQUEONHOVER, PopUpOptions.OpaqueOnHover);
+ {
+#if defined(_UNICODE)
+ BOOL how = TRUE;
+#else
+ BOOL how = (BOOL)(MySetLayeredWindowAttributes);
+#endif
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS) ,how);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_TXT1) ,how && PopUpOptions.UseTransparency);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_SLIDER) ,how && PopUpOptions.UseTransparency);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_PERCENT) ,how && PopUpOptions.UseTransparency);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_OPAQUEONHOVER) ,how && PopUpOptions.UseTransparency);
+ }
+ ShowWindow(GetDlgItem(hwnd, IDC_TRANS), IsWinVer2000Plus() ? SW_SHOW : SW_HIDE);
+ }
+ //Group: Effects
+ {
+ //Use Animations
+ CheckDlgButton(hwnd, IDC_USEANIMATIONS, PopUpOptions.UseAnimations);
+ //Fade
+ SetDlgItemInt (hwnd, IDC_FADEIN, PopUpOptions.FadeIn, FALSE);
+ SetDlgItemInt (hwnd, IDC_FADEOUT,PopUpOptions.FadeOut,FALSE);
+ UDACCEL aAccels[] = {{0,50},{1,100},{3,500}};
+ SendDlgItemMessage(hwnd, IDC_FADEIN_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_FADEINTIME_MAX, SETTING_FADEINTIME_MIN));
+ SendDlgItemMessage(hwnd, IDC_FADEIN_SPIN, UDM_SETACCEL, (WPARAM)SIZEOF(aAccels), (LPARAM)&aAccels);
+ SendDlgItemMessage(hwnd, IDC_FADEOUT_SPIN,UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_FADEOUTTIME_MAX,SETTING_FADEOUTTIME_MIN));
+ SendDlgItemMessage(hwnd, IDC_FADEOUT_SPIN,UDM_SETACCEL, (WPARAM)SIZEOF(aAccels), (LPARAM)&aAccels);
+
+ BOOL how = PopUpOptions.UseAnimations || PopUpOptions.UseEffect;
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_TXT1), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_SPIN), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_TXT2), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_TXT1), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_SPIN), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_TXT2), how);
+ //effects drop down
+ {
+ DWORD dwItem, dwActiveItem = 0;
+
+#if defined(_UNICODE)
+ BOOL how = TRUE;
+#else
+ BOOL how = (BOOL)(MySetLayeredWindowAttributes) /*&& !PopUpOptions.UseAnimations*/;
+#endif
+ EnableWindow(GetDlgItem(hwnd, IDC_EFFECT), how);
+ EnableWindow(GetDlgItem(hwnd, IDC_EFFECT_TXT), how);
+
+ hCtrl = GetDlgItem(hwnd, IDC_EFFECT);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("No effect")) ,-2);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Fade in/out")) ,-1);
+ dwActiveItem = (DWORD)PopUpOptions.UseEffect;
+ for (int i = 0; i < g_lstPopupVfx.getCount(); ++i) {
+ dwItem = ComboBox_AddString(hCtrl, TranslateTS(g_lstPopupVfx[i]));
+ ComboBox_SetItemData(hCtrl, dwItem, i);
+ if (PopUpOptions.UseEffect && !lstrcmp(g_lstPopupVfx[i], PopUpOptions.Effect))
+ dwActiveItem = dwItem;
+ }
+ SendDlgItemMessage(hwnd, IDC_EFFECT, CB_SETCURSEL, dwActiveItem, 0);
+ }
+ }
+
+ //later check stuff
+ {
+ SetDlgItemInt(hwnd, IDC_MAXPOPUPS, PopUpOptions.MaxPopups, FALSE);
+ }
+
+ TranslateDialogDefault(hwnd); //do it on end of WM_INITDIALOG
+ bDlgInit = true;
+ }//end WM_INITDIALOG
+ return TRUE;
+ case WM_HSCROLL: {
+ UINT idCtrl = GetDlgCtrlID((HWND)lParam);
+ switch (idCtrl) {
+ case IDC_AVT_SIZE_SLIDE:
+ {
+ PopUpOptions.avatarSize = SendDlgItemMessage(hwnd,IDC_AVT_SIZE_SLIDE, TBM_GETPOS,0,0);
+ SetDlgItemInt(hwnd, IDC_AVT_SIZE ,PopUpOptions.avatarSize,FALSE);
+ SendDlgItemMessage(hwnd, IDC_AVT_RADIUS_SPIN,UDM_SETRANGE, 0, (LPARAM)MAKELONG((PopUpOptions.avatarSize / 2),0));
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_TRANS_SLIDER:
+ {
+ PopUpOptions.Alpha = (BYTE)SendDlgItemMessage(hwnd,IDC_TRANS_SLIDER, TBM_GETPOS, 0,0);
+ wsprintf(tstr, TranslateT("%d%%"), Byte2Percentile(PopUpOptions.Alpha));
+ SetDlgItemText(hwnd, IDC_TRANS_PERCENT, tstr);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ default:
+ break;
+ }// end switch idCtrl
+ }//end WM_HSCROLL
+ break;
+ case WM_COMMAND: {
+ UINT idCtrl = LOWORD(wParam);
+ switch (HIWORD(wParam)) {
+ case BN_CLICKED: //Button controls
+ switch(idCtrl) {
+ case IDC_ENABLE_HISTORY:
+ {
+ PopUpOptions.EnableHistory = !PopUpOptions.EnableHistory;
+ EnableWindow(GetDlgItem(hwnd, IDC_HISTORY_STATIC1), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_HISTORYSIZE), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_HISTORY_STATIC2), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_SHOWHISTORY), PopUpOptions.EnableHistory);
+ EnableWindow(GetDlgItem(hwnd, IDC_HPPLOG), PopUpOptions.EnableHistory && gbHppInstalled);
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_SHOWHISTORY:
+ {
+ PopupHistoryShow();
+ }
+ break;
+ case IDC_HPPLOG:
+ {
+ PopUpOptions.UseHppHistoryLog = !PopUpOptions.UseHppHistoryLog;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_AVT_BORDER:
+ {
+ PopUpOptions.avatarBorders = !PopUpOptions.avatarBorders;
+ EnableWindow(GetDlgItem(hwnd, IDC_AVT_PNGBORDER), PopUpOptions.avatarBorders);
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_AVT_PNGBORDER:
+ {
+ PopUpOptions.avatarPNGBorders = !PopUpOptions.avatarPNGBorders;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_AVT_REQUEST:
+ {
+ PopUpOptions.EnableAvatarUpdates = !PopUpOptions.EnableAvatarUpdates;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_MIRANDAWND:
+ {
+ PopUpOptions.Monitor = MN_MIRANDA;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_ACTIVEWND:
+ {
+ PopUpOptions.Monitor = MN_ACTIVE;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_TRANS_9X:
+ {
+ PopUpOptions.Enable9xTransparency = !PopUpOptions.Enable9xTransparency;
+ SendMessage(GetParent(hwnd), PSM_CHANGED,0,0);
+ }
+ break;
+ case IDC_TRANS:
+ {
+ PopUpOptions.UseTransparency = !PopUpOptions.UseTransparency;
+#if defined(_UNICODE)
+ BOOL how = TRUE;
+#else
+ BOOL how = (BOOL)(MySetLayeredWindowAttributes);
+#endif
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_TXT1) ,how && PopUpOptions.UseTransparency);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_SLIDER) ,how && PopUpOptions.UseTransparency);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_PERCENT) ,how && PopUpOptions.UseTransparency);
+ EnableWindow(GetDlgItem(hwnd, IDC_TRANS_OPAQUEONHOVER) ,how && PopUpOptions.UseTransparency);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_TRANS_OPAQUEONHOVER:
+ {
+ PopUpOptions.OpaqueOnHover = !PopUpOptions.OpaqueOnHover;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_USEANIMATIONS:
+ {
+ PopUpOptions.UseAnimations = !PopUpOptions.UseAnimations;
+ BOOL enable = PopUpOptions.UseAnimations || PopUpOptions.UseEffect;
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_TXT1), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_SPIN), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_TXT2), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_TXT1), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_SPIN), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_TXT2), enable);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_PREVIEW:
+ {
+ PopUpPreview();
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case CBN_SELCHANGE: //ComboBox controls
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_EFFECT:
+ {
+ int iEffect = ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
+ PopUpOptions.UseEffect = (iEffect != -2) ? TRUE : FALSE;
+ mir_free(PopUpOptions.Effect);
+ PopUpOptions.Effect = mir_tstrdup((iEffect >= 0) ? g_lstPopupVfx[iEffect] : _T(""));
+
+ BOOL enable = PopUpOptions.UseAnimations || PopUpOptions.UseEffect;
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_TXT1), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_SPIN), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEIN_TXT2), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_TXT1), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_SPIN), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_FADEOUT_TXT2), enable);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case EN_CHANGE: //Edit controls change
+ if(!bDlgInit) break;
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_MAXPOPUPS:
+ {
+ int maxPop = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if(maxPop > 0){
+ PopUpOptions.MaxPopups = maxPop;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case IDC_HISTORYSIZE:
+ {
+ int histSize = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if( histSize > 0 &&
+ histSize <= SETTING_HISTORYSIZE_MAX){
+ PopUpOptions.HistorySize = histSize;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case IDC_AVT_RADIUS:
+ {
+ int avtRadius = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if( avtRadius <= SETTING_AVTSIZE_MAX / 2 ){
+ PopUpOptions.avatarRadius = avtRadius;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case IDC_FADEIN:
+ {
+ int fadeIn = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if( fadeIn >= SETTING_FADEINTIME_MIN &&
+ fadeIn <= SETTING_FADEINTIME_MAX ){
+ PopUpOptions.FadeIn = fadeIn;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case IDC_FADEOUT:
+ {
+ int fadeOut = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if( fadeOut >= SETTING_FADEOUTTIME_MIN &&
+ fadeOut <= SETTING_FADEOUTTIME_MAX){
+ PopUpOptions.FadeOut = fadeOut;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ break;
+ case EN_KILLFOCUS: //Edit controls lost fokus
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_MAXPOPUPS:
+ {
+ int maxPop = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if(maxPop <= 0)
+ PopUpOptions.MaxPopups = 20;
+ if(maxPop != PopUpOptions.MaxPopups) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.MaxPopups, FALSE);
+ //ErrorMSG(1);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ case IDC_HISTORYSIZE:
+ {
+ int histSize = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if(histSize <= 0)
+ PopUpOptions.HistorySize = SETTING_HISTORYSIZE_DEFAULT;
+ else if(histSize > SETTING_HISTORYSIZE_MAX)
+ PopUpOptions.HistorySize = SETTING_HISTORYSIZE_MAX;
+ if(histSize != PopUpOptions.HistorySize) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.HistorySize, FALSE);
+ ErrorMSG(1, SETTING_HISTORYSIZE_MAX);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ case IDC_AVT_RADIUS:
+ {
+ int avtRadius = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if(avtRadius > SETTING_AVTSIZE_MAX / 2)
+ PopUpOptions.avatarRadius = SETTING_AVTSIZE_MAX / 2;
+ if(avtRadius != PopUpOptions.avatarRadius) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.avatarRadius, FALSE);
+ ErrorMSG(0, SETTING_AVTSIZE_MAX / 2);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ case IDC_FADEIN:
+ {
+ int fade = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if(fade < SETTING_FADEINTIME_MIN)
+ PopUpOptions.FadeIn = SETTING_FADEINTIME_MIN;
+ else if(fade > SETTING_FADEINTIME_MAX)
+ PopUpOptions.FadeIn = SETTING_FADEINTIME_MAX;
+ if(fade != PopUpOptions.FadeIn) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.FadeIn, FALSE);
+ ErrorMSG(SETTING_FADEINTIME_MIN, SETTING_FADEINTIME_MAX);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ case IDC_FADEOUT:
+ {
+ int fade = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if(fade < SETTING_FADEOUTTIME_MIN)
+ PopUpOptions.FadeOut = SETTING_FADEOUTTIME_MIN;
+ else if(fade > SETTING_FADEOUTTIME_MAX)
+ PopUpOptions.FadeOut = SETTING_FADEOUTTIME_MAX;
+ if(fade != PopUpOptions.FadeOut) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.FadeOut, FALSE);
+ ErrorMSG(SETTING_FADEOUTTIME_MIN, SETTING_FADEOUTTIME_MAX);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ break;
+ default:
+ break;
+ }// end switch (HIWORD(wParam))
+ }//end WM_COMMAND
+ break;
+ case WM_NOTIFY: {
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0: {
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_RESET:
+ LoadOption_AdvOpts();
+ return TRUE;
+ case PSN_APPLY:
+ {
+ //History
+ DBWriteContactSettingByte (NULL,MODULNAME, "EnableHistory", (BYTE)PopUpOptions.EnableHistory);
+ DBWriteContactSettingWord (NULL,MODULNAME, "HistorySize", PopUpOptions.HistorySize);
+ PopupHistoryResize();
+ DBWriteContactSettingByte (NULL,MODULNAME, "UseHppHistoryLog", PopUpOptions.UseHppHistoryLog);
+ //Avatars
+ DBWriteContactSettingByte (NULL,MODULNAME, "AvatarBorders", PopUpOptions.avatarBorders);
+ DBWriteContactSettingByte (NULL,MODULNAME, "AvatarPNGBorders", PopUpOptions.avatarPNGBorders);
+ DBWriteContactSettingByte (NULL,MODULNAME, "AvatarRadius", PopUpOptions.avatarRadius);
+ DBWriteContactSettingWord (NULL,MODULNAME, "AvatarSize", PopUpOptions.avatarSize);
+ DBWriteContactSettingByte (NULL,MODULNAME, "EnableAvatarUpdates", PopUpOptions.EnableAvatarUpdates);
+ //Monitor
+ DBWriteContactSettingByte (NULL,MODULNAME, "Monitor", PopUpOptions.Monitor);
+ //Transparency
+ DBWriteContactSettingByte (NULL,MODULNAME, "EnableRegionTransparency", PopUpOptions.Enable9xTransparency);
+ DBWriteContactSettingByte (NULL,MODULNAME, "UseTransparency", PopUpOptions.UseTransparency);
+ DBWriteContactSettingByte (NULL,MODULNAME, "Alpha", PopUpOptions.Alpha);
+ DBWriteContactSettingByte (NULL,MODULNAME, "OpaqueOnHover", PopUpOptions.OpaqueOnHover);
+
+ //Effects
+ DBWriteContactSettingByte (NULL,MODULNAME, "UseAnimations", PopUpOptions.UseAnimations);
+ DBWriteContactSettingByte (NULL,MODULNAME, "Fade", PopUpOptions.UseEffect);
+ DBWriteContactSettingTString(NULL, MODULNAME, "Effect", PopUpOptions.Effect);
+ DBWriteContactSettingDword(NULL,MODULNAME, "FadeInTime", PopUpOptions.FadeIn);
+ DBWriteContactSettingDword(NULL,MODULNAME, "FadeOutTime", PopUpOptions.FadeOut);
+ //other old stuff
+ DBWriteContactSettingWord (NULL,MODULNAME, "MaxPopups", (BYTE)PopUpOptions.MaxPopups);
+ }
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }//end WM_NOTIFY
+ break;
+ case WM_DESTROY:
+ {
+ bDlgInit = false;
+ }//end WM_DESTROY
+ break;
+ default:
+ return FALSE;
+ }//end switch (msg)
+ return FALSE;
+}
+
+INT_PTR CALLBACK AvatarTrackBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (!IsWindowEnabled(hwnd))
+ return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA), hwnd, msg, wParam, lParam);
+
+ static int oldVal = -1;
+ switch (msg) {
+ case WM_MOUSEWHEEL:
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ {
+ if (!IsWindowVisible(hwndBox))
+ break;
+ }
+ case WM_MOUSEMOVE:
+ {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ tme.hwndTrack = hwnd;
+ _TrackMouseEvent(&tme);
+
+ int newVal = (BYTE)SendMessage(hwnd, TBM_GETPOS, 0, 0);
+ if (oldVal != newVal) {
+ if (oldVal < 0) {
+ SetWindowLongPtr(hwndBox, GWLP_USERDATA, 0);
+ }
+ RECT rc; GetWindowRect(hwnd, &rc);
+ SetWindowPos(hwndBox, NULL,
+ (rc.left+rc.right-newVal)/2, rc.bottom+2, newVal, newVal,
+ SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+
+ HRGN rgn = CreateRoundRectRgn(0, 0, newVal, newVal, 2 * PopUpOptions.avatarRadius, 2 * PopUpOptions.avatarRadius);
+ SetWindowRgn(hwndBox, rgn, TRUE);
+ InvalidateRect(hwndBox, NULL, FALSE);
+ oldVal = newVal;
+ }
+ }
+ break;
+ case WM_MOUSELEAVE:
+ {
+/*
+ SetWindowLongPtr(hwndBox, GWLP_USERDATA, 2);
+ SetWindowPos(hwndBox, NULL,
+ 0, 0, 201, 201,
+ SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+
+ HRGN hrgnWindow, hrgnTmp, hrgnTmp2;
+ hrgnWindow = CreateRectRgn(0, 0, 201, 201);
+ hrgnTmp = CreateEllipticRgn(-90, -90, 90, 90);
+ SubtractRgn(hrgnWindow, hrgnWindow, hrgnTmp);
+ hrgnTmp = CreateEllipticRgn(112, -90, 292, 90);
+ SubtractRgn(hrgnWindow, hrgnWindow, hrgnTmp);
+ hrgnTmp = CreateEllipticRgn(-90, 112, 90, 292);
+ SubtractRgn(hrgnWindow, hrgnWindow, hrgnTmp);
+ hrgnTmp = CreateEllipticRgn(112, 112, 292, 292);
+ SubtractRgn(hrgnWindow, hrgnWindow, hrgnTmp);
+
+ hrgnTmp = CreateRectRgn(5, 5, 196, 196);
+ hrgnTmp2 = CreateRoundRectRgn(89, 0, 113, 201, 8, 8);
+ UnionRgn(hrgnTmp, hrgnTmp, hrgnTmp2);
+ hrgnTmp2 = CreateRoundRectRgn(0, 89, 201, 113, 8, 8);
+ UnionRgn(hrgnTmp, hrgnTmp, hrgnTmp2);
+ IntersectRgn(hrgnWindow, hrgnWindow, hrgnTmp);
+
+ SetWindowRgn(hwndBox, hrgnWindow, FALSE);
+
+ if (MySetLayeredWindowAttributes)
+ {
+ SetWindowLong(hwndBox, GWL_EXSTYLE, GetWindowLong(hwndBox, GWL_EXSTYLE) | WS_EX_LAYERED);
+ MySetLayeredWindowAttributes(hwndBox, NULL, PopUpOptions.Alpha, LWA_ALPHA);
+ }
+*/
+ SetWindowRgn(hwndBox, NULL, TRUE);
+ ShowWindow(hwndBox, SW_HIDE);
+ oldVal = -1;
+ }
+ break;
+ default:
+ break;
+ }
+ return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA), hwnd, msg, wParam, lParam);
+}
+
+INT_PTR CALLBACK AlphaTrackBarWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (!IsWindowEnabled(hwnd))
+ return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA), hwnd, msg, wParam, lParam);
+
+ static int oldVal = -1;
+ switch (msg)
+ {
+ case WM_MOUSEWHEEL:
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ {
+ if (!IsWindowVisible(hwndBox))
+ break;
+ }
+ case WM_MOUSEMOVE:
+ {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ tme.hwndTrack = hwnd;
+ _TrackMouseEvent(&tme);
+
+ int newVal = (BYTE)SendMessage(hwnd, TBM_GETPOS, 0, 0);
+ if (oldVal != newVal)
+ {
+#if defined(_UNICODE)
+ if (oldVal < 0)
+ {
+ SetWindowLongPtr(hwndBox, GWLP_USERDATA, 1);
+ RECT rc; GetWindowRect(hwnd, &rc);
+ SetWindowPos(hwndBox, NULL,
+ (rc.left+rc.right-170)/2, rc.bottom+2, 170, 50,
+ SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ SetWindowRgn(hwndBox, NULL, TRUE);
+ }
+ SetWindowLong(hwndBox, GWL_EXSTYLE, GetWindowLong(hwndBox, GWL_EXSTYLE) | WS_EX_LAYERED);
+ SetLayeredWindowAttributes(hwndBox, NULL, newVal, LWA_ALPHA);
+#else
+ if (MySetLayeredWindowAttributes)
+ {
+ if (oldVal < 0)
+ {
+ SetWindowLongPtr(hwndBox, GWLP_USERDATA, 1);
+ RECT rc; GetWindowRect(hwnd, &rc);
+ SetWindowPos(hwndBox, NULL,
+ (rc.left+rc.right-170)/2, rc.bottom+2, 170, 50,
+ SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ SetWindowRgn(hwndBox, NULL, TRUE);
+ }
+ SetWindowLong(hwndBox, GWL_EXSTYLE, GetWindowLong(hwndBox, GWL_EXSTYLE) | WS_EX_LAYERED);
+ MySetLayeredWindowAttributes(hwndBox, NULL, newVal, LWA_ALPHA);
+ }
+#endif
+ oldVal = newVal;
+ }
+ break;
+ }
+ case WM_MOUSELEAVE:
+ {
+#if defined(_UNICODE)
+ SetWindowLong(hwndBox, GWL_EXSTYLE, GetWindowLong(hwndBox, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+ SetLayeredWindowAttributes(hwndBox, NULL, 255, LWA_ALPHA);
+#else
+ if (MySetLayeredWindowAttributes) {
+ SetWindowLong(hwndBox, GWL_EXSTYLE, GetWindowLong(hwndBox, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+ MySetLayeredWindowAttributes(hwndBox, NULL, 255, LWA_ALPHA);
+ }
+#endif
+ ShowWindow(hwndBox, SW_HIDE);
+ oldVal = -1;
+ break;
+ }
+ }
+ return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA), hwnd, msg, wParam, lParam);
+}
+
diff --git a/plugins/Popup/src/opt_adv.h b/plugins/Popup/src/opt_adv.h
new file mode 100644
index 0000000000..0e3a26a0da
--- /dev/null
+++ b/plugins/Popup/src/opt_adv.h
@@ -0,0 +1,45 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_adv.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __opt_adv_h__
+#define __opt_adv_h__
+
+extern HWND hwndBox;
+
+void OptAdv_RegisterVfx(char *name);
+void OptAdv_UnregisterVfx();
+
+void LoadOption_AdvOpts();
+INT_PTR CALLBACK DlgProcPopUpAdvOpts(HWND, UINT, WPARAM, LPARAM);
+
+
+#endif // __opt_adv_h__
diff --git a/plugins/Popup/src/opt_class.cpp b/plugins/Popup/src/opt_class.cpp
new file mode 100644
index 0000000000..b6376b88c0
--- /dev/null
+++ b/plugins/Popup/src/opt_class.cpp
@@ -0,0 +1,603 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+part of this file is taken from SjE great YAPP plugin:
+https://server.scottellis.com.au/svn/mim_plugs/yapp/options.cpp
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_class.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+#include "headers.h"
+
+//---------------------------------------------------------------------------
+//Workaround for MS bug ComboBox_SelectItemData
+int ComboBox_SelectItem(HWND hwndCtl, int indexStart, char* data) {
+ int i = 0;
+ for ( i ; i < ComboBox_GetCount(hwndCtl); i++) {
+ if(strcmp(data, (char*)ComboBox_GetItemData(hwndCtl, i))==0) {
+ ComboBox_SetCurSel (hwndCtl,i);
+ return i;
+ }
+ }
+ return CB_ERR;
+}
+
+//---------------------------------------------------------------------------
+//some help function (not realy needed)
+#define ComboBox_AddStringW(hwndCtl, lpwsz) ((int)(DWORD)MySendMessageW((HWND)(hwndCtl), CB_ADDSTRING, 0L, (LPARAM)(LPCWSTR)(lpwsz)))
+#define ComboBox_SetTextW(hwndCtl, lpwsz) ((int)(DWORD)MySetWindowTextW((HWND)(hwndCtl), (LPCWSTR)(lpwsz)))
+
+//---------------------------------------------------------------------------
+//Dialog Proc
+INT_PTR CALLBACK DlgProcOptsClasses(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ static TVITEM tvi = {0};
+ static struct {
+ UINT idCtrl;
+ BYTE onTyp0;
+ BYTE onTyp1;
+ BYTE onTyp2;
+ } ctrlsAll[] = {
+ {IDC_TXT_TITLE1 ,0 ,1 ,1},
+ {IDC_ENABLE ,0 ,1 ,1},
+
+ {IDC_TXT_TIMEOUT ,0 ,1 ,1},
+ {IDC_TIMEOUT ,0 ,1 ,1},
+ {IDC_TIMEOUT_SPIN ,0 ,1 ,1},
+ {IDC_TXT_TIMEOUT_SEC ,0 ,1 ,1},
+ {IDC_TXT_TIMEOUT_DEFAULT ,0 ,1 ,1},
+ {IDC_TXT_TIMEOUT_INFINITE ,0 ,1 ,1},
+
+ {IDC_TXT_LACTION ,0 ,1 ,1},
+ {IDC_LACTION ,0 ,1 ,1},
+
+ {IDC_TXT_RACTION ,0 ,1 ,1},
+ {IDC_RACTION ,0 ,1 ,1},
+
+ {IDC_CHECKWINDOW ,0 ,0 ,0}, //may be delete ??
+
+ {IDC_TXT_TITLE3 ,0 ,1 ,0},
+ {IDC_SOFFLINE ,0 ,1 ,0},
+ {IDC_SONLINE ,0 ,1 ,0},
+ {IDC_SAWAY ,0 ,1 ,0},
+ {IDC_SNA ,0 ,1 ,0},
+ {IDC_SOCCUPIED ,0 ,1 ,0},
+ {IDC_SDND ,0 ,1 ,0},
+ {IDC_SFREE4CHAT ,0 ,1 ,0},
+ {IDC_SINVISIBLE ,0 ,1 ,0},
+ {IDC_SPHONE ,0 ,1 ,0},
+ {IDC_SLUNCH ,0 ,1 ,0},
+
+ {IDC_TXT_TITLE4 ,0 ,0 ,0},
+ {IDC_SOFFLINE2 ,0 ,0 ,0},
+ {IDC_SONLINE2 ,0 ,0 ,0},
+ {IDC_SAWAY2 ,0 ,0 ,0},
+ {IDC_SNA2 ,0 ,0 ,0},
+ {IDC_SOCCUPIED2 ,0 ,0 ,0},
+ {IDC_SDND2 ,0 ,0 ,0},
+ {IDC_SFREE4CHAT2 ,0 ,0 ,0},
+ {IDC_SINVISIBLE2 ,0 ,0 ,0},
+ {IDC_SPHONE2 ,0 ,0 ,0},
+ {IDC_SLUNCH2 ,0 ,0 ,0},
+
+ {IDC_ICO_INFO ,0 ,1 ,1},
+ {IDC_TXT_COLORS ,0 ,1 ,1},
+ {IDC_MORE ,0 ,1 ,1},
+
+ {IDC_PREVIEW ,0 ,1 ,1},
+ };
+
+ static UINT ctrlsClass[] = {
+ IDC_TXT_TITLE1, /*IDC_TXT_TITLE3,*/
+ IDC_TXT_TIMEOUT, IDC_TIMEOUT,
+ IDC_TIMEOUT_SPIN, IDC_TXT_TIMEOUT_SEC,
+ IDC_TXT_TIMEOUT_DEFAULT, IDC_TXT_TIMEOUT_INFINITE,
+ IDC_TXT_LACTION, IDC_LACTION,
+ IDC_TXT_RACTION, IDC_RACTION,
+ IDC_ICO_INFO, IDC_TXT_COLORS,
+ };
+
+ static UINT ctrlsEnable[] = {
+ IDC_TXT_TIMEOUT, IDC_TIMEOUT, IDC_TIMEOUT_SPIN,
+ IDC_TXT_TIMEOUT_SEC , IDC_TXT_TIMEOUT_DEFAULT, IDC_TXT_TIMEOUT_INFINITE,
+ IDC_TXT_LACTION, IDC_LACTION,
+ IDC_TXT_RACTION, IDC_RACTION,
+ /*IDC_CHECKWINDOW,*/ IDC_TXT_TITLE3, IDC_TXT_TITLE4,
+ IDC_ICO_INFO, IDC_TXT_COLORS, IDC_MORE,
+
+ IDC_SOFFLINE, IDC_SONLINE, IDC_SAWAY, IDC_SNA,
+ IDC_SOCCUPIED, IDC_SDND, IDC_SFREE4CHAT,
+ IDC_SINVISIBLE, IDC_SPHONE, IDC_SLUNCH,
+
+ IDC_SOFFLINE2, IDC_SONLINE2, IDC_SAWAY2, IDC_SNA2,
+ IDC_SOCCUPIED2, IDC_SDND2, IDC_SFREE4CHAT2,
+ IDC_SINVISIBLE2, IDC_SPHONE2, IDC_SLUNCH2,
+ };
+
+ static UINT ctrlsContact[] = {
+ /*IDC_CHECKWINDOW,*/ IDC_TXT_TITLE4,
+ IDC_SOFFLINE2, IDC_SONLINE2, IDC_SAWAY2, IDC_SNA2,
+ IDC_SOCCUPIED2, IDC_SDND2, IDC_SFREE4CHAT2,
+ IDC_SINVISIBLE2, IDC_SPHONE2, IDC_SLUNCH2,
+ };
+
+ static int titleIds[] = {
+ IDC_TXT_TITLE1,
+ IDC_TXT_TITLE3,
+ IDC_TXT_TITLE4,
+ };
+
+ static struct {
+ int idCtrl;
+ int iconId;
+ char *title;
+ DWORD statusFlag;
+ DWORD disableWhenFlag;
+ } statusButtons[] = {
+ {IDC_SOFFLINE, SKINICON_STATUS_OFFLINE, "Offline", PF2_IDLE, PF2_IDLE},
+ {IDC_SONLINE, SKINICON_STATUS_ONLINE, "Online", PF2_ONLINE, PF2_ONLINE},
+ {IDC_SAWAY, SKINICON_STATUS_AWAY, "Away", PF2_SHORTAWAY, PF2_SHORTAWAY},
+ {IDC_SNA, SKINICON_STATUS_NA, "NA", PF2_LONGAWAY, PF2_LONGAWAY},
+ {IDC_SOCCUPIED, SKINICON_STATUS_OCCUPIED, "Occupied", PF2_LIGHTDND, PF2_LIGHTDND},
+ {IDC_SDND, SKINICON_STATUS_DND, "DND", PF2_HEAVYDND, PF2_HEAVYDND},
+ {IDC_SFREE4CHAT, SKINICON_STATUS_FREE4CHAT, "Free for chat", PF2_FREECHAT, PF2_FREECHAT},
+ {IDC_SINVISIBLE, SKINICON_STATUS_INVISIBLE, "Invisible", PF2_INVISIBLE, PF2_INVISIBLE},
+ {IDC_SPHONE, SKINICON_STATUS_ONTHEPHONE, "On the phone", PF2_ONTHEPHONE, PF2_ONTHEPHONE},
+ {IDC_SLUNCH, SKINICON_STATUS_OUTTOLUNCH, "Out to lunch", PF2_OUTTOLUNCH, PF2_OUTTOLUNCH},
+
+ {IDC_SOFFLINE2, SKINICON_STATUS_OFFLINE, "Offline", PF2_IDLE, PF2_IDLE<<16},
+ {IDC_SONLINE2, SKINICON_STATUS_ONLINE, "Online", PF2_ONLINE, PF2_ONLINE<<16},
+ {IDC_SAWAY2, SKINICON_STATUS_AWAY, "Away", PF2_SHORTAWAY, PF2_SHORTAWAY<<16},
+ {IDC_SNA2, SKINICON_STATUS_NA, "NA", PF2_LONGAWAY, PF2_LONGAWAY<<16},
+ {IDC_SOCCUPIED2, SKINICON_STATUS_OCCUPIED, "Occupied", PF2_LIGHTDND, PF2_LIGHTDND<<16},
+ {IDC_SDND2, SKINICON_STATUS_DND, "DND", PF2_HEAVYDND, PF2_HEAVYDND<<16},
+ {IDC_SFREE4CHAT2, SKINICON_STATUS_FREE4CHAT, "Free for chat", PF2_FREECHAT, PF2_FREECHAT<<16},
+ {IDC_SINVISIBLE2, SKINICON_STATUS_INVISIBLE, "Invisible", PF2_INVISIBLE, PF2_INVISIBLE<<16},
+ {IDC_SPHONE2, SKINICON_STATUS_ONTHEPHONE, "On the phone", PF2_ONTHEPHONE, PF2_ONTHEPHONE<<16},
+ {IDC_SLUNCH2, SKINICON_STATUS_OUTTOLUNCH, "Out to lunch", PF2_OUTTOLUNCH, PF2_OUTTOLUNCH<<16},
+ };
+
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ int i;
+ TranslateDialogDefault( hwnd );
+
+ //Treeview
+ HWND hwndTree = GetDlgItem(hwnd, IDC_TREE1);
+ {
+ int iconIndex = 0;
+ char iconName[MAXMODULELABELLENGTH];
+ TCHAR itemName[MAXMODULELABELLENGTH];
+ TreeView_DeleteAllItems(hwndTree);
+ //Treeview create image list
+ HIMAGELIST hImgLst = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR|ILC_COLOR32|ILC_MASK, 5, num_classes+1);
+ ImageList_ReplaceIcon(hImgLst, -1, IcoLib_GetIcon(ICO_OPT_GROUP,0));
+ TreeView_SetImageList(hwndTree, hImgLst, TVSIL_NORMAL);
+
+ for (i = 0; i < gTreeData.getCount(); ++i) {
+ switch (gTreeData[i]->typ) {
+ case 1: //Treeview part for typ 1 (notification)
+ mir_snprintf(iconName, sizeof(iconName), "%s_"TCHAR_STR_PARAM"_"TCHAR_STR_PARAM, MODULNAME, gTreeData[i]->pszTreeRoot, gTreeData[i]->pszDescription);
+ iconIndex = ImageList_ReplaceIcon(hImgLst, -1, IcoLib_GetIcon(iconName));
+ wsprintf(itemName, _T("%s/%s"), gTreeData[i]->pszTreeRoot, gTreeData[i]->pszDescription);
+ break;
+ case 2: //Treeview part typ 2 (popup class api)
+ iconIndex = ImageList_ReplaceIcon(hImgLst, -1, gTreeData[i]->pupClass.hIcon);
+ wsprintf(itemName, _T("%s/%s"), _T("CLASS Plugins")/*gTreeData[i]->pszTreeRoot*/, gTreeData[i]->pszDescription);
+ break;
+ default:
+ break;
+ }
+ OptTree_AddItem(hwndTree, itemName, (LPARAM)gTreeData[i], iconIndex);
+ }
+ OptTree_Translate(hwndTree);
+ } // end Treeview
+
+ //Bold Title
+ for (i = 0; i < SIZEOF(titleIds); ++i)
+ {
+ LOGFONT lf;
+ GetObject((HFONT)SendDlgItemMessage(hwnd, titleIds[i], WM_GETFONT, 0, 0), sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ SendDlgItemMessage(hwnd, titleIds[i], WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), TRUE);
+ }
+
+ //spindown for Timeout
+ SendDlgItemMessage(hwnd, IDC_TIMEOUT_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_LIFETIME_MAX, SETTING_LIFETIME_INFINITE));
+ SetDlgItemInt(hwnd,IDC_TIMEOUT, (UINT)0, TRUE);
+ //status buttons
+ for (i = 0; i < SIZEOF(statusButtons); ++i)
+ {
+ SendDlgItemMessage(hwnd, statusButtons[i].idCtrl, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwnd, statusButtons[i].idCtrl, BUTTONSETASPUSHBTN, 0, 0);
+ SendDlgItemMessage(hwnd, statusButtons[i].idCtrl, BM_SETIMAGE,
+ IMAGE_ICON, (LPARAM)LoadSkinnedIcon(statusButtons[i].iconId));
+ SendDlgItemMessage(hwnd, statusButtons[i].idCtrl, BUTTONADDTOOLTIP,
+ (WPARAM)Translate(statusButtons[i].title), 0);
+ }
+ //info icon
+ SendDlgItemMessage(hwnd, IDC_ICO_INFO, STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_MISC_NOTIFY,0), 0);
+ //more button
+ EnableWindow(GetDlgItem(hwnd, IDC_MORE), FALSE);
+ //preview button
+ ShowWindow(GetDlgItem(hwnd, IDC_CHECKWINDOW), SW_HIDE);
+
+ SendMessage(hwnd, WM_USER, 0, 0);
+
+ return TRUE;
+ }
+ case WM_USER:
+ {
+ int i;
+ HWND hTV = GetDlgItem(hwnd, IDC_TREE1);
+ //get TreeView selection
+ tvi.hItem = TreeView_GetSelection(hTV);
+ tvi.mask = TVIF_PARAM|TVIF_HANDLE|TVIF_TEXT;
+ if (tvi.hItem) TreeView_GetItem(hTV, &tvi);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, tvi.lParam);
+
+ if (tvi.lParam) {
+ POPUPTREEDATA* ptd = (POPUPTREEDATA *)tvi.lParam;
+ HWND hCtrl = 0;
+ LPTSTR psztSelect = NULL;
+ int index = 0;
+ //combo left action (default)
+ {
+ hCtrl = GetDlgItem(hwnd, IDC_LACTION);
+ ComboBox_ResetContent(hCtrl);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT(POPUP_ACTION_DISMISS)),POPUP_ACTION_DISMISS);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT(POPUP_ACTION_NOTHING)),POPUP_ACTION_NOTHING);
+ }
+ //combo right action (default)
+ {
+ hCtrl = GetDlgItem(hwnd, IDC_RACTION);
+ ComboBox_ResetContent(hCtrl);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT(POPUP_ACTION_DISMISS)),POPUP_ACTION_DISMISS);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT(POPUP_ACTION_NOTHING)),POPUP_ACTION_NOTHING);
+ }
+
+ //element typ1 (Notification)
+ if (ptd->typ == 1) {
+ LPTSTR psztAction = NULL;
+ //Timeout
+ SetDlgItemInt(hwnd,IDC_TIMEOUT, (UINT)ptd->timeoutValue, TRUE);
+ SendDlgItemMessage(hwnd, IDC_TIMEOUT_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(250, -1));
+ //combo left action (EXTRA)
+ hCtrl = GetDlgItem(hwnd, IDC_LACTION);
+ for (i = 0; i < ptd->notification.actionCount; ++i) {
+ psztAction = mir_a2t(ptd->notification.lpActions[i].lpzTitle);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateTS(psztAction)),ptd->notification.lpActions[i].lpzTitle);
+ mir_free(psztAction); psztAction = NULL;
+ }
+ //combo right action (EXTRA)
+ hCtrl = GetDlgItem(hwnd, IDC_RACTION);
+ psztAction = NULL;
+ for (i = 0; i < ptd->notification.actionCount; ++i) {
+ psztAction = mir_a2t(ptd->notification.lpActions[i].lpzTitle);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateTS(psztAction)),ptd->notification.lpActions[i].lpzTitle);
+ mir_free(psztAction); psztAction = NULL;
+ }
+ //enable all controls
+ for (i = 0; i < SIZEOF(ctrlsAll); ++i){
+ ShowWindow(GetDlgItem(hwnd, ctrlsAll[i].idCtrl), ctrlsAll[i].onTyp1 ? SW_SHOW : SW_HIDE);
+ EnableWindow(GetDlgItem(hwnd, ctrlsAll[i].idCtrl), ctrlsAll[i].onTyp1);
+ }
+ //enable or disable controls ctrlsEnable
+ for (i = 0; i < SIZEOF(ctrlsEnable); ++i)
+ EnableWindow(GetDlgItem(hwnd, ctrlsEnable[i]), ptd->enabled ? TRUE : FALSE);
+ //show or hide controls ctrlsContact
+ for (i = 0; i < SIZEOF(ctrlsContact); ++i)
+ ShowWindow(GetDlgItem(hwnd, ctrlsContact[i]), ptd->notification.dwFlags&PNF_CONTACT ? SW_SHOW : SW_HIDE);
+ //statusButtons state
+ for (i = 0; i < SIZEOF(statusButtons); ++i)
+ CheckDlgButton(hwnd, statusButtons[i].idCtrl, ptd->disableWhen & statusButtons[i].disableWhenFlag ? TRUE : FALSE);
+ }
+ //element typ2 (CLASS Plugins)
+ else if (ptd->typ == 2) {
+ //Timeout
+ SetDlgItemInt(hwnd,IDC_TIMEOUT, (UINT)ptd->timeoutValue, TRUE);
+ SendDlgItemMessage(hwnd, IDC_TIMEOUT_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(250, -1));
+ //enable ctrls
+ for (i = 0; i < SIZEOF(ctrlsAll); ++i){
+ ShowWindow(GetDlgItem(hwnd, ctrlsAll[i].idCtrl), ctrlsAll[i].onTyp2 ? SW_SHOW : SW_HIDE);
+ EnableWindow(GetDlgItem(hwnd, ctrlsAll[i].idCtrl), ctrlsAll[i].onTyp2);
+ }
+ }
+ //checkbox enable notify
+ CheckDlgButton(hwnd, IDC_ENABLE, ptd->enabled ? TRUE : FALSE);
+ //combo left action (SELECT)
+ hCtrl = GetDlgItem(hwnd, IDC_LACTION);
+ ComboBox_SelectItem (hCtrl, -1, ptd->leftAction); //use Workaround for MS bug ComboBox_SelectItemData
+ //combo right action (SELECT)
+ hCtrl = GetDlgItem(hwnd, IDC_RACTION);
+ ComboBox_SelectItem (hCtrl, -1, ptd->rightAction); //use Workaround for MS bug ComboBox_SelectItemData
+ } //end if (tvi.lParam)
+ else {
+ //enable / disable controls
+ for (int i = 0; i < SIZEOF(ctrlsAll); ++i) {
+ ShowWindow(GetDlgItem(hwnd, ctrlsAll[i].idCtrl), ctrlsAll[i].onTyp0 ? SW_SHOW : SW_HIDE);
+ EnableWindow(GetDlgItem(hwnd, ctrlsAll[i].idCtrl), ctrlsAll[i].onTyp0);
+ }
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ UINT idCtrl = LOWORD(wParam);
+ POPUPTREEDATA* ptd = (POPUPTREEDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (!ptd) break;
+ switch (HIWORD(wParam)) {
+ int i;
+ case BN_CLICKED: //Button controls
+ switch(idCtrl) {
+ case IDC_ENABLE:
+ ptd->enabled = (BYTE)Button_GetCheck((HWND)lParam);
+ for (i = 0; i < SIZEOF(ctrlsEnable); ++i)
+ EnableWindow(GetDlgItem(hwnd, ctrlsEnable[i]), ptd->enabled);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_PREVIEW:
+ {
+ POPUPDATA2 ppd = {0};
+ ppd.cbSize = sizeof(ppd);
+ ppd.flags = PU2_TCHAR;
+ ppd.lptzTitle = ptd->pszDescription;
+ ppd.lptzText = TranslateT("Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn!");
+ ppd.iSeconds = ptd->timeoutValue;
+ ppd.colorBack = ptd->colorBack;
+ ppd.colorText = ptd->colorText;
+ POPUPTREEDATA *ptdPrev = NULL;
+ if(ptd->typ == 1) {
+ //we work with a copy for preview
+ ptdPrev = (POPUPTREEDATA *)mir_alloc(sizeof(POPUPTREEDATA));
+ memcpy(ptdPrev, ptd, sizeof(POPUPTREEDATA));
+ ptdPrev->enabled = ptd->enabled;
+ ptdPrev->timeoutValue = ptd->timeoutValue;
+ strcpy(ptdPrev->leftAction , ptd->leftAction); //geht noch nicht??
+ strcpy(ptdPrev->rightAction , ptd->rightAction); //geht noch nicht??
+ ptdPrev->disableWhen = ptd->disableWhen;
+
+ ppd.lchNotification = (HANDLE)ptdPrev;
+ }
+ else if(ptd->typ == 2) {
+ ppd.lchIcon = ptd->pupClass.hIcon;
+ }
+ CallService(MS_POPUP_ADDPOPUP2, (WPARAM)&ppd, APF_NO_HISTORY);
+ mir_free(ptdPrev); ptdPrev = NULL;
+ }
+ break;
+ case IDC_MORE:
+ {
+ OPENOPTIONSDIALOG ood = {0};
+ ood.cbSize = sizeof(OPENOPTIONSDIALOG);
+ ood.pszGroup = "Customize";
+ ood.pszPage = "Fonts & Colors";
+ CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood);
+ }
+ break;
+ case IDC_SOFFLINE: case IDC_SONLINE: case IDC_SAWAY: case IDC_SNA: case IDC_SOCCUPIED:
+ case IDC_SDND: case IDC_SFREE4CHAT: case IDC_SINVISIBLE: case IDC_SPHONE: case IDC_SLUNCH:
+ case IDC_SOFFLINE2: case IDC_SONLINE2: case IDC_SAWAY2: case IDC_SNA2: case IDC_SOCCUPIED2:
+ case IDC_SDND2: case IDC_SFREE4CHAT2: case IDC_SINVISIBLE2: case IDC_SPHONE2: case IDC_SLUNCH2:
+ {
+ ptd->disableWhen = 0;
+ for (i = 0; i < SIZEOF(statusButtons); ++i) {
+ if (IsDlgButtonChecked(hwnd, statusButtons[i].idCtrl))
+ ptd->disableWhen |= statusButtons[i].disableWhenFlag;
+ if (idCtrl == statusButtons[i].idCtrl)
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case CBN_SELCHANGE: //ComboBox controls
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_LACTION:
+ lstrcpynA(ptd->leftAction,
+ (char *)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)),
+ sizeof(ptd->leftAction));
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_RACTION:
+ lstrcpynA(ptd->rightAction,
+ (char *)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)),
+ sizeof(ptd->rightAction));
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ case EN_CHANGE: //Edit controls
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_TIMEOUT:
+ {
+ int seconds = GetDlgItemInt(hwnd, idCtrl, NULL, TRUE);
+ if ( seconds >= SETTING_LIFETIME_INFINITE &&
+ seconds <= SETTING_LIFETIME_MAX &&
+ seconds != ptd->timeoutValue) {
+ ptd->timeoutValue = seconds;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case EN_KILLFOCUS: //Edit controls lost fokus
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_TIMEOUT:
+ {
+ int seconds = GetDlgItemInt(hwnd, idCtrl, NULL, TRUE);
+ if (seconds > SETTING_LIFETIME_MAX)
+ ptd->timeoutValue = SETTING_LIFETIME_MAX;
+ else if (seconds < SETTING_LIFETIME_INFINITE)
+ ptd->timeoutValue = SETTING_LIFETIME_INFINITE;
+ if(seconds != ptd->timeoutValue) {
+ SetDlgItemInt(hwnd, idCtrl, ptd->timeoutValue, TRUE);
+ ErrorMSG(SETTING_LIFETIME_INFINITE, SETTING_LIFETIME_MAX);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_RESET:
+ {
+ for(int i = 0; i < gTreeData.getCount(); ++i) {
+ switch (gTreeData[i]->typ) {
+ case 1:
+ LoadNotificationSettings(gTreeData[i], "PopUpNotifications");
+ break;
+ case 2: //not finish
+ LoadClassSettings(gTreeData[i], PU_MODULCLASS);
+ gTreeData[i]->timeoutValue = gTreeData[i]->pupClass.iSeconds;
+ break;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+ }
+ case PSN_APPLY:
+ {
+ for(int i = 0; i < gTreeData.getCount(); ++i) {
+ switch (gTreeData[i]->typ) {
+ case 1:
+ gTreeData[i]->notification.iSeconds = gTreeData[i]->timeoutValue;
+ SaveNotificationSettings(gTreeData[i],"PopUpNotifications");
+ break;
+ case 2: //not finish
+ gTreeData[i]->pupClass.iSeconds = gTreeData[i]->timeoutValue;
+ SaveClassSettings(gTreeData[i],"PopUpCLASS");
+ break;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+
+ case IDC_TREE1:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ {
+ PostMessage(hwnd, WM_USER, 0, 0);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_DESTROY:
+ ZeroMemory(&tvi,sizeof(tvi));
+ break;
+
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+
+void LoadClassSettings(POPUPTREEDATA *ptd, char* szModul)
+{
+ char setting[2*MAXMODULELABELLENGTH];
+ char *szTmp = NULL;
+
+ mir_snprintf(setting, sizeof(setting), "%s/enabled", ptd->pupClass.pszName);
+ ptd->enabled =
+ (signed char)DBGetContactSettingByte(NULL, szModul, setting, TRUE);
+
+ mir_snprintf(setting, sizeof(setting), "%s/Timeout", ptd->pupClass.pszName);
+ ptd->pupClass.iSeconds =
+ (signed char)DBGetContactSettingWord(NULL, szModul, setting, 0);
+
+ mir_snprintf(setting, sizeof(setting), "%s/TimeoutVal", ptd->pupClass.pszName);
+ ptd->timeoutValue =
+ (signed char)DBGetContactSettingWord(NULL, szModul, setting,
+ ptd->pupClass.iSeconds ? ptd->pupClass.iSeconds : PopUpOptions.Seconds);
+
+ mir_snprintf(setting, sizeof(setting), "%s/leftAction", ptd->pupClass.pszName);
+ szTmp = DBGetContactSettingString(NULL, szModul, setting, POPUP_ACTION_NOTHING); //standart ??
+ lstrcpynA(ptd->leftAction, szTmp, sizeof(ptd->leftAction));
+ mir_free(szTmp); szTmp = NULL;
+
+ mir_snprintf(setting, sizeof(setting), "%s/rightAction", ptd->pupClass.pszName);
+ szTmp = DBGetContactSettingString(NULL, szModul, setting, POPUP_ACTION_DISMISS); //standart ??
+ lstrcpynA(ptd->rightAction, szTmp, sizeof(ptd->rightAction));
+ mir_free(szTmp); szTmp = NULL;
+
+}
+void SaveClassSettings(POPUPTREEDATA *ptd, char* szModul)
+{
+ char setting[2*MAXMODULELABELLENGTH];
+
+ mir_snprintf(setting, sizeof(setting), "%s/enabled", ptd->pupClass.pszName);
+ DBWriteContactSettingByte(NULL, szModul, setting, ptd->enabled);
+
+ mir_snprintf(setting, sizeof(setting), "%s/Timeout", ptd->pupClass.pszName);
+ DBWriteContactSettingWord(NULL, szModul, setting, ptd->pupClass.iSeconds);
+
+ mir_snprintf(setting, sizeof(setting), "%s/TimeoutVal",ptd->pupClass.pszName);
+ DBWriteContactSettingWord(NULL, szModul, setting, ptd->timeoutValue);
+
+ mir_snprintf(setting, sizeof(setting), "%s/leftAction",ptd->pupClass.pszName);
+ DBWriteContactSettingString(NULL, szModul, setting, ptd->leftAction);
+
+ mir_snprintf(setting, sizeof(setting), "%s/rightAction",ptd->pupClass.pszName);
+ DBWriteContactSettingString(NULL, szModul, setting, ptd->rightAction);
+}
diff --git a/plugins/Popup/src/opt_class.h b/plugins/Popup/src/opt_class.h
new file mode 100644
index 0000000000..245409a07b
--- /dev/null
+++ b/plugins/Popup/src/opt_class.h
@@ -0,0 +1,41 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_class.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __opt_class_h__
+#define __opt_class_h__
+
+void LoadClassSettings(POPUPTREEDATA *ptd, char* szModul);
+void SaveClassSettings(POPUPTREEDATA *ptd, char* szModul);
+
+INT_PTR CALLBACK DlgProcOptsClasses(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#endif // __opt_class_h__
diff --git a/plugins/Popup/src/opt_contacts.cpp b/plugins/Popup/src/opt_contacts.cpp
new file mode 100644
index 0000000000..582a85ae77
--- /dev/null
+++ b/plugins/Popup/src/opt_contacts.cpp
@@ -0,0 +1,175 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_contacts.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static void sttResetListOptions(HWND hwndList);
+static void sttSetAllContactIcons(HWND hwndList);
+
+INT_PTR CALLBACK DlgProcContactOpts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwnd);
+
+ SendMessage(GetDlgItem(hwnd, IDC_ICO_AUTO), STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_OPT_DEF,0), 0);
+ SendMessage(GetDlgItem(hwnd, IDC_ICO_FAVORITE), STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_OPT_FAV,0), 0);
+ SendMessage(GetDlgItem(hwnd, IDC_ICO_FULLSCREEN), STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_OPT_FULLSCREEN,0), 0);
+ SendMessage(GetDlgItem(hwnd, IDC_ICO_BLOCK), STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_OPT_BLOCK,0), 0);
+
+ HIMAGELIST hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),
+ (IsWinVerXPPlus()?ILC_COLOR32:ILC_COLOR16)|ILC_MASK,5,5);
+ ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT));
+ ImageList_AddIcon(hIml, IcoLib_GetIcon(ICO_OPT_DEF,0));
+ ImageList_AddIcon(hIml, IcoLib_GetIcon(ICO_OPT_FAV,0));
+ ImageList_AddIcon(hIml, IcoLib_GetIcon(ICO_OPT_FULLSCREEN,0));
+ ImageList_AddIcon(hIml, IcoLib_GetIcon(ICO_OPT_BLOCK,0));
+ SendDlgItemMessage(hwnd, IDC_LIST, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml);
+ SendDlgItemMessage(hwnd, IDC_LIST, CLM_SETEXTRACOLUMNS, 4 /*SIZEOF(sttIcons)*/, 0);
+ sttResetListOptions(GetDlgItem(hwnd, IDC_LIST));
+ sttSetAllContactIcons(GetDlgItem(hwnd, IDC_LIST));
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case IDC_LIST:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case CLN_NEWCONTACT:
+ case CLN_LISTREBUILT:
+ sttSetAllContactIcons(GetDlgItem(hwnd,IDC_LIST));
+ break;
+ case CLN_OPTIONSCHANGED:
+ sttResetListOptions(GetDlgItem(hwnd,IDC_LIST));
+ break;
+ case NM_CLICK:
+ {
+ HANDLE hItem;
+ NMCLISTCONTROL *nm=(NMCLISTCONTROL*)lParam;
+ DWORD hitFlags;
+ int iImage;
+
+ if(nm->iColumn==-1) break;
+ hItem=(HANDLE)SendDlgItemMessage(hwnd,IDC_LIST,CLM_HITTEST,(WPARAM)&hitFlags,MAKELPARAM(nm->pt.x,nm->pt.y));
+ if(hItem==NULL) break;
+ if(!(hitFlags&CLCHT_ONITEMEXTRA)) break;
+
+ iImage=SendDlgItemMessage(hwnd,IDC_LIST,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(nm->iColumn,0));
+ if (iImage != 0xFF)
+ {
+ for (int i = 0; i < 4 /*SIZEOF(sttIcons)*/; ++i)
+ //hIml element [0] = SKINICON_OTHER_SMALLDOT
+ //hIml element [1..5] = IcoLib_GetIcon(....) ~ old sttIcons
+ SendDlgItemMessage(hwnd, IDC_LIST, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, (i==nm->iColumn)?i+1:0));
+ }
+/*
+ {
+ while (hItem=(HANDLE)SendDlgItemMessage(hwnd,IDC_LIST,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem))
+ {
+ for (int i = 0; i < SIZEOF(sttIcons); ++i)
+ SendDlgItemMessage(hwnd, IDC_LIST, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, (i==nm->iColumn)?i+1:0));
+ hItem = (HANDLE)SendDlgItemMessage(hwnd,IDC_LIST,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem);
+ }
+ }
+*/
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+ }
+ break;
+ }
+
+ case 0:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ HWND hwndList = GetDlgItem(hwnd, IDC_LIST);
+ for (HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact;
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0))
+ {
+ HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ for (int i = 0; i < 4 /*SIZEOF(sttIcons)*/; ++i)
+ {
+ if (SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(i,0)))
+ {
+ DBWriteContactSettingByte(hContact, MODULNAME, "ShowMode", i);
+ break;
+ }
+ }
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static void sttResetListOptions(HWND hwndList)
+{
+ SendMessage(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL);
+ SendMessage(hwndList,CLM_SETBKCOLOR,GetSysColor(COLOR_WINDOW),0);
+ SendMessage(hwndList,CLM_SETGREYOUTFLAGS,0,0);
+ SendMessage(hwndList,CLM_SETLEFTMARGIN,4,0);
+ SendMessage(hwndList,CLM_SETINDENT,20,0);
+ SendMessage(hwndList,CLM_SETHIDEEMPTYGROUPS,1,0);
+ for(int i=0;i<=FONTID_MAX;i++)
+ SendMessage(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT));
+}
+
+static void sttSetAllContactIcons(HWND hwndList)
+{
+ for (HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact;
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0))
+ {
+ HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ DWORD dwMode = DBGetContactSettingByte(hContact, MODULNAME, "ShowMode", 0);
+ for (int i = 0; i < 4 /*SIZEOF(sttIcons)*/; ++i)
+ //hIml element [0] = SKINICON_OTHER_SMALLDOT
+ //hIml element [1..5] = IcoLib_GetIcon(....) ~ old sttIcons
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, (dwMode==i)?i+1:0));
+ }
+}
diff --git a/plugins/Popup/src/opt_contacts.h b/plugins/Popup/src/opt_contacts.h
new file mode 100644
index 0000000000..222b97c22a
--- /dev/null
+++ b/plugins/Popup/src/opt_contacts.h
@@ -0,0 +1,46 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_contacts.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __opt_contacts_h__
+#define __opt_contacts_h__
+
+enum
+{
+ PU_SHOWMODE_AUTO,
+ PU_SHOWMODE_FAVORITE,
+ PU_SHOWMODE_FULLSCREEN,
+ PU_SHOWMODE_BLOCK
+};
+
+INT_PTR CALLBACK DlgProcContactOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#endif // __opt_contacts_h__
diff --git a/plugins/Popup/src/opt_gen.cpp b/plugins/Popup/src/opt_gen.cpp
new file mode 100644
index 0000000000..109598ee87
--- /dev/null
+++ b/plugins/Popup/src/opt_gen.cpp
@@ -0,0 +1,761 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_gen.cpp $
+Revision : $Revision: 1628 $
+Last change on : $Date: 2010-06-30 03:42:27 +0300 (Ср, 30 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+INT_PTR CALLBACK PositionBoxDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Helper for Status Tree
+static int CountStatusModes(DWORD flags)
+{
+ int res = 0;
+ if (flags & PF2_ONLINE) ++res;
+ if (flags & PF2_INVISIBLE) ++res;
+ if (flags & PF2_SHORTAWAY) ++res;
+ if (flags & PF2_LONGAWAY) ++res;
+ if (flags & PF2_LIGHTDND) ++res;
+ if (flags & PF2_HEAVYDND) ++res;
+ if (flags & PF2_FREECHAT) ++res;
+ if (flags & PF2_OUTTOLUNCH) ++res;
+ if (flags & PF2_ONTHEPHONE) ++res;
+ if (res) ++res; // Offline
+ return res;
+}
+
+int AddStatusMode (OPTTREE_OPTION *options, int pos, LPTSTR prefix, DWORD flag)
+{
+ if (!flag) return pos;
+ options[pos].dwFlag = flag;
+ options[pos].groupId = OPTTREE_CHECK;
+ options[pos].pszOptionName = (LPTSTR)mir_alloc(sizeof(TCHAR)*lstrlen(prefix)+32);
+ options[pos].pszSettingName = mir_tstrdup(prefix);
+ options[pos].iconIndex = 0;
+
+ lstrcpy(options[pos].pszOptionName, prefix);
+ switch (flag)
+ {
+ case PF2_IDLE: lstrcat(options[pos].pszOptionName, _T("/Offline")); break;
+ case PF2_ONLINE: lstrcat(options[pos].pszOptionName, _T("/Online")); break;
+ case PF2_INVISIBLE: lstrcat(options[pos].pszOptionName, _T("/Invisible")); break;
+ case PF2_SHORTAWAY: lstrcat(options[pos].pszOptionName, _T("/Away")); break;
+ case PF2_LONGAWAY: lstrcat(options[pos].pszOptionName, _T("/NA")); break;
+ case PF2_LIGHTDND: lstrcat(options[pos].pszOptionName, _T("/Occupied")); break;
+ case PF2_HEAVYDND: lstrcat(options[pos].pszOptionName, _T("/DND")); break;
+ case PF2_FREECHAT: lstrcat(options[pos].pszOptionName, _T("/Free for chat")); break;
+ case PF2_OUTTOLUNCH:lstrcat(options[pos].pszOptionName, _T("/Out to lunch")); break;
+ case PF2_ONTHEPHONE:lstrcat(options[pos].pszOptionName, _T("/On the phone")); break;
+ }
+ return pos+1;
+}
+
+int AddStatusModes(OPTTREE_OPTION *options, int pos, LPTSTR prefix, DWORD flags)
+{
+ pos = AddStatusMode(options, pos, prefix, PF2_IDLE);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_ONLINE);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_INVISIBLE);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_SHORTAWAY);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_LONGAWAY);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_LIGHTDND);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_HEAVYDND);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_FREECHAT);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_OUTTOLUNCH);
+ pos = AddStatusMode(options, pos, prefix, flags&PF2_ONTHEPHONE);
+ return pos;
+}
+
+
+//Main Dialog Proc
+void LoadOption_General() {
+ //Seconds
+ PopUpOptions.InfiniteDelay = DBGetContactSettingByte(NULL, MODULNAME, "InfiniteDelay", FALSE);
+ PopUpOptions.Seconds = DBGetContactSettingRangedWord(NULL, MODULNAME, "Seconds",
+ SETTING_LIFETIME_DEFAULT, SETTING_LIFETIME_MIN, SETTING_LIFETIME_MAX);
+ PopUpOptions.LeaveHovered = DBGetContactSettingByte(NULL, MODULNAME, "LeaveHovered", TRUE);
+ //Dynamic Resize
+ PopUpOptions.DynamicResize = DBGetContactSettingByte(NULL, MODULNAME, "DynamicResize", FALSE);
+ PopUpOptions.UseMinimumWidth = DBGetContactSettingByte(NULL, MODULNAME, "UseMinimumWidth", TRUE);
+ PopUpOptions.MinimumWidth = DBGetContactSettingWord(NULL, MODULNAME, "MinimumWidth", 160);
+ PopUpOptions.UseMaximumWidth = DBGetContactSettingByte(NULL, MODULNAME, "UseMaximumWidth", TRUE);
+ PopUpOptions.MaximumWidth = DBGetContactSettingWord(NULL, MODULNAME, "MaximumWidth", 300);
+ //Position
+ PopUpOptions.Position = DBGetContactSettingRangedByte(NULL, MODULNAME, "Position",
+ POS_LOWERRIGHT, POS_MINVALUE, POS_MAXVALUE);
+ //Configure popup area
+ PopUpOptions.gapTop = DBGetContactSettingWord(NULL, MODULNAME, "gapTop", 5);
+ PopUpOptions.gapBottom = DBGetContactSettingWord(NULL, MODULNAME, "gapBottom", 5);
+ PopUpOptions.gapLeft = DBGetContactSettingWord(NULL, MODULNAME, "gapLeft", 5);
+ PopUpOptions.gapRight = DBGetContactSettingWord(NULL, MODULNAME, "gapRight", 5);
+ PopUpOptions.spacing = DBGetContactSettingWord(NULL, MODULNAME, "spacing", 5);
+ //Spreading
+ PopUpOptions.Spreading = DBGetContactSettingRangedByte(NULL, MODULNAME, "Spreading",
+ SPREADING_VERTICAL, SPREADING_MINVALUE, SPREADING_MAXVALUE);
+ //miscellaneous
+ PopUpOptions.ReorderPopUps = DBGetContactSettingByte(NULL, MODULNAME, "ReorderPopUps", TRUE);
+ PopUpOptions.ReorderPopUpsWarning = DBGetContactSettingByte(NULL, MODULNAME, "ReorderPopUpsWarning", TRUE);
+ //disable When
+ PopUpOptions.ModuleIsEnabled = DBGetContactSettingByte(NULL, MODULNAME, "ModuleIsEnabled", TRUE);
+ PopUpOptions.DisableWhenFullscreen = DBGetContactSettingByte(NULL, MODULNAME, "DisableWhenFullscreen", TRUE);
+ //new status options (done inside WM_INITDIALOG)
+ //Debug (done inside LoadOptions())
+}
+
+INT_PTR CALLBACK DlgProcPopUpGeneral(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ static bool bDlgInit = false; //some controls send WM_COMMAND before or during WM_INITDIALOG
+
+ static OPTTREE_OPTION *statusOptions = NULL;
+ static int statusOptionsCount = 0;
+ if (statusOptions) {
+ int index;
+ if (OptTree_ProcessMessage(hwnd, msg, wParam, lParam, &index, IDC_STATUSES, statusOptions, statusOptionsCount))
+ return TRUE;
+ }
+
+ switch (msg) {
+ case WM_INITDIALOG: {
+ HWND hCtrl = NULL;
+
+ //Seconds of delay
+ {
+ CheckDlgButton(hwnd, IDC_INFINITEDELAY, PopUpOptions.InfiniteDelay);
+ CheckDlgButton(hwnd, IDC_LEAVEHOVERED, PopUpOptions.LeaveHovered);
+ EnableWindow(GetDlgItem(hwnd, IDC_SECONDS), !PopUpOptions.InfiniteDelay);
+ EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC1), !PopUpOptions.InfiniteDelay);
+ EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC2), !PopUpOptions.InfiniteDelay);
+ EnableWindow(GetDlgItem(hwnd, IDC_LEAVEHOVERED), !PopUpOptions.InfiniteDelay);
+ SetDlgItemInt(hwnd, IDC_SECONDS, PopUpOptions.Seconds, FALSE);
+ SendDlgItemMessage(hwnd, IDC_SECONDS_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_LIFETIME_MAX, SETTING_LIFETIME_MIN));
+ }
+
+ //Dynamic Resize
+ {
+ CheckDlgButton(hwnd, IDC_DYNAMICRESIZE, PopUpOptions.DynamicResize);
+ SetDlgItemText(hwnd, IDC_USEMAXIMUMWIDTH, PopUpOptions.DynamicResize ? _T("Maximum width"): _T("Width"));
+ //Minimum Width
+ CheckDlgButton(hwnd, IDC_USEMINIMUMWIDTH, PopUpOptions.UseMinimumWidth);
+ SendDlgItemMessage(hwnd, IDC_MINIMUMWIDTH_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(
+ SETTING_MAXIMUMWIDTH_MAX,
+ SETTING_MINIMUMWIDTH_MIN) );
+ SetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, PopUpOptions.MinimumWidth, FALSE);
+ //Maximum Width
+ PopUpOptions.UseMaximumWidth = PopUpOptions.DynamicResize ? PopUpOptions.UseMaximumWidth : TRUE;
+ CheckDlgButton(hwnd, IDC_USEMAXIMUMWIDTH, PopUpOptions.UseMaximumWidth);
+ SendDlgItemMessage(hwnd, IDC_MAXIMUMWIDTH_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(
+ SETTING_MAXIMUMWIDTH_MAX,
+ SETTING_MINIMUMWIDTH_MIN) );
+ SetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, PopUpOptions.MaximumWidth, FALSE);
+ //And finally let's enable/disable them.
+ EnableWindow(GetDlgItem(hwnd, IDC_USEMINIMUMWIDTH), PopUpOptions.DynamicResize);
+ EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH), PopUpOptions.DynamicResize && PopUpOptions.UseMinimumWidth);
+ EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH_SPIN), PopUpOptions.DynamicResize && PopUpOptions.UseMinimumWidth);
+ EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH), PopUpOptions.UseMaximumWidth);
+ EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH_SPIN), PopUpOptions.UseMaximumWidth);
+ }
+ //Position combobox.
+ {
+ hCtrl = GetDlgItem(hwnd, IDC_WHERE);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("upper left corner")) ,POS_UPPERLEFT);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("lower left corner")) ,POS_LOWERLEFT);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("lower right corner")) ,POS_LOWERRIGHT);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("upper right corner")) ,POS_UPPERRIGHT);
+ SendDlgItemMessage(hwnd, IDC_WHERE, CB_SETCURSEL, (PopUpOptions.Position) , 0);
+ }
+ //Configure popup area
+ {
+ hCtrl = GetDlgItem(hwnd, IDC_CUSTOMPOS);
+ SendMessage(hCtrl, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(hCtrl, BUTTONADDTOOLTIP, (WPARAM)_T("Popup Area"), BATF_TCHAR);
+ SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_OPT_RESIZE,0));
+ }
+ //Spreading combobox
+ {
+ hCtrl = GetDlgItem(hwnd, IDC_LAYOUT);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("horizontal")) ,SPREADING_HORIZONTAL);
+ ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("vertical")) ,SPREADING_VERTICAL);
+ SendDlgItemMessage(hwnd, IDC_LAYOUT, CB_SETCURSEL, (PopUpOptions.Spreading), 0);
+ }
+ //miscellaneous
+ {
+ CheckDlgButton(hwnd, IDC_REORDERPOPUPS, PopUpOptions.ReorderPopUps);
+ }
+ //Popup enabled
+ {
+ CheckDlgButton(hwnd, IDC_POPUPENABLED, PopUpOptions.ModuleIsEnabled?BST_UNCHECKED:BST_CHECKED);
+ CheckDlgButton(hwnd, IDC_DISABLEINFS, PopUpOptions.DisableWhenFullscreen);
+ EnableWindow(GetDlgItem(hwnd, IDC_DISABLEINFS), PopUpOptions.ModuleIsEnabled);
+ EnableWindow(GetDlgItem(hwnd, IDC_STATUSES), PopUpOptions.ModuleIsEnabled);
+ }
+ //new status options
+ {
+ int protocolCount = 0;
+ int i;
+ PROTOCOLDESCRIPTOR **protocols;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protocolCount, (LPARAM)&protocols);
+ DWORD globalFlags = 0;
+ for (i = 0; i < protocolCount; ++i) {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+ DWORD protoFlags = CallProtoService(protocols[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ globalFlags |= protoFlags;
+ statusOptionsCount += CountStatusModes(protoFlags);
+ }
+ statusOptionsCount += CountStatusModes(globalFlags);
+
+ statusOptions = new OPTTREE_OPTION[statusOptionsCount];
+
+ int pos = 0;
+ pos = AddStatusModes(statusOptions, pos, _T("Global Status"), globalFlags);
+ for (i = 0; i < protocolCount; ++i) {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+ DWORD protoFlags = CallProtoService(protocols[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ if (!CountStatusModes(protoFlags))
+ continue;
+ TCHAR prefix[128];
+ wsprintf(prefix, _T("Protocol Status/%hs"), protocols[i]->szName);
+ pos = AddStatusModes(statusOptions, pos, prefix, protoFlags);
+ }
+
+ int index;
+ OptTree_ProcessMessage(hwnd, msg, wParam, lParam, &index, IDC_STATUSES, statusOptions, statusOptionsCount);
+
+ char prefix[128];
+ LPTSTR pszSettingName = NULL;
+ for (i = 0; i < protocolCount; ++i) {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+ DWORD protoFlags = CallProtoService(protocols[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ if (!CountStatusModes(protoFlags))
+ continue;
+
+ mir_snprintf(prefix, sizeof(prefix), "Protocol Status/%s", protocols[i]->szName);
+ pszSettingName = mir_a2t(prefix);
+ OptTree_SetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount,
+ DBGetContactSettingDword(NULL, MODULNAME, prefix, 0),
+ pszSettingName);
+ mir_free(pszSettingName); pszSettingName = NULL;
+ }
+ OptTree_SetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount,
+ DBGetContactSettingDword(NULL, MODULNAME, "Global Status", 0),
+ _T("Global Status"));
+ }
+ //Debug
+ {
+ #if defined(_DEBUG)
+ CheckDlgButton(hwnd, IDC_DEBUG, PopUpOptions.debug);
+ ShowWindow(GetDlgItem(hwnd, IDC_DEBUG), SW_SHOW);
+ #endif
+ }
+
+ TranslateDialogDefault(hwnd); //do it on end of WM_INITDIALOG
+ bDlgInit = true;
+ }//end WM_INITDIALOG
+ return TRUE;
+ case WM_COMMAND: {
+ UINT idCtrl = LOWORD(wParam);
+ switch (HIWORD(wParam)) {
+ case BN_CLICKED: //Button controls
+ switch(idCtrl) {
+ case IDC_INFINITEDELAY:
+ {
+ PopUpOptions.InfiniteDelay = !PopUpOptions.InfiniteDelay;
+ EnableWindow(GetDlgItem(hwnd, IDC_SECONDS),!PopUpOptions.InfiniteDelay);
+ EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC1), !PopUpOptions.InfiniteDelay);
+ EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC2), !PopUpOptions.InfiniteDelay);
+ EnableWindow(GetDlgItem(hwnd, IDC_LEAVEHOVERED), !PopUpOptions.InfiniteDelay);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_LEAVEHOVERED:
+ {
+ PopUpOptions.LeaveHovered = !PopUpOptions.LeaveHovered;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_DYNAMICRESIZE:
+ {
+ PopUpOptions.DynamicResize=!PopUpOptions.DynamicResize;
+ EnableWindow(GetDlgItem(hwnd, IDC_USEMINIMUMWIDTH), PopUpOptions.DynamicResize);
+ EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH), PopUpOptions.DynamicResize && PopUpOptions.UseMinimumWidth);
+ EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH_SPIN), PopUpOptions.DynamicResize && PopUpOptions.UseMinimumWidth);
+ SetDlgItemText(hwnd, IDC_USEMAXIMUMWIDTH, PopUpOptions.DynamicResize ? TranslateT("Maximum width"): TranslateT("Width"));
+ if(!PopUpOptions.DynamicResize) {
+ PopUpOptions.UseMaximumWidth = TRUE;
+ CheckDlgButton(hwnd, IDC_USEMAXIMUMWIDTH, BST_CHECKED);
+ EnableWindow(GetDlgItem(hwnd, IDC_USEMAXIMUMWIDTH), TRUE);
+ EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH), TRUE);
+ EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH_SPIN), TRUE);
+ }
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_USEMINIMUMWIDTH:
+ {
+ PopUpOptions.UseMinimumWidth= !PopUpOptions.UseMinimumWidth;
+ EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH), PopUpOptions.UseMinimumWidth);
+ EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH_SPIN), PopUpOptions.UseMinimumWidth);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_USEMAXIMUMWIDTH:
+ {
+ PopUpOptions.UseMaximumWidth= Button_GetCheck((HWND)lParam);
+ if(!PopUpOptions.DynamicResize) { //ugly - set always on if DynamicResize = off
+ CheckDlgButton(hwnd, idCtrl, BST_CHECKED);
+ PopUpOptions.UseMaximumWidth = TRUE;
+ }
+ EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH), PopUpOptions.UseMaximumWidth);
+ EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH_SPIN), PopUpOptions.UseMaximumWidth);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_CUSTOMPOS:
+ {
+ RECT rcButton, rcBox;
+ HWND hwndBox = CreateDialog(hInst, MAKEINTRESOURCE(IDD_POSITION), NULL, PositionBoxDlgProc);
+ GetWindowRect((HWND)lParam, &rcButton);
+ GetWindowRect(hwndBox, &rcBox);
+ MoveWindow(hwndBox,
+ rcButton.right-(rcBox.right-rcBox.left) + 15,
+ rcButton.bottom + 3,
+ rcBox.right-rcBox.left,
+ rcBox.bottom-rcBox.top,
+ FALSE);
+#if defined(_UNICODE)
+ SetWindowLongPtr(hwndBox, GWL_EXSTYLE, GetWindowLongPtr(hwndBox, GWL_EXSTYLE)|WS_EX_LAYERED);
+ SetLayeredWindowAttributes(hwndBox, NULL, 0, LWA_ALPHA);
+ ShowWindow(hwndBox, SW_SHOW);
+ for (int i = 0; i <= 255; i += 15) {
+ SetLayeredWindowAttributes(hwndBox, NULL, i, LWA_ALPHA);
+ UpdateWindow(hwndBox);
+ Sleep(1);
+ }
+ SetWindowLongPtr(hwndBox, GWL_EXSTYLE, GetWindowLongPtr(hwndBox, GWL_EXSTYLE)&~WS_EX_LAYERED);
+#else
+ if (MySetLayeredWindowAttributes) {
+ SetWindowLongPtr(hwndBox, GWL_EXSTYLE, GetWindowLongPtr(hwndBox, GWL_EXSTYLE)|WS_EX_LAYERED);
+ MySetLayeredWindowAttributes(hwndBox, NULL, 0, LWA_ALPHA);
+ ShowWindow(hwndBox, SW_SHOW);
+ for (int i = 0; i <= 255; i += 15) {
+ MySetLayeredWindowAttributes(hwndBox, NULL, i, LWA_ALPHA);
+ UpdateWindow(hwndBox);
+ Sleep(1);
+ }
+ SetWindowLongPtr(hwndBox, GWL_EXSTYLE, GetWindowLongPtr(hwndBox, GWL_EXSTYLE)&~WS_EX_LAYERED);
+ }
+#endif
+ ShowWindow(hwndBox, SW_SHOW);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_REORDERPOPUPS:
+ {
+ PopUpOptions.ReorderPopUps = !PopUpOptions.ReorderPopUps;
+ PopUpOptions.ReorderPopUpsWarning = PopUpOptions.ReorderPopUps ?
+ DBGetContactSettingByte(NULL, MODULNAME, "ReorderPopUpsWarning", TRUE) : TRUE;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case IDC_POPUPENABLED:
+ {//PopUpOptions.ModuleIsEnabled is set and store by EnableDisable menu service !!!!!!
+ int chk = IsDlgButtonChecked(hwnd, IDC_POPUPENABLED);
+ if (PopUpOptions.ModuleIsEnabled&&chk || !PopUpOptions.ModuleIsEnabled&&!chk)
+ svcEnableDisableMenuCommand(0,0);
+ EnableWindow(GetDlgItem(hwnd, IDC_STATUSES), PopUpOptions.ModuleIsEnabled);
+ EnableWindow(GetDlgItem(hwnd, IDC_DISABLEINFS), PopUpOptions.ModuleIsEnabled);
+ }
+ break;
+ case IDC_DISABLEINFS:
+ {
+ PopUpOptions.DisableWhenFullscreen = !PopUpOptions.DisableWhenFullscreen;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ #if defined(_DEBUG) //DEBUG
+ case IDC_DEBUG:
+ PopUpOptions.debug = (BYTE)Button_GetCheck((HWND)lParam);
+ //The following line is dangerous, but useful for my debug purposes.
+ //MySetLayeredWindowAttributes = (BOOL)!MySetLayeredWindowAttributes;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ #endif //DEBUG
+ case IDC_PREVIEW:
+ {
+ PopUpPreview();
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case CBN_SELCHANGE: //ComboBox controls
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_WHERE:
+ PopUpOptions.Position = ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_LAYOUT:
+ PopUpOptions.Spreading = ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam));
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ case EN_CHANGE: //Edit controls change
+ if(!bDlgInit) break;
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_SECONDS:
+ {
+ int seconds = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if ( seconds >= SETTING_LIFETIME_MIN &&
+ seconds <= SETTING_LIFETIME_MAX &&
+ seconds != PopUpOptions.Seconds) {
+ PopUpOptions.Seconds = seconds;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case IDC_MINIMUMWIDTH:
+ {
+ int temp = GetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, NULL, FALSE);
+ if ( temp >= SETTING_MINIMUMWIDTH_MIN &&
+ temp <= SETTING_MAXIMUMWIDTH_MAX &&
+ temp != PopUpOptions.MinimumWidth) {
+ PopUpOptions.MinimumWidth = temp;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case IDC_MAXIMUMWIDTH:
+ {
+ int temp = GetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, NULL, FALSE);
+ if ( temp >= SETTING_MINIMUMWIDTH_MIN &&
+ temp <= SETTING_MAXIMUMWIDTH_MAX &&
+ temp != PopUpOptions.MaximumWidth) {
+ PopUpOptions.MaximumWidth = temp;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ break;
+ case EN_KILLFOCUS: //Edit controls lost fokus
+ switch(idCtrl) {
+ //lParam = Handle to the control
+ case IDC_SECONDS:
+ {
+ int seconds = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if (seconds > SETTING_LIFETIME_MAX)
+ PopUpOptions.Seconds = SETTING_LIFETIME_MAX;
+ else if (seconds < SETTING_LIFETIME_MIN)
+ PopUpOptions.Seconds = SETTING_LIFETIME_MIN;
+ if(seconds != PopUpOptions.Seconds) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.Seconds, FALSE);
+ ErrorMSG(SETTING_LIFETIME_MIN, SETTING_LIFETIME_MAX);
+ SetFocus((HWND)lParam);
+ }
+ }
+ break;
+ case IDC_MINIMUMWIDTH:
+ {
+ int temp = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if (temp < SETTING_MINIMUMWIDTH_MIN)
+ PopUpOptions.MinimumWidth = SETTING_MINIMUMWIDTH_MIN;
+ else if(temp > SETTING_MAXIMUMWIDTH_MAX)
+ PopUpOptions.MinimumWidth = SETTING_MAXIMUMWIDTH_MAX;
+ if(temp != PopUpOptions.MinimumWidth) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.MinimumWidth, FALSE);
+ ErrorMSG(SETTING_MINIMUMWIDTH_MIN, SETTING_MAXIMUMWIDTH_MAX);
+ SetFocus((HWND)lParam);
+ break;
+ }
+ if (temp > PopUpOptions.MaximumWidth) {
+ PopUpOptions.MaximumWidth = min(temp, SETTING_MAXIMUMWIDTH_MAX);
+ SetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, PopUpOptions.MaximumWidth, FALSE);
+ }
+ }
+ break;
+ case IDC_MAXIMUMWIDTH:
+ {
+ int temp = GetDlgItemInt(hwnd, idCtrl, NULL, FALSE);
+ if (temp >= SETTING_MAXIMUMWIDTH_MAX)
+ PopUpOptions.MaximumWidth = SETTING_MAXIMUMWIDTH_MAX;
+ else if(temp < SETTING_MINIMUMWIDTH_MIN)
+ PopUpOptions.MaximumWidth = SETTING_MINIMUMWIDTH_MIN;
+ if(temp != PopUpOptions.MaximumWidth) {
+ SetDlgItemInt(hwnd, idCtrl, PopUpOptions.MaximumWidth, FALSE);
+ ErrorMSG(SETTING_MINIMUMWIDTH_MIN, SETTING_MAXIMUMWIDTH_MAX);
+ SetFocus((HWND)lParam);
+ break;
+ }
+ if (temp < PopUpOptions.MinimumWidth) {
+ PopUpOptions.MinimumWidth = max(temp, SETTING_MINIMUMWIDTH_MIN);
+ SetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, PopUpOptions.MinimumWidth, FALSE);
+ }
+ }
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ break;
+ default:
+ break;
+ }// end switch (HIWORD(wParam))
+ }//end WM_COMMAND
+ break;
+ case WM_NOTIFY: {
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0: {
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_RESET:
+ LoadOption_General();
+ return TRUE;
+ case PSN_APPLY: {
+ //Seconds
+ DBWriteContactSettingByte(NULL, MODULNAME, "InfiniteDelay", PopUpOptions.InfiniteDelay);
+ DBWriteContactSettingWord(NULL, MODULNAME, "Seconds", (WORD)PopUpOptions.Seconds);
+ DBWriteContactSettingByte(NULL, MODULNAME, "LeaveHovered", PopUpOptions.LeaveHovered);
+ //Dynamic Resize
+ DBWriteContactSettingByte(NULL, MODULNAME, "DynamicResize", PopUpOptions.DynamicResize);
+ DBWriteContactSettingByte(NULL, MODULNAME, "UseMinimumWidth", PopUpOptions.UseMinimumWidth);
+ DBWriteContactSettingWord(NULL, MODULNAME, "MinimumWidth", PopUpOptions.MinimumWidth);
+ DBWriteContactSettingByte(NULL, MODULNAME, "UseMaximumWidth", PopUpOptions.UseMaximumWidth);
+ DBWriteContactSettingWord(NULL, MODULNAME, "MaximumWidth", PopUpOptions.MaximumWidth);
+ //Position
+ DBWriteContactSettingByte(NULL, MODULNAME, "Position", (BYTE)PopUpOptions.Position);
+ //Configure popup area
+ DBWriteContactSettingWord(NULL, MODULNAME, "gapTop", (WORD)PopUpOptions.gapTop);
+ DBWriteContactSettingWord(NULL, MODULNAME, "gapBottom", (WORD)PopUpOptions.gapBottom);
+ DBWriteContactSettingWord(NULL, MODULNAME, "gapLeft", (WORD)PopUpOptions.gapLeft);
+ DBWriteContactSettingWord(NULL, MODULNAME, "gapRight", (WORD)PopUpOptions.gapRight);
+ DBWriteContactSettingWord(NULL, MODULNAME, "spacing", (WORD)PopUpOptions.spacing);
+ //Spreading
+ DBWriteContactSettingByte(NULL, MODULNAME, "Spreading", (BYTE)PopUpOptions.Spreading);
+ //miscellaneous
+ //DBWriteContactSettingByte(NULL, MODULNAME, "ReorderPopUps", PopUpOptions.ReorderPopUps);
+ Check_ReorderPopUps(hwnd); //this save also PopUpOptions.ReorderPopUps
+ //disable When
+ DBWriteContactSettingByte(NULL, MODULNAME, "DisableWhenFullscreen", PopUpOptions.DisableWhenFullscreen);
+ //new status options
+ {
+ int protocolCount;
+ PROTOCOLDESCRIPTOR **protocols;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protocolCount, (LPARAM)&protocols);
+
+ char prefix[128];
+ LPTSTR pszSettingName = NULL;
+ for (int i = 0; i < protocolCount; ++i)
+ {
+ if (protocols[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ mir_snprintf(prefix, sizeof(prefix), "Protocol Status/%s", protocols[i]->szName);
+ pszSettingName = mir_a2t(prefix);
+ DBWriteContactSettingDword(NULL, MODULNAME, prefix,
+ OptTree_GetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount, pszSettingName));
+ mir_free(pszSettingName); pszSettingName = NULL;
+ }
+ DBWriteContactSettingDword(NULL, MODULNAME, "Global Status",
+ OptTree_GetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount, _T("Global Status")));
+ }
+ //Debug
+ #if defined(_DEBUG)
+ DBWriteContactSettingByte(NULL, MODULNAME, "debug", PopUpOptions.debug);
+ #endif
+
+ }//end PSN_APPLY:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ break;
+ case IDC_MINIMUMWIDTH_SPIN:
+ {
+ LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
+ int temp = lpnmud->iPos + lpnmud->iDelta;
+ if (temp > PopUpOptions.MaximumWidth) {
+ PopUpOptions.MaximumWidth = min(temp, SETTING_MAXIMUMWIDTH_MAX);
+ SetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, PopUpOptions.MaximumWidth, FALSE);
+ }
+ }
+ break;
+ case IDC_MAXIMUMWIDTH_SPIN:
+ {
+ LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
+ int temp = lpnmud->iPos + lpnmud->iDelta;
+ if (temp < PopUpOptions.MinimumWidth) {
+ PopUpOptions.MinimumWidth = max(temp, SETTING_MINIMUMWIDTH_MIN);
+ SetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, PopUpOptions.MinimumWidth, FALSE);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }//end WM_NOTIFY
+ break;
+ case WM_DESTROY: {
+ if (statusOptions) {
+ for (int i = 0; i < statusOptionsCount; ++i) {
+ mir_free(statusOptions[i].pszOptionName);
+ mir_free(statusOptions[i].pszSettingName);
+ }
+ delete [] statusOptions;
+ statusOptions = NULL;
+ statusOptionsCount = 0;
+ bDlgInit = false;
+ }
+ }//end WM_DESTROY
+ break;
+ default:
+ return FALSE;
+ }//end switch (msg)
+ return FALSE;
+}
+
+void ErrorMSG(int minValue, int maxValue) {
+ TCHAR str[128];
+ wsprintf(str, TranslateT("You cannot specify a value lower than %d and higher than %d."), minValue, maxValue);
+ MSGERROR(str);
+}
+
+void Check_ReorderPopUps(HWND hwnd) {
+ if (!PopUpOptions.ReorderPopUps && PopUpOptions.ReorderPopUpsWarning)
+ {
+ int res = MessageBox(hwnd,
+ TranslateTS(
+ _T("'Reorder Popups' option is currently diabled.\r\n")
+ _T("This may cause misaligned popups when used with\r\n")
+ _T("avatars and text replacement (mainly NewStatusNotify).\r\n")
+ _T("\r\n")
+ _T("Do you want to enable popup reordering now?\r\n")
+ ),
+ TranslateT("Popup Plus Warning"), MB_ICONEXCLAMATION|MB_YESNOCANCEL);
+
+ switch (res)
+ {
+ case IDYES:
+ PopUpOptions.ReorderPopUps = TRUE;
+ //Reset warning for next option change !!!
+ PopUpOptions.ReorderPopUpsWarning = TRUE;
+ break;
+ case IDNO:
+ PopUpOptions.ReorderPopUps = FALSE;
+ PopUpOptions.ReorderPopUpsWarning = FALSE;
+ break;
+ default:
+ return;
+ }
+ }
+ DBWriteContactSettingByte(NULL, MODULNAME, "ReorderPopUps", PopUpOptions.ReorderPopUps);
+ DBWriteContactSettingByte(NULL, MODULNAME, "ReorderPopUpsWarning", PopUpOptions.ReorderPopUpsWarning);
+ if(hwnd) CheckDlgButton(hwnd, IDC_REORDERPOPUPS, PopUpOptions.ReorderPopUps);
+}
+
+void ThemeDialogBackground(HWND hwnd) {
+ if (IsWinVerXPPlus()) {
+ static HMODULE hThemeAPI = NULL;
+ if (!hThemeAPI) hThemeAPI = GetModuleHandleA("uxtheme");
+ if (hThemeAPI) {
+ HRESULT (STDAPICALLTYPE *MyEnableThemeDialogTexture)(HWND,DWORD) = (HRESULT (STDAPICALLTYPE*)(HWND,DWORD))GetProcAddress(hThemeAPI,"EnableThemeDialogTexture");
+ if (MyEnableThemeDialogTexture)
+ MyEnableThemeDialogTexture(hwnd,0x00000002|0x00000004); //0x00000002|0x00000004=ETDT_ENABLETAB
+ }
+ }
+}
+
+INT_PTR CALLBACK PositionBoxDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HFONT hFontTitle = 0;
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ ThemeDialogBackground(hwndDlg);
+
+ LOGFONT lf;
+ GetObject((HFONT)SendMessage(GetDlgItem(hwndDlg, IDC_TITLE), WM_GETFONT, 0, 0), sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ lf.lfHeight *= 1.2;
+ hFontTitle = CreateFontIndirect(&lf);
+ SendMessage(GetDlgItem(hwndDlg, IDC_TITLE), WM_SETFONT, (WPARAM)hFontTitle, TRUE);
+
+ SendMessage(GetDlgItem(hwndDlg, IDOK), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hwndDlg, IDOK), BUTTONADDTOOLTIP, (WPARAM)_T("OK"), BATF_TCHAR);
+ SendMessage(GetDlgItem(hwndDlg, IDOK), BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_OPT_OK,0));
+
+ SendMessage(GetDlgItem(hwndDlg, IDCANCEL), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hwndDlg, IDCANCEL), BUTTONADDTOOLTIP, (WPARAM)_T("Cancel"), BATF_TCHAR);
+ SendMessage(GetDlgItem(hwndDlg, IDCANCEL), BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_OPT_CANCEL,0));
+
+ SetDlgItemInt(hwndDlg, IDC_TXT_TOP, PopUpOptions.gapTop, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_TXT_BOTTOM, PopUpOptions.gapBottom, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_TXT_LEFT, PopUpOptions.gapLeft, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_TXT_RIGHT, PopUpOptions.gapRight, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_TXT_SPACING, PopUpOptions.spacing, FALSE);
+
+ TranslateDialogDefault(hwndDlg);
+ break;
+ case WM_COMMAND:
+ if ((LOWORD(wParam)) == IDOK)
+ {
+ PopUpOptions.gapTop = GetDlgItemInt(hwndDlg, IDC_TXT_TOP, NULL, FALSE);
+ PopUpOptions.gapBottom = GetDlgItemInt(hwndDlg, IDC_TXT_BOTTOM, NULL, FALSE);
+ PopUpOptions.gapLeft = GetDlgItemInt(hwndDlg, IDC_TXT_LEFT, NULL, FALSE);
+ PopUpOptions.gapRight = GetDlgItemInt(hwndDlg, IDC_TXT_RIGHT, NULL, FALSE);
+ PopUpOptions.spacing = GetDlgItemInt(hwndDlg, IDC_TXT_SPACING, NULL, FALSE);
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ } else
+ if ((LOWORD(wParam)) == IDCANCEL)
+ {
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ }
+ break;
+ case WM_ACTIVATE:
+ if (wParam == WA_INACTIVE)
+ {
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ DeleteObject(hFontTitle);
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/Popup/src/opt_gen.h b/plugins/Popup/src/opt_gen.h
new file mode 100644
index 0000000000..1f61f6b9a9
--- /dev/null
+++ b/plugins/Popup/src/opt_gen.h
@@ -0,0 +1,43 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_gen.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __opt_gen_h__
+#define __opt_gen_h__
+
+void LoadOption_General();
+void Check_ReorderPopUps(HWND hwnd = 0);
+INT_PTR CALLBACK DlgProcPopUpGeneral(HWND, UINT, WPARAM, LPARAM);
+
+void ErrorMSG(int minValue, int maxValue);
+
+
+#endif // __opt_gen_h__
diff --git a/plugins/Popup/src/opt_skins.cpp b/plugins/Popup/src/opt_skins.cpp
new file mode 100644
index 0000000000..d91efe5afd
--- /dev/null
+++ b/plugins/Popup/src/opt_skins.cpp
@@ -0,0 +1,695 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_skins.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static volatile bool gPreviewOk = false;
+static PopupWnd2 *wndPreview = NULL;
+
+INT_PTR CALLBACK BoxPreviewWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void RegisterOptPrevBox()
+{
+ DWORD err;
+ WNDCLASSEX wcl;
+ wcl.cbSize = sizeof(wcl);
+ wcl.lpfnWndProc = (WNDPROC)BoxPreviewWndProc;
+ wcl.style = IsWinVerXPPlus() ? CS_DROPSHADOW : 0;
+ wcl.cbClsExtra = 0;
+ wcl.cbWndExtra = 0;
+ wcl.hInstance = hInst;
+ wcl.hIcon = NULL;
+ wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcl.hbrBackground = NULL; //(HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ wcl.lpszMenuName = NULL;
+ wcl.lpszClassName = _T(BOXPREVIEW_WNDCLASS);
+ wcl.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
+ g_wndClass.cPopupPreviewBoxWndclass = RegisterClassEx(&wcl);
+ err = GetLastError();
+ if (!g_wndClass.cPopupPreviewBoxWndclass) {
+ TCHAR msg[1024];
+ wsprintf(msg, TranslateT("Failed to register %s class."),wcl.lpszClassName);
+ MSGERROR(msg);
+ }
+
+ // register custom class for dialog box with drop-shadow attribute
+ // "#32770" stays for class name of default system dialog box
+ GetClassInfoEx(hInst, _T("#32770"), &wcl);
+ wcl.hInstance = hInst;
+ wcl.lpszClassName = _T("PopupPlusDlgBox");
+ wcl.style |= IsWinVerXPPlus() ? CS_DROPSHADOW : 0;
+ g_wndClass.cPopupPlusDlgBox = RegisterClassEx(&wcl);
+ err = GetLastError();
+ if (!g_wndClass.cPopupPlusDlgBox) {
+ TCHAR msg[1024];
+ wsprintf(msg, TranslateT("Failed to register %s class."),wcl.lpszClassName);
+ MSGERROR(msg);
+ }
+}
+
+static void updatePreviewImage(HWND hwndBox)
+{
+ gPreviewOk = false;
+
+ POPUPDATA2 ppd;
+ ZeroMemory(&ppd, sizeof(ppd));
+ ppd.cbSize = sizeof(ppd);
+ ppd.flags = PU2_TCHAR;
+ ppd.lchIcon = LoadSkinnedIcon(SKINICON_STATUS_ONLINE);
+ ppd.lptzTitle = TranslateT("Skin preview");
+ ppd.lptzText = TranslateT("Just take a look at this skin... ;)");
+
+ POPUPOPTIONS customOptions = PopUpOptions;
+ customOptions.DynamicResize = FALSE;
+ customOptions.MinimumWidth = customOptions.MaximumWidth = 250;
+
+ if (wndPreview) delete wndPreview;
+ wndPreview = new PopupWnd2(&ppd, &customOptions, true);
+ wndPreview->buildMText();
+ wndPreview->update();
+ gPreviewOk = true;
+
+ InvalidateRect(hwndBox, NULL, TRUE);
+}
+
+static void DrawPreview(HWND hwnd, HDC hdc)
+{
+ RECT rc;
+ HBRUSH hbr;
+
+ BITMAPINFO bi;
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = 8;
+ bi.bmiHeader.biHeight = -8;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ HBITMAP hBmpBrush = (HBITMAP)CreateDIBSection(0, &bi, DIB_RGB_COLORS, 0, 0, 0);
+ HDC dcBmp = CreateCompatibleDC(0);
+ HBITMAP hBmpSave = (HBITMAP)SelectObject(dcBmp, hBmpBrush);
+ hbr = CreateSolidBrush(RGB(0xcc, 0xcc, 0xcc));
+ SetRect(&rc, 0, 0, 8, 8);
+ FillRect(dcBmp, &rc, hbr);
+ DeleteObject(hbr);
+ hbr = CreateSolidBrush(RGB(0xff, 0xff, 0xff));
+ SetRect(&rc, 4, 0, 8, 4);
+ FillRect(dcBmp, &rc, hbr);
+ SetRect(&rc, 0, 4, 4, 8);
+ FillRect(dcBmp, &rc, hbr);
+ DeleteObject(hbr);
+ SelectObject(dcBmp, hBmpSave);
+ DeleteDC(dcBmp);
+
+ GetClientRect(hwnd, &rc);
+ hbr = CreatePatternBrush(hBmpBrush);
+ SetBrushOrgEx(hdc, 1, 1, 0);
+ FillRect(hdc, &rc, hbr);
+ DeleteObject(hbr);
+ DeleteObject(hBmpBrush);
+
+ if (gPreviewOk)
+ {
+ int width = min(rc.right, wndPreview->getContent()->getWidth());
+ int height = min(rc.bottom, wndPreview->getContent()->getHeight());
+ int left = (rc.right - width) / 2;
+ int top = (rc.bottom - height) / 2;
+
+#if defined(_UNICODE)
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdc, left, top, width, height,
+ wndPreview->getContent()->getDC(),
+ 0, 0, width, height, bf);
+#else
+ if (MyAlphaBlend) {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ MyAlphaBlend(hdc, left, top, width, height,
+ wndPreview->getContent()->getDC(),
+ 0, 0, width, height, bf);
+ }
+ else {
+ BitBlt(hdc,
+ left, top, left+width, top+height,
+ wndPreview->getContent()->getDC(),
+ 0, 0, SRCCOPY);
+ }
+#endif
+ }
+
+ FrameRect(hdc, &rc, GetStockBrush(LTGRAY_BRUSH));
+}
+
+static WNDPROC WndProcPreviewBoxSave;
+LRESULT CALLBACK WndProcPreviewBox(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (!wndPreview)
+ return CallWindowProc(WndProcPreviewBoxSave, hwnd, msg, wParam, lParam);
+
+ switch (msg)
+ {
+ case WM_PAINT:
+ {
+ if (GetUpdateRect(hwnd, 0, FALSE))
+ {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwnd, &ps);
+ DrawPreview(hwnd, hdc);
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ }
+
+ case WM_PRINT:
+ case WM_PRINTCLIENT:
+ {
+ HDC hdc = (HDC)wParam;
+ DrawPreview(hwnd, hdc);
+ return 0;
+ }
+ }
+ return CallWindowProc(WndProcPreviewBoxSave, hwnd, msg, wParam, lParam);
+}
+
+int SkinOptionList_AddSkin(OPTTREE_OPTION* &options, int *OptionsCount, int pos, DWORD *dwGlobalOptions) {
+ const PopupSkin *skin = 0;
+ LPTSTR pszName = NULL;
+ if (skin = skins.getSkin(PopUpOptions.SkinPack)) {
+ for (int i = 1; i <= 10; i++) {
+ if(!skin->getFlagName(i))
+ continue;
+ *OptionsCount += 1;
+ options = (OPTTREE_OPTION*)mir_realloc(options,sizeof(OPTTREE_OPTION)*(*OptionsCount));
+ options[pos].dwFlag = (DWORD)(1 << (i-1));
+ options[pos].groupId = OPTTREE_CHECK;
+ options[pos].iconIndex = 0;
+ options[pos].pszSettingName = mir_tstrdup(_T("Skin options"));
+ options[pos].pszOptionName = (LPTSTR)mir_alloc(sizeof(TCHAR)*(
+ lstrlen(options[pos].pszSettingName)+
+ lstrlenA(skin->getFlagName(i)) +10 ));
+ wsprintf(options[pos].pszOptionName,_T("%s/%hs"), options[pos].pszSettingName, skin->getFlagName(i));
+ options[pos].bState = skin->getFlag(i) ? TRUE : FALSE;
+ options[pos].Data = i; //skin flag index
+ *dwGlobalOptions |= skin->getFlag(i) ? (1 << (i-1)) : 0;
+ pos++;
+ }
+ }
+ return pos;
+}
+
+int SkinOptionList_AddMain(OPTTREE_OPTION* &options, int *OptionsCount, int pos, DWORD *dwGlobalOptions) {
+ BOOL bCheck;
+ LPTSTR mainOption [] = {
+ LPGENT("Show clock"),
+ LPGENT("Drop shadow effect (Windows XP+)"),
+ LPGENT("Drop shadow effect (Windows XP+)/non rectangular"),
+ LPGENT("Enable Aero Glass (Vista+)"),
+ LPGENT("Use Windows colours"),
+ LPGENT("Use advanced text render")};
+ for (int i = 0; i < SIZEOF(mainOption); i++) {
+ bCheck = 0;
+ switch (i) {
+ case 0:
+ *dwGlobalOptions |= PopUpOptions.DisplayTime ? (1 << i) : 0;
+ bCheck = PopUpOptions.DisplayTime;
+ break;
+ case 1:
+ if(!IsWinVerXPPlus()) continue;
+ *dwGlobalOptions |= PopUpOptions.DropShadow ? (1 << i) : 0;
+ bCheck = PopUpOptions.DropShadow;
+ break;
+ case 2:
+ if(!IsWinVerXPPlus()) continue;
+ *dwGlobalOptions |= PopUpOptions.EnableFreeformShadows ? (1 << i) : 0;
+ bCheck = PopUpOptions.EnableFreeformShadows;
+ break;
+ case 3:
+ if(!MyDwmEnableBlurBehindWindow) continue;
+ *dwGlobalOptions |= PopUpOptions.EnableAeroGlass ? (1 << i) : 0;
+ bCheck = PopUpOptions.EnableAeroGlass;
+ break;
+ case 4:
+ *dwGlobalOptions |= PopUpOptions.UseWinColors ? (1 << i) : 0;
+ bCheck = PopUpOptions.UseWinColors;
+ break;
+ case 5:
+ if(!(htuText&&htuTitle)) continue;
+ *dwGlobalOptions |= PopUpOptions.UseMText ? (1 << i) : 0;
+ bCheck = PopUpOptions.UseMText;
+ break;
+ default:
+ break;
+ }
+ *OptionsCount += 1;
+ options = (OPTTREE_OPTION*)mir_realloc(options,sizeof(OPTTREE_OPTION)*(*OptionsCount));
+ options[pos].dwFlag = (1 << i);
+ options[pos].groupId = OPTTREE_CHECK;
+ options[pos].iconIndex = 0;
+ options[pos].pszSettingName = mir_tstrdup(_T("Global settings"));
+ options[pos].pszOptionName = (LPTSTR)mir_alloc(sizeof(TCHAR)*(
+ lstrlen(options[pos].pszSettingName)+
+ lstrlen(mainOption[i]) + 10));
+ wsprintf(options[pos].pszOptionName,_T("%s/%s"), options[pos].pszSettingName, mainOption[i]);
+ options[pos].bState = bCheck;
+ pos++;
+ }
+ return pos;
+}
+
+bool SkinOptionList_Update (OPTTREE_OPTION* &options, int *OptionsCount, HWND hwndDlg) {
+ if (options) {
+ int index = -1;
+ OptTree_ProcessMessage(hwndDlg, WM_DESTROY, 0, 0, &index, IDC_SKIN_LIST_OPT, options, *OptionsCount);
+ for (int i = 0; i < *OptionsCount; ++i) {
+ mir_free(options[i].pszOptionName);
+ mir_free(options[i].pszSettingName);
+ }
+ mir_free(options);
+ options = NULL;
+ *OptionsCount = 0;
+ }
+ int pos = 0;
+ //add "Global options"
+ DWORD dwGlobalOptions = 0;
+ pos = SkinOptionList_AddMain(options, OptionsCount, pos, &dwGlobalOptions);
+ //add "Skin options"
+ DWORD dwSkinOptions = 0;
+ pos = SkinOptionList_AddSkin(options, OptionsCount, pos, &dwSkinOptions);
+ //generate treeview
+ int index = -1;
+ OptTree_ProcessMessage(hwndDlg, WM_INITDIALOG, 0, 0, &index, IDC_SKIN_LIST_OPT, options, *OptionsCount);
+
+ //check "Skin options" state
+ char prefix[128];
+ mir_snprintf(prefix, sizeof(prefix),"skin."TCHAR_STR_PARAM, PopUpOptions.SkinPack);
+ OptTree_SetOptions(hwndDlg, IDC_SKIN_LIST_OPT, options, *OptionsCount,
+ DBGetContactSettingDword(NULL, MODULNAME, prefix, dwSkinOptions), _T("Skin options"));
+
+ //check "Global Settings"
+ OptTree_SetOptions(hwndDlg, IDC_SKIN_LIST_OPT, options, *OptionsCount,
+ dwGlobalOptions, _T("Global settings"));
+
+ return true;
+}
+
+void LoadOption_Skins() {
+ //skin pack
+ PopUpOptions.SkinPack = (LPTSTR)DBGetContactSettingStringX(NULL,MODULNAME, "SkinPack", "* Popup Classic",DBVT_TCHAR);
+ //more Skin options
+ PopUpOptions.DisplayTime = DBGetContactSettingByte(NULL,MODULNAME, "DisplayTime", TRUE);
+ PopUpOptions.DropShadow = DBGetContactSettingByte(NULL,MODULNAME, "DropShadow", TRUE);
+ PopUpOptions.EnableFreeformShadows = DBGetContactSettingByte(NULL,MODULNAME, "EnableShadowRegion", 1);
+ PopUpOptions.EnableAeroGlass = DBGetContactSettingByte(NULL,MODULNAME, "EnableAeroGlass", 1);
+ PopUpOptions.UseWinColors = DBGetContactSettingByte(NULL,MODULNAME, "UseWinColors", FALSE);
+ PopUpOptions.UseMText = DBGetContactSettingByte(NULL,MODULNAME, "UseMText", TRUE);
+}
+
+INT_PTR CALLBACK DlgProcPopSkinsOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static bool bDlgInit = false; //some controls send WM_COMMAND before or during WM_INITDIALOG
+ static HANDLE hhkFontsReload = 0;
+ static OPTTREE_OPTION *skinOptions = NULL;
+ static int skinOptionsCount = 0;
+
+ if (skinOptions) {
+ int index = -1;
+ OptTree_ProcessMessage(hwndDlg, msg, wParam, lParam, &index, IDC_SKIN_LIST_OPT, skinOptions, skinOptionsCount);
+ if (index != -1) {
+ if(lstrcmp(skinOptions[index].pszSettingName, _T("Skin options")) == 0) {
+ const PopupSkin *skin = 0;
+ if (skin = skins.getSkin(PopUpOptions.SkinPack)) {
+ skin->setFlag(skinOptions[index].Data, skinOptions[index].bState ? true : false);
+ }
+ }
+ else if (lstrcmp(skinOptions[index].pszSettingName, _T("Global settings")) == 0) {
+ switch (skinOptions[index].dwFlag) {
+ case (1 << 0):
+ PopUpOptions.DisplayTime = skinOptions[index].bState;
+ break;
+ case (1 << 1):
+ PopUpOptions.DropShadow = skinOptions[index].bState;
+ break;
+ case (1 << 2):
+ PopUpOptions.EnableFreeformShadows = skinOptions[index].bState;
+ break;
+ case (1 << 3):
+ PopUpOptions.EnableAeroGlass = skinOptions[index].bState;
+ break;
+ case (1 << 4):
+ PopUpOptions.UseWinColors = skinOptions[index].bState;
+ break;
+ case (1 << 5):
+ PopUpOptions.UseMText = skinOptions[index].bState;
+ break;
+ default:
+ break;
+ }
+ }
+ updatePreviewImage(GetDlgItem(hwndDlg, IDC_PREVIEWBOX));
+ return FALSE;
+ }
+ }
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ HWND hCtrl = NULL;
+ DWORD dwIndex = 0;
+
+ //Skin List
+ hCtrl = GetDlgItem(hwndDlg, IDC_SKINLIST);
+ ListBox_ResetContent(hCtrl);
+ LPTSTR Temp = NULL;
+ for (const Skins::SKINLIST *sl = skins.getSkinList(); sl; sl = sl->next)
+ {
+ dwIndex = ListBox_AddString(hCtrl, sl->name);
+ ListBox_SetItemData(hCtrl, dwIndex, sl->name);
+ }
+ ListBox_SetCurSel(hCtrl, ListBox_FindString(hCtrl, 0, PopUpOptions.SkinPack));
+
+ //Skin List reload button
+ SendMessage(GetDlgItem(hwndDlg, IDC_BTN_RELOAD), BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_BTN_RELOAD), BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_OPT_RELOAD,0));
+ SendMessage(GetDlgItem(hwndDlg, IDC_BTN_RELOAD), BUTTONADDTOOLTIP, (WPARAM)Translate("Refresh List"), 0);
+
+ //Skin Option List
+ SkinOptionList_Update (skinOptions, &skinOptionsCount, hwndDlg);
+
+ //PreviewBox
+ WndProcPreviewBoxSave = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_PREVIEWBOX), GWLP_WNDPROC, (LONG_PTR)WndProcPreviewBox);
+ updatePreviewImage(GetDlgItem(hwndDlg, IDC_PREVIEWBOX));
+
+ //hooks
+ hhkFontsReload = HookEventMessage(ME_FONT_RELOAD, hwndDlg, WM_USER);
+
+ TranslateDialogDefault(hwndDlg);
+ bDlgInit = true;
+ }
+ return TRUE;
+
+ case WM_USER:
+ {
+ updatePreviewImage(GetDlgItem(hwndDlg, IDC_PREVIEWBOX));
+ }
+ return TRUE;
+
+ case WM_COMMAND: {
+ HWND hCtrl = NULL;
+ UINT idCtrl = LOWORD(wParam);
+ switch (HIWORD(wParam)) {
+ case BN_KILLFOCUS: //Button controls
+ case BN_SETFOCUS: //Button controls
+ return TRUE;
+ break;
+ case BN_CLICKED: //Button controls
+ switch(idCtrl)
+ {
+ case IDC_PREVIEW:
+ {
+ PopUpPreview();
+ }
+ break;
+ case IDC_BTN_RELOAD:
+ {
+ LPTSTR Temp = NULL;
+ DWORD dwIndex = 0;
+ TCHAR szNewSkin[128];
+ LPTSTR pszOldSkin = mir_tstrdup(PopUpOptions.SkinPack);
+ skins.load(_T(""));
+ hCtrl = GetDlgItem(hwndDlg, IDC_SKINLIST);
+ ListBox_ResetContent(hCtrl);
+ for (const Skins::SKINLIST *sl = skins.getSkinList(); sl; sl = sl->next)
+ {
+ dwIndex = ListBox_AddString(hCtrl, sl->name);
+ ListBox_SetItemData(hCtrl, dwIndex, sl->name);
+ }
+ ListBox_SetCurSel(hCtrl, ListBox_FindString(hCtrl, 0, PopUpOptions.SkinPack));
+ //make shure we have select skin (ListBox_SetCurSel may be fail)
+ ListBox_GetText(hCtrl, ListBox_GetCurSel(hCtrl), &szNewSkin);
+ if(lstrcmp(pszOldSkin, szNewSkin) != 0) {
+ mir_free(PopUpOptions.SkinPack);
+ PopUpOptions.SkinPack = mir_tstrdup(szNewSkin);
+ }
+ mir_free(pszOldSkin);
+
+ const PopupSkin *skin = 0;
+ if (skin = skins.getSkin(PopUpOptions.SkinPack)) {
+ //update Skin Option List from reload SkinPack
+ bDlgInit = false;
+ bDlgInit = SkinOptionList_Update (skinOptions, &skinOptionsCount, hwndDlg);
+ }
+
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }//end IDC_BTN_RELOAD:
+ break;
+ case IDC_GETSKINS:
+ CallService(MS_UTILS_OPENURL,0,(LPARAM)"http://addons.miranda-im.org/index.php?action=display&id=72");
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ updatePreviewImage(GetDlgItem(hwndDlg, IDC_PREVIEWBOX));
+ break;
+ case CBN_SELCHANGE: //combo box controls
+ switch(idCtrl) {
+ case IDC_SKINLIST: {
+ //Skin list change
+ mir_free(PopUpOptions.SkinPack);
+ PopUpOptions.SkinPack = mir_tstrdup((TCHAR *)SendDlgItemMessage(
+ hwndDlg,
+ IDC_SKINLIST,
+ LB_GETITEMDATA,
+ (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SKINLIST, LB_GETCURSEL,(WPARAM)0,(LPARAM)0),
+ (LPARAM)0) );
+ const PopupSkin *skin = 0;
+ if (skin = skins.getSkin(PopUpOptions.SkinPack)) {
+ mir_free(PopUpOptions.SkinPack);
+ PopUpOptions.SkinPack = mir_tstrdup(skin->getName());
+
+ //update Skin Option List
+ bDlgInit = false;
+ bDlgInit = SkinOptionList_Update (skinOptions, &skinOptionsCount, hwndDlg);
+ }
+ updatePreviewImage(GetDlgItem(hwndDlg, IDC_PREVIEWBOX));
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ default:
+ break;
+ }//end switch(idCtrl)
+ break;
+ default:
+ break;
+ }//end switch (HIWORD(wParam))
+ break;
+ }// end WM_COMMAND
+ return FALSE;
+
+ case WM_NOTIFY: {
+ if(!bDlgInit) return FALSE;
+ switch (((LPNMHDR)lParam)->idFrom) {
+ case 0: {
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_RESET:
+ LoadOption_Skins();
+ return TRUE;
+ case PSN_APPLY:
+ { //skin pack
+ DBWriteContactSettingTString(NULL, MODULNAME, "SkinPack", PopUpOptions.SkinPack);
+ //skin options
+ const PopupSkin *skin = 0;
+ if (skin = skins.getSkin(PopUpOptions.SkinPack))
+ skin->saveOpts();
+ skins.freeAllButActive();
+ //more Skin options
+ DBWriteContactSettingByte(NULL, MODULNAME, "DisplayTime", PopUpOptions.DisplayTime);
+ DBWriteContactSettingByte(NULL, MODULNAME, "DropShadow", PopUpOptions.DropShadow);
+ DBWriteContactSettingByte(NULL, MODULNAME, "EnableShadowRegion", PopUpOptions.EnableFreeformShadows);
+ DBWriteContactSettingByte(NULL, MODULNAME, "EnableAeroGlass", PopUpOptions.EnableAeroGlass);
+ DBWriteContactSettingByte(NULL, MODULNAME, "UseMText", PopUpOptions.UseMText);
+ }//end PSN_APPLY:
+ return TRUE;
+ default:
+ break;
+ }//switch (((LPNMHDR)lParam)->code)
+ }// end case 0:
+ break;
+ default:
+ break;
+ }//end switch (((LPNMHDR)lParam)->idFrom)
+ }//end WM_NOTIFY:
+ return FALSE;
+
+ case WM_DESTROY:
+ {
+ if (wndPreview) {
+ delete wndPreview;
+ wndPreview = NULL;
+ gPreviewOk = false;
+ }
+ if (hhkFontsReload) UnhookEvent(hhkFontsReload);
+ if (skinOptions) {
+ for (int i = 0; i < skinOptionsCount; ++i) {
+ mir_free(skinOptions[i].pszOptionName);
+ mir_free(skinOptions[i].pszSettingName);
+ }
+ mir_free(skinOptions);
+ skinOptions = NULL;
+ skinOptionsCount = 0;
+ }
+ }
+ return TRUE;
+
+ default:
+ break;
+ }//end switch (msg)
+ return FALSE;
+}
+
+static void BoxPreview_OnPaint(HWND hwnd, HDC mydc, int mode)
+{
+ switch (mode)
+ {
+ case 0:
+ { // Avatar
+ HDC hdcAvatar = CreateCompatibleDC(mydc);
+ HBITMAP hbmSave = (HBITMAP)SelectObject(hdcAvatar, hbmNoAvatar);
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ BITMAP bmp;
+ GetObject(hbmNoAvatar, sizeof(bmp), &bmp);
+ StretchBlt(mydc, 0, 0, rc.right, rc.bottom, hdcAvatar, 0, 0, abs(bmp.bmWidth), abs(bmp.bmHeight), SRCCOPY);
+ SelectObject(hdcAvatar, hbmSave);
+ DeleteDC(hdcAvatar);
+ HRGN rgn = CreateRoundRectRgn(0, 0, rc.right, rc.bottom, 2 * PopUpOptions.avatarRadius, 2 * PopUpOptions.avatarRadius);
+ FrameRgn(mydc, rgn, (HBRUSH)GetStockObject(BLACK_BRUSH), 1, 1);
+ DeleteObject(rgn);
+ break;
+ }
+ case 1:
+ { // Opacity
+ RECT rc;
+ HBRUSH hbr = CreateSolidBrush(fonts.clBack);
+ HFONT hfnt = (HFONT)SelectObject(mydc, fonts.title);
+ GetClientRect(hwnd, &rc);
+ FillRect(mydc, &rc, hbr);
+ DrawIconEx(mydc, 10, (rc.bottom-rc.top-16)/2, IcoLib_GetIcon(ICO_POPUP_ON,0), 16, 16, 0, hbr, DI_NORMAL);
+ SetBkMode(mydc, TRANSPARENT);
+ GetClientRect(hwnd, &rc);
+ rc.left += 30; // 10+16+4 -- icon
+ rc.right -= (rc.right-rc.left)/3;
+ rc.bottom -= (rc.bottom-rc.top)/3;
+ DrawText(mydc, _T(MODULNAME_LONG), lstrlen(_T(MODULNAME_LONG)), &rc, DT_CENTER|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
+ GetClientRect(hwnd, &rc);
+ rc.left += 30; // 10+16+4 -- icon
+ rc.left += (rc.right-rc.left)/3;
+ rc.top += (rc.bottom-rc.top)/3;
+ DrawText(mydc, _T(MODULNAME_LONG), lstrlen(_T(MODULNAME_LONG)), &rc, DT_CENTER|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
+ GetClientRect(hwnd, &rc);
+ FrameRect(mydc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
+ SelectObject(mydc, hfnt);
+ DeleteObject(hbr);
+ break;
+ }
+ case 2:
+ { // Position
+ RECT rc;
+ HBRUSH hbr;
+ hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+ GetClientRect(hwnd, &rc);
+ FillRect(mydc, &rc, hbr);
+ DeleteObject(hbr);
+
+ hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
+ GetClientRect(hwnd, &rc);
+ rc.right -= 100;
+ rc.top += 100;
+ FillRect(mydc, &rc, hbr);
+ DeleteObject(hbr);
+
+ HPEN hpen = (HPEN)SelectObject(mydc, CreatePen(PS_DOT, 1, RGB(0,0,0)));
+ MoveToEx(mydc, 0, 100, NULL);
+ LineTo (mydc, 201, 100);
+ MoveToEx(mydc, 100, 0, NULL);
+ LineTo (mydc, 100, 201);
+ DeleteObject(SelectObject(mydc, hpen));
+
+ HRGN hrgn = CreateRectRgn(0,0,0,0);
+ GetWindowRgn(hwnd, hrgn);
+ FrameRgn(mydc, hrgn, (HBRUSH)GetStockObject(BLACK_BRUSH), 1, 1);
+ DeleteObject(hrgn);
+
+ break;
+ }
+ }
+}
+
+INT_PTR CALLBACK BoxPreviewWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_PAINT:
+ {
+ if (GetUpdateRect(hwnd, 0, FALSE))
+ {
+ PAINTSTRUCT ps;
+ HDC mydc = BeginPaint(hwnd, &ps);
+ BoxPreview_OnPaint(hwnd, mydc, GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ EndPaint(hwnd, &ps);
+ return TRUE;
+ }
+ break;
+ }
+
+ case WM_PRINT:
+ case WM_PRINTCLIENT:
+ {
+ HDC mydc = (HDC)wParam;
+ BoxPreview_OnPaint(hwnd, mydc, GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ return TRUE;
+ }
+
+ case WM_LBUTTONDOWN:
+ {
+ ReleaseCapture();
+ SendMessage(hwnd, WM_SYSCOMMAND, 0xF012 /*SC_DRAGMOVE*/, 0);
+ return TRUE;
+ }
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
diff --git a/plugins/Popup/src/opt_skins.h b/plugins/Popup/src/opt_skins.h
new file mode 100644
index 0000000000..4e06893d65
--- /dev/null
+++ b/plugins/Popup/src/opt_skins.h
@@ -0,0 +1,46 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opt_skins.h $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __opt_skins_h__
+#define __opt_skins_h__
+
+#ifndef CS_DROPSHADOW
+#define CS_DROPSHADOW 0x00020000
+#endif
+#define BOXPREVIEW_WNDCLASS "PopupPreviewBoxWndclass"
+
+void RegisterOptPrevBox();
+
+void LoadOption_Skins();
+INT_PTR CALLBACK DlgProcPopSkinsOpts(HWND, UINT, WPARAM, LPARAM);
+
+#endif // __opt_skins_h__
diff --git a/plugins/Popup/src/opttree.cpp b/plugins/Popup/src/opttree.cpp
new file mode 100644
index 0000000000..d6d81c8103
--- /dev/null
+++ b/plugins/Popup/src/opttree.cpp
@@ -0,0 +1,442 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opttree.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+static void OptTree_TranslateItem(HWND hwndTree, HTREEITEM hItem)
+{
+ union
+ {
+ char ansi[128];
+ WCHAR unicode[64];
+ } buf;
+
+#if defined(_UNICODE)
+ TVITEMW tvi = {0};
+ tvi.mask = TVIF_HANDLE|TVIF_TEXT;
+ tvi.hItem = hItem;
+ tvi.pszText = buf.unicode;
+ tvi.cchTextMax = SIZEOF(buf.unicode);
+ SendMessageW(hwndTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
+ tvi.pszText = TranslateW(tvi.pszText);
+ tvi.cchTextMax = lstrlenW(tvi.pszText);
+ SendMessageW(hwndTree, TVM_SETITEMW, 0, (LPARAM)&tvi);
+
+#else
+ if (g_popup.isOsUnicode && MySendMessageW)
+ {
+ TVITEMW tvi = {0};
+ tvi.mask = TVIF_HANDLE|TVIF_TEXT;
+ tvi.hItem = hItem;
+ tvi.pszText = buf.unicode;
+ tvi.cchTextMax = SIZEOF(buf.unicode);
+ MySendMessageW(hwndTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
+ tvi.pszText = TranslateW(tvi.pszText);
+ tvi.cchTextMax = lstrlenW(tvi.pszText);
+ MySendMessageW(hwndTree, TVM_SETITEMW, 0, (LPARAM)&tvi);
+ }
+ else {
+ TVITEMA tvi = {0};
+ tvi.mask = TVIF_HANDLE|TVIF_TEXT;
+ tvi.hItem = hItem;
+ tvi.pszText = buf.ansi;
+ tvi.cchTextMax = SIZEOF(buf.ansi);
+ SendMessageA(hwndTree, TVM_GETITEMA, 0, (LPARAM)&tvi);
+ tvi.pszText = Translate(tvi.pszText);
+ tvi.cchTextMax = lstrlenA(tvi.pszText);
+ SendMessageA(hwndTree, TVM_SETITEMA, 0, (LPARAM)&tvi);
+ }
+#endif
+}
+
+void OptTree_Translate(HWND hwndTree)
+{
+ HTREEITEM hItem = TreeView_GetRoot(hwndTree);
+ while (hItem)
+ {
+ OptTree_TranslateItem(hwndTree, hItem);
+
+ HTREEITEM hItemTmp = 0;
+ if (hItemTmp = TreeView_GetChild(hwndTree, hItem))
+ {
+ hItem = hItemTmp;
+ } else
+ if (hItemTmp = TreeView_GetNextSibling(hwndTree, hItem))
+ {
+ hItem = hItemTmp;
+ } else
+ {
+ while (1)
+ {
+ if (!(hItem = TreeView_GetParent(hwndTree, hItem))) break;
+ if (hItemTmp = TreeView_GetNextSibling(hwndTree, hItem))
+ {
+ hItem = hItemTmp;
+ break;
+ }
+ }
+ }
+ }
+}
+
+HTREEITEM OptTree_FindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, const TCHAR *name)
+{
+ TVITEM tvi = {0};
+ TCHAR str[MAX_PATH];
+
+ if (hItem)
+ tvi.hItem = TreeView_GetChild(hwndTree, hItem);
+ else
+ tvi.hItem = TreeView_GetRoot(hwndTree);
+
+ if (!name)
+ return tvi.hItem;
+
+ tvi.mask = TVIF_TEXT;
+ tvi.pszText = str;
+ tvi.cchTextMax = MAX_PATH;
+
+ while (tvi.hItem)
+ {
+ TreeView_GetItem(hwndTree, &tvi);
+
+ if (!lstrcmp(tvi.pszText, name))
+ return tvi.hItem;
+
+ tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem);
+ }
+ return NULL;
+}
+
+HTREEITEM OptTree_AddItem(HWND hwndTree, LPTSTR name, LPARAM lParam, int iconIndex)
+{
+ TCHAR itemName[1024];
+
+ TCHAR* sectionName;
+ int sectionLevel = 0;
+
+ HTREEITEM hSection = NULL, result = NULL;
+ lstrcpy(itemName, name);
+ sectionName = itemName;
+
+ while (sectionName)
+ {
+ // allow multi-level tree
+ TCHAR* pItemName = sectionName;
+ HTREEITEM hItem;
+
+ if (sectionName = _tcschr(sectionName, '/'))
+ {
+ // one level deeper
+ *sectionName = 0;
+ sectionName++;
+ }
+
+ hItem = OptTree_FindNamedTreeItemAt(hwndTree, hSection, pItemName);
+ if (!sectionName || !hItem)
+ {
+ if (!hItem)
+ {
+ TVINSERTSTRUCT tvis = {0};
+
+ tvis.hParent = hSection;
+ tvis.hInsertAfter = TVI_LAST;//TVI_SORT;
+ tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE;
+ tvis.item.pszText = pItemName;
+ tvis.item.state = tvis.item.stateMask = TVIS_EXPANDED;
+ if (sectionName)
+ {
+ tvis.item.lParam = 0;
+ tvis.item.iImage = tvis.item.iSelectedImage = -1;
+ } else
+ {
+ tvis.item.lParam = lParam;
+ tvis.item.iImage = tvis.item.iSelectedImage = iconIndex;
+ tvis.item.mask |= TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ }
+ hItem = TreeView_InsertItem(hwndTree, &tvis);
+ if (!sectionName)
+ result = hItem;
+ }
+ }
+ sectionLevel++;
+ hSection = hItem;
+ }
+
+ return result;
+}
+
+BOOL OptTree_ProcessMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, int *result, int idcTree, OPTTREE_OPTION *options, int optionCount)
+{
+ enum { IMG_GROUP, IMG_CHECK, IMG_NOCHECK, IMG_RCHECK, IMG_NORCHECK, IMG_GRPOPEN, IMG_GRPCLOSED };
+
+ HWND hwndTree = GetDlgItem(hwnd, idcTree);
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int indx;
+ TCHAR itemName[1024];
+ HIMAGELIST hImgLst;
+
+ TreeView_SelectItem(hwndTree, NULL);
+ TreeView_DeleteAllItems(hwndTree);
+
+ hImgLst = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR|ILC_COLOR32|ILC_MASK, 5, 1);
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED));
+ if (g_popup.MirVer >= PLUGIN_MAKE_VERSION(0,7,0,2))
+ {
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadSkinnedIcon(SKINICON_OTHER_TICK));
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadSkinnedIcon(SKINICON_OTHER_NOTICK));
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadSkinnedIcon(SKINICON_OTHER_TICK));
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadSkinnedIcon(SKINICON_OTHER_NOTICK));
+ } else
+ {
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_OPT_CHECK_ON), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED)); // check buttons
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_OPT_CHECK_OFF), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED)); // check buttons
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_OPT_CHECK_ON), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED)); // check buttons
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_OPT_CHECK_OFF), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED)); // check buttons
+// ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_OPT_RADIO_ON), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED)); // radio buttons
+// ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_OPT_RADIO_OFF), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_SHARED)); // radio buttons
+ }
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadSkinnedIcon(SKINICON_OTHER_GROUPOPEN));
+ ImageList_ReplaceIcon(hImgLst, -1, (HICON)LoadSkinnedIcon(SKINICON_OTHER_GROUPSHUT));
+ TreeView_SetImageList(hwndTree, hImgLst, TVSIL_NORMAL);
+
+ /* build options tree. based on code from IcoLib */
+ for (indx = 0; indx < optionCount; indx++)
+ {
+ TCHAR* sectionName;
+ int sectionLevel = 0;
+
+ HTREEITEM hSection = NULL;
+ lstrcpy(itemName, options[indx].pszOptionName);
+ sectionName = itemName;
+
+ while (sectionName)
+ {
+ // allow multi-level tree
+ TCHAR* pItemName = sectionName;
+ HTREEITEM hItem;
+
+ if (sectionName = _tcschr(sectionName, '/'))
+ {
+ // one level deeper
+ *sectionName = 0;
+ sectionName++;
+ }
+
+ hItem = OptTree_FindNamedTreeItemAt(hwndTree, hSection, pItemName);
+ if (!sectionName || !hItem)
+ {
+ if (!hItem)
+ {
+ TVINSERTSTRUCT tvis = {0};
+
+ tvis.hParent = hSection;
+ tvis.hInsertAfter = TVI_LAST;//TVI_SORT;
+ tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvis.item.pszText = pItemName;
+ tvis.item.state = tvis.item.stateMask = TVIS_EXPANDED;
+ if (sectionName)
+ {
+ tvis.item.lParam = -1;
+ tvis.item.state |= TVIS_BOLD;
+ tvis.item.stateMask |= TVIS_BOLD;
+ tvis.item.iImage = tvis.item.iSelectedImage = IMG_GRPOPEN;
+ } else
+ {
+ tvis.item.lParam = indx;
+ if (options[indx].groupId == OPTTREE_CHECK)
+ {
+ tvis.item.iImage = tvis.item.iSelectedImage = IMG_NOCHECK;
+ } else
+ {
+ tvis.item.iImage = tvis.item.iSelectedImage = IMG_NORCHECK;
+ }
+ }
+ hItem = TreeView_InsertItem(hwndTree, &tvis);
+ if (!sectionName)
+ options[indx].hItem = hItem;
+ }
+ }
+ sectionLevel++;
+ hSection = hItem;
+ }
+ }
+
+ OptTree_Translate(hwndTree);
+ ShowWindow(hwndTree, SW_SHOW);
+ TreeView_SelectItem(hwndTree, OptTree_FindNamedTreeItemAt(hwndTree, 0, NULL));
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ ImageList_Destroy(TreeView_GetImageList(hwndTree, TVSIL_NORMAL));
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lparam;
+ if (lpnmhdr->idFrom != idcTree) break;
+ switch (lpnmhdr->code)
+ {
+ case NM_CLICK:
+ {
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(lpnmhdr->hwndFrom,&hti.pt);
+ if(TreeView_HitTest(lpnmhdr->hwndFrom,&hti))
+ {
+ if(hti.flags&TVHT_ONITEMICON)
+ {
+ TVITEM tvi;
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.hItem=hti.hItem;
+ TreeView_GetItem(lpnmhdr->hwndFrom,&tvi);
+ switch (tvi.iImage)
+ {
+ case IMG_GRPOPEN:
+ tvi.iImage = tvi.iSelectedImage = IMG_GRPCLOSED;
+ TreeView_Expand(lpnmhdr->hwndFrom, tvi.hItem, TVE_COLLAPSE);
+ break;
+ case IMG_GRPCLOSED:
+ tvi.iImage = tvi.iSelectedImage = IMG_GRPOPEN;
+ TreeView_Expand(lpnmhdr->hwndFrom, tvi.hItem, TVE_EXPAND);
+ break;
+
+ case IMG_CHECK:
+ tvi.iImage = tvi.iSelectedImage = IMG_NOCHECK;
+ *result = tvi.lParam;
+ options[tvi.lParam].bState = FALSE;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case IMG_NOCHECK:
+ tvi.iImage = tvi.iSelectedImage = IMG_CHECK;
+ *result = tvi.lParam;
+ options[tvi.lParam].bState = TRUE;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case IMG_NORCHECK:
+ {
+ int i;
+ for (i = 0; i < optionCount; ++i)
+ {
+ if (options[i].groupId == options[tvi.lParam].groupId)
+ {
+ TVITEM tvi_tmp;
+ tvi_tmp.mask = TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi_tmp.hItem = options[i].hItem;
+ tvi_tmp.iImage = tvi_tmp.iSelectedImage = IMG_NORCHECK;
+ TreeView_SetItem(lpnmhdr->hwndFrom, &tvi_tmp);
+ }
+ }
+ tvi.iImage = tvi.iSelectedImage = IMG_RCHECK;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+ }
+ TreeView_SetItem(lpnmhdr->hwndFrom,&tvi);
+ }
+ }
+ break;
+ }
+
+ case TVN_ITEMEXPANDED:
+ {
+ LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lparam;
+ TVITEM tvi;
+ tvi.mask=TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.hItem = lpnmtv->itemNew.hItem;
+ tvi.iImage = tvi.iSelectedImage =
+ (lpnmtv->itemNew.state & TVIS_EXPANDED) ? IMG_GRPOPEN : IMG_GRPCLOSED;
+ TreeView_SetItem(lpnmhdr->hwndFrom,&tvi);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+DWORD OptTree_GetOptions(HWND hwnd, int idcTree, OPTTREE_OPTION *options, int optionCount, LPTSTR pszSettingName)
+{
+ enum { IMG_GROUP, IMG_CHECK, IMG_NOCHECK, IMG_RCHECK, IMG_NORCHECK, IMG_GRPOPEN, IMG_GRPCLOSED };
+
+ HWND hwndTree = GetDlgItem(hwnd, idcTree);
+ DWORD result = 0;
+ int i;
+ for (i = 0; i < optionCount; ++i)
+ {
+ if ((!options[i].pszSettingName && !pszSettingName) ||
+ (options[i].pszSettingName && pszSettingName && !lstrcmp(options[i].pszSettingName, pszSettingName)))
+ {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE|TVIF_IMAGE;
+ tvi.hItem = options[i].hItem;
+ TreeView_GetItem(hwndTree, &tvi);
+ if ((tvi.iImage == IMG_CHECK) || (tvi.iImage == IMG_RCHECK))
+ result |= options[i].dwFlag;
+ }
+ }
+ return result;
+}
+
+void OptTree_SetOptions(HWND hwnd, int idcTree, OPTTREE_OPTION *options, int optionCount, DWORD dwOptions, LPTSTR pszSettingName)
+{
+ enum { IMG_GROUP, IMG_CHECK, IMG_NOCHECK, IMG_RCHECK, IMG_NORCHECK, IMG_GRPOPEN, IMG_GRPCLOSED };
+
+ HWND hwndTree = GetDlgItem(hwnd, idcTree);
+ int i;
+ for (i = 0; i < optionCount; ++i)
+ {
+ if ((!options[i].pszSettingName && !pszSettingName) ||
+ (options[i].pszSettingName && pszSettingName && !lstrcmp(options[i].pszSettingName, pszSettingName)))
+ {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.hItem = options[i].hItem;
+ if (options[i].groupId == OPTTREE_CHECK)
+ {
+ tvi.iImage = tvi.iSelectedImage = (dwOptions & options[i].dwFlag) ? IMG_CHECK : IMG_NOCHECK;
+ } else
+ {
+ tvi.iImage = tvi.iSelectedImage = (dwOptions & options[i].dwFlag) ? IMG_RCHECK : IMG_NORCHECK;
+ }
+ TreeView_SetItem(hwndTree, &tvi);
+ }
+ }
+}
diff --git a/plugins/Popup/src/opttree.h b/plugins/Popup/src/opttree.h
new file mode 100644
index 0000000000..8718ca8cb1
--- /dev/null
+++ b/plugins/Popup/src/opttree.h
@@ -0,0 +1,57 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/opttree.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __opttree_h__
+#define __opttree_h__
+
+#define OPTTREE_CHECK 0
+
+typedef struct {
+ int iconIndex;
+ LPTSTR pszOptionName;
+ int groupId;
+ DWORD dwFlag;
+ HTREEITEM hItem;
+ LPTSTR pszSettingName;
+ BOOL bState;
+ int Data; //free for use (depend on data)
+} OPTTREE_OPTION;
+
+BOOL OptTree_ProcessMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL *result, int idcTree, OPTTREE_OPTION *options, int optionCount);
+DWORD OptTree_GetOptions(HWND hwnd, int idcTree, OPTTREE_OPTION *options, int optionCount, LPTSTR pszSettingName = NULL);
+void OptTree_SetOptions(HWND hwnd, int idcTree, OPTTREE_OPTION *options, int optionCount, DWORD dwOptions, LPTSTR pszSettingName = NULL);
+
+void OptTree_Translate(HWND hwndTree);
+HTREEITEM OptTree_FindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, LPCTSTR name);
+HTREEITEM OptTree_AddItem(HWND hwndTree, LPTSTR name, LPARAM lParam = 0, int iconIndex = -1);
+
+#endif // __opttree_h__
diff --git a/plugins/Popup/src/popup_gdiplus.cpp b/plugins/Popup/src/popup_gdiplus.cpp
new file mode 100644
index 0000000000..186fedb238
--- /dev/null
+++ b/plugins/Popup/src/popup_gdiplus.cpp
@@ -0,0 +1,223 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright � 2002 Luca Santarelli,
+ � 2004-2007 Victor Pavlychko
+ � 2010 MPK
+ � 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_gdiplus.cpp $
+Revision : $Revision: 1622 $
+Last change on : $Date: 2010-06-23 23:32:21 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+/* 99% of this code was adopted from clist_modern by FYR */
+
+#include "headers.h"
+
+#undef Translate
+
+// fix for old SDK and new GDI+
+#define ULONG_PTR unsigned long
+
+#include "gdiplus.h"
+
+DWORD g_gdiplusToken;
+bool gbGdiPlusLoaded;
+
+void LoadGDIPlus()
+{
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ gbGdiPlusLoaded = false;
+ __try {
+ if (g_gdiplusToken == 0)
+ Gdiplus::GdiplusStartup(&g_gdiplusToken, &gdiplusStartupInput, NULL);
+ }
+ __except ( EXCEPTION_EXECUTE_HANDLER ) {
+ gbGdiPlusLoaded = false;
+ }
+}
+
+void UnloadGDIPlus()
+{
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ __try {
+ if (g_gdiplusToken && gbGdiPlusLoaded)
+ Gdiplus::GdiplusShutdown(g_gdiplusToken);
+ }
+ __except ( EXCEPTION_EXECUTE_HANDLER ) {
+ // do nothing
+ }
+ gbGdiPlusLoaded = true;
+ g_gdiplusToken = 0;
+}
+
+using namespace Gdiplus;
+
+/////////////////////////////////////////////////////////////////////////////////
+// GDIPlus_IsAnimatedGIF and GDIPlus_ExtractAnimatedGIF
+// based on routine from http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp
+//
+
+HBITMAP SkinEngine_CreateDIB32(int cx, int cy)
+{
+ BITMAPINFO RGB32BitsBITMAPINFO;
+ UINT * ptPixels;
+ HBITMAP DirectBitmap;
+
+ if ( cx < 0 || cy < 0 ) {
+ return NULL;
+ }
+
+ ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
+ RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ RGB32BitsBITMAPINFO.bmiHeader.biWidth=cx;//bm.bmWidth;
+ RGB32BitsBITMAPINFO.bmiHeader.biHeight=cy;//bm.bmHeight;
+ RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
+ RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
+ // pointer used for direct Bitmap pixels access
+
+
+ DirectBitmap = CreateDIBSection(NULL,
+ (BITMAPINFO *)&RGB32BitsBITMAPINFO,
+ DIB_RGB_COLORS,
+ (void **)&ptPixels,
+ NULL, 0);
+ if ((DirectBitmap == NULL || ptPixels == NULL) && cx!= 0 && cy!=0)
+ {
+ ;
+ }
+ else
+ {
+ memset(ptPixels,0,cx*cy*4);
+ }
+ return DirectBitmap;
+}
+
+
+BOOL GDIPlus_IsAnimatedGIF(TCHAR * szName)
+{
+ int nFrameCount=0;
+ Image image(szName);
+ UINT count = 0;
+
+ count = image.GetFrameDimensionsCount();
+ GUID* pDimensionIDs = new GUID[count];
+
+ // Get the list of frame dimensions from the Image object.
+ image.GetFrameDimensionsList(pDimensionIDs, count);
+
+ // Get the number of frames in the first dimension.
+ nFrameCount = image.GetFrameCount(&pDimensionIDs[0]);
+
+ delete []pDimensionIDs;
+
+ return (BOOL) (nFrameCount > 1) && image.GetWidth() && image.GetHeight();
+}
+
+void GDIPlus_GetGIFSize(TCHAR * szName, int * width, int * height)
+{
+ Image image(szName);
+
+ *width = image.GetWidth();
+ *height = image.GetHeight();
+}
+
+void GDIPlus_ExtractAnimatedGIF(TCHAR * szName, int width, int height, HBITMAP * pBitmap, int ** pframesDelay, int * pframesCount, SIZE * pSizeAvatar)
+{
+ int nFrameCount=0;
+ Bitmap image(szName);
+ PropertyItem * pPropertyItem;
+
+ UINT count = 0;
+
+ count = image.GetFrameDimensionsCount();
+ GUID* pDimensionIDs = new GUID[count];
+
+ // Get the list of frame dimensions from the Image object.
+ image.GetFrameDimensionsList(pDimensionIDs, count);
+
+ // Get the number of frames in the first dimension.
+ nFrameCount = image.GetFrameCount(&pDimensionIDs[0]);
+
+ // Assume that the image has a property item of type PropertyItemEquipMake.
+ // Get the size of that property item.
+ int nSize = image.GetPropertyItemSize(PropertyTagFrameDelay);
+
+ // Allocate a buffer to receive the property item.
+ pPropertyItem = (PropertyItem*) mir_alloc(nSize);
+
+ image.GetPropertyItem(PropertyTagFrameDelay, nSize, pPropertyItem);
+
+ int clipWidth;
+ int clipHeight;
+ int imWidth=image.GetWidth();
+ int imHeight=image.GetHeight();
+ float xscale=(float)width/imWidth;
+ float yscale=(float)height/imHeight;
+ xscale=min(xscale,yscale);
+ clipWidth=(int)(xscale*imWidth+.5);
+ clipHeight=(int)(xscale*imHeight+.5);
+
+ HBITMAP hBitmap=SkinEngine_CreateDIB32(clipWidth*nFrameCount, height);
+ HDC hdc=CreateCompatibleDC(NULL);
+ HBITMAP oldBmp=(HBITMAP)SelectObject(hdc,hBitmap);
+ Graphics graphics(hdc);
+ ImageAttributes attr;
+ ColorMatrix ClrMatrix =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, ((float)255)/255, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
+ };
+ //attr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault,ColorAdjustTypeBitmap);
+ graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
+
+ int * delays=(int*)mir_alloc(nFrameCount*sizeof(int));
+ memset(delays,0,nFrameCount*sizeof(int));
+
+ for (int i=1; i<nFrameCount+1; i++)
+ {
+ GUID pageGuid = FrameDimensionTime;
+ RectF rect((float)(i-1)*clipWidth,(float)0,(float)clipWidth,(float)clipHeight);
+ graphics.DrawImage(&image, rect, (float)0, (float)0, (float)imWidth, (float)imHeight , UnitPixel, &attr, NULL, NULL);
+ image.SelectActiveFrame(&pageGuid, i);
+ long lPause = ((long*) pPropertyItem->value)[i-1] * 10;
+ delays[i-1]=(int)lPause;
+ }
+ SelectObject(hdc,oldBmp);
+ DeleteDC(hdc);
+ mir_free(pPropertyItem);
+ pPropertyItem = NULL;
+ delete []pDimensionIDs;
+ if (pBitmap && pframesDelay && pframesCount && pSizeAvatar)
+ {
+ *pBitmap=hBitmap;
+ *pframesDelay=delays;
+ *pframesCount=nFrameCount;
+ pSizeAvatar->cx=clipWidth;
+ pSizeAvatar->cy=clipHeight;
+ }
+ GdiFlush();
+}
diff --git a/plugins/Popup/src/popup_gdiplus.h b/plugins/Popup/src/popup_gdiplus.h
new file mode 100644
index 0000000000..1214199940
--- /dev/null
+++ b/plugins/Popup/src/popup_gdiplus.h
@@ -0,0 +1,42 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright � 2002 Luca Santarelli,
+ � 2004-2007 Victor Pavlychko
+ � 2010 MPK
+ � 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_gdiplus.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+#ifndef __popup_gdiplus_h__
+#define __popup_gdiplus_h__
+
+void LoadGDIPlus();
+void UnloadGDIPlus();
+
+BOOL GDIPlus_IsAnimatedGIF(TCHAR * szName);
+void GDIPlus_GetGIFSize(TCHAR * szName, int * width, int * height);
+void GDIPlus_ExtractAnimatedGIF(TCHAR * szName, int width, int height, HBITMAP * pBitmap, int ** pframesDelay, int * pframesCount, SIZE * pSizeAvatar);
+
+#endif // __popup_gdiplus_h__
diff --git a/plugins/Popup/src/popup_thread.cpp b/plugins/Popup/src/popup_thread.cpp
new file mode 100644
index 0000000000..2376653cba
--- /dev/null
+++ b/plugins/Popup/src/popup_thread.cpp
@@ -0,0 +1,372 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_thread.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+#include <process.h>
+//#include <list>
+
+// globals
+//static unsigned idPopupThread = 0;
+static int gIdleRequests = 0;
+static bool gTerminating = false;
+static HANDLE hThreadMutex = NULL;
+static HWND gHwndManager = 0;
+static int gLockCount = 0;
+static volatile int nPopups = 0;
+
+//typedef std::list<PopupWnd2 *> PopupList;
+typedef LIST<PopupWnd2> PopupList;
+static PopupList popupList(3);
+
+// forwards
+enum
+{ // message id's
+ UTM_PT_FIRST = WM_USER+1607,
+ UTM_STOP_THREAD,
+ UTM_ADD_WINDOW,
+ UTM_UPDATE_WINDOW,
+ UTM_REMOVE_WINDOW,
+ UTM_REQUEST_IDLE,
+ UTM_LOCK_QUEUE,
+ UTM_UNLOCK_QUEUE,
+ UTM_REQUEST_REMOVE
+};
+static void __cdecl PopupThread(void *arg);
+
+// interface
+void LoadPopupThread()
+{
+ hThreadMutex = CreateMutex(NULL, FALSE, NULL);
+ _beginthread(PopupThread, 0, NULL);
+// _beginthreadex(NULL, 0, PopupThread, NULL, 0, &idPopupThread);
+}
+
+void StopPopupThread()
+{
+ PostMessage(gHwndManager, UTM_STOP_THREAD, 0, 0);
+}
+
+void UnloadPopupThread()
+{
+// We won't waint for thread to exit, Miranda's thread unsind mechanism will do that for us.
+ WaitForSingleObject(hThreadMutex, INFINITE);
+ CloseHandle(hThreadMutex);
+}
+
+void PopupThreadLock()
+{
+ PostMessage(gHwndManager, UTM_LOCK_QUEUE, 0, 0);
+}
+
+void PopupThreadUnlock()
+{
+ PostMessage(gHwndManager, UTM_UNLOCK_QUEUE, 0, 0);
+}
+
+bool PopupThreadIsFull()
+{
+// char buf[128];
+// wsprintf(buf, "%d, %d", nPopups, PopUpOptions.MaxPopups);
+// MessageBoxA(NULL, buf, "Popup Plus", MB_OK);
+ return nPopups >= PopUpOptions.MaxPopups;
+}
+
+bool PopupThreadAddWindow(PopupWnd2 *wnd)
+{
+ PostMessage(gHwndManager, UTM_ADD_WINDOW, 0, (LPARAM)wnd);
+ return true;
+}
+
+bool PopupThreadRemoveWindow(PopupWnd2 *wnd)
+{
+ PostMessage(gHwndManager, UTM_REMOVE_WINDOW, 0, (LPARAM)wnd);
+ return true;
+}
+
+bool PopupThreadUpdateWindow(PopupWnd2 *wnd)
+{
+ PostMessage(gHwndManager, UTM_UPDATE_WINDOW, 0, (LPARAM)wnd);
+ return true;
+}
+
+bool PopupThreadRequestRemoveWindow(PopupWnd2 *wnd)
+{
+ PostMessage(gHwndManager, UTM_REQUEST_REMOVE, 0, (LPARAM)wnd);
+ return true;
+}
+
+bool UpdatePopupPosition(PopupWnd2 *prev, PopupWnd2 *wnd)
+{
+ if (!wnd) return false;
+ if (!PopUpOptions.ReorderPopUps && wnd->isPositioned()) return false;
+
+ int POPUP_SPACING = PopUpOptions.spacing;
+
+ POINT pos;
+ SIZE prevSize = {0}, curSize = wnd->getSize();
+ if (prev) prevSize = prev->getSize();
+
+ RECT rc;
+// SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
+
+#if !defined(_UNICODE)
+ //Win95 or NT don't have the support for multi monitor.
+ if (!MyGetMonitorInfo) {
+ SystemParametersInfo(SPI_GETWORKAREA,0,&rc,0);
+ }
+ //Windows 98/ME/2000/XP do have it.
+ else
+#endif
+ if (GetSystemMetrics(SM_CMONITORS)==1) { //we have only one monitor (cant check it together with 1.if)
+ SystemParametersInfo(SPI_GETWORKAREA,0,&rc,0);
+ }
+ else { //Multimonitor stuff (we have more then 1)
+ HMONITOR hMonitor = NULL;
+ HWND hWnd = NULL;
+ MONITORINFOEX mnti; // = { 0 };
+
+ if (PopUpOptions.Monitor == MN_MIRANDA)
+ hWnd = (HWND)CallService(MS_CLUI_GETHWND,0,0);
+ else // PopUpOptions.Monitor == MN_ACTIVE
+ hWnd = GetForegroundWindow();
+
+ mnti.cbSize = sizeof(MONITORINFOEX);
+
+#if defined(_UNICODE)
+ hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
+ if (GetMonitorInfo(hMonitor, (LPMONITORINFO)&mnti) == TRUE) //It worked
+#else
+ hMonitor = MyMonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
+ if (MyGetMonitorInfo(hMonitor, (LPMONITORINFO)&mnti) == TRUE) //It worked
+#endif
+ CopyMemory(&rc, &(mnti.rcWork), sizeof(RECT));
+ else
+ SystemParametersInfo(SPI_GETWORKAREA,0,&rc,0);
+ }
+
+ rc.left += PopUpOptions.gapLeft - POPUP_SPACING;
+ rc.right -= PopUpOptions.gapRight - POPUP_SPACING;
+ rc.top += PopUpOptions.gapTop - POPUP_SPACING;
+ rc.bottom -= PopUpOptions.gapBottom - POPUP_SPACING;
+ if (PopUpOptions.Spreading == SPREADING_VERTICAL)
+ {
+ switch (PopUpOptions.Position)
+ {
+ case POS_UPPERLEFT:
+ pos.x = rc.left + POPUP_SPACING;
+ pos.y = (prev ? (prev->getPosition().y + prev->getSize().cy) : rc.top) + POPUP_SPACING;
+ break;
+ case POS_LOWERLEFT:
+ pos.x = rc.left + POPUP_SPACING;
+ pos.y = (prev ? prev->getPosition().y : rc.bottom) - wnd->getSize().cy - POPUP_SPACING;
+ break;
+ case POS_LOWERRIGHT:
+ pos.x = rc.right - wnd->getSize().cx - POPUP_SPACING;
+ pos.y = (prev ? prev->getPosition().y : rc.bottom) - wnd->getSize().cy - POPUP_SPACING;
+ break;
+ case POS_UPPERRIGHT:
+ pos.x = rc.right - wnd->getSize().cx - POPUP_SPACING;
+ pos.y = (prev ? (prev->getPosition().y + prev->getSize().cy) : rc.top) + POPUP_SPACING;
+ break;
+ }
+ } else
+ // if (PopUpOptions.Spreading == SPREADING_HORIZONTAL)
+ {
+ switch (PopUpOptions.Position)
+ {
+ case POS_UPPERLEFT:
+ pos.x = (prev ? (prev->getPosition().x + prev->getSize().cx) : rc.left) + POPUP_SPACING;
+ pos.y = rc.top + POPUP_SPACING;
+ break;
+ case POS_LOWERLEFT:
+ pos.x = (prev ? (prev->getPosition().x + prev->getSize().cx) : rc.left) + POPUP_SPACING;
+ pos.y = rc.bottom - wnd->getSize().cy - POPUP_SPACING;
+ break;
+ case POS_LOWERRIGHT:
+ pos.x = (prev ? prev->getPosition().x : rc.right) - wnd->getSize().cx - POPUP_SPACING;
+ pos.y = rc.bottom - wnd->getSize().cy - POPUP_SPACING;
+ break;
+ case POS_UPPERRIGHT:
+ pos.x = (prev ? prev->getPosition().x : rc.right) - wnd->getSize().cx - POPUP_SPACING;
+ pos.y = rc.top + POPUP_SPACING;
+ break;
+ }
+ }
+ wnd->setPosition(pos);
+ return true;
+}
+
+void RepositionPopups()
+{
+ PopupWnd2 *prev = 0;
+ if (PopUpOptions.ReorderPopUps)
+ {
+ for (int i = 0; i < popupList.getCount(); ++i)
+ {
+ UpdatePopupPosition(prev, popupList[i]);
+ prev = popupList[i];
+ }
+ }
+}
+
+static LRESULT CALLBACK PopupThreadManagerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ PopupWnd2 *wnd = NULL;
+ if (message == UTM_ADD_WINDOW ||
+ message == UTM_UPDATE_WINDOW ||
+ message == UTM_REMOVE_WINDOW ||
+ message == UTM_REQUEST_REMOVE)
+ {
+ if (!(wnd = (PopupWnd2 *)lParam))
+ return 0;
+ }
+ switch (message)
+ {
+ case UTM_STOP_THREAD:
+ {
+ gTerminating = true;
+ if (DBGetContactSettingByte(NULL, MODULNAME, "FastExit", 0))
+ for (int i = 0; i < popupList.getCount(); ++i)
+ PUDeletePopUp(popupList[i]->getHwnd());
+ PostQuitMessage(0);
+ break;
+ }
+ case UTM_ADD_WINDOW:
+ {
+ if (gTerminating) break;
+ UpdatePopupPosition(popupList.getCount() ? popupList[popupList.getCount()-1] : 0, wnd);
+ popupList.insert(wnd);
+ ++nPopups;
+ wnd->callMethodAsync(&PopupWnd2::m_show, 0);
+ break;
+ }
+ case UTM_UPDATE_WINDOW:
+ {
+ RepositionPopups();
+ break;
+ }
+ case UTM_REQUEST_REMOVE:
+ {
+ if ((PopUpOptions.LeaveHovered && gLockCount) || (wnd && wnd->isLocked()))
+ {
+ wnd->updateTimer();
+ } else
+ {
+ PostMessage(wnd->getHwnd(), WM_CLOSE, 0, 0);
+ }
+ break;
+ }
+ case UTM_REMOVE_WINDOW:
+ {
+ // popupList.remove(ptr) would be nicer, but it requires sortFunc :(
+ for (int i = 0; i < popupList.getCount(); ++i)
+ if (popupList[i] == wnd)
+ {
+ popupList.remove(i);
+ RepositionPopups();
+ --nPopups;
+ delete wnd;
+ break;
+ }
+ break;
+ }
+ case UTM_LOCK_QUEUE:
+ {
+ ++gLockCount;
+ break;
+ }
+ case UTM_UNLOCK_QUEUE:
+ {
+ if (--gLockCount < 0)
+ gLockCount = 0;
+ break;
+ }
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+// thread func
+static void __cdecl PopupThread(void *arg)
+{
+ // grab the mutex
+ if (WaitForSingleObject(hThreadMutex, INFINITE) != WAIT_OBJECT_0)
+ { // other thread is already running
+ _endthread();
+ return;
+ }
+
+ // Increment Miranda thread counter
+ CallService(MS_SYSTEM_THREAD_PUSH, 0, 0);
+
+ // Create manager window
+ DWORD err;
+ WNDCLASSEX wcl;
+ wcl.cbSize = sizeof(wcl);
+ wcl.lpfnWndProc = PopupThreadManagerWndProc;
+ wcl.style = 0;
+ wcl.cbClsExtra = 0;
+ wcl.cbWndExtra = 0;
+ wcl.hInstance = hInst;
+ wcl.hIcon = NULL;
+ wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ wcl.lpszMenuName = NULL;
+ wcl.lpszClassName = _T("PopupThreadManagerWnd");
+ wcl.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
+ g_wndClass.cPopupThreadManagerWnd = RegisterClassEx(&wcl);
+ err = GetLastError();
+ if (!g_wndClass.cPopupThreadManagerWnd) {
+ TCHAR msg[1024];
+ wsprintf(msg, TranslateT("Failed to register %s class."),wcl.lpszClassName);
+ MSGERROR(msg);
+ }
+
+ gHwndManager = CreateWindow(_T("PopupThreadManagerWnd"), NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInst, NULL);
+ SetWindowPos(gHwndManager, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_HIDEWINDOW);
+
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ ReleaseMutex(hThreadMutex);
+
+ // Decrement Miranda thread counter
+ CallService(MS_SYSTEM_THREAD_POP, 0, 0);
+
+ // Ok, now we can kill this thread
+ _endthread();
+
+ return;
+}
diff --git a/plugins/Popup/src/popup_thread.h b/plugins/Popup/src/popup_thread.h
new file mode 100644
index 0000000000..98e9c75725
--- /dev/null
+++ b/plugins/Popup/src/popup_thread.h
@@ -0,0 +1,52 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_thread.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __popup_thread_h__
+#define __popup_thread_h__
+
+void LoadPopupThread();
+void StopPopupThread();
+void UnloadPopupThread();
+
+void PopupThreadLock();
+void PopupThreadUnlock();
+
+class PopupWnd2;
+
+bool PopupThreadIsFull();
+bool PopupThreadAddWindow(PopupWnd2 *wnd);
+bool PopupThreadRemoveWindow(PopupWnd2 *wnd);
+bool PopupThreadUpdateWindow(PopupWnd2 *wnd);
+
+bool PopupThreadRequestRemoveWindow(PopupWnd2 *wnd);
+
+#endif // __popup_thread_h__
diff --git a/plugins/Popup/src/popup_wnd2.cpp b/plugins/Popup/src/popup_wnd2.cpp
new file mode 100644
index 0000000000..785c0e706e
--- /dev/null
+++ b/plugins/Popup/src/popup_wnd2.cpp
@@ -0,0 +1,1945 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_wnd2.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+#include "bitmap_funcs.h"
+#include <math.h>
+
+#define POPUP_WNDCLASS "PopupWnd2"
+
+#ifndef CS_DROPSHADOW
+#define CS_DROPSHADOW 0x00020000
+#endif
+
+#define ULW_ALPHA 0x00000002
+#define AC_SRC_ALPHA 0x01
+
+#define POPUP_TIMER 1607
+#define AVATAR_TIMER 1608
+#define CURSOR_TIMER 1609
+
+#define UM_AVATARCHANGED (WM_USER+0x300)
+#define UM_MENUDONE (WM_USER+0x301)
+#define UM_SHOWMENU (WM_USER+0x302)
+
+HWND ghwndMenuHost = NULL;
+
+void WindowThread(void *arg);
+
+LRESULT CALLBACK MenuHostWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+bool LoadPopupWnd2()
+{
+ bool res = true;
+ DWORD err;
+
+ WNDCLASSEX wcl;
+ wcl.cbSize = sizeof(wcl);
+ wcl.lpfnWndProc = PopupWnd2::WindowProc;
+ wcl.style = 0;
+ wcl.cbClsExtra = 0;
+ wcl.cbWndExtra = 0;
+ wcl.hInstance = hInst;
+ wcl.hIcon = NULL;
+ wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ wcl.lpszMenuName = NULL;
+ wcl.lpszClassName = _T(POPUP_WNDCLASS);
+ wcl.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
+ g_wndClass.cPopupWnd2 = RegisterClassEx(&wcl);
+ err = GetLastError();
+ if (!g_wndClass.cPopupWnd2) {
+ res = false;
+ TCHAR msg[1024];
+ wsprintf(msg, TranslateT("Failed to register %s class."),wcl.lpszClassName);
+ MessageBox(NULL, msg, _T(MODULNAME_LONG), MB_ICONSTOP|MB_OK);
+ }
+
+ // register custom class for edit box with drop-shadow attribute
+ if (IsWinVerXPPlus())
+ {
+ #if defined(_UNICODE) || defined(_WIN64)
+ #define MyRegisterClassExW RegisterClassExW
+ #define MyGetClassInfoExW GetClassInfoExW
+ #else
+ ATOM (WINAPI *MyRegisterClassExW)(CONST WNDCLASSEXW *);
+ MyRegisterClassExW = (ATOM (WINAPI *)(CONST WNDCLASSEXW *))GetProcAddress(hUserDll, "RegisterClassExW");
+ BOOL (WINAPI *MyGetClassInfoExW)(HINSTANCE, LPCWSTR, LPWNDCLASSEXW);
+ MyGetClassInfoExW = (BOOL (WINAPI *)(HINSTANCE, LPCWSTR, LPWNDCLASSEXW))GetProcAddress(hUserDll, "GetClassInfoExW");
+ #endif
+ WNDCLASSEXW wclw = {0};
+ wclw.cbSize = sizeof(wclw);
+ if (!MyGetClassInfoExW(NULL, L"EDIT", &wclw))
+ MSGERROR(TranslateT("Failed to GetClassInfoExW from EDIT class."));
+ wclw.hInstance = hInst;
+ wclw.lpszClassName = L"PopupEditBox";
+ wclw.style |= CS_DROPSHADOW;
+ g_wndClass.cPopupEditBox = MyRegisterClassExW(&wclw);
+ err = GetLastError();
+ if (!g_wndClass.cPopupEditBox) {
+ TCHAR msg[2048];
+ wsprintf(msg, _T("Failed to register custom edit box window class.\r\n\r\ncbSize: %i\r\nstyle: %p\r\nlpfnWndProc: %i\r\ncbClsExtra: %i\r\ncbWndExtra: %i\r\nhInstance: %i\r\nhIcon: %i\r\nhCursor: %i\r\nhbrBackground: %i\r\nlpszMenuName: %s\r\nlpszClassName: %s\r\nhIconSm: %i\r\n"),
+ wclw.cbSize, //UINT cbSize;
+ wclw.style, //UINT style;
+ wclw.lpfnWndProc, //WNDPROC lpfnWndProc;
+ wclw.cbClsExtra, //int cbClsExtra;
+ wclw.cbWndExtra, //int cbWndExtra;
+ wclw.hInstance, //HINSTANCE hInstance;
+ wclw.hIcon, //HICON hIcon;
+ wclw.hCursor, //HCURSOR hCursor;
+ wclw.hbrBackground, //HBRUSH hbrBackground;
+ wclw.lpszMenuName, //LPCWSTR lpszMenuName;
+ wclw.lpszClassName, //LPCWSTR lpszClassName;
+ wclw.hIconSm //HICON hIconSm;
+ );
+
+ MSGERROR(msg);
+ }
+ }
+
+ ZeroMemory(&wcl, sizeof(wcl));
+ wcl.cbSize = sizeof(wcl);
+ wcl.lpfnWndProc = MenuHostWndProc;
+ wcl.style = 0;
+ wcl.cbClsExtra = 0;
+ wcl.cbWndExtra = 0;
+ wcl.hInstance = hInst;
+ wcl.hIcon = NULL;
+ wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ wcl.lpszMenuName = NULL;
+ wcl.lpszClassName = _T("PopupMenuHostWnd");
+ wcl.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
+ g_wndClass.cPopupMenuHostWnd = RegisterClassEx(&wcl);
+ err = GetLastError();
+ if (!g_wndClass.cPopupMenuHostWnd) {
+ res = false;
+ TCHAR msg[1024];
+ wsprintf(msg, TranslateT("Failed to register %s class."),wcl.lpszClassName);
+ MSGERROR(msg);
+ }
+
+ ghwndMenuHost = CreateWindow(_T("PopupMenuHostWnd"), NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInst, NULL);
+ SetWindowPos(ghwndMenuHost, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_HIDEWINDOW);
+
+ INITCOMMONCONTROLSEX iccex;
+ iccex.dwICC = ICC_WIN95_CLASSES;
+ iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ InitCommonControlsEx(&iccex);
+
+ res = res && ghwndMenuHost;
+
+ return res;
+}
+
+void UnloadPopupWnd2()
+{
+ DestroyWindow(ghwndMenuHost);
+}
+
+PopupWnd2::PopupWnd2(POPUPDATA2 *ppd, POPUPOPTIONS *theCustomOptions, bool renderOnly)
+{
+ m_signature = POPUP_OBJECT_SIGNARURE;
+
+ m_lockCount = 0;
+ m_hbmAvatar = NULL;
+ m_avatar = NULL;
+ m_textType = TT_NONE;
+ m_options = theCustomOptions ? theCustomOptions : &PopUpOptions;
+ m_lpzSkin = NULL;
+ m_customPopup = false;
+ m_lpwzTitle = m_lpwzText = NULL;
+ m_lpzTitle = m_lpzText = NULL;
+ m_mtTitle = m_mtText = NULL;
+ m_hfnText = fonts.text;
+ m_hfnTitle = fonts.title;
+ m_hwnd = m_hwndToolTip = NULL;
+ m_bPositioned = m_bIsHovered = /*m_bIdleRequested =*/ m_bWindowCreated = m_bFade = m_bSlide = m_bDestroy = false;
+ m_bmp = m_bmpBase = m_bmpAnimate = NULL;
+ m_avatarFrameDelay = 0;
+ m_hhkAvatarChanged = NULL;
+ m_actions = NULL;
+ m_actionCount = 0;
+ m_bIsPinned = false;
+ updateData(ppd);
+ if (!renderOnly)
+ startThread();
+}
+
+
+PopupWnd2::~PopupWnd2()
+{
+ m_signature = 0;
+
+ if (m_lpzSkin) mir_free(m_lpzSkin);
+ if (m_hwnd) SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
+ if (m_bmp) delete m_bmp;
+ if (m_bmpBase) delete m_bmpBase;
+ if (m_bmpAnimate) delete m_bmpAnimate;
+ mir_free(m_lpzText); mir_free(m_lpzTitle);
+ mir_free(m_lpwzText); mir_free(m_lpwzTitle);
+ if (m_mtText) MText.Destroy(m_mtText);
+ if (m_mtTitle) MText.Destroy(m_mtTitle);
+ if (m_avatar) delete m_avatar;
+ if (m_actions) delete [] m_actions;
+}
+
+void PopupWnd2::startThread()
+{
+ _beginthread(WindowThread, 0, this);
+}
+
+void PopupWnd2::create()
+{
+ m_hwnd = CreateWindowEx(
+ WS_EX_TRANSPARENT| // prevents unwanted clicks
+ WS_EX_TOOLWINDOW|WS_EX_TOPMOST, // dwStyleEx
+ _T(POPUP_WNDCLASS), // Class name
+ NULL, // Title
+ DS_SETFONT|DS_FIXEDSYS|WS_POPUP, // dwStyle
+ CW_USEDEFAULT, // x
+ CW_USEDEFAULT, // y
+ CW_USEDEFAULT, // Width
+ CW_USEDEFAULT, // Height
+ HWND_DESKTOP, // Parent
+ NULL, // menu handle
+ hInst, // Instance
+ (LPVOID)this);
+
+ // Shadows
+ if (IsWinVerXPPlus())
+ {
+ ULONG_PTR style = GetClassLongPtr(m_hwnd, GCL_STYLE);
+ if (m_options->DropShadow && !(style & CS_DROPSHADOW)) {
+ style |= CS_DROPSHADOW;
+ }
+ else if (!m_options->DropShadow && (style & CS_DROPSHADOW)){
+ style &= ~CS_DROPSHADOW;
+ }
+ SetClassLongPtr(m_hwnd, GCL_STYLE, style);
+ }
+
+ // tooltips
+ m_hwndToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ m_hwnd, NULL, hInst, NULL);
+ SetWindowPos(m_hwndToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ m_bWindowCreated = true;
+ update();
+}
+
+void PopupWnd2::updateLayered(BYTE opacity)
+{
+ if (!m_hwnd) return;
+#if defined(_UNICODE)
+ if (SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(m_hwnd, GWL_EXSTYLE) | WS_EX_LAYERED)) {
+ RECT rc; GetWindowRect(m_hwnd, &rc);
+ POINT ptDst = {rc.left, rc.top};
+ POINT ptSrc = {0, 0};
+
+ BLENDFUNCTION blend;
+ blend.BlendOp = AC_SRC_OVER;
+ blend.BlendFlags = 0;
+ blend.SourceConstantAlpha = opacity; //m_options->UseTransparency ? opacity : 255;
+ blend.AlphaFormat = AC_SRC_ALPHA;
+
+ UpdateLayeredWindow(m_hwnd, NULL, &ptDst, &m_sz,
+ m_bmpAnimate ? m_bmpAnimate->getDC() : m_bmp->getDC(),
+ &ptSrc, 0xffffffff, &blend, ULW_ALPHA);
+
+ UpdateWindow(m_hwnd);
+ }
+#else
+ if (MyUpdateLayeredWindow) {
+ if (SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(m_hwnd, GWL_EXSTYLE) | WS_EX_LAYERED))
+ {
+ RECT rc; GetWindowRect(m_hwnd, &rc);
+ POINT ptDst = {rc.left, rc.top};
+ POINT ptSrc = {0, 0};
+
+ BLENDFUNCTION blend;
+ blend.BlendOp = AC_SRC_OVER;
+ blend.BlendFlags = 0;
+ blend.SourceConstantAlpha = opacity; //m_options->UseTransparency ? opacity : 255;
+ blend.AlphaFormat = AC_SRC_ALPHA;
+
+ MyUpdateLayeredWindow(m_hwnd, NULL, &ptDst, &m_sz,
+ m_bmpAnimate ? m_bmpAnimate->getDC() : m_bmp->getDC(),
+ &ptSrc, 0xffffffff, &blend, ULW_ALPHA);
+
+ UpdateWindow(m_hwnd);
+ }
+ }
+#endif
+}
+
+SIZE PopupWnd2::measure()
+{
+ const PopupSkin *skin = skins.getSkin(m_lpzSkin?m_lpzSkin:m_options->SkinPack);
+ if (!skin) return m_sz;
+
+ MyBitmap bmpTmp(1,1);
+ skin->measure(bmpTmp.getDC(), this, m_options->UseMaximumWidth ? m_options->MaximumWidth : SETTING_MAXIMUMWIDTH_MAX, m_options);
+ return m_sz;
+}
+
+void PopupWnd2::update()
+{
+ const PopupSkin *skin = skins.getSkin(m_lpzSkin?m_lpzSkin:m_options->SkinPack);
+ if (!skin) return;
+
+ // update avatar
+ fixAvatar();
+
+ // destroy content bitmap so animate() can reallocate it if needed
+ if (m_bmp)
+ {
+ delete m_bmp;
+ m_bmp = NULL;
+ }
+
+ // measure popup
+ if (m_bmpBase) delete m_bmpBase;
+ if (m_bmpAnimate) delete m_bmpAnimate;
+ m_bmpBase = new MyBitmap(1,1);
+ skin->measure(m_bmpBase->getDC(), this, m_options->UseMaximumWidth ? m_options->MaximumWidth : SETTING_MAXIMUMWIDTH_MAX, m_options);
+
+ // render popup
+ m_bmpBase->allocate(m_sz.cx, m_sz.cy);
+ HDC hdc = m_bmpBase->getDC();
+ if (!skin) return;
+ SetBkMode(hdc, TRANSPARENT);
+ skin->display(m_bmpBase, this, m_options->UseMaximumWidth ? m_options->MaximumWidth : SETTING_MAXIMUMWIDTH_MAX, m_options,
+ PopupSkin::DF_STATIC);
+ if (*m_time && skin->useInternalClock())
+ {
+ SetTextColor(hdc, m_clClock);
+ HFONT hfnSave = (HFONT)SelectObject(m_bmpBase->getDC(), fonts.clock);
+ SIZE sz; GetTextExtentPoint32A(m_bmpBase->getDC(), m_time, lstrlenA(m_time), &sz);
+ m_bmpBase->Draw_TextA(m_time, this->m_sz.cx - sz.cx - STYLE_SZ_GAP - skin->getRightGap(), STYLE_SZ_GAP);
+ SelectObject(m_bmpBase->getDC(), hfnSave);
+ }
+
+ m_bReshapeWindow = true;
+
+ animate();
+}
+
+void PopupWnd2::animate()
+{
+ const PopupSkin *skin = skins.getSkin(m_lpzSkin?m_lpzSkin:m_options->SkinPack);
+ if (!skin) return;
+
+ if (m_avatar->isAnimated() || m_actionCount)
+ {
+ if (!m_bmp) m_bmp = new MyBitmap(m_bmpBase->getWidth(), m_bmpBase->getHeight());
+ m_bmp->Draw(m_bmpBase, 0, 0, m_bmpBase->getWidth(), m_bmpBase->getHeight());
+ skin->display(m_bmp, this, m_options->UseMaximumWidth ? m_options->MaximumWidth : SETTING_MAXIMUMWIDTH_MAX, m_options, PopupSkin::DF_ANIMATE);
+ } else
+ if (m_bmpBase)
+ {
+ if (m_bmp) delete m_bmp;
+ m_bmp = m_bmpBase;
+ m_bmpBase = NULL;
+ }
+
+ // update layered window if supported
+ updateLayered((m_options->UseTransparency && !(m_bIsHovered && m_options->OpaqueOnHover)) ? m_options->Alpha : 255);
+
+ if (m_bReshapeWindow)
+ {
+ m_bReshapeWindow = false;
+#if defined(_UNICODE)
+ if (m_hwnd && m_bmp && m_options->DropShadow && PopUpOptions.EnableFreeformShadows /*DoWeNeedRegionForThisSkin()*/)
+ SetWindowRgn(m_hwnd, m_bmp->buildOpaqueRgn(skin->getShadowRegionOpacity()), FALSE);
+#else
+ if (!MyUpdateLayeredWindow && m_hwnd && m_bmp && PopUpOptions.Enable9xTransparency)
+ SetWindowRgn(m_hwnd, m_bmp->buildOpaqueRgn(skin->getLegacyRegionOpacity()), FALSE);
+
+ if (MyUpdateLayeredWindow && m_hwnd && m_bmp && m_options->DropShadow && PopUpOptions.EnableFreeformShadows /*DoWeNeedRegionForThisSkin()*/)
+ SetWindowRgn(m_hwnd, m_bmp->buildOpaqueRgn(skin->getShadowRegionOpacity()), FALSE);
+#endif
+
+ if (MyDwmEnableBlurBehindWindow && PopUpOptions.EnableAeroGlass)
+ {
+ DWM_BLURBEHIND bb = {0};
+ bb.dwFlags = DWM_BB_ENABLE|DWM_BB_BLURREGION;
+ bb.fEnable = TRUE;
+ bb.hRgnBlur = m_bmp->buildOpaqueRgn(254, false);
+ MyDwmEnableBlurBehindWindow(m_hwnd, &bb);
+ }
+
+ // update tooltips
+ for (int i = 0; i < m_actionCount; ++i)
+ {
+ char *title = strchr(m_actions[i].actionA.lpzTitle, '/');
+ if (title) title++;
+ else title = m_actions[i].actionA.lpzTitle;
+ AddTooltipTranslated(m_hwndToolTip, m_hwnd, i, m_actions[i].rc, title);
+ }
+
+// if (!customPopup && hwnd /*&& IsWindowVisible(hwnd)*/)
+// PopupThreadUpdateWindow(this);
+ }
+}
+
+void PopupWnd2::show()
+{
+ if ((m_options->UseEffect || (m_options->UseAnimations && !m_customPopup)) && m_options->FadeIn)
+ {
+ IPopupPlusEffect *effect = NULL;
+ m_bSlide = m_bFade = false;
+ DWORD dwTime, dwTime0 = GetTickCount();
+ DWORD dwTime1 = dwTime0 + m_options->FadeIn;
+ if (m_options->UseEffect)
+ {
+ m_bFade = true;
+ m_btAlpha0 = 0;
+ m_btAlpha1 = m_options->UseTransparency ? m_options->Alpha : 255;
+ updateLayered(m_btAlpha0);
+
+ if (*PopUpOptions.Effect)
+ {
+ char vfxService[128];
+ mir_snprintf(vfxService, sizeof(vfxService), "PopUp/Vfx/"TCHAR_STR_PARAM, PopUpOptions.Effect);
+ if (ServiceExists(vfxService))
+ if (effect = (IPopupPlusEffect *)CallService(vfxService, 0, 0))
+ {
+ effect->beginEffect(m_bmp->getWidth(), m_bmp->getHeight(), m_btAlpha0, m_btAlpha1, dwTime1-dwTime0);
+ m_bmpAnimate = new MyBitmap(m_bmp->getWidth(), m_bmp->getHeight());
+ }
+ }
+ } else
+ {
+ updateLayered(m_options->UseTransparency ? m_options->Alpha : 255);
+ }
+ if (m_options->UseAnimations && !m_customPopup)
+ {
+ m_bSlide = true;
+ m_ptPosition0 = m_pos;
+ m_ptPosition1 = m_pos;
+ if (m_options->Position == POS_LOWERLEFT || m_options->Position == POS_UPPERLEFT)
+ m_ptPosition0.x -= m_sz.cx + 2 * 5;
+ else
+ m_ptPosition0.x += m_sz.cx + 2 * 5;
+ SetWindowPos(m_hwnd, 0, m_ptPosition0.x, m_ptPosition0.y, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ } else
+ {
+ SetWindowPos(m_hwnd, 0, m_pos.x, m_pos.y, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ }
+ while ((dwTime = GetTickCount()) < dwTime1)
+ {
+ if (m_bFade)
+ {
+ if (effect)
+ {
+ effect->beginFrame(dwTime - dwTime0);
+ m_bmpAnimate->Draw(m_bmp, 0, 0, m_bmp->getWidth(), m_bmp->getHeight());
+ for (int row = 0; row < m_bmpAnimate->getHeight(); ++row)
+ {
+ unsigned char *pixel = (unsigned char *)m_bmpAnimate->getRow(row);
+ for (int col = 0; col < m_bmpAnimate->getWidth(); ++col)
+ {
+ WORD alphaLevel = effect->getPixelAlpha(col, row);
+ pixel[0] = (pixel[0] * alphaLevel) >> 8;
+ pixel[1] = (pixel[1] * alphaLevel) >> 8;
+ pixel[2] = (pixel[2] * alphaLevel) >> 8;
+ pixel[3] = (pixel[3] * alphaLevel) >> 8;
+ pixel += 4;
+ }
+ }
+ effect->endFrame();
+ updateLayered(255);
+ } else
+ {
+ updateLayered(m_btAlpha0 + (m_btAlpha1 - m_btAlpha0) * int(dwTime - dwTime0) / m_options->FadeIn);
+ }
+ }
+ if (m_bSlide)
+ SetWindowPos(m_hwnd, 0,
+ (int)m_ptPosition0.x + ((int)m_ptPosition1.x - (int)m_ptPosition0.x) * int(dwTime - dwTime0) / (int)m_options->FadeIn,
+ (int)m_ptPosition0.y + ((int)m_ptPosition1.y - (int)m_ptPosition0.y) * int(dwTime - dwTime0) / (int)m_options->FadeIn,
+ 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ UpdateWindow(m_hwnd);
+ Sleep(1);
+ }
+
+ if (effect)
+ {
+ effect->endEffect();
+ effect->destroy();
+ delete m_bmpAnimate;
+ m_bmpAnimate = NULL;
+ }
+ }
+
+ m_bSlide = m_bFade = false;
+
+ updateLayered((m_options->UseTransparency && !(m_bIsHovered && m_options->OpaqueOnHover)) ? m_options->Alpha : 255);
+ //updateLayered(m_options->UseTransparency ? m_options->Alpha : 255);
+ SetWindowPos(m_hwnd, 0, m_pos.x, m_pos.y, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+}
+
+void PopupWnd2::hide()
+{
+ if ((m_options->UseEffect || (m_options->UseAnimations && !m_customPopup)) && m_options->FadeOut)
+ {
+ m_bDestroy = true;
+ IPopupPlusEffect *effect = NULL;
+ m_bFade = m_bSlide = false;
+ DWORD dwTime, dwTime0 = GetTickCount();
+ DWORD dwTime1 = dwTime0 + m_options->FadeOut;
+ if (m_options->UseEffect)
+ {
+ m_bFade = true;
+ m_btAlpha0 = m_options->UseTransparency ? m_options->Alpha : 255;
+ m_btAlpha1 = 0;
+ updateLayered(m_btAlpha0);
+
+ if (*PopUpOptions.Effect)
+ {
+ char vfxService[128];
+ mir_snprintf(vfxService, sizeof(vfxService), "PopUp/Vfx/"TCHAR_STR_PARAM, PopUpOptions.Effect);
+ if (ServiceExists(vfxService))
+ if (effect = (IPopupPlusEffect *)CallService(vfxService, 0, 0))
+ {
+ effect->beginEffect(m_bmp->getWidth(), m_bmp->getHeight(), m_btAlpha0, m_btAlpha1, dwTime1-dwTime0);
+ m_bmpAnimate = new MyBitmap(m_bmp->getWidth(), m_bmp->getHeight());
+ }
+ }
+ }
+ if (m_options->UseAnimations && !m_customPopup)
+ {
+ m_bSlide = true;
+ m_ptPosition0 = m_pos;
+ m_ptPosition1 = m_pos;
+ if (m_options->Position == POS_LOWERLEFT || m_options->Position == POS_UPPERLEFT)
+ m_ptPosition1.x -= m_sz.cx + 2 * 5;
+ else
+ m_ptPosition1.x += m_sz.cx + 2 * 5;
+ SetWindowPos(m_hwnd, 0, m_ptPosition0.x, m_ptPosition0.y, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ }
+ while ((dwTime = GetTickCount()) < dwTime1)
+ {
+ if (m_bFade)
+ {
+ if (effect)
+ {
+ effect->beginFrame(dwTime - dwTime0);
+ m_bmpAnimate->Draw(m_bmp, 0, 0, m_bmp->getWidth(), m_bmp->getHeight());
+ for (int row = 0; row < m_bmpAnimate->getHeight(); ++row)
+ {
+ unsigned char *pixel = (unsigned char *)m_bmpAnimate->getRow(row);
+ for (int col = 0; col < m_bmpAnimate->getWidth(); ++col)
+ {
+ WORD alphaLevel = effect->getPixelAlpha(col, row);
+ pixel[0] = (pixel[0] * alphaLevel) >> 8;
+ pixel[1] = (pixel[1] * alphaLevel) >> 8;
+ pixel[2] = (pixel[2] * alphaLevel) >> 8;
+ pixel[3] = (pixel[3] * alphaLevel) >> 8;
+ pixel += 4;
+ }
+ }
+ effect->endFrame();
+ updateLayered(255);
+ } else
+ {
+ updateLayered((int)m_btAlpha0 + ((int)m_btAlpha1 - (int)m_btAlpha0) * int(dwTime - dwTime0) / (int)m_options->FadeOut);
+ }
+ }
+ if (m_bSlide)
+ SetWindowPos(m_hwnd, 0,
+ (int)m_ptPosition0.x + ((int)m_ptPosition1.x - (int)m_ptPosition0.x) * int(dwTime - dwTime0) / (int)m_options->FadeOut,
+ (int)m_ptPosition0.y + ((int)m_ptPosition1.y - (int)m_ptPosition0.y) * int(dwTime - dwTime0) / (int)m_options->FadeOut,
+ 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_SHOWWINDOW);
+ UpdateWindow(m_hwnd);
+ Sleep(1);
+ }
+
+ if (effect)
+ {
+ effect->endEffect();
+ effect->destroy();
+ delete m_bmpAnimate;
+ m_bmpAnimate = NULL;
+ }
+ }
+
+ SetWindowPos(m_hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_HIDEWINDOW);
+ DestroyWindow(m_hwnd);
+// hwnd = 0;
+}
+
+bool __forceinline isTextEmpty(char *text)
+{
+ if (!text)
+ return true;
+ while (*text)
+ if (!isspace(BYTE(*text++)))
+ return false;
+ return true;
+}
+
+bool __forceinline isTextEmpty(WCHAR *text)
+{
+ if (!text)
+ return true;
+ while (*text)
+ if (!iswspace(*text++))
+ return false;
+ return true;
+}
+
+void PopupWnd2::fixDefaults()
+{
+ if (m_options->UseWinColors)
+ {
+ m_clBack = GetSysColor(COLOR_BTNFACE);
+ m_clText = GetSysColor(COLOR_WINDOWTEXT);
+ m_clTitle = GetSysColor(COLOR_WINDOWTEXT);
+ m_clClock = GetSysColor(COLOR_WINDOWTEXT);
+ } else
+ if ((m_clBack == (COLORREF)NULL) && (m_clText == (COLORREF)NULL))
+ {
+ m_clTitle = fonts.clTitle;
+ m_clBack = fonts.clBack;
+ m_clText = fonts.clText;
+ m_clClock = fonts.clClock;
+ } else
+ {
+ m_clClock = m_clTitle;
+ }
+
+ if (!m_iTimeout)
+ {
+ m_iTimeout = m_options->InfiniteDelay ? -1 : m_options->Seconds;
+ }
+
+ m_hContactPassed = m_hContact;
+ if (m_hContact)
+ {
+ if (!CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)m_hContact, 0))
+ m_hContact = NULL;
+ }
+
+ switch (m_textType)
+ {
+ case TT_ANSI:
+ m_bTextEmpty = ::isTextEmpty(m_lpzText);
+ break;
+
+ case TT_UNICODE:
+ m_bTextEmpty = ::isTextEmpty(m_lpwzText);
+ break;
+
+ default:
+ m_bTextEmpty = false;
+ break;
+ }
+}
+
+void PopupWnd2::fixAvatar()
+{
+ if (m_avatar && !m_avatar->isValid())
+ delete m_avatar;
+
+ if (m_hbmAvatar)
+ {
+ m_avatar = new SimpleAvatar(m_hbmAvatar, true);
+ } else
+ {
+ m_avatar = PopupAvatar::create(m_hContact);
+ }
+}
+
+int PopupWnd2::fixActions(POPUPACTION *theActions, int count)
+{
+ bool isIm = (m_hContact &&
+ (CallProtoService(
+ (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)m_hContact, 0),
+ PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM)) ? true : false;
+
+// bool enableDefault = (isIm || !(PopUpOptions.actions&ACT_DEF_IMONLY)) ? true : false;
+ bool enableDefaultGen = (m_hContact || !(PopUpOptions.actions&ACT_DEF_NOGLOBAL)) ? true : false;
+ bool enableDefaultUsr = (isIm || m_hContact && !(PopUpOptions.actions&ACT_DEF_IMONLY)) ? true : false;
+ bool iconSize = PopUpOptions.actions&ACT_LARGE ? TRUE : FALSE;
+
+ if (PopUpOptions.actions&ACT_ENABLE)
+ {
+ if (enableDefaultUsr && isIm && IsActionEnabled("General/Quick reply")) ++m_actionCount;
+ if (enableDefaultUsr && isIm && IsActionEnabled("General/Send message")) ++m_actionCount;
+ if (enableDefaultUsr && IsActionEnabled("General/User details")) ++m_actionCount;
+ if (enableDefaultUsr && IsActionEnabled("General/Contact menu")) ++m_actionCount;
+ if (enableDefaultUsr && DBGetContactSettingByte(m_hContact, "CList", "NotOnList", 0) && IsActionEnabled("General/Add permanently")) ++m_actionCount;
+ if (enableDefaultGen && (m_iTimeout != -1) && IsActionEnabled("General/Pin popup")) ++m_actionCount;
+ if (enableDefaultGen && IsActionEnabled("General/Dismiss popup")) ++m_actionCount;
+ if (enableDefaultGen && IsActionEnabled("General/Copy to clipboard")) ++m_actionCount;
+
+ int iAction = fixActions(theActions, count, m_actionCount);
+
+ if (enableDefaultUsr && isIm && IsActionEnabled("General/Quick reply"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_REPLY,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Quick reply");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_REPLY;
+ ++iAction;
+ }
+ if (enableDefaultUsr && isIm && IsActionEnabled("General/Send message"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_MESS,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Send message");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_MESSAGE;
+ ++iAction;
+ }
+ if (enableDefaultUsr && IsActionEnabled("General/User details"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_INFO,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/User details");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_DETAILS;
+ ++iAction;
+ }
+ if (enableDefaultUsr && IsActionEnabled("General/Contact menu"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_MENU,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Contact menu");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_MENU;
+ ++iAction;
+ }
+ if (enableDefaultUsr && DBGetContactSettingByte(m_hContact, "CList", "NotOnList", 0) && IsActionEnabled("General/Add permanently"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_ADD,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Add permanently");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_ADD;
+ ++iAction;
+ }
+ if (enableDefaultGen && (m_iTimeout != -1) && IsActionEnabled("General/Pin popup"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = m_bIsPinned ? IcoLib_GetIcon(ICO_ACT_PINNED,iconSize) : IcoLib_GetIcon(ICO_ACT_PIN,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Pin popup");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_PIN;
+ ++iAction;
+ }
+ if (enableDefaultGen && IsActionEnabled("General/Dismiss popup"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_CLOSE,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Dismiss popup");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_DISMISS;
+ ++iAction;
+ }
+ if (enableDefaultGen && IsActionEnabled("General/Copy to clipboard"))
+ {
+ m_actions[iAction].actionA.cbSize = sizeof(POPUPACTION);
+ m_actions[iAction].actionA.lchIcon = IcoLib_GetIcon(ICO_ACT_COPY,iconSize);
+ lstrcpyA(m_actions[iAction].actionA.lpzTitle, "General/Copy to clipboard");
+ m_actions[iAction].actionA.wParam = 0;
+ m_actions[iAction].actionA.lParam = ACT_DEF_COPY;
+ ++iAction;
+ }
+ }
+
+ return m_actionCount;
+}
+
+int PopupWnd2::fixActions(POPUPACTION *theActions, int count, int additional)
+{
+ m_actionCount = 0;
+ if (m_actions) delete [] m_actions;
+ m_actions = NULL;
+
+ int i;
+
+ m_actionCount = additional;
+ for (i = 0; i < count; ++i)
+ if ((theActions[i].flags&PAF_ENABLED) && IsActionEnabled(&theActions[i]))
+ ++m_actionCount;
+
+ m_actions = new ActionInfo[m_actionCount];
+ int iAction = 0;
+
+ for (i = 0; i < count; ++i)
+ if ((theActions[i].flags&PAF_ENABLED) && IsActionEnabled(&theActions[i]))
+ {
+ m_actions[iAction].actionA = theActions[i];
+ ++iAction;
+ }
+
+ return iAction;
+}
+
+void PopupWnd2::updateData(POPUPDATA *ppd)
+{
+ m_hContact = ppd->lchContact;
+
+ m_clBack = ppd->colorBack;
+ m_clClock = m_clTitle = m_clText = ppd->colorText;
+ m_iTimeout = m_options->DisplayTime;
+
+ mir_free(m_lpzText); mir_free(m_lpzTitle);
+ mir_free(m_lpwzText); mir_free(m_lpwzTitle);
+ if (m_textType == TT_NONE) m_textType = TT_ANSI;
+ m_lpzTitle = mir_strdup(ppd->lpzContactName);
+ m_lpzText = mir_strdup(ppd->lpzText);
+ m_lpwzTitle = m_lpwzText = NULL;
+// mtTitle = mtText = NULL;
+ // hfnTitle, hfnText;
+ m_hIcon = ppd->lchIcon;
+
+ m_PluginData = ppd->PluginData;
+ m_PluginWindowProc = ppd->PluginWindowProc;
+
+ if (m_options->DisplayTime)
+ GetTimeFormatA(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm", m_time, SIZEOF(m_time));
+ else m_time[0] = 0;
+
+ fixDefaults();
+
+ if (m_textType == TT_MTEXT) buildMText();
+}
+
+void PopupWnd2::updateData(POPUPDATAEX_V2 *ppd)
+{
+ m_hContact = ppd->lchContact;
+
+ m_clBack = ppd->colorBack;
+ m_clClock = m_clTitle = m_clText = ppd->colorText;
+ m_iTimeout = ppd->iSeconds ? ppd->iSeconds : m_options->Seconds;
+
+ if (m_textType == TT_NONE) m_textType = TT_ANSI;
+ mir_free(m_lpzText); mir_free(m_lpzTitle);
+ mir_free(m_lpwzText); mir_free(m_lpwzTitle);
+ m_lpzTitle = mir_strdup(ppd->lpzContactName);
+ m_lpzText = mir_strdup(ppd->lpzText);
+ m_lpwzTitle = m_lpwzText = NULL;
+// mtTitle = mtText = NULL;
+ // hfnTitle, hfnText;
+ m_hIcon = ppd->lchIcon;
+ m_hNotification = ppd->hNotification;
+
+ m_PluginData = ppd->PluginData;
+ m_PluginWindowProc = ppd->PluginWindowProc;
+
+ if (m_options->DisplayTime)
+ GetTimeFormatA(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm", m_time, SIZEOF(m_time));
+ else m_time[0] = 0;
+
+ fixDefaults();
+ fixActions(ppd->lpActions, ppd->actionCount);
+
+ if (m_textType == TT_MTEXT) buildMText();
+}
+
+void PopupWnd2::updateData(POPUPDATAW_V2 *ppd)
+{
+ m_hContact = ppd->lchContact;
+
+ m_clBack = ppd->colorBack;
+ m_clClock = m_clTitle = m_clText = ppd->colorText;
+ m_iTimeout = ppd->iSeconds ? ppd->iSeconds : m_options->Seconds;
+
+ if (m_textType == TT_NONE) m_textType = TT_UNICODE;
+ mir_free(m_lpzText); mir_free(m_lpzTitle);
+ mir_free(m_lpwzText); mir_free(m_lpwzTitle);
+ m_lpzTitle = m_lpzText = NULL;
+ m_lpwzTitle = mir_wstrdup(ppd->lpwzContactName);
+ m_lpwzText = mir_wstrdup(ppd->lpwzText);
+// mtTitle = mtText = NULL;
+ // hfnTitle, hfnText;
+ m_hIcon = ppd->lchIcon;
+ m_hNotification = ppd->hNotification;
+
+ m_PluginData = ppd->PluginData;
+ m_PluginWindowProc = ppd->PluginWindowProc;
+
+ if (m_options->DisplayTime)
+ GetTimeFormatA(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm", m_time, SIZEOF(m_time));
+ else m_time[0] = 0;
+
+ fixDefaults();
+ fixActions(ppd->lpActions, ppd->actionCount);
+
+ if (m_textType == TT_MTEXT) buildMText();
+}
+
+void PopupWnd2::updateData(POPUPDATA2 *ppd)
+{
+ m_hContact = ppd->lchContact;
+
+ m_clBack = ppd->colorBack;
+ m_clClock = m_clTitle = m_clText = ppd->colorText;
+ m_iTimeout = ppd->iSeconds;
+
+ mir_free(m_lpzText); mir_free(m_lpzTitle);
+ mir_free(m_lpwzText); mir_free(m_lpwzTitle);
+ if (ppd->flags&PU2_UNICODE)
+ {
+ if (m_textType == TT_NONE) m_textType = TT_UNICODE;
+ m_lpzTitle = m_lpzText = NULL;
+ m_lpwzTitle = mir_wstrdup(ppd->lpwzTitle);
+ m_lpwzText = mir_wstrdup(ppd->lpwzText);
+ m_lpzTitle = m_lpzText = NULL;
+ } else
+ {
+ if (m_textType == TT_NONE) m_textType = TT_ANSI;
+ m_lpzTitle = mir_strdup(ppd->lpzTitle);
+ m_lpzText = mir_strdup(ppd->lpzText);
+ m_lpwzTitle = m_lpwzText = NULL;
+ }
+
+ m_hIcon = ppd->lchIcon;
+ m_hNotification = ppd->lchNotification;
+
+ m_PluginData = ppd->PluginData;
+ m_PluginWindowProc = ppd->PluginWindowProc;
+ m_customPopup = (ppd->flags & PU2_CUSTOM_POPUP)!= 0;
+
+ m_hbmAvatar = ppd->hbmAvatar;
+ m_lpzSkin = mir_a2t(ppd->lpzSkin);
+
+ if (m_options->DisplayTime)
+ {
+ if (ppd->dwTimestamp)
+ {
+ DBTIMETOSTRING dbtts;
+ dbtts.szFormat = "t";
+ dbtts.szDest = m_time;
+ dbtts.cbDest = SIZEOF(m_time);
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ppd->dwTimestamp, (LPARAM)&dbtts);
+ } else
+ {
+ GetTimeFormatA(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm", m_time, SIZEOF(m_time));
+ }
+ }
+ else m_time[0] = 0;
+
+ fixDefaults();
+ fixActions(ppd->lpActions, ppd->actionCount);
+
+ if (m_textType == TT_MTEXT) buildMText();
+}
+
+void PopupWnd2::buildMText()
+{
+ if (!(htuText && htuTitle && PopUpOptions.UseMText))
+ return;
+
+ if (m_mtText) MText.Destroy(m_mtText);
+ if (m_mtTitle)MText.Destroy(m_mtTitle);
+ m_mtText = m_mtTitle = NULL;
+
+ if (m_lpwzText && m_lpwzTitle) {
+ m_textType = TT_MTEXT;
+ m_mtText = MText.CreateW(htuText, m_lpwzText);
+ m_mtTitle = MText.CreateW(htuTitle,m_lpwzTitle);
+ }
+ else if (m_lpzText && m_lpzTitle) {
+ m_textType = TT_MTEXT;
+ if (ServiceExists(MS_TEXT_CREATEW)) {
+ LOGFONT lf;
+ LPWSTR lpwzBuf = NULL;
+
+ GetObject(m_hfnText, sizeof(lf), &lf);
+ lpwzBuf = mir_a2u(m_lpzText);
+ m_mtText = MText.CreateW(htuText, lpwzBuf);
+ mir_free(lpwzBuf); lpwzBuf = NULL;
+
+ GetObject(m_hfnTitle, sizeof(lf), &lf);
+ lpwzBuf = mir_a2u(m_lpzTitle);
+ m_mtTitle = MText.CreateW(htuTitle, lpwzBuf);
+ mir_free(lpwzBuf); lpwzBuf = NULL;
+ }
+ else {
+ m_mtText = MText.Create(htuText, m_lpzText);
+ m_mtTitle = MText.Create(htuTitle,m_lpzTitle);
+ }
+ }
+}
+
+void PopupWnd2::updateText(char *text)
+{
+ if (m_lpzText)
+ {
+ mir_free(m_lpzText);
+ m_lpzText = mir_strdup(text);
+ if (m_textType == TT_MTEXT)
+ buildMText();
+ }
+ m_bTextEmpty = ::isTextEmpty(m_lpzText);
+}
+
+void PopupWnd2::updateText(WCHAR *text)
+{
+ if (m_lpwzText)
+ {
+ mir_free(m_lpwzText);
+ m_lpwzText = mir_wstrdup(text);
+ if (m_textType == TT_MTEXT)
+ buildMText();
+ }
+ m_bTextEmpty = ::isTextEmpty(m_lpwzText);
+}
+
+void PopupWnd2::updateTitle(char *title)
+{
+ if (m_lpzTitle)
+ {
+ mir_free(m_lpzTitle);
+ m_lpzTitle = mir_strdup(title);
+ if (m_textType == TT_MTEXT)
+ buildMText();
+ }
+}
+
+void PopupWnd2::updateTitle(WCHAR *title)
+{
+ if (m_lpwzTitle)
+ {
+ mir_free(m_lpwzTitle);
+ m_lpwzTitle = mir_wstrdup(title);
+ if (m_textType == TT_MTEXT)
+ buildMText();
+ }
+}
+
+void PopupWnd2::updateTimer()
+{
+ KillTimer(m_hwnd, POPUP_TIMER);
+ if (m_iTimeout > 0)
+ SetTimer(m_hwnd, POPUP_TIMER, 1000, 0);
+}
+
+LRESULT CALLBACK NullWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_COMMAND:
+ case WM_CONTEXTMENU:
+ PUDeletePopUp(hwnd);
+ break;
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+struct ReplyEditData
+{
+ HWND hwndPopup;
+ HANDLE hContact;
+ WNDPROC oldWndProc;
+};
+
+bool IsMsgServiceNameW(HANDLE hContact) {
+ if (g_popup.isMirUnicode) {
+ char szServiceName[100];
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto == NULL)
+ return false;
+
+ mir_snprintf(szServiceName, sizeof(szServiceName), "%s%sW", szProto, PSS_MESSAGE);
+ if (ServiceExists(szServiceName))
+ return true;
+ }
+ return false;
+}
+
+BOOL IsUtfSendAvailable(HANDLE hContact)
+{
+ char* szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if(szProto == NULL) return FALSE;
+ //check for MetaContact and get szProto from subcontact
+ if(strcmp(szProto, gszMetaProto)==0) {
+ HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT, (WPARAM)hContact, 0);
+ if(!hSubContact) return FALSE;
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hSubContact, 0);
+ }
+ return(CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDUTF) ? TRUE : FALSE;
+}
+
+void AddMessageToDB(HANDLE hContact, char *msg, int flag/*bool utf*/)
+{
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT | ((flag&PREF_UTF)==PREF_UTF ? DBEF_UTF : 0);
+ dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ dbei.timestamp = time(NULL);
+ if(g_popup.isOsUnicode && !((flag&PREF_UTF)==PREF_UTF) && (flag&PREF_UNICODE)==PREF_UNICODE)
+ dbei.cbBlob = (lstrlenW((LPWSTR)msg) + 1)*sizeof(WCHAR/*TCHAR*/);
+ else
+ dbei.cbBlob = lstrlenA(msg) + 1;
+ dbei.pBlob = (PBYTE)msg;
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+}
+
+LRESULT CALLBACK ReplyEditWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ ReplyEditData *dat = (ReplyEditData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ WNDPROC oldWndProc = dat ? dat->oldWndProc : NULL;
+
+ switch (message)
+ {
+/*
+ case WM_ERASEBKGND:
+ {
+ HDC hdc = (HDC)wParam;
+ RECT rc; GetClientRect(hwnd, &rc);
+ FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
+ SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
+ DrawText(hdc, "Quick Reply", -1, &rc, DT_BOTTOM|DT_RIGHT|DT_SINGLELINE);
+ return TRUE;
+ }
+*/
+ case WM_KEYDOWN:
+ {
+ switch (wParam)
+ {
+ case VK_RETURN:
+ {
+ char *buf = NULL;
+ int flag = 0;
+ bool bSendW = IsMsgServiceNameW(dat->hContact);
+ //if (g_popup.isMirUnicode)
+ if (IsWindowUnicode(hwnd))
+ {
+ WCHAR msg[2048];
+ LPWSTR bufW = NULL;
+#if defined(_UNICODE)
+ SendMessageW(hwnd, WM_GETTEXT, SIZEOF(msg), (LPARAM)msg);
+#else
+ MySendMessageW(hwnd, WM_GETTEXT, SIZEOF(msg), (LPARAM)msg);
+#endif
+ if(wcslen(msg)==0){
+ DestroyWindow(hwnd);
+ return 0;
+ }
+ // we have unicode message, check if it is possible and reasonable to send it as unicode
+ if (IsUtfSendAvailable(dat->hContact)) {
+ buf = mir_utf8encodeW(msg);
+ flag = PREF_UTF;
+ }
+ else if(bSendW){
+ bufW = mir_wstrdup(msg) /*mir_tstrdup(msg)*/;
+ buf = (char*)bufW;
+ flag = PREF_UNICODE /*PREF_TCHAR*/;
+ }
+ else {
+ buf = mir_u2a(msg);
+ flag = 0;
+ }
+ }
+ else {
+ char msg[2048];
+ GetWindowTextA(hwnd, msg, SIZEOF(msg));
+ if(strlen(msg)==0){
+ DestroyWindow(hwnd);
+ return 0;
+ }
+ // we have message, check if it is possible and reasonable to send it as unicode
+ if ( IsUtfSendAvailable( dat->hContact )) {
+ buf = mir_utf8encode(msg);
+ flag = PREF_UTF;
+ }
+ else {
+ buf = mir_strdup(msg) /*mir_tstrdup(msg)*/;
+ flag = 0 /*PREF_TCHAR*/;
+ }
+ }
+
+ CallContactService(dat->hContact, bSendW ? (PSS_MESSAGE"W"):PSS_MESSAGE, flag, (LPARAM)buf);
+ AddMessageToDB(dat->hContact, buf, flag);
+ mir_free(buf);
+
+ DestroyWindow(hwnd);
+ return 0;
+ }
+ case VK_ESCAPE:
+ {
+ DestroyWindow(hwnd);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ case WM_ACTIVATE:
+ if (wParam == WA_INACTIVE)
+ DestroyWindow(hwnd);
+ break;
+
+ case WM_DESTROY:
+ PopupThreadUnlock();
+ if (!(PopUpOptions.actions&ACT_DEF_KEEPWND))
+ PUDeletePopUp(dat->hwndPopup);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)dat->oldWndProc);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
+ mir_free(dat);
+ }
+
+ if (oldWndProc)
+ {
+#if defined(_UNICODE)
+ return CallWindowProcW(oldWndProc, hwnd, message, wParam, lParam);
+#else
+ if (IsWindowUnicode(hwnd) && MyCallWindowProcW)
+ return MyCallWindowProcW(oldWndProc, hwnd, message, wParam, lParam);
+ return CallWindowProc(oldWndProc, hwnd, message, wParam, lParam);
+#endif
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+LRESULT CALLBACK PopupWnd2::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_CREATE:
+ {
+// show();
+ return DefWindowProc(m_hwnd, message, wParam, lParam);
+ break;
+ }
+
+ case UM_INITPOPUP:
+ {
+ if (!m_customPopup) PopupThreadAddWindow(this);
+ if (m_iTimeout > 0) SetTimer(m_hwnd, POPUP_TIMER, m_iTimeout*1000, 0);
+ if (m_hContact && !m_hbmAvatar && PopUpOptions.EnableAvatarUpdates)
+ m_hhkAvatarChanged = HookEventMessage(ME_AV_AVATARCHANGED, m_hwnd, UM_AVATARCHANGED);
+ if (m_avatar->activeFrameDelay() > 0) SetTimer(m_hwnd, AVATAR_TIMER, m_avatar->activeFrameDelay(), 0);
+
+ // prevent unwanted clicks, but allow wanted :)
+ GetCursorPos(&m_ptPrevCursor);
+ SetTimer(m_hwnd, CURSOR_TIMER, 500, NULL);
+
+ break;
+ }
+
+ case UM_POPUPSHOW:
+ {
+ POINT pt; pt.x = wParam; pt.y = lParam;
+ setPosition(pt);
+ show();
+ break;
+ }
+
+ case UM_AVATARCHANGED:
+ {
+ if ((HANDLE)wParam == m_hContact)
+ {
+ m_avatar->invalidate();
+ update();
+ if (m_avatar->activeFrameDelay() > 0) SetTimer(m_hwnd, AVATAR_TIMER, m_avatar->activeFrameDelay(), 0);
+ }
+ break;
+ }
+
+ case UM_POPUPACTION:
+ {
+ if (wParam != 0) break;
+ switch (lParam)
+ {
+ case ACT_DEF_MESSAGE:
+ CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)m_hContact, 0);
+ if (!(PopUpOptions.actions&ACT_DEF_KEEPWND))
+ PUDeletePopUp(m_hwnd);
+ break;
+
+ case ACT_DEF_REPLY:
+ {
+ if (!m_customPopup) PopupThreadLock();
+ //RECT rc = renderInfo.textRect;
+ //MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2);
+ RECT rc; GetWindowRect(m_hwnd, &rc);
+#if defined(_UNICODE)
+ HWND hwndEditBox = CreateWindowExW(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
+ g_wndClass.cPopupEditBox ? L"PopupEditBox" : L"EDIT",
+ NULL,
+ WS_BORDER|WS_POPUP|WS_VISIBLE|ES_AUTOVSCROLL|ES_LEFT|ES_MULTILINE|ES_NOHIDESEL|ES_WANTRETURN,
+ rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInst, NULL);
+#else
+ HWND hwndEditBox = 0;
+ if(MyCreateWindowExW && g_popup.isMirUnicode) {
+ //create unicode window only if miranda is unicode
+ //coz many protocol make trouble with unicode text on utf8 send inside ansi release
+ hwndEditBox = MyCreateWindowExW(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
+ g_wndClass.cPopupEditBox ? L"PopupEditBox" : L"EDIT",
+ NULL,
+ WS_BORDER|WS_POPUP|WS_VISIBLE|ES_AUTOVSCROLL|ES_LEFT|ES_MULTILINE|ES_NOHIDESEL|ES_WANTRETURN,
+ rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInst, NULL);
+ }
+ else {
+ hwndEditBox = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
+ g_wndClass.cPopupEditBox ? "PopupEditBox" : "EDIT",
+ NULL,
+ WS_BORDER|WS_POPUP|WS_VISIBLE|ES_AUTOVSCROLL|ES_LEFT|ES_MULTILINE|ES_NOHIDESEL|ES_WANTRETURN,
+ rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInst, NULL);
+ }
+#endif
+ ReplyEditData *dat = (ReplyEditData *)mir_alloc(sizeof(ReplyEditData));
+ dat->oldWndProc = (WNDPROC)GetWindowLongPtr(hwndEditBox, (LONG_PTR)GWLP_WNDPROC);
+ dat->hwndPopup = m_hwnd;
+ dat->hContact = m_hContact;
+ if(IsWindowUnicode(hwndEditBox)) {
+#if defined(_UNICODE)
+ SendMessageW(hwndEditBox, WM_SETFONT, (WPARAM)fonts.text, TRUE);
+#else
+ MySendMessageW(hwndEditBox, WM_SETFONT, (WPARAM)fonts.text, TRUE);
+#endif
+ SetWindowLongPtrW(hwndEditBox, GWLP_USERDATA, (LONG_PTR)dat);
+ SetWindowLongPtrW(hwndEditBox, GWLP_WNDPROC, (LONG_PTR)ReplyEditWndProc);
+ }
+ else {
+ SendMessageA(hwndEditBox, WM_SETFONT, (WPARAM)fonts.text, TRUE);
+ SetWindowLongPtrA(hwndEditBox, GWLP_USERDATA, (LONG_PTR)dat);
+ SetWindowLongPtrA(hwndEditBox, GWLP_WNDPROC, (LONG_PTR)ReplyEditWndProc);
+ }
+ SetFocus(hwndEditBox);
+ break;
+ }
+
+ case ACT_DEF_DETAILS:
+ CallServiceSync(MS_USERINFO_SHOWDIALOG, (WPARAM)m_hContact, 0);
+ if (!(PopUpOptions.actions&ACT_DEF_KEEPWND))
+ PUDeletePopUp(m_hwnd);
+ break;
+ case ACT_DEF_MENU:
+ {
+ lock();
+ PostMessage(ghwndMenuHost, UM_SHOWMENU, (WPARAM)m_hwnd, (LPARAM)m_hContact);
+ break;
+ }
+ case ACT_DEF_ADD:
+ {
+ ADDCONTACTSTRUCT acs = {0};
+ acs.handle = m_hContact;
+ acs.handleType = HANDLE_CONTACT;
+ acs.szProto = 0;
+ CallServiceSync(MS_ADDCONTACT_SHOW, NULL, (LPARAM)&acs);
+ if (!(PopUpOptions.actions&ACT_DEF_KEEPWND))
+ PUDeletePopUp(m_hwnd);
+ break;
+ }
+ case ACT_DEF_PIN:
+ {
+ if (m_bIsPinned)
+ {
+ SetTimer(m_hwnd, POPUP_TIMER, m_iTimeout*1000, NULL);
+ } else
+ {
+ KillTimer(m_hwnd, POPUP_TIMER);
+ }
+ m_bIsPinned = !m_bIsPinned;
+ bool iconSize = PopUpOptions.actions&ACT_LARGE ? TRUE : FALSE;
+ PUModifyActionIcon(m_hwnd, wParam, lParam, m_bIsPinned ? IcoLib_GetIcon(ICO_ACT_PINNED,iconSize) : IcoLib_GetIcon(ICO_ACT_PIN,iconSize));
+ break;
+ }
+ case ACT_DEF_DISMISS:
+ PUDeletePopUp(m_hwnd);
+ break;
+ case ACT_DEF_COPY:
+ {
+ #ifdef UNICODE
+ #define CF_TCHAR CF_UNICODETEXT
+ #else
+ #define CF_TCHAR CF_TEXT
+ #endif
+ HGLOBAL clipbuffer;
+ static TCHAR * buffer, *text;
+ char* sztext;
+ if ((this->m_lpwzText) || (this->m_lpwzTitle))
+ {
+ text = (TCHAR*)mir_alloc((_tcslen(this->m_lpwzText) + _tcslen(this->m_lpwzTitle)+3)*sizeof(TCHAR));
+ mir_sntprintf(text, _tcslen(this->m_lpwzText) + _tcslen(this->m_lpwzTitle)+3, _T("%s\n\n%s"), this->m_lpwzTitle, this->m_lpwzText);
+ }
+ else if ((this->m_lpzText) || (this->m_lpzTitle))
+ {
+ sztext = (char*)mir_alloc((lstrlenA(this->m_lpzText) + lstrlenA(this->m_lpzTitle)+3)*sizeof(char));
+ mir_snprintf(sztext, lstrlenA(this->m_lpzText) + lstrlenA(this->m_lpzTitle)+3, "%s\n\n%s", this->m_lpzTitle, this->m_lpzText);
+ text = mir_a2t(sztext);
+ }
+ OpenClipboard(m_hwnd);
+ EmptyClipboard();
+ clipbuffer = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (lstrlen(text)+1) * sizeof(TCHAR));
+ buffer = (TCHAR *)GlobalLock(clipbuffer);
+ lstrcpy(buffer, text);
+ GlobalUnlock(clipbuffer);
+ SetClipboardData(CF_TCHAR, clipbuffer);
+ CloseClipboard();
+ if (sztext)
+ mir_free(text);
+ PUDeletePopUp(m_hwnd);
+ break;
+ }
+ }
+ break;
+ }
+
+ case UM_POPUPMODIFYACTIONICON:
+ {
+ LPPOPUPACTIONID actionId = (LPPOPUPACTIONID)wParam;
+ for (int i = 0; i < m_actionCount; ++i)
+ if ((m_actions[i].actionA.wParam == actionId->wParam) &&
+ (m_actions[i].actionA.lParam == actionId->lParam))
+ {
+ m_actions[i].actionA.lchIcon = (HICON)lParam;
+ animate();
+ break;
+ }
+
+ break;
+ }
+
+ case UM_MENUDONE:
+ {
+ unlock();
+ if (!(PopUpOptions.actions&ACT_DEF_KEEPWND))
+ PUDeletePopUp(m_hwnd);
+ break;
+ }
+/*
+ case WM_WINDOWPOSCHANGED:
+ {
+ WINDOWPOS *wp = (WINDOWPOS *)lParam;
+ if (!bIsHovered)
+ {
+ RECT rc; SetRect(&rc, wp->x, wp->y, wp->x + wp->cx, wp->y + wp->cy);
+ GetCursorPos(&ptPrevCursor);
+
+ if (PtInRect(&rc, ptPrevCursor))
+ {
+ SetWindowLongPtr(hwnd, GWLP_EXSTYLE, GetWindowLongPtr(hwnd, GWLP_EXSTYLE) | WS_EX_TRANSPARENT);
+ SetTimer(hwnd, CURSOR_TIMER, 500, NULL);
+ }
+ }
+ break;
+ }
+*/
+ case WM_LBUTTONUP:
+ {
+ int i;
+ for (i = 0; i < m_actionCount; ++i)
+ if (m_actions[i].hover)
+ {
+ SendMessage(m_hwnd, UM_POPUPACTION, m_actions[i].actionA.wParam, m_actions[i].actionA.lParam);
+ break;
+ }
+
+ if (i == m_actionCount)
+ {
+ if(PopUpOptions.overrideLeft!=false && (m_hContact!=NULL || PopUpOptions.overrideLeft == 5 || PopUpOptions.overrideLeft == 6)){
+ switch (PopUpOptions.overrideLeft){
+ default:
+ case 1:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_MESSAGE); break;
+ case 2:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_REPLY); break;
+ case 3:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_DETAILS); break;
+ case 4:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_MENU); break;
+ case 5:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_DISMISS); break;
+ case 6:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_PIN); break;
+ case 7:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_COPY); break;
+ }
+ }else{
+ lock();
+ if (!PerformAction(m_hNotification, m_hwnd, message, wParam, lParam))
+ SendMessage(m_hwnd, WM_COMMAND, 0, 0);
+ unlock();
+ }
+ }
+ break;
+ }
+
+ case WM_MBUTTONUP:
+ {
+ if(PopUpOptions.overrideMiddle!=false && (m_hContact!=NULL || PopUpOptions.overrideMiddle == 5 || PopUpOptions.overrideMiddle == 6)){
+ switch (PopUpOptions.overrideMiddle){
+ default:
+ case 1:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_MESSAGE); break;
+ case 2:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_REPLY); break;
+ case 3:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_DETAILS); break;
+ case 4:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_MENU); break;
+ case 5:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_DISMISS); break;
+ case 6:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_PIN); break;
+ case 7:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_COPY); break;
+ }
+ }
+ break;
+ }
+
+ case WM_CONTEXTMENU:
+ {
+ if(PopUpOptions.overrideRight!=false && (m_hContact!=NULL || PopUpOptions.overrideRight == 5 || PopUpOptions.overrideRight == 6)){
+ switch (PopUpOptions.overrideRight){
+ default:
+ case 1:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_MESSAGE); break;
+ case 2:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_REPLY); break;
+ case 3:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_DETAILS); break;
+ case 4:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_MENU); break;
+ case 5:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_DISMISS); break;
+ case 6:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_PIN); break;
+ case 7:SendMessage(m_hwnd, UM_POPUPACTION,0, ACT_DEF_COPY); break;
+ }
+ return TRUE;
+ }else{
+ lock();
+ if (PerformAction(m_hNotification, m_hwnd, message, wParam, lParam))
+ {
+ unlock();
+ return TRUE;
+ }
+ unlock();
+ }
+ }
+/*
+ case WM_RBUTTONUP:
+ {
+ SendMessage(hwnd, WM_CONTEXTMENU, 0, 0);
+ break;
+ }
+*/
+ case WM_TIMER:
+ {
+ switch (wParam)
+ {
+ case POPUP_TIMER:
+ {
+ KillTimer(m_hwnd, POPUP_TIMER);
+ if (!m_customPopup)
+ {
+ PopupThreadRequestRemoveWindow(this);
+ } else
+ {
+ if (isLocked())
+ {
+ updateTimer();
+ } else
+ {
+ PostMessage(m_hwnd, WM_CLOSE, 0, 0);
+ }
+ }
+ break;
+ }
+
+ case AVATAR_TIMER:
+ {
+ int newDelay = m_avatar->activeFrameDelay();
+ animate();
+ if ((newDelay <= 0) || (newDelay != m_avatarFrameDelay)) KillTimer(m_hwnd, AVATAR_TIMER);
+ if (newDelay > 0) {
+ SetTimer(m_hwnd, AVATAR_TIMER, newDelay, 0);
+ m_avatarFrameDelay = newDelay;
+ }
+ break;
+ }
+
+ case CURSOR_TIMER:
+ {
+ POINT pt; GetCursorPos(&pt);
+ if (abs(pt.x-m_ptPrevCursor.x) + abs(pt.y-m_ptPrevCursor.y) > 4)
+ {
+ SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(m_hwnd, GWL_EXSTYLE) & ~WS_EX_TRANSPARENT);
+ KillTimer(m_hwnd, CURSOR_TIMER);
+ }
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case UM_DESTROYPOPUP:
+ {
+ KillTimer(m_hwnd, POPUP_TIMER);
+ KillTimer(m_hwnd, AVATAR_TIMER);
+ KillTimer(m_hwnd, CURSOR_TIMER);
+ PostMessage(m_hwnd, WM_CLOSE, 0, 0);
+ break;
+ }
+
+ case UM_CHANGEPOPUP:
+ {
+ switch (wParam)
+ {
+ case CPT_TEXT: updateText((char *)lParam); mir_free((void *)lParam); break;
+ case CPT_TEXTW: updateText((WCHAR *)lParam); mir_free((void *)lParam); break;
+ case CPT_TITLE: updateTitle((char *)lParam); mir_free((void *)lParam); break;
+ case CPT_TITLEW: updateTitle((WCHAR *)lParam); mir_free((void *)lParam); break;
+ case CPT_DATA: updateData((POPUPDATA *)lParam); mir_free((void *)lParam); break;
+ case CPT_DATAEX: updateData((POPUPDATAEX_V2 *)lParam); mir_free((void *)lParam); break;
+ case CPT_DATAW: updateData((POPUPDATAW_V2 *)lParam); mir_free((void *)lParam); break;
+ }
+ update();
+ break;
+ }
+
+ case UM_CALLMETHOD:
+ {
+ MethodPtr *method_copy = (MethodPtr *)wParam;
+ (this->*(*method_copy))(lParam);
+ delete method_copy;
+ break;
+ }
+
+ case WM_PAINT:
+ {
+ if (GetUpdateRect(m_hwnd, 0, FALSE))
+ {
+ PAINTSTRUCT ps;
+ HDC mydc = BeginPaint(m_hwnd, &ps);
+ BitBlt(mydc, 0, 0, m_sz.cx, m_sz.cy, m_bmp->getDC(), 0, 0, SRCCOPY);
+ EndPaint(m_hwnd, &ps);
+ return 0;
+ }
+ break;
+ }
+
+ case WM_PRINT:
+ case WM_PRINTCLIENT:
+ {
+ HDC mydc = (HDC)wParam;
+ BitBlt(mydc, 0, 0, m_sz.cx, m_sz.cy, m_bmp->getDC(), 0, 0, SRCCOPY);
+ break;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ const PopupSkin *skin = skins.getSkin(m_lpzSkin?m_lpzSkin:m_options->SkinPack);
+ if (skin)
+ if (skin->onMouseMove(this, LOWORD(lParam), HIWORD(lParam)))
+ animate();
+
+ if (m_bIsHovered) break;
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ tme.hwndTrack = m_hwnd;
+ _TrackMouseEvent(&tme);
+ if (!m_customPopup) PopupThreadLock();
+#if defined(_UNICODE)
+ if (m_options->OpaqueOnHover)
+ updateLayered(255);
+#else
+ if (MySetLayeredWindowAttributes && m_options->OpaqueOnHover)
+ updateLayered(255);
+#endif
+ m_bIsHovered = true;
+ break;
+ }
+ case WM_MOUSELEAVE:
+ {
+ const PopupSkin *skin = skins.getSkin(m_lpzSkin?m_lpzSkin:m_options->SkinPack);
+ if (skin)
+ if (skin->onMouseMove(this, LOWORD(lParam), HIWORD(lParam)))
+ animate();
+
+ if (!m_bIsHovered) break;
+#if defined(_UNICODE)
+ if (m_options->OpaqueOnHover)
+ updateLayered(m_options->UseTransparency ? m_options->Alpha : 255);
+#else
+ if (MySetLayeredWindowAttributes && m_options->OpaqueOnHover)
+ updateLayered(m_options->UseTransparency ? m_options->Alpha : 255);
+#endif
+ if (!m_customPopup) PopupThreadUnlock();
+ m_bIsHovered = false;
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ hide();
+ return TRUE;
+ }
+
+ case WM_DESTROY:
+ {
+ if (m_bIsHovered)
+ {
+ if (!m_customPopup) PopupThreadUnlock();
+ m_bIsHovered = false;
+ }
+ if (m_hhkAvatarChanged)
+ PopUp_UnhookEventAsync((WPARAM)m_hwnd, (LPARAM)m_hhkAvatarChanged);
+ SendMessage(m_hwnd, UM_FREEPLUGINDATA, 0, 0);
+ SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
+ m_hwnd = 0;
+
+ DestroyWindow(m_hwndToolTip);
+
+ if (!m_customPopup)
+ {
+ // we can't access "this" pointer after followint line!
+ PopupThreadRemoveWindow(this);
+ } else
+ {
+ delete this;
+ }
+
+ PostQuitMessage(0);
+ return TRUE;
+ }
+/*
+ case WM_WINDOWPOSCHANGING:
+// case WM_WINDOWPOSCHANGED:
+ {
+ WINDOWPOS *wp = (WINDOWPOS *)lParam;
+ wp->flags |= SWP_NOACTIVATE; // block focus stealing
+
+ if (!(wp->flags & SWP_NOZORDER))
+ {
+ if ((wp->hwndInsertAfter == HWND_BOTTOM) ||
+ (wp->hwndInsertAfter == HWND_NOTOPMOST) ||
+ (wp->hwndInsertAfter == HWND_TOP))
+ {
+ wp->hwndInsertAfter == HWND_TOPMOST;
+ } else
+ if (wp->hwndInsertAfter != HWND_TOPMOST)
+ {
+ HWND hwndAbove = GetWindow(wp->hwndInsertAfter, GW_HWNDPREV);
+ if (hwndAbove)
+ {
+ char buf[64];
+ GetClassName(hwndAbove, buf, sizeof(buf));
+ buf[sizeof(buf)-1] = 0;
+
+ if (lstrcmp(buf, POPUP_WNDCLASS))
+ wp->hwndInsertAfter == HWND_TOPMOST;
+ }
+ }
+ }
+
+ // this allows us to reduce message traffic
+ return 0;
+ }
+*/
+ }
+
+ if (m_PluginWindowProc && !closing)
+ {
+ lock();
+
+ // some plugins use cdecl instead of stdcall
+ // this is an attempt to fix them
+ BOOL result;
+
+ result = m_PluginWindowProc(this->m_hwnd, message, wParam, lParam);
+/*
+ DWORD esp_in, esp_out, esp_fixed;
+ __asm
+ {
+ push ecx
+ mov [esp_in], esp
+ push [lParam]
+ push [wParam]
+ push [message]
+ mov ecx, [this]
+ push [ecx+hwnd]
+ call [ecx+PluginWindowProc]
+ mov [result], eax
+ mov [esp_out], esp
+ cmp esp, [esp_in] ; check it
+ jz lbl_stack_fix_end
+ pop ecx ; fix stack
+ pop ecx
+ pop ecx
+ pop ecx
+lbl_stack_fix_end: ; end of stack fix hack
+ mov [esp_fixed], esp
+ pop ecx
+ }
+
+#ifndef POPUP_NO_STACK_WARNING
+ if (esp_in != esp_out)
+ {
+ HANDLE hBadModule = 0;
+ char szBadModule[64] = {0};
+
+ // plugin enumeration from the core
+ char exe[MAX_PATH];
+ char search[MAX_PATH];
+ char *p = 0;
+ // get miranda's exe path
+ GetModuleFileNameA(NULL, exe, SIZEOF(exe));
+ // find the last \ and null it out, this leaves no trailing slash
+ p = strrchr(exe, '\\');
+ if ( p ) *p=0;
+ // create the search filter
+ mir_snprintf(search,SIZEOF(search),"%s\\Plugins\\*.dll", exe);
+ {
+ // FFFN will return filenames for things like dot dll+ or dot dllx
+ HANDLE hFind=INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATAA ffd;
+ hFind = FindFirstFileA(search, &ffd);
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if ( !(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ HMODULE hModule = GetModuleHandleA(ffd.cFileName);
+ if (((char *)PluginWindowProc > (char *)hModule) &&
+ (((char *)PluginWindowProc - (char *)hModule) < ((char *)PluginWindowProc - (char *)hBadModule)))
+ {
+ hBadModule = hModule;
+ lstrcpynA(szBadModule, ffd.cFileName, sizeof(szBadModule));
+ }
+ }
+ } while ( FindNextFileA(hFind, &ffd) );
+ FindClose(hFind);
+ }
+ }
+
+#ifdef POPUP_STACK_WARNING_MSGBOX
+ char buf[256];
+ mir_snprintf(buf, sizeof(buf),
+ "Some plugin passed callback with invalid calling\r\n"
+ "convention and caused stack corruption\r\n"
+ "Module name: %s\r\n"
+ "PluginWindowProc: %x\r\n"
+ "ESP Before: %d\r\n"
+ "ESP After: %d\r\n"
+ "ESP Fixed: %d",
+ szBadModule,
+ PluginWindowProc,
+ esp_in, esp_out, esp_fixed);
+
+ MessageBox(NULL, buf, _T("Popup Plus stack check"), MB_ICONSTOP|MB_OK);
+#else
+ strcat(exe, "\\popup_stack.log");
+ FILE *f = fopen(exe,"a");
+ fprintf(f,
+ "Module name: %s; PluginWindowProc: 0x%x; ESP Before: %d; ESP After: %d; ESP Fixed: %d\n",
+ szBadModule,
+ PluginWindowProc,
+ esp_in, esp_out, esp_fixed);
+ fclose(f);
+#endif // _DEBUG
+ }
+#endif // POPUP_NO_STACK_WARNING
+*/
+ unlock();
+ return result;
+ }
+
+ return NullWindowProc(this->m_hwnd, message, wParam, lParam);
+}
+
+LRESULT CALLBACK PopupWnd2::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ PopupWnd2 *wnd = 0;
+ if (message == WM_CREATE)
+ {
+ LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam;
+ wnd = (PopupWnd2 *)cs->lpCreateParams;
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)wnd);
+ } else
+ {
+ wnd = (PopupWnd2 *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ }
+ if (wnd) return wnd->WindowProc(message, wParam, lParam);
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+void WindowThread(void *arg)
+{
+ CallService(MS_SYSTEM_THREAD_PUSH, 0, 0);
+ OleInitialize(NULL); // we may need OLE in this thread for smiley substitution
+
+ PopupWnd2 *wnd = (PopupWnd2 *)arg;
+ wnd->buildMText();
+ wnd->create();
+ PostMessage(wnd->getHwnd(), UM_INITPOPUP, 0, 0);
+
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ CallService(MS_SYSTEM_THREAD_POP, 0, 0);
+ _endthread();
+}
+
+// Menu Host
+LRESULT CALLBACK MenuHostWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HANDLE hContact = NULL;
+
+ switch (message)
+ {
+ case UM_SHOWMENU:
+ {
+ hContact = (HANDLE)lParam;
+ POINT pt = {0};
+ HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)hContact,0);
+ GetCursorPos(&pt);
+ HWND hwndSave = GetForegroundWindow();
+ SetForegroundWindow(hwnd);
+ TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
+ SetForegroundWindow(hwndSave);
+ DestroyMenu(hMenu);
+ PostMessage((HWND)wParam, UM_MENUDONE, 0, 0);
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ // do not call PluginWindowProc if menu item was clicked. prevent auto-closing...
+ if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)hContact))
+ return DefWindowProc(hwnd, message, wParam, lParam);
+ break;
+ }
+
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+
+ case WM_DRAWITEM:
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
diff --git a/plugins/Popup/src/popup_wnd2.h b/plugins/Popup/src/popup_wnd2.h
new file mode 100644
index 0000000000..8c5fd963e3
--- /dev/null
+++ b/plugins/Popup/src/popup_wnd2.h
@@ -0,0 +1,273 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_wnd2.h $
+Revision : $Revision: 1620 $
+Last change on : $Date: 2010-06-23 21:31:05 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __popup_wnd2_h__
+#define __popup_wnd2_h__
+
+#define UM_CALLMETHOD (WM_USER+2048)
+
+class PopupAvatar;
+
+#define POPUP_OBJECT_SIGNARURE 0x0B1A11BE
+
+class PopupWnd2
+{
+public:
+ typedef LRESULT (PopupWnd2::*MethodPtr)(LPARAM lParam);
+ enum TextType {TT_NONE, TT_ANSI, TT_UNICODE, TT_MTEXT};
+
+ struct ActionInfo
+ {
+ POPUPACTION actionA;
+ RECT rc;
+ bool hover;
+
+ ActionInfo(): hover(false) {}
+ };
+
+ DWORD m_signature;
+
+private:
+ // style
+ COLORREF m_clBack, m_clText, m_clTitle, m_clClock;
+ int m_iTimeout;
+
+ // content
+ TextType m_textType;
+ char *m_lpzTitle, *m_lpzText;
+ WCHAR *m_lpwzTitle, *m_lpwzText;
+ HANDLE m_mtTitle, m_mtText;
+ bool m_bTextEmpty;
+ HFONT m_hfnTitle, m_hfnText;
+ HICON m_hIcon;
+ HBITMAP m_hbmAvatar;
+ char m_time[2+1+2+1];
+ ActionInfo* m_actions;
+ int m_actionCount;
+ HANDLE m_hNotification;
+
+ // other data
+ Formula::Args m_args;
+ HANDLE m_hContact, m_hContactPassed;
+ WNDPROC m_PluginWindowProc;
+ void *m_PluginData;
+
+ // the window
+ LPTSTR m_lpzSkin;
+ bool m_customPopup;
+ HWND m_hwnd, m_hwndToolTip;
+ bool m_bPositioned;
+ POINT m_pos;
+ SIZE m_sz;
+ MyBitmap *m_bmpBase, *m_bmp, *m_bmpAnimate;
+ PopupAvatar *m_avatar;
+ int m_avatarFrameDelay;
+ bool m_bReshapeWindow;
+ HANDLE m_hhkAvatarChanged;
+ bool m_bIsPinned;
+
+ // show & hide
+// bool m_bIdleRequested;
+ bool m_bFade;
+// DWORD m_dwTmFade0, m_dwTmFade1;
+ BYTE m_btAlpha0, m_btAlpha1;
+ bool m_bSlide;
+// DWORD m_dwTmSlide0, m_dwTmSlide1;
+ POINT m_ptPosition0, m_ptPosition1;
+ bool m_bDestroy;
+ bool m_bIsHovered;
+
+ // prevent unwanted clicks
+ POINT m_ptPrevCursor;
+
+ // system
+ POPUPOPTIONS *m_options;
+ DWORD m_lockCount;
+
+ PopupSkin::RenderInfo m_renderInfo;
+
+ void fixDefaults();
+ void fixAvatar();
+ int fixActions(POPUPACTION *theActions, int count);
+ int fixActions(POPUPACTION *theActions, int count, int additional);
+
+public:
+// PopupWnd2(POPUPDATA *ppd, POPUPOPTIONS *theCustomOptions=NULL, bool renderOnly=false);
+// PopupWnd2(POPUPDATAEX_V2 *ppd, POPUPOPTIONS *theCustomOptions=NULL, bool renderOnly=false);
+// PopupWnd2(POPUPDATAW_V2 *ppd, POPUPOPTIONS *theCustomOptions=NULL, bool renderOnly=false);
+ PopupWnd2(POPUPDATA2 *ppd, POPUPOPTIONS *theCustomOptions=NULL, bool renderOnly=false);
+// PopupWnd2(HANDLE hNtf, POPUPOPTIONS *theCustomOptions=NULL, bool renderOnly=false);
+ ~PopupWnd2();
+
+ void startThread();
+
+ void create();
+ void updateLayered(BYTE opacity);
+ SIZE measure();
+ void update();
+ void animate();
+
+ void show();
+ void hide();
+ void idle();
+
+ DWORD lock() { return ++m_lockCount; }
+ DWORD unlock() { return m_lockCount = m_lockCount ? m_lockCount-1 : 0; }
+ bool isLocked() { return m_lockCount != 0; }
+
+ void updateData(POPUPDATA *ppd);
+ void updateData(POPUPDATAEX_V2 *ppd);
+ void updateData(POPUPDATAW_V2 *ppd);
+ void updateData(POPUPDATA2 *ppd);
+// void updateData(HANDLE hNtf);
+ void buildMText();
+ void updateText(char *text);
+ void updateText(WCHAR *text);
+ void updateTitle(char *title);
+ void updateTitle(WCHAR *title);
+
+ void updateTimer();
+
+ MyBitmap *getContent() { return m_bmp; }
+
+ COLORREF getTextColor() { return m_clText; }
+ COLORREF getTitleColor() { return m_clTitle; }
+ COLORREF getClockColor() { return m_clClock; }
+ COLORREF getBackColor() { return m_clBack; }
+
+ bool isTextEmpty() { return m_bTextEmpty; }
+ TextType getTextType() { return m_textType; }
+ char *getTextA() { return m_lpzText; }
+ WCHAR *getTextW() { return m_lpwzText; }
+ HANDLE getTextM() { return m_mtText; }
+ char *getTitleA() { return m_lpzTitle; }
+ WCHAR *getTitleW() { return m_lpwzTitle; }
+ HANDLE getTitleM() { return m_mtTitle; }
+
+ int getActionCount() { return m_actionCount; }
+ ActionInfo *getActions() { return m_actions; }
+
+ char *getTime() { return m_time; }
+ HICON getIcon() { return m_hIcon; }
+ HANDLE getContact() { return m_hContact; }
+ HANDLE getContactPassed() { return m_hContactPassed; }
+ int getTimeout() { return m_iTimeout; }
+// HBITMAP getAvatar() { return hbmAvatar; }
+ PopupAvatar *getAvatar() { return m_avatar; }
+ HWND getHwnd() { return m_hwnd; }
+ void *getData() { return m_PluginData; }
+
+ Formula::Args *getArgs() { return &m_args; }
+ PopupSkin::RenderInfo *getRenderInfo() { return &m_renderInfo; }
+
+ SIZE getSize() { return m_sz; }
+ void setSize(SIZE sz)
+ {
+ this->m_sz = sz;
+ if (m_hwnd)
+ {
+ SetWindowPos(m_hwnd, 0, 0, 0, sz.cx, sz.cy, SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING);
+ if (!m_customPopup)
+ PopupThreadUpdateWindow(this);
+ }
+ }
+ bool isPositioned() { return m_bPositioned; }
+ POINT getPosition() { return m_pos; }
+ POINT getRealPosition() { return POINT(); }
+ void setPosition(POINT pt)
+ {
+ m_bPositioned = true;
+ m_pos = pt;
+ if (m_bSlide)
+ {
+ m_ptPosition1 = pt;
+ } else
+ {
+ SetWindowPos(m_hwnd, 0, pt.x, pt.y, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DEFERERASE|SWP_NOSENDCHANGING);
+ }
+ }
+
+ // Thread-related methods
+ void callMethodAsync(MethodPtr method, LPARAM lParam)
+ {
+ // we can't pass MethodPtr via WPARAM because it's size can differ! well, it's still 4 bytes on msvc but
+ // on gcc we will get 8 bytes...
+ MethodPtr *method_copy = new MethodPtr; *method_copy = method;
+ PostMessage(m_hwnd, UM_CALLMETHOD, (WPARAM)method_copy, (LPARAM)lParam);
+ }
+ void callMethodSync(MethodPtr method, LPARAM lParam)
+ {
+ // we can't pass MethodPtr via WPARAM because it's size can differ! well, it's still 4 bytes on msvc but
+ // on gcc we will get 8 bytes...
+ MethodPtr *method_copy = new MethodPtr; *method_copy = method;
+ SendMessage(m_hwnd, UM_CALLMETHOD, (WPARAM)method_copy, (LPARAM)lParam);
+ }
+
+ LRESULT m_updateData_POPUPDATA(LPARAM arg) { updateData((POPUPDATA *)arg); update(); return 0; }
+ LRESULT m_updateData_POPUPDATAEX_V2(LPARAM arg) { updateData((POPUPDATAEX_V2 *)arg); update(); return 0; }
+ LRESULT m_updateData_POPUPDATAW_V2(LPARAM arg) { updateData((POPUPDATAW_V2 *)arg); update(); return 0; }
+ LRESULT m_updateData_POPUPDATA2(LPARAM arg) { updateData((POPUPDATA2 *)arg); update(); return 0; }
+// LRESULT m_updateData_HNOTIFY(LPARAM arg) { updateData((HANDLE)arg); update(); return 0; }
+ LRESULT m_updateText(LPARAM arg) { updateText((char *)arg); update(); return 0; }
+ LRESULT m_updateTextW(LPARAM arg) { updateText((WCHAR *)arg); update(); return 0; }
+ LRESULT m_updateTitle(LPARAM arg) { updateTitle((char *)arg); update(); return 0; }
+ LRESULT m_updateTitleW(LPARAM arg) { updateTitle((WCHAR *)arg); update(); return 0; }
+ LRESULT m_show(LPARAM arg) { show(); return 0; }
+ LRESULT m_hide(LPARAM arg) { hide(); return 0; }
+
+ // window related stuff
+ LRESULT CALLBACK WindowProc(UINT, WPARAM, LPARAM);
+ static LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
+
+ // window creation flag
+ volatile bool m_bWindowCreated;
+};
+
+bool LoadPopupWnd2();
+void UnloadPopupWnd2();
+
+static inline bool IsValidPopupObject(PopupWnd2 *wnd)
+{
+ bool res = false;
+ __try
+ {
+ if (wnd->m_signature == POPUP_OBJECT_SIGNARURE)
+ res = true;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ res = false;
+ }
+ return res;
+}
+
+#endif // __popup_wnd2_h__
diff --git a/plugins/Popup/src/services.cpp b/plugins/Popup/src/services.cpp
new file mode 100644
index 0000000000..48f1919d12
--- /dev/null
+++ b/plugins/Popup/src/services.cpp
@@ -0,0 +1,675 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/services.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+int num_classes = 0; //for core class api support
+
+// isWorkstationLocked() code from core
+bool isWorkstationLocked()
+{
+ bool rc = false;
+
+ if (OpenInputDesktop != NULL) {
+ HDESK hDesk = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP);
+ if (hDesk == NULL)
+ rc = true;
+ else if (CloseDesktop != NULL)
+ CloseDesktop(hDesk);
+ }
+ return rc;
+}
+
+// isFullScreen() code from core
+static bool isFullScreen()
+{
+ RECT rcScreen = {0};
+
+ rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
+ rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
+
+ if (MonitorFromWindow != NULL)
+ {
+ HMONITOR hMon = MonitorFromWindow(GetForegroundWindow(), MONITOR_DEFAULTTONEAREST);
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfo(hMon, &mi))
+ rcScreen = mi.rcMonitor;
+ }
+
+ HWND hWndDesktop = GetDesktopWindow();
+ HWND hWndShell = GetShellWindow();
+
+ // check foregroundwindow
+ HWND hWnd = GetForegroundWindow();
+ if (hWnd && hWnd != hWndDesktop && hWnd != hWndShell)
+ {
+ TCHAR tszClassName[128] = _T("");
+ GetClassName(hWnd, tszClassName, SIZEOF(tszClassName));
+ if (_tcscmp(tszClassName, _T("WorkerW")))
+ {
+ RECT rect, rectw, recti;
+ GetWindowRect(hWnd, &rectw);
+
+ GetClientRect(hWnd, &rect);
+ ClientToScreen(hWnd, (LPPOINT)&rect);
+ ClientToScreen(hWnd, (LPPOINT)&rect.right);
+
+ if (EqualRect(&rect, &rectw) && IntersectRect(&recti, &rect, &rcScreen) &&
+ EqualRect(&recti, &rcScreen))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//===== PopUp/AddPopUp
+INT_PTR PopUp_AddPopUp(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ POPUPDATA *ppd = (POPUPDATA*)wParam;
+ if (!ppd) return -1;
+
+ POPUPDATA2 ppd2 = {0};
+ ppd2.cbSize = sizeof(ppd2);
+ ppd2.flags = PU2_ANSI;
+ ppd2.lchContact = ppd->lchContact;
+ ppd2.lchIcon = ppd->lchIcon;
+ ppd2.lpzTitle = ppd->lpzContactName;
+ ppd2.lpzText = ppd->lpzText;
+ ppd2.colorBack = ppd->colorBack;
+ ppd2.colorText = ppd->colorText;
+ ppd2.PluginWindowProc = ppd->PluginWindowProc;
+ ppd2.PluginData = ppd->PluginData;
+ ppd2.iSeconds = PopUpOptions.Seconds;
+ return PopUp_AddPopUp2((WPARAM)&ppd2, lParam);
+/*
+ PopupWnd2 *wnd = new PopupWnd2(ppd);
+
+ if (lParam & APF_RETURN_HWND)
+ {
+ while (!wnd->bWindowCreated) Sleep(1);
+ return (int)wnd->getHwnd();
+ }
+
+ return 1;
+*/
+}
+
+//===== PopUp/AddPopUpEx
+INT_PTR PopUp_AddPopUpEx(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ POPUPDATAEX_V2 *ppd = (POPUPDATAEX_V2*)wParam;
+ if (!ppd) return -1;
+
+ POPUPDATA2 ppd2 = {0};
+ ppd2.cbSize = sizeof(ppd2);
+ ppd2.flags = PU2_ANSI;
+ ppd2.lchContact = ppd->lchContact;
+ ppd2.lchIcon = ppd->lchIcon;
+ ppd2.lpzTitle = ppd->lpzContactName;
+ ppd2.lpzText = ppd->lpzText;
+ ppd2.colorBack = ppd->colorBack;
+ ppd2.colorText = ppd->colorText;
+ ppd2.PluginWindowProc = ppd->PluginWindowProc;
+ ppd2.PluginData = ppd->PluginData;
+ ppd2.iSeconds = ppd->iSeconds;
+
+ if (lParam&APF_NEWDATA)
+ {
+ ppd2.lchNotification = ppd->hNotification;
+ ppd2.actionCount = ppd->actionCount;
+ ppd2.lpActions = ppd->lpActions;
+// ppd2.hbmAvatar = ppd->hbmAvatar;
+ }
+
+ return PopUp_AddPopUp2((WPARAM)&ppd2, lParam);
+
+/*
+ if (lParam & APF_RETURN_HWND)
+ {
+ while (!wnd->bWindowCreated) Sleep(1);
+ return (int)wnd->getHwnd();
+ }
+
+ return 1;
+*/
+}
+
+//===== PopUp/AddPopupW
+INT_PTR PopUp_AddPopUpW(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ POPUPDATAW_V2 *ppd = (POPUPDATAW_V2*)wParam;
+ if (!ppd) return -1;
+
+ POPUPDATA2 ppd2 = {0};
+ ppd2.cbSize = sizeof(ppd2);
+ ppd2.flags = PU2_UNICODE;
+ ppd2.lchContact = ppd->lchContact;
+ ppd2.lchIcon = ppd->lchIcon;
+ ppd2.lpwzTitle = ppd->lpwzContactName;
+ ppd2.lpwzText = ppd->lpwzText;
+ ppd2.colorBack = ppd->colorBack;
+ ppd2.colorText = ppd->colorText;
+ ppd2.PluginWindowProc = ppd->PluginWindowProc;
+ ppd2.PluginData = ppd->PluginData;
+ ppd2.iSeconds = ppd->iSeconds;
+ ppd2.lchNotification = ppd->hNotification;
+
+ if (lParam&APF_NEWDATA)
+ {
+ ppd2.actionCount = ppd->actionCount;
+ ppd2.lpActions = ppd->lpActions;
+// ppd2.hbmAvatar = ppd->hbmAvatar;
+ }
+
+ return PopUp_AddPopUp2((WPARAM)&ppd2, lParam);
+
+/*
+ if (lParam & APF_RETURN_HWND)
+ {
+ while (!wnd->bWindowCreated) Sleep(1);
+ return (int)wnd->getHwnd();
+ }
+
+ return 1;
+*/
+}
+
+//===== PopUp/AddPopup2
+static __forceinline DWORD Proto_Status2Flag_My(DWORD status)
+{
+ if (DWORD res = Proto_Status2Flag(status))
+ return res;
+ return PF2_IDLE;
+}
+
+INT_PTR PopUp_AddPopUp2(WPARAM wParam, LPARAM lParam)
+{
+ /* NOTE: we will return 0 instead of -1 since tabSRMM stops using popup after first failure :/ */
+
+ if (!gbPopupLoaded) return -1;
+
+ POPUPDATA2 *ppdIn = (POPUPDATA2 *)wParam;
+ if (!ppdIn) return -1;
+
+ POPUPDATA2 ppdFixed = {0};
+ POPUPDATA2 *ppd = &ppdFixed;
+ CopyMemory(ppd, ppdIn, min(ppdIn->cbSize, sizeof(POPUPDATA2)));
+
+ DWORD disableWhen;
+ FillNotificationData(ppd, &disableWhen);
+
+ if (!(lParam&APF_NO_HISTORY))
+ PopupHistoryAdd(ppd);
+
+ if (PopupThreadIsFull())
+ return -1;
+
+ #ifdef _DEBUG
+ char temp[128];
+ OutputDebugStringA("isWorkstationLocked: \t");
+ OutputDebugStringA(isWorkstationLocked() ? "true":"false");
+ OutputDebugStringA("\n");
+ #endif
+
+ if (isWorkstationLocked())
+ return -1;
+
+ // Check if contact handle is valid.
+ char *proto = NULL;
+ if (ppd->lchContact)
+ proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ppd->lchContact, 0);
+
+ BYTE bShowMode = proto ? DBGetContactSettingByte(ppd->lchContact, MODULNAME, "ShowMode", PU_SHOWMODE_AUTO) : PU_SHOWMODE_AUTO;
+
+ if (bShowMode == PU_SHOWMODE_BLOCK)
+ return -1;
+
+ if (bShowMode != PU_SHOWMODE_FAVORITE)
+ {
+ if (!PopUpOptions.ModuleIsEnabled)
+ return -1;
+ #ifdef _DEBUG
+ itoa(PopUpOptions.DisableWhenFullscreen,temp,10);
+ OutputDebugStringA("PopUpOptions.DisableWhenFullscreen: \t");
+ OutputDebugStringA(temp);
+ OutputDebugStringA("\n");
+ itoa(bShowMode,temp,10);
+ OutputDebugStringA("bShowMode: \t");
+ OutputDebugStringA(temp);
+ OutputDebugStringA("\n");
+ OutputDebugStringA("isFullScreen: \t");
+ OutputDebugStringA(isFullScreen() ? "true":"false");
+ OutputDebugStringA("\n");
+ #endif
+
+ if (PopUpOptions.DisableWhenFullscreen && (bShowMode != PU_SHOWMODE_FULLSCREEN) && isFullScreen())
+ return -1;
+
+ if (DBGetContactSettingDword(NULL, MODULNAME, "Global Status", 0) &
+ Proto_Status2Flag_My(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)))
+ return -1;
+
+ if ((disableWhen & 0x0000FFFF) & Proto_Status2Flag_My(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)))
+ return -1;
+
+ if (proto)
+ {
+ char prefix[128];
+ mir_snprintf(prefix, sizeof(prefix), "Protocol Status/%s", (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ppd->lchContact, 0));
+ if (DBGetContactSettingDword(NULL, MODULNAME, prefix, 0) &
+ Proto_Status2Flag_My(CallProtoService(proto, PS_GETSTATUS, 0, 0)))
+ return -1;
+ if (((disableWhen >> 16) & 0xFFFF0000) & Proto_Status2Flag_My(CallProtoService(proto, PS_GETSTATUS, 0, 0)))
+ return -1;
+ }
+ }
+
+ if (lParam&APF_CUSTOM_POPUP)
+ ppd->flags |= PU2_CUSTOM_POPUP;
+ PopupWnd2 *wnd = new PopupWnd2(ppd, NULL, false);
+
+ if (lParam & APF_RETURN_HWND)
+ {
+ while (!wnd->m_bWindowCreated) Sleep(1);
+ return (INT_PTR)wnd->getHwnd();
+ }
+
+ return 0;
+}
+
+//===== PopUp/GetContact
+INT_PTR PopUp_GetContact(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ HWND hwnd = (HWND)wParam;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (wnd && IsValidPopupObject(wnd)) return (INT_PTR)wnd->getContactPassed();
+ return (INT_PTR)(-1);
+}
+
+//===== PopUp/GetPluginData
+INT_PTR PopUp_GetPluginData(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ HWND hwnd = (HWND)wParam;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (wnd && IsValidPopupObject(wnd)) return (INT_PTR)wnd->getData();
+ return (INT_PTR)(-1);
+}
+
+//===== PopUp/IsSecondLineShown
+INT_PTR PopUp_IsSecondLineShown(WPARAM wParam, LPARAM lParam)
+{
+ return 1;
+}
+
+//===== PopUp/ChangeText
+INT_PTR PopUp_ChangeText(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ if (!wParam) return -1;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA);
+ if (!wnd || !IsValidPopupObject(wnd)) return -1;
+ wnd->callMethodSync(&PopupWnd2::m_updateText, lParam);
+/*
+ char *str = (char *)mir_alloc(sizeof(char) * (strlen((char *)lParam) + 1));
+ strcpy(str, (char *)lParam);
+ PostMessage((HWND)wParam, UM_CHANGEPOPUP, CPT_TEXT, (LPARAM)str);
+*/
+ return 0;
+}
+
+//===== PopUp/ChangeTextW
+INT_PTR PopUp_ChangeTextW(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ if (!wParam) return -1;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA);
+ if (!wnd || !IsValidPopupObject(wnd)) return -1;
+ wnd->callMethodSync(&PopupWnd2::m_updateTextW, lParam);
+/*
+ WCHAR *str = (WCHAR *)mir_alloc(sizeof(WCHAR) * (wcslen((WCHAR *)lParam) + 1));
+ wcscpy(str, (WCHAR *)lParam);
+ PostMessage((HWND)wParam, UM_CHANGEPOPUP, CPT_TEXTW, (LPARAM)str);
+*/
+ return 0;
+}
+
+//===== PopUp/Change
+INT_PTR PopUp_Change(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ if (!wParam) return -1;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA);
+ if (!wnd || !IsValidPopupObject(wnd)) return -1;
+ wnd->callMethodSync(&PopupWnd2::m_updateData_POPUPDATAEX_V2, lParam);
+/*
+ POPUPDATAEX_V2 *ppdx = (POPUPDATAEX_V2 *)mir_alloc(sizeof(POPUPDATAEX_V2));
+ memcpy(ppdx, (POPUPDATAEX_V2 *)lParam, sizeof(POPUPDATAEX_V2));
+ PostMessage((HWND)wParam, UM_CHANGEPOPUP, CPT_DATA, (LPARAM)ppdx);
+*/
+ return 0;
+}
+
+//===== PopUp/ChangeW
+INT_PTR PopUp_ChangeW(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ if (!wParam) return -1;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA);
+ if (!wnd || !IsValidPopupObject(wnd)) return -1;
+ wnd->callMethodSync(&PopupWnd2::m_updateData_POPUPDATAW_V2, lParam);
+/*
+ POPUPDATAW_V2 *ppdw = (POPUPDATAW_V2 *)mir_alloc(sizeof(POPUPDATAW_V2));
+ memcpy(ppdw, (POPUPDATAW_V2 *)lParam, sizeof(POPUPDATAW_V2));
+ PostMessage((HWND)wParam, UM_CHANGEPOPUP, CPT_DATA, (LPARAM)ppdw);
+*/
+ return 0;
+}
+
+//===== PopUp/Change2
+INT_PTR PopUp_Change2(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ if (!wParam) return -1;
+ PopupWnd2 *wnd = (PopupWnd2 *)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA);
+ if (!wnd || IsValidPopupObject(wnd)) return -1;
+ wnd->callMethodSync(&PopupWnd2::m_updateData_POPUPDATA2, lParam);
+ return 0;
+}
+
+//===== PopUp/ShowMessage
+INT_PTR PopUp_ShowMessage(WPARAM wParam, LPARAM lParam) {
+ if(!gbPopupLoaded || !wParam || !lParam) return -1;
+ if(closing) return 0;
+
+ POPUPDATA2 ppd2 = {0};
+ ppd2.cbSize = sizeof(ppd2);
+ ppd2.flags = PU2_ANSI;
+ ppd2.lpzText = (char*)wParam;
+ switch (lParam&0x7fffffff) {
+ case SM_ERROR:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_ERROR,0);
+ ppd2.colorBack = RGB(191,0,0);
+ ppd2.colorText = RGB(255,245,225);
+ ppd2.lchNotification = g_hntfError;
+ ppd2.lpzTitle = Translate("Error");
+ break;
+ case SM_WARNING:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_WARNING,0);
+ ppd2.colorBack = RGB(210,210,150);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfWarning;
+ ppd2.lpzTitle = Translate("Warning");
+ break;
+ case SM_NOTIFY:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_NOTIFY,0);
+ ppd2.colorBack = RGB(230,230,230);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfNotification;
+ ppd2.lpzTitle = Translate("Notify");
+ break;
+ default: //No no no... you must give me a good value.
+ return -1;
+ }
+ return PopUp_AddPopUp2((WPARAM)&ppd2, (LPARAM)((lParam&0x80000000)?APF_NO_HISTORY:0));
+}
+
+INT_PTR PopUp_ShowMessageW(WPARAM wParam, LPARAM lParam) {
+ if(!gbPopupLoaded || !wParam || !lParam) return -1;
+ if(closing) return 0;
+
+ POPUPDATA2 ppd2 = {0};
+ ppd2.cbSize = sizeof(ppd2);
+ ppd2.flags = PU2_UNICODE;
+ ppd2.lpwzText = (WCHAR*)wParam;
+ switch (lParam&0x7fffffff) {
+ case SM_ERROR:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_ERROR,0);
+ ppd2.colorBack = RGB(191,0,0);
+ ppd2.colorText = RGB(255,245,225);
+ ppd2.lchNotification = g_hntfError;
+ ppd2.lpwzTitle = TranslateW(L"Error");
+ break;
+ case SM_WARNING:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_WARNING,0);
+ ppd2.colorBack = RGB(210,210,150);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfWarning;
+ ppd2.lpwzTitle = TranslateW(L"Warning");
+ break;
+ case SM_NOTIFY:
+ ppd2.lchIcon = IcoLib_GetIcon(ICO_MISC_NOTIFY,0);
+ ppd2.colorBack = RGB(230,230,230);
+ ppd2.colorText = RGB(0,0,0);
+ ppd2.lchNotification = g_hntfNotification;
+ ppd2.lpwzTitle = TranslateW(L"Notify");
+ break;
+ default: //No no no... you must give me a good value.
+ return -1;
+ }
+ return PopUp_AddPopUp2((WPARAM)&ppd2, (LPARAM)((lParam&0x80000000)?APF_NO_HISTORY:0));
+}
+
+//===== PopUp/Query
+INT_PTR PopUp_Query(WPARAM wParam, LPARAM lParam)
+{
+ if (!gbPopupLoaded) return -1;
+
+ if (closing)
+ return 0;
+
+ switch (wParam) {
+ case PUQS_ENABLEPOPUPS: {
+ if (PopUpOptions.ModuleIsEnabled) return 1; //They're already ON!!!
+ else { //Module was disabled.
+ svcEnableDisableMenuCommand(0,0);
+ return 0;
+ }
+ }
+ case PUQS_DISABLEPOPUPS: {
+ if (!(PopUpOptions.ModuleIsEnabled)) return 1; //They're already OFF!!!
+ else {
+ svcEnableDisableMenuCommand(0,0);
+ return 0;
+ }
+ }
+ case PUQS_GETSTATUS:
+ return (PopUpOptions.ModuleIsEnabled);
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+
+//===== PopUp/RegisterActions
+INT_PTR PopUp_RegisterActions(WPARAM wParam, LPARAM lParam)
+{
+ LPPOPUPACTION actions = (LPPOPUPACTION)wParam;
+ for (int i = 0; i < lParam; ++i)
+ RegisterAction(&actions[i]);
+ return 0;
+}
+
+
+INT_PTR PopUp_RegisterNotification(WPARAM wParam, LPARAM lParam)
+{
+ return (INT_PTR)RegisterNotification((LPPOPUPNOTIFICATION)wParam);
+}
+
+
+//===== PopUp/UnhookEventAsync
+struct SafeUnhookEventParam
+{
+ HWND hwndPopup;
+ HANDLE hEvent;
+};
+
+static void CALLBACK SafeUnhookEventFunc(ULONG_PTR dwParam)
+{
+ UnhookEvent(((SafeUnhookEventParam *)dwParam)->hEvent);
+ PostMessage(((SafeUnhookEventParam *)dwParam)->hwndPopup, UM_POPUPUNHOOKCOMPLETE, 0,
+ (LPARAM)((SafeUnhookEventParam *)dwParam)->hEvent);
+ delete (SafeUnhookEventParam *)dwParam;
+}
+
+INT_PTR PopUp_UnhookEventAsync(WPARAM wParam, LPARAM lParam)
+{
+ SafeUnhookEventParam *param = new SafeUnhookEventParam;
+ param->hwndPopup = (HWND)wParam;
+ param->hEvent = (HANDLE)lParam;
+ QueueUserAPC(SafeUnhookEventFunc, hMainThread, (ULONG_PTR)param);
+ return 0;
+}
+
+//===== PopUp/RegisterVfx (effekt name for drop down box)
+INT_PTR PopUp_RegisterVfx(WPARAM wParam, LPARAM lParam)
+{
+ OptAdv_RegisterVfx((char *)lParam);
+ return 0;
+}
+
+//===== PopUp/RegisterClass (for core class api support)
+INT_PTR PopUp_RegisterPopupClass(WPARAM wParam, LPARAM lParam) {
+ char setting[256];
+ POPUPCLASS *pc = (POPUPCLASS *)lParam;
+ POPUPTREEDATA *ptd = (POPUPTREEDATA *)mir_alloc(sizeof(POPUPTREEDATA));
+ memset(ptd,0,sizeof(POPUPTREEDATA));
+ ptd->cbSize = sizeof(POPUPTREEDATA);
+ ptd->signature = 0/*PopupNotificationData_SIGNATURE*/;
+ ptd->typ = 2;
+ memcpy(&ptd->pupClass, pc, sizeof(POPUPCLASS));
+ ptd->pszTreeRoot = mir_a2t(pc->pszName);
+ ptd->pupClass.pszName = mir_strdup(pc->pszName);
+ if(pc->flags & PCF_UNICODE) {
+ ptd->pupClass.pwszDescription = mir_wstrdup(pc->pwszDescription);
+ ptd->pszDescription = mir_u2t(pc->pwszDescription);
+ }
+ else {
+ ptd->pupClass.pszDescription = mir_strdup (pc->pszDescription);
+ ptd->pszDescription = mir_a2t(pc->pszDescription);
+ }
+ LoadClassSettings(ptd, PU_MODULCLASS);
+
+ //we ignore pc->colorText and use fonts.text as default (if no setting found in DB)
+ mir_snprintf(setting, 256, "%s/TextCol", ptd->pupClass.pszName);
+ ptd->pupClass.colorText = (COLORREF)DBGetContactSettingDword(NULL, PU_MODULCLASS, setting, fonts.clText/*pc->colorText*/);
+ FontID fid = {0};
+ fid.cbSize = sizeof(FontID);
+ mir_snprintf(fid.group, sizeof(fid.group), "%s/%s", PU_FNT_AND_COLOR, ptd->pupClass.pszName);
+ strcpy(fid.dbSettingsGroup, PU_MODULCLASS);
+ fid.flags = FIDF_DEFAULTVALID;
+ fid.deffontsettings.charset = DEFAULT_CHARSET;
+ fid.deffontsettings.size = -11;
+ strcpy(fid.deffontsettings.szFace, "Verdana");
+ strcpy(fid.name, PU_FNT_NAME_TEXT);
+ strcpy(fid.prefix, setting);
+ mir_snprintf(fid.prefix, sizeof(fid.prefix), "%s/Text", ptd->pupClass.pszName); // result is "%s/TextCol"
+ fid.deffontsettings.style = 0;
+ fid.deffontsettings.colour = fonts.clText;
+ CallService(MS_FONT_REGISTER, (WPARAM)&fid, 0);
+
+ //we ignore pc->colorBack and use fonts.clBack as default (if no setting found in DB)
+ mir_snprintf(setting, 256, "%s/BgCol", ptd->pupClass.pszName);
+ ptd->pupClass.colorBack = (COLORREF)DBGetContactSettingDword(NULL, PU_MODULCLASS, setting, (DWORD)fonts.clBack/*pc->colorBack*/);
+ ColourID cid = {0};
+ cid.cbSize = sizeof(ColourID);
+ mir_snprintf(cid.group, sizeof(cid.group), "%s/%s", PU_FNT_AND_COLOR, ptd->pupClass.pszName);
+ strcpy(cid.dbSettingsGroup, PU_MODULCLASS);
+ strcpy(cid.name, PU_COL_BACK_NAME);
+ mir_snprintf(cid.setting, sizeof(cid.setting), "%s/BgCol", ptd->pupClass.pszName);
+ cid.defcolour = fonts.clBack;
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&cid, 0);
+
+ gTreeData.insert(ptd);
+ num_classes++;
+
+ return 0;
+}
+
+//===== PopUp/AddPopupClass (for core class api support)
+INT_PTR PopUp_CreateClassPopup(WPARAM wParam, LPARAM lParam) {
+ int ret = 1;
+ POPUPDATACLASS *pdc = (POPUPDATACLASS *)lParam;
+ if(pdc->cbSize != sizeof(POPUPDATACLASS)) return ret;
+
+ POPUPCLASS *pc = NULL;
+ POPUPTREEDATA *ptd = NULL;
+
+ if(wParam) pc = (POPUPCLASS *)wParam;
+ else {
+ LPTSTR group = mir_a2t(pdc->pszClassName);
+ ptd = (POPUPTREEDATA *)FindTreeData(group, NULL, 2);
+ if(ptd) pc = &ptd->pupClass;
+ }
+ if(pc) {
+ POPUPDATA2 ppd2 = {0};
+ ppd2.cbSize = sizeof(POPUPDATA2);
+ ppd2.colorBack = pc->colorBack;
+ ppd2.colorText = pc->colorText;
+ ppd2.lchIcon = pc->hIcon;
+ ppd2.iSeconds = pc->iSeconds;
+ ppd2.PluginWindowProc = pc->PluginWindowProc;
+ if(pc->flags & PCF_UNICODE) {
+ ppd2.flags = PU2_UNICODE;
+ ppd2.lpwzTitle = (WCHAR*)pdc->pwszTitle;
+ ppd2.lpwzText = (WCHAR*)pdc->pwszText;
+ }
+ else {
+ ppd2.flags = PU2_ANSI;
+ ppd2.lpzTitle = (char *)pdc->pszTitle;
+ ppd2.lpzText = (char *)pdc->pszText;
+ }
+ ppd2.lchContact = pdc->hContact;
+ ppd2.PluginData = pdc->PluginData;
+
+ ret = PopUp_AddPopUp2((WPARAM)&ppd2, 0);
+ }
+ return ret!=0 ? 1 : 0;
+}
+
diff --git a/plugins/Popup/src/services.h b/plugins/Popup/src/services.h
new file mode 100644
index 0000000000..462d20345c
--- /dev/null
+++ b/plugins/Popup/src/services.h
@@ -0,0 +1,67 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/services.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __services_h__
+#define __services_h__
+
+extern int num_classes; //for core class api support
+
+INT_PTR PopUp_AddPopUp(WPARAM, LPARAM);
+INT_PTR PopUp_AddPopUpW(WPARAM, LPARAM);
+
+INT_PTR PopUp_AddPopUpEx(WPARAM, LPARAM);
+INT_PTR PopUp_AddPopUp2(WPARAM, LPARAM);
+
+INT_PTR PopUp_GetContact(WPARAM, LPARAM);
+INT_PTR PopUp_IsSecondLineShown(WPARAM, LPARAM);
+
+INT_PTR PopUp_ChangeText(WPARAM, LPARAM);
+INT_PTR PopUp_ChangeTextW(WPARAM, LPARAM);
+
+INT_PTR PopUp_Change(WPARAM, LPARAM);
+INT_PTR PopUp_ChangeW(WPARAM, LPARAM);
+INT_PTR PopUp_Change2(WPARAM, LPARAM);
+
+INT_PTR PopUp_ShowMessage(WPARAM, LPARAM);
+INT_PTR PopUp_ShowMessageW(WPARAM, LPARAM);
+
+INT_PTR PopUp_Query(WPARAM, LPARAM);
+INT_PTR PopUp_GetPluginData(WPARAM, LPARAM);
+INT_PTR PopUp_RegisterActions(WPARAM wParam, LPARAM lParam);
+INT_PTR PopUp_RegisterNotification(WPARAM wParam, LPARAM lParam);
+INT_PTR PopUp_UnhookEventAsync(WPARAM wParam, LPARAM lParam);
+INT_PTR PopUp_RegisterVfx(WPARAM wParam, LPARAM lParam);
+
+INT_PTR PopUp_RegisterPopupClass(WPARAM wParam, LPARAM lParam);
+INT_PTR PopUp_CreateClassPopup(WPARAM wParam, LPARAM lParam);
+
+#endif // __services_h__
diff --git a/plugins/Popup/src/skin.cpp b/plugins/Popup/src/skin.cpp
new file mode 100644
index 0000000000..d3847f6f7c
--- /dev/null
+++ b/plugins/Popup/src/skin.cpp
@@ -0,0 +1,1518 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/skin.cpp $
+Revision : $Revision: 1651 $
+Last change on : $Date: 2010-07-15 20:31:06 +0300 (Чт, 15 июл 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+#include <stdio.h>
+#include <fstream>
+#include <sstream>
+
+// PopupSkin
+PopupSkin::PopupSkin(LPCTSTR aName)
+{
+ for (int i = 0; i < 32; i++)
+ m_flag_names[i] = NULL;
+ m_elements = 0;
+ m_name = aName ? mir_tstrdup(aName) : NULL;
+}
+
+PopupSkin::~PopupSkin()
+{
+ if (m_name) mir_free(m_name);
+ for (int i = 0; i < 32; i++)
+ mir_free(m_flag_names[i]);
+ freeSkin(m_elements);
+}
+
+SIZE PopupSkin::measureAction(HDC hdc, POPUPACTION *act) const
+{
+ SIZE sz = {0};
+ if (!(PopUpOptions.actions&ACT_ENABLE))
+ return sz;
+
+ if (PopUpOptions.actions&ACT_LARGE)
+ {
+ sz.cx = sz.cy = 32;
+ } else
+ {
+ sz.cx = sz.cy = 16;
+ }
+
+ if (PopUpOptions.actions&ACT_TEXT)
+ {
+ char *name = strchr(act->lpzTitle, '/');
+ if (!name) name = act->lpzTitle;
+ else ++name;
+
+ SIZE szText, szSpace;
+
+#if defined(_UNICODE)
+ LPWSTR wname = mir_a2u(name);
+ WCHAR *str = TranslateW(wname);
+ GetTextExtentPoint32W(hdc, str, lstrlenW(str), &szText);
+ mir_free(wname);
+ GetTextExtentPoint32W(hdc, L" ", 1, &szSpace);
+#else
+ if (g_popup.isOsUnicode && MyGetTextExtentPoint32W) {
+ LPWSTR wname = mir_a2u(name);
+ WCHAR *str = TranslateW(wname);
+ MyGetTextExtentPoint32W(hdc, str, lstrlenW(str), &szText);
+ mir_free(wname);
+ }
+ else {
+ char *str = Translate(name);
+ GetTextExtentPoint32A(hdc, str, lstrlenA(str), &szText);
+ }
+ GetTextExtentPoint32A(hdc, " ", 1, &szSpace);
+#endif
+ sz.cy = max(sz.cy, szText.cy);
+ sz.cx += szSpace.cx;
+ sz.cx += szText.cx;
+ sz.cy += 2;
+ } else
+ {
+ sz.cx += 4;
+ sz.cy += 4;
+ }
+
+ return sz;
+}
+
+SIZE PopupSkin::measureActionBar(HDC hdc, PopupWnd2 *wnd) const
+{
+ SIZE sz = {0};
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.action);
+ for (int i = 0; i < wnd->getActionCount(); ++i)
+ {
+ SIZE szAction = measureAction(hdc, &wnd->getActions()[i].actionA);
+
+ if (PopUpOptions.actions & ACT_TEXT)
+ {
+ sz.cx = max(sz.cx, szAction.cx);
+ sz.cy += szAction.cy;
+ } else
+ {
+ sz.cx += szAction.cx;
+ sz.cy = max(sz.cy, szAction.cy);
+ }
+ }
+ SelectObject(hdc, hFntSave);
+ return sz;
+}
+
+void PopupSkin::drawAction(MyBitmap *bmp, POPUPACTION *act, int x, int y, bool hover) const
+{
+ if (!(PopUpOptions.actions&ACT_ENABLE))
+ return;
+
+ bmp->DrawIcon(act->lchIcon,
+ (PopUpOptions.actions&ACT_TEXT) ? x : (x+2),
+ y+2,
+ (PopUpOptions.actions&ACT_LARGE) ? 32 : 16,
+ (PopUpOptions.actions&ACT_LARGE) ? 32 : 16);
+
+ if (PopUpOptions.actions&ACT_TEXT)
+ {
+ char *name = strchr(act->lpzTitle, '/');
+ if (!name) name = act->lpzTitle;
+ else ++name;
+
+ SIZE szText, szSpace;
+
+ HFONT hFntSave = (HFONT)SelectObject(bmp->getDC(), hover ? fonts.actionHover : fonts.action);
+ SetTextColor(bmp->getDC(), hover ? fonts.clActionHover : fonts.clAction);
+ SetBkMode(bmp->getDC(), TRANSPARENT);
+
+ GetTextExtentPoint32A(bmp->getDC(), " ", 1, &szSpace);
+
+#if defined(_UNICODE)
+ LPWSTR wname = mir_a2u(name);
+ WCHAR *str = TranslateW(wname);
+ GetTextExtentPoint32W(bmp->getDC(), str, lstrlenW(str), &szText);
+ bmp->Draw_TextW(str,
+ (PopUpOptions.actions&ACT_LARGE) ? (x+szSpace.cx+32) : (x+szSpace.cx+16),
+ max(
+ y+2,
+ y+2 + (((PopUpOptions.actions&ACT_LARGE) ? 32 : 16) - szText.cy)/2
+ ));
+ mir_free(wname);
+#else
+ if (g_popup.isOsUnicode && MyGetTextExtentPoint32W)
+ {
+ LPWSTR wname = mir_a2u(name);
+ WCHAR *str = TranslateW(wname);
+ MyGetTextExtentPoint32W(bmp->getDC(), str, lstrlenW(str), &szText);
+ bmp->Draw_TextW(str,
+ (PopUpOptions.actions&ACT_LARGE) ? (x+szSpace.cx+32) : (x+szSpace.cx+16),
+ max(
+ y+2,
+ y+2 + (((PopUpOptions.actions&ACT_LARGE) ? 32 : 16) - szText.cy)/2
+ ));
+ mir_free(wname);
+ }
+ else {
+ char *str = Translate(name);
+ GetTextExtentPoint32A(bmp->getDC(), str, lstrlenA(str), &szText);
+ bmp->Draw_TextA(str,
+ (PopUpOptions.actions&ACT_LARGE) ? (x+szSpace.cx+32) : (x+szSpace.cx+16),
+ max(
+ y+2,
+ y+2 + (((PopUpOptions.actions&ACT_LARGE) ? 32 : 16) - szText.cy)/2
+ ));
+ }
+#endif
+ SelectObject(bmp->getDC(), hFntSave);
+ }
+ else {
+ if (hover)
+ {
+ RECT rc;
+ rc.left = x;
+ rc.top = y;
+ rc.right = x + ((PopUpOptions.actions&ACT_LARGE) ? 32 : 16) + 4;
+ rc.bottom = y + ((PopUpOptions.actions&ACT_LARGE) ? 32 : 16) + 4;
+ bmp->saveAlpha(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
+ HBRUSH hbr = CreateSolidBrush(fonts.clActionHover);
+ FrameRect(bmp->getDC(), &rc, hbr);
+ DeleteObject(hbr);
+ bmp->restoreAlpha(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
+ }
+ }
+}
+
+void PopupSkin::drawActionBar(MyBitmap *bmp, PopupWnd2 *wnd, int x, int y) const
+{
+ for (int i = 0; i < wnd->getActionCount(); ++i)
+ {
+ SIZE szAction = measureAction(bmp->getDC(), &wnd->getActions()[i].actionA);
+ drawAction(bmp, &wnd->getActions()[i].actionA, x, y, wnd->getActions()[i].hover);
+
+ wnd->getActions()[i].rc.left = x;
+ wnd->getActions()[i].rc.top = y;
+ wnd->getActions()[i].rc.right = x + szAction.cx;
+ wnd->getActions()[i].rc.bottom = y + szAction.cy;
+
+ if (PopUpOptions.actions & ACT_TEXT)
+ {
+ y += szAction.cy;
+ } else
+ {
+ x += szAction.cx;
+ }
+ }
+}
+
+void PopupSkin::measure(HDC hdc, PopupWnd2 *wnd, int maxw, POPUPOPTIONS *options) const
+{
+ if (!m_elements) return;
+
+ SKINELEMENT *head = NULL;
+
+ int STYLE_SZ_CLOCK = 0;
+ if (!this->useInternalClock())
+ for (head = m_elements; head; head = head->next)
+ if ((head->type&ST_TYPEMASK) == ST_CLOCK)
+ break;
+ if (head && head->myBmp)
+ {//layerd clock
+ SIZE szNew;
+ szNew.cx = head->clocksize[CLOCK_LEFT]+head->clocksize[CLOCK_RIGHT];
+ szNew.cy = head->myBmp->getHeight();
+ for (char *p = wnd->getTime(); *p; p++)
+ {
+ if (*p == ':')
+ {
+ szNew.cx += head->clocksize[CLOCK_SEPARATOR];
+ } else
+ if ((*p >= '0') && (*p <= '9'))
+ {
+ szNew.cx += head->clocksize[CLOCK_DIGITS+*p-'0'];
+ }
+ }
+ wnd->getArgs()->add("clock.width",szNew.cx);
+ wnd->getArgs()->add("clock.height",szNew.cy);
+ STYLE_SZ_CLOCK = szNew.cx;
+ } else
+ {//normal clock
+ HFONT hfnSave = (HFONT)SelectObject(hdc, fonts.clock);
+ SIZE sz; GetTextExtentPoint32A(hdc, wnd->getTime(), lstrlenA(wnd->getTime()), &sz);
+ SelectObject(hdc, hfnSave);
+ wnd->getArgs()->add("clock.width",sz.cx+2*STYLE_SZ_GAP);
+ wnd->getArgs()->add("clock.height",sz.cy);
+ STYLE_SZ_CLOCK = sz.cx+2*STYLE_SZ_GAP;
+ }
+
+ wnd->getArgs()->clear();
+ wnd->getArgs()->add("options.avatarsize", PopUpOptions.avatarSize);
+ wnd->getArgs()->add("window.width", maxw);
+ wnd->getArgs()->add("window.maxwidth", maxw);
+
+ for (int i = 0; i < 32; ++i)
+ {
+ char buf[10];
+ wsprintfA(buf, "opt%d", i);
+ wnd->getArgs()->add(buf, (m_flags&(1L<<i)) ? 1 : 0);
+ }
+
+ SIZE sz;
+ sz.cx = sz.cy = 0;
+ head = m_elements;
+ while (head)
+ {
+ if ((m_flags & head->flag_mask) != (head->flags & head->flag_mask))
+ {
+ head = head->next;
+ continue;
+ }
+
+ SIZE szNew = {0,0};
+ switch (head->type & ST_TYPEMASK)
+ {
+ case ST_TEXT:
+ {
+ int tmp = head->fw.eval(wnd->getArgs());
+ // this is used to measure and layout text
+ wnd->getRenderInfo()->textw = tmp ? tmp : (maxw - head->fx.eval(wnd->getArgs()));
+ szNew.cx = wnd->getRenderInfo()->textw;
+ if (wnd->isTextEmpty())
+ {
+ szNew.cx = szNew.cy = 0;
+ } else
+ {
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.text);
+ switch (wnd->getTextType())
+ {
+ case PopupWnd2::TT_ANSI:
+ {
+ RECT rc; SetRect(&rc, 0, 0, szNew.cx, 0);
+ DrawTextExA(hdc, wnd->getTextA(), lstrlenA(wnd->getTextA()), &rc,
+ DT_CALCRECT|DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ szNew.cx = rc.right;
+ szNew.cy = rc.bottom;
+ break;
+ }
+ case PopupWnd2::TT_UNICODE:
+ {
+#if defined(_UNICODE)
+ RECT rc; SetRect(&rc, 0, 0, szNew.cx, 0);
+ DrawTextExW(hdc, wnd->getTextW(), lstrlenW(wnd->getTextW()), &rc,
+ DT_CALCRECT|DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ szNew.cx = rc.right;
+ szNew.cy = rc.bottom;
+#else
+ if (g_popup.isOsUnicode && MyDrawTextExW)
+ {
+ RECT rc; SetRect(&rc, 0, 0, szNew.cx, 0);
+ MyDrawTextExW(hdc, wnd->getTextW(), lstrlenW(wnd->getTextW()), &rc,
+ DT_CALCRECT|DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ szNew.cx = rc.right;
+ szNew.cy = rc.bottom;
+ }
+#endif
+ break;
+ }
+ case PopupWnd2::TT_MTEXT:
+ {
+ MText.Measure(hdc, &szNew, wnd->getTextM());
+ break;
+ }
+ }
+ SelectObject(hdc, hFntSave);
+ }
+
+ wnd->getRenderInfo()->texth = szNew.cy;
+
+ SIZE szActions = measureActionBar(hdc, wnd);
+ wnd->getRenderInfo()->actw = szActions.cx;
+ if (szActions.cy)
+ {
+ szNew.cx = max(szNew.cx, szActions.cx);
+ szNew.cy += szActions.cy;
+ szNew.cy += 3;
+ }
+
+ wnd->getRenderInfo()->realtextw = szNew.cx;
+
+ if (szNew.cx > maxw - head->fx.eval(wnd->getArgs()))
+ szNew.cx = maxw - head->fx.eval(wnd->getArgs());
+ wnd->getArgs()->add("text.width", szNew.cx);
+ wnd->getArgs()->add("text.height", szNew.cy);
+
+ break;
+ }
+
+ case ST_TITLE:
+ {
+ int tmp = head->fw.eval(wnd->getArgs());
+ // this is used to measure and layout text
+ wnd->getRenderInfo()->titlew = tmp ? tmp : (maxw - head->fx.eval(wnd->getArgs()) - STYLE_SZ_CLOCK);
+ szNew.cx = wnd->getRenderInfo()->titlew;
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.title);
+ switch (wnd->getTextType())
+ {
+ case PopupWnd2::TT_ANSI:
+ {
+ RECT rc; SetRect(&rc, 0, 0, szNew.cx, 0);
+ DrawTextExA(hdc, wnd->getTitleA(), lstrlenA(wnd->getTitleA()), &rc,
+ DT_CALCRECT|DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ szNew.cx = rc.right;
+ szNew.cy = rc.bottom;
+ break;
+ }
+ case PopupWnd2::TT_UNICODE:
+ {
+#if defined(_UNICODE)
+ RECT rc; SetRect(&rc, 0, 0, szNew.cx, 0);
+ DrawTextExW(hdc, wnd->getTitleW(), lstrlenW(wnd->getTitleW()), &rc,
+ DT_CALCRECT|DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ szNew.cx = rc.right;
+ szNew.cy = rc.bottom;
+#else
+ if (g_popup.isOsUnicode && MyDrawTextExW)
+ {
+ RECT rc; SetRect(&rc, 0, 0, szNew.cx, 0);
+ MyDrawTextExW(hdc, wnd->getTitleW(), lstrlenW(wnd->getTitleW()), &rc,
+ DT_CALCRECT|DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ szNew.cx = rc.right;
+ szNew.cy = rc.bottom;
+ }
+#endif
+ break;
+ }
+ case PopupWnd2::TT_MTEXT:
+ {
+ MText.Measure(hdc, &szNew, wnd->getTitleM());
+ break;
+ }
+ }
+ SelectObject(hdc, hFntSave);
+ if (szNew.cx > maxw - head->fx.eval(wnd->getArgs()) - STYLE_SZ_CLOCK)
+ szNew.cx = maxw - head->fx.eval(wnd->getArgs()) - STYLE_SZ_CLOCK;
+ szNew.cx += STYLE_SZ_CLOCK;
+ wnd->getArgs()->add("title.width", szNew.cx);
+ wnd->getArgs()->add("title.height", szNew.cy);
+ break;
+ }
+
+ case ST_ICON:
+ szNew.cx = szNew.cy = 16;
+ wnd->getArgs()->add("icon.width",16);
+ wnd->getArgs()->add("icon.height",16);
+ break;
+
+ case ST_BITMAP:
+// szNew.cx = szNew.cy = 0;
+ GetBmpSize(head->hbm, &szNew);
+ break;
+
+ case ST_MYBITMAP:
+ szNew.cx = head->myBmp->getWidth();
+ szNew.cy = head->myBmp->getHeight();
+ break;
+
+ case ST_AVATAR:
+ wnd->getRenderInfo()->hasAvatar = false;
+ szNew.cx = szNew.cy = 0;
+ if (wnd->getAvatar())
+ {
+ szNew.cx = wnd->getAvatar()->getWidth();
+ szNew.cy = wnd->getAvatar()->getHeight();
+ wnd->getArgs()->add("avatarbitmap.width",max(1,szNew.cx));
+ wnd->getArgs()->add("avatarbitmap.height",max(1,szNew.cy));
+ wnd->getRenderInfo()->hasAvatar = true;
+ }
+ break;
+
+ case ST_CLOCK:
+ if (head && head->myBmp)
+ {
+ szNew.cx = head->clocksize[CLOCK_LEFT]+head->clocksize[CLOCK_RIGHT];
+ szNew.cy = head->myBmp->getHeight();
+ for (char *p = wnd->getTime(); *p; p++)
+ {
+ if (*p == ':')
+ {
+ szNew.cx += head->clocksize[CLOCK_SEPARATOR];
+ } else
+ if ((*p >= '0') && (*p <= '9'))
+ {
+ szNew.cx += head->clocksize[CLOCK_DIGITS+*p-'0'];
+ }
+ }
+ wnd->getArgs()->add("clock.width",szNew.cx);
+ wnd->getArgs()->add("clock.height",szNew.cy);
+ } else
+ {
+ HFONT hfnSave = (HFONT)SelectObject(hdc, fonts.clock);
+ SIZE sz; GetTextExtentPoint32A(hdc, wnd->getTime(), lstrlenA(wnd->getTime()), &sz);
+ SelectObject(hdc, hfnSave);
+ wnd->getArgs()->add("clock.width",sz.cx+2*STYLE_SZ_GAP);
+ wnd->getArgs()->add("clock.height",sz.cy);
+ }
+ break;
+ }
+
+ if (head->proportional && szNew.cx && szNew.cy && (((head->fw.eval(wnd->getArgs()) > 0) && !head->fh.eval(wnd->getArgs())) || (!head->fw.eval(wnd->getArgs()) && (head->fh.eval(wnd->getArgs()) > 0))))
+ {
+ if (head->fw.eval(wnd->getArgs()))
+ {
+ szNew.cy = szNew.cy * head->fw.eval(wnd->getArgs()) / szNew.cx;
+ szNew.cx = head->fw.eval(wnd->getArgs());
+ } else
+ {
+ szNew.cx = szNew.cx * head->fh.eval(wnd->getArgs()) / szNew.cy;
+ szNew.cy = head->fh.eval(wnd->getArgs());
+// szNew.cx = head->fx.eval(wnd->getArgs()) + szNew.cx * head->fh.eval(wnd->getArgs()) / szNew.cy;
+// szNew.cy = head->fy.eval(wnd->getArgs()) + head->fh.eval(wnd->getArgs());
+ }
+ }
+
+ if ((head->type & ST_TYPEMASK) == ST_AVATAR)
+ {
+ wnd->getArgs()->add("avatar.width",szNew.cx);
+ wnd->getArgs()->add("avatar.height",szNew.cy);
+
+ szNew.cy += 2;
+ }
+
+ if (!head->fw.eval(wnd->getArgs()))
+ szNew.cx += head->fx.eval(wnd->getArgs());
+ else
+ if (head->fw.eval(wnd->getArgs()) > 0)
+ szNew.cx = head->fx.eval(wnd->getArgs()) + head->fw.eval(wnd->getArgs());
+ else
+ szNew.cx = 0;
+
+ if (!head->fh.eval(wnd->getArgs()))
+ szNew.cy += head->fy.eval(wnd->getArgs());
+ else
+ if (head->fh.eval(wnd->getArgs()) > 0)
+ szNew.cy = head->fy.eval(wnd->getArgs()) + head->fh.eval(wnd->getArgs());
+ else
+ szNew.cy = 0;
+
+ if (head->fx.eval(wnd->getArgs()) >= 0 && szNew.cx > sz.cx) sz.cx = szNew.cx;
+ if (head->fy.eval(wnd->getArgs()) >= 0 && szNew.cy > sz.cy) sz.cy = szNew.cy;
+
+ head = head->next;
+ }
+// if (pw->title_height > 20)
+// sz.cy += pw->title_height - 20;
+
+ sz.cx += m_right_gap;
+ sz.cy += m_bottom_gap;
+
+ int tmp;
+
+ if (tmp = m_fw.eval(wnd->getArgs())) sz.cx = tmp;
+ if (tmp = m_fh.eval(wnd->getArgs())) sz.cy = tmp;
+
+ if (options->DynamicResize)
+ {
+ if (options->UseMinimumWidth && sz.cx < options->MinimumWidth)
+ sz.cx = options->MinimumWidth;
+ } else
+ {
+ sz.cx = options->MaximumWidth;
+ }
+
+ wnd->getArgs()->add("window.width",sz.cx);
+ wnd->getArgs()->add("window.height",sz.cy);
+ wnd->setSize(sz);
+}
+
+void PopupSkin::display(MyBitmap *bmp, PopupWnd2 *wnd, int maxw, POPUPOPTIONS *options, DWORD drawFlags) const
+{
+ if (!m_elements) return;
+
+ HDC hdc = bmp->getDC();
+ SKINELEMENT *head = NULL;
+
+ int STYLE_SZ_CLOCK = 0;
+ if (!this->useInternalClock())
+ for (head = m_elements; head; head = head->next)
+ if ((head->type&ST_TYPEMASK) == ST_CLOCK)
+ break;
+ if (head && head->myBmp)
+ {
+ SIZE szNew;
+ szNew.cx = head->clocksize[CLOCK_LEFT]+head->clocksize[CLOCK_RIGHT];
+ szNew.cy = head->myBmp->getHeight();
+ for (char *p = wnd->getTime(); *p; p++)
+ {
+ if (*p == ':')
+ {
+ szNew.cx += head->clocksize[CLOCK_SEPARATOR];
+ } else
+ if ((*p >= '0') && (*p <= '9'))
+ {
+ szNew.cx += head->clocksize[CLOCK_DIGITS+*p-'0'];
+ }
+ }
+ STYLE_SZ_CLOCK = szNew.cx;
+ } else
+ {
+ HFONT hfnSave = (HFONT)SelectObject(hdc, fonts.clock);
+ SIZE sz; GetTextExtentPoint32A(hdc, wnd->getTime(), lstrlenA(wnd->getTime()), &sz);
+ SelectObject(hdc, hfnSave);
+ STYLE_SZ_CLOCK = sz.cx + 2*STYLE_SZ_GAP;
+ }
+
+
+ head = m_elements;
+
+ SIZE sz;
+ SIZE szWnd = wnd->getSize();
+ SIZE pos;
+ bool actionsRendered = false;
+ while (head)
+ {
+ if ((head->type&ST_TYPEMASK) == ST_AVATAR)
+ {
+ if (wnd->getAvatar()->isAnimated() && !(drawFlags&DF_ANIMATE))
+ {
+ head = head->next;
+ continue;
+ }
+ if (!wnd->getAvatar()->isAnimated() && !(drawFlags&DF_STATIC))
+ {
+ head = head->next;
+ continue;
+ }
+ } else
+ if ((head->type&ST_TYPEMASK) == ST_TEXT)
+ {
+ if (!wnd->getActionCount() && !(drawFlags&DF_STATIC))
+ {
+ head = head->next;
+ continue;
+ }
+ } else
+ if (!(drawFlags&DF_STATIC))
+ {
+ head = head->next;
+ continue;
+ }
+
+ if ((head->type&ST_BADPOS) || ((m_flags & head->flag_mask) != (head->flags & head->flag_mask)))
+ {
+ head = head->next;
+ continue;
+ }
+
+ int hShift = 0;
+ switch (head->type & ST_TYPEMASK)
+ {
+ case ST_TEXT:
+ {
+ if (head->textColor != (COLORREF)0xffffffff)
+ SetTextColor(hdc, head->textColor);
+ else
+ SetTextColor(hdc, wnd->getTextColor());
+
+ POINT pos;
+ pos.x = head->fx.eval(wnd->getArgs());
+ pos.y = head->fy.eval(wnd->getArgs());
+ SIZE sz;
+ sz.cx = wnd->getRenderInfo()->textw;
+ sz.cy = 1000;
+
+ SetRect(&wnd->getRenderInfo()->textRect, pos.x, pos.y,
+ pos.x + wnd->getRenderInfo()->realtextw,
+ pos.y + wnd->getRenderInfo()->texth);
+
+ if ((drawFlags&DF_STATIC) && !wnd->isTextEmpty())
+ {
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.text);
+ bmp->saveAlpha();
+ switch (wnd->getTextType())
+ {
+ case PopupWnd2::TT_ANSI:
+ {
+ RECT rc; SetRect(&rc, pos.x, pos.y, pos.x+sz.cx, pos.y+sz.cy);
+ DrawTextExA(hdc, wnd->getTextA(), lstrlenA(wnd->getTextA()), &rc,
+ DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ break;
+ }
+ case PopupWnd2::TT_UNICODE:
+ {
+#if defined(_UNICODE)
+ RECT rc; SetRect(&rc, pos.x, pos.y, pos.x+sz.cx, pos.y+sz.cy);
+ DrawTextExW(hdc, wnd->getTextW(), lstrlenW(wnd->getTextW()), &rc,
+ DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+#else
+ if (g_popup.isOsUnicode && MyDrawTextExW)
+ {
+ RECT rc; SetRect(&rc, pos.x, pos.y, pos.x+sz.cx, pos.y+sz.cy);
+ MyDrawTextExW(hdc, wnd->getTextW(), lstrlenW(wnd->getTextW()), &rc,
+ DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ }
+#endif
+ break;
+ }
+ case PopupWnd2::TT_MTEXT:
+ {
+ MText.Display(hdc, pos, sz, wnd->getTextM());
+ break;
+ }
+ }
+ SelectObject(hdc, hFntSave);
+ bmp->restoreAlpha();
+ }
+
+ if (!actionsRendered && (drawFlags&DF_ANIMATE))
+ {
+ int textAreaWidth = head->fw.eval(wnd->getArgs());
+ if (textAreaWidth <= 0) textAreaWidth = wnd->getRenderInfo()->realtextw;
+
+ drawActionBar(bmp, wnd,
+ DBGetContactSettingByte(NULL, MODULNAME, "CenterActions", 0) ?
+ (pos.x + (textAreaWidth - wnd->getRenderInfo()->actw)/2) :
+ (PopUpOptions.actions&ACT_RIGHTICONS) ?
+ (pos.x + textAreaWidth - wnd->getRenderInfo()->actw) :
+ // else
+ pos.x,
+ pos.y + wnd->getRenderInfo()->texth + 3);
+
+ actionsRendered = true;
+ }
+
+
+ break;
+ }
+
+ case ST_TITLE:
+ {
+ if (head->textColor != (COLORREF)0xffffffff)
+ SetTextColor(hdc, head->textColor);
+ else
+ SetTextColor(hdc, wnd->getTitleColor());
+
+ bmp->saveAlpha();
+ POINT pos;
+ pos.x = head->fx.eval(wnd->getArgs());
+ pos.y = head->fy.eval(wnd->getArgs());
+ SIZE sz;
+ sz.cx = wnd->getRenderInfo()->titlew;
+ sz.cy = 1000;
+
+ switch (wnd->getTextType())
+ {
+ case PopupWnd2::TT_ANSI:
+ {
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.title);
+ RECT rc; SetRect(&rc, pos.x, pos.y, pos.x+sz.cx, pos.y+sz.cy);
+ DrawTextExA(hdc, wnd->getTitleA(), lstrlenA(wnd->getTitleA()), &rc,
+ DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ SelectObject(hdc, hFntSave);
+ break;
+ }
+ case PopupWnd2::TT_UNICODE:
+ {
+#if defined(_UNICODE)
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.title);
+ RECT rc; SetRect(&rc, pos.x, pos.y, pos.x+sz.cx, pos.y+sz.cy);
+ DrawTextExW(hdc, wnd->getTitleW(), lstrlenW(wnd->getTitleW()), &rc,
+ DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ SelectObject(hdc, hFntSave);
+#else
+ if (g_popup.isOsUnicode && MyDrawTextExW)
+ {
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.title);
+ RECT rc; SetRect(&rc, pos.x, pos.y, pos.x+sz.cx, pos.y+sz.cy);
+ MyDrawTextExW(hdc, wnd->getTitleW(), lstrlenW(wnd->getTitleW()), &rc,
+ DT_EXPANDTABS|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK/*|DT_RTLREADING*/, NULL);
+ SelectObject(hdc, hFntSave);
+ }
+#endif
+ break;
+ }
+ case PopupWnd2::TT_MTEXT:
+ {
+ HFONT hFntSave = (HFONT)SelectObject(hdc, fonts.title);
+ MText.Display(hdc, pos, sz, wnd->getTitleM());
+ SelectObject(hdc, hFntSave);
+ break;
+ }
+ }
+
+ bmp->restoreAlpha();
+ break;
+ }
+
+ case ST_ICON:
+ bmp->DrawIcon(wnd->getIcon(), head->fx.eval(wnd->getArgs()), head->fy.eval(wnd->getArgs()), 16, 16);
+ break;
+
+ case ST_MYBITMAP:
+ sz.cx = head->myBmp->getWidth();
+ sz.cy = head->myBmp->getHeight();
+/*
+ if (head->fh.eval(wnd->getArgs()) > 0)
+ sz.cy = head->fh.eval(wnd->getArgs());
+ else
+ if (head->fh.eval(wnd->getArgs()) < 0)
+ sz.cy = szWnd.cy - head->fy.eval(wnd->getArgs()) + head->fh.eval(wnd->getArgs());
+
+ if (head->fw.eval(wnd->getArgs()) > 0)
+ sz.cx = head->fw.eval(wnd->getArgs());
+ else
+ if (head->fw.eval(wnd->getArgs()) < 0)
+ sz.cx = szWnd.cx - head->fx.eval(wnd->getArgs()) + head->fw.eval(wnd->getArgs());
+*/
+ if (head->proportional && sz.cx && sz.cy && (((head->fw.eval(wnd->getArgs()) > 0) && !head->fh.eval(wnd->getArgs())) || (!head->fw.eval(wnd->getArgs()) && (head->fh.eval(wnd->getArgs()) > 0))))
+ {
+ if (head->fw.eval(wnd->getArgs()))
+ {
+ sz.cy = sz.cy * head->fw.eval(wnd->getArgs()) / sz.cx;
+ sz.cx = head->fw.eval(wnd->getArgs());
+ } else
+ {
+ sz.cx = sz.cx * head->fh.eval(wnd->getArgs()) / sz.cy;
+ sz.cy = head->fh.eval(wnd->getArgs());
+ }
+ } else
+ {
+ if (head->fh.eval(wnd->getArgs()) > 0)
+ sz.cy = head->fh.eval(wnd->getArgs());
+ else
+ if (head->fh.eval(wnd->getArgs()) < 0)
+ sz.cy = szWnd.cy - head->fy.eval(wnd->getArgs()) + head->fh.eval(wnd->getArgs()) + 1;
+ if (head->fw.eval(wnd->getArgs()) > 0)
+ sz.cx = head->fw.eval(wnd->getArgs());
+ else
+ if (head->fw.eval(wnd->getArgs()) < 0)
+ sz.cx = szWnd.cx - head->fx.eval(wnd->getArgs()) + head->fw.eval(wnd->getArgs()) + 1;
+ }
+
+ bool vars;
+ pos.cx = ((head->fx.eval(wnd->getArgs(), &vars) < 0) && !vars) ? szWnd.cx + head->fx.eval(wnd->getArgs()) : head->fx.eval(wnd->getArgs());
+ pos.cy = ((head->fy.eval(wnd->getArgs(), &vars) < 0) && !vars) ? szWnd.cy + head->fy.eval(wnd->getArgs()) : head->fy.eval(wnd->getArgs());
+
+ if (head->type & ST_MONO)
+ {
+ COLORREF back = wnd->getBackColor();
+ if (head->type & ST_BLEND)
+ {
+ bmp->BlendColorized(head->myBmp, pos.cx, pos.cy, sz.cx, sz.cy, back);
+ } else
+ {
+ bmp->DrawColorized(head->myBmp, pos.cx, pos.cy, sz.cx, sz.cy, back);
+ }
+ } else
+ {
+ if (head->type & ST_BLEND)
+ {
+ bmp->Blend(head->myBmp, pos.cx, pos.cy, sz.cx ,sz.cy);
+ } else
+ {
+ bmp->Draw(head->myBmp, pos.cx, pos.cy, sz.cx ,sz.cy);
+ }
+ }
+ break;
+
+ case ST_AVATAR:
+ {
+ if (!wnd->getAvatar()) break;
+
+ sz.cx = wnd->getAvatar()->getWidth();
+ sz.cy = wnd->getAvatar()->getHeight();
+
+ if (head->proportional && sz.cx && sz.cy && (((head->fw.eval(wnd->getArgs()) > 0) && !head->fh.eval(wnd->getArgs())) || (!head->fw.eval(wnd->getArgs()) && (head->fh.eval(wnd->getArgs()) > 0))))
+ {
+ if (head->fw.eval(wnd->getArgs()))
+ {
+ sz.cy = sz.cy * head->fw.eval(wnd->getArgs()) / sz.cx;
+ sz.cx = head->fw.eval(wnd->getArgs());
+ } else
+ {
+ sz.cx = sz.cx * head->fh.eval(wnd->getArgs()) / sz.cy;
+ sz.cy = head->fh.eval(wnd->getArgs());
+ }
+ } else
+ {
+ if (head->fh.eval(wnd->getArgs()) > 0)
+ sz.cy = head->fh.eval(wnd->getArgs());
+ else
+ if (head->fh.eval(wnd->getArgs()) < 0)
+ sz.cy = szWnd.cy - head->fy.eval(wnd->getArgs()) + head->fh.eval(wnd->getArgs());
+
+ if (head->fw.eval(wnd->getArgs()) > 0)
+ sz.cx = head->fw.eval(wnd->getArgs());
+ else
+ if (head->fw.eval(wnd->getArgs()) < 0)
+ sz.cx = szWnd.cx - head->fx.eval(wnd->getArgs()) + head->fw.eval(wnd->getArgs());
+ }
+
+ pos.cx = head->fx.eval(wnd->getArgs()) < 0 ? szWnd.cx + head->fx.eval(wnd->getArgs()) - sz.cx : head->fx.eval(wnd->getArgs());
+ pos.cy = head->fy.eval(wnd->getArgs()) < 0 ? szWnd.cy + head->fy.eval(wnd->getArgs()) - sz.cy : head->fy.eval(wnd->getArgs());
+
+ wnd->getAvatar()->draw(bmp, pos.cx, pos.cy, sz.cx, sz.cy, options);
+ break;
+ }
+
+ case ST_CLOCK:
+ {
+ if (!options->DisplayTime)
+ break;
+
+ COLORREF back = wnd->getBackColor();
+ int x = head->fx.eval(wnd->getArgs());
+ int y = head->fy.eval(wnd->getArgs());
+ if (head->myBmp)
+ {
+ int sy = head->myBmp->getHeight();
+ if (head->type & ST_MONO)
+ bmp->BlendPartColorized(head->myBmp, head->clockstart[CLOCK_LEFT], 0, head->clocksize[CLOCK_LEFT], sy, x, y, head->clocksize[CLOCK_LEFT], sy, back);
+ else
+ bmp->BlendPart(head->myBmp, head->clockstart[CLOCK_LEFT], 0, head->clocksize[CLOCK_LEFT], sy, x, y, head->clocksize[CLOCK_LEFT], sy);
+ x += head->clocksize[CLOCK_LEFT];
+ for (char *p = wnd->getTime(); *p; p++)
+ {
+ int clock_idx = -1;
+ if (*p == ':')
+ {
+ clock_idx = CLOCK_SEPARATOR;
+ } else
+ if ((*p >= '0') && (*p <= '9'))
+ {
+ clock_idx = CLOCK_DIGITS + *p - '0';
+ }
+
+ if (clock_idx >= 0)
+ {
+ if (head->type & ST_MONO)
+ bmp->BlendPartColorized(head->myBmp, head->clockstart[clock_idx], 0, head->clocksize[clock_idx], sy, x, y, head->clocksize[clock_idx], sy, back);
+ else
+ bmp->BlendPart(head->myBmp, head->clockstart[clock_idx], 0, head->clocksize[clock_idx], sy, x, y, head->clocksize[clock_idx], sy);
+ x += head->clocksize[clock_idx];
+ }
+ }
+ if (head->type & ST_MONO)
+ bmp->BlendPartColorized(head->myBmp, head->clockstart[CLOCK_RIGHT], 0, head->clocksize[CLOCK_RIGHT], sy, x, y, head->clocksize[CLOCK_RIGHT], sy, back);
+ else
+ bmp->BlendPart(head->myBmp, head->clockstart[CLOCK_RIGHT], 0, head->clocksize[CLOCK_RIGHT], sy, x, y, head->clocksize[CLOCK_RIGHT], sy);
+ x += head->clocksize[CLOCK_RIGHT];
+ } else
+ {
+ SetTextColor(hdc, wnd->getClockColor());
+ HFONT hfnSave = (HFONT)SelectObject(bmp->getDC(), fonts.clock);
+ SIZE sz; GetTextExtentPoint32A(bmp->getDC(), wnd->getTime(), lstrlenA(wnd->getTime()), &sz);
+ bmp->Draw_TextA(wnd->getTime(), x, y);
+ SelectObject(bmp->getDC(), hfnSave);
+ }
+ break;
+ }
+ }
+ head = head->next;
+ }
+
+}
+
+bool PopupSkin::onMouseMove(PopupWnd2 *wnd, int x, int y) const
+{
+ POINT pt;
+ pt.x = x;
+ pt.y = y;
+
+ bool res = false;
+ bool hovered = false;
+
+ for (int i = 0; i < wnd->getActionCount(); ++i)
+ {
+ bool hover = PtInRect(&wnd->getActions()[i].rc, pt) ? true : false;
+ hovered |= hover;
+ if (wnd->getActions()[i].hover != hover)
+ {
+ wnd->getActions()[i].hover = hover;
+ res = true;
+ }
+ }
+
+ SetCursor(LoadCursor(NULL, hovered ? IDC_HAND : IDC_ARROW));
+
+ return res;
+}
+
+bool PopupSkin::onMouseLeave(PopupWnd2 *wnd) const
+{
+ bool res = false;
+
+ for (int i = 0; i < wnd->getActionCount(); ++i)
+ {
+ if (wnd->getActions()[i].hover)
+ {
+ wnd->getActions()[i].hover = false;
+ res = true;
+ }
+ }
+
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ return res;
+}
+
+void PopupSkin::loadOptions(std::istream &f)
+{
+ char *buf = new char[1024];
+ while (!f.eof())
+ {
+ f >> buf;
+ if (*buf == '#')
+ {
+ f.ignore(1024, '\n');
+ continue;
+ }
+ if (!strcmp(buf, "option"))
+ {
+ int id, val;
+ f >> id >> val;
+ f.getline(buf, 1024);
+ id--;
+ if (m_flag_names[id])
+ mir_free(m_flag_names[id]);
+ char *p = buf;
+ while (isspace(*p))
+ p++;
+ char *q = p + lstrlenA(p) - 1;
+ while ((q >= p) && isspace(*q))
+ *q-- = 0;
+ m_flag_names[id] = mir_strdup(p);
+ if (val)
+ m_flags |= 1 << id;
+ else
+ m_flags &= ~(1 << id);
+ } else
+ if (!strcmp(buf, "end"))
+ {
+ break;
+ }
+ }
+ delete [] buf;
+}
+
+bool PopupSkin::load(LPCTSTR dir)
+{
+ for (int i = 0; i < 32; i++)
+ {
+ if (m_flag_names[i])
+ {
+ mir_free(m_flag_names[i]);
+ m_flag_names[i] = NULL;
+ }
+ }
+ m_flags = 0;
+
+ if (!_tcsncmp(_T("res:"), dir, 4))
+ { // resource
+ loadSkin(dir+4, _T("Skin"));
+ } else
+ { // filesystem
+ // skin info
+ TCHAR dir_save[1024];
+ GetCurrentDirectory(1024, dir_save);
+ SetCurrentDirectory(dir);
+
+ std::ifstream theFile;
+ theFile.open("popupskin.config", std::ios::in);
+ if (theFile)
+ {
+ loadOptions(theFile);
+ theFile.close();
+ }
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = FindFirstFile(_T("*.popupskin"), &ffd);
+ while (hFind != INVALID_HANDLE_VALUE)
+ {
+ loadSkin(ffd.cFileName);
+ break;
+ if (!FindNextFile(hFind, &ffd))
+ break;
+ }
+ FindClose(hFind);
+
+ SetCurrentDirectory(dir_save);
+ }
+
+ loadOpts();
+
+ return true;
+}
+
+void PopupSkin::loadSkin(std::istream &f)
+{
+ m_bottom_gap = m_right_gap = 0;
+ m_legacy_region_opacity = 64;
+ m_shadow_region_opacity = 1;
+ m_popup_version = 0;
+ m_internalClock = true;
+
+ SKINELEMENT *head = new SKINELEMENT;
+ m_elements = head;
+ head->type = ST_NOTHING;
+ head->next = NULL;
+
+ while (!f.eof())
+ {
+ char buf[1024];
+ f >> buf;
+// fscanf(f, "%s", buf);
+
+ if (!*buf)
+ continue;
+
+ if (*buf == '#' || *buf == ';')
+ {
+ f.ignore(1024, '\n');
+ continue;
+ }
+
+ if (!lstrcmpA(buf,"popup-version"))
+ {
+ f >> m_popup_version;
+ m_popup_version = PLUGIN_MAKE_VERSION((m_popup_version/1000000)%100, (m_popup_version/10000)%100, (m_popup_version/100)%100, (m_popup_version/1)%100);
+ if (!isCompatible())
+ break;
+ } else
+ if (!lstrcmpA(buf,"padding-right"))
+ {
+ f >> m_right_gap;
+ } else
+ if (!lstrcmpA(buf,"padding-bottom"))
+ {
+ f >> m_bottom_gap;
+ } else
+ if (!lstrcmpA(buf,"shadow-region-opacity"))
+ {
+ f >> m_shadow_region_opacity;
+ } else
+ if (!lstrcmpA(buf,"legacy-region-opacity"))
+ {
+ f >> m_legacy_region_opacity;
+ } else
+ if (!lstrcmpA(buf,"w"))
+ {
+ f.getline(buf, 1024);
+ m_fw.set(buf);
+ } else
+ if (!lstrcmpA(buf,"h"))
+ {
+ f.getline(buf, 1024);
+ m_fh.set(buf);
+ } else
+ if (!lstrcmpA(buf,"object"))
+ {
+ head->next = loadObject(f);
+ if (head->next && ((head->next->type & ST_TYPEMASK) == ST_CLOCK))
+ m_internalClock = false;
+ head = head->next;
+ head->next = NULL;
+ } else
+ if (!lstrcmpA(buf,"options"))
+ {
+ loadOptions(f);
+ }
+ }
+
+
+ head = m_elements;
+ m_elements = m_elements->next;
+ delete head;
+}
+
+void PopupSkin::loadSkin(LPCTSTR fn)
+{
+ if(!fn) return;
+#if defined (_UNICODE) && _MSC_VER <= 1200
+ char* temp= mir_t2a(fn);
+ std::ifstream theFile;
+ theFile.open(temp, std::ios::in);
+ mir_free(temp);
+#else
+ std::ifstream theFile;
+ theFile.open(fn, std::ios::in);
+#endif
+ if (!theFile) return;
+ loadSkin(theFile);
+ theFile.close();
+}
+
+void PopupSkin::loadSkin(LPCTSTR lpName, LPCTSTR lpType)
+{
+ HRSRC hRes = FindResource(hInst, lpName, lpType);
+// DWORD ResSize = SizeofResource(hInst,hRes);
+ HRSRC hResLoad = (HRSRC)LoadResource(hInst, hRes);
+ char *lpResLock = (char *)LockResource(hResLoad);
+// lpResLock [ResSize] = 0;
+ std::istringstream stream(lpResLock);
+ loadSkin(stream);
+ UnlockResource(lpResLock);
+ FreeResource(hRes);
+}
+
+PopupSkin::SKINELEMENT *PopupSkin::loadObject(std::istream &f)
+{
+// char pth[1024];
+// GetSkinPath(pth,1024);
+
+ SKINELEMENT *element = new SKINELEMENT;
+// element->x = element->y = element->w = element->h = 0;
+ element->proportional = 0;
+ element->type = ST_NOTHING|ST_BADPOS;
+ element->next = NULL;
+ element->flag_mask = 0;
+ element->flags = 0;
+ element->myBmp = NULL;
+
+ while (!f.eof())
+ {
+ char buf[1024];
+ f >> buf;
+
+ if (!*buf)
+ continue;
+
+ if (*buf == '#' || *buf == ';')
+ {
+ f.ignore(1024, '\n');
+ continue;
+ }
+
+ if (!lstrcmpA(buf,"type"))
+ {
+ f >> buf;
+ if (!lstrcmpA(buf,"icon"))
+ element->type = ( element->type & ~ST_TYPEMASK ) | ST_ICON;
+ else
+ if (!lstrcmpA(buf,"bitmap"))
+ element->type = ( element->type & ~ST_TYPEMASK ) | ST_MYBITMAP;
+ else
+ if (!lstrcmpA(buf,"text"))
+ {
+ element->type = ( element->type & ~ST_TYPEMASK ) | ST_TEXT;
+ element->textColor = (COLORREF)0xffffffff;
+ element->hfn = 0;
+ }
+ else
+ if (!lstrcmpA(buf,"title"))
+ {
+ element->type = ( element->type & ~ST_TYPEMASK ) | ST_TITLE;
+ element->textColor = (COLORREF)0xffffffff;
+ element->hfn = 0;
+ } else
+ if (!lstrcmpA(buf,"avatar"))
+ {
+ element->type = ( element->type & ~ST_TYPEMASK ) | ST_AVATAR;
+ } else
+ if (!lstrcmpA(buf,"clock"))
+ {
+ element->type = ( element->type & ~ST_TYPEMASK ) | ST_CLOCK;
+ }
+ } else
+ if (!lstrcmpA(buf,"source"))
+ {
+ f >> buf;
+// fscanf(f, "%*[\x01-\x20]%[^\n]", buf);
+// if ( (element->type & ST_TYPEMASK ) == ST_BITMAP)
+// element->hbm = LoadImageFromFile(buf);
+// else
+ if (((element->type & ST_TYPEMASK) == ST_MYBITMAP) || ((element->type & ST_TYPEMASK) == ST_CLOCK))
+ {
+ char *alpha = mir_strdup(buf);
+ alpha[strlen(alpha)-1] = 'a';
+ element->myBmp = new MyBitmap(buf,alpha);
+ mir_free(alpha);
+ }
+ } else
+ if (!lstrcmpA(buf,"mono"))
+ {
+ element->type |= ST_MONO;
+ } else
+ if (!lstrcmpA(buf,"layer"))
+ {
+ element->type |= ST_BLEND;
+ } else
+ if (!lstrcmpA(buf,"proportional"))
+ {
+ f >> element->proportional;
+ } else
+ if (!lstrcmpA(buf,"x"))
+ {
+ f.getline(buf, 1024);
+ element->fx.set(buf);
+ element->type &= ~ST_BADPOS;
+ } else
+ if (!lstrcmpA(buf,"y"))
+ {
+ f.getline(buf, 1024);
+ element->fy.set(buf);
+ element->type &= ~ST_BADPOS;
+ } else
+ if (!lstrcmpA(buf,"w"))
+ {
+ f.getline(buf, 1024);
+ element->fw.set(buf);
+ } else
+ if (!lstrcmpA(buf,"h"))
+ {
+ f.getline(buf, 1024);
+ element->fh.set(buf);
+ } else
+ if (!lstrcmpA(buf,"ifset"))
+ {
+ int id;
+ f >> id; id--;
+ element->flag_mask |= 1 << id;
+ element->flags |= 1 << id;
+ } else
+ if (!lstrcmpA(buf,"ifnotset"))
+ {
+ int id;
+ f >> id; id--;
+ element->flag_mask |= 1 << id;
+ element->flags &= ~(1 << id);
+ } else
+ if (!lstrcmpA(buf,"color"))
+ {
+ if (((element->type & ST_TYPEMASK) != ST_TEXT) &&
+ ((element->type & ST_TYPEMASK) != ST_TITLE)) continue;
+
+ int r,g,b;
+ f >> r >> g >> b;
+ element->textColor = RGB(r,g,b);
+ } else
+ if (!lstrcmpA(buf,"clocksize"))
+ {
+ element->clockstart[0]=0;
+ f >> element->clocksize[0];
+ for (int i = 1; i < CLOCK_ITEMS; i++)
+ {
+ element->clockstart[i]=element->clockstart[i-1]+element->clocksize[i-1];
+ f >> element->clocksize[i];
+ }
+ } else
+ if (!lstrcmpA(buf,"end"))
+ {
+ break;
+ }
+ }
+ return element;
+}
+
+void PopupSkin::freeSkin(SKINELEMENT *head)
+{
+ while (head)
+ {
+ SKINELEMENT *next = head->next;
+
+ if ((head->type & ST_TYPEMASK) == ST_BITMAP)
+ DeleteObject(head->hbm);
+ if ((head->type & ST_TYPEMASK) == ST_MYBITMAP)
+ delete head->myBmp;
+ if (((head->type & ST_TYPEMASK) == ST_CLOCK) && head->myBmp)
+ delete head->myBmp;
+
+ delete head;
+ head = next;
+ }
+}
+
+void PopupSkin::saveOpts() const
+{
+ char buf[128];
+#if defined( _UNICODE )
+ mir_snprintf(buf, sizeof(buf), "skin.%.120S", m_name);
+#else
+ mir_snprintf(buf, sizeof(buf), "skin.%.120s", m_name);
+#endif
+ DBWriteContactSettingDword(NULL, MODULNAME, buf, m_flags);
+}
+
+void PopupSkin::loadOpts() const
+{
+ char buf[128];
+#if defined( _UNICODE )
+ mir_snprintf(buf, sizeof(buf), "skin.%.120S", m_name);
+#else
+ mir_snprintf(buf, sizeof(buf), "skin.%.120s", m_name);
+#endif
+ m_flags = DBGetContactSettingDword(NULL, MODULNAME, buf, m_flags);
+}
+
+// Skins
+Skins skins;
+
+Skins::Skins()
+{
+ m_skins = 0;
+}
+
+Skins::~Skins()
+{
+ while (m_skins)
+ {
+ SKINLIST *next = m_skins->next;
+ delete m_skins->skin;
+ delete [] m_skins->dir;
+ mir_free(m_skins->name); // this is allocated with mir_strdup()
+ delete m_skins;
+ m_skins = next;
+ }
+}
+
+bool Skins::load(LPCTSTR dir1)
+{
+ while (m_skins)
+ {
+ SKINLIST *next = m_skins->next;
+ mir_free(m_skins->name);
+ delete [] m_skins->dir;
+ delete m_skins->skin;
+ delete m_skins;
+ m_skins = next;
+ }
+
+ SKINLIST *skin = new SKINLIST;
+ skin->next = m_skins;
+ m_skins = skin;
+ m_skins->name = mir_tstrdup(_T("* Popup Classic"));
+ m_skins->dir = new TCHAR[1024];
+ lstrcpy(m_skins->dir, _T("res:classic.popupskin"));
+ m_skins->skin = 0;
+
+ TCHAR dir[1024]={'\0'};
+
+ if (ServiceExists(MS_FOLDERS_GET_PATH)) {
+ if (FoldersGetCustomPathT(folderId, dir, 1024, NULL) != 0)
+ return false;
+ }
+ else {
+ GetModuleFileName(hInst,dir,1024);
+ dir[lstrlen(dir)-18] = 0;
+ lstrcat(dir,_T("\\skins\\popup"));
+ DWORD fa = GetFileAttributes(dir);
+ if ((fa==INVALID_FILE_ATTRIBUTES) || !(fa&FILE_ATTRIBUTE_DIRECTORY))
+ return false;
+ }
+
+ TCHAR dir_save[1024];
+ GetCurrentDirectory(1024, dir_save);
+ SetCurrentDirectory(dir);
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = FindFirstFile(_T("*.*"), &ffd);
+ while (hFind != INVALID_HANDLE_VALUE)
+ {
+ if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && lstrcmp(_T("."), ffd.cFileName) && lstrcmp(_T(".."), ffd.cFileName))
+ {
+ SetCurrentDirectory(ffd.cFileName);
+
+ SKINLIST *skin = new SKINLIST;
+ skin->next = m_skins;
+ m_skins = skin;
+ m_skins->name = mir_tstrdup(ffd.cFileName);
+ m_skins->dir = new TCHAR[1024];
+ GetCurrentDirectory(1024, m_skins->dir);
+ m_skins->skin = 0;
+
+ SetCurrentDirectory(_T(".."));
+ }
+
+ if (!FindNextFile(hFind, &ffd))
+ break;
+ }
+ FindClose(hFind);
+
+ SetCurrentDirectory(dir_save);
+
+ return true;
+}
+
+const PopupSkin *Skins::getSkin(LPCTSTR name)
+{
+ SKINLIST *any = 0;
+ for (SKINLIST *p = m_skins; p; p = p->next)
+ {
+ if (!lstrcmp(p->name, _T("* Popup Classic")) || !any)
+ any = p;
+ if (!lstrcmpi(p->name, name))
+ {
+ any = p;
+ break;
+ }
+ }
+
+ if (any && any->skin)
+ return any->skin;
+ if (!any)
+ return 0;
+
+ any->skin = new PopupSkin(any->name);
+ any->skin->load(any->dir);
+
+ if (!any->skin->isCompatible())
+ MessageBox(NULL,
+ TranslateTS(
+ _T("The skin you are trying to load is designed\r\n")
+ _T("for newer version of Popup Plus. And will not\r\n")
+ _T("display properly.\r\n")
+ _T("\r\n")
+ _T("Please choose another skin.") ),
+ _T(MODULNAME_LONG), MB_ICONSTOP|MB_OK);
+
+ return any->skin;
+}
+
+void Skins::loadActiveSkin()
+{
+ for (SKINLIST *p = m_skins; p; p = p->next)
+ if (!lstrcmpi(p->name, PopUpOptions.SkinPack))
+ {
+ if (p->skin)
+ break;
+
+ p->skin = new PopupSkin(p->name);
+ p->skin->load(p->dir);
+ break;
+ }
+}
+
+void Skins::freeAllButActive()
+{
+ for (SKINLIST *p = m_skins; p; p = p->next)
+ if (lstrcmpi(p->name, PopUpOptions.SkinPack))
+ {
+ delete p->skin;
+ p->skin = NULL;
+ }
+}
diff --git a/plugins/Popup/src/skin.h b/plugins/Popup/src/skin.h
new file mode 100644
index 0000000000..8cc7171e01
--- /dev/null
+++ b/plugins/Popup/src/skin.h
@@ -0,0 +1,203 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/skin.h $
+Revision : $Revision: 1620 $
+Last change on : $Date: 2010-06-23 21:31:05 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __skin_h__
+#define __skin_h__
+
+#include <stdio.h>
+#include <fstream>
+
+class MyBitmap;
+class PopupWnd2;
+
+class PopupSkin
+{
+public:
+ enum
+ {
+ ST_TYPEMASK = 0x07,
+ ST_NOTHING = 0x00,
+ ST_ICON = 0x01,
+ ST_TEXT = 0x02,
+ ST_TITLE = 0x03,
+ ST_BITMAP = 0x04,
+ ST_MYBITMAP = 0x05,
+ ST_AVATAR = 0x06,
+ ST_CLOCK = 0x07,
+
+ ST_STRETCH = 0x08,
+ ST_MONO = 0x10,
+ ST_BLEND = 0x20,
+ ST_BADPOS = 0x40
+ };
+
+ enum
+ {
+ DF_STATIC = 0x01,
+ DF_ANIMATE = 0x02,
+ DF_ALL = 0xff
+ };
+
+ enum
+ {
+ // left, separator, digits, am/pm, right
+ CLOCK_LEFT = 0,
+ CLOCK_SEPARATOR = 1,
+ CLOCK_DIGITS = 2,
+ CLOCK_AM = 12,
+ CLOCK_PM = 13,
+ CLOCK_RIGHT = 14,
+ CLOCK_ITEMS = 1+1+10+2+1
+ };
+
+ struct SKINELEMENT
+ {
+ int type;
+ union
+ {
+ HICON hic;
+ HBITMAP hbm;
+ MyBitmap *myBmp;
+ struct
+ {
+ COLORREF textColor;
+ HFONT hfn;
+// int textw;
+ };
+ };
+ unsigned long flags;
+ unsigned long flag_mask;
+ Formula fx, fy, fw, fh;
+ int clocksize[CLOCK_ITEMS];
+ int clockstart[CLOCK_ITEMS];
+ int proportional;
+ SKINELEMENT *next;
+ };
+
+ struct RenderInfo
+ {
+ bool hasAvatar;
+ int titlew, textw;
+ int realtextw, texth;
+ int actw;
+ RECT textRect;
+ };
+
+private:
+ LPTSTR m_name;
+ int m_bottom_gap, m_right_gap;
+ int m_legacy_region_opacity, m_shadow_region_opacity;
+ int m_popup_version;
+ bool m_internalClock;
+ Formula m_fw, m_fh;
+ SKINELEMENT *m_elements;
+ char *m_flag_names[32];
+ mutable unsigned long m_flags;
+
+ void loadOptions(std::istream &f);
+ SKINELEMENT *loadObject(std::istream &f);
+ void loadSkin(std::istream &f);
+ void loadSkin(LPCTSTR fn);
+ void loadSkin(LPCTSTR lpName, LPCTSTR lpType);
+
+ void freeSkin(SKINELEMENT *head);
+
+ SIZE measureAction(HDC hdc, POPUPACTION *act) const;
+ SIZE measureActionBar(HDC hdc, PopupWnd2 *wnd) const;
+ void drawAction(MyBitmap *bmp, POPUPACTION *act, int x, int y, bool hover) const;
+ void drawActionBar(MyBitmap *bmp, PopupWnd2 *wnd, int x, int y) const;
+
+public:
+ PopupSkin(LPCTSTR aName = 0);
+ ~PopupSkin();
+
+ void measure(HDC hdc, PopupWnd2 *wnd, int maxw, POPUPOPTIONS *options) const;
+ void display(MyBitmap *bmp, PopupWnd2 *wnd, int maxw, POPUPOPTIONS *options, DWORD drawFlags=DF_ALL) const;
+ bool onMouseMove(PopupWnd2 *wnd, int x, int y) const;
+ bool onMouseLeave(PopupWnd2 *wnd) const;
+
+ bool load(LPCTSTR dir); // load skin from current directory
+
+ SKINELEMENT *getSubSkin() { return m_elements; }
+ int getBottomGap() const { return m_bottom_gap; }
+ int getRightGap() const { return m_right_gap; }
+ int useInternalClock() const { return m_internalClock; }
+ int getLegacyRegionOpacity() const { return m_legacy_region_opacity; }
+ int getShadowRegionOpacity() const { return m_shadow_region_opacity; }
+ bool isCompatible() const { return (DWORD) m_popup_version <= (DWORD) pluginInfoEx.version; }
+
+ const LPTSTR getName() const { return m_name; }
+
+ const char *getFlagName(int id) const { return m_flag_names[id-1]; }
+ bool getFlag(int id) const { return (m_flags & (1 << (id-1))) != 0; }
+ void setFlag(int id, bool val) const
+ {
+ if (val)
+ m_flags |= 1 << (id-1);
+ else
+ m_flags &= ~(1 << (id-1));
+ }
+
+ void saveOpts() const;
+ void loadOpts() const;
+};
+
+class Skins
+{
+public:
+ struct SKINLIST
+ {
+ PopupSkin *skin;
+ LPTSTR dir;
+ LPTSTR name;
+ SKINLIST *next;
+ };
+
+private:
+ SKINLIST *m_skins;
+
+public:
+ Skins();
+ ~Skins();
+
+ bool load(LPCTSTR dir);
+ const PopupSkin *getSkin(LPCTSTR name);
+
+ const SKINLIST *getSkinList() const { return m_skins; }
+
+ void loadActiveSkin();
+ void freeAllButActive();
+};
+
+extern Skins skins;
+
+#endif
diff --git a/plugins/Popup/src/srmm_menu.cpp b/plugins/Popup/src/srmm_menu.cpp
new file mode 100644
index 0000000000..398d500e81
--- /dev/null
+++ b/plugins/Popup/src/srmm_menu.cpp
@@ -0,0 +1,171 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/srmm_menu.cpp $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#include "headers.h"
+
+/*************************************************************************************
+ === how does this work ===
+ We have four icons -- one for each mode. and we do hide/show them depending
+ on current active mode for user.
+*************************************************************************************/
+
+static HANDLE hDialogsList = NULL;
+static HANDLE hIconPressed=0,hWindowEvent=0;
+
+static int SrmmMenu_ProcessEvent(WPARAM wParam, LPARAM lParam);
+static int SrmmMenu_ProcessIconClick(WPARAM wParam, LPARAM lParam);
+
+
+void SrmmMenu_Load()
+{
+ if (ServiceExists(MS_MSG_ADDICON))
+ {
+ StatusIconData sid = {0};
+ sid.cbSize = sizeof(sid);
+ sid.szModule = MODULNAME;
+ sid.flags = 0;
+
+ sid.dwId = 0;
+ sid.szTooltip = Translate("Popup Mode: Auto");
+ sid.hIcon = sid.hIconDisabled = IcoLib_GetIcon(ICO_POPUP_ON,0);
+ CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
+
+ sid.dwId = 1;
+ sid.szTooltip = Translate("Popup Mode: Favourite");
+ sid.hIcon = sid.hIconDisabled = IcoLib_GetIcon(ICO_FAV,0);
+ CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
+
+ sid.dwId = 2;
+ sid.szTooltip = Translate("Popup Mode: Ignore fullscreen");
+ sid.hIcon = sid.hIconDisabled = IcoLib_GetIcon(ICO_FULLSCREEN,0);
+ CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
+
+ sid.dwId = 3;
+ sid.szTooltip = Translate("Popup Mode: Block contact");
+ sid.hIcon = sid.hIconDisabled = IcoLib_GetIcon(ICO_POPUP_OFF,0);
+ CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
+
+ hIconPressed = HookEvent(ME_MSG_ICONPRESSED, SrmmMenu_ProcessIconClick);
+ hWindowEvent = HookEvent(ME_MSG_WINDOWEVENT, SrmmMenu_ProcessEvent);
+/*
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+ SrmmMenu_UpdateIcon(hContact);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+*/
+ }
+}
+
+void SrmmMenu_Unload()
+{
+ UnhookEvent(hIconPressed);
+ UnhookEvent(hWindowEvent);
+}
+
+static void SrmmMenu_UpdateIcon(HANDLE hContact)
+{
+ if (!hContact) return;
+
+ int mode = DBGetContactSettingByte(hContact, MODULNAME, "ShowMode", PU_SHOWMODE_AUTO);
+
+ StatusIconData sid = {0};
+ sid.cbSize = sizeof(sid);
+ sid.szModule = MODULNAME;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ sid.dwId = i;
+ sid.flags = (i == mode) ? 0 : MBF_HIDDEN;
+ CallService(MS_MSG_MODIFYICON, (WPARAM)hContact, (LPARAM)&sid);
+ }
+}
+
+static int SrmmMenu_ProcessEvent(WPARAM wParam, LPARAM lParam)
+{
+ MessageWindowEventData *event = (MessageWindowEventData *)lParam;
+
+ if ( event->uType == MSG_WINDOW_EVT_OPEN )
+ {
+ if (!hDialogsList)
+ hDialogsList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
+
+ WindowList_Add(hDialogsList, event->hwndWindow, event->hContact);
+ SrmmMenu_UpdateIcon(event->hContact);
+ }
+ else if ( event->uType == MSG_WINDOW_EVT_CLOSING )
+ {
+ if (hDialogsList)
+ WindowList_Remove(hDialogsList, event->hwndWindow);
+ }
+
+ return 0;
+}
+
+static int SrmmMenu_ProcessIconClick(WPARAM wParam, LPARAM lParam)
+{
+ StatusIconClickData *sicd = (StatusIconClickData *)lParam;
+ if (lstrcmpA(sicd->szModule, MODULNAME)) return 0;
+
+ HANDLE hContact = (HANDLE)wParam;
+ if (!hContact) return 0;
+
+ int mode = DBGetContactSettingByte(hContact, MODULNAME, "ShowMode", PU_SHOWMODE_AUTO);
+
+ if (sicd->flags&MBCF_RIGHTBUTTON)
+ {
+ HMENU hMenu = CreatePopupMenu();
+
+ AppendMenu(hMenu, MF_STRING, 1+PU_SHOWMODE_AUTO, TranslateT("Auto"));
+ AppendMenu(hMenu, MF_STRING, 1+PU_SHOWMODE_FAVORITE, TranslateT("Favourite"));
+ AppendMenu(hMenu, MF_STRING, 1+PU_SHOWMODE_FULLSCREEN, TranslateT("Ignore fullscreen"));
+ AppendMenu(hMenu, MF_STRING, 1+PU_SHOWMODE_BLOCK, TranslateT("Block"));
+
+ CheckMenuItem(hMenu, 1+mode, MF_BYCOMMAND|MF_CHECKED);
+
+ mode = TrackPopupMenu(hMenu, TPM_RETURNCMD, sicd->clickLocation.x, sicd->clickLocation.y, 0, WindowList_Find(hDialogsList, hContact), NULL);
+
+ if (mode)
+ {
+ DBWriteContactSettingByte(hContact, MODULNAME, "ShowMode", mode-1);
+ SrmmMenu_UpdateIcon(hContact);
+ }
+ } else
+ {
+ DBWriteContactSettingByte(hContact, MODULNAME, "ShowMode",
+ (mode == PU_SHOWMODE_AUTO) ? PU_SHOWMODE_BLOCK : PU_SHOWMODE_AUTO);
+ SrmmMenu_UpdateIcon(hContact);
+ }
+
+ return 0;
+}
diff --git a/plugins/Popup/src/srmm_menu.h b/plugins/Popup/src/srmm_menu.h
new file mode 100644
index 0000000000..e9e8ef4966
--- /dev/null
+++ b/plugins/Popup/src/srmm_menu.h
@@ -0,0 +1,39 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+ © 2010 MPK
+ © 2010 Merlin_de
+
+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.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/srmm_menu.h $
+Revision : $Revision: 1610 $
+Last change on : $Date: 2010-06-23 00:55:13 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+#ifndef __srmm_menu_h__
+#define __srmm_menu_h__
+
+void SrmmMenu_Load();
+void SrmmMenu_Unload();
+
+#endif // __srmm_menu_h__