summaryrefslogtreecommitdiff
path: root/plugins/Clist_nicer/SRC
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:02:50 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:02:50 +0000
commitf920ef497f3299ae24fe783ce03bdd93b419f764 (patch)
treebdaa9197c08d29ab141a6adfdd6cc0a68ddd3996 /plugins/Clist_nicer/SRC
parent6c3b0571f0678da0512069869afaa284c054377e (diff)
plugins folders renaming
git-svn-id: http://svn.miranda-ng.org/main/trunk@60 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Clist_nicer/SRC')
-rw-r--r--plugins/Clist_nicer/SRC/CLCButton.cpp711
-rw-r--r--plugins/Clist_nicer/SRC/Docking.cpp286
-rw-r--r--plugins/Clist_nicer/SRC/alphablend.cpp545
-rw-r--r--plugins/Clist_nicer/SRC/clc.cpp827
-rw-r--r--plugins/Clist_nicer/SRC/clcidents.cpp102
-rw-r--r--plugins/Clist_nicer/SRC/clcitems.cpp662
-rw-r--r--plugins/Clist_nicer/SRC/clcmsgs.cpp221
-rw-r--r--plugins/Clist_nicer/SRC/clcopts.cpp1719
-rw-r--r--plugins/Clist_nicer/SRC/clcpaint.cpp1685
-rw-r--r--plugins/Clist_nicer/SRC/clcutils.cpp626
-rw-r--r--plugins/Clist_nicer/SRC/clistevents.cpp399
-rw-r--r--plugins/Clist_nicer/SRC/clistmenus.cpp493
-rw-r--r--plugins/Clist_nicer/SRC/clistmod.cpp260
-rw-r--r--plugins/Clist_nicer/SRC/clistopts.cpp222
-rw-r--r--plugins/Clist_nicer/SRC/clistsettings.cpp33
-rw-r--r--plugins/Clist_nicer/SRC/clisttray.cpp171
-rw-r--r--plugins/Clist_nicer/SRC/clnplus.cpp40
-rw-r--r--plugins/Clist_nicer/SRC/clui.cpp2533
-rw-r--r--plugins/Clist_nicer/SRC/cluiopts.cpp476
-rw-r--r--plugins/Clist_nicer/SRC/cluiservices.cpp261
-rw-r--r--plugins/Clist_nicer/SRC/commonheaders.cpp1
-rw-r--r--plugins/Clist_nicer/SRC/config.cpp482
-rw-r--r--plugins/Clist_nicer/SRC/contact.cpp334
-rw-r--r--plugins/Clist_nicer/SRC/extBackg.cpp1926
-rw-r--r--plugins/Clist_nicer/SRC/init.cpp416
-rw-r--r--plugins/Clist_nicer/SRC/rowheight_funcs.cpp287
-rw-r--r--plugins/Clist_nicer/SRC/statusbar.cpp197
-rw-r--r--plugins/Clist_nicer/SRC/statusfloater.cpp1240
-rw-r--r--plugins/Clist_nicer/SRC/viewmodes.cpp1265
-rw-r--r--plugins/Clist_nicer/SRC/wallpaper.cpp56
30 files changed, 18476 insertions, 0 deletions
diff --git a/plugins/Clist_nicer/SRC/CLCButton.cpp b/plugins/Clist_nicer/SRC/CLCButton.cpp
new file mode 100644
index 0000000000..440178208a
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/CLCButton.cpp
@@ -0,0 +1,711 @@
+/*
+Miranda IM
+Copyright (C) 2002 Robert Rainwater
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include <commonheaders.h>
+
+extern HINSTANCE g_hInst;
+extern LONG g_cxsmIcon, g_cysmIcon;
+extern StatusItems_t *StatusItems;
+extern ImageItem *g_glyphItem;
+
+static LRESULT CALLBACK TSButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+typedef struct {
+ HWND hwnd;
+ int stateId; // button state
+ int focus; // has focus (1 or 0)
+ HFONT hFont; // font
+ HICON arrow; // uses down arrow
+ int defbutton; // default button
+ HICON hIcon, hIconPrivate;
+ HBITMAP hBitmap;
+ int pushBtn;
+ int pbState;
+ HANDLE hThemeButton;
+ HANDLE hThemeToolbar;
+ BOOL bThemed;
+ DWORD bSkinned;
+ char cHot;
+ int flatBtn;
+ TCHAR szText[128];
+ SIZE sLabel;
+ HIMAGELIST hIml;
+ int iIcon;
+ BOOL bSendOnDown;
+ ButtonItem *buttonItem;
+ LONG lastGlyphMetrics[4];
+} MButtonCtrl;
+
+static HWND hwndToolTips = NULL;
+
+int UnloadTSButtonModule(WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+
+int LoadCLCButtonModule(void)
+{
+ WNDCLASSEX wc;
+
+ ZeroMemory(&wc, sizeof(wc));
+ wc.cbSize = sizeof(wc);
+ wc.lpszClassName = _T("CLCButtonClass");
+ wc.lpfnWndProc = TSButtonWndProc;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.cbWndExtra = sizeof(MButtonCtrl *);
+ wc.hbrBackground = 0;
+ wc.style = CS_GLOBALCLASS;
+ RegisterClassEx(&wc);
+ return 0;
+}
+
+// Used for our own cheap TrackMouseEvent
+#define BUTTON_POLLID 100
+#define BUTTON_POLLDELAY 50
+
+#define MGPROC(x) GetProcAddress(themeAPIHandle,x)
+
+static void DestroyTheme(MButtonCtrl *ctl)
+{
+ if(API::pfnCloseThemeData) {
+ if (ctl->hThemeButton) {
+ API::pfnCloseThemeData(ctl->hThemeButton);
+ ctl->hThemeButton = 0;
+ }
+ if (ctl->hThemeToolbar) {
+ API::pfnCloseThemeData(ctl->hThemeToolbar);
+ ctl->hThemeToolbar = 0;
+ }
+ ctl->bThemed = 0;
+ }
+}
+
+static void LoadTheme(MButtonCtrl *ctl)
+{
+ DestroyTheme(ctl);
+ if (IS_THEMED) {
+ ctl->hThemeButton = API::pfnOpenThemeData(ctl->hwnd, L"BUTTON");
+ ctl->hThemeToolbar = API::pfnOpenThemeData(ctl->hwnd, L"TOOLBAR");
+ ctl->bThemed = TRUE;
+ }
+}
+
+static int TBStateConvert2Flat(int state)
+{
+ switch (state) {
+ case PBS_NORMAL:
+ return TS_NORMAL;
+ case PBS_HOT:
+ return TS_HOT;
+ case PBS_PRESSED:
+ return TS_PRESSED;
+ case PBS_DISABLED:
+ return TS_DISABLED;
+ case PBS_DEFAULTED:
+ return TS_NORMAL;
+ }
+ return TS_NORMAL;
+}
+
+static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint)
+{
+ if (hdcPaint) {
+ HDC hdcMem;
+ HBITMAP hbmMem;
+ HBITMAP hbmOld = 0;
+ RECT rcClient;
+ HFONT hOldFont = 0;
+ int xOffset = 0;
+
+ GetClientRect(ctl->hwnd, &rcClient);
+ hdcMem = CreateCompatibleDC(hdcPaint);
+ hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
+ hbmOld = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, hbmMem));
+
+ hOldFont = reinterpret_cast<HFONT>(SelectObject(hdcMem, ctl->hFont));
+ // If its a push button, check to see if it should stay pressed
+ if (ctl->pushBtn && ctl->pbState)
+ ctl->stateId = PBS_PRESSED;
+
+ // Draw the flat button
+ if (ctl->flatBtn) {
+ if (ctl->hThemeToolbar && ctl->bThemed) {
+ RECT rc = rcClient;
+ int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED;
+ SkinDrawBg(ctl->hwnd, hdcMem);
+ if (API::pfnIsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) {
+ API::pfnDrawThemeParentBackground(ctl->hwnd, hdcMem, &rc);
+ }
+ API::pfnDrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rc, &rc);
+ } else {
+ HBRUSH hbr;
+ RECT rc = rcClient;
+
+ if(ctl->buttonItem) {
+ RECT rcParent;
+ POINT pt;
+ HWND hwndParent = pcli->hwndContactList;
+ ImageItem *imgItem = ctl->stateId == PBS_HOT ? ctl->buttonItem->imgHover : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->imgPressed : ctl->buttonItem->imgNormal);
+ LONG *glyphMetrics = ctl->stateId == PBS_HOT ? ctl->buttonItem->hoverGlyphMetrics : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->pressedGlyphMetrics : ctl->buttonItem->normalGlyphMetrics);
+
+ //if(ctl->stateId == PBS_HOT && glyphMetrics[2] <= 1 && glyphMetrics[3] <= 1)
+ // glyphMetrics = ctl->lastGlyphMetrics;
+
+ GetWindowRect(ctl->hwnd, &rcParent);
+ pt.x = rcParent.left;
+ pt.y = rcParent.top;
+
+ ScreenToClient(pcli->hwndContactList, &pt);
+
+ BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY);
+ if(imgItem)
+ DrawAlpha(hdcMem, &rc, 0, 0, 0, 0, 0, 0, 0, imgItem);
+ if(g_glyphItem) {
+ API::pfnAlphaBlend(hdcMem, (rc.right - glyphMetrics[2]) / 2, (rc.bottom - glyphMetrics[3]) / 2,
+ glyphMetrics[2], glyphMetrics[3], g_glyphItem->hdc,
+ glyphMetrics[0], glyphMetrics[1], glyphMetrics[2],
+ glyphMetrics[3], g_glyphItem->bf);
+ //CopyMemory(ctl->lastGlyphMetrics, glyphMetrics, 4 * sizeof(LONG));
+ }
+ }
+ else if(ctl->bSkinned) { // skinned
+ RECT rcParent;
+ POINT pt;
+ HWND hwndParent = pcli->hwndContactList;
+ StatusItems_t *item;
+ int item_id;
+
+ GetWindowRect(ctl->hwnd, &rcParent);
+ pt.x = rcParent.left;
+ pt.y = rcParent.top;
+
+ ScreenToClient(pcli->hwndContactList, &pt);
+
+ if(HIWORD(ctl->bSkinned))
+ item_id = ctl->stateId == PBS_HOT ? ID_EXTBKTBBUTTONMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED);
+ //GetItemByStatus(ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED), &item);
+ else
+ item_id = ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED);
+ item = &StatusItems[item_id - ID_STATUS_OFFLINE];
+ //GetItemByStatus(ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED, &item);
+ SetTextColor(hdcMem, item->TEXTCOLOR);
+ if(item->IGNORED) {
+ if(pt.y < 10 || cfg::dat.bWallpaperMode)
+ //SkinDrawBg(ctl->hwnd, hdcMem);
+ BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY);
+ else
+ FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE));
+ }
+ else {
+ if(pt.y < 10 || cfg::dat.bWallpaperMode)
+ //SkinDrawBg(ctl->hwnd, hdcMem);
+ BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY);
+ else
+ FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE));
+ rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM;
+ rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT;
+ DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT,
+ item->CORNER, item->BORDERSTYLE, item->imageItem);
+ }
+ }
+ else {
+ if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT)
+ hbr = GetSysColorBrush(COLOR_3DFACE);
+ else {
+ HDC dc;
+ HWND hwndParent;
+
+ hwndParent = GetParent(ctl->hwnd);
+ dc = GetDC(hwndParent);
+ hbr = (HBRUSH) SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM) dc, (LPARAM) hwndParent);
+ ReleaseDC(hwndParent, dc);
+ }
+ if (hbr) {
+ FillRect(hdcMem, &rc, hbr);
+ DeleteObject(hbr);
+ }
+ }
+ if(!ctl->bSkinned && ctl->buttonItem == 0) {
+ if (ctl->stateId == PBS_HOT || ctl->focus) {
+ if (ctl->pbState)
+ DrawEdge(hdcMem, &rc, EDGE_ETCHED, BF_RECT | BF_SOFT);
+ else
+ DrawEdge(hdcMem, &rc, BDR_RAISEDOUTER, BF_RECT | BF_SOFT);
+ } else if (ctl->stateId == PBS_PRESSED)
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT | BF_SOFT);
+ }
+ }
+ } else {
+ // Draw background/border
+ if (ctl->hThemeButton && ctl->bThemed) {
+ int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED;
+ POINT pt;
+ RECT rcParent;
+
+ GetWindowRect(ctl->hwnd, &rcParent);
+ pt.x = rcParent.left;
+ pt.y = rcParent.top;
+ ScreenToClient(pcli->hwndContactList, &pt);
+ BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY);
+
+ if (API::pfnIsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) {
+ API::pfnDrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient);
+ }
+ API::pfnDrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient);
+ } else {
+ UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0);
+ if (ctl->defbutton && ctl->stateId == PBS_NORMAL)
+ uState |= DLGC_DEFPUSHBUTTON;
+ DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState);
+ }
+
+ // Draw focus rectangle if button has focus
+ if (ctl->focus) {
+ RECT focusRect = rcClient;
+ InflateRect(&focusRect, -3, -3);
+ DrawFocusRect(hdcMem, &focusRect);
+ }
+ }
+
+ // If we have an icon or a bitmap, ignore text and only draw the image on the button
+ if (ctl->hIcon || ctl->hIconPrivate || ctl->iIcon) {
+ int ix = (rcClient.right - rcClient.left) / 2 - (g_cxsmIcon / 2);
+ int iy = (rcClient.bottom - rcClient.top) / 2 - (g_cxsmIcon / 2);
+ HICON hIconNew = ctl->hIconPrivate != 0 ? ctl->hIconPrivate : ctl->hIcon;
+ if (lstrlen(ctl->szText) == 0) {
+ if (ctl->iIcon)
+ ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ else
+ DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED);
+ ctl->sLabel.cx = ctl->sLabel.cy = 0;
+ } else {
+ GetTextExtentPoint32(hdcMem, ctl->szText, lstrlen(ctl->szText), &ctl->sLabel);
+
+ if(g_cxsmIcon + ctl->sLabel.cx + 8 > rcClient.right - rcClient.left)
+ ctl->sLabel.cx = (rcClient.right - rcClient.left) - g_cxsmIcon - 8;
+ else
+ ctl->sLabel.cx += 4;
+
+ ix = (rcClient.right - rcClient.left) / 2 - ((g_cxsmIcon + ctl->sLabel.cx) / 2);
+ if (ctl->iIcon)
+ ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ else
+ DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED);
+ xOffset = ix + g_cxsmIcon + 4;
+ }
+ } else if (ctl->hBitmap) {
+ BITMAP bminfo;
+ int ix, iy;
+
+ GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo);
+ ix = (rcClient.right - rcClient.left) / 2 - (bminfo.bmWidth / 2);
+ iy = (rcClient.bottom - rcClient.top) / 2 - (bminfo.bmHeight / 2);
+ if (ctl->stateId == PBS_PRESSED) {
+ ix++;
+ iy++;
+ }
+ DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->hBitmap, 0, ix, iy, bminfo.bmWidth, bminfo.bmHeight, IsWindowEnabled(ctl->hwnd) ? DST_BITMAP : DST_BITMAP | DSS_DISABLED);
+ }
+ if (GetWindowTextLength(ctl->hwnd)) {
+ // Draw the text and optinally the arrow
+ RECT rcText;
+
+ CopyRect(&rcText, &rcClient);
+ SetBkMode(hdcMem, TRANSPARENT);
+ // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so.
+ if(!ctl->bSkinned)
+ SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT));
+ if (ctl->arrow)
+ DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->arrow, 0, rcClient.right - rcClient.left - 5 - g_cxsmIcon + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), (rcClient.bottom - rcClient.top) / 2 - g_cysmIcon / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON : DST_ICON | DSS_DISABLED);
+ DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->szText, 0, xOffset + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->hThemeButton ? (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + 1 : (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + (ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->sLabel.cx, ctl->sLabel.cy, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED);
+ }
+ if (hOldFont)
+ SelectObject(hdcMem, hOldFont);
+ BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY);
+ SelectObject(hdcMem, hbmOld);
+ DeleteObject(hbmMem);
+ DeleteDC(hdcMem);
+ DeleteObject(hbmOld);
+ }
+}
+
+static LRESULT CALLBACK TSButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ MButtonCtrl *bct = (MButtonCtrl *) GetWindowLongPtr(hwndDlg, 0);
+ switch (msg) {
+ case WM_NCCREATE:
+ {
+ SetWindowLong(hwndDlg, GWL_STYLE, GetWindowLong(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
+ bct = reinterpret_cast<MButtonCtrl *>(malloc(sizeof(MButtonCtrl)));
+ if (bct == NULL)
+ return FALSE;
+ bct->hwnd = hwndDlg;
+ bct->stateId = PBS_NORMAL;
+ bct->focus = 0;
+ bct->hFont = reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
+ bct->arrow = NULL;
+ bct->defbutton = 0;
+ bct->hIcon = bct->hIconPrivate = 0;
+ bct->iIcon = 0;
+ bct->hIml = 0;
+ bct->hBitmap = NULL;
+ bct->pushBtn = 0;
+ bct->pbState = 0;
+ bct->hThemeButton = NULL;
+ bct->hThemeToolbar = NULL;
+ bct->cHot = 0;
+ bct->flatBtn = 0;
+ bct->bThemed = FALSE;
+ bct->bSkinned = bct->bSendOnDown = 0;
+ bct->buttonItem = NULL;
+ LoadTheme(bct);
+ SetWindowLongPtr(hwndDlg, 0, (LONG_PTR) bct);
+ if (((CREATESTRUCTA *) lParam)->lpszName)
+ SetWindowText(hwndDlg, ((CREATESTRUCT *) lParam)->lpszName);
+ return TRUE;
+ }
+ case WM_DESTROY:
+ {
+ if (bct) {
+ if (hwndToolTips) {
+ TOOLINFO ti;
+
+ ZeroMemory(&ti, sizeof(ti));
+ ti.cbSize = sizeof(ti);
+ ti.uFlags = TTF_IDISHWND;
+ ti.hwnd = bct->hwnd;
+ ti.uId = (UINT_PTR) bct->hwnd;
+ if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) &ti)) {
+ SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM) &ti);
+ }
+ if (SendMessage(hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM) &ti) == 0) {
+ DestroyWindow(hwndToolTips);
+ hwndToolTips = NULL;
+ }
+ }
+ if (bct->hIconPrivate)
+ DestroyIcon(bct->hIconPrivate);
+ DestroyTheme(bct);
+ free(bct);
+ }
+ SetWindowLongPtr(hwndDlg, 0, 0);
+ break; // DONT! fall thru
+ }
+ case WM_SETTEXT:
+ {
+ bct->cHot = 0;
+ if ((char*) lParam) {
+ char *tmp = (char *) lParam;
+ while (*tmp) {
+ if (*tmp == '&' && *(tmp + 1)) {
+ bct->cHot = tolower(*(tmp + 1));
+ break;
+ }
+ tmp++;
+ }
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ lstrcpyn(bct->szText, (TCHAR *)lParam, 127);
+ bct->szText[127] = 0;
+ }
+ break;
+ }
+ case WM_SYSKEYUP:
+ if (bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == tolower((int) wParam)) {
+ if (bct->pushBtn) {
+ if (bct->pbState)
+ bct->pbState = 0;
+ else
+ bct->pbState = 1;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ }
+ if(!bct->bSendOnDown)
+ SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
+ return 0;
+ }
+ break;
+ case WM_THEMECHANGED:
+ {
+ if (bct->bThemed)
+ LoadTheme(bct);
+ InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it
+ break;
+ }
+ case WM_SETFONT:
+ // remember the font so we can use it later
+ {
+ bct->hFont = (HFONT) wParam; // maybe we should redraw?
+ break;
+ }
+ case WM_NCPAINT:
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdcPaint;
+
+ hdcPaint = BeginPaint(hwndDlg, &ps);
+ if (hdcPaint) {
+ PaintWorker(bct, hdcPaint);
+ EndPaint(hwndDlg, &ps);
+ }
+ break;
+ }
+ case BM_GETIMAGE:
+ if(wParam == IMAGE_ICON)
+ return (LRESULT)(bct->hIconPrivate ? bct->hIconPrivate : bct->hIcon);
+ break;
+ case BM_SETIMAGE:
+ if(!lParam)
+ break;
+ bct->hIml = 0;
+ bct->iIcon = 0;
+ if (wParam == IMAGE_ICON) {
+ ICONINFO ii = {0};
+ BITMAP bm = {0};
+
+ if (bct->hIconPrivate) {
+ DestroyIcon(bct->hIconPrivate);
+ bct->hIconPrivate = 0;
+ }
+
+ GetIconInfo((HICON) lParam, &ii);
+ GetObject(ii.hbmColor, sizeof(bm), &bm);
+ if (bm.bmWidth > g_cxsmIcon || bm.bmHeight > g_cysmIcon) {
+ HIMAGELIST hImageList;
+ hImageList = ImageList_Create(g_cxsmIcon, g_cysmIcon, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0);
+ ImageList_AddIcon(hImageList, (HICON) lParam);
+ bct->hIconPrivate = ImageList_GetIcon(hImageList, 0, ILD_NORMAL);
+ ImageList_RemoveAll(hImageList);
+ ImageList_Destroy(hImageList);
+ bct->hIcon = 0;
+ } else {
+ bct->hIcon = (HICON) lParam;
+ bct->hIconPrivate = 0;
+ }
+
+ DeleteObject(ii.hbmMask);
+ DeleteObject(ii.hbmColor);
+ bct->hBitmap = NULL;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ } else if (wParam == IMAGE_BITMAP) {
+ bct->hBitmap = (HBITMAP) lParam;
+ if (bct->hIconPrivate)
+ DestroyIcon(bct->hIconPrivate);
+ bct->hIcon = bct->hIconPrivate = NULL;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ }
+ break;
+ case BM_SETPRIVATEICON:
+ bct->hIml = 0;
+ bct->iIcon = 0; {
+ if (bct->hIconPrivate)
+ DestroyIcon(bct->hIconPrivate);
+ bct->hIconPrivate = DuplicateIcon(g_hInst, (HICON) lParam);
+ bct->hIcon = 0;
+ break;
+ }
+ case BM_SETIMLICON:
+ {
+ if (bct->hIconPrivate)
+ DestroyIcon(bct->hIconPrivate);
+ bct->hIml = (HIMAGELIST) wParam;
+ bct->iIcon = (int) lParam;
+ bct->hIcon = bct->hIconPrivate = 0;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ }
+ case BM_SETSKINNED:
+ bct->bSkinned = (DWORD)lParam;
+ bct->bThemed = bct->bSkinned ? FALSE : bct->bThemed;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case BM_SETBTNITEM:
+ bct->buttonItem = (ButtonItem *)lParam;
+ break;
+ case BM_SETASMENUACTION:
+ bct->bSendOnDown = wParam ? TRUE : FALSE;
+ return 0;
+ case BM_SETCHECK:
+ if (!bct->pushBtn)
+ break;
+ if (wParam == BST_CHECKED) {
+ bct->pbState = 1;
+ bct->stateId = PBS_PRESSED;
+ } else if (wParam == BST_UNCHECKED) {
+ bct->pbState = 0;
+ bct->stateId = PBS_NORMAL;
+ }
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case BM_GETCHECK:
+ if (bct->pushBtn) {
+ return bct->pbState ? BST_CHECKED : BST_UNCHECKED;
+ }
+ return 0;
+ case BUTTONSETARROW:
+ // turn arrow on/off
+ if (wParam) {
+ if (!bct->arrow)
+ bct->arrow = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MINIMIZE), IMAGE_ICON, g_cxsmIcon, g_cysmIcon, 0);
+ } else {
+ if (bct->arrow) {
+ DestroyIcon(bct->arrow);
+ bct->arrow = NULL;
+ }
+ }
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case BUTTONSETDEFAULT:
+ bct->defbutton = wParam ? 1 : 0;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case BUTTONSETASPUSHBTN:
+ bct->pushBtn = 1;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case BUTTONSETASFLATBTN:
+ bct->flatBtn = lParam == 0 ? 1 : 0;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case BUTTONSETASFLATBTN + 10:
+ bct->bThemed = lParam ? TRUE : FALSE;
+ bct->bSkinned = bct->bThemed ? 0 : bct->bSkinned;
+ break;
+ case BUTTONADDTOOLTIP:
+ {
+ TOOLINFO ti;
+
+ if (!(char*) wParam)
+ break;
+ if (!hwndToolTips) {
+ hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
+ SetWindowPos(hwndToolTips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
+ }
+ ZeroMemory(&ti, sizeof(ti));
+ ti.cbSize = sizeof(ti);
+ ti.uFlags = TTF_IDISHWND;
+ ti.hwnd = bct->hwnd;
+ ti.uId = (UINT_PTR) bct->hwnd;
+ if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) &ti)) {
+ SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM) &ti);
+ }
+ ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
+ ti.uId = (UINT_PTR) bct->hwnd;
+ ti.lpszText = (TCHAR *) wParam;
+ SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti);
+ break;
+ }
+ case WM_SETFOCUS:
+ // set keybord focus and redraw
+ bct->focus = 1;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case WM_KILLFOCUS:
+ // kill focus and redraw
+ bct->focus = 0;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case WM_WINDOWPOSCHANGED:
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ case WM_ENABLE:
+ // windows tells us to enable/disable
+ {
+ bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ break;
+ }
+ case WM_MOUSELEAVE:
+ // faked by the WM_TIMER
+ {
+ if (bct->stateId != PBS_DISABLED) {
+ // don't change states if disabled
+ bct->stateId = PBS_NORMAL;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ }
+ break;
+ }
+ case WM_LBUTTONDOWN:
+ {
+ if (bct->stateId != PBS_DISABLED && bct->stateId != PBS_PRESSED) {
+ bct->stateId = PBS_PRESSED;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ if(bct->bSendOnDown) {
+ SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
+ bct->stateId = PBS_NORMAL;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ }
+ }
+ break;
+ }
+ case WM_LBUTTONUP:
+ {
+ if (bct->pushBtn) {
+ if (bct->pbState)
+ bct->pbState = 0;
+ else
+ bct->pbState = 1;
+ }
+ if (bct->stateId != PBS_DISABLED) {
+ // don't change states if disabled
+ if (msg == WM_LBUTTONUP)
+ bct->stateId = PBS_HOT;
+ else
+ bct->stateId = PBS_NORMAL;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ }
+ if(!bct->bSendOnDown)
+ SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg);
+ break;
+ }
+ case WM_MOUSEMOVE:
+ if (bct->stateId == PBS_NORMAL) {
+ bct->stateId = PBS_HOT;
+ InvalidateRect(bct->hwnd, NULL, TRUE);
+ }
+ // Call timer, used to start cheesy TrackMouseEvent faker
+ SetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL);
+ break;
+ case WM_NCHITTEST:
+ {
+ LRESULT lr = SendMessage(GetParent(hwndDlg), WM_NCHITTEST, wParam, lParam);
+ if(lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT
+ || lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT)
+ return HTTRANSPARENT;
+ break;
+ }
+ case WM_TIMER:
+ // use a timer to check if they have did a mouseout
+ {
+ if (wParam == BUTTON_POLLID) {
+ RECT rc;
+ POINT pt;
+ GetWindowRect(hwndDlg, &rc);
+ GetCursorPos(&pt);
+ if (!PtInRect(&rc, pt)) {
+ // mouse must be gone, trigger mouse leave
+ PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L);
+ KillTimer(hwndDlg, BUTTON_POLLID);
+ }
+ }
+ break;
+ }
+ case WM_ERASEBKGND:
+ return 1;
+ }
+ return DefWindowProc(hwndDlg, msg, wParam, lParam);
+}
diff --git a/plugins/Clist_nicer/SRC/Docking.cpp b/plugins/Clist_nicer/SRC/Docking.cpp
new file mode 100644
index 0000000000..bb736880d2
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/Docking.cpp
@@ -0,0 +1,286 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE - done.
+
+*/
+#include "commonheaders.h"
+
+#define WM_DOCKCALLBACK (WM_USER+121)
+#define WM_CREATEDOCKED (WM_USER+122)
+#define EDGESENSITIVITY 3
+
+#define DOCKED_NONE 0
+#define DOCKED_LEFT 1
+#define DOCKED_RIGHT 2
+static int docked;
+
+extern RECT cluiPos;
+
+static void Docking_GetMonitorRectFromPoint(POINT pt, RECT *rc)
+{
+ if ( API::pfnMonitorFromPoint ) {
+ MONITORINFO monitorInfo;
+ HMONITOR hMonitor = API::pfnMonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); // always returns a valid value
+ monitorInfo.cbSize = sizeof(MONITORINFO);
+
+ if ( API::pfnGetMonitorInfo( hMonitor, &monitorInfo )) {
+ CopyMemory(rc, &monitorInfo.rcMonitor, sizeof(RECT));
+ return;
+ }
+ }
+
+ // "generic" win95/NT support, also serves as failsafe
+ rc->left = 0;
+ rc->top = 0;
+ rc->bottom = GetSystemMetrics(SM_CYSCREEN);
+ rc->right = GetSystemMetrics(SM_CXSCREEN);
+}
+
+static void Docking_GetMonitorRectFromWindow(HWND hWnd, RECT *rc)
+{
+ POINT ptWindow;
+ GetWindowRect(hWnd, rc);
+ ptWindow.x = rc->left;
+ ptWindow.y = rc->top;
+ Docking_GetMonitorRectFromPoint(ptWindow, rc);
+}
+
+static void Docking_AdjustPosition(HWND hwnd, RECT *rcDisplay, RECT *rc)
+{
+ APPBARDATA abd;
+
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = hwnd;
+ abd.uEdge = docked == DOCKED_LEFT ? ABE_LEFT : ABE_RIGHT;
+ abd.rc = *rc;
+ abd.rc.top = rcDisplay->top;
+ abd.rc.bottom = rcDisplay->bottom;
+ if (docked == DOCKED_LEFT) {
+ abd.rc.right = rcDisplay->left + (abd.rc.right - abd.rc.left) - cfg::dat.bClipBorder;
+ abd.rc.left = rcDisplay->left - cfg::dat.bClipBorder;
+ } else {
+ abd.rc.left = rcDisplay->right - (abd.rc.right - abd.rc.left) + cfg::dat.bClipBorder;
+ abd.rc.right = rcDisplay->right + cfg::dat.bClipBorder;
+ }
+ SHAppBarMessage(ABM_SETPOS, &abd);
+ *rc = abd.rc;
+}
+
+int Docking_IsDocked(WPARAM wParam, LPARAM lParam)
+{
+ return docked;
+}
+
+int Docking_ProcessWindowMessage(WPARAM wParam, LPARAM lParam)
+{
+ APPBARDATA abd;
+ static int draggingTitle;
+ MSG *msg = (MSG *) wParam;
+
+ if (msg->message == WM_DESTROY)
+ cfg::writeByte("CList", "Docked", (BYTE) docked);
+ if (!docked && msg->message != WM_CREATE && msg->message != WM_MOVING && msg->message != WM_CREATEDOCKED && msg->message != WM_MOVE)
+ return 0;
+ switch (msg->message) {
+ case WM_CREATE:
+ //if(GetSystemMetrics(SM_CMONITORS)>1) return 0;
+ if (cfg::getByte("CList", "Docked", 0))
+ PostMessage(msg->hwnd, WM_CREATEDOCKED, 0, 0);
+ draggingTitle = 0;
+ return 0;
+ case WM_CREATEDOCKED:
+ //we need to post a message just after creation to let main message function do some work
+ docked = (int) (char) cfg::getByte("CList", "Docked", 0);
+ if (IsWindowVisible(msg->hwnd) && !IsIconic(msg->hwnd)) {
+ RECT rc, rcMonitor;
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ abd.lParam = 0;
+ abd.uCallbackMessage = WM_DOCKCALLBACK;
+ SHAppBarMessage(ABM_NEW, &abd);
+ GetWindowRect(msg->hwnd, &rc);
+ Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor);
+ Docking_AdjustPosition(msg->hwnd, &rcMonitor, &rc);
+ MoveWindow(msg->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
+ }
+ break;
+ case WM_ACTIVATE:
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ SHAppBarMessage(ABM_ACTIVATE, &abd);
+ return 0;
+ case WM_WINDOWPOSCHANGED:
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
+ return 0;
+ case WM_MOVING:
+ {
+ RECT rcMonitor;
+ POINT ptCursor;
+
+ // stop early
+ if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
+ return 0;
+
+ // GetMessagePos() is no good, position is always unsigned
+ GetCursorPos(&ptCursor);
+ Docking_GetMonitorRectFromPoint(ptCursor, &rcMonitor);
+
+ if ((ptCursor.x < rcMonitor.left + EDGESENSITIVITY) || (ptCursor.x >= rcMonitor.right - EDGESENSITIVITY)) {
+ if(!(GetWindowLong(msg->hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) {
+ SendMessage(msg->hwnd, CLUIINTM_REDRAW, 0, 0);
+ MessageBox(0, TranslateT("The clist cannot be docked when using the default title bar and border. Use a toolwindow or borderless style instead."),
+ TranslateT("Clist docking"), MB_OK);
+ return 0;
+ }
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ abd.lParam = 0;
+ abd.uCallbackMessage = WM_DOCKCALLBACK;
+ SHAppBarMessage(ABM_NEW, &abd);
+ if (ptCursor.x < rcMonitor.left + EDGESENSITIVITY)
+ docked = DOCKED_LEFT;
+ else
+ docked = DOCKED_RIGHT;
+ SendMessage(msg->hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptCursor.x, ptCursor.y));
+ GetWindowRect(msg->hwnd, (LPRECT) msg->lParam);
+ Docking_AdjustPosition(msg->hwnd, (LPRECT) &rcMonitor, (LPRECT) msg->lParam);
+ PostMessage(msg->hwnd, CLUIINTM_REDRAW, 0, 0);
+ return TRUE;
+ }
+ return 0;
+ }
+ case WM_MOVE:
+ {
+ if (docked) {
+ RECT rc, rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor);
+ GetWindowRect(msg->hwnd, &rc);
+ Docking_AdjustPosition(msg->hwnd, &rcMonitor, &rc);
+ MoveWindow(msg->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
+ return 1;
+ }
+ return 0;
+ }
+ case WM_SIZING:
+ {
+ RECT rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor);
+ Docking_AdjustPosition(msg->hwnd, &rcMonitor, (LPRECT) msg->lParam);
+ *((LRESULT *) lParam) = TRUE;
+ return TRUE;
+ }
+ case WM_SHOWWINDOW:
+ if (msg->lParam)
+ return 0;
+ if ((msg->wParam && docked < 0) || (!msg->wParam && docked > 0))
+ docked = -docked;
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ if (msg->wParam) {
+ RECT rc, rcMonitor;
+ Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor);
+ abd.lParam = 0;
+ abd.uCallbackMessage = WM_DOCKCALLBACK;
+ SHAppBarMessage(ABM_NEW, &abd);
+ GetWindowRect(msg->hwnd, &rc);
+ Docking_AdjustPosition(msg->hwnd, &rcMonitor, &rc);
+ MoveWindow(msg->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE);
+ } else {
+ SHAppBarMessage(ABM_REMOVE, &abd);
+ }
+ return 0;
+ case WM_NCHITTEST:
+ {
+ LONG result;
+ result = DefWindowProc(msg->hwnd, WM_NCHITTEST, msg->wParam, msg->lParam);
+ if (result == HTSIZE || result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT || result == HTBOTTOM || result == HTBOTTOMRIGHT || result == HTBOTTOMLEFT) {
+ *((LRESULT *) lParam) = HTCLIENT; return TRUE;
+ }
+ if (docked == DOCKED_LEFT && result == HTLEFT) {
+ *((LRESULT *) lParam) = HTCLIENT; return TRUE;
+ }
+ if (docked == DOCKED_RIGHT && result == HTRIGHT) {
+ *((LRESULT *) lParam) = HTCLIENT; return TRUE;
+ }
+ return 0;
+ }
+ case WM_SYSCOMMAND:
+ if ((msg->wParam & 0xFFF0) != SC_MOVE)
+ return 0;
+ SetActiveWindow(msg->hwnd);
+ SetCapture(msg->hwnd);
+ draggingTitle = 1;
+ *((LRESULT *) lParam) = 0;
+ return TRUE;
+ case WM_MOUSEMOVE:
+ if (!draggingTitle)
+ return 0; {
+ RECT rc;
+ POINT pt;
+ GetClientRect(msg->hwnd, &rc);
+ if (((docked == DOCKED_LEFT || docked == -DOCKED_LEFT) && (short) LOWORD(msg->lParam) > rc.right) || ((docked == DOCKED_RIGHT || docked == -DOCKED_RIGHT) && (short) LOWORD(msg->lParam) < 0)) {
+ ReleaseCapture();
+ draggingTitle = 0;
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ SHAppBarMessage(ABM_REMOVE, &abd);
+ docked = 0;
+ GetCursorPos(&pt);
+ PostMessage(msg->hwnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ SetWindowPos(msg->hwnd, 0, pt.x - rc.right / 2, pt.y - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYSMCAPTION) / 2, cluiPos.right, cluiPos.bottom, SWP_NOZORDER);
+ }
+ return 1;
+ }
+ case WM_LBUTTONUP:
+ if (draggingTitle) {
+ ReleaseCapture();
+ draggingTitle = 0;
+ }
+ return 0;
+ case WM_DOCKCALLBACK:
+ switch (msg->wParam) {
+ case ABN_WINDOWARRANGE:
+ ShowWindow(msg->hwnd, msg->lParam ? SW_HIDE : SW_SHOW);
+ break;
+ }
+ return TRUE;
+ case WM_DESTROY:
+ if (docked > 0) {
+ ZeroMemory(&abd, sizeof(abd));
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = msg->hwnd;
+ SHAppBarMessage(ABM_REMOVE, &abd);
+ }
+ return 0;
+ }
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/alphablend.cpp b/plugins/Clist_nicer/SRC/alphablend.cpp
new file mode 100644
index 0000000000..b9fd07e904
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/alphablend.cpp
@@ -0,0 +1,545 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "commonheaders.h"
+
+extern int g_hottrack, g_hottrack_done;
+extern BOOL g_inCLCpaint;
+extern BYTE saved_alpha;
+extern DWORD savedCORNER;
+extern StatusItems_t *StatusItems;
+extern ImageItem *g_glyphItem;
+
+BYTE __forceinline percent_to_byte(UINT32 percent)
+{
+ return(BYTE) ((FLOAT) (((FLOAT) percent) / 100) * 255);
+}
+
+COLORREF __forceinline revcolref(COLORREF colref)
+{
+ return RGB(GetBValue(colref), GetGValue(colref), GetRValue(colref));
+}
+
+DWORD __forceinline argb_from_cola(COLORREF col, UINT32 alpha)
+{
+ return((BYTE) percent_to_byte(alpha) << 24 | col);
+}
+
+
+void __forceinline DrawBorderStyle(HDC hdcwnd, RECT *rc, DWORD BORDERSTYLE)
+{
+ if(BORDERSTYLE >= 0) {
+ HPEN hPenOld = 0;
+ POINT pt;
+
+ switch(BORDERSTYLE) {
+ case BDR_RAISEDOUTER: // raised
+ MoveToEx(hdcwnd, rc->left, rc->bottom - 1, &pt);
+ hPenOld = reinterpret_cast<HPEN>(SelectObject(hdcwnd, cfg::dat.hPen3DBright));
+ LineTo(hdcwnd, rc->left, rc->top);
+ LineTo(hdcwnd, rc->right, rc->top);
+ SelectObject(hdcwnd, cfg::dat.hPen3DDark);
+ MoveToEx(hdcwnd, rc->right - 1, rc->top + 1, &pt);
+ LineTo(hdcwnd, rc->right - 1, rc->bottom - 1);
+ LineTo(hdcwnd, rc->left - 1, rc->bottom - 1);
+ break;
+ case BDR_SUNKENINNER:
+ MoveToEx(hdcwnd, rc->left, rc->bottom - 1, &pt);
+ hPenOld = reinterpret_cast<HPEN>(SelectObject(hdcwnd, cfg::dat.hPen3DDark));
+ LineTo(hdcwnd, rc->left, rc->top);
+ LineTo(hdcwnd, rc->right, rc->top);
+ MoveToEx(hdcwnd, rc->right - 1, rc->top + 1, &pt);
+ SelectObject(hdcwnd, cfg::dat.hPen3DBright);
+ LineTo(hdcwnd, rc->right - 1, rc->bottom - 1);
+ LineTo(hdcwnd, rc->left, rc->bottom - 1);
+ break;
+ default:
+ DrawEdge(hdcwnd, rc, BORDERSTYLE, BF_RECT | BF_SOFT);
+ break;
+ }
+ if(hPenOld)
+ SelectObject(hdcwnd, hPenOld);
+ }
+}
+void DrawAlpha(HDC hdcwnd, PRECT rc, DWORD basecolor, int alpha, DWORD basecolor2, BOOL transparent, BYTE FLG_GRADIENT, BYTE FLG_CORNER, DWORD BORDERSTYLE, ImageItem *imageItem)
+{
+ HBRUSH BrMask;
+ HBRUSH holdbrush;
+ HDC hdc;
+ BLENDFUNCTION bf;
+ HBITMAP hbitmap;
+ HBITMAP holdbitmap;
+ BITMAPINFO bmi;
+ VOID *pvBits;
+ UINT32 x, y;
+ ULONG ulBitmapWidth, ulBitmapHeight;
+ UCHAR ubAlpha = 0xFF;
+ UCHAR ubRedFinal = 0xFF;
+ UCHAR ubGreenFinal = 0xFF;
+ UCHAR ubBlueFinal = 0xFF;
+ UCHAR ubRed;
+ UCHAR ubGreen;
+ UCHAR ubBlue;
+ UCHAR ubRed2;
+ UCHAR ubGreen2;
+ UCHAR ubBlue2;
+
+ int realx;
+
+ FLOAT fAlphaFactor;
+ LONG realHeight = (rc->bottom - rc->top);
+ LONG realWidth = (rc->right - rc->left);
+ LONG realHeightHalf = realHeight >> 1;
+
+ if (g_hottrack && g_inCLCpaint) {
+ StatusItems_t *ht = &StatusItems[ID_EXTBKHOTTRACK - ID_STATUS_OFFLINE];
+ if (ht->IGNORED == 0) {
+ basecolor = ht->COLOR;
+ basecolor2 = ht->COLOR2;
+ alpha = ht->ALPHA;
+ FLG_GRADIENT = ht->GRADIENT;
+ transparent = ht->COLOR2_TRANSPARENT;
+ BORDERSTYLE = ht->BORDERSTYLE;
+ imageItem = ht->imageItem;
+ }
+ g_hottrack_done = 1;
+ }
+
+ if(imageItem) {
+ IMG_RenderImageItem(hdcwnd, imageItem, rc);
+ return;
+ }
+
+ if (rc == NULL)
+ return;
+
+ if (rc->right < rc->left || rc->bottom < rc->top || (realHeight <= 0) || (realWidth <= 0))
+ return;
+
+ if(cfg::dat.bUseFastGradients && !(FLG_CORNER & CORNER_ACTIVE)) {
+ GRADIENT_RECT grect;
+ TRIVERTEX tvtx[2];
+ int orig = 1, dest = 0;
+
+ if(!(FLG_GRADIENT & GRADIENT_ACTIVE)) {
+ tvtx[0].Red = tvtx[1].Red = (COLOR16)GetRValue(basecolor) << 8;
+ tvtx[0].Blue = tvtx[1].Blue = (COLOR16)GetBValue(basecolor) << 8;
+ tvtx[0].Green = tvtx[1].Green = (COLOR16)GetGValue(basecolor) << 8;
+ tvtx[0].Alpha = tvtx[1].Alpha = 0;
+ }
+ else {
+ if(FLG_GRADIENT & GRADIENT_LR || FLG_GRADIENT & GRADIENT_TB) {
+ orig = 0;
+ dest = 1;
+ }
+
+ tvtx[orig].Red = (COLOR16)GetRValue(basecolor) << 8;
+ tvtx[orig].Blue = (COLOR16)GetBValue(basecolor) << 8;
+ tvtx[orig].Green = (COLOR16)GetGValue(basecolor) << 8;
+ tvtx[orig].Alpha = (COLOR16)0;
+
+ tvtx[dest].Red = (COLOR16)GetRValue(basecolor2) << 8;
+ tvtx[dest].Blue = (COLOR16)GetBValue(basecolor2) << 8;
+ tvtx[dest].Green = (COLOR16)GetGValue(basecolor2) << 8;
+ tvtx[dest].Alpha = (COLOR16)0;
+ }
+ grect.UpperLeft = 0;
+ grect.LowerRight = 1;
+
+ saved_alpha = (UCHAR) (basecolor >> 24);
+
+ if(alpha < 100) {
+ BLENDFUNCTION bf;
+ HDC hdc;
+ HBITMAP hbm, hbmOld;
+ LONG width = rc->right - rc->left, height = rc->bottom - rc->top;
+
+ tvtx[0].x = tvtx[0].y = 0;
+ tvtx[1].x = width;
+ tvtx[1].y = height;
+
+ basecolor = argb_from_cola(revcolref(basecolor), alpha);
+ basecolor2 = argb_from_cola(revcolref(basecolor2), alpha);
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = percent_to_byte((UINT32)alpha);
+ bf.AlphaFormat = 0; // so it will use our specified alpha value
+ hdc = CreateCompatibleDC(hdcwnd);
+ if (!hdc)
+ return;
+ hbm = CreateCompatibleBitmap(hdcwnd, width, height);
+ hbmOld = reinterpret_cast<HBITMAP>(SelectObject(hdc, hbm));
+ API::pfnGradientFill(hdc, tvtx, 2, &grect, 1, (FLG_GRADIENT & GRADIENT_TB || FLG_GRADIENT & GRADIENT_BT) ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H);
+ API::pfnAlphaBlend(hdcwnd, rc->left, rc->top, width, height, hdc, 0, 0, width, height, bf);
+
+ SelectObject(hdc, hbmOld);
+ DeleteObject(hbm);
+ DeleteDC(hdc);
+ }
+ else {
+ tvtx[0].x = rc->left;
+ tvtx[0].y = rc->top;
+ tvtx[1].x = rc->right;
+ tvtx[1].y = rc->bottom;
+ API::pfnGradientFill(hdcwnd, tvtx, 2, &grect, 1, (FLG_GRADIENT & GRADIENT_TB || FLG_GRADIENT & GRADIENT_BT) ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H);
+ }
+ DrawBorderStyle(hdcwnd, rc, BORDERSTYLE);
+ //_DebugPopup(0, "using gradient fill");
+ return;
+ }
+
+ hdc = CreateCompatibleDC(hdcwnd);
+ if (!hdc)
+ return;
+
+ ZeroMemory(&bmi, sizeof(BITMAPINFO));
+
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+ if (FLG_GRADIENT & GRADIENT_ACTIVE && (FLG_GRADIENT & GRADIENT_LR || FLG_GRADIENT & GRADIENT_RL)) {
+ bmi.bmiHeader.biWidth = ulBitmapWidth = realWidth;
+ bmi.bmiHeader.biHeight = ulBitmapHeight = 1;
+ } else if (FLG_GRADIENT & GRADIENT_ACTIVE && (FLG_GRADIENT & GRADIENT_TB || FLG_GRADIENT & GRADIENT_BT)) {
+ bmi.bmiHeader.biWidth = ulBitmapWidth = 1;
+ bmi.bmiHeader.biHeight = ulBitmapHeight = realHeight;
+ } else {
+ bmi.bmiHeader.biWidth = ulBitmapWidth = 1;
+ bmi.bmiHeader.biHeight = ulBitmapHeight = 1;
+ }
+
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = ulBitmapWidth * ulBitmapHeight * 4;
+
+ if (ulBitmapWidth <= 0 || ulBitmapHeight <= 0)
+ return;
+
+ hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
+ if (hbitmap == NULL || pvBits == NULL) {
+ DeleteDC(hdc);
+ return;
+ }
+
+ holdbitmap = reinterpret_cast<HBITMAP>(SelectObject(hdc, hbitmap));
+
+ // convert basecolor to RGB and then merge alpha so its ARGB
+ basecolor = argb_from_cola(revcolref(basecolor), alpha);
+ basecolor2 = argb_from_cola(revcolref(basecolor2), alpha);
+
+ ubRed = (UCHAR) (basecolor >> 16);
+ ubGreen = (UCHAR) (basecolor >> 8);
+ ubBlue = (UCHAR) basecolor;
+
+ ubRed2 = (UCHAR) (basecolor2 >> 16);
+ ubGreen2 = (UCHAR) (basecolor2 >> 8);
+ ubBlue2 = (UCHAR) basecolor2;
+
+ //DRAW BASE - make corner space 100% transparent
+ for (y = 0; y < ulBitmapHeight; y++) {
+ for (x = 0 ; x < ulBitmapWidth ; x++) {
+ if (FLG_GRADIENT & GRADIENT_ACTIVE) {
+ if (FLG_GRADIENT & GRADIENT_LR || FLG_GRADIENT & GRADIENT_RL) {
+ realx = x + realHeightHalf;
+ realx = (ULONG) realx > ulBitmapWidth ? ulBitmapWidth : realx;
+ gradientHorizontal(&ubRedFinal, &ubGreenFinal, &ubBlueFinal, ulBitmapWidth, ubRed, ubGreen, ubBlue, ubRed2, ubGreen2, ubBlue2, FLG_GRADIENT, transparent, realx, &ubAlpha);
+ } else if (FLG_GRADIENT & GRADIENT_TB || FLG_GRADIENT & GRADIENT_BT)
+ gradientVertical(&ubRedFinal, &ubGreenFinal, &ubBlueFinal, ulBitmapHeight, ubRed, ubGreen, ubBlue, ubRed2, ubGreen2, ubBlue2, FLG_GRADIENT, transparent, y, &ubAlpha);
+
+ fAlphaFactor = (float) ubAlpha / (float) 0xff;
+ ((UINT32 *) pvBits)[x + y * ulBitmapWidth] = (ubAlpha << 24) | ((UCHAR) (ubRedFinal * fAlphaFactor) << 16) | ((UCHAR) (ubGreenFinal * fAlphaFactor) << 8) | ((UCHAR) (ubBlueFinal * fAlphaFactor));
+ } else {
+ ubAlpha = percent_to_byte(alpha);
+ ubRedFinal = ubRed;
+ ubGreenFinal = ubGreen;
+ ubBlueFinal = ubBlue;
+ fAlphaFactor = (float) ubAlpha / (float) 0xff;
+
+ ((UINT32 *) pvBits)[x + y * ulBitmapWidth] = (ubAlpha << 24) | ((UCHAR) (ubRedFinal * fAlphaFactor) << 16) | ((UCHAR) (ubGreenFinal * fAlphaFactor) << 8) | ((UCHAR) (ubBlueFinal * fAlphaFactor));
+ }
+ }
+ }
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = (UCHAR) (basecolor >> 24);
+ bf.AlphaFormat = AC_SRC_ALPHA; // so it will use our specified alpha value
+
+ API::pfnAlphaBlend(hdcwnd, rc->left + realHeightHalf, rc->top, (realWidth - realHeightHalf * 2), realHeight, hdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);
+
+ SelectObject(hdc, holdbitmap);
+ DeleteObject(hbitmap);
+
+ saved_alpha = (UCHAR) (basecolor >> 24);
+
+ // corners
+ BrMask = CreateSolidBrush(RGB(0xFF, 0x00, 0xFF));
+ {
+ bmi.bmiHeader.biWidth = ulBitmapWidth = realHeightHalf;
+ bmi.bmiHeader.biHeight = ulBitmapHeight = realHeight;
+ bmi.bmiHeader.biSizeImage = ulBitmapWidth * ulBitmapHeight * 4;
+
+ if (ulBitmapWidth <= 0 || ulBitmapHeight <= 0) {
+ DeleteDC(hdc);
+ DeleteObject(BrMask);
+ return;
+ }
+
+ // TL+BL CORNER
+ hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
+
+ if(hbitmap == 0 || pvBits == NULL) {
+ DeleteObject(BrMask);
+ DeleteDC(hdc);
+ return;
+ }
+
+ holdbrush = reinterpret_cast<HBRUSH>(SelectObject(hdc, BrMask));
+ holdbitmap = reinterpret_cast<HBITMAP>(SelectObject(hdc, hbitmap));
+ RoundRect(hdc, -1, -1, ulBitmapWidth * 2 + 1, (realHeight + 1), cfg::dat.cornerRadius << 1, cfg::dat.cornerRadius << 1);
+
+ for (y = 0; y < ulBitmapHeight; y++) {
+ for (x = 0; x < ulBitmapWidth; x++) {
+ if (((((UINT32 *) pvBits)[x + y * ulBitmapWidth]) << 8) == 0xFF00FF00 || (y< ulBitmapHeight >> 1 && !(FLG_CORNER & CORNER_BL && FLG_CORNER & CORNER_ACTIVE)) || (y > ulBitmapHeight >> 2 && !(FLG_CORNER & CORNER_TL && FLG_CORNER & CORNER_ACTIVE))) {
+ if (FLG_GRADIENT & GRADIENT_ACTIVE) {
+ if (FLG_GRADIENT & GRADIENT_LR || FLG_GRADIENT & GRADIENT_RL)
+ gradientHorizontal(&ubRedFinal, &ubGreenFinal, &ubBlueFinal, realWidth, ubRed, ubGreen, ubBlue, ubRed2, ubGreen2, ubBlue2, FLG_GRADIENT, transparent, x, &ubAlpha);
+ else if (FLG_GRADIENT & GRADIENT_TB || FLG_GRADIENT & GRADIENT_BT)
+ gradientVertical(&ubRedFinal, &ubGreenFinal, &ubBlueFinal, ulBitmapHeight, ubRed, ubGreen, ubBlue, ubRed2, ubGreen2, ubBlue2, FLG_GRADIENT, transparent, y, &ubAlpha);
+
+ fAlphaFactor = (float) ubAlpha / (float) 0xff;
+ ((UINT32 *) pvBits)[x + y * ulBitmapWidth] = (ubAlpha << 24) | ((UCHAR) (ubRedFinal * fAlphaFactor) << 16) | ((UCHAR) (ubGreenFinal * fAlphaFactor) << 8) | ((UCHAR) (ubBlueFinal * fAlphaFactor));
+ } else {
+ ubAlpha = percent_to_byte(alpha);
+ ubRedFinal = ubRed;
+ ubGreenFinal = ubGreen;
+ ubBlueFinal = ubBlue;
+ fAlphaFactor = (float) ubAlpha / (float) 0xff;
+
+ ((UINT32 *) pvBits)[x + y * ulBitmapWidth] = (ubAlpha << 24) | ((UCHAR) (ubRedFinal * fAlphaFactor) << 16) | ((UCHAR) (ubGreenFinal * fAlphaFactor) << 8) | ((UCHAR) (ubBlueFinal * fAlphaFactor));
+ }
+ }
+ }
+ }
+ API::pfnAlphaBlend(hdcwnd, rc->left, rc->top, ulBitmapWidth, ulBitmapHeight, hdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);
+ SelectObject(hdc, holdbitmap);
+ DeleteObject(hbitmap);
+
+ // TR+BR CORNER
+ hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
+
+ //SelectObject(hdc, BrMask); // already BrMask?
+ holdbitmap = reinterpret_cast<HBITMAP>(SelectObject(hdc, hbitmap));
+ RoundRect(hdc, -1 - ulBitmapWidth, -1, ulBitmapWidth + 1, (realHeight + 1), cfg::dat.cornerRadius << 1, cfg::dat.cornerRadius << 1);
+
+ for (y = 0; y < ulBitmapHeight; y++) {
+ for (x = 0; x < ulBitmapWidth; x++) {
+ if (((((UINT32 *) pvBits)[x + y * ulBitmapWidth]) << 8) == 0xFF00FF00 || (y< ulBitmapHeight >> 1 && !(FLG_CORNER & CORNER_BR && FLG_CORNER & CORNER_ACTIVE)) || (y > ulBitmapHeight >> 1 && !(FLG_CORNER & CORNER_TR && FLG_CORNER & CORNER_ACTIVE))) {
+ if (FLG_GRADIENT & GRADIENT_ACTIVE) {
+ if (FLG_GRADIENT & GRADIENT_LR || FLG_GRADIENT & GRADIENT_RL) {
+ realx = x + realWidth;
+ realx = realx > realWidth ? realWidth : realx;
+ gradientHorizontal(&ubRedFinal, &ubGreenFinal, &ubBlueFinal, realWidth, ubRed, ubGreen, ubBlue, ubRed2, ubGreen2, ubBlue2, FLG_GRADIENT, transparent, realx, &ubAlpha);
+ } else if (FLG_GRADIENT & GRADIENT_TB || FLG_GRADIENT & GRADIENT_BT)
+ gradientVertical(&ubRedFinal, &ubGreenFinal, &ubBlueFinal, ulBitmapHeight, ubRed, ubGreen, ubBlue, ubRed2, ubGreen2, ubBlue2, FLG_GRADIENT, transparent, y, &ubAlpha);
+
+ fAlphaFactor = (float) ubAlpha / (float) 0xff;
+ ((UINT32 *) pvBits)[x + y * ulBitmapWidth] = (ubAlpha << 24) | ((UCHAR) (ubRedFinal * fAlphaFactor) << 16) | ((UCHAR) (ubGreenFinal * fAlphaFactor) << 8) | ((UCHAR) (ubBlueFinal * fAlphaFactor));
+ } else {
+ ubAlpha = percent_to_byte(alpha);
+ ubRedFinal = ubRed;
+ ubGreenFinal = ubGreen;
+ ubBlueFinal = ubBlue;
+ fAlphaFactor = (float) ubAlpha / (float) 0xff;
+
+ ((UINT32 *) pvBits)[x + y * ulBitmapWidth] = (ubAlpha << 24) | ((UCHAR) (ubRedFinal * fAlphaFactor) << 16) | ((UCHAR) (ubGreenFinal * fAlphaFactor) << 8) | ((UCHAR) (ubBlueFinal * fAlphaFactor));
+ }
+ }
+ }
+ }
+ API::pfnAlphaBlend(hdcwnd, rc->right - realHeightHalf, rc->top, ulBitmapWidth, ulBitmapHeight, hdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);
+ }
+ DrawBorderStyle(hdcwnd, rc, BORDERSTYLE);
+
+ SelectObject(hdc, holdbitmap);
+ DeleteObject(hbitmap);
+ SelectObject(hdc, holdbrush);
+ DeleteObject(BrMask);
+ DeleteDC(hdc);
+}
+
+void __inline gradientHorizontal(UCHAR *ubRedFinal, UCHAR *ubGreenFinal, UCHAR *ubBlueFinal, ULONG ulBitmapWidth, UCHAR ubRed, UCHAR ubGreen, UCHAR ubBlue, UCHAR ubRed2, UCHAR ubGreen2, UCHAR ubBlue2, DWORD FLG_GRADIENT, BOOL transparent, UINT32 x, UCHAR *ubAlpha)
+{
+ FLOAT fSolidMulti, fInvSolidMulti;
+
+ // solid to transparent
+ if (transparent) {
+ *ubAlpha = (UCHAR) ((float) x / (float) ulBitmapWidth * 255);
+ *ubAlpha = FLG_GRADIENT & GRADIENT_LR ? 0xFF - (*ubAlpha) : (*ubAlpha);
+ *ubRedFinal = ubRed; *ubGreenFinal = ubGreen; *ubBlueFinal = ubBlue;
+ } else { // solid to solid2
+ if (FLG_GRADIENT & GRADIENT_LR) {
+ fSolidMulti = ((float) x / (float) ulBitmapWidth);
+ fInvSolidMulti = 1 - fSolidMulti;
+ } else {
+ fInvSolidMulti = ((float) x / (float) ulBitmapWidth);
+ fSolidMulti = 1 - fInvSolidMulti;
+ }
+
+ *ubRedFinal = (UCHAR) (((float) ubRed * (float) fInvSolidMulti) + ((float) ubRed2 * (float) fSolidMulti));
+ *ubGreenFinal = (UCHAR) (((float) ubGreen * (float) fInvSolidMulti) + ((float) ubGreen2 * (float) fSolidMulti));
+ *ubBlueFinal = (UCHAR) (((float) ubBlue * (float) fInvSolidMulti) + ((float) ubBlue2 * (float) fSolidMulti));
+
+ *ubAlpha = 0xFF;
+ }
+}
+
+void __inline gradientVertical(UCHAR *ubRedFinal, UCHAR *ubGreenFinal, UCHAR *ubBlueFinal, ULONG ulBitmapHeight, UCHAR ubRed, UCHAR ubGreen, UCHAR ubBlue, UCHAR ubRed2, UCHAR ubGreen2, UCHAR ubBlue2, DWORD FLG_GRADIENT, BOOL transparent, UINT32 y, UCHAR *ubAlpha)
+{
+ FLOAT fSolidMulti, fInvSolidMulti;
+
+ // solid to transparent
+ if (transparent) {
+ *ubAlpha = (UCHAR) ((float) y / (float) ulBitmapHeight * 255);
+ *ubAlpha = FLG_GRADIENT & GRADIENT_BT ? 0xFF - *ubAlpha : *ubAlpha;
+ *ubRedFinal = ubRed; *ubGreenFinal = ubGreen; *ubBlueFinal = ubBlue;
+ } else { // solid to solid2
+ if (FLG_GRADIENT & GRADIENT_BT) {
+ fSolidMulti = ((float) y / (float) ulBitmapHeight);
+ fInvSolidMulti = 1 - fSolidMulti;
+ } else {
+ fInvSolidMulti = ((float) y / (float) ulBitmapHeight);
+ fSolidMulti = 1 - fInvSolidMulti;
+ }
+
+ *ubRedFinal = (UCHAR) (((float) ubRed * (float) fInvSolidMulti) + ((float) ubRed2 * (float) fSolidMulti));
+ *ubGreenFinal = (UCHAR) (((float) ubGreen * (float) fInvSolidMulti) + ((float) ubGreen2 * (float) fSolidMulti));
+ *ubBlueFinal = (UCHAR) (((float) ubBlue * (float) fInvSolidMulti) + ((float) ubBlue2 * (float) fSolidMulti));
+
+ *ubAlpha = 0xFF;
+ }
+}
+
+/*
+ * render a skin image to the given rect.
+ * all parameters are in ImageItem already pre-configured
+ */
+
+// XXX add support for more stretching options (stretch/tile divided image parts etc.
+
+void __fastcall IMG_RenderImageItem(HDC hdc, ImageItem *item, RECT *rc)
+{
+ BYTE l = item->bLeft, r = item->bRight, t = item->bTop, b = item->bBottom;
+ LONG width = rc->right - rc->left;
+ LONG height = rc->bottom - rc->top;
+ BOOL isGlyph = (item->dwFlags & IMAGE_GLYPH) && g_glyphItem;
+ HDC hdcSrc = isGlyph ? g_glyphItem->hdc : item->hdc;
+ LONG srcOrigX = isGlyph ? item->glyphMetrics[0] : 0;
+ LONG srcOrigY = isGlyph ? item->glyphMetrics[1] : 0;
+
+ if(item->dwFlags & IMAGE_FLAG_DIVIDED) {
+ // top 3 items
+
+ API::pfnAlphaBlend(hdc, rc->left, rc->top, l, t, hdcSrc, srcOrigX, srcOrigY, l, t, item->bf);
+ API::pfnAlphaBlend(hdc, rc->left + l, rc->top, width - l - r, t, hdcSrc, srcOrigX + l, srcOrigY, item->inner_width, t, item->bf);
+ API::pfnAlphaBlend(hdc, rc->right - r, rc->top, r, t, hdcSrc, srcOrigX + (item->width - r), srcOrigY, r, t, item->bf);
+
+ // middle 3 items
+
+ API::pfnAlphaBlend(hdc, rc->left, rc->top + t, l, height - t - b, hdcSrc, srcOrigX, srcOrigY + t, l, item->inner_height, item->bf);
+
+ if(item->dwFlags & IMAGE_FILLSOLID && item->fillBrush) {
+ RECT rcFill;
+ rcFill.left = rc->left + l; rcFill.top = rc->top +t;
+ rcFill.right = rc->right - r; rcFill.bottom = rc->bottom - b;
+ FillRect(hdc, &rcFill, item->fillBrush);
+ }
+ else
+ API::pfnAlphaBlend(hdc, rc->left + l, rc->top + t, width - l - r, height - t - b, hdcSrc, srcOrigX + l, srcOrigY + t, item->inner_width, item->inner_height, item->bf);
+
+ API::pfnAlphaBlend(hdc, rc->right - r, rc->top + t, r, height - t - b, hdcSrc, srcOrigX + (item->width - r), srcOrigY + t, r, item->inner_height, item->bf);
+
+ // bottom 3 items
+
+ API::pfnAlphaBlend(hdc, rc->left, rc->bottom - b, l, b, hdcSrc, srcOrigX, srcOrigY + (item->height - b), l, b, item->bf);
+ API::pfnAlphaBlend(hdc, rc->left + l, rc->bottom - b, width - l - r, b, hdcSrc, srcOrigX + l, srcOrigY + (item->height - b), item->inner_width, b, item->bf);
+ API::pfnAlphaBlend(hdc, rc->right - r, rc->bottom - b, r, b, hdcSrc, srcOrigX + (item->width - r), srcOrigY + (item->height - b), r, b, item->bf);
+ }
+ else {
+ switch(item->bStretch) {
+ case IMAGE_STRETCH_H:
+ // tile image vertically, stretch to width
+ {
+ LONG top = rc->top;
+
+ do {
+ if(top + item->height <= rc->bottom) {
+ API::pfnAlphaBlend(hdc, rc->left, top, width, item->height, hdcSrc, srcOrigX, srcOrigY, item->width, item->height, item->bf);
+ top += item->height;
+ }
+ else {
+ API::pfnAlphaBlend(hdc, rc->left, top, width, rc->bottom - top, hdcSrc, srcOrigX, srcOrigY, item->width, rc->bottom - top, item->bf);
+ break;
+ }
+ } while (TRUE);
+ break;
+ }
+ case IMAGE_STRETCH_V:
+ // tile horizontally, stretch to height
+ {
+ LONG left = rc->left;
+
+ do {
+ if(left + item->width <= rc->right) {
+ API::pfnAlphaBlend(hdc, left, rc->top, item->width, height, hdcSrc, srcOrigX, srcOrigY, item->width, item->height, item->bf);
+ left += item->width;
+ }
+ else {
+ API::pfnAlphaBlend(hdc, left, rc->top, rc->right - left, height, hdcSrc, srcOrigX, srcOrigY, rc->right - left, item->height, item->bf);
+ break;
+ }
+ } while (TRUE);
+ break;
+ }
+ case IMAGE_STRETCH_B:
+ // stretch the image in both directions...
+ API::pfnAlphaBlend(hdc, rc->left, rc->top, width, height, hdcSrc, srcOrigX, srcOrigY, item->width, item->height, item->bf);
+ break;
+ /*
+ case IMAGE_STRETCH_V:
+ // stretch vertically, draw 3 horizontal tiles...
+ AlphaBlend(hdc, rc->left, rc->top, l, height, item->hdc, 0, 0, l, item->height, item->bf);
+ AlphaBlend(hdc, rc->left + l, rc->top, width - l - r, height, item->hdc, l, 0, item->inner_width, item->height, item->bf);
+ AlphaBlend(hdc, rc->right - r, rc->top, r, height, item->hdc, item->width - r, 0, r, item->height, item->bf);
+ break;
+ case IMAGE_STRETCH_H:
+ // stretch horizontally, draw 3 vertical tiles...
+ AlphaBlend(hdc, rc->left, rc->top, width, t, item->hdc, 0, 0, item->width, t, item->bf);
+ AlphaBlend(hdc, rc->left, rc->top + t, width, height - t - b, item->hdc, 0, t, item->width, item->inner_height, item->bf);
+ AlphaBlend(hdc, rc->left, rc->bottom - b, width, b, item->hdc, 0, item->height - b, item->width, b, item->bf);
+ break;
+ */
+ default:
+ break;
+ }
+ }
+}
diff --git a/plugins/Clist_nicer/SRC/clc.cpp b/plugins/Clist_nicer/SRC/clc.cpp
new file mode 100644
index 0000000000..788eccb7fd
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clc.cpp
@@ -0,0 +1,827 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: clc.cpp 12968 2010-10-16 20:10:55Z Michael.Kunz@s2005.TU-Chemnitz.de $
+ *
+ */
+
+#include <commonheaders.h>
+#include <resource.h>
+#include <m_userinfo.h>
+#include "../cluiframes/cluiframes.h"
+#include "../coolsb/coolscroll.h"
+
+int DefaultImageListColorDepth = ILC_COLOR32;
+
+extern HPEN g_hPenCLUIFrames;
+extern HANDLE hExtraImageApplying;
+extern wndFrame *wndFrameCLC;
+extern ButtonItem *g_ButtonItems;
+
+extern int during_sizing;
+extern StatusItems_t *StatusItems;
+
+HIMAGELIST hCListImages;
+extern HIMAGELIST himlExtraImages;
+
+HANDLE hSoundHook = 0, hIcoLibChanged = 0, hSvc_GetContactStatusMsg = 0;
+
+static HANDLE hClcSettingsChanged, hClcDBEvent = 0;
+
+static HRESULT(WINAPI *MyCloseThemeData)(HANDLE);
+
+LONG g_cxsmIcon, g_cysmIcon;
+
+void SetDBButtonStates(HANDLE hContact);
+
+HMENU BuildGroupPopupMenu(struct ClcGroup* group)
+{
+ return (HMENU)CallService(MS_CLIST_MENUBUILDSUBGROUP, (WPARAM)group, 0);
+}
+
+int AvatarChanged(WPARAM wParam, LPARAM lParam)
+{
+ pcli->pfnClcBroadcast(INTM_AVATARCHANGED, wParam, lParam);
+ return 0;
+}
+
+int __forceinline __strcmp(const char * src, const char * dst)
+{
+ int ret = 0 ;
+
+ while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
+ ++src, ++dst;
+ return(ret);
+}
+
+static int ClcEventAdded(WPARAM wParam, LPARAM lParam)
+{
+ DBEVENTINFO dbei = {0};
+ int iEntry;
+ DWORD new_freq = 0;
+
+ cfg::dat.t_now = time(NULL);
+
+ if (wParam && lParam) {
+ dbei.cbSize = sizeof(dbei);
+ dbei.pBlob = 0;
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM)lParam, (LPARAM)&dbei);
+ if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ DWORD firstTime = cfg::getDword((HANDLE)wParam, "CList", "mf_firstEvent", 0);
+ DWORD count = cfg::getDword((HANDLE)wParam, "CList", "mf_count", 0);
+ count++;
+ new_freq = count ? (dbei.timestamp - firstTime) / count : 0x7fffffff;
+ cfg::writeDword((HANDLE)wParam, "CList", "mf_freq", new_freq);
+ cfg::writeDword((HANDLE)wParam, "CList", "mf_count", count);
+ iEntry = cfg::getCache((HANDLE)wParam, NULL);
+ if (iEntry >= 0 && iEntry < cfg::nextCacheEntry) {
+ cfg::eCache[iEntry].dwLastMsgTime = dbei.timestamp;
+ if (new_freq)
+ cfg::eCache[iEntry].msgFrequency = new_freq;
+ pcli->pfnClcBroadcast(INTM_FORCESORT, 0, 1);
+ }
+ }
+ }
+ return 0;
+}
+
+int ClcSoundHook(WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+
+static int ClcSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ char *szProto = NULL;
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+
+ if (wParam) {
+ if (!__strcmp(cws->szModule, "CList")) {
+ if (!__strcmp(cws->szSetting, "StatusMsg"))
+ SendMessage(pcli->hwndContactTree, INTM_STATUSMSGCHANGED, wParam, lParam);
+ } else if (!__strcmp(cws->szModule, "UserInfo")) {
+ if (!__strcmp(cws->szSetting, "ANSIcodepage"))
+ pcli->pfnClcBroadcast(INTM_CODEPAGECHANGED, wParam, lParam);
+ else if (!__strcmp(cws->szSetting, "Timezone") || !__strcmp(cws->szSetting, "TzName"))
+ ReloadExtraInfo((HANDLE)wParam);
+ } else if (wParam != 0 && (szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0)) != NULL) {
+ char *id = NULL;
+ if (!__strcmp(cws->szModule, "Protocol") && !__strcmp(cws->szSetting, "p")) {
+ char *szProto_s;
+ pcli->pfnClcBroadcast(INTM_PROTOCHANGED, wParam, lParam);
+ if (cws->value.type == DBVT_DELETED)
+ szProto_s = NULL;
+ else
+ szProto_s = cws->value.pszVal;
+ pcli->pfnChangeContactIcon((HANDLE) wParam, IconFromStatusMode(szProto_s, szProto_s == NULL ? ID_STATUS_OFFLINE : cfg::getWord((HANDLE) wParam, szProto_s, "Status", ID_STATUS_OFFLINE), (HANDLE) wParam, NULL), 0);
+ }
+ // something is being written to a protocol module
+ if (!__strcmp(szProto, cws->szModule)) {
+ // was a unique setting key written?
+ pcli->pfnInvalidateDisplayNameCacheEntry((HANDLE) wParam);
+ if (!__strcmp(cws->szSetting, "Status")) {
+ if (!cfg::getByte((HANDLE) wParam, "CList", "Hidden", 0)) {
+ if (cfg::getByte("CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)) {
+ // User's state is changing, and we are hideOffline-ing
+ if (cws->value.wVal == ID_STATUS_OFFLINE) {
+ pcli->pfnChangeContactIcon((HANDLE) wParam, IconFromStatusMode(cws->szModule, cws->value.wVal, (HANDLE) wParam, NULL), 0);
+ CallService(MS_CLUI_CONTACTDELETED, wParam, 0);
+ return 0;
+ }
+ pcli->pfnChangeContactIcon((HANDLE) wParam, IconFromStatusMode(cws->szModule, cws->value.wVal, (HANDLE) wParam, NULL), 1);
+ }
+ pcli->pfnChangeContactIcon((HANDLE) wParam, IconFromStatusMode(cws->szModule, cws->value.wVal, (HANDLE) wParam, NULL), 0);
+ }
+ SendMessage(pcli->hwndContactTree, INTM_STATUSCHANGED, wParam, lParam);
+ return 0;
+ } else if (strstr("YMsg|StatusDescr|XStatusMsg", cws->szSetting))
+ SendMessage(pcli->hwndContactTree, INTM_STATUSMSGCHANGED, wParam, lParam);
+ else if (strstr(cws->szSetting, "XStatus"))
+ SendMessage(pcli->hwndContactTree, INTM_XSTATUSCHANGED, wParam, lParam);
+ else if (!__strcmp(cws->szSetting, "Timezone") || !__strcmp(cws->szSetting, "TzName"))
+ ReloadExtraInfo((HANDLE)wParam);
+ else if (!__strcmp(cws->szSetting, "MirVer"))
+ NotifyEventHooks(hExtraImageApplying, wParam, 0);
+
+ if (cfg::dat.bMetaAvail && !(cfg::dat.dwFlags & CLUI_USEMETAICONS) && !__strcmp(szProto, cfg::dat.szMetaName)) {
+ if ((lstrlenA(cws->szSetting) > 6 && !strncmp(cws->szSetting, "Status", 6)) || strstr("Default,ForceSend,Nick", cws->szSetting))
+ pcli->pfnClcBroadcast(INTM_NAMEORDERCHANGED, wParam, lParam);
+ }
+ }
+ if (cfg::dat.bMetaAvail && cfg::dat.bMetaEnabled && !__strcmp(cws->szModule, cfg::dat.szMetaName) && !__strcmp(cws->szSetting, "IsSubcontact"))
+ pcli->pfnClcBroadcast(INTM_HIDDENCHANGED, wParam, lParam);
+ }
+ } else if (wParam == 0 && !__strcmp(cws->szModule, cfg::dat.szMetaName)) {
+ BYTE bMetaEnabled = cfg::getByte(cfg::dat.szMetaName, "Enabled", 1);
+ if (bMetaEnabled != (BYTE)cfg::dat.bMetaEnabled) {
+ cfg::dat.bMetaEnabled = bMetaEnabled;
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ }
+ } else if (wParam == 0 && !__strcmp(cws->szModule, "Skin")) {
+ if (!__strcmp(cws->szSetting, "UseSound")) {
+ if (hSoundHook) {
+ UnhookEvent(hSoundHook);
+ hSoundHook = 0;
+ }
+ cfg::dat.soundsOff = cfg::getByte(cws->szModule, cws->szSetting, 0) ? 0 : 1;
+ if (cfg::dat.soundsOff && hSoundHook == 0)
+ hSoundHook = HookEvent(ME_SKIN_PLAYINGSOUND, ClcSoundHook);
+ CheckDlgButton(pcli->hwndContactList, IDC_TBSOUND, cfg::dat.soundsOff ? BST_UNCHECKED : BST_CHECKED);
+ SetButtonStates(pcli->hwndContactList);
+ }
+ } else if (szProto == NULL && wParam == 0) {
+ if (!__strcmp(cws->szSetting, "XStatusId"))
+ CluiProtocolStatusChanged(0, cws->szModule);
+ return 0;
+ }
+ return 0;
+}
+
+static int ClcModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+
+static int ClcPreshutdown(WPARAM wParam, LPARAM lParam)
+{
+ SFL_Destroy();
+ cfg::shutDown = TRUE;
+ if (hSvc_GetContactStatusMsg)
+ DestroyServiceFunction(hSvc_GetContactStatusMsg);
+ UnhookEvent(hClcSettingsChanged);
+ UnhookEvent(hClcDBEvent);
+ if (hIcoLibChanged)
+ UnhookEvent(hIcoLibChanged);
+ return 0;
+}
+
+int ClcShutdown(WPARAM wParam, LPARAM lParam)
+{
+ if (cfg::dat.hIconInvisible)
+ DestroyIcon(cfg::dat.hIconInvisible);
+ if (cfg::dat.hIconVisible)
+ DestroyIcon(cfg::dat.hIconVisible);
+ if (cfg::dat.hIconChatactive)
+ DestroyIcon(cfg::dat.hIconChatactive);
+
+ DeleteObject(cfg::dat.hPen3DBright);
+ DeleteObject(cfg::dat.hPen3DDark);
+ DeleteObject(cfg::dat.hBrushColorKey);
+ DeleteObject(cfg::dat.hBrushCLCBk);
+ DeleteObject(cfg::dat.hBrushAvatarBorder);
+ DestroyMenu(cfg::dat.hMenuNotify);
+ ClearIcons(1);
+ SFL_UnregisterWindowClass();
+ if (cfg::eCache) {
+ int i;
+
+ for (i = 0; i < cfg::nextCacheEntry; i++) {
+ if (cfg::eCache[i].statusMsg)
+ free(cfg::eCache[i].statusMsg);
+ if (cfg::eCache[i].status_item) {
+ StatusItems_t *item = cfg::eCache[i].status_item;
+ int j;
+
+ free(cfg::eCache[i].status_item);
+ cfg::eCache[i].status_item = 0;
+ for (j = i; j < cfg::nextCacheEntry; j++) { // avoid duplicate free()'ing status item pointers (there are references from sub to master contacts, so compare the pointers...
+ if (cfg::eCache[j].status_item == item)
+ cfg::eCache[j].status_item = 0;
+ }
+ }
+ }
+ free(cfg::eCache);
+ cfg::eCache = NULL;
+ }
+ IMG_DeleteItems();
+ free(StatusItems);
+ DeleteCriticalSection(&cfg::cachecs);
+ return 0;
+}
+
+int LoadCLCModule(void)
+{
+ g_cxsmIcon = GetSystemMetrics(SM_CXSMICON);
+ g_cysmIcon = GetSystemMetrics(SM_CYSMICON);
+
+ hCListImages = (HIMAGELIST) CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, ClcModulesLoaded);
+ hClcSettingsChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, ClcSettingChanged);
+ hClcDBEvent = HookEvent(ME_DB_EVENT_ADDED, ClcEventAdded);
+ HookEvent(ME_OPT_INITIALISE, ClcOptInit);
+ HookEvent(ME_SYSTEM_SHUTDOWN, ClcPreshutdown);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// clist_nicer+ control window procedure
+
+extern LRESULT(CALLBACK *saveContactListControlWndProc)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+LRESULT CALLBACK ContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct ClcData *dat;
+ BOOL frameHasTitlebar = FALSE;
+
+ if (wndFrameCLC)
+ frameHasTitlebar = wndFrameCLC->TitleBar.ShowTitleBar;
+
+ dat = (struct ClcData *) GetWindowLongPtr(hwnd, 0);
+ if (msg >= CLM_FIRST && msg < CLM_LAST)
+ return ProcessExternalMessages(hwnd, dat, msg, wParam, lParam);
+
+ switch (msg) {
+ case WM_CREATE:
+ dat = (struct ClcData *)mir_alloc(sizeof(struct ClcData));
+ memset(dat, 0, sizeof(struct ClcData));
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR) dat);
+
+ RowHeight::Init(dat);
+ dat->forceScroll = 0;
+ dat->lastRepaint = 0;
+ dat->himlExtraColumns = himlExtraImages;
+ dat->hwndParent = GetParent(hwnd);
+ dat->lastSort = GetTickCount();
+ dat->bNeedSort = FALSE;
+ {
+ CREATESTRUCT *cs = (CREATESTRUCT *)lParam;
+ if (cs->lpCreateParams == (LPVOID)0xff00ff00) {
+ dat->bisEmbedded = FALSE;
+ dat->bHideSubcontacts = TRUE;
+ cfg::clcdat = dat;
+ if (cfg::dat.bShowLocalTime)
+ SetTimer(hwnd, TIMERID_REFRESH, 65000, NULL);
+ } else
+ dat->bisEmbedded = TRUE;
+ }
+ break;
+ case WM_SIZE:
+ pcli->pfnEndRename(hwnd, dat, 1);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ KillTimer(hwnd, TIMERID_RENAME);
+ pcli->pfnRecalcScrollBar(hwnd, dat);
+LBL_Def:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ case WM_NCCALCSIZE: {
+ return FrameNCCalcSize(hwnd, DefWindowProc, wParam, lParam, frameHasTitlebar);
+ }
+
+ /*
+ * scroll bar handling
+ */
+ case WM_NCPAINT:
+ return FrameNCPaint(hwnd, DefWindowProc, wParam, lParam, frameHasTitlebar);
+ case INTM_GROUPCHANGED: {
+ struct ClcContact *contact;
+ BYTE iExtraImage[MAXEXTRACOLUMNS];
+ BYTE flags = 0;
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ memset(iExtraImage, 0xFF, sizeof(iExtraImage));
+ else {
+ CopyMemory(iExtraImage, contact->iExtraImage, sizeof(iExtraImage));
+ flags = contact->flags;
+ }
+ pcli->pfnDeleteItemFromTree(hwnd, (HANDLE) wParam);
+ if (GetWindowLong(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN || !CLVM_GetContactHiddenStatus((HANDLE)wParam, NULL, dat)) {
+ NMCLISTCONTROL nm;
+ pcli->pfnAddContactToTree(hwnd, dat, (HANDLE) wParam, 1, 1);
+ if (FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL)) {
+ CopyMemory(contact->iExtraImage, iExtraImage, sizeof(iExtraImage));
+ if (flags & CONTACTF_CHECKED)
+ contact->flags |= CONTACTF_CHECKED;
+ }
+ nm.hdr.code = CLN_CONTACTMOVED;
+ nm.hdr.hwndFrom = hwnd;
+ nm.hdr.idFrom = GetDlgCtrlID(hwnd);
+ nm.flags = 0;
+ nm.hItem = (HANDLE) wParam;
+ SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) &nm);
+ }
+ dat->bNeedSort = TRUE;
+ PostMessage(hwnd, INTM_SORTCLC, 0, 1);
+ goto LBL_Def;
+ }
+
+ case INTM_ICONCHANGED: {
+ struct ClcContact *contact = NULL;
+ struct ClcGroup *group = NULL;
+ int recalcScrollBar = 0, shouldShow;
+ WORD status = ID_STATUS_OFFLINE;
+ char *szProto;
+ int contactRemoved = 0;
+ HANDLE hSelItem = NULL;
+ struct ClcContact *selcontact = NULL;
+
+ szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (szProto == NULL)
+ status = ID_STATUS_OFFLINE;
+ else
+ status = cfg::getWord((HANDLE) wParam, szProto, "Status", ID_STATUS_OFFLINE);
+
+ shouldShow = (GetWindowLong(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN || !CLVM_GetContactHiddenStatus((HANDLE)wParam, szProto, dat)) && ((cfg::dat.bFilterEffective ? TRUE : !pcli->pfnIsHiddenMode(dat, status)) || CallService(MS_CLIST_GETCONTACTICON, wParam, 0) != lParam);// XXX CLVM changed - this means an offline msg is flashing, so the contact should be shown
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, &group, NULL)) {
+ if (shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) {
+ if (dat->selection >= 0 && pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1)
+ hSelItem = pcli->pfnContactToHItem(selcontact);
+ pcli->pfnAddContactToTree(hwnd, dat, (HANDLE) wParam, 0, 0);
+ recalcScrollBar = 1;
+ FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL);
+ if (contact) {
+ contact->iImage = (WORD) lParam;
+ pcli->pfnNotifyNewContact(hwnd, (HANDLE) wParam);
+ }
+ }
+ } else {
+ //item in list already
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ if (contact->iImage == (WORD) lParam)
+ break;
+ if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline || cfg::dat.bFilterEffective)) { // CLVM changed
+ if (dat->selection >= 0 && pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1)
+ hSelItem = pcli->pfnContactToHItem(selcontact);
+ pcli->pfnRemoveItemFromGroup(hwnd, group, contact, 0);
+ contactRemoved = TRUE;
+ recalcScrollBar = 1;
+ } else {
+ contact->iImage = (WORD) lParam;
+ if (!pcli->pfnIsHiddenMode(dat, status))
+ contact->flags |= CONTACTF_ONLINE;
+ else
+ contact->flags &= ~CONTACTF_ONLINE;
+ }
+ }
+ if (hSelItem) {
+ struct ClcGroup *selgroup;
+ if (pcli->pfnFindItem(hwnd, dat, hSelItem, &selcontact, &selgroup, NULL))
+ dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, li.List_IndexOf((SortedList*) & selgroup->cl, selcontact));
+ else
+ dat->selection = -1;
+ }
+ dat->bNeedSort = TRUE;
+ PostMessage(hwnd, INTM_SORTCLC, 0, recalcScrollBar);
+ PostMessage(hwnd, INTM_INVALIDATE, 0, (LPARAM)(contactRemoved ? 0 : wParam));
+ if (recalcScrollBar)
+ pcli->pfnRecalcScrollBar(hwnd, dat);
+ goto LBL_Def;
+ }
+ case INTM_METACHANGED: {
+ struct ClcContact *contact;
+ if (!pcli->pfnFindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+ if (contact->bIsMeta && cfg::dat.bMetaAvail && !(cfg::dat.dwFlags & CLUI_USEMETAICONS)) {
+ contact->hSubContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) contact->hContact, 0);
+ contact->metaProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) contact->hSubContact, 0);
+ contact->iImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM) contact->hSubContact, 0);
+ if (contact->extraCacheEntry >= 0 && contact->extraCacheEntry < cfg::nextCacheEntry) {
+ int subIndex = cfg::getCache(contact->hSubContact, contact->metaProto);
+ cfg::eCache[contact->extraCacheEntry].proto_status_item = GetProtocolStatusItem(contact->metaProto);
+ if (subIndex >= 0 && subIndex <= cfg::nextCacheEntry) {
+ cfg::eCache[contact->extraCacheEntry].status_item = cfg::eCache[subIndex].status_item;
+ CopyMemory(cfg::eCache[contact->extraCacheEntry].iExtraImage, cfg::eCache[subIndex].iExtraImage, MAXEXTRACOLUMNS);
+ cfg::eCache[contact->extraCacheEntry].iExtraValid = cfg::eCache[subIndex].iExtraValid;
+ }
+ }
+ }
+ SendMessage(hwnd, INTM_NAMEORDERCHANGED, wParam, lParam);
+ goto LBL_Def;
+ }
+ case INTM_METACHANGEDEVENT: {
+ struct ClcContact *contact;
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+ if (lParam == 0)
+ SendMessage(hwnd, CLM_AUTOREBUILD, 0, 0);
+ goto LBL_Def;
+ }
+ case INTM_NAMECHANGED: {
+ struct ClcContact *contact;
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+ lstrcpyn(contact->szText, pcli->pfnGetContactDisplayName((HANDLE)wParam, 0), safe_sizeof(contact->szText));
+#if defined(_UNICODE)
+ RTL_DetectAndSet(contact, 0);
+#endif
+ dat->bNeedSort = TRUE;
+ PostMessage(hwnd, INTM_SORTCLC, 0, 0);
+ goto LBL_Def;
+ }
+
+ case INTM_CODEPAGECHANGED: {
+ struct ClcContact *contact = NULL;
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+ contact->codePage = cfg::getDword((HANDLE) wParam, "Tab_SRMsg", "ANSIcodepage", cfg::getDword((HANDLE)wParam, "UserInfo", "ANSIcodepage", CP_ACP));
+ PostMessage(hwnd, INTM_INVALIDATE, 0, 0);
+ goto LBL_Def;
+ }
+ case INTM_AVATARCHANGED: {
+ struct avatarCacheEntry *cEntry = (struct avatarCacheEntry *)lParam;
+ struct ClcContact *contact = NULL;
+
+ if (wParam == 0) {
+ //RemoveFromImgCache(0, cEntry);
+ cfg::dat.bForceRefetchOnPaint = TRUE;
+ RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
+ cfg::dat.bForceRefetchOnPaint = FALSE;
+ goto LBL_Def;
+ }
+
+ if (!FindItem(hwnd, dat, (HANDLE)wParam, &contact, NULL, NULL))
+ return 0;
+ contact->ace = cEntry;
+ if (cEntry == NULL)
+ contact->cFlags &= ~ECF_AVATAR;
+ else {
+ DWORD dwFlags;
+
+ if (contact->extraCacheEntry >= 0 && contact->extraCacheEntry < cfg::nextCacheEntry)
+ dwFlags = cfg::eCache[contact->extraCacheEntry].dwDFlags;
+ else
+ dwFlags = cfg::getDword(contact->hContact, "CList", "CLN_Flags", 0);
+ if (cfg::dat.dwFlags & CLUI_FRAME_AVATARS)
+ contact->cFlags = (dwFlags & ECF_HIDEAVATAR ? contact->cFlags & ~ECF_AVATAR : contact->cFlags | ECF_AVATAR);
+ else
+ contact->cFlags = (dwFlags & ECF_FORCEAVATAR ? contact->cFlags | ECF_AVATAR : contact->cFlags & ~ECF_AVATAR);
+ }
+ PostMessage(hwnd, INTM_INVALIDATE, 0, (LPARAM)contact->hContact);
+ goto LBL_Def;
+ }
+ case INTM_STATUSMSGCHANGED: {
+ struct ClcContact *contact = NULL;
+ int index = -1;
+ char *szProto = NULL;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ index = cfg::getCache((HANDLE)wParam, NULL);
+ else {
+ index = contact->extraCacheEntry;
+ szProto = contact->proto;
+ }
+ GetCachedStatusMsg(index, szProto);
+ PostMessage(hwnd, INTM_INVALIDATE, 0, (LPARAM)(contact ? contact->hContact : 0));
+ goto LBL_Def;
+ }
+ case INTM_STATUSCHANGED: {
+ struct ClcContact *contact = NULL;
+ WORD wStatus;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+
+ wStatus = cfg::getWord((HANDLE)wParam, contact->proto, "Status", ID_STATUS_OFFLINE);
+ if (cfg::dat.bNoOfflineAvatars && wStatus != ID_STATUS_OFFLINE && contact->wStatus == ID_STATUS_OFFLINE) {
+ contact->wStatus = wStatus;
+ if (cfg::dat.bAvatarServiceAvail && contact->ace == NULL)
+ LoadAvatarForContact(contact);
+ }
+ contact->wStatus = wStatus;
+ goto LBL_Def;
+ }
+ case INTM_PROTOCHANGED: {
+ DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *) lParam;
+ struct ClcContact *contact = NULL;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+ contact->proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ CallService(MS_CLIST_INVALIDATEDISPLAYNAME, wParam, 0);
+ lstrcpyn(contact->szText, pcli->pfnGetContactDisplayName((HANDLE)wParam, 0), safe_sizeof(contact->szText));
+#if defined(_UNICODE)
+ RTL_DetectAndSet(contact, 0);
+#endif
+ dat->bNeedSort = TRUE;
+ PostMessage(hwnd, INTM_SORTCLC, 0, 0);
+ goto LBL_Def;
+ }
+
+ case INTM_INVALIDATE:
+ if (!dat->bNeedPaint) {
+ KillTimer(hwnd, TIMERID_PAINT);
+ SetTimer(hwnd, TIMERID_PAINT, 100, NULL);
+ dat->bNeedPaint = TRUE;
+ }
+
+ if (lParam && !dat->bisEmbedded) {
+ struct ClcContact *contact = NULL;
+
+ if (FindItem(hwnd, dat, (HANDLE)lParam, &contact, NULL, 0)) {
+ if (contact && contact->extraCacheEntry >= 0 && contact->extraCacheEntry < cfg::nextCacheEntry && cfg::eCache[contact->extraCacheEntry].floater)
+ FLT_Update(dat, contact);
+ }
+ }
+ goto LBL_Def;
+
+ case INTM_INVALIDATECONTACT: {
+ struct ClcContact *contact = 0;
+ struct ClcGroup *group = 0;
+ int iItem;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, &group, NULL))
+ break;
+
+ if (contact == 0 || group == 0)
+ break;
+
+ iItem = pcli->pfnGetRowsPriorTo(&dat->list, group, li.List_IndexOf((SortedList*) & group->cl, contact));
+ pcli->pfnInvalidateItem(hwnd, dat, iItem);
+ goto LBL_Def;
+ }
+ case INTM_FORCESORT:
+ dat->bNeedSort = TRUE;
+ return SendMessage(hwnd, INTM_SORTCLC, wParam, lParam);
+ case INTM_SORTCLC:
+ if (dat->bNeedSort) {
+ pcli->pfnSortCLC(hwnd, dat, TRUE);
+ dat->bNeedSort = FALSE;
+ }
+ if (lParam)
+ pcli->pfnRecalcScrollBar(hwnd, dat);
+ goto LBL_Def;
+
+ case INTM_IDLECHANGED: {
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+ char *szProto;
+ struct ClcContact *contact = NULL;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ break;
+ szProto = (char*)cws->szModule;
+ if (szProto == NULL)
+ break;
+ contact->flags &= ~CONTACTF_IDLE;
+ if (cfg::getDword((HANDLE) wParam, szProto, "IdleTS", 0)) {
+ contact->flags |= CONTACTF_IDLE;
+ }
+ PostMessage(hwnd, INTM_INVALIDATE, 0, (LPARAM)contact->hContact);
+ goto LBL_Def;
+ }
+ case INTM_XSTATUSCHANGED: {
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+ char *szProto;
+ struct ClcContact *contact = NULL;
+ int index;
+
+ szProto = (char *)cws->szModule;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL)) {
+ index = cfg::getCache((HANDLE)wParam, szProto);
+ if (!dat->bisEmbedded && cfg::dat.bMetaAvail && szProto) { // may be a subcontact, forward the xstatus
+ if (cfg::getByte((HANDLE)wParam, cfg::dat.szMetaName, "IsSubcontact", 0)) {
+ HANDLE hMasterContact = (HANDLE)cfg::getDword((HANDLE)wParam, cfg::dat.szMetaName, "Handle", 0);
+ if (hMasterContact && hMasterContact != (HANDLE)wParam) // avoid recursive call of settings handler
+ cfg::writeByte(hMasterContact, cfg::dat.szMetaName, "XStatusId",
+ (BYTE)cfg::getByte((HANDLE)wParam, szProto, "XStatusId", 0));
+ break;
+ }
+ }
+ } else {
+ contact->xStatus = cfg::getByte((HANDLE) wParam, szProto, "XStatusId", 0);
+ index = contact->extraCacheEntry;
+ }
+ if (szProto == NULL)
+ break;
+ GetCachedStatusMsg(index, szProto);
+ PostMessage(hwnd, INTM_INVALIDATE, 0, (LPARAM)(contact ? contact->hContact : 0));
+ goto LBL_Def;
+ }
+ case WM_PAINT: {
+ HDC hdc;
+ PAINTSTRUCT ps;
+ hdc = BeginPaint(hwnd, &ps);
+ if (IsWindowVisible(hwnd) && !during_sizing && !cfg::shutDown) {
+ PaintClc(hwnd, dat, hdc, &ps.rcPaint);
+ dat->bNeedPaint = FALSE;
+ dat->lastRepaint = GetTickCount();
+ }
+ EndPaint(hwnd, &ps);
+ if (dat->selection != dat->oldSelection && !dat->bisEmbedded && g_ButtonItems != NULL) {
+ SetDBButtonStates(0);
+ dat->oldSelection = dat->selection;
+ }
+ goto LBL_Def;
+ }
+
+ case WM_MOUSEWHEEL:
+ dat->forceScroll = TRUE;
+ break;
+
+ case WM_TIMER:
+ if (wParam == TIMERID_PAINT) {
+ KillTimer(hwnd, TIMERID_PAINT);
+ InvalidateRect(hwnd, NULL, FALSE);
+ goto LBL_Def;
+ }
+
+ if (wParam == TIMERID_REFRESH) {
+ InvalidateRect(hwnd, NULL, FALSE);
+ goto LBL_Def;
+ }
+ break;
+
+ case WM_LBUTTONDBLCLK: {
+ struct ClcContact *contact;
+ DWORD hitFlags;
+ ReleaseCapture();
+ dat->iHotTrack = -1;
+ pcli->pfnHideInfoTip(hwnd, dat);
+ KillTimer(hwnd, TIMERID_RENAME);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ dat->szQuickSearch[0] = 0;
+ dat->selection = HitTest(hwnd, dat, (short) LOWORD(lParam), (short) HIWORD(lParam), &contact, NULL, &hitFlags);
+ if (hitFlags & CLCHT_ONITEMEXTRAEX && hwnd == pcli->hwndContactTree && contact != 0) {
+ int column = hitFlags >> 24;
+ if (column-- > 0) {
+ if (contact->type == CLCIT_CONTACT) {
+ CONTACTINFO ci;
+ ZeroMemory(&ci,sizeof(CONTACTINFO));
+ ci.cbSize = sizeof(CONTACTINFO);
+ ci.hContact = contact->hContact;
+ ci.szProto = contact->proto;
+
+ if (column == 0) {
+ ci.dwFlag = CNF_EMAIL;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ char buf[4096];
+ mir_snprintf(buf, sizeof(buf), "mailto:%s", (LPCSTR)ci.pszVal);
+ mir_free(ci.pszVal);
+ ShellExecuteA(hwnd, "open", buf, NULL, NULL, SW_SHOW);
+ }
+ return TRUE;
+ }
+ if (column == 1) {
+ ci.dwFlag = CNF_HOMEPAGE;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ ShellExecuteA(hwnd, "open", (LPCSTR)ci.pszVal, NULL, NULL, SW_SHOW);
+ mir_free(ci.pszVal);
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
+ InvalidateRect(hwnd, NULL, FALSE);
+ if (dat->selection != -1)
+ pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
+ if (hitFlags & CLCHT_ONAVATAR && cfg::dat.bDblClkAvatars) {
+ CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)contact->hContact, 0);
+ return TRUE;
+ }
+ if (hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMLABEL | CLCHT_ONITEMSPACE)) {
+ UpdateWindow(hwnd);
+ pcli->pfnDoSelectionDefaultAction(hwnd, dat);
+ }
+ return TRUE;
+ }
+ case WM_CONTEXTMENU: {
+ struct ClcContact *contact;
+ HMENU hMenu = NULL;
+ POINT pt;
+ DWORD hitFlags;
+
+ pcli->pfnEndRename(hwnd, dat, 1);
+ pcli->pfnHideInfoTip(hwnd, dat);
+ KillTimer(hwnd, TIMERID_RENAME);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ if (GetFocus() != hwnd)
+ SetFocus(hwnd);
+ dat->iHotTrack = -1;
+ dat->szQuickSearch[0] = 0;
+ pt.x = (short) LOWORD(lParam);
+ pt.y = (short) HIWORD(lParam);
+ if (pt.x == -1 && pt.y == -1) {
+ dat->selection = pcli->pfnGetRowByIndex(dat, dat->selection, &contact, NULL);
+ if (dat->selection != -1)
+ pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
+ pt.x = dat->iconXSpace + 15;
+ pt.y = RowHeight::getItemTopY(dat, dat->selection) - dat->yScroll + (int)(dat->row_heights[dat->selection] * .7);
+ hitFlags = dat->selection == -1 ? CLCHT_NOWHERE : CLCHT_ONITEMLABEL;
+ } else {
+ ScreenToClient(hwnd, &pt);
+ dat->selection = HitTest(hwnd, dat, pt.x, pt.y, &contact, NULL, &hitFlags);
+ }
+ InvalidateRect(hwnd, NULL, FALSE);
+ if (dat->selection != -1)
+ pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
+ UpdateWindow(hwnd);
+
+ if (dat->selection != -1 && hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMCHECK | CLCHT_ONITEMLABEL)) {
+ if (contact->type == CLCIT_GROUP) {
+ hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDSUBGROUP, (WPARAM)contact->group, 0);
+ ClientToScreen(hwnd, &pt);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL);
+ CheckMenuItem(hMenu, POPUP_GROUPHIDEOFFLINE, contact->group->hideOffline ? MF_CHECKED : MF_UNCHECKED);
+ DestroyMenu(hMenu);
+ return 0;
+ } else if (contact->type == CLCIT_CONTACT)
+ hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) contact->hContact, 0);
+ } else {
+ //call parent for new group/hide offline menu
+ PostMessage(GetParent(hwnd), WM_CONTEXTMENU, wParam, lParam);
+ return 0;
+ }
+ if (hMenu != NULL) {
+ ClientToScreen(hwnd, &pt);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
+ DestroyMenu(hMenu);
+ }
+ return 0;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == POPUP_NEWGROUP)
+ SendMessage(GetParent(hwnd), msg, wParam, lParam);
+ break;
+
+ case WM_NCHITTEST: {
+ LRESULT lr = SendMessage(GetParent(hwnd), WM_NCHITTEST, wParam, lParam);
+ if (lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT
+ || lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT)
+ return HTTRANSPARENT;
+ break;
+ }
+ case WM_DESTROY: {
+ int i;
+
+ if (!dat->bisEmbedded) {
+ for (i = 0; i < cfg::nextCacheEntry; i++) {
+ if (cfg::eCache[i].floater && cfg::eCache[i].floater->hwnd)
+ DestroyWindow(cfg::eCache[i].floater->hwnd);
+ }
+ }
+ RowHeight::Free(dat);
+ break;
+ }
+ }
+
+ {
+ LRESULT result = saveContactListControlWndProc(hwnd, msg, wParam, lParam);
+ return result;
+ }
+}
diff --git a/plugins/Clist_nicer/SRC/clcidents.cpp b/plugins/Clist_nicer/SRC/clcidents.cpp
new file mode 100644
index 0000000000..1315a61f32
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clcidents.cpp
@@ -0,0 +1,102 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include <commonheaders.h>
+
+/* the CLC uses 3 different ways to identify elements in its list, this file
+contains routines to convert between them.
+
+1) struct ClcContact/struct ClcGroup pair. Only ever used within the duration
+ of a single operation, but used at some point in nearly everything
+2) index integer. The 0-based number of the item from the top. Only visible
+ items are counted (ie not closed groups). Used for saving selection and drag
+ highlight
+3) hItem handle. Either the hContact or (hGroup|HCONTACT_ISGROUP). Used
+ exclusively externally
+
+1->2: GetRowsPriorTo()
+1->3: ContactToHItem()
+3->1: FindItem()
+2->1: GetRowByIndex()
+*/
+
+int FindItem(HWND hwnd, struct ClcData *dat, HANDLE hItem, struct ClcContact **contact, struct ClcGroup **subgroup, int *isVisible)
+{
+ int index = 0;
+ int nowVisible = 1;
+ struct ClcGroup *group = &dat->list;
+
+ group->scanIndex = 0;
+ for (; ;) {
+ if (group->scanIndex == group->cl.count) {
+ struct ClcGroup *tgroup;
+ group = group->parent;
+ if (group == NULL)
+ break;
+ nowVisible = 1;
+ for (tgroup = group; tgroup; tgroup = tgroup->parent) {
+ if (!(group->expanded)) {
+ nowVisible = 0; break;
+ }
+ }
+ group->scanIndex++;
+ continue;
+ }
+ if (nowVisible)
+ index++;
+ if ((IsHContactGroup(hItem) && group->cl.items[group->scanIndex]->type == CLCIT_GROUP && ((UINT_PTR) hItem & ~HCONTACT_ISGROUP) == group->cl.items[group->scanIndex]->groupId) || (IsHContactContact(hItem) && group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->hContact == hItem) || (IsHContactInfo(hItem) && group->cl.items[group->scanIndex]->type == CLCIT_INFO && group->cl.items[group->scanIndex]->hContact == (HANDLE) ((UINT_PTR) hItem & ~HCONTACT_ISINFO))) {
+ if (isVisible) {
+ if (!nowVisible)
+ *isVisible = 0;
+ else {
+ int posy = RowHeight::getItemTopY(dat,index+1);
+ if(posy<dat->yScroll)
+ *isVisible=0;
+ //if ((index + 1) * dat->rowHeight< dat->yScroll)
+ // *isVisible = 0;
+ else {
+ RECT clRect;
+ GetClientRect(hwnd, &clRect);
+ //if (index * dat->rowHeight >= dat->yScroll + clRect.bottom)
+ if (posy >= dat->yScroll + clRect.bottom)
+ *isVisible = 0;
+ else
+ *isVisible = 1;
+ }
+ }
+ }
+ if (contact)
+ *contact = group->cl.items[group->scanIndex];
+ if (subgroup)
+ *subgroup = group;
+ return 1;
+ }
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
+ group = group->cl.items[group->scanIndex]->group;
+ group->scanIndex = 0;
+ nowVisible &= (group->expanded);
+ continue;
+ }
+ group->scanIndex++;
+ }
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/clcitems.cpp b/plugins/Clist_nicer/SRC/clcitems.cpp
new file mode 100644
index 0000000000..d62dd52db9
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clcitems.cpp
@@ -0,0 +1,662 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: clcitems.cpp 12968 2010-10-16 20:10:55Z Michael.Kunz@s2005.TU-Chemnitz.de $
+ *
+ */
+
+#include <commonheaders.h>
+#include <m_icq.h>
+
+extern HANDLE hExtraImageListRebuilding, hExtraImageApplying;
+
+extern int ( *saveAddContactToGroup )(struct ClcData *dat, struct ClcGroup *group, HANDLE hContact);
+extern int ( *saveAddInfoItemToGroup )(struct ClcGroup *group, int flags, const TCHAR *pszText);
+extern struct ClcGroup* ( *saveRemoveItemFromGroup )(HWND hwnd, struct ClcGroup *group, struct ClcContact *contact, int updateTotalCount);
+extern struct ClcGroup* ( *saveAddGroup )(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers);
+
+static void TZ_LoadTimeZone(HANDLE hContact, struct TExtraCache *c, const char *szProto);
+
+//routines for managing adding/removal of items in the list, including sorting
+
+struct ClcContact* CreateClcContact( void )
+{
+ struct ClcContact* p = (struct ClcContact*)mir_alloc( sizeof( struct ClcContact ) );
+ if ( p != NULL ) {
+ ZeroMemory(p, sizeof(struct ClcContact));
+ //p->clientId = -1;
+ p->extraCacheEntry = -1;
+ p->avatarLeft = p->extraIconRightBegin = -1;
+ p->isRtl = 0;
+ p->ace = 0;
+ }
+ return p;
+}
+
+int AddInfoItemToGroup(struct ClcGroup *group, int flags, const TCHAR *pszText)
+{
+ int i = saveAddInfoItemToGroup(group, flags, pszText);
+ struct ClcContact* p = group->cl.items[i];
+ p->codePage = 0;
+ //p->clientId = -1;
+ p->bIsMeta = 0;
+ p->xStatus = 0;
+ p->ace = NULL;
+ p->extraCacheEntry = -1;
+ p->avatarLeft = p->extraIconRightBegin = -1;
+ return i;
+}
+
+struct ClcGroup *AddGroup(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers)
+{
+ struct ClcGroup *p = saveAddGroup( hwnd, dat, szName, flags, groupId, calcTotalMembers);
+
+ #if defined(_UNICODE)
+ if ( p && p->parent )
+ RTL_DetectGroupName( p->parent->cl.items[ p->parent->cl.count-1] );
+ #else
+ if ( p && p->parent )
+ p->parent->cl.items[ p->parent->cl.count -1]->isRtl = 0;
+ #endif
+ return p;
+}
+
+struct ClcGroup *RemoveItemFromGroup(HWND hwnd, struct ClcGroup *group, struct ClcContact *contact, int updateTotalCount)
+{
+ if(contact->extraCacheEntry >= 0 && contact->extraCacheEntry < cfg::nextCacheEntry) {
+ if(cfg::eCache[contact->extraCacheEntry].floater && cfg::eCache[contact->extraCacheEntry].floater->hwnd)
+ ShowWindow(cfg::eCache[contact->extraCacheEntry].floater->hwnd, SW_HIDE);
+ }
+ return(saveRemoveItemFromGroup(hwnd, group, contact, updateTotalCount));
+}
+
+void LoadAvatarForContact(struct ClcContact *p)
+{
+ DWORD dwFlags;
+
+ if(p->extraCacheEntry >= 0 && p->extraCacheEntry < cfg::nextCacheEntry)
+ dwFlags = cfg::eCache[p->extraCacheEntry].dwDFlags;
+ else
+ dwFlags = cfg::getDword(p->hContact, "CList", "CLN_Flags", 0);
+
+ if(cfg::dat.dwFlags & CLUI_FRAME_AVATARS)
+ p->cFlags = (dwFlags & ECF_HIDEAVATAR ? p->cFlags & ~ECF_AVATAR : p->cFlags | ECF_AVATAR);
+ else
+ p->cFlags = (dwFlags & ECF_FORCEAVATAR ? p->cFlags | ECF_AVATAR : p->cFlags & ~ECF_AVATAR);
+
+ p->ace = NULL;
+ if(cfg::dat.bAvatarServiceAvail && (p->cFlags & ECF_AVATAR) && (!cfg::dat.bNoOfflineAvatars || p->wStatus != ID_STATUS_OFFLINE)) {
+ p->ace = (struct avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)p->hContact, 0);
+ if (p->ace != NULL && p->ace->cbSize != sizeof(struct avatarCacheEntry))
+ p->ace = NULL;
+ if (p->ace != NULL)
+ p->ace->t_lastAccess = cfg::dat.t_now;
+ }
+ if(p->ace == NULL)
+ p->cFlags &= ~ECF_AVATAR;
+}
+
+int AddContactToGroup(struct ClcData *dat, struct ClcGroup *group, HANDLE hContact)
+{
+ int i = saveAddContactToGroup( dat, group, hContact );
+ struct ClcContact* p = group->cl.items[i];
+
+ p->wStatus = cfg::getWord(hContact, p->proto, "Status", ID_STATUS_OFFLINE);
+ p->xStatus = cfg::getByte(hContact, p->proto, "XStatusId", 0);
+ //p->iRowHeight = -1;
+
+ if (p->proto)
+ p->bIsMeta = !strcmp(p->proto, cfg::dat.szMetaName);
+ else
+ p->bIsMeta = FALSE;
+ if (p->bIsMeta && cfg::dat.bMetaAvail && !(cfg::dat.dwFlags & CLUI_USEMETAICONS)) {
+ p->hSubContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) hContact, 0);
+ p->metaProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) p->hSubContact, 0);
+ p->iImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM) p->hSubContact, 0);
+ } else {
+ p->iImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM) hContact, 0);
+ p->metaProto = NULL;
+ }
+
+ p->codePage = cfg::getDword(hContact, "Tab_SRMsg", "ANSIcodepage", cfg::getDword(hContact, "UserInfo", "ANSIcodepage", CP_ACP));
+ p->bSecondLine = cfg::getByte(hContact, "CList", "CLN_2ndline", cfg::dat.dualRowMode);
+
+ if(dat->bisEmbedded)
+ p->extraCacheEntry = -1;
+ else {
+ p->extraCacheEntry = cfg::getCache(p->hContact, p->proto);
+ GetExtendedInfo( p, dat);
+ if(p->extraCacheEntry >= 0 && p->extraCacheEntry < cfg::nextCacheEntry) {
+ cfg::eCache[p->extraCacheEntry].proto_status_item = GetProtocolStatusItem(p->bIsMeta ? p->metaProto : p->proto);
+ if(cfg::getByte(p->hContact, "CList", "floating", 0) && g_floatoptions.enabled) {
+ if(cfg::eCache[p->extraCacheEntry].floater == NULL)
+ FLT_Create(p->extraCacheEntry);
+ else {
+ ShowWindow(cfg::eCache[p->extraCacheEntry].floater->hwnd, SW_SHOWNOACTIVATE);
+ FLT_Update(dat, p);
+ }
+ }
+ }
+ LoadAvatarForContact(p);
+ // notify other plugins to re-supply their extra images (icq for xstatus, mBirthday etc...)
+ NotifyEventHooks(hExtraImageApplying, (WPARAM)hContact, 0);
+ }
+#if defined(_UNICODE)
+ RTL_DetectAndSet( p, p->hContact);
+#endif
+ p->avatarLeft = p->extraIconRightBegin = -1;
+ p->flags |= cfg::getByte(p->hContact, "CList", "Priority", 0) ? CONTACTF_PRIORITY : 0;
+
+ return i;
+}
+
+void RebuildEntireList(HWND hwnd, struct ClcData *dat)
+{
+ char *szProto;
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ HANDLE hContact;
+ struct ClcGroup *group;
+ DBVARIANT dbv = {0};
+
+ RowHeight::Clear(dat);
+ RowHeight::getMaxRowHeight(dat, hwnd);
+
+ dat->list.expanded = 1;
+ dat->list.hideOffline = cfg::getByte("CLC", "HideOfflineRoot", 0);
+ dat->list.cl.count = 0;
+ dat->list.totalMembers = 0;
+ dat->selection = -1;
+ dat->SelectMode = cfg::getByte("CLC", "SelectMode", 0); {
+ int i;
+ TCHAR *szGroupName;
+ DWORD groupFlags;
+
+ for (i = 1; ; i++) {
+ szGroupName = pcli->pfnGetGroupName(i, &groupFlags);
+ if (szGroupName == NULL)
+ break;
+ pcli->pfnAddGroup(hwnd, dat, szGroupName, groupFlags, i, 0);
+ }
+ }
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) {
+ if (style & CLS_SHOWHIDDEN || !CLVM_GetContactHiddenStatus(hContact, NULL, dat)) {
+ ZeroMemory((void *)&dbv, sizeof(dbv));
+ if (cfg::getTString(hContact, "CList", "Group", &dbv))
+ group = &dat->list;
+ else {
+ group = pcli->pfnAddGroup(hwnd, dat, dbv.ptszVal, (DWORD) - 1, 0, 0);
+ mir_free(dbv.ptszVal);
+ }
+
+ if (group != NULL) {
+ group->totalMembers++;
+ if (!(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) {
+ szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto == NULL) {
+ if (!pcli->pfnIsHiddenMode(dat, ID_STATUS_OFFLINE))
+ AddContactToGroup(dat, group, hContact);
+ } else if (!pcli->pfnIsHiddenMode(dat, (WORD) cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE)))
+ AddContactToGroup(dat, group, hContact);
+ } else
+ AddContactToGroup(dat, group, hContact);
+ }
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+
+ if (style & CLS_HIDEEMPTYGROUPS) {
+ group = &dat->list;
+ group->scanIndex = 0;
+ for (; ;) {
+ if (group->scanIndex == group->cl.count) {
+ group = group->parent;
+ if (group == NULL)
+ break;
+ } else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
+ if (group->cl.items[group->scanIndex]->group->cl.count == 0) {
+ group = pcli->pfnRemoveItemFromGroup(hwnd, group, group->cl.items[group->scanIndex], 0);
+ } else {
+ group = group->cl.items[group->scanIndex]->group;
+ group->scanIndex = 0;
+ }
+ continue;
+ }
+ group->scanIndex++;
+ }
+ }
+ pcli->pfnSortCLC(hwnd, dat, 0);
+ if(!dat->bisEmbedded)
+ FLT_SyncWithClist();
+}
+
+/*
+ * status msg in the database has changed.
+ * get it and store it properly formatted in the extra data cache
+ */
+
+BYTE GetCachedStatusMsg(int iExtraCacheEntry, char *szProto)
+{
+ DBVARIANT dbv = {0};
+ HANDLE hContact;
+ struct TExtraCache *cEntry;
+ int result;
+
+ if(iExtraCacheEntry < 0 || iExtraCacheEntry > cfg::nextCacheEntry)
+ return 0;
+
+ cEntry = &cfg::eCache[iExtraCacheEntry];
+
+ cEntry->bStatusMsgValid = STATUSMSG_NOTFOUND;
+ hContact = cEntry->hContact;
+
+ result = cfg::getTString(hContact, "CList", "StatusMsg", &dbv);
+ if ( !result && lstrlen(dbv.ptszVal) > 1)
+ cEntry->bStatusMsgValid = STATUSMSG_CLIST;
+ else {
+ if(!szProto)
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(szProto) {
+ if ( !result )
+ DBFreeVariant( &dbv );
+ if( !( result = cfg::getTString(hContact, szProto, "YMsg", &dbv)) && lstrlen(dbv.ptszVal) > 1)
+ cEntry->bStatusMsgValid = STATUSMSG_YIM;
+ else if ( !(result = cfg::getTString(hContact, szProto, "StatusDescr", &dbv)) && lstrlen(dbv.ptszVal) > 1)
+ cEntry->bStatusMsgValid = STATUSMSG_GG;
+ else if( !(result = cfg::getTString(hContact, szProto, "XStatusMsg", &dbv)) && lstrlen(dbv.ptszVal) > 1)
+ cEntry->bStatusMsgValid = STATUSMSG_XSTATUS;
+ } }
+
+ if(cEntry->bStatusMsgValid == STATUSMSG_NOTFOUND) { // no status msg, consider xstatus name (if available)
+ if ( !result )
+ DBFreeVariant( &dbv );
+ result = cfg::getTString(hContact, szProto, "XStatusName", &dbv);
+ if ( !result && lstrlen(dbv.ptszVal) > 1) {
+ int iLen = lstrlen(dbv.ptszVal);
+ cEntry->bStatusMsgValid = STATUSMSG_XSTATUSNAME;
+ cEntry->statusMsg = (TCHAR *)realloc(cEntry->statusMsg, (iLen + 2) * sizeof(TCHAR));
+ _tcsncpy(cEntry->statusMsg, dbv.ptszVal, iLen + 1);
+ }
+ else {
+ ICQ_CUSTOM_STATUS cst = {0};
+ int xStatus;
+ WPARAM xStatus2;
+ TCHAR xStatusName[128];
+ char szServiceName[128];
+
+ mir_snprintf(szServiceName, 128, "%s%s", szProto, PS_ICQ_GETCUSTOMSTATUSEX);
+
+ cst.cbSize = sizeof(ICQ_CUSTOM_STATUS);
+ cst.flags = CSSF_MASK_STATUS;
+ cst.status = &xStatus;
+ if(ServiceExists(szServiceName) && !CallService(szServiceName, (WPARAM)hContact, (LPARAM)&cst) && xStatus > 0) {
+ cst.flags = CSSF_MASK_NAME | CSSF_DEFAULT_NAME | CSSF_TCHAR;
+ cst.wParam = &xStatus2;
+ cst.ptszName = xStatusName;
+ if(!CallService(szServiceName, (WPARAM)hContact, (LPARAM)&cst)) {
+ TCHAR *szwXstatusName = TranslateTS(xStatusName);
+ cEntry->statusMsg = (TCHAR *)realloc(cEntry->statusMsg, (lstrlen(szwXstatusName) + 2) * sizeof(TCHAR));
+ _tcsncpy(cEntry->statusMsg, szwXstatusName, lstrlen(szwXstatusName) + 1);
+ cEntry->bStatusMsgValid = STATUSMSG_XSTATUSNAME;
+ }
+ }
+ }
+ }
+ if(cEntry->bStatusMsgValid > STATUSMSG_XSTATUSNAME) {
+ int j = 0, i;
+ cEntry->statusMsg = (TCHAR *)realloc(cEntry->statusMsg, (lstrlen(dbv.ptszVal) + 2) * sizeof(TCHAR));
+ for(i = 0; dbv.ptszVal[i]; i++) {
+ if(dbv.ptszVal[i] == (TCHAR)0x0d)
+ continue;
+ cEntry->statusMsg[j] = dbv.ptszVal[i] == (wchar_t)0x0a ? (wchar_t)' ' : dbv.ptszVal[i];
+ j++;
+ }
+ cEntry->statusMsg[j] = (TCHAR)0;
+ }
+ if ( !result )
+ DBFreeVariant( &dbv );
+
+#if defined(_UNICODE)
+ if(cEntry->bStatusMsgValid != STATUSMSG_NOTFOUND) {
+ WORD infoTypeC2[12];
+ int iLen, i
+ ;
+ ZeroMemory(infoTypeC2, sizeof(WORD) * 12);
+ iLen = min(lstrlenW(cEntry->statusMsg), 10);
+ GetStringTypeW(CT_CTYPE2, cEntry->statusMsg, iLen, infoTypeC2);
+ cEntry->dwCFlags &= ~ECF_RTLSTATUSMSG;
+ for(i = 0; i < 10; i++) {
+ if(infoTypeC2[i] == C2_RIGHTTOLEFT) {
+ cEntry->dwCFlags |= ECF_RTLSTATUSMSG;
+ break;
+ }
+ }
+ }
+#endif
+ if(cEntry->hTimeZone == NULL)
+ TZ_LoadTimeZone(hContact, cEntry, szProto);
+ return cEntry->bStatusMsgValid;;
+}
+
+/*
+ * load time zone information for the contact
+ * if TzName is set, use it. It has to be a standard windows time zone name
+ * Currently, it can only be set by using UserInfoEx plugin
+ *
+ * Fallback: use ordinary GMT offsets (incorrect, in some cases due to DST
+ * differences.
+ */
+
+static void TZ_LoadTimeZone(HANDLE hContact, struct TExtraCache *c, const char *szProto)
+{
+ DWORD flags = 0;
+ if (cfg::dat.bShowLocalTimeSelective) flags |= TZF_DIFONLY;
+ c->hTimeZone = tmi.createByContact(hContact, flags);
+}
+
+void ReloadExtraInfo(HANDLE hContact)
+{
+ if(hContact && pcli->hwndContactTree) {
+ int index = cfg::getCache(hContact, NULL);
+ if(index >= 0 && index < cfg::nextCacheEntry) {
+ char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+
+ TZ_LoadTimeZone(hContact, &cfg::eCache[index], szProto);
+ InvalidateRect(pcli->hwndContactTree, NULL, FALSE);
+ }
+ }
+}
+
+/*
+ * autodetect RTL property of the nickname, evaluates the first 10 characters of the nickname only
+ */
+
+#if defined(_UNICODE)
+void RTL_DetectAndSet(struct ClcContact *contact, HANDLE hContact)
+{
+ WORD infoTypeC2[12];
+ int i, index;
+ TCHAR *szText = NULL;
+ DWORD iLen;
+
+ ZeroMemory(infoTypeC2, sizeof(WORD) * 12);
+
+ if(contact == NULL) {
+ szText = pcli->pfnGetContactDisplayName(hContact, 0);
+ index = cfg::getCache(hContact, NULL);
+ }
+ else {
+ szText = contact->szText;
+ index = contact->extraCacheEntry;
+ }
+ if(index >= 0 && index < cfg::nextCacheEntry) {
+ iLen = min(lstrlenW(szText), 10);
+ GetStringTypeW(CT_CTYPE2, szText, iLen, infoTypeC2);
+ cfg::eCache[index].dwCFlags &= ~ECF_RTLNICK;
+ for(i = 0; i < 10; i++) {
+ if(infoTypeC2[i] == C2_RIGHTTOLEFT) {
+ cfg::eCache[index].dwCFlags |= ECF_RTLNICK;
+ return;
+ }
+ }
+ }
+}
+
+void RTL_DetectGroupName(struct ClcContact *group)
+{
+ WORD infoTypeC2[12];
+ int i;
+ DWORD iLen;
+
+ group->isRtl = 0;
+
+ if(group->szText) {
+ iLen = min(lstrlenW(group->szText), 10);
+ GetStringTypeW(CT_CTYPE2, group->szText, iLen, infoTypeC2);
+ for(i = 0; i < 10; i++) {
+ if(infoTypeC2[i] == C2_RIGHTTOLEFT) {
+ group->isRtl = 1;
+ return;
+ }
+ }
+ }
+}
+#endif
+/*
+ * check for exteneded user information - email, phone numbers, homepage
+ * set extra icons accordingly
+ */
+
+void GetExtendedInfo(struct ClcContact *contact, struct ClcData *dat)
+{
+ CONTACTINFO ci;
+ BOOL iCacheNew = FALSE;
+ int index;
+
+ if(dat->bisEmbedded || contact == NULL)
+ return;
+
+ if(contact->proto == NULL || contact->hContact == 0)
+ return;
+
+ index = contact->extraCacheEntry;
+
+ //firstTime = DBGetContactSettingDword(contact->hContact, "CList", "mf_firstEvent", 0);
+ //count = DBGetContactSettingDword(contact->hContact, "CList", "mf_count", 0);
+ //new_freq = count ? (g_CluiData.t_now - firstTime) / count : 0x7fffffff;
+ cfg::eCache[index].msgFrequency = cfg::getDword(contact->hContact, "CList", "mf_freq", 0x7fffffff);
+ //g_ExtraCache[index].msgFrequency = new_freq;
+ //DBWriteContactSettingDword(contact->hContact, "CList", "mf_freq", new_freq);
+
+ if(index >= 0 && index < cfg::nextCacheEntry) {
+ if(cfg::eCache[index].valid)
+ return;
+ cfg::eCache[index].valid = TRUE;
+ }
+ else
+ return;
+
+ cfg::eCache[index].isChatRoom = cfg::getByte(contact->hContact, contact->proto, "ChatRoom", 0);
+
+ cfg::eCache[index].iExtraValid &= ~(EIMG_SHOW_EMAIL | EIMG_SHOW_SMS | EIMG_SHOW_WEB);
+ cfg::eCache[index].iExtraImage[EXTRA_ICON_EMAIL] = cfg::eCache[index].iExtraImage[EXTRA_ICON_WEB] = cfg::eCache[index].iExtraImage[EXTRA_ICON_SMS] = 0xff;
+
+ ZeroMemory(&ci,sizeof(CONTACTINFO));
+ ci.cbSize = sizeof(CONTACTINFO);
+ ci.hContact = contact->hContact;
+ ci.szProto = contact->proto;
+
+ ci.dwFlag = CNF_EMAIL;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ cfg::eCache[index].iExtraImage[EXTRA_ICON_EMAIL] = 0;
+ mir_free(ci.pszVal);
+ }
+
+ ci.dwFlag = CNF_HOMEPAGE;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ cfg::eCache[index].iExtraImage[EXTRA_ICON_WEB] = 1;
+ mir_free(ci.pszVal);
+ }
+
+ ci.dwFlag = CNF_CELLULAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ cfg::eCache[index].iExtraImage[EXTRA_ICON_SMS] = 2;
+ mir_free(ci.pszVal);
+ }
+ else {
+ ci.dwFlag = CNF_PHONE;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ cfg::eCache[index].iExtraImage[EXTRA_ICON_SMS] = 2;
+ mir_free(ci.pszVal);
+ }
+ }
+
+ // set the mask for valid extra images...
+
+ cfg::eCache[index].iExtraValid |= ((cfg::eCache[index].iExtraImage[EXTRA_ICON_EMAIL] != 0xff ? EIMG_SHOW_EMAIL : 0) |
+ (cfg::eCache[index].iExtraImage[EXTRA_ICON_WEB] != 0xff ? EIMG_SHOW_WEB : 0) |
+ (cfg::eCache[index].iExtraImage[EXTRA_ICON_SMS] != 0xff ? EIMG_SHOW_SMS : 0));
+
+
+}
+
+void LoadSkinItemToCache(struct TExtraCache *cEntry, const char *szProto)
+{
+ HANDLE hContact = cEntry->hContact;
+
+ if(cfg::getByte(hContact, "EXTBK", "VALID", 0)) {
+ if(cEntry->status_item == NULL)
+ cEntry->status_item = reinterpret_cast<StatusItems_t *>(malloc(sizeof(StatusItems_t)));
+ ZeroMemory(cEntry->status_item, sizeof(StatusItems_t));
+ strcpy(cEntry->status_item->szName, "{--CONTACT--}"); // mark as "per contact" item
+ cEntry->status_item->IGNORED = 0;
+
+ cEntry->status_item->TEXTCOLOR = cfg::getDword(hContact, "EXTBK", "TEXT", RGB(20, 20, 20));
+ cEntry->status_item->COLOR = cfg::getDword(hContact, "EXTBK", "COLOR1", RGB(224, 224, 224));
+ cEntry->status_item->COLOR2 = cfg::getDword(hContact, "EXTBK", "COLOR2", RGB(224, 224, 224));
+ cEntry->status_item->ALPHA = (BYTE)cfg::getByte(hContact, "EXTBK", "ALPHA", 100);
+
+ cEntry->status_item->MARGIN_LEFT = (DWORD)cfg::getByte(hContact, "EXTBK", "LEFT", 0);
+ cEntry->status_item->MARGIN_RIGHT = (DWORD)cfg::getByte(hContact, "EXTBK", "RIGHT", 0);
+ cEntry->status_item->MARGIN_TOP = (DWORD)cfg::getByte(hContact, "EXTBK", "TOP", 0);
+ cEntry->status_item->MARGIN_BOTTOM = (DWORD)cfg::getByte(hContact, "EXTBK", "BOTTOM", 0);
+
+ cEntry->status_item->COLOR2_TRANSPARENT = (BYTE)cfg::getByte(hContact, "EXTBK", "TRANS", 1);
+ cEntry->status_item->BORDERSTYLE = cfg::getDword(hContact, "EXTBK", "BDR", 0);
+
+ cEntry->status_item->CORNER = cfg::getByte(hContact, "EXTBK", "CORNER", 0);
+ cEntry->status_item->GRADIENT = cfg::getByte(hContact, "EXTBK", "GRAD", 0);
+ }
+ else if(cEntry->status_item) {
+ free(cEntry->status_item);
+ cEntry->status_item = NULL;
+ }
+}
+
+void ReloadSkinItemsToCache()
+{
+ int i;
+ char *szProto;
+
+ for(i = 0; i < cfg::nextCacheEntry; i++) {
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)cfg::eCache[i].hContact, 0);
+ if(szProto)
+ LoadSkinItemToCache(&cfg::eCache[i], szProto);
+ }
+}
+
+DWORD CalcXMask(HANDLE hContact)
+{
+ DWORD dwXMask = cfg::getDword(hContact, "CList", "CLN_xmask", 0);
+ int i;
+ DWORD dwResult = cfg::dat.dwExtraImageMask, bForced, bHidden;
+
+ for(i = 0; i <= 10; i++) {
+ bForced = (dwXMask & (1 << (2 * i)));
+ bHidden = (dwXMask & (1 << (2 * i + 1)));
+ if(bForced == 0 && bHidden == 0)
+ continue;
+ else if(bForced)
+ dwResult |= (1 << i);
+ else if(bHidden)
+ dwResult &= ~(1 << i);
+ }
+ return(dwResult);
+}
+
+/*
+ * checks the currently active view mode filter and returns true, if the contact should be hidden
+ * if no view mode is active, it returns the CList/Hidden setting
+ * also cares about sub contacts (if meta is active)
+ */
+
+int __fastcall CLVM_GetContactHiddenStatus(HANDLE hContact, char *szProto, struct ClcData *dat)
+{
+ int dbHidden = cfg::getByte(hContact, "CList", "Hidden", 0); // default hidden state, always respect it.
+ int filterResult = 1;
+ DBVARIANT dbv = {0};
+ char szTemp[64];
+ TCHAR szGroupMask[256];
+ DWORD dwLocalMask;
+
+ // always hide subcontacts (but show them on embedded contact lists)
+
+ if(cfg::dat.bMetaAvail && dat != NULL && dat->bHideSubcontacts && cfg::dat.bMetaEnabled && cfg::getByte(hContact, cfg::dat.szMetaName, "IsSubcontact", 0))
+ return 1;
+
+ if(cfg::dat.bFilterEffective) {
+ if(szProto == NULL)
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ // check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set).
+ if(cfg::dat.bFilterEffective & CLVM_STICKY_CONTACTS) {
+ if((dwLocalMask = cfg::getDword(hContact, "CLVM", cfg::dat.current_viewmode, 0)) != 0) {
+ if(cfg::dat.bFilterEffective & CLVM_FILTER_STICKYSTATUS) {
+ WORD wStatus = cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask));
+ }
+ return 0;
+ }
+ }
+ // check the proto, use it as a base filter result for all further checks
+ if(cfg::dat.bFilterEffective & CLVM_FILTER_PROTOS) {
+ mir_snprintf(szTemp, sizeof(szTemp), "%s|", szProto);
+ filterResult = strstr(cfg::dat.protoFilter, szTemp) ? 1 : 0;
+ }
+ if(cfg::dat.bFilterEffective & CLVM_FILTER_GROUPS) {
+ if(!cfg::getTString(hContact, "CList", "Group", &dbv)) {
+ _sntprintf(szGroupMask, safe_sizeof(szGroupMask), _T("%s|"), &dbv.ptszVal[1]);
+ filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(cfg::dat.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(cfg::dat.groupFilter, szGroupMask) ? 1 : 0));
+ mir_free(dbv.ptszVal);
+ }
+ else if(cfg::dat.filterFlags & CLVM_INCLUDED_UNGROUPED)
+ filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1;
+ else
+ filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0;
+ }
+ if(cfg::dat.bFilterEffective & CLVM_FILTER_STATUS) {
+ WORD wStatus = cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ filterResult = (cfg::dat.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & cfg::dat.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & cfg::dat.statusMaskFilter ? 1 : 0));
+ }
+ if(cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG) {
+ DWORD now;
+ int iEntry = cfg::getCache(hContact, szProto);
+ if(iEntry >= 0 && iEntry <= cfg::nextCacheEntry) {
+ now = cfg::dat.t_now;
+ now -= cfg::dat.lastMsgFilter;
+ if(cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN)
+ filterResult = filterResult & (cfg::eCache[iEntry].dwLastMsgTime < now);
+ else if(cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN)
+ filterResult = filterResult & (cfg::eCache[iEntry].dwLastMsgTime > now);
+ }
+ }
+ return (dbHidden | !filterResult);
+ }
+ else
+ return dbHidden;
+}
diff --git a/plugins/Clist_nicer/SRC/clcmsgs.cpp b/plugins/Clist_nicer/SRC/clcmsgs.cpp
new file mode 100644
index 0000000000..97a4d0bb99
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clcmsgs.cpp
@@ -0,0 +1,221 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: clcmsgs.cpp 12535 2010-08-29 23:48:32Z silvercircle $
+ *
+ */
+
+#include <commonheaders.h>
+
+//processing of all the CLM_ messages incoming
+
+extern LRESULT ( *saveProcessExternalMessages )(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam);
+
+LRESULT ProcessExternalMessages(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case CLM_SETSTICKY:
+ {
+ struct ClcContact *contact;
+ struct ClcGroup *group;
+
+ if (wParam == 0 || !FindItem(hwnd, dat, (HANDLE) wParam, &contact, &group, NULL))
+ return 0;
+ if (lParam)
+ contact->flags |= CONTACTF_STICKY;
+ else
+ contact->flags &= ~CONTACTF_STICKY;
+ break;
+ }
+
+ case CLM_SETEXTRAIMAGEINT:
+ {
+ struct ClcContact *contact = NULL;
+ int index = -1;
+
+ if (LOWORD(lParam) >= MAXEXTRACOLUMNS || wParam == 0)
+ return 0;
+
+ if (!FindItem(hwnd, dat, (HANDLE) wParam, &contact, NULL, NULL))
+ return 0;
+
+ index = contact->extraCacheEntry;
+
+ if(contact->type != CLCIT_CONTACT) // || contact->bIsMeta)
+ return 0;
+
+ //if(contact->bIsMeta && LOWORD(lParam) != EIMG_EXTRA && LOWORD(lParam) != EIMG_CLIENT)
+ // return 0;
+
+ /*
+ if(contact->hContact == 5846286) {
+ _DebugTraceA("set extra image %d", LOWORD(lParam));
+ }
+ */
+ if(index >= 0 && index < cfg::nextCacheEntry) {
+ cfg::eCache[index].iExtraImage[LOWORD(lParam)] = (BYTE)HIWORD(lParam);
+ cfg::eCache[index].iExtraValid = cfg::eCache[index].iExtraImage[LOWORD(lParam)] != (BYTE)0xff ? (cfg::eCache[index].iExtraValid | (1 << LOWORD(lParam))) : (cfg::eCache[index].iExtraValid & ~(1 << LOWORD(lParam)));
+ PostMessage(hwnd, INTM_INVALIDATE, 0, (LPARAM)(contact ? contact->hContact : 0));
+ }
+ }
+ return 0;
+ case CLM_SETEXTRAIMAGEINTMETA:
+ {
+ HANDLE hMasterContact = 0;
+ int index = -1;
+
+ if (LOWORD(lParam) >= MAXEXTRACOLUMNS)
+ return 0;
+
+ index = cfg::getCache((HANDLE)wParam, NULL);
+ if(index >= 0 && index < cfg::nextCacheEntry) {
+ cfg::eCache[index].iExtraImage[LOWORD(lParam)] = (BYTE)HIWORD(lParam);
+ cfg::eCache[index].iExtraValid = cfg::eCache[index].iExtraImage[LOWORD(lParam)] != (BYTE)0xff ? (cfg::eCache[index].iExtraValid | (1 << LOWORD(lParam))) : (cfg::eCache[index].iExtraValid & ~(1 << LOWORD(lParam)));
+ }
+
+ hMasterContact = (HANDLE)cfg::getDword((HANDLE)wParam, cfg::dat.szMetaName, "Handle", 0);
+
+ index = cfg::getCache(hMasterContact, NULL);
+ if(index >= 0 && index < cfg::nextCacheEntry) {
+ cfg::eCache[index].iExtraImage[LOWORD(lParam)] = (BYTE)HIWORD(lParam);
+ cfg::eCache[index].iExtraValid = cfg::eCache[index].iExtraImage[LOWORD(lParam)] != (BYTE)0xff ? (cfg::eCache[index].iExtraValid | (1 << LOWORD(lParam))) : (cfg::eCache[index].iExtraValid & ~(1 << LOWORD(lParam)));
+ PostMessage(hwnd, INTM_INVALIDATE, 0, 0);
+ }
+ }
+ return 0;
+
+ case CLM_GETSTATUSMSG:
+ {
+ struct ClcContact *contact = NULL;
+
+ if (wParam == 0)
+ return 0;
+
+ if (!FindItem(hwnd, dat, (HANDLE)wParam, &contact, NULL, NULL))
+ return 0;
+ if(contact->type != CLCIT_CONTACT)
+ return 0;
+ if(contact->extraCacheEntry >= 0 && contact->extraCacheEntry <= cfg::nextCacheEntry) {
+ if(cfg::eCache[contact->extraCacheEntry].bStatusMsgValid != STATUSMSG_NOTFOUND)
+ return((INT_PTR)cfg::eCache[contact->extraCacheEntry].statusMsg);
+ } }
+ return 0;
+
+ case CLM_SETHIDESUBCONTACTS:
+ dat->bHideSubcontacts = (BOOL)lParam;
+ return 0;
+
+ case CLM_TOGGLEPRIORITYCONTACT:
+ {
+ struct ClcContact *contact = NULL;
+
+ if (wParam == 0)
+ return 0;
+
+ if (!FindItem(hwnd, dat, (HANDLE)wParam, &contact, NULL, NULL))
+ return 0;
+ if(contact->type != CLCIT_CONTACT)
+ return 0;
+ contact->flags ^= CONTACTF_PRIORITY;
+ cfg::writeByte(contact->hContact, "CList", "Priority", (BYTE)(contact->flags & CONTACTF_PRIORITY ? 1 : 0));
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ return 0;
+ }
+ case CLM_QUERYPRIORITYCONTACT:
+ {
+ struct ClcContact *contact = NULL;
+
+ if (wParam == 0)
+ return 0;
+
+ if (!FindItem(hwnd, dat, (HANDLE)wParam, &contact, NULL, NULL))
+ return 0;
+ if(contact->type != CLCIT_CONTACT)
+ return 0;
+ return(contact->flags & CONTACTF_PRIORITY ? 1 : 0);
+ }
+ case CLM_TOGGLEFLOATINGCONTACT:
+ {
+ struct ClcContact *contact = NULL;
+ BYTE state;
+ int iEntry;
+
+ if (wParam == 0)
+ return 0;
+
+ if (!FindItem(hwnd, dat, (HANDLE)wParam, &contact, NULL, NULL))
+ return 0;
+ if(contact->type != CLCIT_CONTACT)
+ return 0;
+
+ iEntry = contact->extraCacheEntry;
+
+ if(iEntry >= 0 && iEntry <= cfg::nextCacheEntry) {
+ state = !cfg::getByte(contact->hContact, "CList", "floating", 0);
+ if(state) {
+ if(cfg::eCache[iEntry].floater == NULL)
+ FLT_Create(iEntry);
+ ShowWindow(cfg::eCache[contact->extraCacheEntry].floater->hwnd, SW_SHOW);
+ }
+ else {
+ if(cfg::eCache[iEntry].floater && cfg::eCache[iEntry].floater->hwnd) {
+ DestroyWindow(cfg::eCache[iEntry].floater->hwnd);
+ cfg::eCache[iEntry].floater = 0;
+ }
+ }
+ cfg::writeByte(contact->hContact, "CList", "floating", state);
+ }
+ return 0;
+ }
+ case CLM_QUERYFLOATINGCONTACT:
+ {
+ return(cfg::getByte((HANDLE)wParam, "CList", "floating", 0));
+ }
+ case CLM_SETEXTRAIMAGELIST:
+ dat->himlExtraColumns = (HIMAGELIST) lParam;
+ InvalidateRect(hwnd, NULL, FALSE);
+ return 0;
+
+ case CLM_SETFONT:
+ if(HIWORD(lParam)<0 || HIWORD(lParam)>FONTID_LAST)
+ return 0;
+ dat->fontInfo[HIWORD(lParam)].hFont = (HFONT)wParam;
+ dat->fontInfo[HIWORD(lParam)].changed = 1;
+
+ RowHeight::getMaxRowHeight(dat, hwnd);
+
+ if(LOWORD(lParam))
+ InvalidateRect(hwnd,NULL,FALSE);
+ return 0;
+
+ case CLM_ISMULTISELECT:
+ return dat->isMultiSelect;
+ }
+
+ return saveProcessExternalMessages(hwnd, dat, msg, wParam, lParam);
+}
diff --git a/plugins/Clist_nicer/SRC/clcopts.cpp b/plugins/Clist_nicer/SRC/clcopts.cpp
new file mode 100644
index 0000000000..f942f833e4
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clcopts.cpp
@@ -0,0 +1,1719 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include <commonheaders.h>
+#include "../coolsb/coolscroll.h"
+
+#define DBFONTF_BOLD 1
+#define DBFONTF_ITALIC 2
+#define DBFONTF_UNDERLINE 4
+
+static INT_PTR CALLBACK DlgProcClcMainOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK DlgProcClcBkgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+//static INT_PTR CALLBACK DlgProcClcTextOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK DlgProcViewModesSetup(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK DlgProcFloatingContacts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK DlgProcSBarOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK DlgProcGenOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern void ReloadExtraIcons( void );
+
+extern HIMAGELIST himlExtraImages;
+
+struct CheckBoxToStyleEx_t {
+ int id;
+ DWORD flag;
+ int not_t;
+} static const checkBoxToStyleEx[] = {
+ {IDC_DISABLEDRAGDROP,CLS_EX_DISABLEDRAGDROP,0}, {IDC_NOTEDITLABELS,CLS_EX_EDITLABELS,1},
+ {IDC_SHOWSELALWAYS,CLS_EX_SHOWSELALWAYS,0}, {IDC_TRACKSELECT,CLS_EX_TRACKSELECT,0},
+ {IDC_DIVIDERONOFF,CLS_EX_DIVIDERONOFF,0}, {IDC_NOTNOTRANSLUCENTSEL,CLS_EX_NOTRANSLUCENTSEL,1},
+ {IDC_NOTNOSMOOTHSCROLLING,CLS_EX_NOSMOOTHSCROLLING,1}
+};
+
+struct CheckBoxToGroupStyleEx_t {
+ int id;
+ DWORD flag;
+ int not_t;
+} static const checkBoxToGroupStyleEx[] = {
+ {IDC_SHOWGROUPCOUNTS,CLS_EX_SHOWGROUPCOUNTS,0}, {IDC_HIDECOUNTSWHENEMPTY,CLS_EX_HIDECOUNTSWHENEMPTY,0},
+ {IDC_LINEWITHGROUPS,CLS_EX_LINEWITHGROUPS,0}, {IDC_QUICKSEARCHVISONLY,CLS_EX_QUICKSEARCHVISONLY,0},
+ {IDC_SORTGROUPSALPHA,CLS_EX_SORTGROUPSALPHA,0}
+};
+
+struct CheckBoxValues_t {
+ DWORD style;
+ TCHAR *szDescr;
+};
+
+static const struct CheckBoxValues_t greyoutValues[] = {
+ {GREYF_UNFOCUS,_T("Not focused")}, {MODEF_OFFLINE,_T("Offline")}, {PF2_ONLINE,_T("Online")}, {PF2_SHORTAWAY,_T("Away")}, {PF2_LONGAWAY,_T("NA")}, {PF2_LIGHTDND,_T("Occupied")}, {PF2_HEAVYDND,_T("DND")}, {PF2_FREECHAT,_T("Free for chat")}, {PF2_INVISIBLE,_T("Invisible")}, {PF2_OUTTOLUNCH,_T("Out to lunch")}, {PF2_ONTHEPHONE,_T("On the phone")}
+};
+static const struct CheckBoxValues_t offlineValues[] = {
+ {MODEF_OFFLINE,_T("Offline")}, {PF2_ONLINE,_T("Online")}, {PF2_SHORTAWAY,_T("Away")}, {PF2_LONGAWAY,_T("NA")}, {PF2_LIGHTDND,_T("Occupied")}, {PF2_HEAVYDND,_T("DND")}, {PF2_FREECHAT,_T("Free for chat")}, {PF2_INVISIBLE,_T("Invisible")}, {PF2_OUTTOLUNCH,_T("Out to lunch")}, {PF2_ONTHEPHONE,_T("On the phone")}
+};
+
+static HIMAGELIST himlCheckBoxes = 0;
+
+static void CreateStateImageList()
+{
+ HICON hIconNoTick = reinterpret_cast<HICON>(LoadImage(g_hInst, MAKEINTRESOURCE(IDI_NOTICK), IMAGE_ICON, 16, 16, 0));
+ HICON hIconTick = reinterpret_cast<HICON>(LoadImage(g_hInst, MAKEINTRESOURCE(IDI_TICK), IMAGE_ICON, 16, 16, 0));
+
+ himlCheckBoxes=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,2,2);
+ ImageList_AddIcon(himlCheckBoxes, hIconNoTick);
+ ImageList_AddIcon(himlCheckBoxes, hIconTick);
+ ImageList_AddIcon(himlCheckBoxes, hIconNoTick);
+
+ DestroyIcon(hIconTick);
+ DestroyIcon(hIconNoTick);
+}
+
+
+static UINT sortCtrlIDs[] = {IDC_SORTPRIMARY, IDC_SORTTHEN, IDC_SORTFINALLY, 0};
+
+static void FillCheckBoxTree(HWND hwndTree, const struct CheckBoxValues_t *values, int nValues, DWORD style)
+{
+ TVINSERTSTRUCT tvis;
+ int i;
+
+ tvis.hParent = NULL;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
+ for (i = 0; i < nValues; i++) {
+ tvis.item.lParam = values[i].style;
+ tvis.item.pszText = TranslateTS(values[i].szDescr);
+ tvis.item.stateMask = TVIS_STATEIMAGEMASK;
+ tvis.item.state = INDEXTOSTATEIMAGEMASK((style & tvis.item.lParam) != 0 ? 1 : 2);
+ TreeView_InsertItem(hwndTree, &tvis);
+ }
+}
+
+static DWORD MakeCheckBoxTreeFlags(HWND hwndTree)
+{
+ DWORD flags = 0;
+ TVITEM tvi;
+
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE;
+ tvi.hItem = TreeView_GetRoot(hwndTree);
+ while (tvi.hItem) {
+ TreeView_GetItem(hwndTree, &tvi);
+ if (((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 1))
+ flags |= tvi.lParam;
+ tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem);
+ }
+ return flags;
+}
+
+/*
+ * functions to enumerate display profiles
+ */
+
+/*
+int DSP_EnumProc(const char *szSetting, LPARAM lParam)
+{
+ pfnEnumCallback EnumCallback = (pfnEnumCallback)lParam;
+ if (szSetting != NULL)
+ EnumCallback((char *)szSetting);
+ return(0);
+}
+
+void DSP_EnumModes(pfnEnumCallback EnumCallback)
+{
+ static UINT uID_max;
+
+ DBCONTACTENUMSETTINGS dbces;
+
+ uID_max = 0;
+
+ dbces.pfnEnumProc = DSP_EnumProc;
+ dbces.szModule = DSP_PROFILES_MODULE;
+ dbces.ofsSettings = 0;
+ dbces.lParam = (LPARAM)EnumCallback;
+ CallService(MS_DB_CONTACT_ENUMSETTINGS,0,(LPARAM)&dbces);
+}
+
+ */
+/*
+ * write a display profile to the db
+ * p->uID must contain the (valid) identifier
+ */
+
+static void DSP_Write(DISPLAYPROFILESET *p)
+{
+ char szBuf[256], szKey[256];
+ int i = 0, j;
+ DWORD dwFlags = 0;
+ DISPLAYPROFILE *dp;
+
+ _snprintf(szKey, 256, "[%u]", p->uID);
+ cfg::writeTString(NULL, DSP_PROFILES_MODULE, szKey, p->tszName);
+
+ for(j = 0; j < 4; j++) {
+
+ dp = &p->dp[i];
+ i = 0;
+
+ /*
+ * dword values
+ */
+
+ _snprintf(szBuf, 256, "%u,%u,%d,%u,%u", dp->dwFlags, dp->dwExtraImageMask, dp->avatarBorder, dp->clcExStyle, dp->clcOfflineModes);
+ szBuf[255] = 0;
+ _snprintf(szKey, 256, "{dw_%u_%u}", p->uID, j);
+ cfg::writeString(NULL, DSP_PROFILES_MODULE, szKey, szBuf);
+
+ _snprintf(szKey, 256, "{b_%u_%u}", p->uID, j);
+
+ /*
+ * byte values
+ */
+
+ szBuf[i++] = (BYTE)dp->exIconScale;
+ szBuf[i++] = (BYTE)dp->dualRowMode;
+ szBuf[i++] = (BYTE)dp->avatarRadius;
+ szBuf[i++] = (BYTE)dp->avatarSize;
+ szBuf[i++] = (BYTE)dp->sortOrder[0];szBuf[i++] = (BYTE)dp->sortOrder[1];szBuf[i++] = (BYTE)dp->sortOrder[2];
+ szBuf[i++] = dp->bUseDCMirroring;
+ szBuf[i++] = dp->bGroupAlign;
+ szBuf[i++] = dp->avatarPadding;
+ szBuf[i++] = dp->bLeftMargin; szBuf[i++] = dp->bRightMargin; szBuf[i++] = dp->bRowSpacing;
+ szBuf[i++] = dp->bGroupIndent; szBuf[i++] = dp->bRowHeight; szBuf[i++] = dp->bGroupRowHeight;
+ szBuf[i++] = 0;
+
+ cfg::writeString(NULL, DSP_PROFILES_MODULE, szKey, szBuf);
+
+ /*
+ * bool values (convert to bitflags
+ */
+
+ _snprintf(szKey, 256, "{f_%u_%u}", p->uID, j);
+ dwFlags = ((dp->bCenterStatusIcons ? DSPF_CENTERSTATUSICON : 0) |
+ (dp->bDimIdle ? DSPF_DIMIDLE : 0) |
+ (dp->bNoOfflineAvatars ? DSPF_NOFFLINEAVATARS : 0) |
+ (dp->bShowLocalTime ? DSPF_SHOWLOCALTIME : 0) |
+ (dp->bShowLocalTimeSelective ? DSPF_LOCALTIMESELECTIVE : 0) |
+ (dp->bDontSeparateOffline ? DSPF_DONTSEPARATEOFFLINE : 0) |
+ (dp->bCenterGroupNames ? DSPF_CENTERGROUPNAMES : 0));
+
+ cfg::writeDword(NULL, DSP_PROFILES_MODULE, szKey, dwFlags);
+ }
+}
+
+
+/*
+ * read a profile from the DB
+ * p->uID must contain the (valid) identifier
+ */
+
+static int DSP_Read(DISPLAYPROFILESET *p)
+{
+ char szBuf[256], szKey[256];
+ int i = 0, j;
+ DWORD dwFlags = 0;
+ DBVARIANT dbv = {0};
+ DISPLAYPROFILE *dp;
+
+ _snprintf(szKey, 256, "[%u]", p->uID);
+
+ if(cfg::getTString(NULL, DSP_PROFILES_MODULE, szKey, &dbv))
+ return 0;
+
+ mir_sntprintf(p->tszName, 60, dbv.ptszVal);
+ DBFreeVariant(&dbv);
+
+ for(j = 0; j < 4; j++) {
+
+ dp = &p->dp[j];
+ i = 0;
+ /*
+ * dword values
+ */
+
+ mir_snprintf(szKey, 256, "{dw_%u_%u}", p->uID, j);
+ if(!cfg::getString(NULL, DSP_PROFILES_MODULE, szKey, &dbv)) {
+ sscanf(dbv.pszVal, "%u,%u,%u,%u,%u", dp->dwFlags, dp->dwExtraImageMask, dp->avatarBorder, dp->clcExStyle, dp->clcOfflineModes);
+ DBFreeVariant(&dbv);
+ }
+ else
+ return 0;
+
+ /*
+ * byte values
+ */
+
+ _snprintf(szKey, 256, "{b_%u_%u}", p->uID, j);
+ if(!cfg::getString(NULL, DSP_PROFILES_MODULE, szKey, &dbv)) {
+ if(lstrlenA(dbv.pszVal) >= 16) {
+ dp->exIconScale = (int)szBuf[i++];
+ dp->dualRowMode = szBuf[i++];
+ dp->avatarRadius = szBuf[i++];
+ dp->avatarSize = szBuf[i++];
+ dp->sortOrder[0] = szBuf[i++]; dp->sortOrder[1] = szBuf[i++]; dp->sortOrder[2] = szBuf[i++];
+ dp->bUseDCMirroring = szBuf[i++];
+ dp->bGroupAlign = szBuf[i++];
+ dp->avatarPadding = szBuf[i++];
+ dp->bLeftMargin = szBuf[i++]; dp->bRightMargin = szBuf[i++]; dp->bRowSpacing = szBuf[i++];
+ dp->bGroupIndent = szBuf[i++]; dp->bRowHeight = szBuf[i++]; dp->bGroupRowHeight = szBuf[i++];
+ }
+ else {
+ DBFreeVariant(&dbv);
+ return 0;
+ }
+ DBFreeVariant(&dbv);
+ }
+ else
+ return 0;
+
+ /*
+ * bool values (convert to bitflags
+ */
+
+ _snprintf(szKey, 256, "{f_%u_%u}", p->uID, j);
+ dwFlags = cfg::getDword(DSP_PROFILES_MODULE, szKey, 0);
+
+ dp->bCenterStatusIcons = dwFlags & DSPF_CENTERSTATUSICON ? 1 : 0;
+ dp->bDimIdle = dwFlags & DSPF_DIMIDLE ? 1 : 0;
+ dp->bNoOfflineAvatars = dwFlags & DSPF_NOFFLINEAVATARS ? 1 : 0;
+ dp->bShowLocalTime = dwFlags & DSPF_SHOWLOCALTIME ? 1 : 0;
+ dp->bShowLocalTimeSelective = dwFlags & DSPF_LOCALTIMESELECTIVE ? 1 : 0;
+ dp->bDontSeparateOffline = dwFlags & DSPF_DONTSEPARATEOFFLINE ? 1 : 0;
+ dp->bCenterGroupNames = dwFlags & DSPF_CENTERGROUPNAMES ? 1 : 0;
+ }
+
+ return 1;
+}
+
+/*
+ * load current values into the given profile
+ */
+
+static void DSP_LoadFromDefaults(DISPLAYPROFILE *p)
+{
+ p->dwExtraImageMask = cfg::dat.dwExtraImageMask;
+ p->exIconScale = cfg::dat.exIconScale;
+ p->bCenterStatusIcons = cfg::dat.bCenterStatusIcons;
+ p->dwFlags = cfg::dat.dwFlags;
+ p->bDimIdle = cfg::getByte("CLC", "ShowIdle", CLCDEFAULT_SHOWIDLE);
+ p->avatarBorder = cfg::dat.avatarBorder;
+ p->avatarSize = cfg::dat.avatarSize;
+ p->avatarRadius = cfg::dat.avatarRadius;
+ p->dualRowMode = cfg::dat.dualRowMode;
+ p->bNoOfflineAvatars = cfg::dat.bNoOfflineAvatars;
+ p->bShowLocalTime = cfg::dat.bShowLocalTime;
+ p->bShowLocalTimeSelective = cfg::dat.bShowLocalTimeSelective;
+ p->clcExStyle = cfg::getDword("CLC", "ExStyle", pcli->pfnGetDefaultExStyle());
+ p->clcOfflineModes = cfg::getDword("CLC", "OfflineModes", CLCDEFAULT_OFFLINEMODES);
+ p->bDontSeparateOffline = cfg::dat.bDontSeparateOffline;
+ p->sortOrder[0] = cfg::dat.sortOrder[0];
+ p->sortOrder[1] = cfg::dat.sortOrder[1];
+ p->sortOrder[2] = cfg::dat.sortOrder[2];
+ p->bUseDCMirroring = cfg::dat.bUseDCMirroring;
+ p->bCenterGroupNames = cfg::getByte("CLCExt", "EXBK_CenterGroupnames", 0);
+ p->bGroupAlign = cfg::dat.bGroupAlign;
+ p->avatarPadding = cfg::dat.avatarPadding;
+
+ p->bLeftMargin = cfg::getByte("CLC", "LeftMargin", CLCDEFAULT_LEFTMARGIN);
+ p->bRightMargin = cfg::getByte("CLC", "RightMargin", CLCDEFAULT_LEFTMARGIN);
+ p->bRowSpacing = cfg::dat.bRowSpacing;
+ p->bGroupIndent = cfg::getByte("CLC", "GroupIndent", CLCDEFAULT_GROUPINDENT);
+ p->bRowHeight = cfg::getByte("CLC", "RowHeight", CLCDEFAULT_ROWHEIGHT);
+ p->bGroupRowHeight = cfg::getByte("CLC", "GRowHeight", CLCDEFAULT_ROWHEIGHT);
+ CopyMemory(p->exIconOrder, cfg::dat.exIconOrder, EXICON_COUNT);
+}
+
+/*
+ * apply a display profile
+ */
+
+void DSP_Apply(DISPLAYPROFILE *p)
+{
+ int oldexIconScale = cfg::dat.exIconScale;
+ DWORD oldMask = cfg::dat.dwExtraImageMask;
+ int i;
+ DWORD exStyle;
+ char temp[EXICON_COUNT + 1];
+ /*
+ * icons page
+ */
+ cfg::dat.dwFlags &= ~(CLUI_FRAME_STATUSICONS | CLUI_SHOWVISI | CLUI_USEMETAICONS | CLUI_FRAME_USEXSTATUSASSTATUS | CLUI_FRAME_OVERLAYICONS | CLUI_FRAME_SELECTIVEICONS);
+ cfg::dat.dwExtraImageMask = p->dwExtraImageMask;
+ cfg::dat.exIconScale = p->exIconScale;
+ cfg::dat.bCenterStatusIcons = p->bCenterStatusIcons;
+
+ cfg::writeDword("CLUI", "ximgmask", cfg::dat.dwExtraImageMask);
+ cfg::writeByte("CLC", "ExIconScale", (BYTE)cfg::dat.exIconScale);
+ cfg::writeByte("CLC", "si_centered", (BYTE)cfg::dat.bCenterStatusIcons);
+ cfg::writeByte("CLC", "ShowIdle", (BYTE)p->bDimIdle);
+
+ CopyMemory(cfg::dat.exIconOrder, p->exIconOrder, EXICON_COUNT);
+ CopyMemory(temp, p->exIconOrder, EXICON_COUNT);
+ temp[EXICON_COUNT] = 0;
+ cfg::writeString(NULL, "CLUI", "exIconOrder", temp);
+
+ /*
+ * advanced (avatars & 2nd row)
+ */
+
+ cfg::dat.dwFlags &= ~(CLUI_FRAME_AVATARSLEFT | CLUI_FRAME_AVATARSRIGHT | CLUI_FRAME_AVATARSRIGHTWITHNICK |
+ CLUI_FRAME_AVATARS | CLUI_FRAME_AVATARBORDER | CLUI_FRAME_ROUNDAVATAR |
+ CLUI_FRAME_ALWAYSALIGNNICK | CLUI_FRAME_SHOWSTATUSMSG | CLUI_FRAME_GDIPLUS);
+
+ cfg::dat.avatarSize = p->avatarSize;
+ cfg::dat.avatarBorder = p->avatarBorder;
+ cfg::dat.avatarRadius = p->avatarRadius;
+ cfg::dat.dualRowMode = p->dualRowMode;
+ cfg::dat.bNoOfflineAvatars = p->bNoOfflineAvatars;
+ cfg::dat.bShowLocalTime = p->bShowLocalTime;
+ cfg::dat.bShowLocalTimeSelective = p->bShowLocalTimeSelective;
+
+ if(cfg::dat.hBrushAvatarBorder)
+ DeleteObject(cfg::dat.hBrushAvatarBorder);
+ cfg::dat.hBrushAvatarBorder = CreateSolidBrush(cfg::dat.avatarBorder);
+
+ /*
+ * items page
+ */
+
+ cfg::dat.dwFlags &= ~CLUI_STICKYEVENTS;
+
+ cfg::dat.sortOrder[0] = p->sortOrder[0];
+ cfg::dat.sortOrder[1] = p->sortOrder[1];
+ cfg::dat.sortOrder[2] = p->sortOrder[2];
+ cfg::dat.bDontSeparateOffline = p->bDontSeparateOffline;
+ cfg::writeByte("CList", "DontSeparateOffline", (BYTE)cfg::dat.bDontSeparateOffline);
+ cfg::writeDword("CLC", "OfflineModes", p->clcOfflineModes);
+
+ cfg::writeDword("CList", "SortOrder",
+ MAKELONG(MAKEWORD(cfg::dat.sortOrder[0], cfg::dat.sortOrder[1]),
+ MAKEWORD(cfg::dat.sortOrder[2], 0)));
+
+ cfg::dat.bUseDCMirroring = p->bUseDCMirroring;
+ cfg::writeByte("CLC", "MirrorDC", cfg::dat.bUseDCMirroring);
+
+ /*
+ * groups page
+ */
+
+ cfg::dat.dwFlags &= ~CLUI_FRAME_NOGROUPICON;
+ cfg::dat.bGroupAlign = p->bGroupAlign;
+ cfg::writeByte("CLC", "GroupAlign", cfg::dat.bGroupAlign);
+ cfg::writeByte("CLCExt", "EXBK_CenterGroupnames", (BYTE)p->bCenterGroupNames);
+
+ exStyle = cfg::getDword("CLC", "ExStyle", pcli->pfnGetDefaultExStyle());
+ for (i = 0; i < sizeof(checkBoxToGroupStyleEx) / sizeof(checkBoxToGroupStyleEx[0]); i++)
+ exStyle &= ~(checkBoxToGroupStyleEx[i].flag);
+
+ exStyle |= p->clcExStyle;
+ cfg::writeDword("CLC", "ExStyle", exStyle);
+ cfg::dat.avatarPadding = p->avatarPadding;
+ cfg::writeByte("CList", "AvatarPadding", cfg::dat.avatarPadding);
+
+ cfg::dat.bRowSpacing = p->bRowSpacing;
+ cfg::writeByte("CLC", "RowGap", cfg::dat.bRowSpacing);
+
+ cfg::writeByte("CLC", "LeftMargin", (BYTE)p->bLeftMargin);
+ cfg::writeByte("CLC", "RightMargin", (BYTE)p->bRightMargin);
+ cfg::writeByte("CLC", "GroupIndent", (BYTE)p->bGroupIndent);
+ cfg::writeByte("CLC", "RowHeight", (BYTE)p->bRowHeight);
+ cfg::writeByte("CLC", "GRowHeight", (BYTE)p->bGroupRowHeight);
+
+ if(cfg::dat.sortOrder[0] == SORTBY_LASTMSG || cfg::dat.sortOrder[1] == SORTBY_LASTMSG || cfg::dat.sortOrder[2] == SORTBY_LASTMSG) {
+ int i;
+
+ for(i = 0; i < cfg::nextCacheEntry; i++)
+ cfg::eCache[i].dwLastMsgTime = INTSORT_GetLastMsgTime(cfg::eCache[i].hContact);
+ }
+
+ cfg::writeByte("CLC", "ShowLocalTime", (BYTE)cfg::dat.bShowLocalTime);
+ cfg::writeByte("CLC", "SelectiveLocalTime", (BYTE)cfg::dat.bShowLocalTimeSelective);
+ cfg::writeDword("CLC", "avatarborder", cfg::dat.avatarBorder);
+ cfg::writeDword("CLC", "avatarradius", cfg::dat.avatarRadius);
+ cfg::writeWord(NULL, "CList", "AvatarSize", (WORD)cfg::dat.avatarSize);
+ cfg::writeByte("CLC", "DualRowMode", cfg::dat.dualRowMode);
+ cfg::writeByte("CList", "NoOfflineAV", (BYTE)cfg::dat.bNoOfflineAvatars);
+
+ KillTimer(pcli->hwndContactTree, TIMERID_REFRESH);
+ if(cfg::dat.bShowLocalTime)
+ SetTimer(pcli->hwndContactTree, TIMERID_REFRESH, 65000, NULL);
+
+ cfg::dat.dwFlags |= p->dwFlags;
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+
+ for(i = 0; i < cfg::nextCacheEntry; i++)
+ cfg::eCache[i].dwXMask = CalcXMask(cfg::eCache[i].hContact);
+
+ if(oldexIconScale != cfg::dat.exIconScale) {
+ ImageList_RemoveAll(himlExtraImages);
+ ImageList_SetIconSize(himlExtraImages, cfg::dat.exIconScale, cfg::dat.exIconScale);
+ if(cfg::dat.IcoLib_Avail)
+ IcoLibReloadIcons();
+ else {
+ CLN_LoadAllIcons(0);
+ pcli->pfnReloadProtoMenus();
+ //FYR: Not necessary. It is already notified in pfnReloadProtoMenus
+ //NotifyEventHooks(pcli->hPreBuildStatusMenuEvent, 0, 0);
+ ReloadExtraIcons();
+ }
+ }
+ pcli->pfnClcOptionsChanged();
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+}
+
+void GetDefaultFontSetting(int i, LOGFONT *lf, COLORREF *colour)
+{
+ SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), lf, FALSE);
+ *colour = GetSysColor(COLOR_WINDOWTEXT);
+ switch (i) {
+ case FONTID_GROUPS:
+ lf->lfWeight = FW_BOLD;
+ break;
+ case FONTID_GROUPCOUNTS:
+ lf->lfHeight = (int) (lf->lfHeight * .75);
+ *colour = GetSysColor(COLOR_3DSHADOW);
+ break;
+ case FONTID_OFFINVIS:
+ case FONTID_INVIS:
+ lf->lfItalic = !lf->lfItalic;
+ break;
+ case FONTID_DIVIDERS:
+ lf->lfHeight = (int) (lf->lfHeight * .75);
+ break;
+ case FONTID_NOTONLIST:
+ *colour = GetSysColor(COLOR_3DSHADOW);
+ break;
+} }
+
+static INT_PTR CALLBACK DlgProcDspGroups(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ int i = 0;
+ TranslateDialogDefault(hwndDlg);
+ SendDlgItemMessage(hwndDlg, IDC_GROUPALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always Left"));
+ SendDlgItemMessage(hwndDlg, IDC_GROUPALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always Right"));
+ SendDlgItemMessage(hwndDlg, IDC_GROUPALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Automatic (RTL)"));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_ROWHEIGHT || LOWORD(wParam) == IDC_AVATARPADDING || LOWORD(wParam) == IDC_ROWGAP || LOWORD(wParam) == IDC_RIGHTMARGIN || LOWORD(wParam) == IDC_LEFTMARGIN || LOWORD(wParam) == IDC_SMOOTHTIME || LOWORD(wParam) == IDC_GROUPINDENT || LOWORD(wParam) == IDC_GROUPROWHEIGHT)
+ && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_USER + 100:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ DWORD exStyle = p->clcExStyle;
+ int i;
+ for (i = 0; i < sizeof(checkBoxToGroupStyleEx) / sizeof(checkBoxToGroupStyleEx[0]); i++)
+ CheckDlgButton(hwndDlg, checkBoxToGroupStyleEx[i].id, (exStyle & checkBoxToGroupStyleEx[i].flag) ^ (checkBoxToGroupStyleEx[i].flag * checkBoxToGroupStyleEx[i].not_t) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_NOGROUPICON, (p->dwFlags & CLUI_FRAME_NOGROUPICON) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_CENTERGROUPNAMES, p->bCenterGroupNames);
+ SendDlgItemMessage(hwndDlg, IDC_GROUPALIGN, CB_SETCURSEL, p->bGroupAlign, 0);
+ SendDlgItemMessage(hwndDlg, IDC_AVATARPADDINGSPIN, UDM_SETRANGE, 0, MAKELONG(10, 0));
+ SendDlgItemMessage(hwndDlg, IDC_AVATARPADDINGSPIN, UDM_SETPOS, 0, p->avatarPadding);
+
+ SendDlgItemMessage(hwndDlg, IDC_LEFTMARGINSPIN, UDM_SETRANGE, 0, MAKELONG(64, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, p->bLeftMargin);
+ SendDlgItemMessage(hwndDlg, IDC_RIGHTMARGINSPIN, UDM_SETRANGE, 0, MAKELONG(64, 0));
+ SendDlgItemMessage(hwndDlg, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, p->bRightMargin);
+ SendDlgItemMessage(hwndDlg, IDC_ROWGAPSPIN, UDM_SETRANGE, 0, MAKELONG(10, 0));
+ SendDlgItemMessage(hwndDlg, IDC_ROWGAPSPIN, UDM_SETPOS, 0, p->bRowSpacing);
+ SendDlgItemMessage(hwndDlg, IDC_GROUPINDENTSPIN, UDM_SETRANGE, 0, MAKELONG(50, 0));
+ SendDlgItemMessage(hwndDlg, IDC_GROUPINDENTSPIN, UDM_SETPOS, 0, p->bGroupIndent);
+ SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_SETRANGE, 0, MAKELONG(255, 8));
+ SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_SETPOS, 0, p->bRowHeight);
+ SendDlgItemMessage(hwndDlg, IDC_GROUPROWHEIGHTSPIN, UDM_SETRANGE, 0, MAKELONG(255, 8));
+ SendDlgItemMessage(hwndDlg, IDC_GROUPROWHEIGHTSPIN, UDM_SETPOS, 0, p->bGroupRowHeight);
+ }
+ return 0;
+ }
+ case WM_USER + 200:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ int i;
+ DWORD exStyle = 0;
+ LRESULT curSel;
+ BOOL translated;
+
+ for (i = 0; i < sizeof(checkBoxToGroupStyleEx) / sizeof(checkBoxToGroupStyleEx[0]); i++) {
+ if ((IsDlgButtonChecked(hwndDlg, checkBoxToGroupStyleEx[i].id) == 0) == checkBoxToGroupStyleEx[i].not_t)
+ exStyle |= checkBoxToGroupStyleEx[i].flag;
+ }
+ p->clcExStyle = exStyle;
+ p->dwFlags |= (IsDlgButtonChecked(hwndDlg, IDC_NOGROUPICON) ? CLUI_FRAME_NOGROUPICON : 0);
+ p->bCenterGroupNames = IsDlgButtonChecked(hwndDlg, IDC_CENTERGROUPNAMES) ? 1 : 0;
+ curSel = SendDlgItemMessage(hwndDlg, IDC_GROUPALIGN, CB_GETCURSEL, 0, 0);
+ if(curSel != CB_ERR)
+ p->bGroupAlign = (BYTE)curSel;
+
+ p->avatarPadding = (BYTE)GetDlgItemInt(hwndDlg, IDC_AVATARPADDING, &translated, FALSE);
+ p->bLeftMargin = (BYTE)SendDlgItemMessage(hwndDlg, IDC_LEFTMARGINSPIN, UDM_GETPOS, 0, 0);
+ p->bRightMargin = (BYTE)SendDlgItemMessage(hwndDlg, IDC_RIGHTMARGINSPIN, UDM_GETPOS, 0, 0);
+ p->bRowSpacing = (BYTE)SendDlgItemMessage(hwndDlg, IDC_ROWGAPSPIN, UDM_GETPOS, 0, 0);
+ p->bGroupIndent = (BYTE)SendDlgItemMessage(hwndDlg, IDC_GROUPINDENTSPIN, UDM_GETPOS, 0, 0);
+ p->bRowHeight = (BYTE)SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_GETPOS, 0, 0);
+ p->bGroupRowHeight = (BYTE)SendDlgItemMessage(hwndDlg, IDC_GROUPROWHEIGHTSPIN, UDM_GETPOS, 0, 0);
+ }
+ return 0;
+ }
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK DlgProcDspItems(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ int i = 0;
+ HIMAGELIST himlOld;
+
+ TranslateDialogDefault(hwndDlg);
+ if(himlCheckBoxes == 0)
+ CreateStateImageList();
+
+ himlOld = TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS), himlCheckBoxes, TVSIL_STATE);
+ ImageList_Destroy(himlOld);
+
+ for(i = 0; sortCtrlIDs[i] != 0; i++) {
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_INSERTSTRING, -1, (LPARAM)TranslateT("Nothing"));
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_INSERTSTRING, -1, (LPARAM)TranslateT("Name"));
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_INSERTSTRING, -1, (LPARAM)TranslateT("Protocol"));
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_INSERTSTRING, -1, (LPARAM)TranslateT("Status"));
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_INSERTSTRING, -1, (LPARAM)TranslateT("Last Message"));
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_INSERTSTRING, -1, (LPARAM)TranslateT("Message Frequency"));
+ }
+ SendDlgItemMessage(hwndDlg, IDC_CLISTALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Never"));
+ SendDlgItemMessage(hwndDlg, IDC_CLISTALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always"));
+ SendDlgItemMessage(hwndDlg, IDC_CLISTALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("For RTL only"));
+ SendDlgItemMessage(hwndDlg, IDC_CLISTALIGN, CB_INSERTSTRING, -1, (LPARAM)TranslateT("RTL TEXT only"));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_USER + 100:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ int i;
+ FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS), offlineValues, sizeof(offlineValues) / sizeof(offlineValues[0]), p->clcOfflineModes);
+ CheckDlgButton(hwndDlg, IDC_EVENTSONTOP, (p->dwFlags & CLUI_STICKYEVENTS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DONTSEPARATE, p->bDontSeparateOffline);
+ for(i = 0; sortCtrlIDs[i] != 0; i++)
+ SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_SETCURSEL, p->sortOrder[i], 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_CLISTALIGN, CB_SETCURSEL, p->bUseDCMirroring, 0);
+ }
+ return 0;
+ }
+ case WM_USER + 200:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ int i;
+ LRESULT curSel;
+
+ for(i = 0; sortCtrlIDs[i] != 0; i++) {
+ curSel = SendDlgItemMessage(hwndDlg, sortCtrlIDs[i], CB_GETCURSEL, 0, 0);
+ if(curSel == 0 || curSel == CB_ERR)
+ p->sortOrder[i] = 0;
+ else
+ p->sortOrder[i] = (BYTE)curSel;
+ }
+ p->bDontSeparateOffline = IsDlgButtonChecked(hwndDlg, IDC_DONTSEPARATE) ? 1 : 0;
+ p->dwFlags |= IsDlgButtonChecked(hwndDlg, IDC_EVENTSONTOP) ? CLUI_STICKYEVENTS : 0;
+ p->clcOfflineModes = MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS));
+ p->bUseDCMirroring = (BYTE)SendDlgItemMessage(hwndDlg, IDC_CLISTALIGN, CB_GETCURSEL, 0, 0);
+ }
+ return 0;
+ }
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case IDC_HIDEOFFLINEOPTS:
+ if (((LPNMHDR) lParam)->code == NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x = (short) LOWORD(GetMessagePos());
+ hti.pt.y = (short) HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR) lParam)->hwndFrom, &hti.pt);
+ if (TreeView_HitTest(((LPNMHDR) lParam)->hwndFrom, &hti))
+ if (hti.flags & TVHT_ONITEMSTATEICON) {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvi.hItem = hti.hItem;
+ TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1;
+ TreeView_SetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_DESTROY: {
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static UINT avatar_controls[] = { IDC_ALIGNMENT, IDC_AVATARSBORDER, IDC_AVATARSROUNDED, IDC_AVATARBORDERCLR, IDC_ALWAYSALIGNNICK, IDC_AVATARHEIGHT, IDC_AVATARSIZESPIN, 0 };
+static INT_PTR CALLBACK DlgProcDspAdvanced(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ int i = 0;
+
+ TranslateDialogDefault(hwndDlg);
+ SendDlgItemMessage(hwndDlg, IDC_DUALROWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Never"));
+ SendDlgItemMessage(hwndDlg, IDC_DUALROWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always"));
+ SendDlgItemMessage(hwndDlg, IDC_DUALROWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When space allows it"));
+ SendDlgItemMessage(hwndDlg, IDC_DUALROWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When needed"));
+
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("With Nickname - left"));
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Far left"));
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Far right"));
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("With Nickname - right"));
+
+ if(cfg::dat.bAvatarServiceAvail) {
+ Utils::enableDlgControl(hwndDlg, IDC_CLISTAVATARS, TRUE);
+ while(avatar_controls[i] != 0)
+ Utils::enableDlgControl(hwndDlg, avatar_controls[i++], TRUE);
+ }
+ else {
+ Utils::enableDlgControl(hwndDlg, IDC_CLISTAVATARS, FALSE);
+ while(avatar_controls[i] != 0)
+ Utils::enableDlgControl(hwndDlg, avatar_controls[i++], FALSE);
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_CLISTAVATARS:
+ if((HWND)lParam != GetFocus())
+ return 0;
+ break;
+ case IDC_SHOWLOCALTIME:
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWLOCALTIMEONLYWHENDIFFERENT, IsDlgButtonChecked(hwndDlg, IDC_SHOWLOCALTIME));
+ break;
+ case IDC_AVATARSROUNDED:
+ Utils::enableDlgControl(hwndDlg, IDC_RADIUS, IsDlgButtonChecked(hwndDlg, IDC_AVATARSROUNDED) ? TRUE : FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_RADIUSSPIN, IsDlgButtonChecked(hwndDlg, IDC_AVATARSROUNDED) ? TRUE : FALSE);
+ break;
+ case IDC_AVATARSBORDER:
+ Utils::enableDlgControl(hwndDlg, IDC_AVATARBORDERCLR, IsDlgButtonChecked(hwndDlg, IDC_AVATARSBORDER) ? TRUE : FALSE);
+ break;
+ }
+ if ((LOWORD(wParam) == IDC_RADIUS || LOWORD(wParam) == IDC_AVATARHEIGHT) && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_USER + 100:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ CheckDlgButton(hwndDlg, IDC_NOAVATARSOFFLINE, p->bNoOfflineAvatars);
+ SendDlgItemMessage(hwndDlg, IDC_DUALROWMODE, CB_SETCURSEL, (WPARAM)p->dualRowMode, 0);
+ CheckDlgButton(hwndDlg, IDC_CLISTAVATARS, (p->dwFlags & CLUI_FRAME_AVATARS) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_AVATARSBORDER, (p->dwFlags & CLUI_FRAME_AVATARBORDER) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AVATARSROUNDED, (p->dwFlags & CLUI_FRAME_ROUNDAVATAR) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ALWAYSALIGNNICK, (p->dwFlags & CLUI_FRAME_ALWAYSALIGNNICK) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUSMSG, (p->dwFlags & CLUI_FRAME_SHOWSTATUSMSG) ? BST_CHECKED : BST_UNCHECKED);
+
+ SendDlgItemMessage(hwndDlg, IDC_AVATARBORDERCLR, CPM_SETCOLOUR, 0, p->avatarBorder);
+
+ SendDlgItemMessage(hwndDlg, IDC_RADIUSSPIN, UDM_SETRANGE, 0, MAKELONG(10, 2));
+ SendDlgItemMessage(hwndDlg, IDC_RADIUSSPIN, UDM_SETPOS, 0, p->avatarRadius);
+
+ SendDlgItemMessage(hwndDlg, IDC_AVATARSIZESPIN, UDM_SETRANGE, 0, MAKELONG(100, 16));
+ SendDlgItemMessage(hwndDlg, IDC_AVATARSIZESPIN, UDM_SETPOS, 0, p->avatarSize);
+
+ Utils::enableDlgControl(hwndDlg, IDC_RADIUS, IsDlgButtonChecked(hwndDlg, IDC_AVATARSROUNDED) ? TRUE : FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_RADIUSSPIN, IsDlgButtonChecked(hwndDlg, IDC_AVATARSROUNDED) ? TRUE : FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_AVATARBORDERCLR, IsDlgButtonChecked(hwndDlg, IDC_AVATARSBORDER) ? TRUE : FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_SHOWLOCALTIME, p->bShowLocalTime ? 1 : 0);
+ CheckDlgButton(hwndDlg, IDC_SHOWLOCALTIMEONLYWHENDIFFERENT, p->bShowLocalTimeSelective ? 1 : 0);
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWLOCALTIMEONLYWHENDIFFERENT, IsDlgButtonChecked(hwndDlg, IDC_SHOWLOCALTIME));
+
+ if(p->dwFlags & CLUI_FRAME_AVATARSLEFT)
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_SETCURSEL, 1, 0);
+ else if(p->dwFlags & CLUI_FRAME_AVATARSRIGHT)
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_SETCURSEL, 2, 0);
+ else if(p->dwFlags & CLUI_FRAME_AVATARSRIGHTWITHNICK)
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_SETCURSEL, 3, 0);
+ else
+ SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_SETCURSEL, 0, 0);
+ }
+ return 0;
+ }
+ case WM_USER + 200:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ LRESULT sel = SendDlgItemMessage(hwndDlg, IDC_ALIGNMENT, CB_GETCURSEL, 0, 0);
+ BOOL translated;
+
+ if(sel != CB_ERR) {
+ if(sel == 1)
+ p->dwFlags |= CLUI_FRAME_AVATARSLEFT;
+ else if(sel == 2)
+ p->dwFlags |= CLUI_FRAME_AVATARSRIGHT;
+ else if(sel == 3)
+ p->dwFlags |= CLUI_FRAME_AVATARSRIGHTWITHNICK;
+ }
+
+ p->dwFlags |= ((IsDlgButtonChecked(hwndDlg, IDC_CLISTAVATARS) ? CLUI_FRAME_AVATARS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_AVATARSBORDER) ? CLUI_FRAME_AVATARBORDER : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_AVATARSROUNDED) ? CLUI_FRAME_ROUNDAVATAR : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_ALWAYSALIGNNICK) ? CLUI_FRAME_ALWAYSALIGNNICK : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUSMSG) ? CLUI_FRAME_SHOWSTATUSMSG : 0));
+
+ p->avatarBorder = SendDlgItemMessage(hwndDlg, IDC_AVATARBORDERCLR, CPM_GETCOLOUR, 0, 0);
+ p->avatarRadius = GetDlgItemInt(hwndDlg, IDC_RADIUS, &translated, FALSE);
+ p->avatarSize = GetDlgItemInt(hwndDlg, IDC_AVATARHEIGHT, &translated, FALSE);
+ p->bNoOfflineAvatars = IsDlgButtonChecked(hwndDlg, IDC_NOAVATARSOFFLINE) ? TRUE : FALSE;
+ p->bShowLocalTime = IsDlgButtonChecked(hwndDlg, IDC_SHOWLOCALTIME) ? 1 : 0;
+ p->bShowLocalTimeSelective = IsDlgButtonChecked(hwndDlg, IDC_SHOWLOCALTIMEONLYWHENDIFFERENT) ? 1 : 0;
+
+ p->dualRowMode = (BYTE)SendDlgItemMessage(hwndDlg, IDC_DUALROWMODE, CB_GETCURSEL, 0, 0);
+ if(p->dualRowMode == CB_ERR)
+ p->dualRowMode = 0;
+ }
+ return 0;
+ }
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+ORDERTREEDATA OrderTreeData[]=
+{
+ {EXTRA_ICON_RES0, _T("Reserved, unused"), 9, TRUE, 0},
+ {EXTRA_ICON_EMAIL, _T("E-mail"), 0, TRUE, 0},
+ {EXTRA_ICON_RES1, _T("Reserved #1"), 7, TRUE, 0},
+ {EXTRA_ICON_SMS, _T("Telephone"), 2, TRUE, 0},
+ {EXTRA_ICON_ADV1, _T("Advanced #1 (ICQ X-Status)"), 3, TRUE, 0},
+ {EXTRA_ICON_ADV2, _T("Advanced #2"), 4, TRUE, 0},
+ {EXTRA_ICON_WEB, _T("Homepage"), 1, TRUE, 0},
+ {EXTRA_ICON_CLIENT, _T("Client (fingerprint required)"), 10, TRUE, 0},
+ {EXTRA_ICON_RES2, _T("Reserved #2"), 8, TRUE, 0},
+ {EXTRA_ICON_ADV3, _T("Advanced #3"), 5, TRUE, 0},
+ {EXTRA_ICON_ADV4, _T("Advanced #4"), 6, TRUE, 0},
+};
+
+static int dragging=0;
+static HTREEITEM hDragItem=NULL;
+
+static int FillOrderTree(HWND hwndDlg, HWND hwndTree, BYTE *exIconOrder, unsigned dwExtraImageMask)
+{
+ int i = 0;
+ TVINSERTSTRUCT tvis = {0};
+ TreeView_DeleteAllItems(hwndTree);
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+
+ for (i = 0; i < EXICON_COUNT; i++) {
+ int iIndex = (int)(exIconOrder[i] - 1);
+ tvis.item.lParam=(LPARAM)(&(OrderTreeData[iIndex]));
+ tvis.item.pszText = TranslateTS(OrderTreeData[iIndex].Name);
+ OrderTreeData[iIndex].Visible = (dwExtraImageMask & (1 << OrderTreeData[iIndex].ID)) != 0;
+ tvis.item.iImage = tvis.item.iSelectedImage = OrderTreeData[iIndex].Visible;
+ TreeView_InsertItem(hwndTree, &tvis);
+ }
+ /*
+ {
+ TVSORTCB sort={0};
+ sort.hParent=NULL;
+ sort.lParam=0;
+ sort.lpfnCompare=CompareFunc;
+ TreeView_SortChildrenCB(Tree,&sort,0);
+ }
+ */
+ return 0;
+}
+
+static int SaveOrderTree(HWND hwndDlg, HWND hwndTree, DISPLAYPROFILE *p)
+{
+ HTREEITEM ht;
+ TVITEM tvi = {0};
+ int iIndex = 0;
+
+ tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
+ ht = TreeView_GetRoot(hwndTree);
+
+ p->dwExtraImageMask = 0;
+
+ do {
+ ORDERTREEDATA *it = NULL;
+ tvi.hItem = ht;
+ TreeView_GetItem(hwndTree, &tvi);
+ it = (ORDERTREEDATA *)(tvi.lParam);
+
+ p->exIconOrder[iIndex] = it->ID + 1;
+ p->dwExtraImageMask |= (it->Visible ? (1 << it->ID) : 0);
+ ht = TreeView_GetNextSibling(hwndTree, ht);
+ iIndex++;
+ } while (ht);
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcXIcons(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_EXTRAORDER), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg,IDC_EXTRAORDER),GWL_STYLE)|TVS_NOHSCROLL);
+ {
+ if(himlCheckBoxes == 0) {
+ CreateStateImageList();
+ }
+ TreeView_SetImageList(GetDlgItem(hwndDlg,IDC_EXTRAORDER), himlCheckBoxes, TVSIL_NORMAL);
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_EXICONSCALE) && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+
+ if(IDC_RESETXICONS == LOWORD(wParam))
+ {
+ BYTE exIconOrder[EXICON_COUNT];
+ for(int i = 0; i < EXICON_COUNT; i++)
+ {
+ OrderTreeData[i].Visible = TRUE;
+ exIconOrder[i] = i + 1;
+ }
+ FillOrderTree(hwndDlg, GetDlgItem(hwndDlg, IDC_EXTRAORDER), exIconOrder, 0xffffffff);
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case WM_USER + 100:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ CheckDlgButton(hwndDlg, IDC_XSTATUSASSTATUS, p->dwFlags & CLUI_FRAME_USEXSTATUSASSTATUS ? 1 : 0);
+
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUSICONS, (p->dwFlags & CLUI_FRAME_STATUSICONS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWVISIBILITY, (p->dwFlags & CLUI_SHOWVISI) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWMETA, (p->dwFlags & CLUI_USEMETAICONS) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_OVERLAYICONS, (p->dwFlags & CLUI_FRAME_OVERLAYICONS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SELECTIVEICONS, (p->dwFlags & CLUI_FRAME_SELECTIVEICONS) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_STATUSICONSCENTERED, p->bCenterStatusIcons ? 1 : 0);
+ CheckDlgButton(hwndDlg, IDC_IDLE, p->bDimIdle ? BST_CHECKED : BST_UNCHECKED);
+
+ SendDlgItemMessage(hwndDlg, IDC_EXICONSCALESPIN, UDM_SETRANGE, 0, MAKELONG(20, 8));
+ SendDlgItemMessage(hwndDlg, IDC_EXICONSCALESPIN, UDM_SETPOS, 0, (LPARAM)p->exIconScale);
+ FillOrderTree(hwndDlg, GetDlgItem(hwndDlg, IDC_EXTRAORDER), p->exIconOrder, p->dwExtraImageMask);
+ }
+ return 0;
+ }
+ case WM_USER + 200:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ if(p) {
+ SaveOrderTree(hwndDlg, GetDlgItem(hwndDlg, IDC_EXTRAORDER), p);
+
+ p->exIconScale = SendDlgItemMessage(hwndDlg, IDC_EXICONSCALESPIN, UDM_GETPOS, 0, 0);
+ p->exIconScale = (p->exIconScale < 8 || p->exIconScale > 20) ? 16 : p->exIconScale;
+
+ p->dwFlags |= ((IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUSICONS) ? CLUI_FRAME_STATUSICONS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SHOWVISIBILITY) ? CLUI_SHOWVISI : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SHOWMETA) ? CLUI_USEMETAICONS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_OVERLAYICONS) ? CLUI_FRAME_OVERLAYICONS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_XSTATUSASSTATUS) ? CLUI_FRAME_USEXSTATUSASSTATUS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SELECTIVEICONS) ? CLUI_FRAME_SELECTIVEICONS : 0));
+
+ p->bDimIdle = IsDlgButtonChecked(hwndDlg, IDC_IDLE) ? 1 : 0;
+ p->bCenterStatusIcons = IsDlgButtonChecked(hwndDlg, IDC_STATUSICONSCENTERED) ? 1 : 0;
+ }
+ return 0;
+ }
+ case WM_NOTIFY:
+ if(((LPNMHDR) lParam)->idFrom == IDC_EXTRAORDER) {
+ switch (((LPNMHDR)lParam)->code) {
+ case TVN_BEGINDRAGA:
+ case TVN_BEGINDRAGW:
+ SetCapture(hwndDlg);
+ dragging=1;
+ hDragItem=((LPNMTREEVIEWA)lParam)->itemNew.hItem;
+ TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_EXTRAORDER),hDragItem);
+ break;
+ case NM_CLICK:
+ {
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt);
+ if(TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti))
+ if(hti.flags&TVHT_ONITEMICON)
+ {
+ TVITEMA tvi;
+ tvi.mask=TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvi.hItem=hti.hItem;
+ TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi);
+ tvi.iImage=tvi.iSelectedImage=!tvi.iImage;
+ ((ORDERTREEDATA *)tvi.lParam)->Visible=tvi.iImage;
+ TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi);
+ SendMessage((GetParent(hwndDlg)), PSM_CHANGED, (WPARAM)hwndDlg, 0);
+ }
+
+ }
+ }
+ break;
+ }
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ return TRUE;
+ }
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ {
+ if(!dragging)
+ break;
+ {
+ TVHITTESTINFO hti;
+ hti.pt.x = (short)LOWORD(lParam);
+ hti.pt.y = (short)HIWORD(lParam);
+ ClientToScreen(hwndDlg, &hti.pt);
+ ScreenToClient(GetDlgItem(hwndDlg, IDC_EXTRAORDER), &hti.pt);
+ TreeView_HitTest(GetDlgItem(hwndDlg,IDC_EXTRAORDER), &hti);
+ if(hti.flags&(TVHT_ONITEM|TVHT_ONITEMRIGHT)) {
+ HTREEITEM it = hti.hItem;
+ hti.pt.y -= TreeView_GetItemHeight(GetDlgItem(hwndDlg, IDC_EXTRAORDER)) / 2;
+ TreeView_HitTest(GetDlgItem(hwndDlg, IDC_EXTRAORDER), &hti);
+ //TreeView_SetInsertMark(GetDlgItem(hwndDlg,IDC_EXTRAORDER),hti.hItem,1);
+ if (!(hti.flags & TVHT_ABOVE))
+ TreeView_SetInsertMark(GetDlgItem(hwndDlg, IDC_EXTRAORDER), hti.hItem, 1);
+ else
+ TreeView_SetInsertMark(GetDlgItem(hwndDlg, IDC_EXTRAORDER), it, 0);
+ }
+ else {
+ if(hti.flags & TVHT_ABOVE) SendDlgItemMessage(hwndDlg,IDC_EXTRAORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
+ if(hti.flags & TVHT_BELOW) SendDlgItemMessage(hwndDlg, IDC_EXTRAORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
+ TreeView_SetInsertMark(GetDlgItem(hwndDlg, IDC_EXTRAORDER), NULL, 0);
+ }
+ }
+ }
+ break;
+ case WM_LBUTTONUP:
+ {
+ if(!dragging) break;
+ TreeView_SetInsertMark(GetDlgItem(hwndDlg,IDC_EXTRAORDER),NULL,0);
+ dragging=0;
+ ReleaseCapture();
+ {
+ TVHITTESTINFO hti;
+ TVITEM tvi;
+ hti.pt.x=(short)LOWORD(lParam);
+ hti.pt.y=(short)HIWORD(lParam);
+ ClientToScreen(hwndDlg,&hti.pt);
+ ScreenToClient(GetDlgItem(hwndDlg,IDC_EXTRAORDER),&hti.pt);
+ hti.pt.y-=TreeView_GetItemHeight(GetDlgItem(hwndDlg,IDC_EXTRAORDER))/2;
+ TreeView_HitTest(GetDlgItem(hwndDlg,IDC_EXTRAORDER),&hti);
+ if(hDragItem==hti.hItem) break;
+ if (hti.flags&TVHT_ABOVE) hti.hItem=TVI_FIRST;
+ tvi.mask=TVIF_HANDLE|TVIF_PARAM;
+ tvi.hItem=hDragItem;
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_EXTRAORDER),&tvi);
+ if(hti.flags&(TVHT_ONITEM|TVHT_ONITEMRIGHT)||(hti.hItem==TVI_FIRST))
+ {
+ TVINSERTSTRUCT tvis;
+ TCHAR name[128];
+ tvis.item.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
+ tvis.item.stateMask=0xFFFFFFFF;
+ tvis.item.pszText=name;
+ tvis.item.cchTextMax=sizeof(name);
+ tvis.item.hItem=hDragItem;
+ tvis.item.iImage=tvis.item.iSelectedImage=((ORDERTREEDATA *)tvi.lParam)->Visible;
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_EXTRAORDER),&tvis.item);
+ TreeView_DeleteItem(GetDlgItem(hwndDlg,IDC_EXTRAORDER),hDragItem);
+ tvis.hParent=NULL;
+ tvis.hInsertAfter=hti.hItem;
+ TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_EXTRAORDER),TreeView_InsertItem(GetDlgItem(hwndDlg,IDC_EXTRAORDER),&tvis));
+ SendMessage((GetParent(hwndDlg)), PSM_CHANGED, (WPARAM)hwndDlg, 0);
+ }
+ }
+ }
+ case WM_DESTROY: {
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static HWND hwndList;
+static DISPLAYPROFILE dsp_current;
+
+static INT_PTR CALLBACK DlgProcDspProfiles(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int iInit = TRUE;
+ static HWND hwndTab;
+ static int iTabCount;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEM tci;
+ RECT rcClient;
+ int oPage = cfg::getByte("CLUI", "opage_d", 0);
+ HWND hwndAdd;
+ DISPLAYPROFILE dsp_default;
+
+ TranslateDialogDefault(hwnd);
+ hwndList = GetDlgItem(hwnd, IDC_PROFILELIST);
+
+ hwndAdd = GetDlgItem(hwnd, IDC_DSP_ADD);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1);
+ SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ADDCONTACT), IMAGE_ICON, 16, 16, LR_SHARED));
+ SetWindowText(hwndAdd, TranslateT("Add New..."));
+
+ hwndAdd = GetDlgItem(hwnd, IDC_DSP_DELETE);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1);
+ SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_DELETE), IMAGE_ICON, 16, 16, LR_SHARED));
+ SetWindowText(hwndAdd, TranslateT("Delete"));
+
+ hwndAdd = GetDlgItem(hwnd, IDC_DSP_RENAME);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1);
+ SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_RENAME), IMAGE_ICON, 16, 16, LR_SHARED));
+ SetWindowText(hwndAdd, TranslateT("Rename..."));
+
+ hwndAdd = GetDlgItem(hwnd, IDC_DSP_APPLY);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1);
+ SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_OPTIONS), IMAGE_ICON, 16, 16, LR_SHARED));
+ SetWindowText(hwndAdd, TranslateT("Apply this profile"));
+
+ GetClientRect(hwnd, &rcClient);
+ hwndTab = GetDlgItem(hwnd, IDC_OPTIONSTAB);
+ iInit = TRUE;
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_DSPITEMS), hwnd, DlgProcDspItems);
+ tci.pszText = TranslateT("Contacts");
+ TabCtrl_InsertItem(hwndTab, 0, &tci);
+ MoveWindow((HWND)tci.lParam,64,25,rcClient.right-128,rcClient.bottom-67,1);
+ ShowWindow((HWND)tci.lParam, oPage == 0 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_DSPGROUPS), hwnd, DlgProcDspGroups);
+ tci.pszText = TranslateT("Groups and layout");
+ TabCtrl_InsertItem(hwndTab, 1, &tci);
+ MoveWindow((HWND)tci.lParam,64,25,rcClient.right-128,rcClient.bottom-67,1);
+ ShowWindow((HWND)tci.lParam, oPage == 1 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_XICONS), hwnd, DlgProcXIcons);
+ tci.pszText = TranslateT("Icons");
+ TabCtrl_InsertItem(hwndTab, 2, &tci);
+ MoveWindow((HWND)tci.lParam,64,25,rcClient.right-128,rcClient.bottom-67,1);
+ ShowWindow((HWND)tci.lParam, oPage == 2 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_DSPADVANCED), hwnd, DlgProcDspAdvanced);
+ tci.pszText = TranslateT("Advanced");
+ TabCtrl_InsertItem(hwndTab, 3, &tci);
+ MoveWindow((HWND)tci.lParam,64,25,rcClient.right-128,rcClient.bottom-67,1);
+ ShowWindow((HWND)tci.lParam, oPage == 3 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ TabCtrl_SetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB), oPage);
+
+ DSP_LoadFromDefaults(&dsp_default);
+ CopyMemory(&dsp_current, &dsp_default, sizeof(DISPLAYPROFILE));
+
+ iTabCount = TabCtrl_GetItemCount(hwndTab);
+
+ SendMessage(hwnd, WM_USER + 100, 0, (LPARAM)&dsp_default);
+ SendMessage(hwndList, LB_INSERTSTRING, 0, (LPARAM)TranslateT("<current>"));
+
+ hwndList = GetDlgItem(hwnd, IDC_CLASSLIST);
+ SendMessage(hwndList, LB_INSERTSTRING, 0, (LPARAM)TranslateT("Default"));
+ SendMessage(hwndList, LB_INSERTSTRING, 1, (LPARAM)TranslateT("Offline contact"));
+ SendMessage(hwndList, LB_INSERTSTRING, 2, (LPARAM)TranslateT("Selected contact"));
+ SendMessage(hwndList, LB_INSERTSTRING, 3, (LPARAM)TranslateT("Hottracked contact"));
+
+ iInit = FALSE;
+ return FALSE;
+ }
+
+ /*
+ * distribute a WM_USER message to all child windows so they can update their pages from the
+ * display profile structure
+ * LPARAM = DISPLAYPROFILE *
+ */
+
+ case WM_USER + 100:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+
+ if(p) {
+ int i;
+ TCITEM item = {0};
+ item.mask = TCIF_PARAM;
+
+ for(i = 0; i < iTabCount; i++) {
+ TabCtrl_GetItem(hwndTab, i, &item);
+ if(item.lParam && IsWindow((HWND)item.lParam))
+ SendMessage((HWND)item.lParam, WM_USER + 100, 0, (LPARAM)p);
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * collect the settings from the pages into a DISPLAYPROFILE struct
+ */
+ case WM_USER + 200:
+ {
+ DISPLAYPROFILE *p = (DISPLAYPROFILE *)lParam;
+ int i;
+ TCITEM item = {0};
+ item.mask = TCIF_PARAM;
+
+ for(i = 0; i < iTabCount; i++) {
+ TabCtrl_GetItem(hwndTab, i, &item);
+ if(item.lParam && IsWindow((HWND)item.lParam))
+ SendMessage((HWND)item.lParam, WM_USER + 200, 0, (LPARAM)p);
+ }
+ return 0;
+ }
+
+ case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0);
+ if(!iInit)
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ DISPLAYPROFILE p;
+
+ ZeroMemory(&p, sizeof(DISPLAYPROFILE));
+ SendMessage(hwnd, WM_USER + 200, 0, (LPARAM)&p);
+ DSP_Apply(&p);
+ }
+ break;
+ }
+ break;
+ case IDC_OPTIONSTAB:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGING:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_HIDE);
+ }
+ break;
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_SHOW);
+ cfg::writeByte("CLUI", "opage_d", (BYTE)TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)));
+ }
+ break;
+ }
+ break;
+
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK TabOptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int iInit = TRUE;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEM tci;
+ RECT rcClient;
+ int oPage = cfg::getByte("CLUI", "opage_m", 0);
+
+ GetClientRect(hwnd, &rcClient);
+ iInit = TRUE;
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_CLIST), hwnd, DlgProcGenOpts);
+ tci.pszText = TranslateT("General");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci);
+ MoveWindow((HWND)tci.lParam,5,25,rcClient.right-9,rcClient.bottom-30,1);
+ ShowWindow((HWND)tci.lParam, oPage == 0 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_CLC), hwnd, DlgProcClcMainOpts);
+ tci.pszText = TranslateT("List layout");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 1, &tci);
+ MoveWindow((HWND)tci.lParam,5,25,rcClient.right-9,rcClient.bottom-30,1);
+ ShowWindow((HWND)tci.lParam, oPage == 1 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_CLUI), hwnd, DlgProcCluiOpts);
+ tci.pszText = TranslateT("Window");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 2, &tci);
+ MoveWindow((HWND)tci.lParam,5,25,rcClient.right-9,rcClient.bottom-30,1);
+ ShowWindow((HWND)tci.lParam, oPage == 2 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_CLCBKG), hwnd, DlgProcClcBkgOpts);
+ tci.pszText = TranslateT("Background");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 3, &tci);
+ MoveWindow((HWND)tci.lParam,5,25,rcClient.right-9,rcClient.bottom-30,1);
+ ShowWindow((HWND)tci.lParam, oPage == 3 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SBAR), hwnd, DlgProcSBarOpts);
+ tci.pszText = TranslateT("Status Bar");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 4, &tci);
+ MoveWindow((HWND)tci.lParam,5,25,rcClient.right-9,rcClient.bottom-30,1);
+ ShowWindow((HWND)tci.lParam, oPage == 4 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ TabCtrl_SetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB), oPage);
+ iInit = FALSE;
+ return FALSE;
+ }
+
+ case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0);
+ if(!iInit)
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ TCITEM tci;
+ int i,count;
+ tci.mask = TCIF_PARAM;
+ count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB));
+ for (i=0;i<count;i++)
+ {
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),i,&tci);
+ SendMessage((HWND)tci.lParam,WM_NOTIFY,0,lParam);
+ }
+ }
+ break;
+ }
+ break;
+ case IDC_OPTIONSTAB:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGING:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_HIDE);
+ }
+ break;
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_SHOW);
+ cfg::writeByte("CLUI", "opage_m", (BYTE)TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)));
+ }
+ break;
+ }
+ break;
+
+ }
+ break;
+ }
+ return FALSE;
+}
+
+int ClcOptInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = 0;
+ odp.hInstance = g_hInst;
+ odp.pszGroup = LPGEN("Contact List");
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_DSPPROFILES);
+ odp.pszTitle = LPGEN("Contact rows");
+ odp.pfnDlgProc = DlgProcDspProfiles;
+ odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FLOATING);
+ odp.pszTitle = LPGEN("Floating contacts");
+ odp.pfnDlgProc = DlgProcFloatingContacts;
+ odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT);
+ odp.pszGroup = LPGEN("Skins");
+ odp.pszTitle = LPGEN("Contact list");
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = OptionsDlgProc;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ odp.position = -1000000000;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONSDIALOG);
+ odp.pszGroup = NULL;
+ odp.pszTitle = LPGEN("Contact List");
+ odp.pfnDlgProc = TabOptionsDlgProc;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.nIDBottomSimpleControl = 0;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+ return 0;
+}
+
+static int opt_clc_main_changed = 0;
+
+static INT_PTR CALLBACK DlgProcClcMainOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ opt_clc_main_changed = 0;
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES);
+
+ {
+ int i;
+ DWORD exStyle = cfg::getDword("CLC", "ExStyle", pcli->pfnGetDefaultExStyle());
+ UDACCEL accel[2] = {
+ {0,10}, {2,50}
+ };
+ SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_SETRANGE, 0, MAKELONG(999, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_SETACCEL, sizeof(accel) / sizeof(accel[0]), (LPARAM) &accel);
+ SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_SETPOS, 0, MAKELONG(cfg::getWord("CLC", "ScrollTime", CLCDEFAULT_SCROLLTIME), 0));
+
+ for (i = 0; i < sizeof(checkBoxToStyleEx) / sizeof(checkBoxToStyleEx[0]); i++)
+ CheckDlgButton(hwndDlg, checkBoxToStyleEx[i].id, (exStyle & checkBoxToStyleEx[i].flag) ^ (checkBoxToStyleEx[i].flag * checkBoxToStyleEx[i].not_t) ? BST_CHECKED : BST_UNCHECKED);
+ }
+ CheckDlgButton(hwndDlg, IDC_FULLROWSELECT, (cfg::dat.dwFlags & CLUI_FULLROWSELECT) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_DBLCLKAVATARS, cfg::dat.bDblClkAvatars);
+ CheckDlgButton(hwndDlg, IDC_GREYOUT, cfg::getDword("CLC", "GreyoutFlags", CLCDEFAULT_GREYOUTFLAGS) ? BST_CHECKED : BST_UNCHECKED);
+ Utils::enableDlgControl(hwndDlg, IDC_SMOOTHTIME, IsDlgButtonChecked(hwndDlg, IDC_NOTNOSMOOTHSCROLLING));
+ Utils::enableDlgControl(hwndDlg, IDC_GREYOUTOPTS, IsDlgButtonChecked(hwndDlg, IDC_GREYOUT));
+ FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), greyoutValues, sizeof(greyoutValues) / sizeof(greyoutValues[0]), cfg::getDword("CLC", "FullGreyoutFlags", CLCDEFAULT_FULLGREYOUTFLAGS));
+ CheckDlgButton(hwndDlg, IDC_NOSCROLLBAR, cfg::getByte("CLC", "NoVScrollBar", 0) ? BST_CHECKED : BST_UNCHECKED);
+
+ return TRUE;
+ case WM_VSCROLL:
+ opt_clc_main_changed = 1;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_NOTNOSMOOTHSCROLLING)
+ Utils::enableDlgControl(hwndDlg, IDC_SMOOTHTIME, IsDlgButtonChecked(hwndDlg, IDC_NOTNOSMOOTHSCROLLING));
+ if (LOWORD(wParam) == IDC_GREYOUT)
+ Utils::enableDlgControl(hwndDlg, IDC_GREYOUTOPTS, IsDlgButtonChecked(hwndDlg, IDC_GREYOUT));
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ opt_clc_main_changed = 1;
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case IDC_GREYOUTOPTS:
+ if (((LPNMHDR) lParam)->code == NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x = (short) LOWORD(GetMessagePos());
+ hti.pt.y = (short) HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR) lParam)->hwndFrom, &hti.pt);
+ if (TreeView_HitTest(((LPNMHDR) lParam)->hwndFrom, &hti))
+ if (hti.flags & TVHT_ONITEMSTATEICON) {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvi.hItem = hti.hItem;
+ TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1;
+ TreeView_SetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ opt_clc_main_changed = 1;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ int i;
+ DWORD exStyle = cfg::getDword("CLC", "ExStyle", CLCDEFAULT_EXSTYLE);
+
+ if(!opt_clc_main_changed)
+ return TRUE;
+
+ for (i = 0; i < sizeof(checkBoxToStyleEx) / sizeof(checkBoxToStyleEx[0]); i++)
+ exStyle &= ~(checkBoxToStyleEx[i].flag);
+
+ for (i = 0; i < sizeof(checkBoxToStyleEx) / sizeof(checkBoxToStyleEx[0]); i++) {
+ if ((IsDlgButtonChecked(hwndDlg, checkBoxToStyleEx[i].id) == 0) == checkBoxToStyleEx[i].not_t)
+ exStyle |= checkBoxToStyleEx[i].flag;
+ }
+ cfg::writeDword("CLC", "ExStyle", exStyle);
+ } {
+ DWORD fullGreyoutFlags = MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS));
+ cfg::writeDword("CLC", "FullGreyoutFlags", fullGreyoutFlags);
+ if (IsDlgButtonChecked(hwndDlg, IDC_GREYOUT))
+ cfg::writeDword("CLC", "GreyoutFlags", fullGreyoutFlags);
+ else
+ cfg::writeDword("CLC", "GreyoutFlags", 0);
+ }
+ cfg::writeWord("CLC", "ScrollTime", (WORD) SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_GETPOS, 0, 0));
+ cfg::writeByte("CLC", "NoVScrollBar", (BYTE) (IsDlgButtonChecked(hwndDlg, IDC_NOSCROLLBAR) ? 1 : 0));
+ cfg::dat.dwFlags = IsDlgButtonChecked(hwndDlg, IDC_FULLROWSELECT) ? cfg::dat.dwFlags | CLUI_FULLROWSELECT : cfg::dat.dwFlags & ~CLUI_FULLROWSELECT;
+ cfg::dat.bDblClkAvatars = IsDlgButtonChecked(hwndDlg, IDC_DBLCLKAVATARS) ? TRUE : FALSE;
+ cfg::writeByte("CLC", "dblclkav", (BYTE)cfg::dat.bDblClkAvatars);
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+
+ pcli->pfnClcOptionsChanged();
+ CoolSB_SetupScrollBar();
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ opt_clc_main_changed = 0;
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ ImageList_Destroy(TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), TVSIL_STATE));
+ break;
+ }
+ return FALSE;
+}
+
+static int opt_clc_bkg_changed = 0;
+
+static INT_PTR CALLBACK DlgProcClcBkgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ opt_clc_bkg_changed = 0;
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_BITMAP, cfg::getByte("CLC", "UseBitmap", CLCDEFAULT_USEBITMAP) ? BST_CHECKED : BST_UNCHECKED);
+ SendMessage(hwndDlg, WM_USER + 10, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETDEFAULTCOLOUR, 0, CLCDEFAULT_BKCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETCOLOUR, 0, cfg::getDword("CLC", "BkColour", CLCDEFAULT_BKCOLOUR));
+ CheckDlgButton(hwndDlg, IDC_WINCOLOUR, cfg::getByte("CLC", "UseWinColours", 0));
+ CheckDlgButton(hwndDlg, IDC_SKINMODE, cfg::dat.bWallpaperMode);
+ SendMessage(hwndDlg, WM_USER + 11, 0, 0); {
+ DBVARIANT dbv;
+
+ if (!cfg::getString(NULL, "CLC", "BkBitmap", &dbv)) {
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)) {
+ char szPath[MAX_PATH];
+
+ if (CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) dbv.pszVal, (LPARAM) szPath))
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, szPath);
+ }
+ DBFreeVariant(&dbv);
+ }
+ } {
+ WORD bmpUse = cfg::getWord("CLC", "BkBmpUse", CLCDEFAULT_BKBMPUSE);
+ CheckDlgButton(hwndDlg, IDC_STRETCHH, bmpUse & CLB_STRETCHH ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_STRETCHV, bmpUse & CLB_STRETCHV ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_TILEH, bmpUse & CLBF_TILEH ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_TILEV, bmpUse & CLBF_TILEV ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SCROLL, bmpUse & CLBF_SCROLL ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_PROPORTIONAL, bmpUse & CLBF_PROPORTIONAL ? BST_CHECKED : BST_UNCHECKED);
+ } {
+ HRESULT (STDAPICALLTYPE *MySHAutoComplete)(HWND, DWORD);
+ MySHAutoComplete = (HRESULT(STDAPICALLTYPE *)(HWND, DWORD))GetProcAddress(GetModuleHandleA("shlwapi"), "SHAutoComplete");
+ if (MySHAutoComplete)
+ MySHAutoComplete(GetDlgItem(hwndDlg, IDC_FILENAME), 1);
+ }
+ return TRUE;
+ case WM_USER+10:
+ Utils::enableDlgControl(hwndDlg, IDC_FILENAME, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_BROWSE, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_STRETCHH, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_STRETCHV, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_TILEH, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_TILEV, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_SCROLL, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ Utils::enableDlgControl(hwndDlg, IDC_PROPORTIONAL, IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ break;
+ case WM_USER+11:
+ {
+ BOOL b = IsDlgButtonChecked(hwndDlg, IDC_WINCOLOUR);
+ Utils::enableDlgControl(hwndDlg, IDC_BKGCOLOUR, !b);
+ break;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BROWSE) {
+ char str[MAX_PATH];
+ OPENFILENAMEA ofn = {
+ 0
+ };
+ char filter[512];
+
+ GetDlgItemTextA(hwndDlg, IDC_FILENAME, str, sizeof(str));
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ ofn.hInstance = NULL;
+ CallService(MS_UTILS_GETBITMAPFILTERSTRINGS, sizeof(filter), (LPARAM) filter);
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.nMaxFile = sizeof(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = "bmp";
+ if (!GetOpenFileNameA(&ofn))
+ break;
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, str);
+ } else if (LOWORD(wParam) == IDC_FILENAME && HIWORD(wParam) != EN_CHANGE)
+ break;
+ if (LOWORD(wParam) == IDC_BITMAP)
+ SendMessage(hwndDlg, WM_USER + 10, 0, 0);
+ if (LOWORD(wParam) == IDC_WINCOLOUR)
+ SendMessage(hwndDlg, WM_USER + 11, 0, 0);
+ if (LOWORD(wParam) == IDC_FILENAME && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ opt_clc_bkg_changed = 1;
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ if(!opt_clc_bkg_changed)
+ return TRUE;
+
+ cfg::writeByte("CLC", "UseBitmap", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_BITMAP)); {
+ COLORREF col;
+ col = SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0);
+ if (col == CLCDEFAULT_BKCOLOUR)
+ DBDeleteContactSetting(NULL, "CLC", "BkColour");
+ else
+ cfg::writeDword("CLC", "BkColour", col);
+ cfg::writeByte("CLC", "UseWinColours", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_WINCOLOUR));
+ } {
+ char str[MAX_PATH], strrel[MAX_PATH];
+
+ GetDlgItemTextA(hwndDlg, IDC_FILENAME, str, sizeof(str));
+ if (CallService(MS_UTILS_PATHTORELATIVE, (WPARAM) str, (LPARAM) strrel))
+ cfg::writeString(NULL, "CLC", "BkBitmap", strrel);
+ else
+ cfg::writeString(NULL, "CLC", "BkBitmap", str);
+ } {
+ WORD flags = 0;
+ if (IsDlgButtonChecked(hwndDlg, IDC_STRETCHH))
+ flags |= CLB_STRETCHH;
+ if (IsDlgButtonChecked(hwndDlg, IDC_STRETCHV))
+ flags |= CLB_STRETCHV;
+ if (IsDlgButtonChecked(hwndDlg, IDC_TILEH))
+ flags |= CLBF_TILEH;
+ if (IsDlgButtonChecked(hwndDlg, IDC_TILEV))
+ flags |= CLBF_TILEV;
+ if (IsDlgButtonChecked(hwndDlg, IDC_SCROLL))
+ flags |= CLBF_SCROLL;
+ if (IsDlgButtonChecked(hwndDlg, IDC_PROPORTIONAL))
+ flags |= CLBF_PROPORTIONAL;
+ cfg::writeWord("CLC", "BkBmpUse", flags);
+ cfg::dat.bWallpaperMode = IsDlgButtonChecked(hwndDlg, IDC_SKINMODE) ? 1 : 0;
+ cfg::writeByte("CLUI", "UseBkSkin", (BYTE)cfg::dat.bWallpaperMode);
+ }
+ pcli->pfnClcOptionsChanged();
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ opt_clc_bkg_changed = 0;
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+
+
diff --git a/plugins/Clist_nicer/SRC/clcpaint.cpp b/plugins/Clist_nicer/SRC/clcpaint.cpp
new file mode 100644
index 0000000000..866279ae59
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clcpaint.cpp
@@ -0,0 +1,1685 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: clcpaint.cpp 12909 2010-10-06 14:53:00Z silvercircle $
+ *
+ */
+
+#include "commonheaders.h"
+
+extern struct avatarCache *g_avatarCache;
+extern int g_curAvatar;
+
+extern ImageItem *g_glyphItem;
+
+extern int hClcProtoCount;
+extern ORDERTREEDATA OrderTreeData[];
+
+extern HIMAGELIST hCListImages;
+static BYTE divide3[765] = {255};
+extern char *im_clients[];
+extern HICON im_clienthIcons[];
+extern HICON overlayicons[];
+
+extern TCHAR *statusNames[];
+
+extern LONG g_cxsmIcon, g_cysmIcon;
+extern StatusItems_t *StatusItems;
+
+int g_hottrack, g_center, g_ignoreselforgroups, g_selectiveIcon, g_exIconSpacing, g_hottrack_done;
+HWND g_focusWnd;
+BYTE selBlend;
+BYTE saved_alpha;
+int my_status;
+
+BOOL g_inCLCpaint = FALSE;
+int g_list_avatars = 0;
+
+HFONT __fastcall ChangeToFont(HDC hdc, struct ClcData *dat, int id, int *fontHeight)
+{
+ HFONT hOldFont = 0;
+ /*
+ hOldFont = SelectObject(hdc, dat->fontInfo[id].hFont);
+ SetTextColor(hdc, dat->fontInfo[id].colour);
+ if (fontHeight)
+ *fontHeight = dat->fontInfo[id].fontHeight;
+ */
+ hOldFont = reinterpret_cast<HFONT>(SelectObject(hdc, cfg::clcdat->fontInfo[id].hFont));
+ SetTextColor(hdc, cfg::clcdat->fontInfo[id].colour);
+ if (fontHeight)
+ *fontHeight = cfg::clcdat->fontInfo[id].fontHeight;
+
+ dat->currentFontID = id;
+ return hOldFont;
+}
+
+static void __inline SetHotTrackColour(HDC hdc, struct ClcData *dat)
+{
+ if (dat->gammaCorrection) {
+ COLORREF oldCol, newCol;
+ int oldLum, newLum;
+
+ oldCol = GetTextColor(hdc);
+ oldLum = (GetRValue(oldCol) * 30 + GetGValue(oldCol) * 59 + GetBValue(oldCol) * 11) / 100;
+ newLum = (GetRValue(dat->hotTextColour) * 30 + GetGValue(dat->hotTextColour) * 59 + GetBValue(dat->hotTextColour) * 11) / 100;
+ if (newLum == 0) {
+ SetTextColor(hdc, dat->hotTextColour);
+ return;
+ }
+ if (newLum >= oldLum + 20) {
+ oldLum += 20;
+ newCol = RGB(GetRValue(dat->hotTextColour) * oldLum / newLum, GetGValue(dat->hotTextColour) * oldLum / newLum, GetBValue(dat->hotTextColour) * oldLum / newLum);
+ } else if (newLum <= oldLum) {
+ int r, g, b;
+ r = GetRValue(dat->hotTextColour) * oldLum / newLum;
+ g = GetGValue(dat->hotTextColour) * oldLum / newLum;
+ b = GetBValue(dat->hotTextColour) * oldLum / newLum;
+ if (r > 255) {
+ g +=(r-255)*3 / 7;
+ b +=(r-255)*3 / 7;
+ r = 255;
+ }
+ if (g > 255) {
+ r +=(g-255)*59 / 41;
+ if (r > 255)
+ r = 255;
+ b +=(g-255)*59 / 41;
+ g = 255;
+ }
+ if (b > 255) {
+ r +=(b-255)*11 / 89;
+ if (r > 255)
+ r = 255;
+ g +=(b-255)*11 / 89;
+ if (g > 255)
+ g = 255;
+ b = 255;
+ }
+ newCol = RGB(r, g, b);
+ } else
+ newCol = dat->hotTextColour;
+ SetTextColor(hdc, newCol);
+ } else
+ SetTextColor(hdc, dat->hotTextColour);
+}
+
+int __fastcall GetStatusOnlineness(int status)
+{
+ if(status >= ID_STATUS_CONNECTING && status < ID_STATUS_OFFLINE)
+ return 120;
+
+ switch (status) {
+ case ID_STATUS_FREECHAT:
+ return 110;
+ case ID_STATUS_ONLINE:
+ return 100;
+ case ID_STATUS_OCCUPIED:
+ return 60;
+ case ID_STATUS_ONTHEPHONE:
+ return 50;
+ case ID_STATUS_DND:
+ return 40;
+ case ID_STATUS_AWAY:
+ return 30;
+ case ID_STATUS_OUTTOLUNCH:
+ return 20;
+ case ID_STATUS_NA:
+ return 10;
+ case ID_STATUS_INVISIBLE:
+ return 5;
+ }
+ return 0;
+}
+
+static int __fastcall GetGeneralisedStatus(void)
+{
+ int i, status, thisStatus, statusOnlineness, thisOnlineness;
+
+ status = ID_STATUS_OFFLINE;
+ statusOnlineness = 0;
+
+ for (i = 0; i < pcli->hClcProtoCount; i++) {
+ thisStatus = pcli->clcProto[i].dwStatus;
+ if (thisStatus == ID_STATUS_INVISIBLE)
+ return ID_STATUS_INVISIBLE;
+ thisOnlineness = GetStatusOnlineness(thisStatus);
+ if (thisOnlineness > statusOnlineness) {
+ status = thisStatus;
+ statusOnlineness = thisOnlineness;
+ }
+ }
+ return status;
+}
+
+static int __fastcall GetRealStatus(struct ClcContact *contact, int status)
+{
+ int i;
+ char *szProto = contact->proto;
+ if (!szProto)
+ return status;
+ for (i = 0; i < pcli->hClcProtoCount; i++) {
+ if (!lstrcmpA(pcli->clcProto[i].szProto, szProto)) {
+ return pcli->clcProto[i].dwStatus;
+ }
+ }
+ return status;
+}
+
+int GetBasicFontID(struct ClcContact * contact)
+{
+ switch (contact->type)
+ {
+ case CLCIT_GROUP:
+ return FONTID_GROUPS;
+ break;
+ case CLCIT_INFO:
+ if(contact->flags & CLCIIF_GROUPFONT)
+ return FONTID_GROUPS;
+ else
+ return FONTID_CONTACTS;
+ break;
+ case CLCIT_DIVIDER:
+ return FONTID_DIVIDERS;
+ break;
+ case CLCIT_CONTACT:
+ if (contact->flags & CONTACTF_NOTONLIST)
+ return FONTID_NOTONLIST;
+ else if ((contact->flags&CONTACTF_INVISTO && GetRealStatus(contact, ID_STATUS_OFFLINE) != ID_STATUS_INVISIBLE)
+ || (contact->flags&CONTACTF_VISTO && GetRealStatus(contact, ID_STATUS_OFFLINE) == ID_STATUS_INVISIBLE))
+ return contact->flags & CONTACTF_ONLINE ? FONTID_INVIS : FONTID_OFFINVIS;
+ else
+ return contact->flags & CONTACTF_ONLINE ? FONTID_CONTACTS : FONTID_OFFLINE;
+ break;
+ default:
+ return FONTID_CONTACTS;
+ }
+}
+
+void PaintNotifyArea(HDC hDC, RECT *rc)
+{
+ struct ClcData *dat = (struct ClcData *) GetWindowLongPtr(pcli->hwndContactTree, 0);
+ int iCount;
+ static int ev_lastIcon = 0;
+
+ rc->left += 26; // button
+ iCount = GetMenuItemCount(cfg::dat.hMenuNotify);
+ if (cfg::dat.hUpdateContact != 0) {
+ TCHAR *szName = pcli->pfnGetContactDisplayName(cfg::dat.hUpdateContact, 0);
+ int iIcon = CallService(MS_CLIST_GETCONTACTICON, (WPARAM) cfg::dat.hUpdateContact, 0);
+
+ ImageList_DrawEx(hCListImages, iIcon, hDC, rc->left, (rc->bottom + rc->top - g_cysmIcon) / 2, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rc->left += 18;
+ DrawText(hDC, szName, -1, rc, DT_VCENTER | DT_SINGLELINE);
+ ImageList_DrawEx(hCListImages, (int)cfg::dat.hIconNotify, hDC, 4, (rc->bottom + rc->top - 16) / 2, 16, 16, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ ev_lastIcon = cfg::dat.hIconNotify;
+ } else if (iCount > 0) {
+ MENUITEMINFO mii = {0};
+ struct NotifyMenuItemExData *nmi;
+ TCHAR *szName;
+ int iIcon;
+
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+ GetMenuItemInfo(cfg::dat.hMenuNotify, iCount - 1, TRUE, &mii);
+ nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
+ szName = pcli->pfnGetContactDisplayName(nmi->hContact, 0);
+ iIcon = CallService(MS_CLIST_GETCONTACTICON, (WPARAM) nmi->hContact, 0);
+ ImageList_DrawEx(hCListImages, iIcon, hDC, rc->left, (rc->bottom + rc->top - g_cysmIcon) / 2, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rc->left += 18;
+ ImageList_DrawEx(hCListImages, nmi->iIcon, hDC, 4, (rc->bottom + rc->top) / 2 - 8, 16, 16, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ DrawText(hDC, szName, -1, rc, DT_VCENTER | DT_SINGLELINE);
+ ev_lastIcon = (int)nmi->hIcon;
+ } else {
+ HICON hIcon = reinterpret_cast<HICON>(LoadImage(g_hInst, MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, 16, 16, 0));
+ DrawText(hDC, cfg::dat.szNoEvents, lstrlen(cfg::dat.szNoEvents), rc, DT_VCENTER | DT_SINGLELINE);
+ DrawIconEx(hDC, 4, (rc->bottom + rc->top - 16) / 2, hIcon, 16, 16, 0, 0, DI_NORMAL | DI_COMPAT);
+ DestroyIcon(hIcon);
+ }
+}
+
+static BLENDFUNCTION bf = {0, 0, AC_SRC_OVER, 0};
+static BOOL avatar_done = FALSE;
+HDC g_HDC;
+static BOOL g_RTL;
+HDC hdcTempAV;
+HBITMAP hbmTempAV, hbmTempOldAV;
+
+HDC hdcAV;
+
+LONG g_maxAV_X = 200, g_maxAV_Y = 200;
+
+static int __fastcall DrawAvatar(HDC hdcMem, RECT *rc, struct ClcContact *contact, int y, struct ClcData *dat, WORD cstatus, int rowHeight, DWORD dwFlags)
+{
+ float dScale = 0.;
+ float newHeight, newWidth;
+ HDC hdcAvatar = hdcAV;
+ //HBITMAP hbmMem;
+ DWORD topoffset = 0, leftoffset = 0;
+ LONG bmWidth, bmHeight;
+ float dAspect;
+ HBITMAP hbm, hbmOldAV;
+ HRGN rgn = 0;
+ int avatar_size = cfg::dat.avatarSize;
+ DWORD av_saved_left;
+ StatusItems_t *item = contact->wStatus == ID_STATUS_OFFLINE ? &StatusItems[ID_EXTBKAVATARFRAMEOFFLINE - ID_STATUS_OFFLINE] : &StatusItems[ID_EXTBKAVATARFRAME - ID_STATUS_OFFLINE];
+ int skinMarginX, skinMarginY;
+ BOOL fOverlay = (cfg::dat.dwFlags & CLUI_FRAME_OVERLAYICONS);
+
+ contact->avatarLeft = -1;
+ if(!cfg::dat.bAvatarServiceAvail || dat->bisEmbedded)
+ return 0;
+
+ if(contact->ace != NULL && contact->ace->cbSize == sizeof(struct avatarCacheEntry)) {
+ if(contact->ace->dwFlags & AVS_HIDEONCLIST) {
+ if (cfg::dat.dwFlags & CLUI_FRAME_ALWAYSALIGNNICK)
+ return avatar_size + 2;
+ else
+ return 0;
+ }
+ bmHeight = contact->ace->bmHeight;
+ bmWidth = contact->ace->bmWidth;
+ if(bmWidth != 0)
+ dAspect = (float)bmHeight / (float)bmWidth;
+ else
+ dAspect = 1.0;
+ hbm = contact->ace->hbmPic;
+ contact->ace->t_lastAccess = cfg::dat.t_now;
+ }
+ else if (cfg::dat.dwFlags & CLUI_FRAME_ALWAYSALIGNNICK)
+ return avatar_size + 2;
+ else
+ return 0;
+
+ if(bmHeight == 0 || bmWidth == 0 || hbm == 0)
+ return 0;
+
+ g_maxAV_X = max(bmWidth, g_maxAV_X);
+ g_maxAV_Y = max(bmHeight, g_maxAV_Y);
+
+ if(dAspect >= 1.0) { // height > width
+ skinMarginY = item->IGNORED ? 0 : (item->MARGIN_TOP + item->MARGIN_BOTTOM);
+ skinMarginX = item->IGNORED ? 0 : (item->MARGIN_LEFT + item->MARGIN_RIGHT);
+
+ dScale = (float)(avatar_size - 2) / (float)bmHeight;
+ newHeight = (float)(avatar_size - skinMarginY - 2);
+ newWidth = (float)(bmWidth * dScale) - skinMarginX;
+ }
+ else {
+ skinMarginY = item->IGNORED ? 0 : (item->MARGIN_LEFT + item->MARGIN_RIGHT);
+ skinMarginX = item->IGNORED ? 0 : (item->MARGIN_LEFT + item->MARGIN_RIGHT);
+
+ newWidth = (float)(avatar_size - 2) - skinMarginX;
+ dScale = (float)(avatar_size - 2) / (float)bmWidth;
+ newHeight = (float)(bmHeight * dScale) - skinMarginY;
+ }
+ topoffset = rowHeight > (int)newHeight ? (rowHeight - (int)newHeight) / 2 : 0;
+ if(!item->IGNORED) {
+ //topoffset += item->MARGIN_TOP;
+ leftoffset = item->MARGIN_LEFT;
+ }
+ // create the region for the avatar border - use the same region for clipping, if needed.
+
+ av_saved_left = rc->left;
+ if(cfg::dat.bCenterStatusIcons && newWidth < newHeight)
+ rc->left += (((avatar_size - 2) - ((int)newWidth + skinMarginX)) / 2);
+
+ if(cfg::dat.dwFlags & CLUI_FRAME_ROUNDAVATAR)
+ rgn = CreateRoundRectRgn(leftoffset + rc->left, y + topoffset, leftoffset + rc->left + (int)newWidth + 1, y + topoffset + (int)newHeight + 1, 2 * cfg::dat.avatarRadius, 2 * cfg::dat.avatarRadius);
+ else
+ rgn = CreateRectRgn(leftoffset + rc->left, y + topoffset, leftoffset + rc->left + (int)newWidth, y + topoffset + (int)newHeight);
+
+ hbmOldAV = reinterpret_cast<HBITMAP>(SelectObject(hdcAV, hbm));
+ bf.SourceConstantAlpha = 255; //(g_CluiData.dwFlags & CLUI_FRAME_TRANSPARENTAVATAR && (UCHAR)saved_alpha > 20) ? (UCHAR)saved_alpha : 255;
+ bf.AlphaFormat = contact->ace->dwFlags & AVS_PREMULTIPLIED ? AC_SRC_ALPHA : 0;
+
+ /*
+ if(dat->showIdle && contact->flags & CONTACTF_IDLE)
+ bf.SourceConstantAlpha -= (bf.SourceConstantAlpha > 100 ? 50 : 0);
+ */
+
+ SelectClipRgn(hdcMem, rgn);
+ SetStretchBltMode(hdcMem, HALFTONE);
+ if(bf.SourceConstantAlpha == 255 && bf.AlphaFormat == 0) {
+ StretchBlt(hdcMem, leftoffset + rc->left - (g_RTL ? 1 : 0), y + topoffset, (int)newWidth, (int)newHeight, hdcAvatar, 0, 0, bmWidth, bmHeight, SRCCOPY);
+ }
+ else {
+ /*
+ * get around SUCKY AlphaBlend() rescaling quality...
+ */
+ SetStretchBltMode(hdcTempAV, HALFTONE);
+ StretchBlt(hdcTempAV, 0, 0, bmWidth, bmHeight, hdcMem, leftoffset + rc->left, y + topoffset, (int)newWidth, (int)newHeight, SRCCOPY);
+ API::pfnAlphaBlend(hdcTempAV, 0, 0, bmWidth, bmHeight, hdcAvatar, 0, 0, bmWidth, bmHeight, bf);
+ StretchBlt(hdcMem, leftoffset + rc->left - (g_RTL ? 1 : 0), y + topoffset, (int)newWidth, (int)newHeight, hdcTempAV, 0, 0, bmWidth, bmHeight, SRCCOPY);
+ }
+ SelectObject(hdcAV, hbmOldAV);
+
+ if(cfg::dat.dwFlags & CLUI_FRAME_AVATARBORDER) {
+ if(g_RTL)
+ OffsetRgn(rgn, -1 , 0);
+ FrameRgn(hdcMem, rgn, cfg::dat.hBrushAvatarBorder, 1, 1);
+ }
+
+ if(fOverlay)
+ fOverlay = (dwFlags & ECF_HIDEOVERLAY) ? 0 : 1;
+ else
+ fOverlay = (dwFlags & ECF_FORCEOVERLAY) ? 1 : 0;
+
+ if(fOverlay && cstatus && (int)newHeight >= g_cysmIcon)
+ DrawIconEx(hdcMem, rc->left + (int)newWidth - 15, y + topoffset + (int)newHeight - 15, overlayicons[cstatus - ID_STATUS_OFFLINE], g_cxsmIcon, g_cysmIcon, 0, 0, DI_NORMAL | DI_COMPAT);
+
+ SelectClipRgn(hdcMem, NULL);
+ DeleteObject(rgn);
+
+ if(!item->IGNORED) {
+ RECT rcFrame;
+ BOOL inClCPaint_save = g_inCLCpaint;
+ HDC hdcTemp = 0, hdcSaved = 0;
+ HBITMAP hbmOld, hbmTemp;
+
+ g_inCLCpaint = FALSE;
+ rcFrame.left = rc->left;
+ rcFrame.top = y + topoffset - item->MARGIN_TOP;
+ rcFrame.right = rcFrame.left + (int)newWidth + item->MARGIN_RIGHT + item->MARGIN_LEFT;
+ rcFrame.bottom = rcFrame.top + (int)newHeight + item->MARGIN_BOTTOM + item->MARGIN_TOP;
+ if(g_RTL) {
+ RECT rcTemp;
+
+ OffsetRect(&rcFrame, 1, 0);
+ rcTemp.left = rcTemp.top = 0;
+ rcTemp.right = rcFrame.right - rcFrame.left;
+ rcTemp.bottom = rcFrame.bottom - rcFrame.top;
+ hdcTemp = CreateCompatibleDC(g_HDC);
+ hbmTemp = CreateCompatibleBitmap(g_HDC, rcTemp.right, rcTemp.bottom);
+ hbmOld = reinterpret_cast<HBITMAP>(SelectObject(hdcTemp, hbmTemp));
+ API::pfnSetLayout(hdcTemp, LAYOUT_RTL);
+ BitBlt(hdcTemp, 0, 0, rcTemp.right, rcTemp.bottom,
+ hdcMem, rcFrame.left, rcFrame.top, SRCCOPY);
+ API::pfnSetLayout(hdcTemp, 0);
+ DrawAlpha(hdcTemp, &rcTemp, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT,
+ item->CORNER, item->BORDERSTYLE, item->imageItem);
+ BitBlt(hdcMem, rcFrame.left, rcFrame.top, rcFrame.right - rcFrame.left, rcFrame.bottom - rcFrame.top,
+ hdcTemp, 0, 0, SRCCOPY);
+ SelectObject(hdcTemp, hbmOld);
+ DeleteObject(hbmTemp);
+ DeleteDC(hdcTemp);
+ } else
+ DrawAlpha(hdcMem, &rcFrame, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT,
+ item->CORNER, item->BORDERSTYLE, item->imageItem);
+ g_inCLCpaint = inClCPaint_save;
+ }
+ contact->avatarLeft = rc->left;
+ avatar_done = TRUE;
+ rc->left = av_saved_left;
+ return avatar_size + 2;
+
+}
+
+static BOOL pi_avatar = FALSE;
+static RECT rcContent;
+static BOOL pi_selectiveIcon;
+
+static BOOL av_left, av_right, av_rightwithnick;
+static BOOL mirror_rtl, mirror_always, mirror_rtltext;
+
+BYTE savedCORNER = -1;
+int g_padding_y = 0;
+
+void __inline PaintItem(HDC hdcMem, struct ClcGroup *group, struct ClcContact *contact, int indent, int y, struct ClcData *dat, int index, HWND hwnd, DWORD style, RECT *clRect, BOOL *bFirstNGdrawn, int groupCountsFontTopShift, int rowHeight)
+{
+ RECT rc;
+ int iImage = -1;
+ int selected;
+ SIZE textSize, countsSize, spaceSize;
+ int width, checkboxWidth;
+ char *szCounts;
+ int fontHeight;
+ BOOL twoRows = FALSE;
+ WORD cstatus;
+ DWORD leftOffset = 0, rightOffset = 0;
+ int iconXSpace = dat->iconXSpace;
+ //BOOL xStatusValid = 0;
+ HFONT hPreviousFont = 0;
+ BYTE type;
+ BYTE flags;
+ COLORREF oldGroupColor = -1;
+ DWORD qLeft = 0;
+ int leftX = dat->leftMargin + indent * dat->groupIndent;
+ int bg_indent_r = 0;
+ int bg_indent_l = 0;
+ int rightIcons = 0;
+ DWORD dt_nickflags = 0, dt_2ndrowflags = 0;
+ struct TExtraCache *cEntry = NULL;
+ DWORD dwFlags = cfg::dat.dwFlags;
+ int scanIndex;
+ BOOL check_selected, av_local_wanted, fLocalTime;
+
+ rowHeight -= cfg::dat.bRowSpacing;
+ savedCORNER = -1;
+
+ if(group == NULL || contact == NULL)
+ return;
+
+ g_RTL = FALSE;
+ scanIndex = group->scanIndex;
+ av_local_wanted = (g_list_avatars > 0);
+
+ type = contact->type;
+ flags = contact->flags;
+ selected = index == dat->selection && (dat->showSelAlways || dat->exStyle &CLS_EX_SHOWSELALWAYS || g_focusWnd == hwnd) && type != CLCIT_DIVIDER;
+ avatar_done = FALSE;
+ if(contact->extraCacheEntry >= 0 && contact->extraCacheEntry < cfg::nextCacheEntry)
+ cEntry = &cfg::eCache[contact->extraCacheEntry];
+ else
+ cEntry = cfg::eCache;
+
+#if defined(_UNICODE)
+ if(dat->bisEmbedded)
+ goto set_bg_l;
+
+ if(type == CLCIT_CONTACT && (cEntry->dwCFlags & ECF_RTLNICK || mirror_always)) {
+ if(API::pfnSetLayout != NULL && (mirror_rtl || mirror_always)) {
+ g_RTL = TRUE;
+ bg_indent_r = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ }
+ else if(mirror_rtltext) {
+ bg_indent_l = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ dt_nickflags = DT_RTLREADING | DT_RIGHT;
+ }
+ else
+ bg_indent_l = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ }
+ else if(type == CLCIT_GROUP && API::pfnSetLayout != NULL) {
+ if((contact->isRtl && cfg::dat.bGroupAlign == CLC_GROUPALIGN_AUTO) || cfg::dat.bGroupAlign == CLC_GROUPALIGN_RIGHT) {
+ g_RTL = TRUE;
+ bg_indent_r = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ }
+ else
+ bg_indent_l = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ }
+ else
+ bg_indent_l = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+
+set_bg_l:
+#else
+ if(type == CLCIT_GROUP && cfg::dat.bGroupAlign == CLC_GROUPALIGN_RIGHT && !dat->bisEmbedded && API::pfnSetLayout != 0) {
+ g_RTL = TRUE;
+ bg_indent_r = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ }
+ else {
+ g_RTL = FALSE;
+ bg_indent_l = cfg::dat.bApplyIndentToBg ? indent * dat->groupIndent : 0;
+ }
+#endif
+
+ g_hottrack = dat->exStyle & CLS_EX_TRACKSELECT && type == CLCIT_CONTACT && dat->iHotTrack == index;
+ if (g_hottrack == selected)
+ g_hottrack = 0;
+
+ saved_alpha = 0;
+
+ //setup
+ if (type == CLCIT_GROUP)
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
+ else if (type == CLCIT_INFO) {
+ if (flags & CLCIIF_GROUPFONT)
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
+ else
+ ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
+ } else if (type == CLCIT_DIVIDER) {
+ ChangeToFont(hdcMem, dat, FONTID_DIVIDERS, &fontHeight);
+ GetTextExtentPoint32(hdcMem, contact->szText, lstrlen(contact->szText), &textSize);
+ }
+ else if (type == CLCIT_CONTACT && flags & CONTACTF_NOTONLIST)
+ ChangeToFont(hdcMem, dat, FONTID_NOTONLIST, &fontHeight);
+ else if (type == CLCIT_CONTACT && ((flags & CONTACTF_INVISTO && GetRealStatus(contact, my_status) != ID_STATUS_INVISIBLE) || (flags & CONTACTF_VISTO && GetRealStatus(contact, my_status) == ID_STATUS_INVISIBLE))) {
+ // the contact is in the always visible list and the proto is invisible
+ // the contact is in the always invisible and the proto is in any other mode
+ ChangeToFont(hdcMem, dat, flags & CONTACTF_ONLINE ? FONTID_INVIS : FONTID_OFFINVIS, &fontHeight);
+ } else if (type == CLCIT_CONTACT && !(flags & CONTACTF_ONLINE))
+ ChangeToFont(hdcMem, dat, FONTID_OFFLINE, &fontHeight);
+ else
+ ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
+
+ if (type == CLCIT_GROUP) {
+ GetTextExtentPoint32(hdcMem, contact->szText, lstrlen(contact->szText), &textSize);
+ width = textSize.cx;
+ szCounts = pcli->pfnGetGroupCountsText(dat, contact);
+ if (szCounts[0]) {
+ GetTextExtentPoint32(hdcMem, _T(" "), 1, &spaceSize);
+ ChangeToFont(hdcMem, dat, FONTID_GROUPCOUNTS, &fontHeight);
+ GetTextExtentPoint32A(hdcMem, szCounts, lstrlenA(szCounts), &countsSize);
+ width += spaceSize.cx + countsSize.cx;
+ }
+ }
+ if ((style & CLS_CHECKBOXES && type == CLCIT_CONTACT) || (style & CLS_GROUPCHECKBOXES && type == CLCIT_GROUP) || (type == CLCIT_INFO && flags & CLCIIF_CHECKBOX))
+ checkboxWidth = dat->checkboxSize + 2;
+ else
+ checkboxWidth = 0;
+
+ rc.left = 0;
+ cstatus = contact->wStatus;
+
+ /***** BACKGROUND DRAWING *****/
+ // contacts
+
+ g_hottrack_done = 0;
+ check_selected = (!selected || selBlend);
+
+ if(dat->bisEmbedded) {
+ rc.left = bg_indent_l;
+ rc.top = y;
+ rc.right = clRect->right - bg_indent_r;
+ rc.bottom = y + rowHeight;
+ if (selected) {
+ FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ SetTextColor(hdcMem, dat->selTextColour);
+ }
+ else {
+ FillRect(hdcMem, &rc, cfg::dat.hBrushCLCBk);
+ if(g_hottrack)
+ SetHotTrackColour(hdcMem,dat);
+ }
+ goto bgskipped;
+ }
+
+ if (type == CLCIT_CONTACT || type == CLCIT_DIVIDER) {
+ StatusItems_t *sitem, *sfirstitem, *ssingleitem, *slastitem, *slastitem_NG,
+ *sfirstitem_NG, *ssingleitem_NG, *sevencontact_pos, *soddcontact_pos, *pp_item;
+
+ if (cstatus >= ID_STATUS_OFFLINE && cstatus <= ID_STATUS_OUTTOLUNCH) {
+ BYTE perstatus_ignored;
+
+ if((flags & CONTACTF_IDLE) && !StatusItems[ID_EXTBKIDLE - ID_STATUS_OFFLINE].IGNORED)
+ sitem = &StatusItems[ID_EXTBKIDLE - ID_STATUS_OFFLINE];
+ else
+ sitem = &StatusItems[cstatus - ID_STATUS_OFFLINE];
+
+ if(!dat->bisEmbedded) {
+ pp_item = cEntry->status_item ? cEntry->status_item : cEntry->proto_status_item;
+
+ if (!(perstatus_ignored = sitem->IGNORED) && !(flags & CONTACTF_NOTONLIST))
+ SetTextColor(hdcMem, sitem->TEXTCOLOR);
+
+ if(cfg::dat.bUsePerProto && pp_item && !pp_item->IGNORED) {
+ sitem = pp_item;
+ if((perstatus_ignored || cfg::dat.bOverridePerStatusColors) && sitem->TEXTCOLOR != -1)
+ SetTextColor(hdcMem, sitem->TEXTCOLOR);
+ }
+ }
+ else if(!sitem->IGNORED)
+ SetTextColor(hdcMem, sitem->TEXTCOLOR);
+
+ sevencontact_pos = &StatusItems[ID_EXTBKEVEN_CNTCTPOS - ID_STATUS_OFFLINE];
+ soddcontact_pos = &StatusItems[ID_EXTBKODD_CNTCTPOS - ID_STATUS_OFFLINE];
+ sfirstitem = &StatusItems[ID_EXTBKFIRSTITEM - ID_STATUS_OFFLINE];
+ ssingleitem = &StatusItems[ID_EXTBKSINGLEITEM - ID_STATUS_OFFLINE];
+ slastitem = &StatusItems[ID_EXTBKLASTITEM - ID_STATUS_OFFLINE];
+
+ sfirstitem_NG = &StatusItems[ID_EXTBKFIRSTITEM_NG - ID_STATUS_OFFLINE];
+ ssingleitem_NG = &StatusItems[ID_EXTBKSINGLEITEM_NG - ID_STATUS_OFFLINE];
+ slastitem_NG = &StatusItems[ID_EXTBKLASTITEM_NG - ID_STATUS_OFFLINE];
+
+ rc.left = sitem->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + sitem->MARGIN_TOP;
+ rc.right = clRect->right - sitem->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - sitem->MARGIN_BOTTOM;
+
+ // check for special cases (first item, single item, last item)
+ // this will only change the shape for this status. Color will be blended over with ALPHA value
+ if (!ssingleitem->IGNORED && scanIndex == 0 && group->cl.count == 1 && group->parent != NULL) {
+ rc.left = ssingleitem->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + ssingleitem->MARGIN_TOP;
+ rc.right = clRect->right - ssingleitem->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - ssingleitem->MARGIN_BOTTOM;
+
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, ssingleitem->CORNER, ssingleitem->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, ssingleitem->CORNER, ssingleitem->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (!sitem->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, ssingleitem->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = ssingleitem->CORNER;
+ }
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, ssingleitem->COLOR, ssingleitem->ALPHA, ssingleitem->COLOR2, ssingleitem->COLOR2_TRANSPARENT, ssingleitem->GRADIENT, ssingleitem->CORNER, ssingleitem->BORDERSTYLE, ssingleitem->imageItem);
+ } else if (scanIndex == 0 && group->cl.count > 1 && !sfirstitem->IGNORED && group->parent != NULL) {
+ rc.left = sfirstitem->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + sfirstitem->MARGIN_TOP;
+ rc.right = clRect->right - sfirstitem->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - sfirstitem->MARGIN_BOTTOM;
+
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, sfirstitem->CORNER, sevencontact_pos->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, sfirstitem->CORNER, soddcontact_pos->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (!sitem->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, sfirstitem->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = sfirstitem->CORNER;
+ }
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sfirstitem->COLOR, sfirstitem->ALPHA, sfirstitem->COLOR2, sfirstitem->COLOR2_TRANSPARENT, sfirstitem->GRADIENT, sfirstitem->CORNER, sfirstitem->BORDERSTYLE, sfirstitem->imageItem);
+ } else if (scanIndex == group->cl.count - 1 && !slastitem->IGNORED && group->parent != NULL) {
+ // last item of group
+ rc.left = slastitem->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + slastitem->MARGIN_TOP;
+ rc.right = clRect->right - slastitem->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - slastitem->MARGIN_BOTTOM;
+ rc.bottom = y + rowHeight - slastitem->MARGIN_BOTTOM;
+
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, slastitem->CORNER, sevencontact_pos->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, slastitem->CORNER, soddcontact_pos->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (!sitem->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, slastitem->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = slastitem->CORNER;
+ }
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, slastitem->COLOR, slastitem->ALPHA, slastitem->COLOR2, slastitem->COLOR2_TRANSPARENT, slastitem->GRADIENT, slastitem->CORNER, slastitem->BORDERSTYLE, slastitem->imageItem);
+ } else
+ // - - - Non-grouped items - - -
+ if (type != CLCIT_GROUP // not a group
+ && group->parent == NULL // not grouped
+ && !sfirstitem_NG->IGNORED && scanIndex != group->cl.count - 1 && !(*bFirstNGdrawn)) {
+ // first NON-grouped
+ *bFirstNGdrawn = TRUE;
+ rc.left = sfirstitem_NG->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + sfirstitem_NG->MARGIN_TOP;
+ rc.right = clRect->right - sfirstitem_NG->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - sfirstitem_NG->MARGIN_BOTTOM;
+
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, sfirstitem_NG->CORNER, sevencontact_pos->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, sfirstitem_NG->CORNER, soddcontact_pos->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (!sitem->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, sfirstitem_NG->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = sfirstitem_NG->CORNER;
+ }
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sfirstitem_NG->COLOR, sfirstitem_NG->ALPHA, sfirstitem_NG->COLOR2, sfirstitem_NG->COLOR2_TRANSPARENT, sfirstitem_NG->GRADIENT, sfirstitem_NG->CORNER, sfirstitem->BORDERSTYLE, sfirstitem->imageItem);
+ } else if (type != CLCIT_GROUP // not a group
+ && group->parent == NULL && !slastitem_NG->IGNORED && scanIndex == group->cl.count - 1 && (*bFirstNGdrawn)) {
+ // last item of list (NON-group)
+ // last NON-grouped
+ rc.left = slastitem_NG->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + slastitem_NG->MARGIN_TOP;
+ rc.right = clRect->right - slastitem_NG->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - slastitem_NG->MARGIN_BOTTOM;
+
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, slastitem_NG->CORNER, sevencontact_pos->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, slastitem_NG->CORNER, soddcontact_pos->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (!sitem->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, slastitem_NG->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = slastitem_NG->CORNER;
+ }
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, slastitem_NG->COLOR, slastitem_NG->ALPHA, slastitem_NG->COLOR2, slastitem_NG->COLOR2_TRANSPARENT, slastitem_NG->GRADIENT, slastitem_NG->CORNER, slastitem->BORDERSTYLE, slastitem->imageItem);
+ } else if (type != CLCIT_GROUP // not a group
+ && group->parent == NULL && !slastitem_NG->IGNORED && !(*bFirstNGdrawn)) {
+ // single item of NON-group
+ // single NON-grouped
+ rc.left = ssingleitem_NG->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + ssingleitem_NG->MARGIN_TOP;
+ rc.right = clRect->right - ssingleitem_NG->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - ssingleitem_NG->MARGIN_BOTTOM;
+
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, ssingleitem_NG->CORNER, sevencontact_pos->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, ssingleitem_NG->CORNER, soddcontact_pos->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (!sitem->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, ssingleitem_NG->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = ssingleitem_NG->CORNER;
+ }
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, ssingleitem_NG->COLOR, ssingleitem_NG->ALPHA, ssingleitem_NG->COLOR2, ssingleitem_NG->COLOR2_TRANSPARENT, ssingleitem_NG->GRADIENT, ssingleitem_NG->CORNER, ssingleitem->BORDERSTYLE, ssingleitem->imageItem);
+ } else if (!sitem->IGNORED) {
+ // draw default grouped
+ // draw odd/even contact underlay
+ if ((scanIndex == 0 || scanIndex % 2 == 0) && !sevencontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sevencontact_pos->COLOR, sevencontact_pos->ALPHA, sevencontact_pos->COLOR2, sevencontact_pos->COLOR2_TRANSPARENT, sevencontact_pos->GRADIENT, sitem->CORNER, sevencontact_pos->BORDERSTYLE, sevencontact_pos->imageItem);
+ } else if (scanIndex % 2 != 0 && !soddcontact_pos->IGNORED) {
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, soddcontact_pos->COLOR, soddcontact_pos->ALPHA, soddcontact_pos->COLOR2, soddcontact_pos->COLOR2_TRANSPARENT, soddcontact_pos->GRADIENT, sitem->CORNER, soddcontact_pos->BORDERSTYLE, soddcontact_pos->imageItem);
+ }
+
+ if (check_selected)
+ DrawAlpha(hdcMem, &rc, sitem->COLOR, sitem->ALPHA, sitem->COLOR2, sitem->COLOR2_TRANSPARENT, sitem->GRADIENT, sitem->CORNER, sitem->BORDERSTYLE, sitem->imageItem);
+ savedCORNER = sitem->CORNER;
+ }
+ }
+ }
+ if (type == CLCIT_GROUP) {
+ StatusItems_t *sempty = &StatusItems[ID_EXTBKEMPTYGROUPS - ID_STATUS_OFFLINE];
+ StatusItems_t *sexpanded = &StatusItems[ID_EXTBKEXPANDEDGROUP - ID_STATUS_OFFLINE];
+ StatusItems_t *scollapsed = &StatusItems[ID_EXTBKCOLLAPSEDDGROUP - ID_STATUS_OFFLINE];
+
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
+ if (contact->group->cl.count == 0) {
+ if (!sempty->IGNORED) {
+ rc.left = sempty->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + sempty->MARGIN_TOP;
+ rc.right = clRect->right - sempty->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - sempty->MARGIN_BOTTOM;
+ DrawAlpha(hdcMem, &rc, sempty->COLOR, sempty->ALPHA, sempty->COLOR2, sempty->COLOR2_TRANSPARENT, sempty->GRADIENT, sempty->CORNER, sempty->BORDERSTYLE, sempty->imageItem);
+ savedCORNER = sempty->CORNER;
+ oldGroupColor = SetTextColor(hdcMem, sempty->TEXTCOLOR);
+ }
+ } else if (contact->group->expanded) {
+ if (!sexpanded->IGNORED) {
+ rc.left = sexpanded->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + sexpanded->MARGIN_TOP;
+ rc.right = clRect->right - sexpanded->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - (char) sexpanded->MARGIN_BOTTOM;
+ DrawAlpha(hdcMem, &rc, sexpanded->COLOR, sexpanded->ALPHA, sexpanded->COLOR2, sexpanded->COLOR2_TRANSPARENT, sexpanded->GRADIENT, sexpanded->CORNER, sexpanded->BORDERSTYLE, sexpanded->imageItem);
+ savedCORNER = sexpanded->CORNER;
+ oldGroupColor = SetTextColor(hdcMem, sexpanded->TEXTCOLOR);
+ }
+ } else {
+ if (!scollapsed->IGNORED) {
+ // collapsed but not empty
+ rc.left = scollapsed->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + scollapsed->MARGIN_TOP;
+ rc.right = clRect->right - scollapsed->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - scollapsed->MARGIN_BOTTOM;
+ DrawAlpha(hdcMem, &rc, scollapsed->COLOR, scollapsed->ALPHA, scollapsed->COLOR2, scollapsed->COLOR2_TRANSPARENT, scollapsed->GRADIENT, scollapsed->CORNER, scollapsed->BORDERSTYLE, scollapsed->imageItem);
+ savedCORNER = scollapsed->CORNER;
+ oldGroupColor = SetTextColor(hdcMem, scollapsed->TEXTCOLOR);
+ }
+ }
+ }
+ if (selected) {
+ StatusItems_t *sselected = &StatusItems[ID_EXTBKSELECTION - ID_STATUS_OFFLINE];
+
+ if (!g_ignoreselforgroups || type != CLCIT_GROUP) {
+ if (!sselected->IGNORED) {
+ rc.left = sselected->MARGIN_LEFT + bg_indent_l;
+ rc.top = y + sselected->MARGIN_TOP;
+ rc.right = clRect->right - sselected->MARGIN_RIGHT - bg_indent_r;
+ rc.bottom = y + rowHeight - sselected->MARGIN_BOTTOM;
+ if (cfg::getByte("CLCExt", "EXBK_EqualSelection", 0) == 1 && savedCORNER != -1) {
+ DrawAlpha(hdcMem, &rc, sselected->COLOR, sselected->ALPHA, sselected->COLOR2, sselected->COLOR2_TRANSPARENT, sselected->GRADIENT, savedCORNER, sselected->BORDERSTYLE, sselected->imageItem);
+ } else {
+ DrawAlpha(hdcMem, &rc, sselected->COLOR, sselected->ALPHA, sselected->COLOR2, sselected->COLOR2_TRANSPARENT, sselected->GRADIENT, sselected->CORNER, sselected->BORDERSTYLE, sselected->imageItem);
+ }
+ SetTextColor(hdcMem, sselected->TEXTCOLOR);
+ }
+ else {
+ rc.left = bg_indent_l;
+ rc.top = y;
+ rc.right = clRect->right - bg_indent_r;
+ rc.bottom = y + rowHeight;
+ FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ SetTextColor(hdcMem, dat->selTextColour);
+ }
+ }
+ }
+ else if (g_hottrack) {
+ StatusItems_t *ht = &StatusItems[ID_EXTBKHOTTRACK - ID_STATUS_OFFLINE];
+
+ SetHotTrackColour(hdcMem,dat);
+ if(ht->IGNORED == 0)
+ SetTextColor(hdcMem, ht->TEXTCOLOR);
+ if(!g_hottrack_done) {
+ if (ht->IGNORED == 0) {
+ DrawAlpha(hdcMem, &rc, ht->COLOR, ht->ALPHA, ht->COLOR2, ht->COLOR2_TRANSPARENT, ht->GRADIENT,
+ ht->CORNER, ht->BORDERSTYLE, ht->imageItem);
+ }
+ }
+ }
+
+ if(g_RTL)
+ API::pfnSetLayout(hdcMem, LAYOUT_RTL | LAYOUT_BITMAPORIENTATIONPRESERVED);
+bgskipped:
+
+ rcContent.top = y + g_padding_y;
+ rcContent.bottom = y + rowHeight - (2 * g_padding_y);
+ rcContent.left = leftX;
+ rcContent.right = clRect->right - dat->rightMargin;
+ twoRows = ((dat->fontInfo[FONTID_STATUS].fontHeight + fontHeight <= rowHeight + 1) && (contact->bSecondLine != MULTIROW_NEVER)) && !dat->bisEmbedded;
+
+ pi_avatar = !dat->bisEmbedded && type == CLCIT_CONTACT && (contact->cFlags & ECF_AVATAR) && contact->ace != 0 && !(contact->ace->dwFlags & AVS_HIDEONCLIST);
+
+ //checkboxes
+ if (checkboxWidth) {
+ RECT rc;
+ HANDLE hTheme = 0;
+
+ if (IS_THEMED)
+ hTheme = API::pfnOpenThemeData(hwnd, L"BUTTON");
+
+ rc.left = leftX;
+ rc.right = rc.left + dat->checkboxSize;
+ rc.top = y + ((rowHeight - dat->checkboxSize) >> 1);
+ rc.bottom = rc.top + dat->checkboxSize;
+ if (hTheme) {
+ API::pfnDrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, flags & CONTACTF_CHECKED ? (g_hottrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : (g_hottrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL), &rc, &rc);
+ API::pfnCloseThemeData(hTheme);
+ hTheme = 0;
+ }
+ else
+ DrawFrameControl(hdcMem, &rc, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT | (flags & CONTACTF_CHECKED ? DFCS_CHECKED : 0) | (g_hottrack ? DFCS_HOT : 0));
+ rcContent.left += checkboxWidth;
+ leftX += checkboxWidth;
+ }
+
+ if (type == CLCIT_GROUP)
+ iImage = (contact->group->expanded) ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT;
+ else if (type == CLCIT_CONTACT)
+ iImage = contact->iImage;
+
+
+ if(pi_avatar && (av_left || av_right)) {
+ RECT rc;
+
+ rc.left = rcContent.left;
+ rc.right = clRect->right;
+ rc.top = y;
+ rc.bottom = rc.top + rowHeight;
+
+ if(av_left) {
+ leftOffset += DrawAvatar(hdcMem, &rc, contact, y, dat, (WORD)(iImage ? cstatus : 0), rowHeight, cEntry->dwDFlags);
+ rcContent.left += leftOffset;
+ leftX += leftOffset;
+ }
+ else {
+ rc.left = (rcContent.right - cfg::dat.avatarSize) + 1;
+ rightOffset += DrawAvatar(hdcMem, &rc, contact, y, dat, (WORD)(iImage ? cstatus : 0), rowHeight, cEntry->dwDFlags);
+ rcContent.right -= (rightOffset);
+ }
+ }
+ else if(type == CLCIT_CONTACT && !dat->bisEmbedded && !g_selectiveIcon && (dwFlags & CLUI_FRAME_ALWAYSALIGNNICK) && av_local_wanted && (av_left || av_right)) {
+ if(av_right)
+ rcContent.right -= (cfg::dat.avatarSize + 2);
+ if(av_left)
+ rcContent.left += (cfg::dat.avatarSize + 2);
+ }
+ //icon
+
+ // skip icon for groups if the option is enabled...
+
+ if(type == CLCIT_GROUP && dwFlags & CLUI_FRAME_NOGROUPICON) {
+ iconXSpace = 0;
+ goto text;
+ }
+ if (iImage != -1) {
+ // this doesnt use CLS_CONTACTLIST since the colour prolly wont match anyway
+ COLORREF colourFg = dat->selBkColour;
+ //int clientId = contact->clientId;
+ int mode = ILD_NORMAL;
+ pi_selectiveIcon = g_selectiveIcon && (type == CLCIT_CONTACT);
+
+ if((dwFlags & CLUI_FRAME_STATUSICONS && !pi_selectiveIcon) || type != CLCIT_CONTACT || (pi_selectiveIcon && !avatar_done)) {
+ HIMAGELIST hImgList = 0;
+ if(!dat->bisEmbedded && type == CLCIT_CONTACT && cEntry && (dwFlags & CLUI_FRAME_USEXSTATUSASSTATUS) && cEntry->iExtraImage[EXTRA_ICON_ADV1] != 0xff) {
+ if(pcli->pfnIconFromStatusMode(contact->proto, contact->wStatus, contact->hContact) == iImage) {
+ hImgList = dat->himlExtraColumns;
+ iImage = cEntry->iExtraImage[EXTRA_ICON_ADV1];
+ }
+ else hImgList = hCListImages;
+ }
+ else
+ hImgList = hCListImages;
+
+ if (g_hottrack) {
+ colourFg = dat->hotTextColour;
+ } else if (type == CLCIT_CONTACT && flags & CONTACTF_NOTONLIST) {
+ colourFg = dat->fontInfo[FONTID_NOTONLIST].colour;
+ mode = ILD_BLEND50;
+ }
+ if (type == CLCIT_CONTACT && dat->showIdle && (flags & CONTACTF_IDLE) && contact->wStatus != ID_STATUS_OFFLINE)
+ mode = ILD_SELECTED;
+
+ if(pi_selectiveIcon && av_right) {
+ ImageList_DrawEx(hImgList, iImage, hdcMem, rcContent.right - 18, (twoRows && type == CLCIT_CONTACT && !cfg::dat.bCenterStatusIcons) ? y + 2 : y + ((rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode);
+ rcContent.right -= 18;
+ }
+ else {
+ LONG offset = 0;
+ BOOL centered = FALSE;
+ offset += (type != CLCIT_CONTACT || avatar_done || !(av_local_wanted) ? 20 : dwFlags & CLUI_FRAME_ALWAYSALIGNNICK && av_left && g_selectiveIcon ? cfg::dat.avatarSize + 2 : 20);
+ centered = (cfg::dat.bCenterStatusIcons && offset == cfg::dat.avatarSize + 2);
+ ImageList_DrawEx(hImgList, iImage, hdcMem, centered ? rcContent.left + offset / 2 - 10 : rcContent.left, (twoRows && type == CLCIT_CONTACT && !cfg::dat.bCenterStatusIcons) ? y + 2 : y + ((rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode);
+ rcContent.left += offset;
+ }
+ }
+ else
+ iconXSpace = 0;
+ if (type == CLCIT_CONTACT && !dat->bisEmbedded) {
+ BYTE bApparentModeDontCare = !((flags & CONTACTF_VISTO) ^ (flags & CONTACTF_INVISTO));
+ contact->extraIconRightBegin = 0;
+ if(cEntry && (contact->extraCacheEntry >= 0 && contact->extraCacheEntry < cfg::nextCacheEntry && cEntry->iExtraValid)) {
+ int i, iIndex, id;
+ DWORD dwOldMask = cEntry->dwXMask;
+ if(dwFlags & CLUI_FRAME_USEXSTATUSASSTATUS)
+ cEntry->dwXMask &= ~EIMG_SHOW_ADV1;
+
+ for(i = EXICON_COUNT - 1; i >= 0; i--) {
+ iIndex = cfg::dat.exIconOrder[i] - 1;
+ if(iIndex >= 0 && iIndex < EXICON_COUNT) {
+ id = OrderTreeData[iIndex].ID;
+ if(cEntry->iExtraImage[id] != 0xff && ((1 << id) & cEntry->dwXMask)) {
+ if(contact->extraIconRightBegin == 0 && i != (EXICON_COUNT - 1))
+ contact->extraIconRightBegin = rcContent.right;
+ ImageList_DrawEx(dat->himlExtraColumns, cEntry->iExtraImage[id], hdcMem, rcContent.right - cfg::dat.exIconScale, twoRows ? rcContent.bottom - g_exIconSpacing : y + ((rowHeight - cfg::dat.exIconScale) >> 1),
+ 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rcContent.right -= g_exIconSpacing;
+ rightIcons++;
+ }
+ }
+ }
+ cEntry->dwXMask = dwOldMask;
+ }
+ if (!bApparentModeDontCare && (dwFlags & CLUI_SHOWVISI) && contact->proto) {
+ BOOL fVisi;
+
+ if(dwFlags & CLUI_SHOWVISI)
+ fVisi = cEntry->dwDFlags & ECF_HIDEVISIBILITY ? 0 : 1;
+ else
+ fVisi = cEntry->dwDFlags & ECF_FORCEVISIBILITY ? 1 : 0;
+
+ if(fVisi) {
+ if(cEntry->isChatRoom)
+ DrawIconEx(hdcMem, rcContent.right - cfg::dat.exIconScale, twoRows ? rcContent.bottom - g_exIconSpacing : y + ((rowHeight - cfg::dat.exIconScale) >> 1),
+ cfg::dat.hIconChatactive, cfg::dat.exIconScale, cfg::dat.exIconScale, 0, 0, DI_NORMAL | DI_COMPAT);
+ else
+ DrawIconEx(hdcMem, rcContent.right - cfg::dat.exIconScale, twoRows ? rcContent.bottom - g_exIconSpacing : y + ((rowHeight - cfg::dat.exIconScale) >> 1),
+ flags & CONTACTF_VISTO ? cfg::dat.hIconVisible : cfg::dat.hIconInvisible, cfg::dat.exIconScale, cfg::dat.exIconScale, 0, 0, DI_NORMAL | DI_COMPAT);
+ rcContent.right -= g_exIconSpacing;
+ rightIcons++;
+ }
+ }
+ }
+ }
+ //text
+text:
+ if (type == CLCIT_DIVIDER) {
+ RECT rc;
+ rc.top = y + ((rowHeight) >> 1); rc.bottom = rc.top + 2;
+ rc.left = rcContent.left;
+ rc.right = rc.left - dat->rightMargin + ((clRect->right - rc.left - textSize.cx) >> 1) - 3;
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ TextOut(hdcMem, rc.right + 3, y + ((rowHeight - fontHeight) >> 1), contact->szText, lstrlen(contact->szText));
+ rc.left = rc.right + 6 + textSize.cx;
+ rc.right = clRect->right - dat->rightMargin;
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ } else if (type == CLCIT_GROUP) {
+ RECT rc;
+ int leftMargin = 0, countStart = 0, leftLineEnd, rightLineStart;
+ fontHeight = dat->fontInfo[FONTID_GROUPS].fontHeight;
+ rc.top = y + ((rowHeight - fontHeight) >> 1) + cfg::dat.group_padding;
+ rc.bottom = rc.top + textSize.cy;
+ if (szCounts[0]) {
+ int required, labelWidth, offset = 0;
+ int height = 0;
+ COLORREF clr = GetTextColor(hdcMem);
+
+ ChangeToFont(hdcMem, dat, FONTID_GROUPCOUNTS, &height);
+ if(oldGroupColor != -1)
+ SetTextColor(hdcMem, clr);
+
+ rc.left = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + iconXSpace;
+ rc.right = clRect->right - dat->rightMargin;
+
+ if(indent == 0 && iconXSpace == 0)
+ rc.left += 2;
+
+ required = textSize.cx + countsSize.cx + spaceSize.cx;
+
+ if(required > rc.right - rc.left)
+ textSize.cx = (rc.right - rc.left) - countsSize.cx - spaceSize.cx;
+
+ labelWidth = textSize.cx + countsSize.cx + spaceSize.cx;
+ if(g_center)
+ offset = ((rc.right - rc.left) - labelWidth) / 2;
+
+
+ TextOutA(hdcMem, rc.left + offset + textSize.cx + spaceSize.cx, rc.top + groupCountsFontTopShift, szCounts, lstrlenA(szCounts));
+ rightLineStart = rc.left + offset + textSize.cx + spaceSize.cx + countsSize.cx + 2;
+
+ if (selected && !g_ignoreselforgroups)
+ SetTextColor(hdcMem, dat->selTextColour);
+ else
+ SetTextColor(hdcMem, clr);
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &height);
+ SetTextColor(hdcMem, clr);
+ rc.left += offset;
+ rc.right = rc.left + textSize.cx;
+ leftLineEnd = rc.left - 2;
+ qLeft = rc.left;
+ DrawText(hdcMem, contact->szText, -1, &rc, DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS);
+ } else if (g_center && !szCounts[0]) {
+ int offset;
+
+ rc.left = rcContent.left;
+ rc.right = clRect->right - dat->rightMargin;
+ if(textSize.cx >= rc.right - rc.left)
+ textSize.cx = rc.right - rc.left;
+
+ offset = ((rc.right - rc.left) - textSize.cx) / 2;
+ rc.left += offset;
+ rc.right = rc.left + textSize.cx;
+ leftLineEnd = rc.left - 2;
+ rightLineStart = rc.right + 2;
+ DrawText(hdcMem, contact->szText, -1, &rc, DT_CENTER | DT_NOPREFIX | DT_SINGLELINE);
+ qLeft = rc.left;
+ } else {
+ qLeft = rcContent.left + (indent == 0 && iconXSpace == 0 ? 2 : 0);;
+ rc.left = qLeft;
+ rc.right = min(rc.left + textSize.cx, clRect->right - dat->rightMargin);;
+ DrawText(hdcMem, contact->szText, -1, &rc, DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS);
+ rightLineStart = qLeft + textSize.cx + 2;
+ }
+
+ if (dat->exStyle & CLS_EX_LINEWITHGROUPS) {
+ if(!g_center) {
+ rc.top = y + ((rowHeight) >> 1); rc.bottom = rc.top + 2;
+ rc.left = rightLineStart;
+ rc.right = clRect->right - 1 - dat->extraColumnSpacing * dat->extraColumnsCount - dat->rightMargin;
+ if (rc.right - rc.left > 1)
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
+ else {
+ rc.top = y + ((rowHeight) >> 1); rc.bottom = rc.top + 2;
+ rc.left = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + iconXSpace;
+ rc.right = leftLineEnd;
+ if (rc.right > rc.left)
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ rc.right = clRect->right - dat->rightMargin;
+ rc.left = rightLineStart;
+ if (rc.right > rc.left)
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
+ }
+ } else {
+ TCHAR *szText = contact->szText;
+
+ rcContent.top = y + ((rowHeight - fontHeight) >> 1);
+
+ // avatar
+
+ if(!dat->bisEmbedded) {
+ if(av_local_wanted && !avatar_done && pi_avatar) {
+ if(av_rightwithnick) {
+ RECT rcAvatar = rcContent;
+
+ rcAvatar.left = rcContent.right - (cfg::dat.avatarSize - 1);
+ DrawAvatar(hdcMem, &rcAvatar, contact, y, dat, (WORD)(iImage ? cstatus : 0), rowHeight, cEntry->dwDFlags);
+ rcContent.right -= (cfg::dat.avatarSize + 2);
+ }
+ else
+ rcContent.left += DrawAvatar(hdcMem, &rcContent, contact, y, dat, (WORD)(iImage ? cstatus : 0), rowHeight, cEntry->dwDFlags);
+ }
+ else if(dwFlags & CLUI_FRAME_ALWAYSALIGNNICK && !avatar_done && av_local_wanted)
+ rcContent.left += (dwFlags & (CLUI_FRAME_AVATARSLEFT | CLUI_FRAME_AVATARSRIGHT | CLUI_FRAME_AVATARSRIGHTWITHNICK) ? 0 : cfg::dat.avatarSize + 2);
+ }
+
+ // nickname
+ if(!twoRows) {
+ if(dt_nickflags)
+ DrawText(hdcMem, szText, -1, &rcContent, DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS | DT_SINGLELINE | dt_nickflags);
+ else
+ DrawText(hdcMem, szText, -1, &rcContent, DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS | DT_SINGLELINE);
+ }
+ else {
+ int statusFontHeight;
+ DWORD dtFlags = DT_WORD_ELLIPSIS | DT_NOPREFIX | DT_NOCLIP | DT_SINGLELINE;
+ DWORD saved_right = rcContent.right;
+ BOOL verticalfit = FALSE;
+
+ rcContent.top = y + cfg::dat.avatarPadding / 2;
+
+ if(cfg::dat.bShowLocalTime)
+ fLocalTime = cEntry->dwDFlags & ECF_HIDELOCALTIME ? 0 : 1;
+ else
+ fLocalTime = cEntry->dwDFlags & ECF_FORCELOCALTIME ? 1 : 0;
+
+ if (cEntry->hTimeZone && fLocalTime) {
+ int idOldFont;
+ DWORD now = cfg::dat.t_now;
+ SIZE szTime;
+ RECT rc = rcContent;
+ COLORREF oldColor;
+ int fHeight = 0;
+
+
+ TCHAR szResult[80];
+ if (tmi.printDateTime(cEntry->hTimeZone, _T("t"), szResult, SIZEOF(szResult), 0))
+ goto nodisplay;
+
+ oldColor = GetTextColor(hdcMem);
+ idOldFont = dat->currentFontID;
+ ChangeToFont(hdcMem, dat, FONTID_TIMESTAMP, &fHeight);
+ GetTextExtentPoint32(hdcMem, szResult, lstrlen(szResult), &szTime);
+ verticalfit = (rowHeight - fHeight >= cfg::dat.exIconScale + 1);
+
+ if(av_right) {
+ if(verticalfit)
+ rc.left = rcContent.right + (rightIcons * g_exIconSpacing) - szTime.cx - 2;
+ else
+ rc.left = rcContent.right - szTime.cx - 2;
+ }
+ else if(av_rightwithnick) {
+ if(verticalfit && rightIcons * g_exIconSpacing >= szTime.cx)
+ rc.left = clRect->right - dat->rightMargin - szTime.cx;
+ else if(verticalfit && !avatar_done)
+ rc.left = clRect->right - dat->rightMargin - szTime.cx;
+ else {
+ rc.left = rcContent.right - szTime.cx - 2;
+ rcContent.right = rc.left - 2;
+ }
+ }
+ else {
+ if(verticalfit)
+ rc.left = clRect->right - dat->rightMargin - szTime.cx;
+ else
+ rc.left = rcContent.right - szTime.cx - 2;
+ }
+ DrawText(hdcMem, szResult, -1, &rc, DT_NOPREFIX | DT_NOCLIP | DT_SINGLELINE);
+ ChangeToFont(hdcMem, dat, idOldFont, 0);
+ SetTextColor(hdcMem, oldColor);
+
+ verticalfit = (rowHeight - fontHeight >= cfg::dat.exIconScale + 1);
+ if(verticalfit && av_right)
+ rcContent.right = min(clRect->right - cfg::dat.avatarSize - 2, rc.left - 2);
+ else if(verticalfit && !av_rightwithnick)
+ rcContent.right = min(clRect->right - dat->rightMargin, rc.left - 3);
+ }
+ else {
+nodisplay:
+ verticalfit = (rowHeight - fontHeight >= cfg::dat.exIconScale + 1);
+ if(avatar_done) {
+ if(verticalfit && av_right)
+ rcContent.right = clRect->right - cfg::dat.avatarSize - 2;
+ else if(verticalfit && !av_rightwithnick)
+ rcContent.right = clRect->right - dat->rightMargin;
+ }
+ }
+ DrawText(hdcMem, szText, -1, &rcContent, DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS | DT_SINGLELINE | dt_nickflags);
+
+ rcContent.right = saved_right;
+ rcContent.top += (fontHeight - 1);
+ hPreviousFont = ChangeToFont(hdcMem, dat, FONTID_STATUS, &statusFontHeight);
+ //if(selected)
+ // SetTextColor(hdcMem, dat->selTextColour);
+ rcContent.bottom = y + rowHeight;
+
+ if(cstatus >= ID_STATUS_OFFLINE && cstatus <= ID_STATUS_OUTTOLUNCH) {
+ TCHAR *szText = NULL;
+ BYTE smsgValid = cEntry->bStatusMsgValid;
+
+ if((dwFlags & CLUI_FRAME_SHOWSTATUSMSG && smsgValid > STATUSMSG_XSTATUSID) || smsgValid == STATUSMSG_XSTATUSNAME)
+ szText = cEntry->statusMsg;
+ else
+#if defined(_UNICODE)
+ szText = &statusNames[cstatus - ID_STATUS_OFFLINE][0];
+#else
+ szText = statusNames[cstatus - ID_STATUS_OFFLINE];
+#endif
+ if(cEntry->dwCFlags & ECF_RTLSTATUSMSG && cfg::dat.bUseDCMirroring == 3)
+ dt_2ndrowflags |= (DT_RTLREADING | DT_RIGHT);
+
+ if(rightIcons == 0) {
+ if((rcContent.bottom - rcContent.top) >= (2 * statusFontHeight)) {
+ dtFlags &= ~(DT_SINGLELINE | DT_BOTTOM | DT_NOCLIP);
+ dtFlags |= DT_WORDBREAK;
+ rcContent.bottom -= ((rcContent.bottom - rcContent.top) % statusFontHeight);
+ }
+ DrawText(hdcMem, szText, -1, &rcContent, dtFlags | dt_2ndrowflags);
+ }
+ else {
+ if((rcContent.bottom - rcContent.top) < (2 * statusFontHeight) - 2)
+ DrawText(hdcMem, szText, -1, &rcContent, dtFlags | dt_2ndrowflags);
+ else {
+ DRAWTEXTPARAMS dtp = {0};
+ LONG rightIconsTop = rcContent.bottom - g_exIconSpacing;
+ LONG old_right = rcContent.right;
+ ULONG textCounter = 0;
+ ULONG ulLen = lstrlen(szText);
+ LONG old_bottom = rcContent.bottom;
+ DWORD i_dtFlags = DT_WORDBREAK | DT_NOPREFIX | dt_2ndrowflags;
+ dtp.cbSize = sizeof(dtp);
+ rcContent.right = clRect->right - dat->rightMargin - rightOffset;
+ do {
+ if(rcContent.top + (statusFontHeight - 1) > rightIconsTop + 1)
+ rcContent.right = old_right;
+ dtp.uiLengthDrawn = 0;
+ rcContent.bottom = rcContent.top + statusFontHeight - 1;
+ if(rcContent.bottom + statusFontHeight >= old_bottom)
+ i_dtFlags |= DT_END_ELLIPSIS;
+ DrawTextEx(hdcMem, &szText[textCounter], -1, &rcContent, i_dtFlags, &dtp);
+ rcContent.top += statusFontHeight;
+ textCounter += dtp.uiLengthDrawn;
+ } while (textCounter <= ulLen && dtp.uiLengthDrawn && rcContent.top + statusFontHeight <= old_bottom);
+ }
+ }
+ }
+ }
+ }
+ if (selected) {
+ if (type != CLCIT_DIVIDER) {
+ TCHAR *szText = contact->szText;
+ RECT rc;
+ int qlen = lstrlen(dat->szQuickSearch);
+ if(hPreviousFont)
+ SelectObject(hdcMem, hPreviousFont);
+ SetTextColor(hdcMem, dat->quickSearchColour);
+ if(type == CLCIT_CONTACT) {
+ rc.left = rcContent.left;
+ rc.top = y + ((rowHeight - fontHeight) >> 1);
+ rc.right = clRect->right - rightOffset;
+ rc.right = rcContent.right;
+ rc.bottom = rc.top;
+ if(twoRows)
+ rc.top = y;
+ }
+ else {
+ rc.left = qLeft;
+ rc.top = y + ((rowHeight - fontHeight) >> 1);
+ rc.right = clRect->right - rightOffset;
+ rc.bottom = rc.top;
+ }
+ if (qlen)
+ DrawText(hdcMem, szText, qlen, &rc, DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS | DT_SINGLELINE);
+ }
+ }
+ //extra icons
+ for (iImage = 0; iImage< dat->extraColumnsCount; iImage++) {
+ COLORREF colourFg = dat->selBkColour;
+ int mode = ILD_NORMAL;
+ if (contact->iExtraImage[iImage] == 0xFF)
+ continue;
+ if (selected)
+ mode = ILD_SELECTED;
+ else if (g_hottrack) {
+ mode = ILD_FOCUS; colourFg = dat->hotTextColour;
+ } else if (type == CLCIT_CONTACT && flags & CONTACTF_NOTONLIST) {
+ colourFg = dat->fontInfo[FONTID_NOTONLIST].colour; mode = ILD_BLEND50;
+ }
+ ImageList_DrawEx(dat->himlExtraColumns, contact->iExtraImage[iImage], hdcMem, clRect->right - rightOffset - dat->extraColumnSpacing * (dat->extraColumnsCount - iImage), y + ((rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode);
+ }
+ if(g_RTL)
+ API::pfnSetLayout(hdcMem, 0);
+}
+
+void SkinDrawBg(HWND hwnd, HDC hdc)
+{
+ RECT rcCl;
+ POINT ptTest = {0};
+
+ ClientToScreen(hwnd, &ptTest);
+ GetClientRect(hwnd, &rcCl);
+
+ BitBlt(hdc, 0, 0, rcCl.right - rcCl.left, rcCl.bottom - rcCl.top, cfg::dat.hdcBg, ptTest.x - cfg::dat.ptW.x, ptTest.y - cfg::dat.ptW.y, SRCCOPY);
+}
+
+void PaintClc(HWND hwnd, struct ClcData *dat, HDC hdc, RECT *rcPaint)
+{
+ HDC hdcMem;
+ RECT clRect;
+ int y,indent,index,fontHeight;
+ struct ClcGroup *group;
+ HBITMAP hBmpOsb, hOldBitmap;
+ HFONT hOldFont;
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ int grey = 0,groupCountsFontTopShift;
+ BOOL bFirstNGdrawn = FALSE;
+ int line_num = -1;
+ COLORREF tmpbkcolour = style & CLS_CONTACTLIST ? (dat->useWindowsColours ? GetSysColor(COLOR_3DFACE) : dat->bkColour) : dat->bkColour;
+ DWORD done, now = GetTickCount();
+ selBlend = cfg::getByte("CLCExt", "EXBK_SelBlend", 1);
+ g_inCLCpaint = TRUE;
+ g_focusWnd = GetFocus();
+ my_status = GetGeneralisedStatus();
+ g_HDC = hdc;
+
+ /*
+ * temporary DC for avatar drawing
+ */
+
+ g_padding_y = 0;
+
+ hdcTempAV = CreateCompatibleDC(g_HDC);
+ hdcAV = CreateCompatibleDC(g_HDC);
+ hbmTempAV = CreateCompatibleBitmap(g_HDC, g_maxAV_X, g_maxAV_Y);
+ hbmTempOldAV = reinterpret_cast<HBITMAP>(SelectObject(hdcTempAV, hbmTempAV));
+
+ cfg::dat.t_now = time(NULL);
+ GetSystemTime(&cfg::dat.st);
+ SystemTimeToFileTime(&cfg::dat.st, &cfg::dat.ft);
+
+ cfg::dat.bUseFastGradients = cfg::dat.bWantFastGradients && (API::pfnGradientFill != 0);
+
+ av_left = (cfg::dat.dwFlags & CLUI_FRAME_AVATARSLEFT);
+ av_right = (cfg::dat.dwFlags & CLUI_FRAME_AVATARSRIGHT);
+ av_rightwithnick = (cfg::dat.dwFlags & CLUI_FRAME_AVATARSRIGHTWITHNICK);
+
+ mirror_rtl = (cfg::dat.bUseDCMirroring == 2);
+ mirror_always = (cfg::dat.bUseDCMirroring == 1);
+ mirror_rtltext = (cfg::dat.bUseDCMirroring == 3);
+
+ g_center = cfg::getByte("CLCExt", "EXBK_CenterGroupnames", 0) && !dat->bisEmbedded;
+ g_ignoreselforgroups = cfg::getByte("CLC", "IgnoreSelforGroups", 0);
+ g_exIconSpacing = cfg::dat.exIconScale + 2;
+
+ if (dat->greyoutFlags & pcli->pfnClcStatusToPf2(my_status) || style & WS_DISABLED)
+ grey = 1;
+ else if (GetFocus() != hwnd && dat->greyoutFlags & GREYF_UNFOCUS)
+ grey = 1;
+ GetClientRect(hwnd, &clRect);
+ if (rcPaint == NULL)
+ rcPaint = &clRect;
+ if (IsRectEmpty(rcPaint)) {
+ SelectObject(hdcTempAV, hbmTempOldAV);
+ DeleteObject(hbmTempAV);
+ DeleteDC(hdcTempAV);
+
+ DeleteDC(hdcAV);
+ return;
+ }
+ y = -dat->yScroll;
+ hdcMem = CreateCompatibleDC(hdc);
+ hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
+
+ hOldBitmap = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, hBmpOsb));
+ {
+ TEXTMETRIC tm;
+ hOldFont = reinterpret_cast<HFONT>(SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPS].hFont));
+ GetTextMetrics(hdcMem, &tm);
+ groupCountsFontTopShift = tm.tmAscent;
+ SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPCOUNTS].hFont);
+ GetTextMetrics(hdcMem, &tm);
+ groupCountsFontTopShift -= tm.tmAscent;
+ }
+ ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
+
+ SetBkMode(hdcMem, TRANSPARENT); {
+ HBRUSH hBrush, hoBrush;
+
+ hBrush = CreateSolidBrush(tmpbkcolour);
+ hoBrush = (HBRUSH) SelectObject(hdcMem, hBrush);
+ FillRect(hdcMem, rcPaint, hBrush);
+
+ SelectObject(hdcMem, hoBrush);
+ DeleteObject(hBrush);
+
+ if(1) {
+ if(cfg::dat.bWallpaperMode && !dat->bisEmbedded) {
+ SkinDrawBg(hwnd, hdcMem);
+ goto bgdone;
+ }
+ if (dat->hBmpBackground) {
+ BITMAP bmp;
+ HDC hdcBmp;
+ int x, y;
+ int bitx, bity;
+ int maxx, maxy;
+ int destw, desth;
+ // XXX: Halftone isnt supported on 9x, however the scretch problems dont happen on 98.
+ SetStretchBltMode(hdcMem, HALFTONE);
+
+ GetObject(dat->hBmpBackground, sizeof(bmp), &bmp);
+ hdcBmp = CreateCompatibleDC(hdcMem);
+ SelectObject(hdcBmp, dat->hBmpBackground);
+ y = dat->backgroundBmpUse & CLBF_SCROLL ? -dat->yScroll : 0;
+ maxx = dat->backgroundBmpUse & CLBF_TILEH ? clRect.right : 1;
+ maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rcPaint->bottom : y + 1;
+ switch (dat->backgroundBmpUse & CLBM_TYPE) {
+ case CLB_STRETCH:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) {
+ desth = clRect.bottom;
+ destw = desth * bmp.bmWidth / bmp.bmHeight;
+ } else {
+ destw = clRect.right;
+ desth = destw * bmp.bmHeight / bmp.bmWidth;
+ }
+ } else {
+ destw = clRect.right;
+ desth = clRect.bottom;
+ }
+ break;
+ case CLB_STRETCHH:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ destw = clRect.right;
+ desth = destw * bmp.bmHeight / bmp.bmWidth;
+ } else {
+ destw = clRect.right;
+ desth = bmp.bmHeight;
+ }
+ break;
+ case CLB_STRETCHV:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ desth = clRect.bottom;
+ destw = desth * bmp.bmWidth / bmp.bmHeight;
+ } else {
+ destw = bmp.bmWidth;
+ desth = clRect.bottom;
+ }
+ break;
+ default:
+ //clb_topleft
+ destw = bmp.bmWidth;
+ desth = bmp.bmHeight;
+ break;
+ }
+
+ bitx = 0;
+ bity = 0;
+
+ for (; y < maxy; y += desth) {
+ if (y< rcPaint->top - desth)
+ continue;
+ for (x = 0; x < maxx; x += destw) {
+ StretchBlt(hdcMem, x, y, destw, desth, cfg::dat.hdcPic, bitx, bity, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
+ }
+ }
+ DeleteDC(hdcBmp);
+ }
+ }
+ }
+bgdone:
+ group = &dat->list;
+ group->scanIndex = 0;
+
+ if ( dat->row_heights == NULL )
+ RowHeight::calcRowHeights(dat, hwnd);
+
+ group = &dat->list;
+ group->scanIndex = 0;
+
+ g_list_avatars = 0;
+ while(TRUE)
+ {
+ if (group->scanIndex==group->cl.count)
+ {
+ group=group->parent;
+ if(group==NULL) break; // Finished list
+ group->scanIndex++;
+ continue;
+ }
+
+ if(group->cl.items[group->scanIndex]->cFlags & ECF_AVATAR)
+ g_list_avatars++;
+
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP && (group->cl.items[group->scanIndex]->group->expanded)) {
+ group=group->cl.items[group->scanIndex]->group;
+ group->scanIndex=0;
+ continue;
+ }
+ group->scanIndex++;
+ }
+ g_selectiveIcon = (g_list_avatars > 0) && (cfg::dat.dwFlags & CLUI_FRAME_SELECTIVEICONS) && !dat->bisEmbedded;
+
+ group = &dat->list;
+ group->scanIndex = 0;
+ indent = 0;
+
+ for (index = 0; y< rcPaint->bottom;) {
+ if (group->scanIndex == group->cl.count) {
+ group = group->parent;
+ indent--;
+ if (group == NULL) {
+ break;
+ }
+ group->scanIndex++;
+ continue;
+ }
+
+ line_num++;
+ if(cfg::dat.bForceRefetchOnPaint)
+ group->cl.items[group->scanIndex]->ace = (struct avatarCacheEntry*)-1;
+
+ if (y > rcPaint->top - dat->row_heights[line_num] && y <= rcPaint->bottom) {
+ if (group->cl.items[group->scanIndex]->ace == (struct avatarCacheEntry*)-1 )
+ group->cl.items[group->scanIndex]->ace = (struct avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)group->cl.items[group->scanIndex]->hContact, 0);
+ RowHeight::getRowHeight(dat, hwnd, group->cl.items[group->scanIndex], line_num, style);
+ PaintItem(hdcMem, group, group->cl.items[group->scanIndex], indent, y, dat, index, hwnd, style, &clRect, &bFirstNGdrawn, groupCountsFontTopShift, dat->row_heights[line_num]);
+ }
+ index++;
+ y += dat->row_heights[line_num];
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP && (group->cl.items[group->scanIndex]->group->expanded)) {
+ group = group->cl.items[group->scanIndex]->group;
+ indent++;
+ group->scanIndex = 0;
+ continue;
+ }
+ group->scanIndex++;
+ }
+
+ SelectObject(hdcTempAV, hbmTempOldAV);
+ DeleteObject(hbmTempAV);
+ DeleteDC(hdcTempAV);
+
+ DeleteDC(hdcAV);
+
+ if (dat->iInsertionMark != -1) {
+ //insertion mark
+ HBRUSH hBrush, hoBrush;
+ POINT pts[8];
+ HRGN hRgn;
+
+ pts[0].x=dat->leftMargin; pts[0].y = RowHeight::getItemTopY(dat, dat->iInsertionMark) - dat->yScroll - 4;
+ //pts[0]. x = dat->leftMargin; pts[0]. y = dat->iInsertionMark * rowHeight - dat->yScroll - 4;
+ pts[1]. x = pts[0].x + 2; pts[1]. y = pts[0].y + 3;
+ pts[2]. x = clRect.right - 4; pts[2]. y = pts[1].y;
+ pts[3]. x = clRect.right - 1; pts[3]. y = pts[0].y - 1;
+ pts[4]. x = pts[3].x; pts[4]. y = pts[0].y + 7;
+ pts[5]. x = pts[2].x + 1; pts[5]. y = pts[1].y + 2;
+ pts[6]. x = pts[1].x; pts[6]. y = pts[5].y;
+ pts[7]. x = pts[0].x; pts[7]. y = pts[4].y;
+ hRgn = CreatePolygonRgn(pts, sizeof(pts) / sizeof(pts[0]), ALTERNATE);
+ hBrush = CreateSolidBrush(dat->fontInfo[FONTID_CONTACTS].colour);
+ hoBrush = (HBRUSH) SelectObject(hdcMem, hBrush);
+ FillRgn(hdcMem, hRgn, hBrush);
+ SelectObject(hdcMem, hoBrush);
+ DeleteObject(hBrush);
+ }
+ if (!grey)
+ BitBlt(hdc, rcPaint->left, rcPaint->top, rcPaint->right - rcPaint->left, rcPaint->bottom - rcPaint->top, hdcMem, rcPaint->left, rcPaint->top, SRCCOPY);
+
+ SelectObject(hdcMem, hOldBitmap);
+ SelectObject(hdcMem, hOldFont);
+
+ DeleteDC(hdcMem);
+ if (grey) {
+ PBYTE bits;
+ BITMAPINFOHEADER bmih = {0};
+
+ int i;
+ int greyRed, greyGreen, greyBlue;
+ COLORREF greyColour;
+ bmih.biBitCount = 32;
+ bmih.biSize = sizeof(bmih);
+ bmih.biCompression = BI_RGB;
+ bmih.biHeight = -clRect.bottom;
+ bmih.biPlanes = 1;
+ bmih.biWidth = clRect.right;
+ bits = (PBYTE) mir_alloc(4 * bmih.biWidth * -bmih.biHeight);
+ GetDIBits(hdc, hBmpOsb, 0, clRect.bottom, bits, (BITMAPINFO *) &bmih, DIB_RGB_COLORS);
+ greyColour = GetSysColor(COLOR_3DFACE);
+ greyRed = GetRValue(greyColour) * 2;
+ greyGreen = GetGValue(greyColour) * 2;
+ greyBlue = GetBValue(greyColour) * 2;
+ if (divide3[0] == 255) {
+ for (i = 0; i < sizeof(divide3) / sizeof(divide3[0]); i++) {
+ divide3[i] = (i + 1) / 3;
+ }
+ }
+ for (i = 4 * clRect.right *clRect.bottom - 4; i >= 0; i -= 4) {
+ bits[i] = divide3[bits[i] + greyBlue];
+ bits[i + 1] = divide3[bits[i + 1] + greyGreen];
+ bits[i + 2] = divide3[bits[i + 2] + greyRed];
+ }
+ SetDIBitsToDevice(hdc, 0, 0, clRect.right, clRect.bottom, 0, 0, 0, clRect.bottom, bits, (BITMAPINFO *) &bmih, DIB_RGB_COLORS);
+ mir_free(bits);
+ }
+ DeleteObject(hBmpOsb);
+ g_inCLCpaint = FALSE;
+ done = GetTickCount();
+}
diff --git a/plugins/Clist_nicer/SRC/clcutils.cpp b/plugins/Clist_nicer/SRC/clcutils.cpp
new file mode 100644
index 0000000000..bec62044e9
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clcutils.cpp
@@ -0,0 +1,626 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include <commonheaders.h>
+#include <richedit.h>
+#include "../coolsb/coolscroll.h"
+
+#ifndef SPI_GETDESKWALLPAPER
+#define SPI_GETDESKWALLPAPER 115
+#endif
+//loads of stuff that didn't really fit anywhere else
+
+extern int /*g_isConnecting,*/ during_sizing;
+
+extern void ( *saveRecalcScrollBar )(HWND hwnd, struct ClcData *dat);
+
+static int MY_pathIsAbsolute(const TCHAR *path)
+{
+ if (!path || !(lstrlen(path) > 2))
+ return 0;
+ if ((path[1] == ':' && path[2] == '\\') || (path[0] == '\\' && path[1] == '\\'))
+ return 1;
+ return 0;
+}
+
+size_t MY_pathToRelative(const TCHAR *pSrc, TCHAR *pOut)
+{
+ if (!pSrc || !lstrlen(pSrc) || lstrlen(pSrc) > MAX_PATH)
+ return 0;
+ if (!MY_pathIsAbsolute(pSrc)) {
+ mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc);
+ return lstrlen(pOut);
+ } else {
+ TCHAR szTmp[MAX_PATH];
+ mir_sntprintf(szTmp, SIZEOF(szTmp), _T("%s"), pSrc);
+ _tcslwr(szTmp);
+ if (_tcsstr(szTmp, cfg::dat.tszProfilePath)) {
+ mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc + lstrlen(cfg::dat.tszProfilePath) - 1);
+ pOut[0]='.';
+ return lstrlen(pOut);
+ } else {
+ mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc);
+ return lstrlen(pOut);
+ }
+ }
+}
+
+size_t MY_pathToAbsolute(const TCHAR *pSrc, TCHAR *pOut)
+{
+ if (!pSrc || !lstrlen(pSrc) || lstrlen(pSrc) > MAX_PATH)
+ return 0;
+ if (MY_pathIsAbsolute(pSrc)&&pSrc[0]!='.')
+ mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc);
+ else if (pSrc[0]=='.')
+ mir_sntprintf(pOut, MAX_PATH, _T("%s\\%s"), cfg::dat.tszProfilePath, pSrc);
+
+ return lstrlen(pOut);
+}
+
+/*
+ * performs hit-testing for reversed (mirrored) contact rows when using RTL
+ * shares all the init stuff with HitTest()
+ */
+
+int RTL_HitTest(HWND hwnd, struct ClcData *dat, int testx, int testy, struct ClcContact *hitcontact, DWORD *flags, int indent, int hit)
+{
+ RECT clRect;
+ int right, checkboxWidth, cxSmIcon, i, width;
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ SIZE textSize;
+ HDC hdc;
+ HFONT hFont;
+
+ GetClientRect(hwnd, &clRect);
+ right = clRect.right;
+
+ // avatar check
+ if(hitcontact->type == CLCIT_CONTACT && cfg::dat.dwFlags & CLUI_FRAME_AVATARS && hitcontact->ace != NULL && hitcontact->avatarLeft != -1) {
+ if(testx < right - hitcontact->avatarLeft && testx > right - hitcontact->avatarLeft - cfg::dat.avatarSize) {
+ if(flags)
+ *flags |= CLCHT_ONAVATAR;
+ }
+ }
+ if (testx > right - (dat->leftMargin + indent * dat->groupIndent)) {
+ if (flags)
+ *flags |= CLCHT_ONITEMINDENT;
+ return hit;
+ }
+ checkboxWidth = 0;
+ if (style & CLS_CHECKBOXES && hitcontact->type == CLCIT_CONTACT)
+ checkboxWidth = dat->checkboxSize + 2;
+ if (style & CLS_GROUPCHECKBOXES && hitcontact->type == CLCIT_GROUP)
+ checkboxWidth = dat->checkboxSize + 2;
+ if (hitcontact->type == CLCIT_INFO && hitcontact->flags & CLCIIF_CHECKBOX)
+ checkboxWidth = dat->checkboxSize + 2;
+ if (testx > right - (dat->leftMargin + indent * dat->groupIndent + checkboxWidth)) {
+ if (flags)
+ *flags |= CLCHT_ONITEMCHECK;
+ return hit;
+ }
+ if (testx > right - (dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace)) {
+ if (flags)
+ *flags |= CLCHT_ONITEMICON;
+ return hit;
+ }
+ cxSmIcon = GetSystemMetrics(SM_CXSMICON);
+ for (i = 0; i< dat->extraColumnsCount; i++) {
+ if (hitcontact->iExtraImage[i] == 0xFF)
+ continue;
+ if (testx >= dat->extraColumnSpacing * (dat->extraColumnsCount - i) && testx < dat->extraColumnSpacing * (dat->extraColumnsCount - i) + cxSmIcon) {
+ if (flags)
+ *flags |= CLCHT_ONITEMEXTRA | (i << 24);
+ return hit;
+ }
+ }
+ if(hitcontact->extraCacheEntry >= 0 && hitcontact->extraCacheEntry < cfg::nextCacheEntry && cfg::eCache[hitcontact->extraCacheEntry].iExtraValid) {
+ int rightOffset = hitcontact->extraIconRightBegin;
+ int images_present = 0;
+
+ for (i = 5; i >= 0; i--) {
+ if (cfg::eCache[hitcontact->extraCacheEntry].iExtraImage[i] == 0xFF)
+ continue;
+ if(!((1 << i) & cfg::eCache[hitcontact->extraCacheEntry].dwXMask))
+ continue;
+ images_present++;
+ if (testx < right - (rightOffset - (cfg::dat.exIconScale + 2) * images_present) && testx > right - (rightOffset - (cfg::dat.exIconScale + 2) * images_present + (cfg::dat.exIconScale))) {
+ if (flags)
+ *flags |= (CLCHT_ONITEMEXTRAEX | ((i + 1) << 24));
+ return hit;
+ }
+ }
+ }
+
+ hdc = GetDC(hwnd);
+ if (hitcontact->type == CLCIT_GROUP)
+ hFont = reinterpret_cast<HFONT>(SelectObject(hdc, dat->fontInfo[FONTID_GROUPS].hFont));
+ else
+ hFont = reinterpret_cast<HFONT>(SelectObject(hdc, dat->fontInfo[FONTID_CONTACTS].hFont));
+ GetTextExtentPoint32(hdc, hitcontact->szText, lstrlen(hitcontact->szText), &textSize);
+ width = textSize.cx;
+ if (hitcontact->type == CLCIT_GROUP) {
+ char *szCounts;
+ szCounts = pcli->pfnGetGroupCountsText(dat, hitcontact);
+ if (szCounts[0]) {
+ GetTextExtentPoint32A(hdc, " ", 1, &textSize);
+ width += textSize.cx;
+ SelectObject(hdc, dat->fontInfo[FONTID_GROUPCOUNTS].hFont);
+ GetTextExtentPoint32A(hdc, szCounts, lstrlenA(szCounts), &textSize);
+ width += textSize.cx;
+ }
+ }
+ SelectObject(hdc, hFont);
+ ReleaseDC(hwnd, hdc);
+ if (testx > right - (dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 4 + (cfg::dat.dwFlags & CLUI_FRAME_AVATARS ? cfg::dat.avatarSize : 0))) {
+ if (flags)
+ *flags |= CLCHT_ONITEMLABEL;
+ return hit;
+ }
+ if (cfg::dat.dwFlags & CLUI_FULLROWSELECT && !(GetKeyState(VK_SHIFT) & 0x8000) && testx < right - (dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 4 + (cfg::dat.dwFlags & CLUI_FRAME_AVATARS ? cfg::dat.avatarSize : 0))) {
+ if (flags)
+ *flags |= CLCHT_ONITEMSPACE;
+ return hit;
+ }
+ if (flags)
+ *flags |= CLCHT_NOWHERE;
+ return -1;
+}
+
+int HitTest(HWND hwnd, struct ClcData *dat, int testx, int testy, struct ClcContact **contact, struct ClcGroup **group, DWORD *flags)
+{
+ struct ClcContact *hitcontact;
+ struct ClcGroup *hitgroup;
+ int hit, indent, width, i, cxSmIcon;
+ int checkboxWidth;
+ SIZE textSize;
+ HDC hdc;
+ RECT clRect;
+ HFONT hFont;
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ BYTE mirror_mode = cfg::dat.bUseDCMirroring;
+
+ if (flags)
+ *flags = 0;
+ GetClientRect(hwnd, &clRect);
+ if (testx < 0 || testy < 0 || testy >= clRect.bottom || testx >= clRect.right) {
+ if (flags) {
+ if (testx < 0)
+ *flags |= CLCHT_TOLEFT;
+ else if (testx >= clRect.right)
+ *flags |= CLCHT_TORIGHT;
+ if (testy < 0)
+ *flags |= CLCHT_ABOVE;
+ else if (testy >= clRect.bottom)
+ *flags |= CLCHT_BELOW;
+ }
+ return -1;
+ }
+ if (testx< dat->leftMargin) {
+ if (flags)
+ *flags |= CLCHT_INLEFTMARGIN | CLCHT_NOWHERE;
+ return -1;
+ }
+ hit = RowHeight::hitTest(dat, dat->yScroll + testy);
+ if (hit != -1)
+ hit = pcli->pfnGetRowByIndex(dat, hit, &hitcontact, &hitgroup);
+
+ if (hit == -1) {
+ if (flags)
+ *flags |= CLCHT_NOWHERE | CLCHT_BELOWITEMS;
+ return -1;
+ }
+ if (contact)
+ *contact = hitcontact;
+ if (group)
+ *group = hitgroup;
+
+ for (indent = 0; hitgroup->parent; indent++,hitgroup = hitgroup->parent) {
+ ;
+ }
+
+ if(!dat->bisEmbedded) {
+ if(hitcontact->type == CLCIT_CONTACT) {
+ if(mirror_mode == 1 || (mirror_mode == 2 && cfg::eCache[hitcontact->extraCacheEntry].dwCFlags & ECF_RTLNICK))
+ return RTL_HitTest(hwnd, dat, testx, testy, hitcontact, flags, indent, hit);
+ }
+ else if(hitcontact->type == CLCIT_GROUP) {
+ if(cfg::dat.bGroupAlign == CLC_GROUPALIGN_RIGHT || (hitcontact->isRtl && cfg::dat.bGroupAlign == CLC_GROUPALIGN_AUTO))
+ return RTL_HitTest(hwnd, dat, testx, testy, hitcontact, flags, indent, hit);
+ }
+ }
+
+ // avatar check
+ if(hitcontact->type == CLCIT_CONTACT && cfg::dat.dwFlags & CLUI_FRAME_AVATARS && hitcontact->ace != NULL && hitcontact->avatarLeft != -1) {
+ if(testx >hitcontact->avatarLeft && testx < hitcontact->avatarLeft + cfg::dat.avatarSize) {
+ if(flags)
+ *flags |= CLCHT_ONAVATAR;
+ }
+ }
+ if (testx< dat->leftMargin + indent * dat->groupIndent) {
+ if (flags)
+ *flags |= CLCHT_ONITEMINDENT;
+ return hit;
+ }
+ checkboxWidth = 0;
+ if (style & CLS_CHECKBOXES && hitcontact->type == CLCIT_CONTACT)
+ checkboxWidth = dat->checkboxSize + 2;
+ if (style & CLS_GROUPCHECKBOXES && hitcontact->type == CLCIT_GROUP)
+ checkboxWidth = dat->checkboxSize + 2;
+ if (hitcontact->type == CLCIT_INFO && hitcontact->flags & CLCIIF_CHECKBOX)
+ checkboxWidth = dat->checkboxSize + 2;
+ if (testx< dat->leftMargin + indent * dat->groupIndent + checkboxWidth) {
+ if (flags)
+ *flags |= CLCHT_ONITEMCHECK;
+ return hit;
+ }
+ if (testx< dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace) {
+ if (flags)
+ *flags |= CLCHT_ONITEMICON;
+ return hit;
+ }
+ cxSmIcon = GetSystemMetrics(SM_CXSMICON);
+ for (i = 0; i< dat->extraColumnsCount; i++) {
+ if (hitcontact->iExtraImage[i] == 0xFF)
+ continue;
+ if (testx >= clRect.right - dat->extraColumnSpacing * (dat->extraColumnsCount - i) && testx< clRect.right - dat->extraColumnSpacing * (dat->extraColumnsCount - i) + cxSmIcon) {
+ if (flags)
+ *flags |= CLCHT_ONITEMEXTRA | (i << 24);
+ return hit;
+ }
+ }
+ if(hitcontact->extraCacheEntry >= 0 && hitcontact->extraCacheEntry < cfg::nextCacheEntry && cfg::eCache[hitcontact->extraCacheEntry].iExtraValid) {
+ //int rightOffset = clRect.right;
+ int rightOffset = hitcontact->extraIconRightBegin;
+ int images_present = 0;
+
+ for (i = 5; i >= 0; i--) {
+ if (cfg::eCache[hitcontact->extraCacheEntry].iExtraImage[i] == 0xFF)
+ continue;
+ if(!((1 << i) & cfg::eCache[hitcontact->extraCacheEntry].dwXMask))
+ continue;
+ images_present++;
+ if (testx > (rightOffset - (cfg::dat.exIconScale + 2) * images_present) && testx < (rightOffset - (cfg::dat.exIconScale + 2) * images_present + (cfg::dat.exIconScale))) {
+ if (flags)
+ *flags |= (CLCHT_ONITEMEXTRAEX | ((i + 1) << 24));
+ return hit;
+ }
+ }
+ }
+ hdc = GetDC(hwnd);
+ if (hitcontact->type == CLCIT_GROUP)
+ hFont = reinterpret_cast<HFONT>(SelectObject(hdc, dat->fontInfo[FONTID_GROUPS].hFont));
+ else
+ hFont = reinterpret_cast<HFONT>(SelectObject(hdc, dat->fontInfo[FONTID_CONTACTS].hFont));
+ GetTextExtentPoint32(hdc, hitcontact->szText, lstrlen(hitcontact->szText), &textSize);
+ width = textSize.cx;
+ if (hitcontact->type == CLCIT_GROUP) {
+ char *szCounts;
+ szCounts = pcli->pfnGetGroupCountsText(dat, hitcontact);
+ if (szCounts[0]) {
+ GetTextExtentPoint32A(hdc, " ", 1, &textSize);
+ width += textSize.cx;
+ SelectObject(hdc, dat->fontInfo[FONTID_GROUPCOUNTS].hFont);
+ GetTextExtentPoint32A(hdc, szCounts, lstrlenA(szCounts), &textSize);
+ width += textSize.cx;
+ }
+ }
+ SelectObject(hdc, hFont);
+ ReleaseDC(hwnd, hdc);
+ if (cfg::dat.dwFlags & CLUI_FULLROWSELECT && !(GetKeyState(VK_SHIFT) & 0x8000) && testx > dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 4 + (cfg::dat.dwFlags & CLUI_FRAME_AVATARS ? cfg::dat.avatarSize : 0)) {
+ if (flags)
+ *flags |= CLCHT_ONITEMSPACE;
+ return hit;
+ }
+ if (testx< dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 4 + (cfg::dat.dwFlags & CLUI_FRAME_AVATARS ? cfg::dat.avatarSize : 0)) {
+ if (flags)
+ *flags |= CLCHT_ONITEMLABEL;
+ return hit;
+ }
+ if (flags)
+ *flags |= CLCHT_NOWHERE;
+ return -1;
+}
+
+void ScrollTo(HWND hwnd, struct ClcData *dat, int desty, int noSmooth)
+{
+ DWORD startTick, nowTick;
+ int oldy = dat->yScroll;
+ RECT clRect, rcInvalidate;
+ int maxy, previousy;
+
+ if (dat->iHotTrack != -1 && dat->yScroll != desty) {
+ pcli->pfnInvalidateItem(hwnd, dat, dat->iHotTrack);
+ dat->iHotTrack = -1;
+ ReleaseCapture();
+ }
+ GetClientRect(hwnd, &clRect);
+ rcInvalidate = clRect;
+
+ maxy = RowHeight::getTotalHeight(dat)-clRect.bottom;
+ if (desty > maxy)
+ desty = maxy;
+ if (desty < 0)
+ desty = 0;
+ if (abs(desty - dat->yScroll) < 4)
+ noSmooth = 1;
+ if (!noSmooth && dat->exStyle & CLS_EX_NOSMOOTHSCROLLING)
+ noSmooth = 1;
+ previousy = dat->yScroll;
+ if (!noSmooth) {
+ startTick = GetTickCount();
+ for (; ;) {
+ nowTick = GetTickCount();
+ if (nowTick >= startTick + dat->scrollTime)
+ break;
+ dat->yScroll = oldy + (desty - oldy) * (int) (nowTick - startTick) / dat->scrollTime;
+ if (dat->backgroundBmpUse & CLBF_SCROLL || dat->hBmpBackground == NULL)
+ ScrollWindowEx(hwnd, 0, previousy - dat->yScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE);
+ else
+ InvalidateRect(hwnd, NULL, FALSE);
+ previousy = dat->yScroll;
+ if(cfg::dat.bSkinnedScrollbar && !dat->bisEmbedded)
+ CoolSB_SetScrollPos(hwnd, SB_VERT, dat->yScroll, TRUE);
+ else
+ SetScrollPos(hwnd, SB_VERT, dat->yScroll, TRUE);
+ UpdateWindow(hwnd);
+ }
+ }
+ dat->yScroll = desty;
+ if (dat->backgroundBmpUse & CLBF_SCROLL || dat->hBmpBackground == NULL) {
+ if(!noSmooth)
+ ScrollWindowEx(hwnd, 0, previousy - dat->yScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE);
+ else
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ else
+ InvalidateRect(hwnd, NULL, FALSE);
+
+ if(cfg::dat.bSkinnedScrollbar && !dat->bisEmbedded)
+ CoolSB_SetScrollPos(hwnd, SB_VERT, dat->yScroll, TRUE);
+ else
+ SetScrollPos(hwnd, SB_VERT, dat->yScroll, TRUE);
+ dat->forceScroll = 0;
+}
+
+void RecalcScrollBar(HWND hwnd, struct ClcData *dat)
+{
+ SCROLLINFO si = { 0 };
+ RECT clRect;
+ NMCLISTCONTROL nm;
+
+ RowHeight::calcRowHeights(dat, hwnd);
+
+ GetClientRect(hwnd, &clRect);
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ si.nMin = 0;
+ si.nMax = pcli->pfnGetRowTotalHeight(dat)-1;
+ si.nPage = clRect.bottom;
+ si.nPos = dat->yScroll;
+
+ if (GetWindowLong(hwnd, GWL_STYLE) & CLS_CONTACTLIST) {
+ if (dat->noVScrollbar == 0) {
+ if(cfg::dat.bSkinnedScrollbar && !dat->bisEmbedded)
+ CoolSB_SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+ else
+ SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+ }
+ }
+ else {
+ if(cfg::dat.bSkinnedScrollbar && !dat->bisEmbedded)
+ CoolSB_SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+ else
+ SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+ }
+ ScrollTo(hwnd, dat, dat->yScroll, 1);
+ nm.hdr.code = CLN_LISTSIZECHANGE;
+ nm.hdr.hwndFrom = hwnd;
+ nm.hdr.idFrom = GetDlgCtrlID(hwnd);
+ nm.pt.y = si.nMax;
+ SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm);
+ //saveRecalcScrollBar(hwnd, dat);
+}
+
+void SetGroupExpand(HWND hwnd,struct ClcData *dat,struct ClcGroup *group,int newState)
+{
+ int contentCount;
+ int groupy;
+ int newy;
+ int posy;
+ RECT clRect;
+ NMCLISTCONTROL nm;
+
+ if (newState == -1)
+ group->expanded ^= 1;
+ else {
+ if (group->expanded == (newState != 0))
+ return;
+ group->expanded = newState != 0;
+ }
+ InvalidateRect(hwnd,NULL,FALSE);
+ contentCount = pcli->pfnGetGroupContentsCount(group,1);
+
+ groupy=pcli->pfnGetRowsPriorTo(&dat->list,group,-1);
+ if(dat->selection>groupy && dat->selection<groupy+contentCount) dat->selection=groupy;
+ pcli->pfnRecalcScrollBar(hwnd,dat);
+
+ GetClientRect(hwnd,&clRect);
+ newy=dat->yScroll;
+ posy = RowHeight::getItemBottomY(dat, groupy+contentCount);
+ if(posy>=newy+clRect.bottom)
+ newy=posy-clRect.bottom;
+ posy = RowHeight::getItemTopY(dat, groupy);
+ if(newy>posy) newy=posy;
+ ScrollTo(hwnd,dat,newy,0);
+
+ nm.hdr.code=CLN_EXPANDED;
+ nm.hdr.hwndFrom=hwnd;
+ nm.hdr.idFrom=GetDlgCtrlID(hwnd);
+ nm.hItem=(HANDLE)group->groupId;
+ nm.action = (group->expanded);
+ SendMessage(GetParent(hwnd),WM_NOTIFY,0,(LPARAM)&nm);
+}
+
+static WNDPROC OldRenameEditWndProc;
+static LRESULT CALLBACK RenameEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_KEYDOWN:
+ switch (wParam) {
+ case VK_RETURN:
+ pcli->pfnEndRename(GetParent(hwnd), (struct ClcData *) GetWindowLongPtr(GetParent(hwnd), 0), 1);
+ return 0;
+ case VK_ESCAPE:
+ pcli->pfnEndRename(GetParent(hwnd), (struct ClcData *) GetWindowLongPtr(GetParent(hwnd), 0), 0);
+ return 0;
+ }
+ break;
+ case WM_GETDLGCODE:
+ if (lParam) {
+ MSG *msg = (MSG *) lParam;
+ if (msg->message == WM_KEYDOWN && msg->wParam == VK_TAB)
+ return 0;
+ if (msg->message == WM_CHAR && msg->wParam == '\t')
+ return 0;
+ }
+ return DLGC_WANTMESSAGE;
+ case WM_KILLFOCUS:
+ pcli->pfnEndRename(GetParent(hwnd), (struct ClcData *) GetWindowLongPtr(GetParent(hwnd), 0), 1);
+ return 0;
+ }
+ return CallWindowProc(OldRenameEditWndProc, hwnd, msg, wParam, lParam);
+}
+
+void BeginRenameSelection(HWND hwnd, struct ClcData *dat)
+{
+ struct ClcContact *contact;
+ struct ClcGroup *group;
+ int indent, x, y, h;
+ RECT clRect;
+
+ KillTimer(hwnd, TIMERID_RENAME);
+ ReleaseCapture();
+ dat->iHotTrack = -1;
+ dat->selection = pcli->pfnGetRowByIndex(dat, dat->selection, &contact, &group);
+ if (dat->selection == -1)
+ return;
+ if (contact->type != CLCIT_CONTACT && contact->type != CLCIT_GROUP)
+ return;
+ for (indent = 0; group->parent; indent++,group = group->parent) {
+ ;
+ }
+ GetClientRect(hwnd, &clRect);
+ x = indent * dat->groupIndent + dat->iconXSpace - 2;
+ //y = dat->selection * dat->rowHeight - dat->yScroll;
+ y = RowHeight::getItemTopY(dat, dat->selection)-dat->yScroll;
+
+ h=dat->row_heights[dat->selection];
+ {
+ int i;
+ for (i=0; i <= FONTID_LAST; i++)
+ if (h<dat->fontInfo[i].fontHeight+2) h=dat->fontInfo[i].fontHeight+2;
+ }
+#if defined(_UNICODE)
+ dat->hwndRenameEdit = CreateWindowEx(0, _T("RichEdit20W"),contact->szText,WS_CHILD|WS_BORDER|ES_MULTILINE|ES_AUTOHSCROLL,x,y,clRect.right-x,h,hwnd,NULL,g_hInst,NULL);
+ {
+ if((contact->type == CLCIT_CONTACT && cfg::eCache[contact->extraCacheEntry].dwCFlags & ECF_RTLNICK) || (contact->type == CLCIT_GROUP && contact->isRtl)) {
+ PARAFORMAT2 pf2;
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_RTLPARA;
+ pf2.wEffects = PFE_RTLPARA;
+ SetWindowText(dat->hwndRenameEdit, _T(""));
+ SendMessage(dat->hwndRenameEdit, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ SetWindowText(dat->hwndRenameEdit, contact->szText);
+ }
+ }
+#else
+ dat->hwndRenameEdit = CreateWindow(_T("EDIT"),contact->szText,WS_CHILD|WS_BORDER|ES_MULTILINE|ES_AUTOHSCROLL,x,y,clRect.right-x,h,hwnd,NULL,g_hInst,NULL);
+#endif
+ //dat->hwndRenameEdit = CreateWindow(_T("EDIT"), contact->szText, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, x, y, clRect.right - x, dat->rowHeight, hwnd, NULL, g_hInst, NULL);
+ OldRenameEditWndProc = (WNDPROC) SetWindowLongPtr(dat->hwndRenameEdit, GWLP_WNDPROC, (LONG_PTR) RenameEditSubclassProc);
+ SendMessage(dat->hwndRenameEdit, WM_SETFONT, (WPARAM) (contact->type == CLCIT_GROUP ? dat->fontInfo[FONTID_GROUPS].hFont : dat->fontInfo[FONTID_CONTACTS].hFont), 0);
+ SendMessage(dat->hwndRenameEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0);
+ SendMessage(dat->hwndRenameEdit, EM_SETSEL, 0, (LPARAM) (-1));
+ ShowWindow(dat->hwndRenameEdit, SW_SHOW);
+ SetFocus(dat->hwndRenameEdit);
+}
+
+extern void ( *saveLoadClcOptions )(HWND hwnd,struct ClcData *dat);
+
+void LoadClcOptions(HWND hwnd, struct ClcData *dat)
+{
+ dat->bkChanged = 0;
+
+ saveLoadClcOptions(hwnd, dat);
+
+ dat->min_row_heigh = (int)cfg::getByte("CLC","RowHeight",CLCDEFAULT_ROWHEIGHT);
+ dat->group_row_height = (int)cfg::getByte("CLC","GRowHeight",CLCDEFAULT_ROWHEIGHT);
+ dat->row_border = 0;
+ dat->rightMargin = cfg::getByte("CLC", "RightMargin", CLCDEFAULT_LEFTMARGIN);
+ dat->bkColour = cfg::getByte("CLC", "UseWinColours", CLCDEFAULT_USEWINDOWSCOLOURS) ?
+ GetSysColor(COLOR_3DFACE) : cfg::getDword("CLC", "BkColour", CLCDEFAULT_BKCOLOUR);
+ if (!dat->bkChanged) {
+ if(cfg::dat.hBrushCLCBk)
+ DeleteObject(cfg::dat.hBrushCLCBk);
+ cfg::dat.hBrushCLCBk = CreateSolidBrush(dat->bkColour);
+ if (dat->hBmpBackground) {
+ if(cfg::dat.hdcPic) {
+ SelectObject(cfg::dat.hdcPic, cfg::dat.hbmPicOld);
+ DeleteDC(cfg::dat.hdcPic);
+ cfg::dat.hdcPic = 0;
+ cfg::dat.hbmPicOld = 0;
+ } }
+
+ cfg::dat.bmpBackground = dat->hBmpBackground;
+ if(cfg::dat.bmpBackground) {
+ HDC hdcThis = GetDC(pcli->hwndContactList);
+ GetObject(cfg::dat.bmpBackground, sizeof(cfg::dat.bminfoBg), &(cfg::dat.bminfoBg));
+ cfg::dat.hdcPic = CreateCompatibleDC(hdcThis);
+ cfg::dat.hbmPicOld = reinterpret_cast<HBITMAP>(SelectObject(cfg::dat.hdcPic, cfg::dat.bmpBackground));
+ ReleaseDC(pcli->hwndContactList, hdcThis);
+ }
+ }
+ if (cfg::getByte("CLCExt", "EXBK_FillWallpaper", 0)) {
+ char wpbuf[MAX_PATH];
+ if (dat->hBmpBackground)
+ DeleteObject(dat->hBmpBackground); dat->hBmpBackground = NULL;
+
+ SystemParametersInfoA(SPI_GETDESKWALLPAPER, MAX_PATH, wpbuf, 0);
+
+ // we have a wallpaper string
+ if (strlen(wpbuf) > 0) {
+ dat->hBmpBackground = reinterpret_cast<HBITMAP>(LoadImageA(NULL, wpbuf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
+ }
+ cfg::dat.bmpBackground = dat->hBmpBackground;
+ if(cfg::dat.bmpBackground) {
+ HDC hdcThis = GetDC(pcli->hwndContactList);
+ GetObject(cfg::dat.bmpBackground, sizeof(cfg::dat.bminfoBg), &(cfg::dat.bminfoBg));
+ cfg::dat.hdcPic = CreateCompatibleDC(hdcThis);
+ cfg::dat.hbmPicOld = reinterpret_cast<HBITMAP>(SelectObject(cfg::dat.hdcPic, cfg::dat.bmpBackground));
+ ReleaseDC(pcli->hwndContactList, hdcThis);
+ }
+ }
+}
diff --git a/plugins/Clist_nicer/SRC/clistevents.cpp b/plugins/Clist_nicer/SRC/clistevents.cpp
new file mode 100644
index 0000000000..85b145f32a
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clistevents.cpp
@@ -0,0 +1,399 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include <commonheaders.h>
+#include "../cluiframes/cluiframes.h"
+
+static HWND hwndEventFrame = 0;
+HFONT __fastcall ChangeToFont(HDC hdc, struct ClcData *dat, int id, int *fontHeight);
+
+extern struct CListEvent* ( *saveAddEvent )(CLISTEVENT *cle);
+extern int ( *saveRemoveEvent )(HANDLE hContact, HANDLE hDbEvent);
+extern wndFrame *wndFrameEventArea;
+
+extern HPEN g_hPenCLUIFrames;
+
+extern StatusItems_t *StatusItems;
+
+HWND g_hwndEventArea = 0;
+
+struct CListEvent {
+ int imlIconIndex;
+ int flashesDone;
+ CLISTEVENT cle;
+
+ int menuId;
+ int imlIconOverlayIndex;
+};
+
+struct CListImlIcon {
+ int index;
+ HICON hIcon;
+};
+
+static int iconsOn;
+extern HIMAGELIST hCListImages;
+
+HANDLE hNotifyFrame = (HANDLE)-1;
+
+struct CListEvent* fnCreateEvent( void )
+{
+ CListEvent *p = reinterpret_cast<CListEvent *>(mir_alloc(sizeof(struct CListEvent)));
+ if(p)
+ ZeroMemory(p, sizeof(struct CListEvent));
+
+ return p;
+}
+
+void HideShowNotifyFrame()
+{
+ int dwVisible = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hNotifyFrame), 0) & F_VISIBLE;
+ int desired;
+
+ if(cfg::dat.dwFlags & CLUI_FRAME_AUTOHIDENOTIFY)
+ desired = cfg::dat.notifyActive ? TRUE : FALSE;
+ else
+ desired = dwVisible;
+
+ if(desired) {
+ if(!dwVisible)
+ CallService(MS_CLIST_FRAMES_SHFRAME, (WPARAM)hNotifyFrame, 0);
+ }
+ else {
+ if(dwVisible)
+ CallService(MS_CLIST_FRAMES_SHFRAME, (WPARAM)hNotifyFrame, 0);
+ }
+}
+
+static CLISTEVENT* MyGetEvent(int iSelection)
+{
+ int i;
+
+ for (i = 0; i < pcli->events.count; i++) {
+ struct CListEvent* p = pcli->events.items[i];
+ if (p->menuId == iSelection)
+ return &p->cle;
+ }
+ return NULL;
+}
+
+LRESULT CALLBACK EventAreaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_CREATE:
+ hwndEventFrame = hwnd;
+ return FALSE;
+
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *lpi = (LPMEASUREITEMSTRUCT) lParam;
+ MENUITEMINFOA mii = {0};
+
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA | MIIM_ID;
+ if (GetMenuItemInfoA(cfg::dat.hMenuNotify, lpi->itemID, FALSE, &mii) != 0) {
+ if (mii.dwItemData == lpi->itemData) {
+ lpi->itemWidth = 8 + 16;
+ lpi->itemHeight = 0;
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_NCCALCSIZE:
+ return FrameNCCalcSize(hwnd, DefWindowProc, wParam, lParam,
+ wndFrameEventArea ? wndFrameEventArea->TitleBar.ShowTitleBar : 0);
+ case WM_NCPAINT:
+ return FrameNCPaint(hwnd, DefWindowProc, wParam, lParam,
+ wndFrameEventArea ? wndFrameEventArea->TitleBar.ShowTitleBar : 0);
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+
+ if (dis->hwndItem == (HWND) cfg::dat.hMenuNotify) {
+ MENUITEMINFOA mii = {0};
+
+ struct NotifyMenuItemExData *nmi = 0;
+ int iIcon;
+ HICON hIcon;
+
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+ if (GetMenuItemInfoA(cfg::dat.hMenuNotify, (UINT) dis->itemID, FALSE, &mii) != 0) {
+ nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
+ if (nmi) {
+ iIcon = CallService(MS_CLIST_GETCONTACTICON, (WPARAM) nmi->hContact, 0);
+ hIcon = ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL);
+ pcli->pfnDrawMenuItem(dis, hIcon, nmi->hIcon);
+ return TRUE;
+ }
+ }
+ }
+ break;
+ }
+ case WM_LBUTTONUP:
+ if(cfg::dat.bEventAreaEnabled)
+ SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_NOTIFYBUTTON, 0), 0);
+ break;
+ case WM_COMMAND:
+ if(LOWORD(wParam) == IDC_NOTIFYBUTTON) {
+ int iSelection;
+ MENUITEMINFO mii = {0};
+ POINT pt;
+ struct NotifyMenuItemExData *nmi = 0;
+ int iCount = GetMenuItemCount(cfg::dat.hMenuNotify);
+ BOOL result;
+
+ GetCursorPos(&pt);
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+ if (iCount > 1)
+ iSelection = TrackPopupMenu(cfg::dat.hMenuNotify, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);
+ else
+ iSelection = GetMenuItemID(cfg::dat.hMenuNotify, 0);
+ result = GetMenuItemInfo(cfg::dat.hMenuNotify, (UINT) iSelection, FALSE, &mii);
+ if (result != 0) {
+ nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
+ if (nmi) {
+ CLISTEVENT *cle = MyGetEvent(iSelection);
+ if (cle) {
+ CLISTEVENT *cle1 = NULL;
+ CallService(cle->pszService, (WPARAM) NULL, (LPARAM) cle);
+ // re-obtain the pointer, it may already be invalid/point to another event if the
+ // event we're interested in was removed by the service (nasty one...)
+ cle1 = MyGetEvent(iSelection);
+ if (cle1 != NULL)
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM) cle->hContact, (LPARAM) cle->hDbEvent);
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ RECT rc, rcClient;
+ HDC hdc = BeginPaint(hwnd, &ps);
+ LONG dwLeft;
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ HBITMAP hbm, hbmold;
+ StatusItems_t *item;
+ int height;
+ HFONT hFontOld = 0;
+
+ GetClientRect(hwnd, &rc);
+ rcClient = rc;
+ hbm = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
+ hbmold = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, hbm));
+ SetBkMode(hdcMem, TRANSPARENT);
+
+ if(cfg::clcdat)
+ hFontOld = ChangeToFont(hdcMem, cfg::clcdat, FONTID_EVENTAREA, &height);
+
+ if(cfg::dat.bWallpaperMode)
+ SkinDrawBg(hwnd, hdcMem);
+ item = &StatusItems[ID_EXTBKEVTAREA - ID_STATUS_OFFLINE];
+ if(item->IGNORED) {
+ FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE));
+ }
+ else {
+ rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM;
+ rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT;
+
+ DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT,
+ item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem);
+ SetTextColor(hdcMem, item->TEXTCOLOR);
+ }
+
+ dwLeft = rc.left;
+
+ PaintNotifyArea(hdcMem, &rc);
+ if(cfg::dat.dwFlags & CLUI_FRAME_EVENTAREASUNKEN) {
+ rc.left = dwLeft;
+ InflateRect(&rc, -2, -2);
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
+ BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY);
+ SelectObject(hdcMem, hbmold);
+ if(hFontOld)
+ SelectObject(hdcMem, hFontOld);
+ DeleteObject(hbm);
+ DeleteDC(hdcMem);
+ ps.fErase = FALSE;
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return TRUE;
+}
+
+struct CListEvent* AddEvent(CLISTEVENT *cle)
+{
+ struct CListEvent* p = saveAddEvent(cle);
+ if ( p == NULL )
+ return NULL;
+
+ if (1) {
+ if (p->cle.hContact != 0 && p->cle.hDbEvent != (HANDLE) 1 && !(p->cle.flags & CLEF_ONLYAFEW)) {
+ int j;
+ struct NotifyMenuItemExData *nmi = 0;
+ char *szProto;
+ TCHAR *szName;
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA | MIIM_BITMAP | MIIM_ID;
+ if (p->cle.pszService && !strncmp("SRMsg/ReadMessage", p->cle.pszService, 17)) {
+ // dup check only for msg events
+ for (j = 0; j < GetMenuItemCount(cfg::dat.hMenuNotify); j++) {
+ if (GetMenuItemInfo(cfg::dat.hMenuNotify, j, TRUE, &mii) != 0) {
+ nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
+ if (nmi != 0 && (HANDLE) nmi->hContact == (HANDLE) p->cle.hContact && nmi->iIcon == p->imlIconIndex)
+ return p;
+ } } }
+
+ szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) p->cle.hContact, 0);
+ szName = pcli->pfnGetContactDisplayName(p->cle.hContact, 0);
+ if (szProto && szName) {
+ nmi = (struct NotifyMenuItemExData *) malloc(sizeof(struct NotifyMenuItemExData));
+ if (nmi) {
+ TCHAR szBuffer[128];
+ TCHAR* szStatus = pcli->pfnGetStatusModeDescription(cfg::getWord(p->cle.hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
+#if defined(_UNICODE)
+ TCHAR szwProto[64];
+ MultiByteToWideChar(CP_ACP, 0, szProto, -1, szwProto, 64);
+ szwProto[63] = 0;
+ _snwprintf(szBuffer, SIZEOF(szBuffer), L"%s: %s (%s)", szwProto, szName, szStatus);
+#else
+ _snprintf(szBuffer, SIZEOF(szBuffer), "%s: %s (%s)", szProto, szName, szStatus);
+#endif
+ szBuffer[127] = 0;
+ AppendMenu(cfg::dat.hMenuNotify, MF_BYCOMMAND | MF_STRING, cfg::dat.wNextMenuID, szBuffer);
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ nmi->hContact = p->cle.hContact;
+ nmi->iIcon = p->imlIconIndex;
+ nmi->hIcon = p->cle.hIcon;
+ nmi->hDbEvent = p->cle.hDbEvent;
+ mii.dwItemData = (ULONG_PTR) nmi;
+ mii.wID = cfg::dat.wNextMenuID;
+ SetMenuItemInfo(cfg::dat.hMenuNotify, cfg::dat.wNextMenuID, FALSE, &mii);
+ p-> menuId = cfg::dat.wNextMenuID;
+ cfg::dat.wNextMenuID++;
+ if (cfg::dat.wNextMenuID > 0x7fff)
+ cfg::dat.wNextMenuID = 1;
+ cfg::dat.hIconNotify = p->imlIconIndex;
+ }
+ }
+ } else if (p->cle.hContact != 0 && (p->cle.flags & CLEF_ONLYAFEW)) {
+ cfg::dat.hIconNotify = p->imlIconIndex;
+ cfg::dat.hUpdateContact = p->cle.hContact;
+ }
+ if (cfg::dat.dwFlags & CLUI_STICKYEVENTS) {
+ HANDLE hItem = (HANDLE) SendMessage(pcli->hwndContactTree, CLM_FINDCONTACT, (WPARAM) p->cle.hContact, 0);
+ if (hItem) {
+ SendMessage(pcli->hwndContactTree, CLM_SETSTICKY, (WPARAM) hItem, 1);
+ pcli->pfnClcBroadcast(INTM_PROTOCHANGED, (WPARAM) p->cle.hContact, 0);
+ }
+ }
+ if (pcli->events.count > 0) {
+ cfg::dat.bEventAreaEnabled = TRUE;
+ if (cfg::dat.notifyActive == 0) {
+ cfg::dat.notifyActive = 1;
+ HideShowNotifyFrame();
+ }
+ }
+ InvalidateRect(hwndEventFrame, NULL, FALSE);
+ if(cfg::dat.bUseFloater & CLUI_USE_FLOATER && cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS)
+ SFL_Update(0, 0, 0, NULL, FALSE);
+ }
+
+ return p;
+}
+
+// Removes an event from the contact list's queue
+// wParam=(WPARAM)(HANDLE)hContact
+// lParam=(LPARAM)(HANDLE)hDbEvent
+// Returns 0 if the event was successfully removed, or nonzero if the event was not found
+int RemoveEvent(HANDLE hContact, HANDLE hDbEvent)
+{
+ HANDLE hItem;
+ int i;
+ BOOL bUnstick = TRUE;
+
+ // Find the event that should be removed
+ for (i = 0; i < pcli->events.count; i++) {
+ if ((pcli->events.items[i]->cle.hContact == hContact) && (pcli->events.items[i]->cle.hDbEvent == hDbEvent)) {
+ break;
+ }
+ }
+
+ // Event was not found
+ if (i == pcli->events.count)
+ return 1;
+
+ // remove event from the notify menu
+ if (1) {
+ if (pcli->events.items[i]->menuId > 0) {
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+ if (GetMenuItemInfo(cfg::dat.hMenuNotify, pcli->events.items[i]->menuId, FALSE, &mii) != 0) {
+ struct NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
+ if (nmi && nmi->hContact == hContact && nmi->hDbEvent == hDbEvent) {
+ free(nmi);
+ DeleteMenu(cfg::dat.hMenuNotify, pcli->events.items[i]->menuId, MF_BYCOMMAND);
+ } } } }
+
+ saveRemoveEvent(hContact, hDbEvent);
+
+ if (pcli->events.count == 0) {
+ cfg::dat.bEventAreaEnabled = FALSE;
+ if (cfg::dat.dwFlags & CLUI_FRAME_AUTOHIDENOTIFY) {
+ cfg::dat.notifyActive = 0;
+ HideShowNotifyFrame();
+ } }
+
+ if (bUnstick) {
+ // clear "sticky" (sort) status
+
+ hItem = (HANDLE) SendMessage(pcli->hwndContactTree, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ if (hItem) {
+ SendMessage(pcli->hwndContactTree, CLM_SETSTICKY, (WPARAM) hItem, 0);
+ pcli->pfnClcBroadcast(INTM_PROTOCHANGED, (WPARAM)hContact, 0);
+ } }
+
+ if (hContact == cfg::dat.hUpdateContact || (INT_PTR)hDbEvent == 1)
+ cfg::dat.hUpdateContact = 0;
+
+ if (cfg::dat.notifyActive) {
+ InvalidateRect(hwndEventFrame, NULL, FALSE);
+ if(cfg::dat.bUseFloater & CLUI_USE_FLOATER && cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS)
+ SFL_Update(0, 0, 0, NULL, FALSE);
+ }
+
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/clistmenus.cpp b/plugins/Clist_nicer/SRC/clistmenus.cpp
new file mode 100644
index 0000000000..22b5b87df1
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clistmenus.cpp
@@ -0,0 +1,493 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <commonheaders.h>
+#include <m_genmenu.h>
+#include <m_ignore.h>
+#include "../CLUIFrames/cluiframes.h"
+
+#pragma hdrstop
+
+static HMENU hMainMenu, hMainStatusMenu;
+
+void DestroyTrayMenu(HMENU hMenu)
+{
+ int i, cnt;
+
+ cnt = GetMenuItemCount(hMenu);
+ for (i=0; i<cnt; ++i)
+ {
+ HMENU hSubMenu = GetSubMenu(hMenu, i);
+ if (hSubMenu == hMainStatusMenu || hSubMenu == hMainMenu)
+ RemoveMenu(hMenu, i--, MF_BYPOSITION);
+ }
+ DestroyMenu(hMenu);
+}
+
+INT_PTR CloseAction(WPARAM wParam,LPARAM lParam)
+{
+ int k;
+ cfg::shutDown = 1;
+ k=CallService(MS_SYSTEM_OKTOEXIT,(WPARAM)0,(LPARAM)0);
+ if (k) {
+ DestroyWindow(pcli->hwndContactList);
+ PostQuitMessage(0);
+ Sleep(0);
+ }
+
+ return(0);
+}
+
+static HANDLE hWindowListIGN = 0;
+
+/*
+ * dialog procedure for handling the contact ignore dialog (available from the contact
+ * menu
+ */
+
+static const UINT xImgCtrlIds[] = {
+ IDC_EXTRA_ICON_RES0,
+ IDC_EXTRA_ICON_EMAIL,
+ IDC_EXTRA_ICON_RES1,
+ IDC_EXTRA_ICON_SMS,
+ IDC_EXTRA_ICON_ADV1,
+ IDC_EXTRA_ICON_ADV2,
+ IDC_EXTRA_ICON_WEB,
+ IDC_EXTRA_ICON_CLIENT,
+ IDC_EXTRA_ICON_RES2,
+ IDC_EXTRA_ICON_ADV3,
+ IDC_EXTRA_ICON_ADV4
+};
+
+// static UINT xImgCtrlBits[] = {6, 4, 0, 1, 2, 3, 5, 7, 8, 9, 10};
+static const UINT xImgCtrlBits[] = {
+ EXTRA_ICON_RES0,
+ EXTRA_ICON_EMAIL,
+ EXTRA_ICON_RES1,
+ EXTRA_ICON_SMS,
+ EXTRA_ICON_ADV1,
+ EXTRA_ICON_ADV2,
+ EXTRA_ICON_WEB,
+ EXTRA_ICON_CLIENT,
+ EXTRA_ICON_RES2,
+ EXTRA_ICON_ADV3,
+ EXTRA_ICON_ADV4
+};
+
+static INT_PTR CALLBACK IgnoreDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ DWORD dwMask;
+ struct ClcContact *contact = NULL;
+ int pCaps;
+ HWND hwndAdd;
+
+ hContact = (HANDLE)lParam;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)hContact);
+ dwMask = cfg::getDword(hContact, "Ignore", "Mask1", 0);
+ SendMessage(hWnd, WM_USER + 100, (WPARAM)hContact, dwMask);
+ SendMessage(hWnd, WM_USER + 120, 0, 0);
+ TranslateDialogDefault(hWnd);
+ hwndAdd = GetDlgItem(hWnd, IDC_IGN_ADDPERMANENTLY); // CreateWindowEx(0, _T("CLCButtonClass"), _T("FOO"), WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 200, 276, 106, 24, hWnd, (HMENU)IDC_IGN_ADDPERMANENTLY, g_hInst, NULL);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1);
+
+ SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(210), IMAGE_ICON, 16, 16, LR_SHARED));
+ SetWindowText(hwndAdd, TranslateT("Add permanently"));
+ EnableWindow(hwndAdd, cfg::getByte(hContact, "CList", "NotOnList", 0));
+
+ hwndAdd = GetDlgItem(hWnd, IDC_DSP_LOADDEFAULT); // CreateWindowEx(0, _T("CLCButtonClass"), _T("FOO"), WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 200, 276, 106, 24, hWnd, (HMENU)IDC_IGN_ADDPERMANENTLY, g_hInst, NULL);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1);
+ SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1);
+
+ SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_DELETE), IMAGE_ICON, 16, 16, LR_SHARED));
+ SetWindowText(hwndAdd, TranslateT("Revert to default"));
+ EnableWindow(hwndAdd, TRUE);
+
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Default (global setting)"));
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Show always when available"));
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Hide always"));
+
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Default (global setting)"));
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Never"));
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always"));
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When space is available"));
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When needed by status message"));
+
+ if(cfg::clcdat) {
+ FindItem(pcli->hwndContactTree, cfg::clcdat, hContact, &contact, NULL, NULL);
+ if(contact && contact->type != CLCIT_CONTACT) {
+ DestroyWindow(hWnd);
+ return FALSE;
+ } else {
+ TCHAR szTitle[512];
+ DWORD dwFlags = cfg::getDword(hContact, "CList", "CLN_Flags", 0);
+ BYTE bSecondLine = cfg::getByte(hContact, "CList", "CLN_2ndline", -1);
+ DWORD dwXMask = cfg::getDword(hContact, "CList", "CLN_xmask", 0);
+ int i = 0;
+
+ mir_sntprintf(szTitle, 512, TranslateT("Contact list display and ignore options for %s"), contact ? contact->szText : (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR));
+
+ SetWindowText(hWnd, szTitle);
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+ pCaps = CallProtoService(contact ? contact->proto : (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0), PS_GETCAPS, PFLAGNUM_1, 0);
+ Utils::enableDlgControl(hWnd, IDC_IGN_ALWAYSONLINE, pCaps & PF1_INVISLIST ? TRUE : FALSE);
+ Utils::enableDlgControl(hWnd, IDC_IGN_ALWAYSOFFLINE, pCaps & PF1_VISLIST ? TRUE : FALSE);
+ CheckDlgButton(hWnd, IDC_IGN_PRIORITY, cfg::getByte(hContact, "CList", "Priority", 0) ? 1 : 0);
+ Utils::enableDlgControl(hWnd, IDC_IGN_PRIORITY, TRUE);
+ Utils::enableDlgControl(hWnd, IDC_AVATARDISPMODE, TRUE);
+ Utils::enableDlgControl(hWnd, IDC_SECONDLINEMODE, TRUE);
+ if(dwFlags & ECF_FORCEAVATAR)
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 1, 0);
+ else if(dwFlags & ECF_HIDEAVATAR)
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 2, 0);
+ else
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 0, 0);
+
+ if(dwFlags & ECF_FORCEOVERLAY)
+ SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_CHECKED, 0);
+ else if(dwFlags & ECF_HIDEOVERLAY)
+ SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_UNCHECKED, 0);
+ else
+ SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_INDETERMINATE, 0);
+
+ if(dwFlags & ECF_FORCELOCALTIME)
+ SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_SETCHECK, BST_CHECKED, 0);
+ else if(dwFlags & ECF_HIDELOCALTIME)
+ SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_SETCHECK, BST_UNCHECKED, 0);
+ else
+ SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_SETCHECK, BST_INDETERMINATE, 0);
+
+ if(dwFlags & ECF_FORCEVISIBILITY)
+ SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_CHECKED, 0);
+ else if(dwFlags & ECF_HIDEVISIBILITY)
+ SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_UNCHECKED, 0);
+ else
+ SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_INDETERMINATE, 0);
+
+ while(xImgCtrlIds[i] != 0) {
+ if(dwXMask & (1 << (2 * xImgCtrlBits[i])))
+ SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_SETCHECK, BST_CHECKED, 0);
+ else if(dwXMask & (1 << (2 * xImgCtrlBits[i] + 1)))
+ SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_SETCHECK, BST_UNCHECKED, 0);
+ else
+ SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_SETCHECK, BST_INDETERMINATE, 0);
+ i++;
+ }
+
+ if(bSecondLine == 0xff)
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, 0, 0);
+ else
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, (WPARAM)(bSecondLine + 1), 0);
+ }
+ }
+ WindowList_Add(hWindowListIGN, hWnd, hContact);
+ ShowWindow(hWnd, SW_SHOWNORMAL);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_IGN_PRIORITY:
+ SendMessage(pcli->hwndContactTree, CLM_TOGGLEPRIORITYCONTACT, (WPARAM)hContact, 0);
+ return 0;
+ case IDC_IGN_ALL:
+ SendMessage(hWnd, WM_USER + 100, (WPARAM)hContact, (LPARAM)0xffffffff);
+ return 0;
+ case IDC_IGN_NONE:
+ SendMessage(hWnd, WM_USER + 100, (WPARAM)hContact, (LPARAM)0);
+ return 0;
+ case IDC_IGN_ALWAYSONLINE:
+ if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSONLINE))
+ CheckDlgButton(hWnd, IDC_IGN_ALWAYSOFFLINE, FALSE);
+ break;
+ case IDC_IGN_ALWAYSOFFLINE:
+ if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSOFFLINE))
+ CheckDlgButton(hWnd, IDC_IGN_ALWAYSONLINE, FALSE);
+ break;
+ case IDC_HIDECONTACT:
+ cfg::writeByte(hContact, "CList", "Hidden", (BYTE)(IsDlgButtonChecked(hWnd, IDC_HIDECONTACT) ? 1 : 0));
+ break;
+ case IDC_IGN_ADDPERMANENTLY:
+ {
+ ADDCONTACTSTRUCT acs = {0};
+
+ acs.handle = hContact;
+ acs.handleType = HANDLE_CONTACT;
+ acs.szProto = 0;
+ CallService(MS_ADDCONTACT_SHOW, (WPARAM)hWnd, (LPARAM)&acs);
+ Utils::enableDlgControl(hWnd, IDC_IGN_ADDPERMANENTLY, cfg::getByte(hContact, "CList", "NotOnList", 0));
+ break;
+ }
+ case IDC_DSP_LOADDEFAULT:
+ {
+ int i = 0;
+
+ SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 0, 0);
+ SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, 0, 0);
+ while(xImgCtrlIds[i] != 0)
+ SendDlgItemMessage(hWnd, xImgCtrlIds[i++], BM_SETCHECK, BST_INDETERMINATE, 0);
+
+ SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_INDETERMINATE, 0);
+ SendDlgItemMessage(hWnd, IDC_LOCALTIME, BM_SETCHECK, BST_INDETERMINATE, 0);
+ SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_INDETERMINATE, 0);
+ break;
+ }
+ case IDOK:
+ {
+ DWORD newMask = 0;
+ struct ClcContact *contact = NULL;
+
+ SendMessage(hWnd, WM_USER + 110, 0, (LPARAM)&newMask);
+ cfg::writeDword(hContact, "Ignore", "Mask1", newMask);
+ SendMessage(hWnd, WM_USER + 130, 0, 0);
+
+ if(cfg::clcdat) {
+ LRESULT iSel = SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_GETCURSEL, 0, 0);
+ DWORD dwFlags = cfg::getDword(hContact, "CList", "CLN_Flags", 0), dwXMask = 0;
+ LRESULT checked = 0;
+ int i = 0;
+
+ FindItem(pcli->hwndContactTree, cfg::clcdat, hContact, &contact, NULL, NULL);
+ if(iSel != CB_ERR) {
+ dwFlags &= ~(ECF_FORCEAVATAR | ECF_HIDEAVATAR);
+
+ if(iSel == 1)
+ dwFlags |= ECF_FORCEAVATAR;
+ else if(iSel == 2)
+ dwFlags |= ECF_HIDEAVATAR;
+ if(contact)
+ LoadAvatarForContact(contact);
+ }
+
+ dwFlags &= ~(ECF_FORCEOVERLAY | ECF_HIDEOVERLAY | ECF_FORCELOCALTIME | ECF_HIDELOCALTIME |
+ ECF_FORCEVISIBILITY | ECF_HIDEVISIBILITY);
+
+ checked = SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_GETCHECK, 0, 0);
+ if(checked == BST_CHECKED)
+ dwFlags |= ECF_FORCEOVERLAY;
+ else if(checked == BST_UNCHECKED)
+ dwFlags |= ECF_HIDEOVERLAY;
+
+ checked = SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_GETCHECK, 0, 0);
+ if(checked == BST_CHECKED)
+ dwFlags |= ECF_FORCELOCALTIME;
+ else if(checked == BST_UNCHECKED)
+ dwFlags |= ECF_HIDELOCALTIME;
+
+ checked = SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_GETCHECK, 0, 0);
+ if(checked == BST_CHECKED)
+ dwFlags |= ECF_FORCEVISIBILITY;
+ else if(checked == BST_UNCHECKED)
+ dwFlags |= ECF_HIDEVISIBILITY;
+
+ cfg::writeDword(hContact, "CList", "CLN_Flags", dwFlags);
+
+ if((iSel = SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_GETCURSEL, 0, 0)) != CB_ERR) {
+ if(iSel == 0) {
+ DBDeleteContactSetting(hContact, "CList", "CLN_2ndline");
+ if(contact)
+ contact->bSecondLine = cfg::dat.dualRowMode;
+ }
+ else {
+ DBWriteContactSettingByte(hContact, "CList", "CLN_2ndline", (BYTE)(iSel - 1));
+ if(contact)
+ contact->bSecondLine = (BYTE)(iSel - 1);
+ }
+ }
+ while(xImgCtrlIds[i] != 0) {
+ checked = SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_GETCHECK, 0, 0);
+ if(checked == BST_CHECKED)
+ dwXMask |= (1 << (2 * xImgCtrlBits[i]));
+ else if(checked == BST_UNCHECKED)
+ dwXMask |= (1 << (2 * xImgCtrlBits[i] + 1));
+ i++;
+ }
+ cfg::writeDword(hContact, "CList", "CLN_xmask", dwXMask);
+ if(contact) {
+ if(contact->extraCacheEntry >= 0 && contact->extraCacheEntry <= cfg::nextCacheEntry) {
+ cfg::eCache[contact->extraCacheEntry].dwDFlags = dwFlags;
+ cfg::eCache[contact->extraCacheEntry].dwXMask = CalcXMask(hContact);
+ }
+ }
+ else {
+ int iIndex = cfg::getCache(hContact, NULL);
+ if(iIndex >= 0 && iIndex <= cfg::nextCacheEntry) {
+ cfg::eCache[iIndex].dwDFlags = dwFlags;
+ cfg::eCache[iIndex].dwXMask = CalcXMask(hContact);
+ }
+ }
+ cfg::writeByte(hContact, "CList", "Priority", (BYTE)(IsDlgButtonChecked(hWnd, IDC_IGN_PRIORITY) ? 1 : 0));
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ }
+ }
+ case IDCANCEL:
+ DestroyWindow(hWnd);
+ break;
+ }
+ break;
+ case WM_USER + 100: // fill dialog (wParam = hContact, lParam = mask)
+ {
+ CheckDlgButton(hWnd, IDC_IGN_MSGEVENTS, lParam & (1 << (IGNOREEVENT_MESSAGE - 1)) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_IGN_FILEEVENTS, lParam & (1 << (IGNOREEVENT_FILE - 1)) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_IGN_URLEVENTS, lParam & (1 << (IGNOREEVENT_URL - 1)) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_IGN_AUTH, lParam & (1 << (IGNOREEVENT_AUTHORIZATION - 1)) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_IGN_ADD, lParam & (1 << (IGNOREEVENT_YOUWEREADDED - 1)) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hWnd, IDC_IGN_ONLINE, lParam & (1 << (IGNOREEVENT_USERONLINE - 1)) ? BST_CHECKED : BST_UNCHECKED);
+ return 0;
+ }
+ case WM_USER + 110: // retrieve value
+ {
+ DWORD *dwNewMask = (DWORD *)lParam, dwMask = 0;
+
+ dwMask = (IsDlgButtonChecked(hWnd, IDC_IGN_MSGEVENTS) ? (1 << (IGNOREEVENT_MESSAGE - 1)) : 0) |
+ (IsDlgButtonChecked(hWnd, IDC_IGN_FILEEVENTS) ? (1 << (IGNOREEVENT_FILE - 1)) : 0) |
+ (IsDlgButtonChecked(hWnd, IDC_IGN_URLEVENTS) ? (1 << (IGNOREEVENT_URL - 1)) : 0) |
+ (IsDlgButtonChecked(hWnd, IDC_IGN_AUTH) ? (1 << (IGNOREEVENT_AUTHORIZATION - 1)) : 0) |
+ (IsDlgButtonChecked(hWnd, IDC_IGN_ADD) ? (1 << (IGNOREEVENT_YOUWEREADDED - 1)) : 0) |
+ (IsDlgButtonChecked(hWnd, IDC_IGN_ONLINE) ? (1 << (IGNOREEVENT_USERONLINE - 1)) : 0);
+
+ if(dwNewMask)
+ *dwNewMask = dwMask;
+ return 0;
+ }
+ case WM_USER + 120: // set visibility status
+ {
+ struct ClcContact *contact = NULL;
+
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, hContact, &contact, NULL, NULL)) {
+ if(contact) {
+ WORD wApparentMode = cfg::getWord(contact->hContact, contact->proto, "ApparentMode", 0);
+
+ CheckDlgButton(hWnd, IDC_IGN_ALWAYSOFFLINE, wApparentMode == ID_STATUS_OFFLINE ? TRUE : FALSE);
+ CheckDlgButton(hWnd, IDC_IGN_ALWAYSONLINE, wApparentMode == ID_STATUS_ONLINE ? TRUE : FALSE);
+ }
+ }
+ return 0;
+ }
+ case WM_USER + 130: // update apparent mode
+ {
+ struct ClcContact *contact = NULL;
+
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, hContact, &contact, NULL, NULL)) {
+ if(contact) {
+ WORD wApparentMode = 0, oldApparentMode = cfg::getWord(hContact, contact->proto, "ApparentMode", 0);
+
+ if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSONLINE))
+ wApparentMode = ID_STATUS_ONLINE;
+ else if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSOFFLINE))
+ wApparentMode = ID_STATUS_OFFLINE;
+
+ //DBWriteContactSettingWord(hContact, contact->proto, "ApparentMode", wApparentMode);
+ //if(oldApparentMode != wApparentMode)
+ CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)wApparentMode, 0);
+ SendMessage(hWnd, WM_USER + 120, 0, 0);
+ }
+ }
+ return 0;
+ }
+ case WM_DESTROY:
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
+ WindowList_Remove(hWindowListIGN, hWnd);
+ break;
+ }
+ return FALSE;
+}
+
+/*
+ * service function: Open ignore settings dialog for the contact handle in wParam
+ * (clist_nicer+ specific service)
+ *
+ * Servicename = CList/SetContactIgnore
+ *
+ * ensure that dialog is only opened once (the dialog proc saves the window handle of an open dialog
+ * of this type to the contacts database record).
+ *
+ * if dialog is already open, focus it.
+*/
+
+static INT_PTR SetContactIgnore(WPARAM wParam, LPARAM lParam)
+{
+ HWND hWnd = 0;
+
+ if(hWindowListIGN == 0)
+ hWindowListIGN = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
+
+ hWnd = WindowList_Find(hWindowListIGN, (HANDLE)wParam);
+ if ( wParam ) {
+ if ( hWnd == 0 )
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_QUICKIGNORE), 0, IgnoreDialogProc, (LPARAM)wParam);
+ else if ( IsWindow( hWnd ))
+ SetFocus(hWnd);
+ }
+ return 0;
+}
+
+/*
+ * service function: Set a contacts floating status.
+ * (clist_nicer+ specific service)
+ *
+ * Servicename = CList/SetContactFloating
+ *
+ * a floating contact appears as a small independent top level window anywhere on
+ * the desktop.
+*/
+
+static INT_PTR SetContactFloating(WPARAM wParam, LPARAM lParam)
+{
+ SendMessage(pcli->hwndContactTree, CLM_TOGGLEFLOATINGCONTACT, wParam, lParam);
+ return 0;
+}
+
+int InitCustomMenus(void)
+{
+ CreateServiceFunction("CloseAction",CloseAction);
+ CreateServiceFunction("CList/SetContactFloating", SetContactFloating);
+ CreateServiceFunction("CList/SetContactIgnore", SetContactIgnore);
+ {
+ //FYR: Visibility and ignore item moved back to clist_nicer from core
+ HANDLE hIgnoreItem = 0; // FYR: moved from global it is never used globally
+ CLISTMENUITEM mi = { 0 };
+ mi.cbSize = sizeof( mi );
+
+ if ( !hIgnoreItem ) {
+ mi.position = 200000;
+ mi.pszPopupName = ( char* )-1;
+ mi.pszService = "CList/SetContactIgnore";
+ mi.pszName = LPGEN("&Contact list settings...");
+ hIgnoreItem = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
+ }
+ }
+ hMainStatusMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS,0,0);
+ hMainMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN,0,0);
+
+ return 0;
+}
+
+void UninitCustomMenus(void)
+{
+
+}
diff --git a/plugins/Clist_nicer/SRC/clistmod.cpp b/plugins/Clist_nicer/SRC/clistmod.cpp
new file mode 100644
index 0000000000..a691dc44d4
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clistmod.cpp
@@ -0,0 +1,260 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: clistmod.cpp 12978 2010-10-17 06:50:51Z silvercircle $
+ *
+ */
+
+#include <commonheaders.h>
+
+BOOL (WINAPI *MySetProcessWorkingSetSize)(HANDLE, SIZE_T, SIZE_T) = 0;
+
+extern int AddEvent(WPARAM wParam, LPARAM lParam);
+extern int RemoveEvent(WPARAM wParam, LPARAM lParam);
+
+int InitCustomMenus(void);
+void UninitCustomMenus(void);
+INT_PTR GetContactStatusMessage(WPARAM wParam, LPARAM lParam);
+void TrayIconUpdateBase(const char *szChangedProto);
+int EventsProcessContactDoubleClick(HANDLE hContact);
+int SetHideOffline(WPARAM wParam, LPARAM lParam);
+
+extern HIMAGELIST hCListImages;
+
+extern int g_maxStatus;
+extern HANDLE hSvc_GetContactStatusMsg;
+extern ImageItem *g_CLUIImageItem;
+
+static INT_PTR GetStatusMode(WPARAM wParam, LPARAM lParam)
+{
+ return(g_maxStatus == ID_STATUS_OFFLINE ? pcli->currentDesiredStatusMode : g_maxStatus);
+}
+
+extern int ( *saveIconFromStatusMode )( const char *szProto, int status, HANDLE hContact );
+
+int IconFromStatusMode(const char *szProto, int status, HANDLE hContact, HICON *phIcon)
+{
+ char *szFinalProto;
+ int finalStatus;
+
+ if (szProto != NULL && !strcmp(szProto, cfg::dat.szMetaName) && cfg::dat.bMetaAvail && hContact != 0 && !(cfg::dat.dwFlags & CLUI_USEMETAICONS)) {
+ HANDLE hSubContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) hContact, 0);
+ szFinalProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hSubContact, 0);
+ finalStatus = (status == 0) ? (WORD) cfg::getWord(hSubContact, szFinalProto, "Status", ID_STATUS_OFFLINE) : status;
+ } else {
+ szFinalProto = (char*) szProto;
+ finalStatus = status;
+ }
+
+ if(status >= ID_STATUS_CONNECTING && status < ID_STATUS_OFFLINE && phIcon != NULL) {
+ if(szProto && cfg::dat.IcoLib_Avail) {
+ char szBuf[128];
+ mir_snprintf(szBuf, 128, "%s_conn", szProto);
+ *phIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)szBuf);
+ }
+ else if(szProto)
+ *phIcon = cfg::dat.hIconConnecting;;
+ }
+ return saveIconFromStatusMode(szFinalProto, finalStatus, hContact);
+}
+
+static int MenuItem_LockAvatar(WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+
+static int ContactListShutdownProc(WPARAM wParam, LPARAM lParam)
+{
+ UninitCustomMenus();
+ return 0;
+}
+
+int LoadContactListModule(void)
+{
+ HookEvent(ME_SYSTEM_SHUTDOWN, ContactListShutdownProc);
+ CreateServiceFunction(MS_CLIST_GETSTATUSMODE, GetStatusMode);
+
+ hSvc_GetContactStatusMsg = CreateServiceFunction("CList/GetContactStatusMsg", GetContactStatusMessage);
+ InitCustomMenus();
+ MySetProcessWorkingSetSize = (BOOL(WINAPI *)(HANDLE, SIZE_T, SIZE_T))GetProcAddress(GetModuleHandleA("kernel32"), "SetProcessWorkingSetSize");
+ return 0;
+}
+
+/*
+Begin of Hrk's code for bug
+*/
+#define GWVS_HIDDEN 1
+#define GWVS_VISIBLE 2
+#define GWVS_COVERED 3
+#define GWVS_PARTIALLY_COVERED 4
+
+int GetWindowVisibleState(HWND hWnd, int iStepX, int iStepY)
+{
+ RECT rc = {0}, rcUpdate = {0};
+ POINT pt = {0};
+ register int i = 0, j = 0, width = 0, height = 0, iCountedDots = 0, iNotCoveredDots = 0;
+ BOOL bPartiallyCovered = FALSE;
+ HWND hAux = 0;
+
+ if (hWnd == NULL) {
+ SetLastError(0x00000006); //Wrong handle
+ return -1;
+ }
+ //Some defaults now. The routine is designed for thin and tall windows.
+
+ if (IsIconic(hWnd) || !IsWindowVisible(hWnd))
+ return GWVS_HIDDEN;
+ else {
+ HRGN rgn = 0;
+ POINT ptOrig;
+ RECT rcClient;
+ int clip = (int)cfg::dat.bClipBorder;
+
+ GetClientRect(hWnd, &rcClient);
+ ptOrig.x = ptOrig.y = 0;
+ ClientToScreen(hWnd, &ptOrig);
+ rc.left = ptOrig.x;
+ rc.top = ptOrig.y;
+ rc.right = rc.left + rcClient.right;
+ rc.bottom = rc.top + rcClient.bottom;
+
+ //GetWindowRect(hWnd, &rc);
+ width = rc.right - rc.left;
+ height = rc.bottom - rc.top;
+
+ if (iStepX <= 0)
+ iStepX = 4;
+ if (iStepY <= 0)
+ iStepY = 16;
+
+ /*
+ * use a rounded clip region to determine which pixels are covered
+ * this will avoid problems with certain XP themes which are using transparency for rounded
+ * window frames (reluna being one popular example).
+
+ * the radius of 8 should be sufficient for most themes as they usually don't use bigger
+ * radii.
+ * also, clip at least 2 pixels from the border (same reason)
+ */
+
+ if(g_CLUIImageItem)
+ clip = 5;
+ else
+ clip = 0;
+ //clip = max(clip, DBGetContactSettingByte(NULL, "CLUI", "ignoreframepixels", 2));
+ //rgn = CreateRoundRectRgn(rc.left + clip, rc.top + clip, rc.right - clip, rc.bottom - clip, 10 + clip, 10 + clip);
+ //rgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
+ //for (i = rc.top + 3 + clip; i < rc.bottom - 3 - clip; i += (height / iStepY)) {
+ for (i = rc.top + clip; i < rc.bottom; i += (height / iStepY)) {
+ pt.y = i;
+ //for (j = rc.left + 3 + clip; j < rc.right - 3 - clip; j += (width / iStepX)) {
+ for (j = rc.left + clip; j < rc.right; j += (width / iStepX)) {
+ /*if(rgn) {
+ ptTest.x = j;
+ ptTest.y = i;
+ if(!PtInRegion(rgn, ptTest.x, ptTest.y)) {
+ continue;
+ }
+ }*/
+ pt.x = j;
+ hAux = WindowFromPoint(pt);
+ while (GetParent(hAux) != NULL)
+ hAux = GetParent(hAux);
+ if (hAux != hWnd && hAux) //There's another window!
+ bPartiallyCovered = TRUE;
+ else
+ iNotCoveredDots++; //Let's count the not covered dots.
+ iCountedDots++; //Let's keep track of how many dots we checked.
+ }
+ }
+ if(rgn)
+ DeleteObject(rgn);
+
+ if (iNotCoveredDots == iCountedDots) //Every dot was not covered: the window is visible.
+ return GWVS_VISIBLE;
+ else if (iNotCoveredDots == 0) //They're all covered!
+ return GWVS_COVERED;
+ else //There are dots which are visible, but they are not as many as the ones we counted: it's partially covered.
+ return GWVS_PARTIALLY_COVERED;
+ }
+}
+
+int ShowHide(WPARAM wParam, LPARAM lParam)
+{
+ BOOL bShow = FALSE;
+
+ int iVisibleState = pcli->pfnGetWindowVisibleState(pcli->hwndContactList, 0, 0);
+
+ if(IsIconic(pcli->hwndContactList)) {
+ SendMessage(pcli->hwndContactList, WM_SYSCOMMAND, SC_RESTORE, 0);
+ bShow = TRUE;
+ }
+ else {
+ switch (iVisibleState) {
+ case GWVS_PARTIALLY_COVERED:
+ //If we don't want to bring it to top, we can use a simple break. This goes against readability ;-) but the comment explains it.
+ if (!cfg::getByte("CList", "BringToFront", SETTING_BRINGTOFRONT_DEFAULT))
+ break;
+ case GWVS_COVERED: //Fall through (and we're already falling)
+ case GWVS_HIDDEN:
+ bShow = TRUE;
+ break;
+ case GWVS_VISIBLE: //This is not needed, but goes for readability.
+ bShow = FALSE;
+ break;
+ case -1: //We can't get here, both cli.hwndContactList and iStepX and iStepY are right.
+ return 0;
+ }
+ }
+
+ if (bShow == TRUE) {
+ RECT rcWindow;
+
+ SetWindowPos(pcli->hwndContactList, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOCOPYBITS);
+ if (!cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT))
+ SetWindowPos(pcli->hwndContactList, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOCOPYBITS);
+ SetForegroundWindow(pcli->hwndContactList);
+ //SetActiveWindow(pcli->hwndContactList);
+ ShowWindow(pcli->hwndContactList, SW_SHOW);
+ cfg::writeByte("CList", "State", SETTING_STATE_NORMAL);
+
+ GetWindowRect(pcli->hwndContactList, &rcWindow);
+ if (Utils_AssertInsideScreen(&rcWindow) == 1)
+ {
+ MoveWindow(pcli->hwndContactList, rcWindow.left, rcWindow.top,
+ rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE);
+ }
+ }
+ else { //It needs to be hidden
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+ cfg::writeByte("CList", "State", SETTING_STATE_HIDDEN);
+ if (MySetProcessWorkingSetSize != NULL && cfg::getByte("CList", "DisableWorkingSet", 1))
+ MySetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
+ }
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/clistopts.cpp b/plugins/Clist_nicer/SRC/clistopts.cpp
new file mode 100644
index 0000000000..520c9ceb49
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clistopts.cpp
@@ -0,0 +1,222 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include "commonheaders.h"
+
+void LoadContactTree(void);
+void SortContacts(void);
+
+static int opt_gen_opts_changed = 0;
+
+static void __setFlag(DWORD dwFlag, int iMode)
+{
+ cfg::dat.dwFlags = iMode ? cfg::dat.dwFlags | dwFlag : cfg::dat.dwFlags & ~dwFlag;
+}
+
+INT_PTR CALLBACK DlgProcGenOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_USER+1:
+ {
+ HANDLE hContact = (HANDLE) wParam;
+ DBCONTACTWRITESETTING *ws = (DBCONTACTWRITESETTING *) lParam;
+ if (hContact == NULL && ws != NULL && ws->szModule != NULL && ws->szSetting != NULL && lstrcmpiA(ws->szModule, "CList") == 0 && lstrcmpiA(ws->szSetting, "UseGroups") == 0 && IsWindowVisible(hwndDlg)) {
+ CheckDlgButton(hwndDlg, IDC_DISABLEGROUPS, ws->value.bVal == 0);
+ }
+ break;
+ }
+ case WM_DESTROY:
+ UnhookEvent((HANDLE) GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
+ break;
+
+ case WM_INITDIALOG:
+ opt_gen_opts_changed = 0;
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) HookEventMessage(ME_DB_CONTACT_SETTINGCHANGED, hwndDlg, WM_USER + 1));
+ CheckDlgButton(hwndDlg, IDC_ONTOP, cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_HIDEOFFLINE, cfg::getByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_HIDEEMPTYGROUPS, cfg::getByte("CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DISABLEGROUPS, cfg::getByte("CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hwndDlg, IDC_CONFIRMDELETE, cfg::getByte("CList", "ConfirmDelete", SETTING_CONFIRMDELETE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ {
+ DWORD caps = CallService(MS_CLUI_GETCAPS, CLUICAPS_FLAGS1, 0);
+ if (!(caps & CLUIF_HIDEEMPTYGROUPS))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_HIDEEMPTYGROUPS), SW_HIDE);
+ if (!(caps & CLUIF_DISABLEGROUPS))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_DISABLEGROUPS), SW_HIDE);
+ if (caps & CLUIF_HASONTOPOPTION)
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ONTOP), SW_HIDE);
+ if (caps & CLUIF_HASAUTOHIDEOPTION) {
+ }
+ }
+
+ CheckDlgButton(hwndDlg, IDC_SHOWBUTTONBAR, cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS);
+ CheckDlgButton(hwndDlg, IDC_SHOWBOTTOMBUTTONS, cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS);
+ CheckDlgButton(hwndDlg, IDC_CLISTSUNKEN, cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN);
+ CheckDlgButton(hwndDlg, IDC_EVENTAREAAUTOHIDE, cfg::dat.dwFlags & CLUI_FRAME_AUTOHIDENOTIFY);
+ CheckDlgButton(hwndDlg, IDC_EVENTAREASUNKEN, (cfg::dat.dwFlags & CLUI_FRAME_EVENTAREASUNKEN) ? BST_CHECKED : BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_ONECLK, cfg::getByte("CList", "Tray1Click", SETTING_TRAY1CLICK_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ALWAYSSTATUS, cfg::getByte("CList", "AlwaysStatus", SETTING_ALWAYSSTATUS_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ALWAYSMULTI, !cfg::getByte("CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DONTCYCLE, cfg::getByte("CList", "TrayIcon", SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_SINGLE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_CYCLE, cfg::getByte("CList", "TrayIcon", SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_CYCLE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_MULTITRAY, cfg::getByte("CList", "TrayIcon", SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_MULTI ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DISABLEBLINK, cfg::getByte("CList", "DisableTrayFlash", 0) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ICONBLINK, cfg::getByte("CList", "NoIconBlink", 0) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ if (IsDlgButtonChecked(hwndDlg, IDC_DONTCYCLE)) {
+ Utils::enableDlgControl(hwndDlg, IDC_CYCLETIMESPIN, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_CYCLETIME, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_ALWAYSMULTI, FALSE);
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_CYCLE)) {
+ Utils::enableDlgControl(hwndDlg, IDC_PRIMARYSTATUS, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_ALWAYSMULTI, FALSE);
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_MULTITRAY)) {
+ Utils::enableDlgControl(hwndDlg, IDC_CYCLETIMESPIN, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_CYCLETIME, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_PRIMARYSTATUS, FALSE);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_CYCLETIMESPIN, UDM_SETRANGE, 0, MAKELONG(120, 1));
+ SendDlgItemMessage(hwndDlg, IDC_CYCLETIMESPIN, UDM_SETPOS, 0, MAKELONG(cfg::getWord("CList", "CycleTime", SETTING_CYCLETIME_DEFAULT), 0)); {
+ int i, count, item;
+ PROTOACCOUNT **accs;
+ DBVARIANT dbv = {
+ DBVT_DELETED
+ };
+ DBGetContactSetting(NULL, "CList", "PrimaryStatus", &dbv);
+ ProtoEnumAccounts( &count, &accs );
+ item = SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_ADDSTRING, 0, (LPARAM) TranslateT("Global"));
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETITEMDATA, item, (LPARAM) 0);
+ for (i = 0; i < count; i++) {
+ if ( !IsAccountEnabled(accs[i]) || CallProtoService(accs[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) == 0)
+ continue;
+
+ item = SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_ADDSTRING, 0, (LPARAM) accs[i]->tszAccountName);
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETITEMDATA, item, (LPARAM)accs[i] );
+ if (dbv.type == DBVT_ASCIIZ && !lstrcmpA(dbv.pszVal, accs[i]->szModuleName ))
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETCURSEL, item, 0);
+ }
+ }
+ if (-1 == (int) SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETCURSEL, 0, 0))
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETCURSEL, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM) GetDlgItem(hwndDlg, IDC_BLINKTIME), 0); // set buddy
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE, 0, MAKELONG(0x3FFF, 250));
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(cfg::getWord("CList", "IconFlashTime", 550), 0));
+ CheckDlgButton(hwndDlg, IDC_NOTRAYINFOTIPS, cfg::dat.bNoTrayTips ? 1 : 0);
+ CheckDlgButton(hwndDlg, IDC_APPLYLASTVIEWMODE, cfg::getByte("CList", "AutoApplyLastViewMode", 0) ? 1 : 0);
+ return TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_DONTCYCLE || LOWORD(wParam) == IDC_CYCLE || LOWORD(wParam) == IDC_MULTITRAY) {
+ Utils::enableDlgControl(hwndDlg, IDC_PRIMARYSTATUS, IsDlgButtonChecked(hwndDlg, IDC_DONTCYCLE));
+ Utils::enableDlgControl(hwndDlg, IDC_CYCLETIME, IsDlgButtonChecked(hwndDlg, IDC_CYCLE));
+ Utils::enableDlgControl(hwndDlg, IDC_CYCLETIMESPIN, IsDlgButtonChecked(hwndDlg, IDC_CYCLE));
+ Utils::enableDlgControl(hwndDlg, IDC_ALWAYSMULTI, IsDlgButtonChecked(hwndDlg, IDC_MULTITRAY));
+ }
+ if ((LOWORD(wParam) == IDC_CYCLETIME) && HIWORD(wParam) != EN_CHANGE)
+ break;
+ if (LOWORD(wParam) == IDC_PRIMARYSTATUS && HIWORD(wParam) != CBN_SELCHANGE)
+ break;
+ if ((LOWORD(wParam) == IDC_CYCLETIME) && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ if (LOWORD(wParam) == IDC_BLINKTIME && HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0; // dont make apply enabled during buddy set crap
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ opt_gen_opts_changed = TRUE;
+ break;
+
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ if(!opt_gen_opts_changed)
+ return TRUE;
+
+ cfg::writeByte("CList", "HideOffline", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_HIDEOFFLINE));
+ {
+ DWORD caps = CallService(MS_CLUI_GETCAPS, CLUICAPS_FLAGS1, 0);
+ if (caps & CLUIF_HIDEEMPTYGROUPS)
+ cfg::writeByte("CList", "HideEmptyGroups", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_HIDEEMPTYGROUPS));
+ if (caps & CLUIF_DISABLEGROUPS)
+ cfg::writeByte("CList", "UseGroups", (BYTE) ! IsDlgButtonChecked(hwndDlg, IDC_DISABLEGROUPS));
+ if (!(caps & CLUIF_HASONTOPOPTION)) {
+ cfg::writeByte("CList", "OnTop", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONTOP));
+ SetWindowPos(pcli->hwndContactList, IsDlgButtonChecked(hwndDlg, IDC_ONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ }
+ if (!(caps & CLUIF_HASAUTOHIDEOPTION)) {
+ }
+ }
+ cfg::writeByte("CList", "ConfirmDelete", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CONFIRMDELETE));
+ cfg::writeByte("CList", "Tray1Click", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONECLK));
+ cfg::writeByte("CList", "AlwaysStatus", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ALWAYSSTATUS));
+ cfg::writeByte("CList", "AlwaysMulti", (BYTE) ! IsDlgButtonChecked(hwndDlg, IDC_ALWAYSMULTI));
+ cfg::writeByte("CList", "TrayIcon", (BYTE) (IsDlgButtonChecked(hwndDlg, IDC_DONTCYCLE) ? SETTING_TRAYICON_SINGLE : (IsDlgButtonChecked(hwndDlg, IDC_CYCLE) ? SETTING_TRAYICON_CYCLE : SETTING_TRAYICON_MULTI)));
+ cfg::writeWord("CList", "CycleTime", (WORD) SendDlgItemMessage(hwndDlg, IDC_CYCLETIMESPIN, UDM_GETPOS, 0, 0));
+ cfg::writeWord("CList", "IconFlashTime", (WORD) SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0));
+ cfg::writeByte("CList", "DisableTrayFlash", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ cfg::writeByte("CList", "NoIconBlink", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ICONBLINK));
+ cfg::writeByte("CList", "AutoApplyLastViewMode", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_APPLYLASTVIEWMODE));
+
+ __setFlag(CLUI_FRAME_EVENTAREASUNKEN, IsDlgButtonChecked(hwndDlg, IDC_EVENTAREASUNKEN));
+ __setFlag(CLUI_FRAME_AUTOHIDENOTIFY, IsDlgButtonChecked(hwndDlg, IDC_EVENTAREAAUTOHIDE));
+
+ __setFlag(CLUI_FRAME_SHOWTOPBUTTONS, IsDlgButtonChecked(hwndDlg, IDC_SHOWBUTTONBAR));
+ __setFlag(CLUI_FRAME_SHOWBOTTOMBUTTONS, IsDlgButtonChecked(hwndDlg, IDC_SHOWBOTTOMBUTTONS));
+ __setFlag(CLUI_FRAME_CLISTSUNKEN, IsDlgButtonChecked(hwndDlg, IDC_CLISTSUNKEN));
+
+ cfg::dat.bNoTrayTips = IsDlgButtonChecked(hwndDlg, IDC_NOTRAYINFOTIPS) ? 1 : 0;
+ cfg::writeByte("CList", "NoTrayTips", (BYTE)cfg::dat.bNoTrayTips);
+ {
+ int cursel = SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETCURSEL, 0, 0);
+ PROTOACCOUNT* pa = (PROTOACCOUNT*)SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETITEMDATA, cursel, 0);
+ if ( !pa )
+ DBDeleteContactSetting(NULL, "CList", "PrimaryStatus");
+ else
+ cfg::writeString(NULL, "CList", "PrimaryStatus", pa->szModuleName );
+ }
+ pcli->pfnTrayIconIconsChanged();
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+ ConfigureFrame();
+ ConfigureCLUIGeometry(1);
+ ConfigureEventArea(pcli->hwndContactList);
+ HideShowNotifyFrame();
+ SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ LoadContactTree(); /* this won't do job properly since it only really works when changes happen */
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+
+ opt_gen_opts_changed = 0;
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/Clist_nicer/SRC/clistsettings.cpp b/plugins/Clist_nicer/SRC/clistsettings.cpp
new file mode 100644
index 0000000000..ce58e22b45
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clistsettings.cpp
@@ -0,0 +1,33 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include "commonheaders.h"
+
+INT_PTR GetContactStatusMessage(WPARAM wParam, LPARAM lParam)
+{
+ if(!cfg::shutDown)
+ return SendMessage(pcli->hwndContactTree, CLM_GETSTATUSMSG, wParam, lParam);
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/clisttray.cpp b/plugins/Clist_nicer/SRC/clisttray.cpp
new file mode 100644
index 0000000000..7a20e71ce3
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clisttray.cpp
@@ -0,0 +1,171 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include "commonheaders.h"
+
+#define TRAYICON_ID_BASE 100
+#define TIM_CALLBACK (WM_USER+1857)
+#define TIM_CREATE (WM_USER+1858)
+
+extern HIMAGELIST hCListImages;
+
+// don't move to win2k.h, need new and old versions to work on 9x/2000/XP
+#define NIF_STATE 0x00000008
+#define NIF_INFO 0x00000010
+
+void TrayIconUpdateBase(const char *szChangedProto)
+{
+ int i,count,netProtoCount,changed = -1;
+ PROTOACCOUNT **accs;
+ int averageMode = 0;
+ HWND hwnd = pcli->hwndContactList;
+
+ if (pcli->cycleTimerId)
+ KillTimer(NULL, pcli->cycleTimerId); pcli->cycleTimerId = 0;
+
+ ProtoEnumAccounts( &count, &accs );
+ for (i = 0,netProtoCount = 0; i < count; i++) {
+ if ( !pcli->pfnGetProtocolVisibility( accs[i]->szModuleName ))
+ continue;
+ netProtoCount++;
+ if (!lstrcmpA(szChangedProto, accs[i]->szModuleName ))
+ pcli->cycleStep = i;
+ if (averageMode == 0)
+ averageMode = CallProtoService( accs[i]->szModuleName, PS_GETSTATUS, 0, 0);
+ else if (averageMode != CallProtoService( accs[i]->szModuleName, PS_GETSTATUS, 0, 0)) {
+ averageMode = -1; break;
+ }
+ }
+ if (netProtoCount > 1) {
+ if (averageMode > 0) {
+ if (cfg::getByte("CList", "TrayIcon", SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_MULTI) {
+ if (cfg::getByte("CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT)) {
+ HICON hIcon = 0;
+ int iIcon = IconFromStatusMode(szChangedProto, averageMode, 0, &hIcon);
+ if(hIcon)
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), szChangedProto);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), szChangedProto);
+ }
+ else if (pcli->trayIcon && pcli->trayIcon[0].szProto != NULL) {
+ pcli->pfnTrayIconDestroy(hwnd);
+ pcli->pfnTrayIconInit(hwnd);
+ }
+ else {
+ HICON hIcon = 0;
+ int iIcon = IconFromStatusMode(NULL, averageMode, 0, &hIcon);
+
+ if(hIcon)
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), NULL);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), NULL);
+ }
+ } else {
+ HICON hIcon = 0;
+ int iIcon = IconFromStatusMode(NULL, averageMode, 0, &hIcon);
+
+ if(hIcon)
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), NULL);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), NULL);
+ }
+ } else {
+ switch (cfg::getByte("CList", "TrayIcon", SETTING_TRAYICON_DEFAULT)) {
+ case SETTING_TRAYICON_SINGLE:
+ {
+ DBVARIANT dbv = {DBVT_DELETED};
+ int iIcon = 0;
+ HICON hIcon = 0;
+ char *szProto;
+ if (cfg::getString(NULL, "CList", "PrimaryStatus", &dbv))
+ szProto = NULL;
+ else
+ szProto = dbv.pszVal;
+ iIcon = IconFromStatusMode(szProto, szProto ? CallProtoService(szProto, PS_GETSTATUS, 0, 0) : CallService(MS_CLIST_GETSTATUSMODE, 0, 0), 0, &hIcon);
+ if(hIcon)
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), NULL);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), NULL);
+ DBFreeVariant(&dbv);
+ break;
+ }
+ case SETTING_TRAYICON_CYCLE:
+ {
+ HICON hIcon = 0;
+ int iIcon = IconFromStatusMode(szChangedProto, CallProtoService(szChangedProto, PS_GETSTATUS, 0, 0), 0, &hIcon);
+
+ pcli->cycleTimerId = SetTimer(NULL, 0, cfg::getWord("CList", "CycleTime", SETTING_CYCLETIME_DEFAULT) * 1000, pcli->pfnTrayCycleTimerProc);
+ if(hIcon)
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), NULL);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), NULL);
+ break;
+ }
+ case SETTING_TRAYICON_MULTI:
+ if ( !pcli->trayIcon )
+ pcli->pfnTrayIconRemove(NULL, NULL);
+ else if (cfg::getByte("CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT)) {
+ HICON hIcon = 0;
+ int iIcon = IconFromStatusMode(szChangedProto, CallProtoService(szChangedProto, PS_GETSTATUS, 0, 0), 0, &hIcon);
+
+ if(hIcon)
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), szChangedProto);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), szChangedProto);
+ }
+ else {
+ pcli->pfnTrayIconDestroy(hwnd);
+ pcli->pfnTrayIconInit(hwnd);
+ }
+ break;
+ }
+ }
+ } else {
+ HICON hIcon = 0;
+ int iIcon = IconFromStatusMode(NULL, averageMode, 0, &hIcon);
+ if ( hIcon )
+ changed = pcli->pfnTrayIconSetBaseInfo(CopyIcon(hIcon), NULL);
+ else
+ changed = pcli->pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, iIcon, ILD_NORMAL), NULL);
+ }
+ if (changed != -1 && pcli->trayIcon[changed].isBase)
+ pcli->pfnTrayIconUpdate( pcli->trayIcon[changed].hBaseIcon, NULL, pcli->trayIcon[changed].szProto, 1);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+extern INT_PTR ( *saveTrayIconProcessMessage )(WPARAM wParam, LPARAM lParam);
+
+INT_PTR TrayIconProcessMessage(WPARAM wParam, LPARAM lParam)
+{
+ MSG* msg = ( MSG* )wParam;
+ if ( msg->message == TIM_CALLBACK && msg->lParam == WM_MOUSEMOVE ) {
+ if ( cfg::dat.bNoTrayTips ) {
+ *((LRESULT *) lParam) = 0;
+ return TRUE;
+ } }
+
+ return saveTrayIconProcessMessage(wParam, lParam);
+}
diff --git a/plugins/Clist_nicer/SRC/clnplus.cpp b/plugins/Clist_nicer/SRC/clnplus.cpp
new file mode 100644
index 0000000000..24c5fdddff
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clnplus.cpp
@@ -0,0 +1,40 @@
+/*
+ * test for gdi+
+ */
+
+#include <commonheaders.h>
+#include <shobjidl.h>
+
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0501
+
+#define _CLN_GDIP
+
+
+#undef Translate
+
+void RemoveFromTaskBar(HWND hWnd)
+{
+ ITaskbarList *pTaskbarList = NULL;
+
+ if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, IID_ITaskbarList,
+ (void **)(&pTaskbarList))) && pTaskbarList != NULL) {
+ if (SUCCEEDED(pTaskbarList->HrInit())) {
+ pTaskbarList->DeleteTab(hWnd);
+ }
+ pTaskbarList->Release();
+ }
+}
+
+void AddToTaskBar(HWND hWnd)
+{
+ ITaskbarList *pTaskbarList = NULL;
+
+ if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, IID_ITaskbarList,
+ (void **)(&pTaskbarList))) && pTaskbarList != NULL) {
+ if (SUCCEEDED(pTaskbarList->HrInit())) {
+ pTaskbarList->AddTab(hWnd);
+ }
+ pTaskbarList->Release();
+ }
+}
diff --git a/plugins/Clist_nicer/SRC/clui.cpp b/plugins/Clist_nicer/SRC/clui.cpp
new file mode 100644
index 0000000000..0a3d3133ed
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/clui.cpp
@@ -0,0 +1,2533 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: clui.cpp 13813 2011-08-31 21:49:46Z borkra $
+ *
+ */
+
+#include <commonheaders.h>
+#include <m_findadd.h>
+#include <m_icq.h>
+#include <m_updater.h>
+#include "../cluiframes/cluiframes.h"
+#include "../coolsb/coolscroll.h"
+
+#define TM_AUTOALPHA 1
+#define TIMERID_AUTOSIZE 100
+#define MENU_MIRANDAMENU 0xFFFF1234
+
+int g_fading_active = 0;
+
+static RECT g_PreSizeRect, g_SizingRect;
+static int g_sizingmethod;
+static LONG g_CLUI_x_off, g_CLUI_y_off, g_CLUI_y1_off, g_CLUI_x1_off;
+static RECT rcWPC;
+
+static int transparentFocus = 1;
+static byte oldhideoffline;
+static int disableautoupd = 1;
+HANDLE hFrameContactTree;
+extern HIMAGELIST hCListImages;
+extern PLUGININFOEX pluginInfo;
+extern WNDPROC OldStatusBarProc;
+extern RECT old_window_rect, new_window_rect;
+
+extern BOOL g_trayTooltipActive;
+extern POINT tray_hover_pos;
+extern HWND g_hwndViewModeFrame, g_hwndEventArea;
+
+extern ImageItem *g_CLUIImageItem;
+extern HBRUSH g_CLUISkinnedBkColor;
+extern StatusItems_t *StatusItems;
+extern HWND g_hwndSFL;
+extern ButtonItem *g_ButtonItems;
+extern COLORREF g_CLUISkinnedBkColorRGB;
+extern wndFrame *wndFrameCLC;
+
+HIMAGELIST himlExtraImages = 0;
+
+static BYTE old_cliststate, show_on_first_autosize = FALSE;
+
+RECT cluiPos;
+
+TCHAR *statusNames[12];
+
+extern LRESULT CALLBACK EventAreaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+extern HANDLE hNotifyFrame;
+
+int SortList(WPARAM wParam, LPARAM lParam);
+int LoadCluiServices(void);
+void InitGroupMenus();
+void ReloadExtraIcons();
+void FS_RegisterFonts();
+void LoadExtraIconModule();
+int MTG_OnmodulesLoad(WPARAM wParam, LPARAM lParam);
+void RemoveFromTaskBar(HWND hWnd);
+void FLT_ShowHideAll(int showCmd);
+void FLT_SnapToEdges(HWND hwnd);
+void DestroyTrayMenu(HMENU hMenu);
+
+extern LONG g_cxsmIcon, g_cysmIcon;
+extern HANDLE hSoundHook;
+extern HANDLE hIcoLibChanged;
+extern HANDLE hExtraImageListRebuilding, hExtraImageApplying;
+
+SIZE g_oldSize = {0};
+POINT g_oldPos = {0};
+int during_sizing = 0;
+extern int dock_prevent_moving;
+
+static HDC hdcLockedPoint = 0;
+static HBITMAP hbmLockedPoint = 0, hbmOldLockedPoint = 0;
+
+HICON overlayicons[10];
+
+struct CluiTopButton top_buttons[] = {
+ 0, 0, 0, IDC_TBTOPMENU, IDI_TBTOPMENU, 0, "CLN_topmenu", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 1, LPGENT("Show menu"),
+ 0, 0, 0, IDC_TBHIDEOFFLINE, IDI_HIDEOFFLINE, 0, "CLN_online", NULL, 0, 2, LPGENT("Show / hide offline contacts"),
+ 0, 0, 0, IDC_TBHIDEGROUPS, IDI_HIDEGROUPS, 0, "CLN_groups", NULL, 0, 4, LPGENT("Toggle group mode"),
+ 0, 0, 0, IDC_TBFINDANDADD, IDI_FINDANDADD, 0, "CLN_findadd", NULL, TOPBUTTON_PUSH, 8, LPGENT("Find and add contacts"),
+ 0, 0, 0, IDC_TBACCOUNTS, IDI_TBACCOUNTS, 0, "CLN_accounts", NULL, TOPBUTTON_PUSH, 8192, LPGENT("Accounts"),
+ 0, 0, 0, IDC_TBOPTIONS, IDI_TBOPTIONS, 0, "CLN_options", NULL, TOPBUTTON_PUSH, 16, LPGENT("Open preferences"),
+ 0, 0, 0, IDC_TBSOUND, IDI_SOUNDSON, IDI_SOUNDSOFF, "CLN_sound", "CLN_soundsoff", 0, 32, LPGENT("Toggle sounds"),
+ 0, 0, 0, IDC_TBMINIMIZE, IDI_MINIMIZE, 0, "CLN_minimize", NULL, TOPBUTTON_PUSH, 64, LPGENT("Minimize contact list"),
+ 0, 0, 0, IDC_TBTOPSTATUS, 0, 0, "CLN_topstatus", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 128, LPGENT("Status menu"),
+ 0, 0, 0, IDC_TABSRMMSLIST, IDI_TABSRMMSESSIONLIST, 0, "CLN_slist", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 256, LPGENT("tabSRMM session list"),
+ 0, 0, 0, IDC_TABSRMMMENU, IDI_TABSRMMMENU, 0, "CLN_menu", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 512, LPGENT("tabSRMM Menu"),
+
+ 0, 0, 0, IDC_TBSELECTVIEWMODE, IDI_CLVM_SELECT, 0, "CLN_CLVM_select", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 1024, LPGENT("Select view mode"),
+ 0, 0, 0, IDC_TBCONFIGUREVIEWMODE, IDI_CLVM_OPTIONS, 0, "CLN_CLVM_options", NULL, TOPBUTTON_PUSH, 2048, LPGENT("Setup view modes"),
+ 0, 0, 0, IDC_TBCLEARVIEWMODE, IDI_DELETE, 0, "CLN_CLVM_reset", NULL, TOPBUTTON_PUSH, 4096, LPGENT("Clear view mode"),
+
+ 0, 0, 0, IDC_TBGLOBALSTATUS, 0, 0, "", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 0, LPGENT("Set status modes"),
+ 0, 0, 0, IDC_TBMENU, IDI_MINIMIZE, 0, "", NULL, TOPBUTTON_PUSH | TOPBUTTON_SENDONDOWN, 0, LPGENT("Open main menu"),
+ (HWND) - 1, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static struct IconDesc myIcons[] = {
+ "CLN_online", LPGEN("Toggle show online/offline"), -IDI_HIDEOFFLINE,
+ "CLN_groups", LPGEN("Toggle groups"), -IDI_HIDEGROUPS,
+ "CLN_findadd", LPGEN("Find contacts"), -IDI_FINDANDADD,
+ "CLN_options", LPGEN("Open preferences"), -IDI_TBOPTIONS,
+ "CLN_sound", LPGEN("Toggle sounds"), -IDI_SOUNDSON,
+ "CLN_minimize", LPGEN("Minimize contact list"), -IDI_MINIMIZE,
+ "CLN_slist", LPGEN("Show tabSRMM session list"), -IDI_TABSRMMSESSIONLIST,
+ "CLN_menu", LPGEN("Show tabSRMM menu"), -IDI_TABSRMMMENU,
+ "CLN_soundsoff", LPGEN("Sounds are off"), -IDI_SOUNDSOFF,
+ "CLN_CLVM_select", LPGEN("Select view mode"), -IDI_CLVM_SELECT,
+ "CLN_CLVM_reset", LPGEN("Reset view mode"), -IDI_DELETE,
+ "CLN_CLVM_options", LPGEN("Configure view modes"), -IDI_CLVM_OPTIONS,
+ "CLN_topmenu", LPGEN("Show menu"), -IDI_TBTOPMENU,
+ "CLN_accounts", LPGEN("Setup accounts"), -IDI_TBACCOUNTS,
+ NULL, NULL, 0
+};
+
+/*
+ * simple service for testing purpose
+ * get the *proper* time zone offset for the given contact
+ * only UserInfoEx can currently set real time zones
+ *
+ * This stuff should go into the core...
+ *
+ * returns: timediff for the contact in seconds. This value has inverted sign,
+ * so you need to SUBTRACT it from your current time in order to get the correct
+ * target time.
+ *
+ * If no real time zone is set, the service falls back to ordinary GMT offsets
+ */
+
+static void Tweak_It(COLORREF clr)
+{
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED);
+ API::pfnSetLayeredWindowAttributes(pcli->hwndContactList, clr, 0, LWA_COLORKEY);
+ cfg::dat.colorkey = clr;
+}
+
+static void LayoutButtons(HWND hwnd, RECT *rc)
+{
+ int i;
+ RECT rect;
+ BYTE rightButton = 1, leftButton = 0;
+ BYTE left_offset = cfg::dat.bCLeft - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0);
+ BYTE right_offset = cfg::dat.bCRight - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0);
+ BYTE delta = left_offset + right_offset;
+ ButtonItem *btnItems = g_ButtonItems;
+
+ if (rc == NULL)
+ GetClientRect(hwnd, &rect);
+ else
+ rect = *rc;
+
+ rect.bottom -= cfg::dat.bCBottom;
+
+ if (g_ButtonItems) {
+ while (btnItems) {
+ LONG x = (btnItems->xOff >= 0) ? rect.left + btnItems->xOff : rect.right - abs(btnItems->xOff);
+ LONG y = (btnItems->yOff >= 0) ? rect.top + btnItems->yOff : rect.bottom - cfg::dat.statusBarHeight;
+
+ SetWindowPos(btnItems->hWnd, 0, x, y, btnItems->width, btnItems->height,
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ btnItems = btnItems->nextItem;
+ }
+ SetWindowPos(top_buttons[15].hwnd, 0, 2 + left_offset, rect.bottom - cfg::dat.statusBarHeight - BUTTON_HEIGHT_D - 1,
+ BUTTON_WIDTH_D * 3, BUTTON_HEIGHT_D + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ SetWindowPos(top_buttons[14].hwnd, 0, left_offset + (3 * BUTTON_WIDTH_D) + 3, rect.bottom - cfg::dat.statusBarHeight - BUTTON_HEIGHT_D - 1,
+ rect.right - delta - (3 * BUTTON_WIDTH_D + 5), BUTTON_HEIGHT_D + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ return;
+ }
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+ if (top_buttons[i].hwnd == 0)
+ continue;
+ if (top_buttons[i].id == IDC_TBMENU) {
+ SetWindowPos(top_buttons[i].hwnd, 0, 2 + left_offset, rect.bottom - cfg::dat.statusBarHeight - BUTTON_HEIGHT_D - 1,
+ BUTTON_WIDTH_D * 3, BUTTON_HEIGHT_D + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+
+ } else if (top_buttons[i].id == IDC_TBGLOBALSTATUS) {
+ SetWindowPos(top_buttons[i].hwnd, 0, left_offset + (3 * BUTTON_WIDTH_D) + 3, rect.bottom - cfg::dat.statusBarHeight - BUTTON_HEIGHT_D - 1,
+ rect.right - delta - (3 * BUTTON_WIDTH_D + 5), BUTTON_HEIGHT_D + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ }
+ if (!(top_buttons[i].visibilityOrder & cfg::dat.toolbarVisibility))
+ continue;
+ if (top_buttons[i].id == IDC_TBTOPSTATUS || top_buttons[i].id == IDC_TBMINIMIZE || top_buttons[i].id == IDC_TABSRMMMENU || top_buttons[i].id == IDC_TABSRMMSLIST) {
+ SetWindowPos(top_buttons[i].hwnd, 0, rect.right - right_offset - 2 - (rightButton * (cfg::dat.dwButtonWidth + 1)), 2 + cfg::dat.bCTop, cfg::dat.dwButtonWidth, cfg::dat.dwButtonHeight - 2,
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ rightButton++;
+ continue;
+ } else {
+ SetWindowPos(top_buttons[i].hwnd, 0, left_offset + 3 + (leftButton * (cfg::dat.dwButtonWidth + 1)), 2 + cfg::dat.bCTop, cfg::dat.dwButtonWidth, cfg::dat.dwButtonHeight - 2,
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ leftButton++;
+ }
+ }
+}
+
+static int FS_FontsChanged(WPARAM wParam, LPARAM lParam)
+{
+ pcli->pfnClcOptionsChanged();
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+}
+
+/*
+* create the CLC control, but not yet the frame. The frame containing the CLC should be created as the
+* last frame of all.
+*/
+
+static HWND PreCreateCLC(HWND parent)
+{
+ pcli->hwndContactTree = CreateWindow(CLISTCONTROL_CLASS, _T(""),
+ WS_CHILD | CLS_CONTACTLIST
+ | (cfg::getByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ? CLS_USEGROUPS : 0)
+ | CLS_HIDEOFFLINE
+ //|(DBGetContactSettingByte(NULL,"CList","HideOffline",SETTING_HIDEOFFLINE_DEFAULT)?CLS_HIDEOFFLINE:0)
+ | (cfg::getByte(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) ? CLS_HIDEEMPTYGROUPS : 0)
+ | CLS_MULTICOLUMN
+ , 0, 0, 0, 0, parent, NULL, g_hInst, (LPVOID)0xff00ff00);
+
+ cfg::clcdat = (struct ClcData *)GetWindowLongPtr(pcli->hwndContactTree, 0);
+ return pcli->hwndContactTree;
+}
+
+/*
+* create internal frames, including the last frame (actual CLC control)
+*/
+
+static int CreateCLC(HWND parent)
+{
+ ReloadExtraIcons();
+ CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)oldhideoffline, 0);
+ disableautoupd = 0;
+
+ {
+ CLISTFrame frame = {0};
+ frame.cbSize = sizeof(frame);
+ frame.tname = _T("EventArea");
+ frame.TBtname = TranslateT("Event Area");
+ frame.hIcon = 0;
+ frame.height = 20;
+ frame.Flags = F_VISIBLE | F_SHOWTBTIP | F_NOBORDER | F_TCHAR;
+ frame.align = alBottom;
+ frame.hWnd = CreateWindowExA(0, "EventAreaClass", "evt", WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, pcli->hwndContactList, (HMENU) 0, g_hInst, NULL);
+ g_hwndEventArea = frame.hWnd;
+ hNotifyFrame = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM) & frame, (LPARAM)0);
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)hNotifyFrame, FU_FMPOS);
+ HideShowNotifyFrame();
+ CreateViewModeFrame();
+ }
+ SetButtonToSkinned();
+
+ {
+ DWORD flags;
+ CLISTFrame Frame;
+ memset(&Frame, 0, sizeof(Frame));
+ Frame.cbSize = sizeof(CLISTFrame);
+ Frame.hWnd = pcli->hwndContactTree;
+ Frame.align = alClient;
+ Frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ Frame.Flags = F_VISIBLE | F_SHOWTB | F_SHOWTBTIP | F_NOBORDER | F_TCHAR;
+ Frame.tname = _T("My Contacts");
+ Frame.TBtname = TranslateT("My Contacts");
+ Frame.height = 200;
+ hFrameContactTree = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM) & Frame, (LPARAM)0);
+ //free(Frame.name);
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_TBTIPNAME, hFrameContactTree), (LPARAM)Translate("My Contacts"));
+
+ /*
+ * ugly, but working hack. Prevent that annoying little scroll bar from appearing in the "My Contacts" title bar
+ */
+
+ flags = (DWORD)CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hFrameContactTree), 0);
+ flags |= F_VISIBLE;
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hFrameContactTree), flags);
+ }
+ return(0);
+}
+
+static int CluiModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ static Update upd = {0};
+ static const char *szPrefix = "clist_nicer_plus ";
+
+#if defined(_UNICODE)
+ static char *component = "CList Nicer+ (Unicode)";
+ static char szCurrentVersion[30];
+ static char *szVersionUrl = "http://download.miranda.or.at/clist_nicer/0.9/versionW.txt";
+ static char *szUpdateUrl = "http://download.miranda.or.at/clist_nicer/0.9/clist_nicer_plusW.zip";
+#else
+ static char *component = "CList Nicer+";
+ static char szCurrentVersion[30];
+ static char *szVersionUrl = "http://download.miranda.or.at/clist_nicer/0.9/version.txt";
+ static char *szUpdateUrl = "http://download.miranda.or.at/clist_nicer/0.9/clist_nicer_plus.zip";
+#endif
+
+ // updater plugin support
+
+ upd.cbSize = sizeof(upd);
+ upd.szComponentName = pluginInfo.shortName;
+ upd.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szCurrentVersion);
+ upd.cpbVersion = (int)strlen((char *)upd.pbVersion);
+ upd.szUpdateURL = UPDATER_AUTOREGISTER;
+
+ upd.szBetaUpdateURL = szUpdateUrl;
+ upd.szBetaVersionURL = szVersionUrl;
+ upd.pbBetaVersionPrefix = (BYTE *)szPrefix;
+ upd.cpbBetaVersionPrefix = (int)strlen((char *)upd.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
+
+ MTG_OnmodulesLoad(wParam, lParam);
+ if (ServiceExists(MS_FONT_REGISTER)) {
+ cfg::dat.bFontServiceAvail = TRUE;
+ FS_RegisterFonts();
+ HookEvent(ME_FONT_RELOAD, FS_FontsChanged);
+ }
+ return 0;
+}
+
+static HICON hIconSaved = 0;
+
+void ClearIcons(int mode)
+{
+ int i;
+
+ for (i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) {
+ if (overlayicons[i - IDI_OVL_OFFLINE] != 0) {
+ if (mode)
+ DestroyIcon(overlayicons[i - IDI_OVL_OFFLINE]);
+ overlayicons[i - IDI_OVL_OFFLINE] = 0;
+ }
+ }
+ hIconSaved = ImageList_GetIcon(himlExtraImages, 3, ILD_NORMAL);
+ ImageList_RemoveAll(himlExtraImages);
+}
+
+static void CacheClientIcons()
+{
+ int i = 0;
+ char szBuffer[128];
+
+ ClearIcons(0);
+
+ for (i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) {
+ mir_snprintf(szBuffer, sizeof(szBuffer), "cln_ovl_%d", ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE));
+ overlayicons[i - IDI_OVL_OFFLINE] = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) szBuffer);
+ }
+ ImageList_AddIcon(himlExtraImages, (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM) "core_main_14"));
+ ImageList_AddIcon(himlExtraImages, (HICON)LoadSkinnedIcon(SKINICON_EVENT_URL));
+ ImageList_AddIcon(himlExtraImages, (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM) "core_main_17"));
+ if (hIconSaved != 0) {
+ ImageList_AddIcon(himlExtraImages, hIconSaved);
+ DestroyIcon(hIconSaved);
+ hIconSaved = 0;
+ } else
+ ImageList_AddIcon(himlExtraImages, (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM) "core_main_17"));
+}
+
+static void InitIcoLib()
+{
+ SKINICONDESC sid = {0};
+ TCHAR szFilename[MAX_PATH];
+ int i = 0, version = 0;
+ char szBuffer[128];
+ int p_count = 0;
+ PROTOACCOUNT **accs = NULL;
+
+ GetModuleFileName(g_hInst, szFilename, MAX_PATH);
+
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.flags = SIDF_PATH_TCHAR;
+ sid.pszSection = LPGEN("CList - Nicer/Default");
+ sid.ptszDefaultFile = szFilename;
+ i = 0;
+ do {
+ if (myIcons[i].szName == NULL)
+ break;
+ sid.pszName = myIcons[i].szName;
+ sid.pszDescription = myIcons[i].szDesc;
+ sid.iDefaultIndex = myIcons[i].uId;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM) &sid);
+ } while (++i);
+
+ sid.pszName = "CLN_visible";
+ sid.pszDescription = LPGEN("Contact on visible list");
+ sid.iDefaultIndex = -IDI_CLVISIBLE;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM) &sid);
+ sid.pszName = "CLN_invisible";
+ sid.pszDescription = LPGEN("Contact on invisible list or blocked");
+ sid.iDefaultIndex = -IDI_CLINVISIBLE;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM) &sid);
+ sid.pszName = "CLN_chatactive";
+ sid.pszDescription = LPGEN("Chat room/IRC channel activity");
+ sid.iDefaultIndex = -IDI_OVL_FREEFORCHAT;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM) &sid);
+
+ sid.flags = SIDF_ALL_TCHAR;
+ sid.ptszSection = LPGENT("CList - Nicer/Overlay Icons");
+ for (i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) {
+ mir_snprintf(szBuffer, sizeof(szBuffer), "cln_ovl_%d", ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE));
+ sid.pszName = szBuffer;
+ sid.ptszDescription = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE), GSMDF_TCHAR);
+ sid.iDefaultIndex = -i;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM) &sid);
+ }
+ sid.ptszSection = LPGENT("CList - Nicer/Connecting Icons");
+ ProtoEnumAccounts( &p_count, &accs );
+ for (i = 0; i < p_count; i++) {
+ TCHAR szDescr[128];
+ if ( !IsAccountEnabled(accs[i]) || CallProtoService(accs[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) == 0)
+ continue;
+ mir_snprintf(szBuffer, 128, "%s_conn", accs[i]->szModuleName );
+ sid.pszName = szBuffer;
+ mir_sntprintf(szDescr, 128, TranslateT("%s Connecting"), accs[i]->tszAccountName );
+ sid.ptszDescription = szDescr;
+ sid.iDefaultIndex = -IDI_PROTOCONNECTING;
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM) &sid);
+ }
+}
+
+static int IcoLibChanged(WPARAM wParam, LPARAM lParam)
+{
+ IcoLibReloadIcons();
+ return 0;
+}
+
+/*
+* if mode != 0 we do first time init, otherwise only reload the extra icon stuff
+*/
+
+void CLN_LoadAllIcons(BOOL mode)
+{
+ if (mode) {
+ InitIcoLib();
+ hIcoLibChanged = HookEvent(ME_SKIN2_ICONSCHANGED, IcoLibChanged);
+ cfg::dat.hIconVisible = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) "CLN_visible");
+ cfg::dat.hIconInvisible = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) "CLN_invisible");
+ cfg::dat.hIconChatactive = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) "CLN_chatactive");
+ }
+ CacheClientIcons();
+}
+
+void ConfigureEventArea(HWND hwnd)
+{
+ int iCount = GetMenuItemCount(cfg::dat.hMenuNotify);
+ DWORD dwFlags = cfg::dat.dwFlags;
+ int oldstate = cfg::dat.notifyActive;
+ int dwVisible = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hNotifyFrame), 0) & F_VISIBLE;
+
+ if (dwVisible) {
+ if (dwFlags & CLUI_FRAME_AUTOHIDENOTIFY)
+ cfg::dat.notifyActive = iCount > 0 ? 1 : 0;
+ else
+ cfg::dat.notifyActive = 1;
+ } else
+ cfg::dat.notifyActive = 0;
+
+ if (oldstate != cfg::dat.notifyActive)
+ HideShowNotifyFrame();
+}
+
+void ConfigureFrame()
+{
+ int i;
+ int showCmd;
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+ if (top_buttons[i].hwnd == 0)
+ continue;
+ switch (top_buttons[i].id) {
+ case IDC_TBMENU:
+ case IDC_TBGLOBALSTATUS:
+ ShowWindow(top_buttons[i].hwnd, cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? SW_SHOW : SW_HIDE);
+ break;
+ default:
+ if (cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS) {
+ showCmd = (top_buttons[i].visibilityOrder & cfg::dat.toolbarVisibility) ? SW_SHOW : SW_HIDE;
+ CheckMenuItem(cfg::dat.hMenuButtons, 50000 + i, MF_BYCOMMAND | (showCmd == SW_SHOW ? MF_CHECKED : MF_UNCHECKED));
+ } else
+ showCmd = SW_HIDE;
+ ShowWindow(top_buttons[i].hwnd, showCmd);
+ break;
+ }
+ }
+}
+
+void IcoLibReloadIcons()
+{
+ int i;
+ HICON hIcon;
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+
+ if ((top_buttons[i].id == IDC_TABSRMMMENU || top_buttons[i].id == IDC_TABSRMMSLIST) && !cfg::dat.tabSRMM_Avail)
+ continue;
+
+ if (top_buttons[i].id == IDC_TBMENU || top_buttons[i].id == IDC_TBGLOBALSTATUS || top_buttons[i].id == IDC_TBTOPSTATUS)
+ continue;
+
+ hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) top_buttons[i].szIcoLibIcon);
+ if (top_buttons[i].hwnd && IsWindow(top_buttons[i].hwnd)) {
+ SendMessage(top_buttons[i].hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
+ InvalidateRect(top_buttons[i].hwnd, NULL, TRUE);
+ }
+ }
+ cfg::dat.hIconVisible = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) "CLN_visible");
+ cfg::dat.hIconInvisible = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) "CLN_invisible");
+ cfg::dat.hIconChatactive = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) "CLN_chatactive");
+ CacheClientIcons();
+ ReloadExtraIcons();
+
+ // force client icons reload
+ {
+ int i;
+
+ for (i = 0; i < cfg::nextCacheEntry; i++) {
+ if (cfg::eCache[i].hContact)
+ NotifyEventHooks(hExtraImageApplying, (WPARAM)cfg::eCache[i].hContact, 0);
+ }
+ }
+ //
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ SendMessage(g_hwndViewModeFrame, WM_USER + 100, 0, 0);
+}
+
+
+static void SetButtonStyle()
+{
+ int i;
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+ if (top_buttons[i].hwnd == 0 || top_buttons[i].id == IDC_TBGLOBALSTATUS || top_buttons[i].id == IDC_TBMENU)
+ continue;
+ SendMessage(top_buttons[i].hwnd, BUTTONSETASFLATBTN, 0, cfg::dat.dwFlags & CLUI_FRAME_BUTTONSFLAT ? 0 : 1);
+ SendMessage(top_buttons[i].hwnd, BUTTONSETASFLATBTN + 10, 0, cfg::dat.dwFlags & CLUI_FRAME_BUTTONSCLASSIC ? 0 : 1);
+ }
+}
+
+void CreateButtonBar(HWND hWnd)
+{
+ int i;
+ HICON hIcon;
+ HMENU hMenuButtonList = GetSubMenu(cfg::dat.hMenuButtons, 0);
+
+ DeleteMenu(hMenuButtonList, 0, MF_BYPOSITION);
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+ if (top_buttons[i].hwnd)
+ continue;
+
+ if (g_ButtonItems && top_buttons[i].id != IDC_TBGLOBALSTATUS && top_buttons[i].id != IDC_TBMENU)
+ continue;
+
+ if ((top_buttons[i].id == IDC_TABSRMMMENU || top_buttons[i].id == IDC_TABSRMMSLIST) && !cfg::dat.tabSRMM_Avail)
+ continue;
+
+ top_buttons[i].hwnd = CreateWindowEx(0, _T("CLCButtonClass"), _T(""), BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, hWnd, (HMENU) top_buttons[i].id, g_hInst, NULL);
+ if (top_buttons[i].id != IDC_TBMENU && top_buttons[i].id != IDC_TBGLOBALSTATUS)
+ AppendMenu(hMenuButtonList, MF_STRING, 50000 + i, TranslateTS(top_buttons[i].szTooltip));
+ if (!cfg::dat.IcoLib_Avail) {
+ hIcon = top_buttons[i].hIcon = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(top_buttons[i].idIcon), IMAGE_ICON, g_cxsmIcon, g_cysmIcon, LR_SHARED);
+ if (top_buttons[i].idAltIcon)
+ top_buttons[i].hAltIcon = reinterpret_cast<HICON>(LoadImage(g_hInst, MAKEINTRESOURCE(top_buttons[i].idAltIcon), IMAGE_ICON, g_cxsmIcon, g_cysmIcon, LR_SHARED));
+ } else {
+ hIcon = top_buttons[i].hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) top_buttons[i].szIcoLibIcon);
+ if (top_buttons[i].szIcoLibAltIcon)
+ top_buttons[i].hAltIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) top_buttons[i].szIcoLibAltIcon);
+ }
+ if (top_buttons[i].id == IDC_TBMENU) {
+ SetWindowText(top_buttons[i].hwnd, TranslateT("Menu"));
+ SendMessage(top_buttons[i].hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM) LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+ } else
+ SendMessage(top_buttons[i].hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
+ if (top_buttons[i].id == IDC_TBGLOBALSTATUS) {
+ SetWindowText(top_buttons[i].hwnd, TranslateT("Offline"));
+ SendMessage(top_buttons[i].hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM) LoadSkinnedIcon(SKINICON_STATUS_OFFLINE));
+ }
+ if (!(top_buttons[i].flags & TOPBUTTON_PUSH))
+ SendMessage(top_buttons[i].hwnd, BUTTONSETASPUSHBTN, 0, 0);
+ if (top_buttons[i].id != IDC_TBGLOBALSTATUS && top_buttons[i].id != IDC_TBMENU)
+ SendMessage(top_buttons[i].hwnd, BUTTONSETASFLATBTN, 0, 0);
+
+ if (top_buttons[i].flags & TOPBUTTON_SENDONDOWN)
+ SendMessage(top_buttons[i].hwnd, BM_SETASMENUACTION, 1, 0);
+
+ SendMessage(top_buttons[i].hwnd, BUTTONADDTOOLTIP, (WPARAM) TranslateTS(top_buttons[i].szTooltip), 0);
+ }
+ SetButtonStyle();
+}
+
+void SetTBSKinned(int mode)
+{
+ int i;
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+ if (top_buttons[i].hwnd == 0 || top_buttons[i].id == IDC_TBGLOBALSTATUS || top_buttons[i].id == IDC_TBMENU)
+ continue;
+ SendMessage(top_buttons[i].hwnd, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(top_buttons[i].hwnd, BUTTONSETASFLATBTN + 10, 0, 0);
+ SendMessage(top_buttons[i].hwnd, BM_SETSKINNED, 0, mode ? MAKELONG(mode, 1) : 0);
+ }
+ if (!mode)
+ SetButtonStyle(); // restore old style
+}
+
+void ConfigureCLUIGeometry(int mode)
+{
+ RECT rcStatus;
+ DWORD clmargins = cfg::getDword("CLUI", "clmargins", 0);
+
+ cfg::dat.bCLeft = LOBYTE(LOWORD(clmargins));
+ cfg::dat.bCRight = HIBYTE(LOWORD(clmargins));
+ cfg::dat.bCTop = LOBYTE(HIWORD(clmargins));
+ cfg::dat.bCBottom = HIBYTE(HIWORD(clmargins));
+
+ cfg::dat.dwButtonWidth = cfg::dat.dwButtonHeight = cfg::getByte("CLUI", "TBSize", 19);
+
+ if (mode) {
+ if (cfg::dat.dwFlags & CLUI_FRAME_SBARSHOW) {
+ SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0);
+ GetWindowRect(pcli->hwndStatus, &rcStatus);
+ cfg::dat.statusBarHeight = (rcStatus.bottom - rcStatus.top);
+ } else
+ cfg::dat.statusBarHeight = 0;
+ }
+
+ cfg::dat.topOffset = (cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS ? 2 + cfg::dat.dwButtonHeight : 0) + cfg::dat.bCTop;
+ cfg::dat.bottomOffset = (cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? 2 + BUTTON_HEIGHT_D : 0) + cfg::dat.bCBottom;
+
+ if (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN) {
+ cfg::dat.topOffset += 2;
+ cfg::dat.bottomOffset += 2;
+ cfg::dat.bCLeft += 3;
+ cfg::dat.bCRight += 3;
+ }
+}
+
+void RefreshButtons()
+{
+ int i;
+
+ for (i = 0; ; i++) {
+ if (top_buttons[i].szTooltip == NULL)
+ break;
+ if (top_buttons[i].hwnd == 0 || top_buttons[i].id == IDC_TBGLOBALSTATUS || top_buttons[i].id == IDC_TBMENU)
+ continue;
+ InvalidateRect(top_buttons[i].hwnd, NULL, FALSE);
+ }
+}
+
+/*
+ * set the states of defined database action buttons (only if button is a toggle)
+*/
+
+void SetDBButtonStates(HANDLE hPassedContact)
+{
+ ButtonItem *buttonItem = g_ButtonItems;
+ HANDLE hContact = 0, hFinalContact = 0;
+ char *szModule, *szSetting;
+ int sel = cfg::clcdat ? cfg::clcdat->selection : -1;
+ struct ClcContact *contact = 0;
+
+ if (sel != -1 && hPassedContact == 0) {
+ sel = pcli->pfnGetRowByIndex(cfg::clcdat, cfg::clcdat->selection, &contact, NULL);
+ if (contact && contact->type == CLCIT_CONTACT) {
+ hContact = contact->hContact;
+ }
+ }
+
+ while (buttonItem) {
+ BOOL result = FALSE;
+
+ if (!(buttonItem->dwFlags & BUTTON_ISTOGGLE && buttonItem->dwFlags & BUTTON_ISDBACTION)) {
+ buttonItem = buttonItem->nextItem;
+ continue;
+ }
+ szModule = buttonItem->szModule;
+ szSetting = buttonItem->szSetting;
+ if (buttonItem->dwFlags & BUTTON_DBACTIONONCONTACT || buttonItem->dwFlags & BUTTON_ISCONTACTDBACTION) {
+ if (hContact == 0) {
+ SendMessage(buttonItem->hWnd, BM_SETCHECK, BST_UNCHECKED, 0);
+ buttonItem = buttonItem->nextItem;
+ continue;
+ }
+ if (buttonItem->dwFlags & BUTTON_ISCONTACTDBACTION)
+ szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ hFinalContact = hContact;
+ } else
+ hFinalContact = 0;
+
+ if (buttonItem->type == DBVT_ASCIIZ) {
+ DBVARIANT dbv = {0};
+
+ if (!cfg::getString(hFinalContact, szModule, szSetting, &dbv)) {
+ result = !strcmp((char *)buttonItem->bValuePush, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ } else {
+ switch (buttonItem->type) {
+ case DBVT_BYTE: {
+ BYTE val = cfg::getByte(hFinalContact, szModule, szSetting, 0);
+ result = (val == buttonItem->bValuePush[0]);
+ break;
+ }
+ case DBVT_WORD: {
+ WORD val = cfg::getWord(hFinalContact, szModule, szSetting, 0);
+ result = (val == *((WORD *) & buttonItem->bValuePush));
+ break;
+ }
+ case DBVT_DWORD: {
+ DWORD val = cfg::getDword(hFinalContact, szModule, szSetting, 0);
+ result = (val == *((DWORD *) & buttonItem->bValuePush));
+ break;
+ }
+ }
+ }
+ SendMessage(buttonItem->hWnd, BM_SETCHECK, (WPARAM)result, 0);
+ buttonItem = buttonItem->nextItem;
+ }
+}
+
+/*
+ * set states of standard buttons (pressed/unpressed
+ */
+void SetButtonStates(HWND hwnd)
+{
+ BYTE iMode;
+ ButtonItem *buttonItem = g_ButtonItems;
+
+ iMode = cfg::getByte("CList", "HideOffline", 0);
+ if (!g_ButtonItems) {
+ SendDlgItemMessage(hwnd, IDC_TBSOUND, BM_SETIMAGE, IMAGE_ICON, (LPARAM)(cfg::dat.soundsOff ? top_buttons[6].hAltIcon : top_buttons[6].hIcon));
+ CheckDlgButton(hwnd, IDC_TBHIDEGROUPS, cfg::getByte("CList", "UseGroups", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd, IDC_TBHIDEOFFLINE, iMode ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd, IDC_TBSOUND, cfg::dat.soundsOff ? BST_UNCHECKED : BST_CHECKED);
+ } else {
+ while (buttonItem) {
+ if (buttonItem->dwFlags & BUTTON_ISINTERNAL) {
+ switch (buttonItem->uId) {
+ case IDC_TBSOUND:
+ SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::dat.soundsOff ? BST_UNCHECKED : BST_CHECKED, 0);
+ break;
+ case IDC_TBHIDEOFFLINE:
+ SendMessage(buttonItem->hWnd, BM_SETCHECK, iMode ? BST_CHECKED : BST_UNCHECKED, 0);
+ break;
+ case IDC_TBHIDEGROUPS:
+ SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::getByte("CList", "UseGroups", 0) ? BST_CHECKED : BST_UNCHECKED, 0);
+ break;
+ }
+ }
+ buttonItem = buttonItem->nextItem;
+ }
+ }
+}
+
+void BlitWallpaper(HDC hdc, RECT *rc, RECT *rcPaint, struct ClcData *dat)
+{
+ int x, y;
+ int bitx, bity;
+ int maxx, maxy;
+ int destw, desth, height, width;
+ BITMAP *bmp = &cfg::dat.bminfoBg;
+ HRGN my_rgn = 0;
+ LONG clip = cfg::dat.bClipBorder;
+
+ if (dat == 0)
+ return;
+
+ SetStretchBltMode(hdc, HALFTONE);
+
+ y = rc->top;
+
+ rc->left = max(rc->left, clip);
+ rc->right = min(rc->right - clip, rc->right);
+ rc->top = max(rc->top, clip);
+ rc->bottom = min(rc->bottom - clip, rc->bottom);
+
+ width = rc->right - rc->left;
+ height = rc->bottom - rc->top;
+ my_rgn = CreateRectRgn(rc->left, rc->top, rc->right, rc->bottom);
+ SelectClipRgn(hdc, my_rgn);
+ maxx = dat->backgroundBmpUse & CLBF_TILEH ? rc->right : rc->left + 1;
+ maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rc->bottom : y + 1;
+ switch (dat->backgroundBmpUse & CLBM_TYPE) {
+ case CLB_STRETCH:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ if (width * bmp->bmHeight < height * bmp->bmWidth) {
+ desth = height;
+ destw = desth * bmp->bmWidth / bmp->bmHeight;
+ } else {
+ destw = width;
+ desth = destw * bmp->bmHeight / bmp->bmWidth;
+ }
+ } else {
+ destw = width;
+ desth = height;
+ }
+ break;
+ case CLB_STRETCHH:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ destw = width;
+ desth = destw * bmp->bmHeight / bmp->bmWidth;
+ } else {
+ destw = width;
+ desth = bmp->bmHeight;
+ }
+ break;
+ case CLB_STRETCHV:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ desth = height;
+ destw = desth * bmp->bmWidth / bmp->bmHeight;
+ } else {
+ destw = bmp->bmWidth;
+ desth = height;
+ }
+ break;
+ default:
+ //clb_topleft
+ destw = bmp->bmWidth;
+ desth = bmp->bmHeight;
+ break;
+ }
+
+ bitx = 0;
+ bity = 0;
+ for (; y < maxy; y += desth) {
+ for (x = rc->left; x < maxx; x += destw)
+ StretchBlt(hdc, x, y, destw, desth, cfg::dat.hdcPic, bitx, bity, bmp->bmWidth, bmp->bmHeight, SRCCOPY);
+ }
+ SelectClipRgn(hdc, NULL);
+ DeleteObject(my_rgn);
+}
+
+void ReloadThemedOptions()
+{
+ cfg::dat.bSkinnedToolbar = cfg::getByte("CLUI", "tb_skinned", 1);
+ cfg::dat.bSkinnedStatusBar = cfg::getByte("CLUI", "sb_skinned", 0);
+ cfg::dat.bUsePerProto = cfg::getByte("CLCExt", "useperproto", 0);
+ cfg::dat.bOverridePerStatusColors = cfg::getByte("CLCExt", "override_status", 0);
+ cfg::dat.bRowSpacing = cfg::getByte("CLC", "RowGap", 0);
+ cfg::dat.exIconScale = cfg::getByte("CLC", "ExIconScale", 16);
+ cfg::dat.bApplyIndentToBg = cfg::getByte("CLCExt", "applyindentbg", 0);
+ cfg::dat.bWallpaperMode = cfg::getByte("CLUI", "UseBkSkin", 1);
+ cfg::dat.bClipBorder = cfg::getByte("CLUI", "clipborder", 0);
+ cfg::dat.cornerRadius = cfg::getByte("CLCExt", "CornerRad", 6);
+ cfg::dat.gapBetweenFrames = (BYTE)cfg::getDword("CLUIFrames", "GapBetweenFrames", 1);
+ cfg::dat.bUseDCMirroring = cfg::getByte("CLC", "MirrorDC", 0);
+ cfg::dat.bGroupAlign = cfg::getByte("CLC", "GroupAlign", 0);
+ if (cfg::dat.hBrushColorKey)
+ DeleteObject(cfg::dat.hBrushColorKey);
+ cfg::dat.hBrushColorKey = CreateSolidBrush(RGB(255, 0, 255));
+ cfg::dat.bUseFloater = cfg::getByte("CLUI", "FloaterMode", 0);
+ cfg::dat.bWantFastGradients = cfg::getByte("CLCExt", "FastGradients", 0);
+ cfg::dat.titleBarHeight = cfg::getByte("CLCExt", "frame_height", DEFAULT_TITLEBAR_HEIGHT);
+ cfg::dat.group_padding = cfg::getDword("CLCExt", "grp_padding", 0);
+}
+
+static RECT rcWindow = {0};
+
+static void sttProcessResize(HWND hwnd, NMCLISTCONTROL *nmc)
+{
+ RECT rcTree, rcWorkArea, rcOld;
+ int maxHeight, newHeight;
+ int winstyle, skinHeight = 0;
+
+ if (disableautoupd)
+ return;
+
+ if (!cfg::getByte("CLUI", "AutoSize", 0))
+ return;
+
+ if (Docking_IsDocked(0, 0))
+ return;
+ if (hFrameContactTree == 0)
+ return;
+
+ maxHeight = cfg::getByte("CLUI", "MaxSizeHeight", 75);
+ rcOld = rcWindow;
+
+ GetWindowRect(hwnd, &rcWindow);
+ GetWindowRect(pcli->hwndContactTree, &rcTree);
+ winstyle = GetWindowLong(pcli->hwndContactTree, GWL_STYLE);
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE);
+ if (API::pfnMonitorFromWindow)
+ {
+ HMONITOR hMon = API::pfnMonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (API::pfnGetMonitorInfo(hMon, &mi))
+ rcWorkArea = mi.rcWork;
+ }
+
+ if (nmc->pt.y > (rcWorkArea.bottom - rcWorkArea.top)) {
+ nmc->pt.y = (rcWorkArea.bottom - rcWorkArea.top);
+ }
+
+ if (winstyle & CLS_SKINNEDFRAME) {
+ BOOL hasTitleBar = wndFrameCLC ? wndFrameCLC->TitleBar.ShowTitleBar : 0;
+ StatusItems_t *item = &StatusItems[(hasTitleBar ? ID_EXTBKOWNEDFRAMEBORDERTB : ID_EXTBKOWNEDFRAMEBORDER) - ID_STATUS_OFFLINE];
+ skinHeight = item->IGNORED ? 0 : item->MARGIN_BOTTOM + item->MARGIN_TOP;
+ }
+
+ newHeight = max(nmc->pt.y, 3) + 1 + ((winstyle & WS_BORDER) ? 2 : 0) + skinHeight + (rcWindow.bottom - rcWindow.top) - (rcTree.bottom - rcTree.top);
+ if (newHeight == (rcWindow.bottom - rcWindow.top) && show_on_first_autosize == FALSE)
+ return;
+
+ if (newHeight > (rcWorkArea.bottom - rcWorkArea.top)*maxHeight / 100)
+ newHeight = (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100;
+ if (cfg::getByte("CLUI", "AutoSizeUpward", 0)) {
+ rcWindow.top = rcWindow.bottom - newHeight;
+ if (rcWindow.top < rcWorkArea.top) rcWindow.top = rcWorkArea.top;
+ } else {
+ rcWindow.bottom = rcWindow.top + newHeight;
+ if (rcWindow.bottom > rcWorkArea.bottom) rcWindow.bottom = rcWorkArea.bottom;
+ }
+ if (cfg::dat.szOldCTreeSize.cx != rcTree.right - rcTree.left) {
+ cfg::dat.szOldCTreeSize.cx = rcTree.right - rcTree.left;
+ return;
+ }
+ KillTimer(hwnd, TIMERID_AUTOSIZE);
+ SetTimer(hwnd, TIMERID_AUTOSIZE, 100, 0);
+}
+
+int CustomDrawScrollBars(NMCSBCUSTOMDRAW *nmcsbcd)
+{
+ switch (nmcsbcd->hdr.code) {
+ case NM_COOLSB_CUSTOMDRAW: {
+ static HDC hdcScroll = 0;
+ static HBITMAP hbmScroll, hbmScrollOld;
+ static LONG scrollLeft, scrollRight, scrollHeight, scrollYmin, scrollYmax;
+
+ switch (nmcsbcd->dwDrawStage) {
+ case CDDS_PREPAINT:
+ if (cfg::dat.bSkinnedScrollbar) // XXX fix (verify skin items to be complete, otherwise don't draw
+ return CDRF_SKIPDEFAULT;
+ else
+ return CDRF_DODEFAULT;
+ case CDDS_POSTPAINT:
+ return 0;
+ case CDDS_ITEMPREPAINT: {
+ HDC hdc = nmcsbcd->hdc;
+ StatusItems_t *item = 0, *arrowItem = 0;
+ UINT uItemID = ID_EXTBKSCROLLBACK;
+ RECT rcWindow;
+ POINT pt;
+ DWORD dfcFlags;
+ HRGN rgn = 0;
+ GetWindowRect(pcli->hwndContactTree, &rcWindow);
+ pt.x = rcWindow.left;
+ pt.y = rcWindow.top;
+ ScreenToClient(pcli->hwndContactList, &pt);
+ hdcScroll = hdc;
+ BitBlt(hdcScroll, nmcsbcd->rect.left, nmcsbcd->rect.top, nmcsbcd->rect.right - nmcsbcd->rect.left,
+ nmcsbcd->rect.bottom - nmcsbcd->rect.top, cfg::dat.hdcBg, pt.x + nmcsbcd->rect.left, pt.y + nmcsbcd->rect.top, SRCCOPY);
+
+ switch (nmcsbcd->uItem) {
+ case HTSCROLL_UP:
+ case HTSCROLL_DOWN:
+ uItemID = (nmcsbcd->uState == CDIS_DEFAULT || nmcsbcd->uState == CDIS_DISABLED) ? ID_EXTBKSCROLLBUTTON :
+ (nmcsbcd->uState == CDIS_HOT ? ID_EXTBKSCROLLBUTTONHOVER : ID_EXTBKSCROLLBUTTONPRESSED);
+ break;
+ case HTSCROLL_PAGEGDOWN:
+ case HTSCROLL_PAGEGUP:
+ uItemID = nmcsbcd->uItem == HTSCROLL_PAGEGUP ? ID_EXTBKSCROLLBACK : ID_EXTBKSCROLLBACKLOWER;;
+ rgn = CreateRectRgn(nmcsbcd->rect.left, nmcsbcd->rect.top, nmcsbcd->rect.right, nmcsbcd->rect.bottom);
+ SelectClipRgn(hdcScroll, rgn);
+ break;
+ case HTSCROLL_THUMB:
+ uItemID = nmcsbcd->uState == CDIS_HOT ? ID_EXTBKSCROLLTHUMBHOVER : ID_EXTBKSCROLLTHUMB;
+ uItemID = nmcsbcd->uState == CDIS_SELECTED ? ID_EXTBKSCROLLTHUMBPRESSED : ID_EXTBKSCROLLTHUMB;
+ break;
+ default:
+ break;
+ }
+
+ uItemID -= ID_STATUS_OFFLINE;
+ item = &StatusItems[uItemID];
+ if (!item->IGNORED) {
+ int alpha = nmcsbcd->uState == CDIS_DISABLED ? item->ALPHA - 50 : item->ALPHA;
+ DrawAlpha(hdcScroll, &nmcsbcd->rect, item->COLOR, alpha, item->COLOR2, item->COLOR2_TRANSPARENT,
+ item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem);
+ }
+ dfcFlags = DFCS_FLAT | (nmcsbcd->uState == CDIS_DISABLED ? DFCS_INACTIVE :
+ (nmcsbcd->uState == CDIS_HOT ? DFCS_HOT :
+ (nmcsbcd->uState == CDIS_SELECTED ? DFCS_PUSHED : 0)));
+
+ if (nmcsbcd->uItem == HTSCROLL_UP)
+ arrowItem = &StatusItems[ID_EXTBKSCROLLARROWUP - ID_STATUS_OFFLINE];
+ if (nmcsbcd->uItem == HTSCROLL_DOWN)
+ arrowItem = &StatusItems[ID_EXTBKSCROLLARROWDOWN - ID_STATUS_OFFLINE];
+ if (arrowItem && !arrowItem->IGNORED)
+ DrawAlpha(hdcScroll, &nmcsbcd->rect, arrowItem->COLOR, arrowItem->ALPHA, arrowItem->COLOR2, arrowItem->COLOR2_TRANSPARENT,
+ arrowItem->GRADIENT, arrowItem->CORNER, arrowItem->BORDERSTYLE, arrowItem->imageItem);
+ else if (arrowItem)
+ DrawFrameControl(hdcScroll, &nmcsbcd->rect, DFC_SCROLL, (nmcsbcd->uItem == HTSCROLL_UP ? DFCS_SCROLLUP : DFCS_SCROLLDOWN) | dfcFlags);
+
+ if (rgn) {
+ SelectClipRgn(hdcScroll, NULL);
+ DeleteObject(rgn);
+ }
+ }
+ default:
+ break;
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+extern LRESULT(CALLBACK *saveContactListWndProc)(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+static int ServiceParamsOK(ButtonItem *item, WPARAM *wParam, LPARAM *lParam, HANDLE hContact)
+{
+ if (item->dwFlags & BUTTON_PASSHCONTACTW || item->dwFlags & BUTTON_PASSHCONTACTL || item->dwFlags & BUTTON_ISCONTACTDBACTION) {
+ if (hContact == 0)
+ return 0;
+ if (item->dwFlags & BUTTON_PASSHCONTACTW)
+ *wParam = (WPARAM)hContact;
+ else if (item->dwFlags & BUTTON_PASSHCONTACTL)
+ *lParam = (LPARAM)hContact;
+ return 1;
+ }
+ return 1; // doesn't need a paramter
+}
+static void ShowCLUI(HWND hwnd)
+{
+ int state = old_cliststate;
+ int onTop = cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT);
+
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, FALSE);
+ if (!cfg::getByte("CLUI", "ShowMainMenu", SETTING_SHOWMAINMENU_DEFAULT))
+ SetMenu(pcli->hwndContactList, NULL);
+ if (state == SETTING_STATE_NORMAL) {
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ ShowWindow(pcli->hwndContactList, SW_SHOWNORMAL);
+ SendMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ } else if (state == SETTING_STATE_MINIMIZED) {
+ cfg::dat.forceResize = TRUE;
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+ } else if (state == SETTING_STATE_HIDDEN) {
+ cfg::dat.forceResize = TRUE;
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+ }
+ SetWindowPos(pcli->hwndContactList, onTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOSENDCHANGING);
+ DrawMenuBar(hwnd);
+ if (cfg::dat.autosize) {
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0);
+ }
+ SFL_Create();
+ SFL_SetState(cfg::dat.bUseFloater & CLUI_FLOATER_AUTOHIDE ? (old_cliststate == SETTING_STATE_NORMAL ? 0 : 1) : 1);
+}
+
+#define M_CREATECLC (WM_USER+1)
+LRESULT CALLBACK ContactListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_CREATE: {
+ int i;
+ {
+ int flags = WS_CHILD | CCS_BOTTOM;
+ flags |= cfg::getByte("CLUI", "ShowSBar", 1) ? WS_VISIBLE : 0;
+ flags |= cfg::getByte("CLUI", "ShowGrip", 1) ? SBARS_SIZEGRIP : 0;
+ pcli->hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, flags, 0, 0, 0, 0, hwnd, NULL, g_hInst, NULL);
+ if (flags & WS_VISIBLE) {
+ ShowWindow(pcli->hwndStatus, SW_SHOW);
+ SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0);
+ }
+ OldStatusBarProc = (WNDPROC)SetWindowLongPtr(pcli->hwndStatus, GWLP_WNDPROC, (LONG_PTR)NewStatusBarWndProc);
+ SetClassLong(pcli->hwndStatus, GCL_STYLE, GetClassLong(pcli->hwndStatus, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW));
+ }
+ g_oldSize.cx = g_oldSize.cy = 0;
+ old_cliststate = cfg::getByte("CList", "State", SETTING_STATE_NORMAL);
+ cfg::writeByte("CList", "State", SETTING_STATE_HIDDEN);
+ SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE);
+ SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_CLIPCHILDREN);
+ if (!cfg::dat.bFirstRun)
+ ConfigureEventArea(hwnd);
+ CluiProtocolStatusChanged(0, 0);
+ ConfigureCLUIGeometry(0);
+
+ for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++)
+ statusNames[i - ID_STATUS_OFFLINE] = reinterpret_cast<TCHAR *>(CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)i, GSMDF_TCHAR));
+
+ //delay creation of CLC so that it can get the status icons right the first time (needs protocol modules loaded)
+ if (cfg::dat.bLayeredHack) {
+ SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | (WS_EX_LAYERED));
+ API::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 255, LWA_ALPHA);
+ }
+
+ if (cfg::dat.isTransparent) {
+ SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ }
+ transparentFocus = 1;
+
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) GetMenu(hwnd), 0);
+ PostMessage(hwnd, M_CREATECLC, 0, 0);
+ return FALSE;
+ }
+ case WM_NCCREATE: {
+ LPCREATESTRUCT p = (LPCREATESTRUCT)lParam;
+ p->style &= ~(CS_HREDRAW | CS_VREDRAW);
+ }
+ break;
+ case M_CREATECLC: {
+ if (cfg::getByte("CLUI", "useskin", 0))
+ IMG_LoadItems();
+ CreateButtonBar(hwnd);
+ //FYR: to be checked: otherwise it raises double xStatus items
+ //NotifyEventHooks(pcli->hPreBuildStatusMenuEvent, 0, 0);
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, FALSE);
+ {
+ LONG style;
+ BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_TOOLWINDOW);
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+ style = GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE);
+ if (windowStyle != SETTING_WINDOWSTYLE_DEFAULT)
+ {
+ style |= WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
+ style &= ~WS_EX_APPWINDOW;
+ }
+ else
+ {
+ style &= ~(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE);
+ if (cfg::getByte("CList", "AlwaysHideOnTB", 1))
+ style &= ~WS_EX_APPWINDOW;
+ else
+ style |= WS_EX_APPWINDOW;
+ }
+
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, style);
+ ApplyCLUIBorderStyle(pcli->hwndContactList);
+
+ SetWindowPos(pcli->hwndContactList, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE);
+ }
+
+ if (cfg::dat.soundsOff)
+ hSoundHook = HookEvent(ME_SKIN_PLAYINGSOUND, ClcSoundHook);
+ if (cfg::dat.bSkinnedToolbar)
+ SetTBSKinned(1);
+ ConfigureFrame();
+ SetButtonStates(hwnd);
+
+ CreateCLC(hwnd);
+ cfg::clcdat = (struct ClcData *)GetWindowLongPtr(pcli->hwndContactTree, 0);
+
+ if (API::sysConfig.isWin2KPlus && cfg::dat.bFullTransparent) {
+ if (g_CLUISkinnedBkColorRGB)
+ Tweak_It(g_CLUISkinnedBkColorRGB);
+ else if (cfg::dat.bClipBorder || (cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME))
+ Tweak_It(RGB(255, 0, 255));
+ else
+ Tweak_It(cfg::clcdat->bkColour);
+ }
+
+ cfg::writeByte("CList", "State", old_cliststate);
+
+ if (cfg::getByte("CList", "AutoApplyLastViewMode", 0)) {
+ DBVARIANT dbv = {0};
+ if (!DBGetContactSetting(NULL, "CList", "LastViewMode", &dbv)) {
+ if (lstrlenA(dbv.pszVal) > 2) {
+ if (cfg::getDword(NULL, CLVM_MODULE, dbv.pszVal, -1) != 0xffffffff)
+ ApplyViewMode((char *)dbv.pszVal);
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ if (!cfg::dat.autosize)
+ ShowCLUI(hwnd);
+ else {
+ show_on_first_autosize = TRUE;
+ RecalcScrollBar(pcli->hwndContactTree, cfg::clcdat);
+ }
+ return 0;
+ }
+ case WM_ERASEBKGND:
+ return TRUE;
+ if (cfg::dat.bSkinnedButtonMode)
+ return TRUE;
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ case WM_PAINT: {
+ PAINTSTRUCT ps;
+ RECT rc, rcFrame, rcClient;
+ HDC hdc;
+ HRGN rgn = 0;
+ HDC hdcReal = BeginPaint(hwnd, &ps);
+
+ if (during_sizing)
+ rcClient = rcWPC;
+ else
+ GetClientRect(hwnd, &rcClient);
+ CopyRect(&rc, &rcClient);
+
+ if (!cfg::dat.hdcBg || rc.right > cfg::dat.dcSize.cx || rc.bottom + cfg::dat.statusBarHeight > cfg::dat.dcSize.cy) {
+ RECT rcWorkArea;
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE);
+ if (API::pfnMonitorFromWindow)
+ {
+ HMONITOR hMon = API::pfnMonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (API::pfnGetMonitorInfo(hMon, &mi))
+ rcWorkArea = mi.rcWork;
+ }
+
+ cfg::dat.dcSize.cy = max(rc.bottom + cfg::dat.statusBarHeight, rcWorkArea.bottom - rcWorkArea.top);
+ cfg::dat.dcSize.cx = max(rc.right, (rcWorkArea.right - rcWorkArea.left) / 2);
+
+ if (cfg::dat.hdcBg) {
+ SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBgOld);
+ DeleteObject(cfg::dat.hbmBg);
+ DeleteDC(cfg::dat.hdcBg);
+ }
+ cfg::dat.hdcBg = CreateCompatibleDC(hdcReal);
+ cfg::dat.hbmBg = CreateCompatibleBitmap(hdcReal, cfg::dat.dcSize.cx, cfg::dat.dcSize.cy);
+ cfg::dat.hbmBgOld = reinterpret_cast<HBITMAP>(SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBg));
+ }
+
+ if (cfg::shutDown) {
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+
+ hdc = cfg::dat.hdcBg;
+
+ CopyRect(&rcFrame, &rcClient);
+ if (g_CLUISkinnedBkColor) {
+ if (cfg::dat.fOnDesktop) {
+ HDC dc = GetDC(0);
+ RECT rcWin;
+
+ GetWindowRect(hwnd, &rcWin);
+ BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, dc, rcWin.left, rcWin.top, SRCCOPY);
+ } else
+ FillRect(hdc, &rcClient, g_CLUISkinnedBkColor);
+ }
+
+ if (cfg::dat.bClipBorder != 0 || cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME) {
+ int docked = CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0);
+ int clip = cfg::dat.bClipBorder;
+
+ if (!g_CLUISkinnedBkColor)
+ FillRect(hdc, &rcClient, cfg::dat.hBrushColorKey);
+ if (cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME)
+ rgn = CreateRoundRectRgn(clip, docked ? 0 : clip, rcClient.right - clip + 1, rcClient.bottom - (docked ? 0 : clip - 1), 8 + clip, 8 + clip);
+ else
+ rgn = CreateRectRgn(clip, docked ? 0 : clip, rcClient.right - clip, rcClient.bottom - (docked ? 0 : clip));
+ SelectClipRgn(hdc, rgn);
+ }
+
+ if (g_CLUIImageItem) {
+ IMG_RenderImageItem(hdc, g_CLUIImageItem, &rcFrame);
+ cfg::dat.ptW.x = cfg::dat.ptW.y = 0;
+ ClientToScreen(hwnd, &cfg::dat.ptW);
+ goto skipbg;
+ }
+
+ if (cfg::dat.bWallpaperMode)
+ FillRect(hdc, &rcClient, cfg::dat.hBrushCLCBk);
+ else
+ FillRect(hdc, &rcClient, GetSysColorBrush(COLOR_3DFACE));
+
+ rcFrame.left += (cfg::dat.bCLeft - 1);
+ rcFrame.right -= (cfg::dat.bCRight - 1);
+ //if(!g_CluiData.bSkinnedButtonMode)
+ // rcFrame.bottom -= (g_CluiData.bottomOffset);
+ rcFrame.bottom++;
+ rcFrame.bottom -= cfg::dat.statusBarHeight;
+ if (cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS && cfg::dat.dwFlags & CLUI_FRAME_BUTTONBARSUNKEN) {
+ rc.top = cfg::dat.bCTop;;
+ rc.bottom = cfg::dat.dwButtonHeight + 2 + cfg::dat.bCTop;
+ rc.left++;
+ rc.right--;
+ DrawEdge(hdc, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
+ if (cfg::dat.bSkinnedToolbar && !(cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN))
+ rcFrame.top = 0;
+ else
+ rcFrame.top += (cfg::dat.topOffset - 1);
+
+ //if(g_CluiData.neeedSnap)
+ // goto skipbg;
+ if (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN) {
+ if (cfg::dat.bWallpaperMode && cfg::clcdat != NULL) {
+ InflateRect(&rcFrame, -1, -1);
+ if (cfg::dat.bmpBackground)
+ BlitWallpaper(hdc, &rcFrame, &ps.rcPaint, cfg::clcdat);
+ cfg::dat.ptW.x = cfg::dat.ptW.y = 0;
+ ClientToScreen(hwnd, &cfg::dat.ptW);
+ }
+ InflateRect(&rcFrame, 1, 1);
+ if (cfg::dat.bSkinnedButtonMode)
+ rcFrame.bottom -= (cfg::dat.bottomOffset);
+ DrawEdge(hdc, &rcFrame, BDR_SUNKENOUTER, BF_RECT);
+ } else if (cfg::dat.bWallpaperMode && cfg::clcdat != NULL) {
+ if (cfg::dat.bmpBackground)
+ BlitWallpaper(hdc, &rcFrame, &ps.rcPaint, cfg::clcdat);
+ cfg::dat.ptW.x = cfg::dat.ptW.y = 0;
+ ClientToScreen(hwnd, &cfg::dat.ptW);
+ }
+skipbg:
+ if (cfg::dat.bSkinnedToolbar && cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS) {
+ StatusItems_t *item = &StatusItems[ID_EXTBKBUTTONBAR - ID_STATUS_OFFLINE];
+ RECT rc = {rcClient.left, 0, rcClient.right, cfg::dat.dwButtonHeight + 2};
+
+ if (!item->IGNORED) {
+ rc.left += item->MARGIN_LEFT;
+ rc.right -= item->MARGIN_RIGHT;
+ rc.top += item->MARGIN_TOP;
+ rc.bottom -= item->MARGIN_BOTTOM;
+ DrawAlpha(hdc, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT,
+ item->CORNER, item->BORDERSTYLE, item->imageItem);
+ }
+ }
+ BitBlt(hdcReal, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdc, 0, 0, SRCCOPY);
+ if (rgn) {
+ SelectClipRgn(hdc, NULL);
+ DeleteObject(rgn);
+ }
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ case WM_ENTERSIZEMOVE: {
+ RECT rc;
+ POINT pt = {0};
+
+ GetWindowRect(hwnd, &g_PreSizeRect);
+ GetClientRect(hwnd, &rc);
+ ClientToScreen(hwnd, &pt);
+ g_CLUI_x_off = pt.x - g_PreSizeRect.left;
+ g_CLUI_y_off = pt.y - g_PreSizeRect.top;
+ pt.x = rc.right;
+ ClientToScreen(hwnd, &pt);
+ g_CLUI_x1_off = g_PreSizeRect.right - pt.x;
+ pt.x = 0;
+ pt.y = rc.bottom;
+ ClientToScreen(hwnd, &pt);
+ g_CLUI_y1_off = g_PreSizeRect.bottom - pt.y;
+ //g_CluiData.neeedSnap = TRUE;
+ break;
+ }
+ case WM_EXITSIZEMOVE:
+ //g_CluiData.neeedSnap = FALSE;
+ PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0);
+ //RedrawWindow(hwnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_FRAME|RDW_UPDATENOW|RDW_ALLCHILDREN);
+ break;
+ case WM_SIZING: {
+ RECT *szrect = (RECT *)lParam;
+
+ break;
+ if (Docking_IsDocked(0, 0))
+ break;
+ g_SizingRect = *((RECT *)lParam);
+ if (wParam != WMSZ_BOTTOM && wParam != WMSZ_BOTTOMRIGHT && wParam != WMSZ_BOTTOMLEFT)
+ szrect->bottom = g_PreSizeRect.bottom;
+ if (wParam != WMSZ_RIGHT && wParam != WMSZ_BOTTOMRIGHT && wParam != WMSZ_TOPRIGHT)
+ szrect->right = g_PreSizeRect.right;
+ return TRUE;
+ }
+
+ case WM_WINDOWPOSCHANGED:
+ if(!Docking_IsDocked(0, 0))
+ return(0);
+ else
+ break;
+
+ case WM_WINDOWPOSCHANGING: {
+ WINDOWPOS *wp = (WINDOWPOS *)lParam;
+
+ if (wp && wp->flags & SWP_NOSIZE)
+ return FALSE;
+
+ //if (Docking_IsDocked(0, 0))
+ // break;
+
+ if (pcli->hwndContactList != NULL) {
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+ during_sizing = true;
+
+ new_window_rect.left = 0;
+ new_window_rect.right = wp->cx - (g_CLUI_x_off + g_CLUI_x1_off);
+ new_window_rect.top = 0;
+ new_window_rect.bottom = wp->cy - g_CLUI_y_off - g_CLUI_y1_off;
+
+ if (cfg::dat.dwFlags & CLUI_FRAME_SBARSHOW) {
+ RECT rcStatus;
+ SetWindowPos(pcli->hwndStatus, 0, 0, new_window_rect.bottom - 20, new_window_rect.right, 20, SWP_NOZORDER);
+ GetWindowRect(pcli->hwndStatus, &rcStatus);
+ cfg::dat.statusBarHeight = (rcStatus.bottom - rcStatus.top);
+ if(wp->cx != g_oldSize.cx)
+ SendMessage(hwnd, CLUIINTM_STATUSBARUPDATE, 0, 0);
+ RedrawWindow(pcli->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+ } else
+ cfg::dat.statusBarHeight = 0;
+
+ SizeFramesByWindowRect(&new_window_rect);
+ dock_prevent_moving = 0;
+ LayoutButtons(hwnd, &new_window_rect);
+ dock_prevent_moving = 1;
+ g_oldPos.x = wp->x;
+ g_oldPos.y = wp->y;
+ g_oldSize.cx = wp->cx;
+ g_oldSize.cy = wp->cy;
+ rcWPC = new_window_rect;
+
+ during_sizing = false;
+ }
+ during_sizing = false;
+ return(0);
+ }
+
+ case WM_SIZE: {
+ RECT rc;
+
+ if ((wParam == 0 && lParam == 0) || Docking_IsDocked(0, 0)) {
+
+ if (IsZoomed(hwnd))
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+
+ if (pcli->hwndContactList != 0) {
+ SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0);
+ GetWindowRect(hwnd, &rc);
+ WINDOWPOS wp = {0};
+ wp.cx = rc.right - rc.left;
+ wp.cy = rc.bottom - rc.top;
+ wp.x = rc.left;
+ wp.y = rc.top;
+ wp.flags = 0;
+ SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp);
+ SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
+ }
+ }
+ }
+ case WM_MOVE:
+ if (!IsIconic(hwnd)) {
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+
+ if (!Docking_IsDocked(0, 0)) {
+ cluiPos.bottom = (DWORD)(rc.bottom - rc.top);
+ cluiPos.left = rc.left;
+ cluiPos.top = rc.top;
+ }
+ cluiPos.right = rc.right - rc.left;
+ if (cfg::dat.realTimeSaving) {
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+
+ if (!CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) { //if docked, dont remember pos (except for width)
+ cfg::writeDword("CList", "Height", (DWORD)(rc.bottom - rc.top));
+ cfg::writeDword("CList", "x", (DWORD) rc.left);
+ cfg::writeDword("CList", "y", (DWORD) rc.top);
+ }
+ cfg::writeDword("CList", "Width", (DWORD)(rc.right - rc.left));
+ }
+ }
+ return TRUE;
+
+ case WM_SETFOCUS:
+ SetFocus(pcli->hwndContactTree);
+ return 0;
+ case CLUIINTM_REMOVEFROMTASKBAR: {
+ BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT);
+ if (windowStyle == SETTING_WINDOWSTYLE_DEFAULT && cfg::getByte("CList", "AlwaysHideOnTB", 0))
+ RemoveFromTaskBar(hwnd);
+ return 0;
+ }
+ case WM_ACTIVATE:
+ if (g_fading_active) {
+ if (wParam != WA_INACTIVE && cfg::dat.isTransparent)
+ transparentFocus = 1;
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ if (wParam == WA_INACTIVE) {
+ if ((HWND) wParam != hwnd)
+ if (cfg::dat.isTransparent)
+ if (transparentFocus)
+ SetTimer(hwnd, TM_AUTOALPHA, 250, NULL);
+ } else {
+ if (cfg::dat.isTransparent) {
+ KillTimer(hwnd, TM_AUTOALPHA);
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ transparentFocus = 1;
+ }
+ SetWindowPos(pcli->hwndContactList, cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING);
+ }
+ PostMessage(hwnd, CLUIINTM_REMOVEFROMTASKBAR, 0, 0);
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ case WM_SETCURSOR:
+ if (cfg::dat.isTransparent) {
+ if (!transparentFocus && GetForegroundWindow() != hwnd) {
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ transparentFocus = 1;
+ SetTimer(hwnd, TM_AUTOALPHA, 250, NULL);
+ }
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ case WM_NCHITTEST: {
+ LRESULT result;
+ RECT r;
+ POINT pt;
+ int k = 0;
+ int clip = cfg::dat.bClipBorder;
+
+ GetWindowRect(hwnd, &r);
+ GetCursorPos(&pt);
+ if (pt.y <= r.bottom && pt.y >= r.bottom - clip - 6 && !cfg::getByte("CLUI", "AutoSize", 0)) {
+ if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10)
+ return HTBOTTOM;
+ if (pt.x < r.left + clip + 10)
+ return HTBOTTOMLEFT;
+ if (pt.x > r.right - clip - 10)
+ return HTBOTTOMRIGHT;
+
+ } else if (pt.y >= r.top && pt.y <= r.top + 3 && !cfg::getByte("CLUI", "AutoSize", 0)) {
+ if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10)
+ return HTTOP;
+ if (pt.x < r.left + clip + 10)
+ return HTTOPLEFT;
+ if (pt.x > r.right - clip - 10)
+ return HTTOPRIGHT;
+ } else if (pt.x >= r.left && pt.x <= r.left + clip + 6)
+ return HTLEFT;
+ else if (pt.x >= r.right - clip - 6 && pt.x <= r.right)
+ return HTRIGHT;
+
+ result = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
+ if (result == HTSIZE || result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT || result == HTBOTTOM || result == HTBOTTOMRIGHT || result == HTBOTTOMLEFT)
+ if (cfg::dat.autosize)
+ return HTCLIENT;
+ return result;
+ }
+
+ case WM_TIMER:
+ if ((int) wParam == TM_AUTOALPHA) {
+ int inwnd;
+
+ if (GetForegroundWindow() == hwnd) {
+ KillTimer(hwnd, TM_AUTOALPHA);
+ inwnd = 1;
+ } else {
+ POINT pt;
+ HWND hwndPt;
+ pt.x = (short) LOWORD(GetMessagePos());
+ pt.y = (short) HIWORD(GetMessagePos());
+ hwndPt = WindowFromPoint(pt);
+ inwnd = (hwndPt == hwnd || GetParent(hwndPt) == hwnd);
+ }
+ if (inwnd != transparentFocus) {
+ //change
+ transparentFocus = inwnd;
+ if (transparentFocus)
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ else
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.autoalpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ }
+ if (!transparentFocus)
+ KillTimer(hwnd, TM_AUTOALPHA);
+ } else if (wParam == TIMERID_AUTOSIZE) {
+ KillTimer(hwnd, wParam);
+ SetWindowPos(hwnd, 0, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+ PostMessage(hwnd, WM_SIZE, 0, 0);
+ PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0);
+ }
+ return TRUE;
+ case WM_SHOWWINDOW: {
+ static int noRecurse = 0;
+ DWORD thisTick, startTick;
+ int sourceAlpha, destAlpha;
+
+ if (cfg::dat.forceResize && wParam != SW_HIDE) {
+ cfg::dat.forceResize = FALSE;
+ if (0) { //!g_CluiData.fadeinout && MySetLayeredWindowAttributes && g_CluiData.bLayeredHack) {
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), 0, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ ShowWindow(hwnd, SW_SHOW);
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), 255, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ } else {
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0);
+ }
+ }
+ PostMessage(hwnd, CLUIINTM_REMOVEFROMTASKBAR, 0, 0);
+
+ if (g_floatoptions.enabled) {
+ if (wParam)
+ FLT_ShowHideAll(SW_HIDE);
+ else
+ FLT_ShowHideAll(SW_SHOWNOACTIVATE);
+ }
+
+ if (!cfg::dat.fadeinout)
+ SFL_SetState(-1);
+ if (lParam)
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ if (noRecurse)
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ if (!cfg::dat.fadeinout || !IsWinVer2000Plus())
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ g_fading_active = 1;
+
+ if (wParam) {
+ sourceAlpha = 0;
+ destAlpha = cfg::dat.isTransparent ? cfg::dat.alpha : 255;
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? (COLORREF)cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)sourceAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ noRecurse = 1;
+ ShowWindow(hwnd, SW_SHOW);
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ noRecurse = 0;
+ } else {
+ sourceAlpha = cfg::dat.isTransparent ? (transparentFocus ? cfg::dat.alpha : cfg::dat.autoalpha) : 255;
+ destAlpha = 0;
+ }
+ for (startTick = GetTickCount(); ;) {
+ thisTick = GetTickCount();
+ if (thisTick >= startTick + 200) {
+ SFL_SetState(-1);
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)(destAlpha), LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ g_fading_active = 0;
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)(sourceAlpha + (destAlpha - sourceAlpha) * (int)(thisTick - startTick) / 200), LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ }
+ API::SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)(destAlpha), LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0));
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+
+ case WM_SYSCOMMAND: {
+ BYTE bWindowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT);
+ if(SETTING_WINDOWSTYLE_DEFAULT == bWindowStyle) {
+ if(wParam == SC_RESTORE) {
+ CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ SendMessage(hwnd, CLUIINTM_REDRAW, 0, 0);
+ SendMessage(hwnd, CLUIINTM_STATUSBARUPDATE, 0, 0);
+ cfg::writeByte("CList", "State", SETTING_STATE_NORMAL);
+ break;
+ }
+ }
+
+ if (wParam == SC_MAXIMIZE)
+ return 0;
+ else if (wParam == SC_MINIMIZE) {
+ if(SETTING_WINDOWSTYLE_DEFAULT == bWindowStyle && !cfg::getByte("CList", "AlwaysHideOnTB", 0)) {
+ cfg::writeByte("CList", "State", SETTING_STATE_MINIMIZED);
+ break;
+ }
+ pcli->pfnShowHide(0, 0);
+ return 0;
+ }
+ else if (wParam == SC_RESTORE) {
+ pcli->pfnShowHide(0, 0);
+ return(0);
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+
+ case WM_COMMAND: {
+ DWORD dwOldFlags = cfg::dat.dwFlags;
+ if (HIWORD(wParam) == BN_CLICKED && lParam != 0) {
+ if (LOWORD(wParam) == IDC_TBFIRSTUID - 1)
+ break;
+ else if (LOWORD(wParam) >= IDC_TBFIRSTUID) { // skinnable buttons handling
+ ButtonItem *item = g_ButtonItems;
+ WPARAM wwParam = 0;
+ LPARAM llParam = 0;
+ HANDLE hContact = 0;
+ struct ClcContact *contact = 0;
+ int sel = cfg::clcdat ? cfg::clcdat->selection : -1;
+ int serviceFailure = FALSE;
+
+ if (sel != -1) {
+ sel = pcli->pfnGetRowByIndex(cfg::clcdat, cfg::clcdat->selection, &contact, NULL);
+ if (contact && contact->type == CLCIT_CONTACT) {
+ hContact = contact->hContact;
+ }
+ }
+ while (item) {
+ if (item->uId == (DWORD)LOWORD(wParam)) {
+ int contactOK = ServiceParamsOK(item, &wwParam, &llParam, hContact);
+
+ if (item->dwFlags & BUTTON_ISSERVICE) {
+ if (ServiceExists(item->szService) && contactOK)
+ CallService(item->szService, wwParam, llParam);
+ else if (contactOK)
+ serviceFailure = TRUE;
+ } else if (item->dwFlags & BUTTON_ISPROTOSERVICE && cfg::clcdat) {
+ if (contactOK) {
+ char szFinalService[512];
+
+ mir_snprintf(szFinalService, 512, "%s/%s", (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0), item->szService);
+ if (ServiceExists(szFinalService))
+ CallService(szFinalService, wwParam, llParam);
+ else
+ serviceFailure = TRUE;
+ }
+ } else if (item->dwFlags & BUTTON_ISDBACTION) {
+ BYTE *pValue;
+ char *szModule = item->szModule;
+ char *szSetting = item->szSetting;
+ HANDLE finalhContact = 0;
+
+ if (item->dwFlags & BUTTON_ISCONTACTDBACTION || item->dwFlags & BUTTON_DBACTIONONCONTACT) {
+ contactOK = ServiceParamsOK(item, &wwParam, &llParam, hContact);
+ if (contactOK && item->dwFlags & BUTTON_ISCONTACTDBACTION)
+ szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ finalhContact = hContact;
+ } else
+ contactOK = 1;
+
+ if (contactOK) {
+ BOOL fDelete = FALSE;
+
+ if (item->dwFlags & BUTTON_ISTOGGLE) {
+ BOOL fChecked = (SendMessage(item->hWnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED);
+
+ pValue = fChecked ? item->bValueRelease : item->bValuePush;
+ if (fChecked && pValue[0] == 0)
+ fDelete = TRUE;
+ } else
+ pValue = item->bValuePush;
+
+ if (fDelete) {
+ //_DebugTraceA("delete value: %s, %s ON %d", szModule, szSetting, finalhContact);
+ DBDeleteContactSetting(finalhContact, szModule, szSetting);
+ } else {
+ switch (item->type) {
+ case DBVT_BYTE:
+ cfg::writeByte(finalhContact, szModule, szSetting, pValue[0]);
+ break;
+ case DBVT_WORD:
+ cfg::writeWord(finalhContact, szModule, szSetting, *((WORD *)&pValue[0]));
+ //_DebugTraceA("set WORD value: %s, %s, %d ON %d", szModule, item->szSetting, *((WORD *)&pValue[0]), finalhContact);
+ break;
+ case DBVT_DWORD:
+ cfg::writeDword(finalhContact, szModule, szSetting, *((DWORD *)&pValue[0]));
+ break;
+ case DBVT_ASCIIZ:
+ cfg::writeString(finalhContact, szModule, szSetting, (char *)pValue);
+ break;
+ }
+ }
+ } else if (item->dwFlags & BUTTON_ISTOGGLE)
+ SendMessage(item->hWnd, BM_SETCHECK, 0, 0);
+ }
+ if (!contactOK)
+ MessageBox(0, _T("The requested action requires a valid contact selection. Please select a contact from the contact list and repeat"), _T("Parameter mismatch"), MB_OK);
+ if (serviceFailure) {
+ char szError[512];
+
+ mir_snprintf(szError, 512, "The service %s specified by the %s button definition was not found. You may need to install additional plugins", item->szService, item->szName);
+ MessageBoxA(0, szError, "Service failure", MB_OK);
+ }
+ break;
+ }
+ item = item->nextItem;
+ }
+ goto buttons_done;
+ }
+ switch (LOWORD(wParam)) {
+ case IDC_TBMENU:
+ case IDC_TBTOPMENU: {
+ RECT rc;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUGETMAIN, 0, 0);
+
+ GetWindowRect(GetDlgItem(hwnd, LOWORD(wParam)), &rc);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, LOWORD(wParam) == IDC_TBMENU ? rc.top : rc.bottom, 0, hwnd, NULL);
+ return 0;
+ }
+ case IDC_TBGLOBALSTATUS:
+ case IDC_TBTOPSTATUS: {
+ RECT rc;
+ HMENU hmenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0);
+ GetWindowRect(GetDlgItem(hwnd, LOWORD(wParam)), &rc);
+ TrackPopupMenu(hmenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, rc.top, 0, hwnd, NULL);
+ return 0;
+ }
+ case IDC_TABSRMMSLIST:
+ case IDC_TABSRMMMENU: {
+ if (ServiceExists("SRMsg_MOD/GetWindowFlags"))
+ CallService("SRMsg_MOD/Show_TrayMenu", 0, LOWORD(wParam) == IDC_TABSRMMSLIST ? 0 : 1);
+
+ return 0;
+ }
+ case IDC_TBSOUND: {
+ cfg::dat.soundsOff = !cfg::dat.soundsOff;
+ cfg::writeByte("CLUI", "NoSounds", (BYTE)cfg::dat.soundsOff);
+ cfg::writeByte("Skin", "UseSound", (BYTE)(cfg::dat.soundsOff ? 0 : 1));
+ return 0;
+ }
+ case IDC_TBSELECTVIEWMODE:
+ SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_SELECTMODE, lParam);
+ break;
+ case IDC_TBCLEARVIEWMODE:
+ SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_RESETMODES, lParam);
+ break;
+ case IDC_TBCONFIGUREVIEWMODE:
+ SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_CONFIGUREMODES, lParam);
+ break;
+ case IDC_TBFINDANDADD:
+ CallService(MS_FINDADD_FINDADD, 0, 0);
+ return 0;
+ case IDC_TBACCOUNTS:
+ CallService(MS_PROTO_SHOWACCMGR, 0, 0);
+ break;
+ case IDC_TBOPTIONS:
+ CallService("Options/OptionsCommand", 0, 0);
+ return 0;
+ }
+ } else if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), (LPARAM)(HANDLE) NULL))
+ return 0;
+
+buttons_done:
+ switch (LOWORD(wParam)) {
+ case ID_TRAY_EXIT:
+ case ID_ICQ_EXIT:
+ cfg::shutDown = 1;
+ if (CallService(MS_SYSTEM_OKTOEXIT, 0, 0))
+ DestroyWindow(hwnd);
+ break;
+ case IDC_TBMINIMIZE:
+ case ID_TRAY_HIDE:
+ pcli->pfnShowHide(0, 0);
+ break;
+ case POPUP_NEWGROUP:
+ SendMessage(pcli->hwndContactTree, CLM_SETHIDEEMPTYGROUPS, 0, 0);
+ CallService(MS_CLIST_GROUPCREATE, 0, 0);
+ break;
+ case POPUP_HIDEOFFLINE:
+ case IDC_TBHIDEOFFLINE:
+ CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)(-1), 0);
+ break;
+ case POPUP_HIDEOFFLINEROOT:
+ SendMessage(pcli->hwndContactTree, CLM_SETHIDEOFFLINEROOT, !SendMessage(pcli->hwndContactTree, CLM_GETHIDEOFFLINEROOT, 0, 0), 0);
+ break;
+ case POPUP_HIDEEMPTYGROUPS: {
+ int newVal = !(GetWindowLong(pcli->hwndContactTree, GWL_STYLE) & CLS_HIDEEMPTYGROUPS);
+ cfg::writeByte("CList", "HideEmptyGroups", (BYTE) newVal);
+ SendMessage(pcli->hwndContactTree, CLM_SETHIDEEMPTYGROUPS, newVal, 0);
+ break;
+ }
+ case POPUP_DISABLEGROUPS:
+ case IDC_TBHIDEGROUPS: {
+ int newVal = !(GetWindowLong(pcli->hwndContactTree, GWL_STYLE) & CLS_USEGROUPS);
+ cfg::writeByte("CList", "UseGroups", (BYTE) newVal);
+ SendMessage(pcli->hwndContactTree, CLM_SETUSEGROUPS, newVal, 0);
+ CheckDlgButton(hwnd, IDC_TBHIDEGROUPS, newVal ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case POPUP_HIDEMIRANDA:
+ pcli->pfnShowHide(0, 0);
+ break;
+ case POPUP_VISIBILITY:
+ cfg::dat.dwFlags ^= CLUI_SHOWVISI;
+ break;
+ case POPUP_SHOWMETAICONS:
+ cfg::dat.dwFlags ^= CLUI_USEMETAICONS;
+ SendMessage(pcli->hwndContactTree, CLM_AUTOREBUILD, 0, 0);
+ break;
+ case POPUP_FRAME:
+ cfg::dat.dwFlags ^= CLUI_FRAME_CLISTSUNKEN;
+ break;
+ case POPUP_TOOLBAR:
+ cfg::dat.dwFlags ^= CLUI_FRAME_SHOWTOPBUTTONS;
+ break;
+ case POPUP_BUTTONS:
+ cfg::dat.dwFlags ^= CLUI_FRAME_SHOWBOTTOMBUTTONS;
+ break;
+ case POPUP_SHOWSTATUSICONS:
+ cfg::dat.dwFlags ^= CLUI_FRAME_STATUSICONS;
+ break;
+ case POPUP_FLOATER:
+ cfg::dat.bUseFloater ^= CLUI_USE_FLOATER;
+ if (cfg::dat.bUseFloater & CLUI_USE_FLOATER) {
+ SFL_Create();
+ SFL_SetState(-1);
+ } else
+ SFL_Destroy();
+ cfg::writeByte("CLUI", "FloaterMode", cfg::dat.bUseFloater);
+ break;
+ case POPUP_FLOATER_AUTOHIDE:
+ cfg::dat.bUseFloater ^= CLUI_FLOATER_AUTOHIDE;
+ SFL_SetState(cfg::dat.bUseFloater & CLUI_FLOATER_AUTOHIDE ? (cfg::getByte("CList", "State", SETTING_STATE_NORMAL) == SETTING_STATE_NORMAL ? 0 : 1) : 1);
+ cfg::writeByte("CLUI", "FloaterMode", cfg::dat.bUseFloater);
+ break;
+ case POPUP_FLOATER_EVENTS:
+ cfg::dat.bUseFloater ^= CLUI_FLOATER_EVENTS;
+ SFL_SetSize();
+ SFL_Update(0, 0, 0, NULL, FALSE);
+ cfg::writeByte("CLUI", "FloaterMode", cfg::dat.bUseFloater);
+ break;
+ }
+ if (dwOldFlags != cfg::dat.dwFlags) {
+ InvalidateRect(pcli->hwndContactTree, NULL, FALSE);
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+ if ((dwOldFlags & (CLUI_FRAME_SHOWTOPBUTTONS | CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_CLISTSUNKEN)) != (cfg::dat.dwFlags & (CLUI_FRAME_SHOWTOPBUTTONS | CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_CLISTSUNKEN))) {
+ ConfigureFrame();
+ ConfigureCLUIGeometry(1);
+ }
+ ConfigureEventArea(pcli->hwndContactList);
+ SetButtonStyle();
+ PostMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ }
+ return FALSE;
+ }
+ case WM_LBUTTONDOWN: {
+ if (cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS || g_ButtonItems) {
+ POINT ptMouse, pt;
+ RECT rcClient;
+
+ GetCursorPos(&ptMouse);
+ pt = ptMouse;
+ if (g_ButtonItems)
+ return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ ScreenToClient(hwnd, &ptMouse);
+ GetClientRect(hwnd, &rcClient);
+ rcClient.bottom = cfg::dat.topOffset;
+ if (PtInRect(&rcClient, ptMouse))
+ return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ }
+ break;
+ }
+ case WM_DISPLAYCHANGE:
+ SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0); //forces it to send a cln_listsizechanged
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR) lParam)->hwndFrom == pcli->hwndContactTree) {
+ switch (((LPNMHDR) lParam)->code) {
+ case CLN_LISTSIZECHANGE:
+ sttProcessResize(hwnd, (NMCLISTCONTROL*)lParam);
+ return FALSE;
+
+ case NM_CLICK: {
+ NMCLISTCONTROL *nm = (NMCLISTCONTROL *) lParam;
+ DWORD hitFlags;
+ HANDLE hItem;
+
+ hItem = (HANDLE)SendMessage(pcli->hwndContactTree, CLM_HITTEST, (WPARAM) & hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y));
+
+ if ((hitFlags & (CLCHT_NOWHERE | CLCHT_INLEFTMARGIN | CLCHT_BELOWITEMS)) == 0)
+ break;
+ if (cfg::getByte("CLUI", "ClientAreaDrag", SETTING_CLIENTDRAG_DEFAULT)) {
+ POINT pt;
+ pt = nm->pt;
+ ClientToScreen(pcli->hwndContactTree, &pt);
+ return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ }
+ }
+ return FALSE;
+ }
+ }
+ break;
+ case WM_CONTEXTMENU: {
+ RECT rc;
+ POINT pt;
+
+ pt.x = (short) LOWORD(lParam);
+ pt.y = (short) HIWORD(lParam);
+ // x/y might be -1 if it was generated by a kb click
+ GetWindowRect(pcli->hwndContactTree, &rc);
+ if (pt.x == -1 && pt.y == -1) {
+ // all this is done in screen-coords!
+ GetCursorPos(&pt);
+ // the mouse isnt near the window, so put it in the middle of the window
+ if (!PtInRect(&rc, pt)) {
+ pt.x = rc.left + (rc.right - rc.left) / 2;
+ pt.y = rc.top + (rc.bottom - rc.top) / 2;
+ }
+ }
+ if (PtInRect(&rc, pt)) {
+ HMENU hMenu;
+ hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDGROUP, 0, 0);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
+ DestroyTrayMenu(hMenu);
+ return 0;
+ }
+ GetWindowRect(pcli->hwndStatus, &rc);
+ if (PtInRect(&rc, pt)) {
+ HMENU hMenu;
+ if (cfg::getByte("CLUI", "SBarRightClk", 0))
+ hMenu = (HMENU) CallService(MS_CLIST_MENUGETMAIN, 0, 0);
+ else
+ hMenu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS, 0, 0);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
+ return 0;
+ }
+ if (cfg::dat.dwFlags & CLUI_FRAME_SHOWTOPBUTTONS) {
+ HMENU hMenu;
+ int iSelection;
+ RECT rcHit;
+
+ GetClientRect(hwnd, &rcHit);
+ GetCursorPos(&pt);
+ ScreenToClient(hwnd, &pt);
+ hMenu = cfg::dat.hMenuButtons;
+ rcHit.bottom = cfg::dat.dwButtonHeight + cfg::dat.bCTop;
+ if (!PtInRect(&rcHit, pt))
+ break;
+ ClientToScreen(hwnd, &pt);
+ EnableMenuItem(hMenu, ID_BUTTONBAR_DECREASEBUTTONSIZE, MF_BYCOMMAND | (cfg::dat.dwButtonHeight <= 17 ? MF_GRAYED : MF_ENABLED));
+ EnableMenuItem(hMenu, ID_BUTTONBAR_INCREASEBUTTONSIZE, MF_BYCOMMAND | (cfg::dat.dwButtonHeight >= 24 ? MF_GRAYED : MF_ENABLED));
+ CheckMenuItem(hMenu, ID_BUTTONBAR_FLATBUTTONS, MF_BYCOMMAND | ((cfg::dat.dwFlags & CLUI_FRAME_BUTTONSFLAT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenu, ID_BUTTONBAR_NOVISUALSTYLES, MF_BYCOMMAND | ((cfg::dat.dwFlags & CLUI_FRAME_BUTTONSCLASSIC) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenu, ID_BUTTONBAR_DRAWSUNKENFRAME, MF_BYCOMMAND | ((cfg::dat.dwFlags & CLUI_FRAME_BUTTONBARSUNKEN) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenu, ID_BUTTONBAR_SKINNEDTOOLBAR, MF_BYCOMMAND | (cfg::dat.bSkinnedToolbar ? MF_CHECKED : MF_UNCHECKED));
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hMenu, 0);
+
+ iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
+ if (iSelection >= 50000) {
+ int iIndex = iSelection - 50000;
+ cfg::dat.toolbarVisibility ^= top_buttons[iIndex].visibilityOrder;
+ cfg::writeDword("CLUI", "TBVisibility", cfg::dat.toolbarVisibility);
+ ConfigureFrame();
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ InvalidateRect(hwnd, NULL, TRUE);
+ break;
+ }
+ switch (iSelection) {
+ case ID_BUTTONBAR_DECREASEBUTTONSIZE:
+ case ID_BUTTONBAR_INCREASEBUTTONSIZE:
+ cfg::dat.dwButtonHeight += (iSelection == ID_BUTTONBAR_DECREASEBUTTONSIZE ? -1 : 1);
+ cfg::dat.dwButtonWidth = cfg::dat.dwButtonHeight;
+ cfg::writeByte("CLUI", "TBSize", (BYTE) cfg::dat.dwButtonHeight);
+ ConfigureCLUIGeometry(1);
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ InvalidateRect(hwnd, NULL, TRUE);
+ break;
+ case ID_BUTTONBAR_NOVISUALSTYLES:
+ cfg::dat.dwFlags ^= CLUI_FRAME_BUTTONSCLASSIC;
+ SetButtonStyle();
+ break;
+ case ID_BUTTONBAR_FLATBUTTONS:
+ cfg::dat.dwFlags ^= CLUI_FRAME_BUTTONSFLAT;
+ SetButtonStyle();
+ break;
+ case ID_BUTTONBAR_DRAWSUNKENFRAME:
+ cfg::dat.dwFlags ^= CLUI_FRAME_BUTTONBARSUNKEN;
+ InvalidateRect(hwnd, NULL, FALSE);
+ break;
+ case ID_BUTTONBAR_SKINNEDTOOLBAR:
+ cfg::dat.bSkinnedToolbar = !cfg::dat.bSkinnedToolbar;
+ SetTBSKinned(cfg::dat.bSkinnedToolbar);
+ cfg::writeByte("CLUI", "tb_skinned", (BYTE)cfg::dat.bSkinnedToolbar);
+ PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0);
+ break;
+ }
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+ return 0;
+ }
+ }
+ break;
+
+ case WM_MEASUREITEM:
+ if (((LPMEASUREITEMSTRUCT) lParam)->itemData == MENU_MIRANDAMENU) {
+ ((LPMEASUREITEMSTRUCT) lParam)->itemWidth = g_cxsmIcon * 4 / 3;
+ ((LPMEASUREITEMSTRUCT) lParam)->itemHeight = 0;
+ return TRUE;
+ }
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ case WM_DRAWITEM: {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+
+ if (hbmLockedPoint == 0) {
+ RECT rc = {0, 0, 5, 5};
+
+ hdcLockedPoint = CreateCompatibleDC(dis->hDC);
+ hbmLockedPoint = CreateCompatibleBitmap(dis->hDC, 5, 5);
+ hbmOldLockedPoint = reinterpret_cast<HBITMAP>(SelectObject(hdcLockedPoint, hbmLockedPoint));
+ }
+ if (dis->hwndItem == pcli->hwndStatus) {
+ ProtocolData *pd = (ProtocolData *)dis->itemData;
+ int nParts = SendMessage(pcli->hwndStatus, SB_GETPARTS, 0, 0);
+ char *szProto;
+ int status, x;
+ SIZE textSize;
+ BYTE showOpts = cfg::getByte("CLUI", "SBarShow", 1);
+ if (IsBadCodePtr((FARPROC)pd))
+ return TRUE;
+ if (cfg::shutDown)
+ return TRUE;
+ szProto = pd->RealName;
+ status = CallProtoService(szProto, PS_GETSTATUS, 0, 0);
+ SetBkMode(dis->hDC, TRANSPARENT);
+ x = dis->rcItem.left;
+
+ if (showOpts & 1) {
+ HICON hIcon;
+
+ if (status >= ID_STATUS_CONNECTING && status < ID_STATUS_OFFLINE) {
+ if (cfg::dat.IcoLib_Avail) {
+ char szBuffer[128];
+ mir_snprintf(szBuffer, 128, "%s_conn", pd->RealName);
+ hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)szBuffer);
+ } else
+ hIcon = cfg::dat.hIconConnecting;
+ } else if (cfg::dat.bShowXStatusOnSbar && status > ID_STATUS_OFFLINE) {
+ ICQ_CUSTOM_STATUS cst = {0};
+ char szServiceName[128];
+ int xStatus;
+
+ mir_snprintf(szServiceName, 128, "%s%s", pd->RealName, PS_ICQ_GETCUSTOMSTATUSEX);
+ cst.cbSize = sizeof(ICQ_CUSTOM_STATUS);
+ cst.flags = CSSF_MASK_STATUS;
+ cst.status = &xStatus;
+ if (ServiceExists(szServiceName) && !CallService(szServiceName, 0, (LPARAM)&cst) && xStatus > 0) {
+ hIcon = (HICON)CallProtoService(pd->RealName, PS_ICQ_GETCUSTOMSTATUSICON, 0, LR_SHARED); // get OWN xStatus icon (if set)
+ } else
+ hIcon = LoadSkinnedProtoIcon(szProto, status);
+ } else
+ hIcon = LoadSkinnedProtoIcon(szProto, status);
+
+ if (!(showOpts & 6) && cfg::dat.bEqualSections)
+ x = (dis->rcItem.left + dis->rcItem.right - 16) >> 1;
+ if (pd->statusbarpos == 0)
+ x += (cfg::dat.bEqualSections ? (cfg::dat.bCLeft / 2) : cfg::dat.bCLeft);
+ else if (pd->statusbarpos == nParts - 1)
+ x -= (cfg::dat.bCRight / 2);
+ DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - 16) >> 1, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0);
+
+ if (cfg::getByte("CLUI", "sbar_showlocked", 1)) {
+ if (cfg::getByte(szProto, "LockMainStatus", 0)) {
+ hIcon = LoadSkinnedIcon(SKINICON_OTHER_STATUS_LOCKED);
+ if (hIcon != NULL) {
+ DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - 16) >> 1, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0);
+ }
+ }
+ }
+ x += 18;
+ } else {
+ x += 2;
+ if (pd->statusbarpos == 0)
+ x += (cfg::dat.bEqualSections ? (cfg::dat.bCLeft / 2) : cfg::dat.bCLeft);
+ else if (pd->statusbarpos == nParts - 1)
+ x -= (cfg::dat.bCRight / 2);
+ }
+ if (showOpts & 2) {
+ TCHAR szName[64];
+ PROTOACCOUNT* pa = ProtoGetAccount( szProto );
+ if ( pa ) {
+ lstrcpyn( szName, pa->tszAccountName, SIZEOF(szName));
+ szName[ SIZEOF(szName)-1 ] = 0;
+ }
+ else szName[0] = 0;
+
+ if (lstrlen(szName) < sizeof(szName) - 1)
+ lstrcat(szName, _T(" "));
+ GetTextExtentPoint32(dis->hDC, szName, lstrlen(szName), &textSize);
+ TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szName, lstrlen(szName));
+ x += textSize.cx;
+ }
+ if (showOpts & 4) {
+ TCHAR *szStatus = pcli->pfnGetStatusModeDescription( status, 0 );
+ GetTextExtentPoint32(dis->hDC, szStatus, lstrlen(szStatus), &textSize);
+ TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szStatus, lstrlen(szStatus));
+ }
+ } else if (dis->CtlType == ODT_MENU) {
+ if (dis->itemData == MENU_MIRANDAMENU)
+ break;
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ }
+ return 0;
+ }
+
+ case WM_CLOSE:
+ if(SETTING_WINDOWSTYLE_DEFAULT == cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT) && !cfg::getByte("CList", "AlwaysHideOnTB", 0)) {
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ return(0);
+ }
+ pcli->pfnShowHide(0, 0);
+ return(0);
+
+ case CLUIINTM_REDRAW:
+ if (show_on_first_autosize) {
+ show_on_first_autosize = FALSE;
+ ShowCLUI(hwnd);
+ }
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+ case CLUIINTM_STATUSBARUPDATE:
+ CluiProtocolStatusChanged(0, 0);
+ return 0;
+
+ case WM_THEMECHANGED:
+ API::updateState();
+ break;
+
+ case WM_DESTROY:
+ if (cfg::dat.hdcBg) {
+ SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBgOld);
+ DeleteObject(cfg::dat.hbmBg);
+ DeleteDC(cfg::dat.hdcBg);
+ cfg::dat.hdcBg = NULL;
+ }
+ if (cfg::dat.bmpBackground) {
+ SelectObject(cfg::dat.hdcPic, cfg::dat.hbmPicOld);
+ DeleteDC(cfg::dat.hdcPic);
+ DeleteObject(cfg::dat.bmpBackground);
+ cfg::dat.bmpBackground = NULL;
+ }
+ DestroyMenu(cfg::dat.hMenuButtons);
+ FreeProtocolData();
+ if (hdcLockedPoint) {
+ SelectObject(hdcLockedPoint, hbmOldLockedPoint);
+ DeleteObject(hbmLockedPoint);
+ DeleteDC(hdcLockedPoint);
+ }
+ /*
+ * if this has not yet been set, do it now.
+ * indicates that clist is shutting down and prevents various things
+ * from happening at shutdown.
+ */
+ if (!cfg::shutDown)
+ cfg::shutDown = 1;
+ CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)hFrameContactTree, (LPARAM)0);
+ break;
+ }
+ return saveContactListWndProc(hwnd, msg, wParam, lParam);
+}
+
+#ifndef CS_DROPSHADOW
+#define CS_DROPSHADOW 0x00020000
+#endif
+
+static int MetaChanged(WPARAM wParam, LPARAM lParam)
+{
+ pcli->pfnClcBroadcast(INTM_METACHANGEDEVENT, wParam, lParam);
+ return 0;
+}
+
+static BOOL g_AboutDlgActive = 0;
+
+INT_PTR CALLBACK DlgProcAbout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HICON hIcon;
+ COLORREF url_visited = RGB(128, 0, 128);
+ COLORREF url_unvisited = RGB(0, 0, 255);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ int h;
+ HFONT hFont;
+ LOGFONT lf;
+
+ g_AboutDlgActive = TRUE;
+ hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_GETFONT, 0, 0);
+ GetObject(hFont, sizeof(lf), &lf);
+ h = lf.lfHeight;
+ lf.lfHeight = (int)(lf.lfHeight * 1.5);
+ lf.lfWeight = FW_BOLD;
+ hFont = CreateFontIndirect(&lf);
+ SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_SETFONT, (WPARAM)hFont, 0);
+ lf.lfHeight = h;
+ hFont = CreateFontIndirect(&lf);
+ SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, (WPARAM)hFont, 0);
+ }
+ {
+ char str[64];
+ DWORD v = pluginInfo.version;
+#if defined(_UNICODE)
+ mir_snprintf(str, sizeof(str), "%s %d.%d.%d.%d (Unicode)", Translate("Version"), HIBYTE(HIWORD(v)), LOBYTE(HIWORD(v)), HIBYTE(LOWORD(v)), LOBYTE(LOWORD(v)));
+#else
+ mir_snprintf(str, sizeof(str), "%s %d.%d.%d.%d", Translate("Version"), HIBYTE(HIWORD(v)), LOBYTE(HIWORD(v)), HIBYTE(LOWORD(v)), LOBYTE(LOWORD(v)));
+#endif
+ SetDlgItemTextA(hwndDlg, IDC_VERSION, str);
+ mir_snprintf(str, sizeof(str), Translate("Built %s %s"), __DATE__, __TIME__);
+ SetDlgItemTextA(hwndDlg, IDC_BUILDTIME, str);
+ }
+ hIcon = LoadIcon(GetModuleHandleA("miranda32.exe"), MAKEINTRESOURCE(102));
+ SendDlgItemMessage(hwndDlg, IDC_LOGO, STM_SETICON, (WPARAM)hIcon, 0);
+ SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
+ DestroyIcon(hIcon);
+ return TRUE;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ case IDC_SUPPORT:
+#if defined(_UNICODE)
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://miranda-im.org/download/details.php?action=viewfile&id=2365");
+#else
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://miranda-im.org/download/details.php?action=viewfile&id=2189");
+#endif
+ break;
+ }
+ break;
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_WHITERECT)
+ || (HWND)lParam == GetDlgItem(hwndDlg, IDC_CLNICER)
+ || (HWND)lParam == GetDlgItem(hwndDlg, IDC_VERSION)
+ || (HWND)lParam == GetDlgItem(hwndDlg, IDC_BUILDTIME)
+ || (HWND)lParam == GetDlgItem(hwndDlg, IDC_COPYRIGHT)
+ || (HWND)lParam == GetDlgItem(hwndDlg, IDC_SUPPORT)
+ || (HWND)lParam == GetDlgItem(hwndDlg, IDC_LOGO)) {
+ if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_CLNICER))
+ SetTextColor((HDC)wParam, RGB(180, 10, 10));
+ else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_VERSION))
+ SetTextColor((HDC)wParam, RGB(70, 70, 70));
+ else
+ SetTextColor((HDC)wParam, RGB(0, 0, 0));
+ SetBkColor((HDC)wParam, RGB(255, 255, 255));
+ return (INT_PTR)GetStockObject(WHITE_BRUSH);
+ }
+ break;
+ case WM_DESTROY: {
+ HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_GETFONT, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0), 0);
+ DeleteObject(hFont);
+ hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_GETFONT, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0), 0);
+ DeleteObject(hFont);
+ g_AboutDlgActive = FALSE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CLN_ShowAbout(WPARAM wParam, LPARAM lParam)
+{
+ if (!g_AboutDlgActive)
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CLNABOUT), 0, DlgProcAbout, 0);
+ return 0;
+}
+
+static INT_PTR CLN_ShowMainMenu(WPARAM wParam, LPARAM lParam)
+{
+ HMENU hMenu;
+ POINT pt;
+
+ hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0);
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL);
+ return 0;
+}
+
+static INT_PTR CLN_ShowStatusMenu(WPARAM wParam, LPARAM lParam)
+{
+ HMENU hMenu;
+ POINT pt;
+
+ hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0);
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL);
+ return 0;
+}
+
+#define MS_CLUI_SHOWMAINMENU "CList/ShowMainMenu"
+#define MS_CLUI_SHOWSTATUSMENU "CList/ShowStatusMenu"
+
+void LoadCLUIModule(void)
+{
+ WNDCLASS wndclass;
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, CluiModulesLoaded);
+ HookEvent(ME_MC_DEFAULTTCHANGED, MetaChanged);
+ HookEvent(ME_MC_SUBCONTACTSCHANGED, MetaChanged);
+
+ InitGroupMenus();
+
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = EventAreaWndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = g_hInst;
+ wndclass.hIcon = 0;
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE);
+ wndclass.lpszMenuName = 0;
+ wndclass.lpszClassName = _T("EventAreaClass");
+ RegisterClass(&wndclass);
+
+ oldhideoffline = cfg::getByte("CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT);
+ cluiPos.left = cfg::getDword("CList", "x", 600);
+ cluiPos.top = cfg::getDword("CList", "y", 200);
+ cluiPos.right = cfg::getDword("CList", "Width", 150);
+ cluiPos.bottom = cfg::getDword("CList", "Height", 350);
+
+ LoadExtraIconModule();
+ SFL_RegisterWindowClass();
+
+ PreCreateCLC(pcli->hwndContactList);
+ LoadCLUIFramesModule();
+ CreateServiceFunction("CLN/About", CLN_ShowAbout);
+ CreateServiceFunction(MS_CLUI_SHOWMAINMENU, CLN_ShowMainMenu);
+ CreateServiceFunction(MS_CLUI_SHOWSTATUSMENU, CLN_ShowStatusMenu);
+}
+
+static struct {
+ UINT id;
+ char *name;
+} _tagFSINFO[] = {
+ FONTID_CONTACTS, LPGEN( "Standard contacts"),
+ FONTID_INVIS, LPGEN( "Online contacts to whom you have a different visibility"),
+ FONTID_OFFLINE, LPGEN( "Offline contacts"),
+ FONTID_OFFINVIS, LPGEN( "Offline contacts to whom you have a different visibility" ),
+ FONTID_NOTONLIST, LPGEN( "Contacts which are 'not on list'"),
+ FONTID_GROUPS, LPGEN( "Groups"),
+ FONTID_GROUPCOUNTS, LPGEN( "Group member counts"),
+ FONTID_DIVIDERS, LPGEN( "Dividers"),
+ FONTID_STATUS, LPGEN("Status mode"),
+ FONTID_FRAMETITLE, LPGEN("Frame titles"),
+ FONTID_EVENTAREA, LPGEN("Event area"),
+ FONTID_TIMESTAMP, LPGEN("Contact list local time"),
+ 0, NULL
+};
+
+void FS_RegisterFonts()
+{
+ ColourID colourid;
+ FontID fid = {0};
+ char szTemp[50];
+ DBVARIANT dbv;
+ int j = 0;
+
+ fid.cbSize = sizeof(fid);
+ strncpy(fid.group, "Contact List", sizeof(fid.group));
+ strncpy(fid.dbSettingsGroup, "CLC", 5);
+ fid.flags = FIDF_DEFAULTVALID | FIDF_ALLOWEFFECTS | FIDF_APPENDNAME | FIDF_SAVEPOINTSIZE;
+ while (_tagFSINFO[j].name != 0) {
+ _snprintf(szTemp, sizeof(szTemp), "Font%d", _tagFSINFO[j].id);
+ strncpy(fid.prefix, szTemp, sizeof(fid.prefix));
+ fid.order = _tagFSINFO[j].id;
+ strncpy(fid.name, Translate(_tagFSINFO[j].name), 60);
+ _snprintf(szTemp, sizeof(szTemp), "Font%dCol", _tagFSINFO[j].id);
+ fid.deffontsettings.colour = (COLORREF)cfg::getDword("CLC", szTemp, GetSysColor(COLOR_WINDOWTEXT));
+
+ _snprintf(szTemp, sizeof(szTemp), "Font%dSize", _tagFSINFO[j].id);
+ fid.deffontsettings.size = (BYTE)cfg::getByte("CLC", szTemp, 8);
+
+ _snprintf(szTemp, sizeof(szTemp), "Font%dSty", _tagFSINFO[j].id);
+ fid.deffontsettings.style = cfg::getByte("CLC", szTemp, 0);
+ _snprintf(szTemp, sizeof(szTemp), "Font%dSet", _tagFSINFO[j].id);
+ fid.deffontsettings.charset = cfg::getByte("CLC", szTemp, DEFAULT_CHARSET);
+ _snprintf(szTemp, sizeof(szTemp), "Font%dName", _tagFSINFO[j].id);
+ if (cfg::getString(NULL, "CLC", szTemp, &dbv))
+ lstrcpynA(fid.deffontsettings.szFace, "Arial", LF_FACESIZE);
+ else {
+ lstrcpynA(fid.deffontsettings.szFace, dbv.pszVal, LF_FACESIZE);
+ mir_free(dbv.pszVal);
+ }
+ CallService(MS_FONT_REGISTER, (WPARAM)&fid, 0);
+ j++;
+ }
+ // and colours
+ colourid.cbSize = sizeof(ColourID);
+ colourid.order = 0;
+ strncpy(colourid.dbSettingsGroup, "CLC", sizeof(colourid.dbSettingsGroup));
+
+ strncpy(colourid.setting, "BkColour", sizeof(colourid.setting));
+ strncpy(colourid.name, LPGEN("Background"), SIZEOF(colourid.name));
+ strncpy(colourid.group, LPGEN("Contact List"), SIZEOF(colourid.group));
+ colourid.defcolour = CLCDEFAULT_BKCOLOUR;
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&colourid, 0);
+
+ strncpy(colourid.setting, "SelTextColour", sizeof(colourid.setting));
+ strncpy(colourid.name, LPGEN("Selected Text"), SIZEOF(colourid.name));
+ colourid.order = 1;
+ colourid.defcolour = CLCDEFAULT_SELTEXTCOLOUR;
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&colourid, 0);
+
+ strncpy(colourid.setting, "HotTextColour", sizeof(colourid.setting));
+ strncpy(colourid.name, LPGEN("Hottrack Text"), SIZEOF(colourid.name));
+ colourid.order = 1;
+ colourid.defcolour = CLCDEFAULT_HOTTEXTCOLOUR;
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&colourid, 0);
+
+ strncpy(colourid.setting, "QuickSearchColour", sizeof(colourid.setting));
+ strncpy(colourid.name, LPGEN("Quicksearch Text"), SIZEOF(colourid.name));
+ colourid.order = 1;
+ colourid.defcolour = CLCDEFAULT_QUICKSEARCHCOLOUR;
+ CallService(MS_COLOUR_REGISTER, (WPARAM)&colourid, 0);
+
+}
diff --git a/plugins/Clist_nicer/SRC/cluiopts.cpp b/plugins/Clist_nicer/SRC/cluiopts.cpp
new file mode 100644
index 0000000000..d77caadea4
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/cluiopts.cpp
@@ -0,0 +1,476 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include "commonheaders.h"
+
+extern WNDPROC OldStatusBarProc;
+extern HANDLE hExtraImageApplying;
+extern SIZE g_oldSize;
+extern POINT g_oldPos;
+extern COLORREF g_CLUISkinnedBkColorRGB;
+extern HPEN g_hPenCLUIFrames;
+
+static int opt_clui_changed = 0;
+
+void AddToTaskBar(HWND hWnd);
+
+INT_PTR CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ opt_clui_changed = 0;
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_BRINGTOFRONT, cfg::getByte("CList", "BringToFront", SETTING_BRINGTOFRONT_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ALWAYSHIDEONTASKBAR, cfg::getByte("CList", "AlwaysHideOnTB", 1) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONTOP, cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWMAINMENU, cfg::getByte("CLUI", "ShowMainMenu", SETTING_SHOWMAINMENU_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_CLIENTDRAG, cfg::getByte("CLUI", "ClientAreaDrag", SETTING_CLIENTDRAG_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_FADEINOUT, cfg::dat.fadeinout ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOSIZE, cfg::dat.autosize);
+ CheckDlgButton(hwndDlg, IDC_DROPSHADOW, cfg::getByte("CList", "WindowShadow", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONDESKTOP, cfg::getByte("CList", "OnDesktop", 0) ? BST_CHECKED : BST_UNCHECKED);
+
+ SendDlgItemMessage(hwndDlg, IDC_BORDERSTYLE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Title bar"));
+ SendDlgItemMessage(hwndDlg, IDC_BORDERSTYLE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Tool Window"));
+ SendDlgItemMessage(hwndDlg, IDC_BORDERSTYLE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Thin border"));
+ SendDlgItemMessage(hwndDlg, IDC_BORDERSTYLE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("No border"));
+ SendDlgItemMessage(hwndDlg, IDC_BORDERSTYLE, CB_SETCURSEL, cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_TOOLWINDOW), 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_MAXSIZESPIN, UDM_SETRANGE, 0, MAKELONG(100, 0));
+ SendDlgItemMessage(hwndDlg, IDC_MAXSIZESPIN, UDM_SETPOS, 0, cfg::getByte("CLUI", "MaxSizeHeight", 75));
+
+ SendDlgItemMessage(hwndDlg, IDC_CLIPBORDERSPIN, UDM_SETRANGE, 0, MAKELONG(10, 0));
+ SendDlgItemMessage(hwndDlg, IDC_CLIPBORDERSPIN, UDM_SETPOS, 0, cfg::dat.bClipBorder);
+
+ SendDlgItemMessage(hwndDlg, IDC_CLEFTSPIN, UDM_SETRANGE, 0, MAKELONG(255, 0));
+ SendDlgItemMessage(hwndDlg, IDC_CRIGHTSPIN, UDM_SETRANGE, 0, MAKELONG(255, 0));
+ SendDlgItemMessage(hwndDlg, IDC_CTOPSPIN, UDM_SETRANGE, 0, MAKELONG(255, 0));
+ SendDlgItemMessage(hwndDlg, IDC_CBOTTOMSPIN, UDM_SETRANGE, 0, MAKELONG(255, 0));
+
+ SendDlgItemMessage(hwndDlg, IDC_CLUIFRAMESBDR, CPM_SETCOLOUR, 0, cfg::getDword("CLUI", "clr_frameborder", RGB(40, 40, 40)));
+
+ SendDlgItemMessage(hwndDlg, IDC_CLEFTSPIN, UDM_SETPOS, 0, cfg::dat.bCLeft - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0));
+ SendDlgItemMessage(hwndDlg, IDC_CRIGHTSPIN, UDM_SETPOS, 0, cfg::dat.bCRight - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0));
+ SendDlgItemMessage(hwndDlg, IDC_CTOPSPIN, UDM_SETPOS, 0, cfg::dat.bCTop);
+ SendDlgItemMessage(hwndDlg, IDC_CBOTTOMSPIN, UDM_SETPOS, 0, cfg::dat.bCBottom);
+
+ CheckDlgButton(hwndDlg, IDC_AUTOSIZEUPWARD, cfg::getByte("CLUI", "AutoSizeUpward", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOHIDE, cfg::getByte("CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_SETRANGE, 0, MAKELONG(900, 1));
+ SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_SETPOS, 0, MAKELONG(cfg::getWord("CList", "HideTime", SETTING_HIDETIME_DEFAULT), 0));
+ Utils::enableDlgControl(hwndDlg, IDC_HIDETIME, IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ Utils::enableDlgControl(hwndDlg, IDC_HIDETIMESPIN, IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC01, IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ if (!IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE)) {
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC21, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC22, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_MAXSIZEHEIGHT, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_MAXSIZESPIN, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_AUTOSIZEUPWARD, FALSE);
+ } {
+ DBVARIANT dbv;
+ if (!cfg::getTString(NULL, "CList", "TitleText", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_TITLETEXT, dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ } else
+ SetDlgItemTextA(hwndDlg, IDC_TITLETEXT, MIRANDANAME);
+ }
+
+ if (!API::sysConfig.isWin2KPlus) {
+ Utils::enableDlgControl(hwndDlg, IDC_FADEINOUT, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_TRANSPARENT, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_DROPSHADOW, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_FULLTRANSPARENT, FALSE);
+ } else {
+ CheckDlgButton(hwndDlg, IDC_TRANSPARENT, cfg::dat.isTransparent ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_FULLTRANSPARENT, cfg::dat.bFullTransparent ? BST_CHECKED : BST_UNCHECKED);
+ }
+ if (!IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT)) {
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC11, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC12, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_TRANSACTIVE, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_TRANSINACTIVE, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_ACTIVEPERC, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_INACTIVEPERC, FALSE);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_SETRANGE, FALSE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_SETRANGE, FALSE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_SETPOS, TRUE, cfg::dat.alpha);
+ SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_SETPOS, TRUE, cfg::dat.autoalpha);
+ SendMessage(hwndDlg, WM_HSCROLL, 0x12345678, 0);
+
+ CheckDlgButton(hwndDlg, IDC_ROUNDEDBORDER, cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME);
+ SendDlgItemMessage(hwndDlg, IDC_FRAMEGAPSPIN, UDM_SETRANGE, 0, MAKELONG(10, 0));
+ SendDlgItemMessage(hwndDlg, IDC_FRAMEGAPSPIN, UDM_SETPOS, 0, (LPARAM)cfg::dat.gapBetweenFrames);
+
+ return TRUE;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_AUTOHIDE) {
+ Utils::enableDlgControl(hwndDlg, IDC_HIDETIME, IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ Utils::enableDlgControl(hwndDlg, IDC_HIDETIMESPIN, IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC01, IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ } else if (LOWORD(wParam) == IDC_TRANSPARENT) {
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC11, IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC12, IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ Utils::enableDlgControl(hwndDlg, IDC_TRANSACTIVE, IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ Utils::enableDlgControl(hwndDlg, IDC_TRANSINACTIVE, IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ Utils::enableDlgControl(hwndDlg, IDC_ACTIVEPERC, IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ Utils::enableDlgControl(hwndDlg, IDC_INACTIVEPERC, IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ } else if (LOWORD(wParam) == IDC_AUTOSIZE) {
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC21, IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ Utils::enableDlgControl(hwndDlg, IDC_STATIC22, IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ Utils::enableDlgControl(hwndDlg, IDC_MAXSIZEHEIGHT, IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ Utils::enableDlgControl(hwndDlg, IDC_MAXSIZESPIN, IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ Utils::enableDlgControl(hwndDlg, IDC_AUTOSIZEUPWARD, IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ }
+ if ((LOWORD(wParam) == IDC_FRAMEGAP || LOWORD(wParam) == IDC_HIDETIME || LOWORD(wParam) == IDC_CLIPBORDER || LOWORD(wParam) == IDC_ROWGAP || LOWORD(wParam) == IDC_TITLETEXT ||
+ LOWORD(wParam) == IDC_MAXSIZEHEIGHT || LOWORD(wParam) == IDC_CLEFT || LOWORD(wParam) == IDC_CRIGHT || LOWORD(wParam) == IDC_CTOP
+ || LOWORD(wParam) == IDC_CBOTTOM) && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ opt_clui_changed = 1;
+ break;
+
+ case WM_HSCROLL:
+ {
+ char str[10];
+ wsprintfA(str, "%d%%", 100 * SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_GETPOS, 0, 0) / 255);
+ SetDlgItemTextA(hwndDlg, IDC_INACTIVEPERC, str);
+ wsprintfA(str, "%d%%", 100 * SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_GETPOS, 0, 0) / 255);
+ SetDlgItemTextA(hwndDlg, IDC_ACTIVEPERC, str);
+ }
+ if (wParam != 0x12345678) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ opt_clui_changed = 1;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ BOOL translated;
+ BYTE oldFading;
+ BYTE windowStyle = (BYTE)SendDlgItemMessage(hwndDlg, IDC_BORDERSTYLE, CB_GETCURSEL, 0, 0);
+ COLORREF clr_cluiframes;
+
+ if(!opt_clui_changed)
+ return TRUE;
+
+ cfg::writeByte("CLUI", "FadeInOut", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FADEINOUT));
+ cfg::dat.fadeinout = IsDlgButtonChecked(hwndDlg, IDC_FADEINOUT) ? 1 : 0;
+ oldFading = cfg::dat.fadeinout;
+ cfg::dat.fadeinout = FALSE;
+
+ cfg::writeByte("CLUI", "WindowStyle", windowStyle);
+ cfg::dat.gapBetweenFrames = GetDlgItemInt(hwndDlg, IDC_FRAMEGAP, &translated, FALSE);
+
+ cfg::writeDword("CLUIFrames", "GapBetweenFrames", cfg::dat.gapBetweenFrames);
+ cfg::writeByte("CList", "OnTop", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONTOP));
+ SetWindowPos(pcli->hwndContactList, IsDlgButtonChecked(hwndDlg, IDC_ONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+
+ cfg::dat.bCLeft = (BYTE)SendDlgItemMessage(hwndDlg, IDC_CLEFTSPIN, UDM_GETPOS, 0, 0);
+ cfg::dat.bCRight = (BYTE)SendDlgItemMessage(hwndDlg, IDC_CRIGHTSPIN, UDM_GETPOS, 0, 0);
+ cfg::dat.bCTop = (BYTE)SendDlgItemMessage(hwndDlg, IDC_CTOPSPIN, UDM_GETPOS, 0, 0);
+ cfg::dat.bCBottom = (BYTE)SendDlgItemMessage(hwndDlg, IDC_CBOTTOMSPIN, UDM_GETPOS, 0, 0);
+
+ cfg::writeDword("CLUI", "clmargins", MAKELONG(MAKEWORD(cfg::dat.bCLeft, cfg::dat.bCRight), MAKEWORD(cfg::dat.bCTop, cfg::dat.bCBottom)));
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+
+ cfg::writeByte("CList", "BringToFront", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_BRINGTOFRONT));
+ cfg::writeByte("CList", "AlwaysHideOnTB", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_ALWAYSHIDEONTASKBAR));
+
+ if (windowStyle != SETTING_WINDOWSTYLE_DEFAULT) {
+ LONG style;
+ // Window must be hidden to dynamically remove the taskbar button.
+ // See http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_programming/taskbar.asp
+ WINDOWPLACEMENT p;
+ p.length = sizeof(p);
+ GetWindowPlacement(pcli->hwndContactList, &p);
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+
+ style = GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE);
+ style |= WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
+ style &= ~WS_EX_APPWINDOW;
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, style);
+
+ SetWindowPlacement(pcli->hwndContactList, &p);
+ ShowWindow(pcli->hwndContactList, SW_SHOW);
+ }
+ else
+ {
+ LONG style;
+ style = GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE);
+ style &= ~(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE);
+ if (cfg::getByte("CList", "AlwaysHideOnTB", 1))
+ style &= ~WS_EX_APPWINDOW;
+ else
+ {
+ style |= WS_EX_APPWINDOW;
+ AddToTaskBar(pcli->hwndContactList);
+ }
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, style);
+ }
+
+ cfg::dat.bClipBorder = (BYTE)GetDlgItemInt(hwndDlg, IDC_CLIPBORDER, &translated, FALSE);
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+ cfg::writeByte("CLUI", "clipborder", cfg::dat.bClipBorder);
+
+ cfg::writeByte("CLUI", "ShowMainMenu", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWMAINMENU));
+ cfg::writeByte("CLUI", "ClientAreaDrag", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CLIENTDRAG));
+
+ clr_cluiframes = (COLORREF)SendDlgItemMessage(hwndDlg, IDC_CLUIFRAMESBDR, CPM_GETCOLOUR, 0, 0);
+
+ if(g_hPenCLUIFrames)
+ DeleteObject(g_hPenCLUIFrames);
+ g_hPenCLUIFrames = CreatePen(PS_SOLID, 1, clr_cluiframes);
+ cfg::writeDword("CLUI", "clr_frameborder", clr_cluiframes);
+
+ ApplyCLUIBorderStyle(pcli->hwndContactList);
+
+ if (!IsDlgButtonChecked(hwndDlg, IDC_SHOWMAINMENU))
+ SetMenu(pcli->hwndContactList, NULL);
+ else
+ SetMenu(pcli->hwndContactList, pcli->hMenuMain);
+
+ {
+ TCHAR title[256];
+ GetDlgItemText(hwndDlg, IDC_TITLETEXT, title, SIZEOF(title));
+ cfg::writeTString(NULL, "CList", "TitleText", title);
+ SetWindowText(pcli->hwndContactList, title);
+ }
+ cfg::dat.dwFlags = IsDlgButtonChecked(hwndDlg, IDC_ROUNDEDBORDER) ? cfg::dat.dwFlags | CLUI_FRAME_ROUNDEDFRAME : cfg::dat.dwFlags & ~CLUI_FRAME_ROUNDEDFRAME;
+ cfg::writeByte("CLUI", "AutoSize", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+
+ if((cfg::dat.autosize = IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE) ? 1 : 0)) {
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0);
+ }
+
+ cfg::writeByte("CLUI", "MaxSizeHeight", (BYTE) GetDlgItemInt(hwndDlg, IDC_MAXSIZEHEIGHT, NULL, FALSE));
+ cfg::writeByte("CLUI", "AutoSizeUpward", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZEUPWARD));
+ cfg::writeByte("CList", "AutoHide", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ cfg::writeWord("CList", "HideTime", (WORD) SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_GETPOS, 0, 0));
+
+ cfg::writeByte("CList", "Transparent", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ cfg::dat.isTransparent = IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT) ? 1 : 0;
+ cfg::writeByte("CList", "Alpha", (BYTE) SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_GETPOS, 0, 0));
+ cfg::dat.alpha = (BYTE) SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_GETPOS, 0, 0);
+ cfg::writeByte("CList", "AutoAlpha", (BYTE) SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_GETPOS, 0, 0));
+ cfg::dat.autoalpha = (BYTE) SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_GETPOS, 0, 0);
+ cfg::writeByte("CList", "WindowShadow", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DROPSHADOW));
+ cfg::writeByte("CList", "OnDesktop", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONDESKTOP));
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+ cfg::dat.bFullTransparent = IsDlgButtonChecked(hwndDlg, IDC_FULLTRANSPARENT) ? 1 : 0;
+ cfg::writeByte("CLUI", "fulltransparent", (BYTE)cfg::dat.bFullTransparent);
+
+ if (cfg::dat.bLayeredHack)
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED);
+
+ if(g_CLUISkinnedBkColorRGB)
+ cfg::dat.colorkey = g_CLUISkinnedBkColorRGB;
+ else if(cfg::dat.bClipBorder == 0 && !(cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME))
+ cfg::dat.colorkey = cfg::getDword("CLC", "BkColour", CLCDEFAULT_BKCOLOUR);
+ else {
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ cfg::dat.colorkey = RGB(255, 0, 255);
+ }
+ if (cfg::dat.isTransparent || cfg::dat.bFullTransparent) {
+ if(API::sysConfig.isWin2KPlus) {
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED);
+ API::SetLayeredWindowAttributes(pcli->hwndContactList, 0, 255, LWA_ALPHA | LWA_COLORKEY);
+ API::SetLayeredWindowAttributes(pcli->hwndContactList,
+ (COLORREF)(cfg::dat.bFullTransparent ? cfg::dat.colorkey : 0),
+ (BYTE)(cfg::dat.isTransparent ? cfg::dat.autoalpha : 255),
+ (DWORD)((cfg::dat.isTransparent ? LWA_ALPHA : 0L) | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0L)));
+ }
+ } else {
+ API::SetLayeredWindowAttributes(pcli->hwndContactList, RGB(0, 0, 0), (BYTE)255, LWA_ALPHA);
+ if(!cfg::dat.bLayeredHack)
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+ }
+
+ ConfigureCLUIGeometry(1);
+ ShowWindow(pcli->hwndContactList, SW_SHOW);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ SetWindowPos(pcli->hwndContactList, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
+ cfg::dat.fadeinout = oldFading;
+ SFL_SetState(cfg::dat.bUseFloater & CLUI_FLOATER_AUTOHIDE ? (cfg::getByte("CList", "State", SETTING_STATE_NORMAL) == SETTING_STATE_NORMAL ? 0 : 1) : 1);
+ opt_clui_changed = 0;
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static int opt_sbar_changed = 0;
+
+INT_PTR CALLBACK DlgProcSBarOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ opt_sbar_changed = 0;
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_SHOWSBAR, cfg::getByte("CLUI", "ShowSBar", 1) ? BST_CHECKED : BST_UNCHECKED); {
+ BYTE showOpts = cfg::getByte("CLUI", "SBarShow", 1);
+ CheckDlgButton(hwndDlg, IDC_SHOWICON, showOpts & 1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWPROTO, showOpts & 2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUS, showOpts & 4 ? BST_CHECKED : BST_UNCHECKED);
+ }
+ CheckDlgButton(hwndDlg, IDC_RIGHTSTATUS, cfg::getByte("CLUI", "SBarRightClk", 0) ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hwndDlg, IDC_RIGHTMIRANDA, !IsDlgButtonChecked(hwndDlg, IDC_RIGHTSTATUS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_EQUALSECTIONS, cfg::dat.bEqualSections ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SBPANELBEVEL, cfg::getByte("CLUI", "SBarBevel", 1) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWGRIP, cfg::getByte("CLUI", "ShowGrip", 1) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SKINBACKGROUND, cfg::dat.bSkinnedStatusBar);
+ CheckDlgButton(hwndDlg, IDC_SHOWXSTATUS, cfg::dat.bShowXStatusOnSbar);
+ CheckDlgButton(hwndDlg, IDC_MARKLOCKED, cfg::getByte("CLUI", "sbar_showlocked", 1));
+
+ if (!IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR)) {
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWICON, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWPROTO, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWSTATUS, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_RIGHTSTATUS, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_RIGHTMIRANDA, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_EQUALSECTIONS, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_SBPANELBEVEL, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWGRIP, FALSE);
+ Utils::enableDlgControl(hwndDlg, IDC_SKINBACKGROUND, FALSE);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_SHOWSBAR) {
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWICON, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWPROTO, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWSTATUS, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_RIGHTSTATUS, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_RIGHTMIRANDA, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_EQUALSECTIONS, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_SBPANELBEVEL, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_SHOWGRIP, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ Utils::enableDlgControl(hwndDlg, IDC_SKINBACKGROUND, IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ opt_sbar_changed = 1;
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ if(!opt_sbar_changed)
+ return TRUE;
+
+ cfg::writeByte("CLUI", "ShowSBar", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ cfg::writeByte("CLUI", "SBarShow", (BYTE) ((IsDlgButtonChecked(hwndDlg, IDC_SHOWICON) ? 1 : 0) | (IsDlgButtonChecked(hwndDlg, IDC_SHOWPROTO) ? 2 : 0) | (IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUS) ? 4 : 0)));
+ cfg::writeByte("CLUI", "SBarRightClk", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RIGHTMIRANDA));
+ cfg::writeByte("CLUI", "EqualSections", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_EQUALSECTIONS));
+ cfg::writeByte("CLUI", "sb_skinned", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SKINBACKGROUND));
+ cfg::writeByte("CLUI", "sbar_showlocked", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MARKLOCKED));
+
+ cfg::dat.bEqualSections = IsDlgButtonChecked(hwndDlg, IDC_EQUALSECTIONS) ? 1 : 0;
+ cfg::dat.bSkinnedStatusBar = IsDlgButtonChecked(hwndDlg, IDC_SKINBACKGROUND) ? 1 : 0;
+ cfg::dat.bShowXStatusOnSbar = IsDlgButtonChecked(hwndDlg, IDC_SHOWXSTATUS) ? 1 : 0;
+ cfg::writeByte("CLUI", "xstatus_sbar", (BYTE)cfg::dat.bShowXStatusOnSbar);
+ cfg::writeByte("CLUI", "SBarBevel", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SBPANELBEVEL));
+ if (cfg::getByte("CLUI", "ShowGrip", 1) != (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWGRIP)) {
+ HWND parent = GetParent(pcli->hwndStatus);
+ int flags = WS_CHILD | CCS_BOTTOM;
+ cfg::writeByte("CLUI", "ShowGrip", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWGRIP));
+ ShowWindow(pcli->hwndStatus, SW_HIDE);
+ SetWindowLongPtr(pcli->hwndStatus, GWLP_WNDPROC, (LONG_PTR)OldStatusBarProc);
+ DestroyWindow(pcli->hwndStatus);
+ flags |= cfg::getByte("CLUI", "ShowSBar", 1) ? WS_VISIBLE : 0;
+ flags |= cfg::getByte("CLUI", "ShowGrip", 1) ? SBARS_SIZEGRIP : 0;
+ pcli->hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, flags, 0, 0, 0, 0, parent, NULL, g_hInst, NULL);
+ OldStatusBarProc = (WNDPROC)SetWindowLongPtr(pcli->hwndStatus, GWLP_WNDPROC, (LONG_PTR)NewStatusBarWndProc);
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR)) {
+ ShowWindow(pcli->hwndStatus, SW_SHOW);
+ SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0);
+ cfg::dat.dwFlags |= CLUI_FRAME_SBARSHOW;
+ } else {
+ ShowWindow(pcli->hwndStatus, SW_HIDE);
+ cfg::dat.dwFlags &= ~CLUI_FRAME_SBARSHOW;
+ }
+ cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags);
+ ConfigureCLUIGeometry(1);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ CluiProtocolStatusChanged(0, 0);
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ opt_sbar_changed = 0;
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+DWORD GetCLUIWindowStyle(BYTE style)
+{
+ DWORD dwBasic = WS_CLIPCHILDREN;
+
+ if(style == SETTING_WINDOWSTYLE_THINBORDER)
+ return dwBasic | WS_BORDER;
+ else if(style == SETTING_WINDOWSTYLE_TOOLWINDOW || style == 0)
+ return dwBasic | (WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_THICKFRAME);
+ else if(style == SETTING_WINDOWSTYLE_NOBORDER)
+ return dwBasic;
+
+ return dwBasic;
+}
+
+void ApplyCLUIBorderStyle(HWND hwnd)
+{
+ BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_TOOLWINDOW);
+ WINDOWPLACEMENT p;
+ bool minToTray = TRUE;
+
+ p.length = sizeof(p);
+ GetWindowPlacement(pcli->hwndContactList, &p);
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+
+ if (windowStyle == SETTING_WINDOWSTYLE_DEFAULT || windowStyle == SETTING_WINDOWSTYLE_TOOLWINDOW) {
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE, GetWindowLong(pcli->hwndContactList, GWL_STYLE) | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_THICKFRAME);
+ if(SETTING_WINDOWSTYLE_DEFAULT == windowStyle) {
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE, GetWindowLong(pcli->hwndContactList, GWL_STYLE) & ~(WS_MAXIMIZEBOX/* | WS_MINIMIZEBOX*/));
+ minToTray = FALSE;
+ }
+ } else if(windowStyle == SETTING_WINDOWSTYLE_THINBORDER) {
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE, GetWindowLong(pcli->hwndContactList, GWL_STYLE) & ~(WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_THICKFRAME));
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE, GetWindowLong(pcli->hwndContactList, GWL_STYLE) | WS_BORDER | WS_CLIPCHILDREN);
+ }
+ else {
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE, GetWindowLong(pcli->hwndContactList, GWL_STYLE) & ~(WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_THICKFRAME));
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE, GetWindowLong(pcli->hwndContactList, GWL_STYLE) | WS_CLIPCHILDREN);
+ }
+ p.showCmd = SW_HIDE;
+ SetWindowPlacement(pcli->hwndContactList, &p);
+
+ cfg::writeByte(0, "CList", "Min2Tray", minToTray);
+}
diff --git a/plugins/Clist_nicer/SRC/cluiservices.cpp b/plugins/Clist_nicer/SRC/cluiservices.cpp
new file mode 100644
index 0000000000..d2c5c4d9fa
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/cluiservices.cpp
@@ -0,0 +1,261 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+UNICODE done
+
+*/
+#include <commonheaders.h>
+#include "../cluiframes/cluiframes.h"
+#include <m_icq.h>
+
+extern HIMAGELIST hCListImages, himlExtraImages;;
+extern ButtonItem *g_ButtonItems;
+extern PLUGININFOEX pluginInfo;
+
+static INT_PTR GetClistVersion(WPARAM wParam, LPARAM lParam)
+{
+ static char g_szVersionString[256];
+
+ mir_snprintf(g_szVersionString, 256, "%s, %d.%d.%d.%d", pluginInfo.shortName, HIBYTE(HIWORD(pluginInfo.version)), LOBYTE(HIWORD(pluginInfo.version)), HIBYTE(LOWORD(pluginInfo.version)), LOBYTE(LOBYTE(pluginInfo.version)));
+ if(!IsBadWritePtr((LPVOID)lParam, 4))
+ *((DWORD *)lParam) = pluginInfo.version;
+
+ return (INT_PTR)g_szVersionString;
+}
+
+
+void FreeProtocolData( void )
+{
+ //free protocol data
+ int nPanel;
+ int nParts=SendMessage(pcli->hwndStatus,SB_GETPARTS,0,0);
+ for (nPanel=0;nPanel<nParts;nPanel++)
+ {
+ ProtocolData *PD;
+ PD=(ProtocolData *)SendMessage(pcli->hwndStatus,SB_GETTEXT,(WPARAM)nPanel,(LPARAM)0);
+ if (PD!=NULL&&!IsBadCodePtr((FARPROC)PD))
+ {
+ SendMessage(pcli->hwndStatus,SB_SETTEXT,(WPARAM)nPanel|SBT_OWNERDRAW,(LPARAM)0);
+ if (PD->RealName) mir_free(PD->RealName);
+ if (PD) mir_free(PD);
+} } }
+
+int g_maxStatus = ID_STATUS_OFFLINE;
+char g_maxProto[100] = "";
+
+void CluiProtocolStatusChanged( int parStatus, const char* szProto )
+{
+ int protoCount,i;
+ PROTOACCOUNT **accs;
+ int *partWidths,partCount;
+ int borders[3];
+ int status;
+ int toshow;
+ TCHAR *szStatus = NULL;
+ char *szMaxProto = NULL;
+ int maxOnline = 0, onlineness = 0;
+ WORD maxStatus = ID_STATUS_OFFLINE, wStatus;
+ DBVARIANT dbv = {0};
+ int iIcon = 0;
+ HICON hIcon = 0;
+ int rdelta = cfg::dat.bCLeft + cfg::dat.bCRight;
+ BYTE windowStyle;
+
+ if (pcli->hwndStatus == 0 || cfg::shutDown)
+ return;
+
+ ProtoEnumAccounts( &protoCount, &accs );
+ if (protoCount == 0)
+ return;
+
+ FreeProtocolData();
+ g_maxStatus = ID_STATUS_OFFLINE;
+ g_maxProto[0] = 0;
+
+ SendMessage(pcli->hwndStatus,SB_GETBORDERS,0,(LPARAM)&borders);
+
+ partWidths=(int*)_alloca(( protoCount+1)*sizeof(int));
+
+ if (cfg::dat.bEqualSections) {
+ RECT rc;
+ int part;
+ //SendMessage(pcli->hwndStatus,WM_SIZE,0,0); // XXX fix (may break status bar geometry)
+ GetClientRect(pcli->hwndStatus,&rc);
+ rc.right-=borders[0]*2;
+ toshow=0;
+ for ( i=0; i < protoCount; i++ )
+ if ( pcli->pfnGetProtocolVisibility( accs[i]->szModuleName ))
+ toshow++;
+
+ if ( toshow > 0 ) {
+ for ( part=0, i=0; i < protoCount; i++ ) {
+ if ( !pcli->pfnGetProtocolVisibility( accs[i]->szModuleName ))
+ continue;
+
+ partWidths[ part ] = ((rc.right-rc.left-rdelta)/toshow)*(part+1) + cfg::dat.bCLeft;
+ if ( part == toshow-1 )
+ partWidths[ part ] += cfg::dat.bCRight;
+ part++;
+ } }
+
+ partCount=toshow;
+ }
+ else {
+ HDC hdc;
+ SIZE textSize;
+ BYTE showOpts = cfg::getByte("CLUI","SBarShow",1);
+ int x;
+ HFONT hofont;
+ TCHAR szName[32];
+ PROTOACCOUNT* pa;
+
+ hdc=GetDC(NULL);
+ hofont = reinterpret_cast<HFONT>(SelectObject(hdc,(HFONT)SendMessage(pcli->hwndStatus,WM_GETFONT,0,0)));
+
+ for ( partCount=0,i=0; i < protoCount; i++ ) { //count down since built in ones tend to go at the end
+ int idx = pcli->pfnGetAccountIndexByPos( i );
+ if ( idx == -1 )
+ continue;
+
+ pa = accs[idx];
+ if ( !pcli->pfnGetProtocolVisibility( pa->szModuleName ))
+ continue;
+
+ x=2;
+ if (showOpts & 1)
+ x += 16;
+ if (showOpts & 2) {
+ lstrcpyn( szName, pa->tszAccountName, SIZEOF(szName));
+ szName[ SIZEOF(szName)-1 ] = 0;
+ if (( showOpts & 4 ) && lstrlen(szName) < sizeof(szName)-1 )
+ lstrcat( szName, _T(" "));
+ GetTextExtentPoint32( hdc, szName, lstrlen(szName), &textSize );
+ x += textSize.cx + GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room
+ }
+ if (showOpts & 4) {
+ TCHAR* modeDescr = pcli->pfnGetStatusModeDescription( CallProtoService(accs[i]->szModuleName,PS_GETSTATUS,0,0 ), 0 );
+ GetTextExtentPoint32(hdc, modeDescr, lstrlen(modeDescr), &textSize );
+ x += textSize.cx + GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room
+ }
+ partWidths[partCount]=(partCount?partWidths[partCount-1]:cfg::dat.bCLeft)+ x + 2;
+ partCount++;
+ }
+ SelectObject(hdc,hofont);
+ ReleaseDC(NULL,hdc);
+ }
+ if (partCount==0) {
+ SendMessage(pcli->hwndStatus,SB_SIMPLE,TRUE,0);
+ return;
+ }
+ SendMessage(pcli->hwndStatus,SB_SIMPLE,FALSE,0);
+
+ partWidths[partCount-1]=-1;
+ windowStyle = cfg::getByte("CLUI", "WindowStyle", 0);
+ SendMessage(pcli->hwndStatus,SB_SETMINHEIGHT, 18 + cfg::dat.bClipBorder + ((windowStyle == SETTING_WINDOWSTYLE_THINBORDER || windowStyle == SETTING_WINDOWSTYLE_NOBORDER) ? 3 : 0), 0);
+ SendMessage(pcli->hwndStatus, SB_SETPARTS, partCount, (LPARAM)partWidths);
+
+ for ( partCount=0, i=0; i < protoCount; i++ ) { //count down since built in ones tend to go at the end
+ ProtocolData *PD;
+ PROTOACCOUNT *pa;
+ int caps1, caps2;
+
+ int idx = pcli->pfnGetAccountIndexByPos( i );
+ if ( idx == -1 )
+ continue;
+
+ pa = accs[idx];
+ if ( !pcli->pfnGetProtocolVisibility( pa->szModuleName ))
+ continue;
+
+ status = CallProtoService( pa->szModuleName,PS_GETSTATUS,0,0);
+ PD = ( ProtocolData* )mir_alloc(sizeof(ProtocolData));
+ PD->RealName = mir_strdup( pa->szModuleName );
+ PD->statusbarpos = partCount;
+ {
+ int flags;
+ flags = SBT_OWNERDRAW;
+ if ( cfg::getByte("CLUI","SBarBevel", 1)==0 )
+ flags |= SBT_NOBORDERS;
+ SendMessageA( pcli->hwndStatus, SB_SETTEXTA, partCount|flags,(LPARAM)PD );
+ }
+ caps2 = CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0);
+ caps1 = CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0);
+ if((caps1 & PF1_IM) && (caps2 & (PF2_LONGAWAY | PF2_SHORTAWAY))) {
+ onlineness = GetStatusOnlineness(status);
+ if(onlineness > maxOnline) {
+ maxStatus = status;
+ maxOnline = onlineness;
+ szMaxProto = pa->szModuleName;
+ }
+ }
+ partCount++;
+ }
+ // update the clui button
+
+ if (!DBGetContactSetting(NULL, "CList", "PrimaryStatus", &dbv)) {
+ if (dbv.type == DBVT_ASCIIZ && lstrlenA(dbv.pszVal) > 1) {
+ wStatus = (WORD) CallProtoService(dbv.pszVal, PS_GETSTATUS, 0, 0);
+ iIcon = IconFromStatusMode(dbv.pszVal, (int) wStatus, 0, &hIcon);
+ }
+ mir_free(dbv.pszVal);
+ } else {
+ wStatus = maxStatus;
+ iIcon = IconFromStatusMode((wStatus >= ID_STATUS_CONNECTING && wStatus < ID_STATUS_OFFLINE) ? szMaxProto : NULL, (int) wStatus, 0, &hIcon);
+ g_maxStatus = (int)wStatus;
+ if(szMaxProto) {
+ lstrcpynA(g_maxProto, szMaxProto, 100);
+ g_maxProto[99] = 0;
+ }
+ }
+ /*
+ * this is used globally (actually, by the clist control only) to determine if
+ * any protocol is "in connection" state. If true, then the clist discards redraws
+ * and uses timer based sort and redraw handling. This can improve performance
+ * when connecting multiple protocols significantly.
+ */
+ //g_isConnecting = (wStatus >= ID_STATUS_CONNECTING && wStatus < ID_STATUS_OFFLINE);
+ szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM) wStatus, GSMDF_TCHAR);
+
+ /*
+ * set the global status icon and display the global (most online) status mode on the
+ * status mode button
+ */
+
+ if (szStatus) {
+ if(pcli->hwndContactList && IsWindow(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS)) && IsWindow(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS))) {
+ SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), WM_SETTEXT, 0, (LPARAM) szStatus);
+ if(!hIcon) {
+ SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), BM_SETIMLICON, (WPARAM) hCListImages, (LPARAM) iIcon);
+ if(g_ButtonItems == NULL)
+ SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS), BM_SETIMLICON, (WPARAM) hCListImages, (LPARAM) iIcon);
+ }
+ else {
+ SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
+ if(g_ButtonItems == NULL)
+ SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS), BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
+ }
+ InvalidateRect(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), NULL, TRUE);
+ InvalidateRect(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS), NULL, TRUE);
+ SFL_Update(hIcon, iIcon, hCListImages, szStatus, TRUE);
+ } }
+ return;
+}
diff --git a/plugins/Clist_nicer/SRC/commonheaders.cpp b/plugins/Clist_nicer/SRC/commonheaders.cpp
new file mode 100644
index 0000000000..b317365c87
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/commonheaders.cpp
@@ -0,0 +1 @@
+#include <commonheaders.h> \ No newline at end of file
diff --git a/plugins/Clist_nicer/SRC/config.cpp b/plugins/Clist_nicer/SRC/config.cpp
new file mode 100644
index 0000000000..04315a162a
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/config.cpp
@@ -0,0 +1,482 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: config.cpp 12887 2010-10-04 03:58:32Z borkra $
+ *
+ */
+
+#include <commonheaders.h>
+
+TCluiData cfg::dat = {0};
+ClcData* cfg::clcdat = 0;
+TExtraCache* cfg::eCache = 0;
+int cfg::nextCacheEntry = 0, cfg::maxCacheEntry = 0;
+
+CRITICAL_SECTION cfg::cachecs = {0};
+
+bool cfg::shutDown = false;
+
+pfnSetLayeredWindowAttributes_t API::pfnSetLayeredWindowAttributes = 0;
+pfnUpdateLayeredWindow_t API::pfnUpdateLayeredWindow = 0;
+pfnMonitorFromPoint_t API::pfnMonitorFromPoint = 0;
+pfnMonitorFromWindow_t API::pfnMonitorFromWindow = 0;
+pfnGetMonitorInfo_t API::pfnGetMonitorInfo = 0;
+pfnTrackMouseEvent_t API::pfnTrackMouseEvent = 0;
+//pfnDrawAlpha_t API::pfnDrawAlpha = 0;
+PGF API::pfnGradientFill = 0;
+pfnSetLayout_t API::pfnSetLayout = 0;
+pfnAlphaBlend_t API::pfnAlphaBlend = 0;
+
+TSysConfig API::sysConfig = {0};
+TSysState API::sysState = {0};
+
+pfnIsThemeActive_t API::pfnIsThemeActive = 0;
+pfnOpenThemeData_t API::pfnOpenThemeData = 0;
+pfnDrawThemeBackground_t API::pfnDrawThemeBackground = 0;
+pfnCloseThemeData_t API::pfnCloseThemeData = 0;
+pfnDrawThemeText_t API::pfnDrawThemeText = 0;
+pfnDrawThemeTextEx_t API::pfnDrawThemeTextEx = 0;
+pfnIsThemeBackgroundPartiallyTransparent_t API::pfnIsThemeBackgroundPartiallyTransparent = 0;
+pfnDrawThemeParentBackground_t API::pfnDrawThemeParentBackground = 0;
+pfnGetThemeBackgroundContentRect_t API::pfnGetThemeBackgroundContentRect = 0;
+pfnEnableThemeDialogTexture_t API::pfnEnableThemeDialogTexture = 0;
+
+pfnDwmExtendFrameIntoClientArea_t API::pfnDwmExtendFrameIntoClientArea = 0;
+pfnDwmIsCompositionEnabled_t API::pfnDwmIsCompositionEnabled = 0;
+
+EXCEPTION_RECORD API::exRecord = {0};
+CONTEXT API::exCtx = {0};
+LRESULT API::exLastResult = 0;
+char API::exSzFile[MAX_PATH] = "";
+TCHAR API::exReason[256] = _T("");
+int API::exLine = 0;
+bool API::exAllowContinue = false;
+HMODULE API::hUxTheme = 0, API::hDwm = 0;
+
+void cfg::init()
+{
+ InitializeCriticalSection(&cachecs);
+}
+
+DWORD cfg::getDword(const HANDLE hContact = 0, const char *szModule = 0, const char *szSetting = 0, DWORD uDefault = 0)
+{
+ return((DWORD)DBGetContactSettingDword(hContact, szModule, szSetting, uDefault));
+}
+
+/*
+ * read a setting from our default module (Tab_SRMSG)
+ */
+
+DWORD cfg::getDword(const char *szSetting = 0, DWORD uDefault = 0)
+{
+ return((DWORD)DBGetContactSettingDword(0, DEFAULT_MODULE, szSetting, uDefault));
+}
+
+/*
+ * read a setting from module only
+ */
+
+DWORD cfg::getDword(const char *szModule, const char *szSetting, DWORD uDefault)
+{
+ return((DWORD)DBGetContactSettingDword(0, szModule, szSetting, uDefault));
+}
+
+
+WORD cfg::getWord(const HANDLE hContact = 0, const char *szModule = 0, const char *szSetting = 0, WORD uDefault = 0)
+{
+ return((WORD)DBGetContactSettingWord(hContact, szModule, szSetting, uDefault));
+}
+
+/*
+ * read a setting from our default module (Tab_SRMSG)
+ */
+
+WORD cfg::getWord(const char *szSetting = 0, WORD uDefault = 0)
+{
+ return((WORD)DBGetContactSettingWord(0, DEFAULT_MODULE, szSetting, uDefault));
+}
+
+/*
+ * read a setting from module only
+ */
+
+WORD cfg::getWord(const char *szModule, const char *szSetting, WORD uDefault)
+{
+ return((WORD)DBGetContactSettingWord(0, szModule, szSetting, uDefault));
+}
+
+/*
+ * same for bytes now
+ */
+int cfg::getByte(const HANDLE hContact = 0, const char *szModule = 0, const char *szSetting = 0, int uDefault = 0)
+{
+ return(DBGetContactSettingByte(hContact, szModule, szSetting, uDefault));
+}
+
+int cfg::getByte(const char *szSetting = 0, int uDefault = 0)
+{
+ return(DBGetContactSettingByte(0, DEFAULT_MODULE, szSetting, uDefault));
+}
+
+int cfg::getByte(const char *szModule, const char *szSetting, int uDefault)
+{
+ return(DBGetContactSettingByte(0, szModule, szSetting, uDefault));
+}
+
+INT_PTR cfg::getTString(const HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv)
+{
+ return(DBGetContactSettingTString(hContact, szModule, szSetting, dbv));
+}
+
+INT_PTR cfg::getString(const HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv)
+{
+ return(DBGetContactSettingString(hContact, szModule, szSetting, dbv));
+}
+
+/*
+ * writer functions
+ */
+
+INT_PTR cfg::writeDword(const HANDLE hContact = 0, const char *szModule = 0, const char *szSetting = 0, DWORD value = 0)
+{
+ return(DBWriteContactSettingDword(hContact, szModule, szSetting, value));
+}
+
+INT_PTR cfg::writeDword(const char *szModule = 0, const char *szSetting = 0, DWORD value = 0)
+{
+ return(DBWriteContactSettingDword(0, szModule, szSetting, value));
+}
+
+INT_PTR cfg::writeWord(const HANDLE hContact = 0, const char *szModule = 0, const char *szSetting = 0, WORD value = 0)
+{
+ return(DBWriteContactSettingWord(hContact, szModule, szSetting, value));
+}
+
+INT_PTR cfg::writeWord(const char *szModule = 0, const char *szSetting = 0, WORD value = 0)
+{
+ return(DBWriteContactSettingWord(0, szModule, szSetting, value));
+}
+
+INT_PTR cfg::writeByte(const HANDLE hContact = 0, const char *szModule = 0, const char *szSetting = 0, BYTE value = 0)
+{
+ return(DBWriteContactSettingByte(hContact, szModule, szSetting, value));
+}
+
+INT_PTR cfg::writeByte(const char *szModule = 0, const char *szSetting = 0, BYTE value = 0)
+{
+ return(DBWriteContactSettingByte(0, szModule, szSetting, value));
+}
+
+INT_PTR cfg::writeTString(const HANDLE hContact, const char *szModule = 0, const char *szSetting = 0, const TCHAR *str = 0)
+{
+ return(DBWriteContactSettingTString(hContact, szModule, szSetting, str));
+}
+
+INT_PTR cfg::writeString(const HANDLE hContact, const char *szModule = 0, const char *szSetting = 0, const char *str = 0)
+{
+ return(DBWriteContactSettingString(hContact, szModule, szSetting, str));
+}
+
+int cfg::getCache(const HANDLE hContact, const char *szProto)
+{
+ int i, iFound = -1;
+
+ for(i = 0; i < nextCacheEntry; i++) {
+ if(eCache[i].hContact == hContact) {
+ iFound = i;
+ break;
+ }
+ }
+ if(iFound == -1) {
+ EnterCriticalSection(&cachecs);
+ if(nextCacheEntry == maxCacheEntry) {
+ maxCacheEntry += 100;
+ cfg::eCache = (TExtraCache *)realloc(cfg::eCache, maxCacheEntry * sizeof(TExtraCache));
+ }
+ memset(&cfg::eCache[nextCacheEntry], 0, sizeof(TExtraCache));
+ cfg::eCache[nextCacheEntry].hContact = hContact;
+ memset(cfg::eCache[nextCacheEntry].iExtraImage, 0xff, MAXEXTRACOLUMNS);
+ cfg::eCache[nextCacheEntry].iExtraValid = 0;
+ cfg::eCache[nextCacheEntry].valid = FALSE;
+ cfg::eCache[nextCacheEntry].bStatusMsgValid = 0;
+ cfg::eCache[nextCacheEntry].statusMsg = NULL;
+ cfg::eCache[nextCacheEntry].status_item = NULL;
+ LoadSkinItemToCache(&cfg::eCache[nextCacheEntry], szProto);
+ cfg::eCache[nextCacheEntry].dwCFlags = 0;
+ cfg::eCache[nextCacheEntry].dwDFlags = DBGetContactSettingDword(hContact, "CList", "CLN_Flags", 0);
+ cfg::eCache[nextCacheEntry].dwXMask = CalcXMask(hContact);
+ GetCachedStatusMsg(nextCacheEntry, const_cast<char *>(szProto));
+ cfg::eCache[nextCacheEntry].dwLastMsgTime = INTSORT_GetLastMsgTime(hContact);
+ iFound = nextCacheEntry++;
+ LeaveCriticalSection(&cachecs);
+ }
+ return iFound;
+}
+
+void API::onInit()
+{
+ HMODULE hUserDll = 0;
+
+ pfnSetLayout = (DWORD ( WINAPI *)(HDC, DWORD))GetProcAddress( GetModuleHandleA( "GDI32.DLL" ), "SetLayout" );
+
+ hUserDll = GetModuleHandleA("user32.dll");
+ if (hUserDll) {
+ pfnMonitorFromPoint = ( pfnMonitorFromPoint_t )GetProcAddress(hUserDll, "MonitorFromPoint");
+ pfnMonitorFromWindow = ( pfnMonitorFromWindow_t )GetProcAddress(hUserDll, "MonitorFromWindow");
+ pfnGetMonitorInfo = ( pfnGetMonitorInfo_t )GetProcAddress(hUserDll, "GetMonitorInfoA");
+ pfnSetLayeredWindowAttributes = ( pfnSetLayeredWindowAttributes_t )GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
+ pfnUpdateLayeredWindow = ( pfnUpdateLayeredWindow_t )GetProcAddress(hUserDll, "UpdateLayeredWindow");
+ pfnTrackMouseEvent = ( pfnTrackMouseEvent_t )GetProcAddress(hUserDll, "TrackMouseEvent");
+ }
+
+ pfnAlphaBlend = (pfnAlphaBlend_t) GetProcAddress(GetModuleHandleA("gdi32"), "GdiAlphaBlend");
+ pfnGradientFill = (PGF) GetProcAddress(GetModuleHandleA("gdi32"), "GdiGradientFill");
+ if (0 == pfnAlphaBlend) {
+ HMODULE hMsImgDll = LoadLibraryA("msimg32.dll");
+ pfnAlphaBlend = (pfnAlphaBlend_t)GetProcAddress(hMsImgDll, "AlphaBlend");
+ pfnGradientFill = (PGF) GetProcAddress(hMsImgDll, "GradientFill");
+ }
+
+ sysConfig.isVistaPlus = (IsWinVerVistaPlus() ? true : false);
+ sysConfig.isSevenPlus = (IsWinVer7Plus() ? true : false);
+ sysConfig.isXPPlus = (IsWinVerXPPlus() ? true : false);
+ sysConfig.isWin2KPlus = (IsWinVer2000Plus() ? true : false);
+
+ if(sysConfig.isXPPlus) {
+ if ((hUxTheme = Utils::loadSystemLibrary(_T("\\uxtheme.dll")), true) != 0) {
+ pfnIsThemeActive = (pfnIsThemeActive_t)GetProcAddress(hUxTheme, "IsThemeActive");
+ pfnOpenThemeData = (pfnOpenThemeData_t)GetProcAddress(hUxTheme, "OpenThemeData");
+ pfnDrawThemeBackground = (pfnDrawThemeBackground_t)GetProcAddress(hUxTheme, "DrawThemeBackground");
+ pfnCloseThemeData = (pfnCloseThemeData_t)GetProcAddress(hUxTheme, "CloseThemeData");
+ pfnDrawThemeText = (pfnDrawThemeText_t)GetProcAddress(hUxTheme, "DrawThemeText");
+ pfnIsThemeBackgroundPartiallyTransparent = (pfnIsThemeBackgroundPartiallyTransparent_t)GetProcAddress(hUxTheme, "IsThemeBackgroundPartiallyTransparent");
+ pfnDrawThemeParentBackground = (pfnDrawThemeParentBackground_t)GetProcAddress(hUxTheme, "DrawThemeParentBackground");
+ pfnGetThemeBackgroundContentRect = (pfnGetThemeBackgroundContentRect_t)GetProcAddress(hUxTheme, "GetThemeBackgroundContentRect");
+ pfnEnableThemeDialogTexture = (pfnEnableThemeDialogTexture_t)GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+
+ if (pfnIsThemeActive != 0 && pfnOpenThemeData != 0 && pfnDrawThemeBackground != 0 && pfnCloseThemeData != 0
+ && pfnDrawThemeText != 0 && pfnIsThemeBackgroundPartiallyTransparent != 0 && pfnDrawThemeParentBackground != 0
+ && pfnGetThemeBackgroundContentRect != 0) {
+ sysConfig.uxThemeValid = true;
+ }
+ }
+ }
+ if(sysConfig.isVistaPlus) {
+ if ((hDwm = Utils::loadSystemLibrary(_T("\\dwmapi.dll")), true) != 0) {
+ pfnDwmIsCompositionEnabled = (pfnDwmIsCompositionEnabled_t)GetProcAddress(hDwm, "DwmIsCompositionEnabled");
+ pfnDwmExtendFrameIntoClientArea = (pfnDwmExtendFrameIntoClientArea_t)GetProcAddress(hDwm,"DwmExtendFrameIntoClientArea");
+ }
+ }
+
+ updateState();
+}
+
+void API::onUnload()
+{
+ if(hUxTheme)
+ FreeLibrary(hUxTheme);
+}
+
+/**
+ * update system's state (theme status, aero status, DWM check...
+ *
+ * called when windows broadcasts things like WM_THEMECHANGED or
+ * WM_DWMCOMPOSITIONCHANGED
+ */
+void API::updateState()
+{
+ BOOL result = FALSE;
+
+ ::ZeroMemory(&sysState, sizeof(TSysState));
+
+ if(sysConfig.uxThemeValid)
+ sysState.isThemed = pfnIsThemeActive() ? true : false;
+
+ if(sysConfig.isVistaPlus) {
+ sysState.isDwmActive = (pfnDwmIsCompositionEnabled && (pfnDwmIsCompositionEnabled(&result) == S_OK) && result) ? true : false;
+ sysState.isAero = /* (CSkin::m_skinEnabled == false) && */ cfg::getByte("CLUI", "useAero", 1) /* && CSkin::m_fAeroSkinsValid */ && sysState.isDwmActive;
+ }
+}
+
+BOOL API::SetLayeredWindowAttributes(HWND hWnd, COLORREF clr, BYTE alpha, DWORD dwFlags)
+{
+ if(sysConfig.isWin2KPlus)
+ return(pfnSetLayeredWindowAttributes(hWnd, clr, alpha, dwFlags));
+
+ return(FALSE);
+}
+
+/**
+ * exception handling for SEH exceptions
+ */
+
+/**
+ * exception handling - copy error message to clip board
+ * @param hWnd: window handle of the edit control containing the error message
+ */
+void API::Ex_CopyEditToClipboard(HWND hWnd)
+{
+ SendMessage(hWnd, EM_SETSEL, 0, 65535L);
+ SendMessage(hWnd, WM_COPY, 0 , 0);
+ SendMessage(hWnd, EM_SETSEL, 0, 0);
+}
+
+INT_PTR CALLBACK API::Ex_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ WORD wNotifyCode, wID;
+
+ switch(uMsg) {
+ case WM_INITDIALOG: {
+ char szBuffer[2048];
+#ifdef _WIN64
+ sprintf(szBuffer,
+ "Exception %16.16X at address %16.16X occured in %s at line %d.\r\n\r\nEAX=%16.16X EBX=%16.16X ECX=%16.16X\r\nEDX=%16.16X ESI=%16.16X EDI=%16.16X\r\nEBP=%16.16X ESP=%16.16X EIP=%16.16X",
+ exRecord.ExceptionCode, exRecord.ExceptionAddress, exSzFile, exLine,
+ exCtx.Rax,exCtx.Rbx, exCtx.Rcx, exCtx.Rdx,
+ exCtx.Rsi, exCtx.Rdi, exCtx.Rbp, exCtx.Rsp, exCtx.Rip);
+#else
+ sprintf(szBuffer,
+ "Exception %8.8X at address %8.8X occured in %s at line %d.\r\n\r\nEAX=%8.8X EBX=%8.8X ECX=%8.8X\r\nEDX=%8.8X ESI=%8.8X EDI=%8.8X\r\nEBP=%8.8X ESP=%8.8X EIP=%8.8X",
+ exRecord.ExceptionCode, exRecord.ExceptionAddress, exSzFile, exLine,
+ exCtx.Eax,exCtx.Ebx, exCtx.Ecx, exCtx.Edx,
+ exCtx.Esi, exCtx.Edi, exCtx.Ebp, exCtx.Esp, exCtx.Eip);
+#endif
+ SetDlgItemTextA(hwndDlg, IDC_EXCEPTION_DETAILS, szBuffer);
+ SetFocus(GetDlgItem(hwndDlg, IDC_EXCEPTION_DETAILS));
+ SendDlgItemMessage(hwndDlg, IDC_EXCEPTION_DETAILS, WM_SETFONT, (WPARAM)GetStockObject(OEM_FIXED_FONT), 0);
+ SetDlgItemText(hwndDlg, IDC_EX_REASON, exReason);
+ Utils::enableDlgControl(hwndDlg, IDOK, exAllowContinue ? TRUE : FALSE);
+ }
+ break;
+
+ case WM_COMMAND:
+ wNotifyCode = HIWORD(wParam);
+ wID = LOWORD(wParam);
+ if (wNotifyCode == BN_CLICKED)
+ {
+ if (wID == IDOK || wID == IDCANCEL)
+ EndDialog(hwndDlg, wID);
+
+ if (wID == IDC_COPY_EXCEPTION)
+ Ex_CopyEditToClipboard(GetDlgItem(hwndDlg, IDC_EXCEPTION_DETAILS));
+ }
+
+ break;
+ }
+ return FALSE;
+}
+
+void API::Ex_Handler()
+{
+ if (exLastResult == IDCANCEL)
+ ExitProcess(1);
+}
+
+int API::Ex_ShowDialog(EXCEPTION_POINTERS *ep, const char *szFile, int line, TCHAR* szReason, bool fAllowContinue)
+{
+ char szDrive[MAX_PATH], szDir[MAX_PATH], szName[MAX_PATH], szExt[MAX_PATH];
+
+ _splitpath(szFile, szDrive, szDir, szName, szExt);
+ memcpy(&exRecord, ep->ExceptionRecord, sizeof(EXCEPTION_RECORD));
+ memcpy(&exCtx, ep->ContextRecord, sizeof(CONTEXT));
+
+ _snprintf(exSzFile, MAX_PATH, "%s%s", szName, szExt);
+ mir_sntprintf(exReason, 256, _T("An application error has occured: %s"), szReason);
+ exLine = line;
+ exLastResult = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_EXCEPTION), 0, Ex_DlgProc, 0);
+ exAllowContinue = fAllowContinue;
+ if(IDCANCEL == exLastResult)
+ ExitProcess(1);
+ return 1;
+}
+
+
+/**
+ * enable or disable a dialog control
+ */
+void TSAPI Utils::enableDlgControl(const HWND hwnd, UINT id, BOOL fEnable)
+{
+ ::EnableWindow(::GetDlgItem(hwnd, id), fEnable);
+}
+
+/**
+ * show or hide a dialog control
+ */
+void TSAPI Utils::showDlgControl(const HWND hwnd, UINT id, int showCmd)
+{
+ ::ShowWindow(::GetDlgItem(hwnd, id), showCmd);
+}
+
+/**
+ * load a system library from the Windows system path and return its module
+ * handle.
+ *
+ * return 0 and throw an exception if something goes wrong.
+ */
+HMODULE Utils::loadSystemLibrary(const TCHAR* szFilename, bool useGetHandle)
+{
+ TCHAR sysPathName[MAX_PATH + 2];
+ HMODULE _h = 0;
+
+ try {
+ if(0 == ::GetSystemDirectory(sysPathName, MAX_PATH))
+ throw(CRTException("Error while loading system library", szFilename));
+
+ sysPathName[MAX_PATH - 1] = 0;
+ if(_tcslen(sysPathName) + _tcslen(szFilename) >= MAX_PATH)
+ throw(CRTException("Error while loading system library", szFilename));
+
+ lstrcat(sysPathName, szFilename);
+ if(useGetHandle)
+ _h = ::GetModuleHandle(sysPathName);
+ else
+ _h = LoadLibrary(sysPathName);
+ if(0 == _h)
+ throw(CRTException("Error while loading system library", szFilename));
+ }
+ catch(CRTException& ex) {
+ ex.display();
+ return(0);
+ }
+ return(_h);
+}
+
+CRTException::CRTException(const char *szMsg, const TCHAR *szParam) : std::runtime_error(std::string(szMsg))
+{
+ mir_sntprintf(m_szParam, MAX_PATH, szParam);
+}
+
+void CRTException::display() const
+{
+ TCHAR* tszMsg = mir_a2t(what());
+ TCHAR tszBoxMsg[500];
+
+ mir_sntprintf(tszBoxMsg, 500, _T("%s\n\n(%s)"), tszMsg, m_szParam);
+ ::MessageBox(0, tszBoxMsg, _T("TabSRMM runtime error"), MB_OK | MB_ICONERROR);
+ mir_free(tszMsg);
+}
diff --git a/plugins/Clist_nicer/SRC/contact.cpp b/plugins/Clist_nicer/SRC/contact.cpp
new file mode 100644
index 0000000000..34f15b3fb9
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/contact.cpp
@@ -0,0 +1,334 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: contact.cpp 12535 2010-08-29 23:48:32Z silvercircle $
+ *
+ */
+
+#include <commonheaders.h>
+
+struct {
+ int status,order;
+} statusModeOrder[]={
+ {ID_STATUS_OFFLINE,500},
+ {ID_STATUS_ONLINE,10},
+ {ID_STATUS_AWAY,200},
+ {ID_STATUS_DND,110},
+ {ID_STATUS_NA,450},
+ {ID_STATUS_OCCUPIED,100},
+ {ID_STATUS_FREECHAT,0},
+ {ID_STATUS_INVISIBLE,20},
+ {ID_STATUS_ONTHEPHONE,150},
+ {ID_STATUS_OUTTOLUNCH,425}
+};
+
+static int GetContactStatus(HANDLE hContact)
+{
+ char *szProto;
+
+ szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto == NULL)
+ return ID_STATUS_OFFLINE;
+ return cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+}
+
+int __forceinline GetStatusModeOrdering(int statusMode)
+{
+ int i;
+ for (i = 0; i < sizeof(statusModeOrder) / sizeof(statusModeOrder[0]); i++) {
+ if (statusModeOrder[i].status == statusMode)
+ return statusModeOrder[i].order;
+ }
+ return 1000;
+}
+
+int mf_updatethread_running = TRUE;
+HANDLE hThreadMFUpdate = 0;
+
+static void MF_CalcFrequency(HANDLE hContact, DWORD dwCutoffDays, int doSleep)
+{
+ DWORD curTime = time(NULL);
+ DWORD frequency, eventCount;
+ DBEVENTINFO dbei = {0};
+ HANDLE hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ DWORD firstEventTime = 0, lastEventTime = 0;
+
+ eventCount = 0;
+ dbei.cbSize = sizeof(dbei);
+ dbei.timestamp = 0;
+
+ while(hEvent) {
+ dbei.cbBlob = 0;
+ dbei.pBlob = NULL;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbei);
+
+ if(dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) { // record time of last event
+ eventCount++;
+ }
+ if(eventCount >= 100 || dbei.timestamp < curTime - (dwCutoffDays * 86400))
+ break;
+ hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEvent, 0);
+ if(doSleep && mf_updatethread_running == FALSE)
+ return;
+ if(doSleep)
+ Sleep(100);
+ }
+
+ if(eventCount == 0) {
+ frequency = 0x7fffffff;
+ cfg::writeDword(hContact, "CList", "mf_firstEvent", curTime - (dwCutoffDays * 86400));
+ }
+ else {
+ frequency = (curTime - dbei.timestamp) / eventCount;
+ cfg::writeDword(hContact, "CList", "mf_firstEvent", dbei.timestamp);
+ }
+
+ cfg::writeDword(hContact, "CList", "mf_freq", frequency);
+ cfg::writeDword(hContact, "CList", "mf_count", eventCount);
+}
+
+extern TCHAR g_ptszEventName[];
+
+DWORD WINAPI MF_UpdateThread(LPVOID p)
+{
+ HANDLE hContact;
+ HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, g_ptszEventName);
+
+ WaitForSingleObject(hEvent, 20000);
+ ResetEvent(hEvent);
+
+ while(mf_updatethread_running) {
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact != NULL && mf_updatethread_running) {
+ MF_CalcFrequency(hContact, 50, 1);
+ if(mf_updatethread_running)
+ WaitForSingleObject(hEvent, 5000);
+ ResetEvent(hEvent);
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ if(mf_updatethread_running)
+ WaitForSingleObject(hEvent, 1000000);
+ ResetEvent(hEvent);
+ }
+ CloseHandle(hEvent);
+ return 0;
+}
+
+static BOOL mc_hgh_removed = FALSE;
+
+void LoadContactTree(void)
+{
+ HANDLE hContact;
+ int i, status, hideOffline;
+ BOOL mc_disablehgh = ServiceExists(MS_MC_DISABLEHIDDENGROUP);
+ DBVARIANT dbv = {0};
+ BYTE bMsgFrequency = cfg::getByte("CList", "fhistdata", 0);
+
+ CallService(MS_CLUI_LISTBEGINREBUILD, 0, 0);
+ for (i = 1; ; i++) {
+ if (pcli->pfnGetGroupName(i, NULL) == NULL)
+ break;
+ CallService(MS_CLUI_GROUPADDED, i, 0);
+ }
+
+ hideOffline = cfg::getByte("CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT);
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact != NULL) {
+ status = GetContactStatus(hContact);
+ if ((!hideOffline || status != ID_STATUS_OFFLINE) && !CLVM_GetContactHiddenStatus(hContact, NULL, NULL))
+ pcli->pfnChangeContactIcon(hContact, IconFromStatusMode((char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0), status, hContact, NULL), 1);
+
+ if(mc_disablehgh && !mc_hgh_removed) {
+ if(!DBGetContactSetting(hContact, "CList", "Group", &dbv)) {
+ if(!strcmp(dbv.pszVal, "MetaContacts Hidden Group"))
+ DBDeleteContactSetting(hContact, "CList", "Group");
+ mir_free(dbv.pszVal);
+ }
+ }
+
+ // build initial data for message frequency
+ if(!bMsgFrequency)
+ MF_CalcFrequency(hContact, 100, 0);
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ cfg::writeByte("CList", "fhistdata", 1);
+ mc_hgh_removed = TRUE;
+ CallService(MS_CLUI_SORTLIST, 0, 0);
+ CallService(MS_CLUI_LISTENDREBUILD, 0, 0);
+}
+
+DWORD INTSORT_GetLastMsgTime(HANDLE hContact)
+{
+ HANDLE hDbEvent;
+ DBEVENTINFO dbei = {0};
+
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ while(hDbEvent) {
+ dbei.cbSize = sizeof(dbei);
+ dbei.pBlob = 0;
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei);
+ if(dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT))
+ return dbei.timestamp;
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+ }
+ return 0;
+}
+
+int __forceinline GetProtoIndex(char * szName)
+{
+ if ( !szName )
+ return -1;
+ else {
+ PROTOACCOUNT* pa = ProtoGetAccount( szName );
+ return ( pa == NULL ) ? -1 : pa->iOrder;
+ }
+}
+
+int __forceinline INTSORT_CompareContacts(const struct ClcContact* c1, const struct ClcContact* c2, UINT bywhat)
+{
+ TCHAR *namea, *nameb;
+ int statusa, statusb;
+ char *szProto1, *szProto2;
+ int rc;
+
+ if (c1 == 0 || c2 == 0)
+ return 0;
+
+ szProto1 = c1->proto;
+ szProto2 = c2->proto;
+ statusa = c1->wStatus;
+ statusb = c2->wStatus;
+ // make sure, sticky contacts are always at the beginning of the group/list
+
+ if ((c1->flags & CONTACTF_STICKY) != (c2->flags & CONTACTF_STICKY))
+ return 2 * (c2->flags & CONTACTF_STICKY) - 1;
+
+ if(bywhat == SORTBY_PRIOCONTACTS) {
+ if((cfg::clcdat->exStyle & CLS_EX_DIVIDERONOFF) && ((c1->flags & CONTACTF_ONLINE) != (c2->flags & CONTACTF_ONLINE)))
+ return 0;
+ if ((c1->flags & CONTACTF_PRIORITY) != (c2->flags & CONTACTF_PRIORITY))
+ return 2 * (c2->flags & CONTACTF_PRIORITY) - 1;
+ else
+ return 0;
+ }
+
+ if (bywhat == SORTBY_STATUS) {
+ int ordera, orderb;
+
+ ordera = GetStatusModeOrdering(statusa);
+ orderb = GetStatusModeOrdering(statusb);
+ if (ordera != orderb)
+ return ordera - orderb;
+ else
+ return 0;
+ }
+
+ // separate contacts treated as "offline"
+ if ( !cfg::dat.bDontSeparateOffline && ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE )))
+ return 2 * (statusa == ID_STATUS_OFFLINE) - 1;
+
+ switch( bywhat ) {
+ case SORTBY_NAME:
+ namea = (TCHAR *)c1->szText;
+ nameb = (TCHAR *)c2->szText;
+ return CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, namea, -1, nameb, -1) - 2;
+
+ case SORTBY_LASTMSG:
+ if(c1->extraCacheEntry >= 0 && c1->extraCacheEntry < cfg::nextCacheEntry &&
+ c2->extraCacheEntry >= 0 && c2->extraCacheEntry < cfg::nextCacheEntry)
+ return(cfg::eCache[c2->extraCacheEntry].dwLastMsgTime - cfg::eCache[c1->extraCacheEntry].dwLastMsgTime);
+ else {
+ DWORD timestamp1 = INTSORT_GetLastMsgTime(c1->hContact);
+ DWORD timestamp2 = INTSORT_GetLastMsgTime(c2->hContact);
+ return timestamp2 - timestamp1;
+ }
+
+ case SORTBY_FREQUENCY:
+ if ( c1->extraCacheEntry >= 0 && c1->extraCacheEntry < cfg::nextCacheEntry &&
+ c2->extraCacheEntry >= 0 && c2->extraCacheEntry < cfg::nextCacheEntry )
+ return(cfg::eCache[c1->extraCacheEntry].msgFrequency - cfg::eCache[c2->extraCacheEntry].msgFrequency);
+ break;
+
+ case SORTBY_PROTO:
+ if(c1->bIsMeta)
+ szProto1 = c1->metaProto ? c1->metaProto : c1->proto;
+ if(c2->bIsMeta)
+ szProto2 = c2->metaProto ? c2->metaProto : c2->proto;
+
+ rc = GetProtoIndex(szProto1) - GetProtoIndex(szProto2);
+
+ if (rc != 0 && (szProto1 != NULL && szProto2 != NULL))
+ return rc;
+ }
+ return 0;
+}
+
+int CompareContacts(const struct ClcContact* c1, const struct ClcContact* c2)
+{
+ int i, result;
+
+ result = INTSORT_CompareContacts(c1, c2, SORTBY_PRIOCONTACTS);
+ if(result)
+ return result;
+
+ for(i = 0; i <= 2; i++) {
+ if(cfg::dat.sortOrder[i]) {
+ result = INTSORT_CompareContacts(c1, c2, cfg::dat.sortOrder[i]);
+ if(result != 0)
+ return result;
+ }
+ }
+ return 0;
+}
+
+#undef SAFESTRING
+
+static int resortTimerId = 0;
+static VOID CALLBACK SortContactsTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime)
+{
+ KillTimer(NULL, resortTimerId);
+ resortTimerId = 0;
+ CallService(MS_CLUI_SORTLIST, 0, 0);
+}
+
+int SetHideOffline(WPARAM wParam, LPARAM lParam)
+{
+ switch ((int) wParam) {
+ case 0:
+ cfg::writeByte("CList", "HideOffline", 0); break;
+ case 1:
+ cfg::writeByte("CList", "HideOffline", 1); break;
+ case -1:
+ cfg::writeByte("CList", "HideOffline", (BYTE) ! cfg::getByte("CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)); break;
+ }
+ SetButtonStates(pcli->hwndContactList);
+ LoadContactTree();
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/extBackg.cpp b/plugins/Clist_nicer/SRC/extBackg.cpp
new file mode 100644
index 0000000000..3b7d692c33
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/extBackg.cpp
@@ -0,0 +1,1926 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <commonheaders.h>
+#include "../coolsb/coolscroll.h"
+
+extern int g_hottrack;
+
+extern HWND g_hwndViewModeFrame;
+extern HIMAGELIST himlExtraImages;
+extern struct CluiTopButton top_buttons[];
+
+StatusItems_t *StatusItems = NULL;
+ImageItem *g_ImageItems = NULL, *g_glyphItem = NULL;
+ButtonItem *g_ButtonItems = NULL;
+ImageItem *g_CLUIImageItem = NULL;
+HBRUSH g_CLUISkinnedBkColor = 0;
+COLORREF g_CLUISkinnedBkColorRGB = 0;
+
+int ID_EXTBK_LAST = ID_EXTBK_LAST_D;
+
+void SetTBSKinned(int mode);
+void ReloadThemedOptions();
+void ReloadExtraIcons();
+static void SaveCompleteStructToDB(void);
+
+static StatusItems_t _StatusItems[] = {
+ {"Offline", "EXBK_Offline", ID_STATUS_OFFLINE,
+ CLCDEFAULT_GRADIENT, CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Online", "EXBK_Online", ID_STATUS_ONLINE,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Away", "EXBK_Away", ID_STATUS_AWAY,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"DND", "EXBK_Dnd", ID_STATUS_DND,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"NA", "EXBK_NA", ID_STATUS_NA,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Occupied", "EXBK_Occupied", ID_STATUS_OCCUPIED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Free for chat", "EXBK_FFC", ID_STATUS_FREECHAT,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Invisible", "EXBK_Invisible", ID_STATUS_INVISIBLE,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"On the phone", "EXBK_OTP", ID_STATUS_ONTHEPHONE,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Out to lunch", "EXBK_OTL", ID_STATUS_OUTTOLUNCH,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Idle", "EXBK_IDLE", ID_EXTBKIDLE,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"{-}Expanded Group", "EXBK_EXPANDEDGROUPS", ID_EXTBKEXPANDEDGROUP,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Collapsed Group", "EXBK_COLLAPSEDGROUP", ID_EXTBKCOLLAPSEDDGROUP,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Empty Group", "EXBK_EMPTYGROUPS", ID_EXTBKEMPTYGROUPS,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"{-}First contact of a group", "EXBK_FIRSTITEM", ID_EXTBKFIRSTITEM,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, 0, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Single item in group", "EXBK_SINGLEITEM", ID_EXTBKSINGLEITEM,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, 0, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Last contact of a group", "EXBK_LASTITEM", ID_EXTBKLASTITEM,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, 0, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"{-}First contact of NON-group", "EXBK_FIRSTITEM_NG", ID_EXTBKFIRSTITEM_NG,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, 0, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Single item in NON-group", "EXBK_SINGLEITEM_NG", ID_EXTBKSINGLEITEM_NG,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, 0, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Last contact of NON-group", "EXBK_LASTITEM_NG", ID_EXTBKLASTITEM_NG,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, 0, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"{-}Even Contact Positions", "EXBK_EVEN_CNTC_POS", ID_EXTBKEVEN_CNTCTPOS,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Odd Contact Positions", "EXBK_ODD_CNTC_POS", ID_EXTBKODD_CNTCTPOS,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"{-}Selection", "EXBK_SELECTION", ID_EXTBKSELECTION,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Hottracked Item", "EXBK_HOTTRACK", ID_EXTBKHOTTRACK,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"{-}Frame titlebars", "EXBK_FRAMETITLE", ID_EXTBKFRAMETITLE,
+ CLCDEFAULT_GRADIENT, CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 0
+ }, {"Event area", "EXBK_EVTAREA", ID_EXTBKEVTAREA,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 0
+ }, {"Status Bar", "EXBK_STATUSBAR", ID_EXTBKSTATUSBAR,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Tool bar", "EXBK_TOOLBAR", ID_EXTBKBUTTONBAR,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 0
+ }, {"{-}UI Button - pressed", "EXBK_BUTTONSPRESSED", ID_EXTBKBUTTONSPRESSED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"UI Button - not pressed", "EXBK_BUTTONSNPRESSED", ID_EXTBKBUTTONSNPRESSED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"UI Button - mouseover", "EXBK_BUTTONSMOUSEOVER", ID_EXTBKBUTTONSMOUSEOVER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Toolbar button - pressed", "EXBK_TBBUTTONSPRESSED", ID_EXTBKTBBUTTONSPRESSED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Toolbar button - not pressed", "EXBK_TBBUTTONSNPRESSED", ID_EXTBKTBBUTTONSNPRESSED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"Toolbar button - mouseover", "EXBK_TBBUTTONMOUSEOVER", ID_EXTBKTBBUTTONMOUSEOVER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"{-}Status floater", "EXBK_STATUSFLOATER", ID_EXTBKSTATUSFLOATER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+ }, {"{-}Frame border - no titlebar", "EXBK_OWNEDFRAMEBORDER", ID_EXTBKOWNEDFRAMEBORDER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, 1,
+ 1, 1, 1, CLCDEFAULT_IGNORE
+ }, {"Frame border - with titlebar", "EXBK_OWNEDFRAMEBORDERTB", ID_EXTBKOWNEDFRAMEBORDERTB,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, 1,
+ CLCDEFAULT_MRGN_TOP, 1, 1, CLCDEFAULT_IGNORE
+ }, {"{-}Avatarframe", "EXBK_AVATARFRAME", ID_EXTBKAVATARFRAME,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Avatarframe offline", "EXBK_AVATARFRAMEOFFLINE", ID_EXTBKAVATARFRAMEOFFLINE,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"{-}Scrollbar backgroundupper", "EXBK_SCROLLBACK", ID_EXTBKSCROLLBACK,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar backgroundlower", "EXBK_SCROLLBACKLOWER", ID_EXTBKSCROLLBACKLOWER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar thumb", "EXBK_SCROLLTHUMB", ID_EXTBKSCROLLTHUMB,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar thumb hovered", "EXBK_SCROLLTHUMBHOVER", ID_EXTBKSCROLLTHUMBHOVER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar thumb pressed", "EXBK_SCROLLTHUMBPRESSED", ID_EXTBKSCROLLTHUMBPRESSED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar button", "EXBK_SCROLLBUTTON", ID_EXTBKSCROLLBUTTON,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar button hovered", "EXBK_SCROLLBUTTONHOVER", ID_EXTBKSCROLLBUTTONHOVER,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar button pressed", "EXBK_SCROLLBUTTONPRESSED", ID_EXTBKSCROLLBUTTONPRESSED,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar arrow up", "EXBK_SCROLLARROWUP", ID_EXTBKSCROLLARROWUP,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }, {"Scrollbar arrow down", "EXBK_SCROLLARROWDOWN", ID_EXTBKSCROLLARROWDOWN,
+ CLCDEFAULT_GRADIENT,CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, CLCDEFAULT_TEXTCOLOR, CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT,
+ CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT, CLCDEFAULT_MRGN_BOTTOM, 1
+ }
+};
+
+BOOL __forceinline GetItemByStatus(int status, StatusItems_t *retitem)
+{
+ status = (status >= ID_STATUS_OFFLINE && status <= ID_EXTBK_LAST) ? status : ID_STATUS_OFFLINE; // better check the index...
+ *retitem = StatusItems[status - ID_STATUS_OFFLINE];
+ if(g_hottrack && status != ID_EXTBKHOTTRACK) // allow hottracking for ignored items, unless hottrack item itself should be ignored
+ retitem->IGNORED = FALSE;
+ return TRUE;
+}
+
+StatusItems_t *GetProtocolStatusItem(const char *szProto)
+{
+ int i;
+
+ if(szProto == NULL)
+ return NULL;
+
+ for(i = ID_EXTBK_LAST_D - ID_STATUS_OFFLINE + 1; i <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; i++) {
+ if(!strcmp(StatusItems[i].szName[0] == '{' ? &StatusItems[i].szName[3] : StatusItems[i].szName, szProto))
+ return &StatusItems[i];
+ }
+ return NULL;
+}
+
+// fills the struct with the settings in the database
+void LoadExtBkSettingsFromDB()
+{
+ DWORD ret;
+ int n;
+ char buffer[255];
+ int protoCount = 0, i;
+ PROTOACCOUNT **accs = 0;
+ DBVARIANT dbv = {0};
+
+ ProtoEnumAccounts( &protoCount, &accs );
+
+ StatusItems = (StatusItems_t *)malloc(sizeof(StatusItems_t) * ((ID_EXTBK_LAST - ID_STATUS_OFFLINE) + protoCount + 2));
+ CopyMemory(StatusItems, _StatusItems, sizeof(_StatusItems));
+
+ for(i = 0; i < protoCount; i++) {
+ ID_EXTBK_LAST++;
+ CopyMemory(&StatusItems[ID_EXTBK_LAST - ID_STATUS_OFFLINE], &StatusItems[0], sizeof(StatusItems_t));
+ mir_snprintf(StatusItems[ID_EXTBK_LAST - ID_STATUS_OFFLINE].szDBname, 30, "EXBK_%s", accs[i]->szModuleName );
+ if(i == 0) {
+ lstrcpynA(StatusItems[ID_EXTBK_LAST - ID_STATUS_OFFLINE].szName, "{-}", 30);
+ strncat(StatusItems[ID_EXTBK_LAST - ID_STATUS_OFFLINE].szName, accs[i]->szModuleName, 30);
+ }
+ else
+ lstrcpynA(StatusItems[ID_EXTBK_LAST - ID_STATUS_OFFLINE].szName, accs[i]->szModuleName, 30);
+ StatusItems[ID_EXTBK_LAST - ID_STATUS_OFFLINE].statusID = ID_EXTBK_LAST;
+ }
+ for (n = 0; n <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; n++) {
+ if (StatusItems[n].statusID != ID_EXTBKSEPARATOR) {
+ StatusItems[n].imageItem = 0;
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_IGNORE");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].IGNORED);
+ StatusItems[n]. IGNORED = (BYTE) ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_GRADIENT");
+ ret = cfg::getDword("CLCExt", buffer, StatusItems[n].GRADIENT);
+ StatusItems[n]. GRADIENT = (BYTE) ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_CORNER");
+ ret = cfg::getDword("CLCExt", buffer, StatusItems[n].CORNER);
+ StatusItems[n]. CORNER = (BYTE) ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR");
+ ret = cfg::getDword("CLCExt", buffer, StatusItems[n].COLOR);
+ StatusItems[n]. COLOR = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2");
+ ret = cfg::getDword(NULL, "CLCExt", buffer, StatusItems[n].COLOR2);
+ StatusItems[n]. COLOR2 = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2_TRANSPARENT");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].COLOR2_TRANSPARENT);
+ StatusItems[n]. COLOR2_TRANSPARENT = (BYTE) ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_TEXTCOLOR");
+ ret = cfg::getDword("CLCExt", buffer, StatusItems[n].TEXTCOLOR);
+ StatusItems[n]. TEXTCOLOR = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_ALPHA");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].ALPHA);
+ StatusItems[n]. ALPHA = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_LEFT");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].MARGIN_LEFT);
+ StatusItems[n]. MARGIN_LEFT = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_TOP");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].MARGIN_TOP);
+ StatusItems[n]. MARGIN_TOP = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_RIGHT");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].MARGIN_RIGHT);
+ StatusItems[n]. MARGIN_RIGHT = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_BOTTOM");
+ ret = cfg::getByte("CLCExt", buffer, StatusItems[n].MARGIN_BOTTOM);
+ StatusItems[n]. MARGIN_BOTTOM = ret;
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_BDRSTYLE");
+ ret = cfg::getDword("CLCExt", buffer, StatusItems[n].BORDERSTYLE);
+ StatusItems[n]. BORDERSTYLE = ret;
+ }
+ }
+ if(cfg::dat.bFirstRun) {
+ StatusItems_t *item = &StatusItems[ID_EXTBKBUTTONBAR - ID_STATUS_OFFLINE];
+
+ item->COLOR = GetSysColor(COLOR_3DFACE);
+ item->COLOR2 = GetSysColor(COLOR_3DFACE);
+
+ item = &StatusItems[ID_EXTBKEVTAREA - ID_STATUS_OFFLINE];
+ item->COLOR = item->COLOR2 = GetSysColor(COLOR_WINDOW);
+ item->BORDERSTYLE = EDGE_ETCHED;
+ SaveCompleteStructToDB();
+ }
+}
+
+// writes whole struct to the database
+static void SaveCompleteStructToDB(void)
+{
+ int n;
+ char buffer[255];
+
+ for (n = 0; n <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; n++) {
+ if (StatusItems[n].statusID != ID_EXTBKSEPARATOR) {
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_IGNORE");
+ cfg::writeByte("CLCExt", buffer, StatusItems[n].IGNORED);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_GRADIENT");
+ cfg::writeDword("CLCExt", buffer, StatusItems[n].GRADIENT);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_CORNER");
+ cfg::writeDword("CLCExt", buffer, StatusItems[n].CORNER);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR");
+ cfg::writeDword("CLCExt", buffer, StatusItems[n].COLOR);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2");
+ cfg::writeDword("CLCExt", buffer, StatusItems[n].COLOR2);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2_TRANSPARENT");
+ cfg::writeByte("CLCExt", buffer, StatusItems[n].COLOR2_TRANSPARENT);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_TEXTCOLOR");
+ cfg::writeDword("CLCExt", buffer, StatusItems[n].TEXTCOLOR);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_ALPHA");
+ cfg::writeByte("CLCExt", buffer, (BYTE)StatusItems[n].ALPHA);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_LEFT");
+ cfg::writeByte("CLCExt", buffer, (BYTE)StatusItems[n].MARGIN_LEFT);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_TOP");
+ cfg::writeByte("CLCExt", buffer, (BYTE)StatusItems[n].MARGIN_TOP);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_RIGHT");
+ cfg::writeByte("CLCExt", buffer, (BYTE)StatusItems[n].MARGIN_RIGHT);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MRGN_BOTTOM");
+ cfg::writeByte("CLCExt", buffer, (BYTE)StatusItems[n].MARGIN_BOTTOM);
+
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_BDRSTYLE");
+ cfg::writeDword("CLCExt", buffer, StatusItems[n].BORDERSTYLE);
+ }
+ }
+}
+
+void SetButtonToSkinned()
+{
+ int bSkinned = cfg::dat.bSkinnedButtonMode = cfg::getByte("CLCExt", "bskinned", 0);
+
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBMENU, BM_SETSKINNED, 0, bSkinned);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBGLOBALSTATUS, BM_SETSKINNED, 0, bSkinned);
+ if(bSkinned) {
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBMENU, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBGLOBALSTATUS, BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBGLOBALSTATUS, BUTTONSETASFLATBTN + 10, 0, 0);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBMENU, BUTTONSETASFLATBTN + 10, 0, 0);
+ }
+ else {
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBMENU, BUTTONSETASFLATBTN, 0, 1);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBGLOBALSTATUS, BUTTONSETASFLATBTN, 0, 1);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBGLOBALSTATUS, BUTTONSETASFLATBTN + 10, 0, 1);
+ SendDlgItemMessage(pcli->hwndContactList, IDC_TBMENU, BUTTONSETASFLATBTN + 10, 0, 1);
+ }
+ SendMessage(g_hwndViewModeFrame, WM_USER + 100, 0, 0);
+}
+
+void Reload3dBevelColors()
+{
+ if(cfg::dat.hPen3DBright)
+ DeleteObject(cfg::dat.hPen3DBright);
+ if(cfg::dat.hPen3DDark)
+ DeleteObject(cfg::dat.hPen3DDark);
+
+ cfg::dat.hPen3DBright = CreatePen(PS_SOLID, 1, cfg::getDword("CLCExt", "3dbright", GetSysColor(COLOR_3DLIGHT)));
+ cfg::dat.hPen3DDark = CreatePen(PS_SOLID, 1, cfg::getDword("CLCExt", "3ddark", GetSysColor(COLOR_3DSHADOW)));
+
+}
+
+// Save Non-StatusItems Settings
+void SaveNonStatusItemsSettings(HWND hwndDlg)
+{
+ BOOL translated;
+
+ cfg::writeByte("CLCExt", "EXBK_EqualSelection", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_EQUALSELECTION));
+ cfg::writeByte("CLCExt", "EXBK_SelBlend", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SELBLEND));
+
+ cfg::dat.cornerRadius = GetDlgItemInt(hwndDlg, IDC_CORNERRAD, &translated, FALSE);
+ cfg::dat.bApplyIndentToBg = IsDlgButtonChecked(hwndDlg, IDC_APPLYINDENTBG) ? 1 : 0;
+ cfg::dat.bUsePerProto = IsDlgButtonChecked(hwndDlg, IDC_USEPERPROTO) ? 1 : 0;
+ cfg::dat.bWantFastGradients = IsDlgButtonChecked(hwndDlg, IDC_FASTGRADIENT) ? 1 : 0;
+ cfg::dat.bOverridePerStatusColors = IsDlgButtonChecked(hwndDlg, IDC_OVERRIDEPERSTATUSCOLOR) ? 1 : 0;
+ cfg::dat.titleBarHeight = (BYTE)GetDlgItemInt(hwndDlg, IDC_LASTITEMPADDING, &translated, FALSE);
+ cfg::dat.group_padding = GetDlgItemInt(hwndDlg, IDC_GRPTOPPADDING, &translated, FALSE);
+
+ cfg::writeByte("CLCExt", "CornerRad", cfg::dat.cornerRadius);
+ cfg::writeByte("CLCExt", "applyindentbg", (BYTE)cfg::dat.bApplyIndentToBg);
+ cfg::writeByte("CLCExt", "useperproto", (BYTE)cfg::dat.bUsePerProto);
+ cfg::writeByte("CLCExt", "override_status", (BYTE)cfg::dat.bOverridePerStatusColors);
+ cfg::writeByte("CLCExt", "bskinned", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SETALLBUTTONSKINNED) ? 1 : 0));
+ cfg::writeByte("CLCExt", "FastGradients", cfg::dat.bWantFastGradients);
+ cfg::writeByte("CLC", "IgnoreSelforGroups", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORESELFORGROUPS));
+
+ cfg::writeDword("CLCExt", "grp_padding", cfg::dat.group_padding);
+ cfg::writeByte("CLCExt", "frame_height", cfg::dat.titleBarHeight);
+
+ Reload3dBevelColors();
+ SetButtonToSkinned();
+}
+
+/*
+ * skin/theme related settings which are exported to/imported from the .ini style .clist file
+ */
+
+struct {char *szModule; char *szSetting; unsigned int size; int defaultval;} _tagSettings[] = {
+ "CLCExt", "3dbright", 4, RGB(224, 225, 225),
+ "CLCExt", "3ddark", 4, RGB(224, 225, 225),
+ "CLCExt", "bskinned", 1, 0,
+ "CLCExt", "CornerRad", 1, 0,
+ "CLCExt", "applyindentbg", 1, 0,
+ "CLCExt", "override_status", 1, 0,
+ "CLCExt", "useperproto", 1, 0,
+ "CLUI", "tb_skinned", 1, 0,
+ "CLUI", "sb_skinned", 1, 0,
+ "CLC", "RowGap", 1, 0,
+ "CLC", "ExIconScale", 1, 0,
+ "CLUI", "UseBkSkin", 1, 0,
+ "CLUI", "clipborder", 1, 0,
+ "CLUIFrames", "GapBetweenFrames", 4, 0,
+ "CLC", "BkColour", 4, RGB(224, 224, 224),
+ "CLCExt", "EXBK_CenterGroupnames", 1, 0,
+ "CLUI", "TBSize", 1, 19,
+ "CLC", "BkBmpUse", 2, 0,
+ "CLUI", "clmargins", 4, 0,
+ // frame stuff
+
+ "WorldTime", "BgColour", 4, 0,
+ "WorldTime", "FontCol", 4, 0,
+ NULL, NULL, 0, 0
+};
+void extbk_export(char *file)
+{
+ int n, i;
+ char buffer[255];
+ char szSection[255];
+ char szKey[255];
+ DBVARIANT dbv = {0};
+ DWORD data;
+
+ data = 3;
+
+ WritePrivateProfileStructA("Global", "Version", &data, 4, file);
+ for (n = 0; n <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; n++) {
+ if (StatusItems[n].statusID != ID_EXTBKSEPARATOR) {
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_ALPHA");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].ALPHA), sizeof(StatusItems[n].ALPHA), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].COLOR), sizeof(StatusItems[n].COLOR), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].COLOR2), sizeof(StatusItems[n].COLOR2), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2_TRANSPARENT");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].COLOR2_TRANSPARENT), sizeof(StatusItems[n].COLOR2_TRANSPARENT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_TEXTCOLOR");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].TEXTCOLOR), sizeof(StatusItems[n].TEXTCOLOR), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_CORNER");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].CORNER), sizeof(StatusItems[n].CORNER), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_GRADIENT");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].GRADIENT), sizeof(StatusItems[n].GRADIENT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_IGNORED");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].IGNORED), sizeof(StatusItems[n].IGNORED), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_BOTTOM");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_BOTTOM), sizeof(StatusItems[n].MARGIN_BOTTOM), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_LEFT");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_LEFT), sizeof(StatusItems[n].MARGIN_LEFT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_RIGHT");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_RIGHT), sizeof(StatusItems[n].MARGIN_RIGHT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_TOP");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_TOP), sizeof(StatusItems[n].MARGIN_TOP), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_BORDERSTYLE");
+ WritePrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].BORDERSTYLE), sizeof(StatusItems[n].BORDERSTYLE), file);
+ }
+ }
+ for(n = 0; n <= FONTID_LAST; n++) {
+ mir_snprintf(szSection, 255, "Font%d", n);
+
+ mir_snprintf(szKey, 255, "Font%dName", n);
+ if(!cfg::getString(NULL, "CLC", szKey, &dbv)) {
+ WritePrivateProfileStringA(szSection, "Name", dbv.pszVal, file);
+ mir_free(dbv.pszVal);
+ }
+ mir_snprintf(szKey, 255, "Font%dSize", n);
+ data = (DWORD)cfg::getByte("CLC", szKey, 8);
+ WritePrivateProfileStructA(szSection, "Size", &data, 1, file);
+
+ mir_snprintf(szKey, 255, "Font%dSty", n);
+ data = (DWORD)cfg::getByte("CLC", szKey, 8);
+ WritePrivateProfileStructA(szSection, "Style", &data, 1, file);
+
+ mir_snprintf(szKey, 255, "Font%dSet", n);
+ data = (DWORD)cfg::getByte("CLC", szKey, 8);
+ WritePrivateProfileStructA(szSection, "Set", &data, 1, file);
+
+ mir_snprintf(szKey, 255, "Font%dCol", n);
+ data = cfg::getDword("CLC", szKey, 8);
+ WritePrivateProfileStructA(szSection, "Color", &data, 4, file);
+
+ mir_snprintf(szKey, 255, "Font%dFlags", n);
+ data = (DWORD)cfg::getDword("CLC", szKey, 8);
+ WritePrivateProfileStructA(szSection, "Flags", &data, 4, file);
+
+ mir_snprintf(szKey, 255, "Font%dAs", n);
+ data = (DWORD)cfg::getWord("CLC", szKey, 8);
+ WritePrivateProfileStructA(szSection, "SameAs", &data, 2, file);
+ }
+ i = 0;
+ while(_tagSettings[i].szModule != NULL) {
+ data = 0;
+ switch(_tagSettings[i].size) {
+ case 1:
+ data = (DWORD)cfg::getByte( _tagSettings[i].szModule, _tagSettings[i].szSetting, (BYTE)_tagSettings[i].defaultval);
+ break;
+ case 2:
+ data = (DWORD)cfg::getWord( _tagSettings[i].szModule, _tagSettings[i].szSetting, (DWORD)_tagSettings[i].defaultval);
+ break;
+ case 4:
+ data = (DWORD)cfg::getDword( _tagSettings[i].szModule, _tagSettings[i].szSetting, (DWORD)_tagSettings[i].defaultval);
+ break;
+ }
+ WritePrivateProfileStructA("Global", _tagSettings[i].szSetting, &data, _tagSettings[i].size, file);
+ i++;
+ }
+ if(!cfg::getString(NULL, "CLC", "BkBitmap", &dbv)) {
+ WritePrivateProfileStringA("Global", "BkBitmap", dbv.pszVal, file);
+ DBFreeVariant(&dbv);
+ }
+}
+
+DWORD __fastcall HexStringToLong(const char *szSource)
+{
+ char *stopped;
+ COLORREF clr = strtol(szSource, &stopped, 16);
+ if(clr == -1)
+ return clr;
+ return(RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)));
+}
+
+static StatusItems_t default_item = {
+ "{--Contact--}", "", 0,
+ CLCDEFAULT_GRADIENT, CLCDEFAULT_CORNER,
+ CLCDEFAULT_COLOR, CLCDEFAULT_COLOR2, CLCDEFAULT_COLOR2_TRANSPARENT, -1,
+ CLCDEFAULT_ALPHA, CLCDEFAULT_MRGN_LEFT, CLCDEFAULT_MRGN_TOP, CLCDEFAULT_MRGN_RIGHT,
+ CLCDEFAULT_MRGN_BOTTOM, CLCDEFAULT_IGNORE
+};
+
+
+static void PreMultiply(HBITMAP hBitmap, int mode)
+{
+ BYTE *p = NULL;
+ DWORD dwLen;
+ int width, height, x, y;
+ BITMAP bmp;
+ BYTE alpha;
+
+ GetObject(hBitmap, sizeof(bmp), &bmp);
+ width = bmp.bmWidth;
+ height = bmp.bmHeight;
+ dwLen = width * height * 4;
+ p = (BYTE *)malloc(dwLen);
+ if(p) {
+ GetBitmapBits(hBitmap, dwLen, p);
+ for (y = 0; y < height; ++y) {
+ BYTE *px = p + width * 4 * y;
+
+ for (x = 0; x < width; ++x) {
+ if(mode) {
+ alpha = px[3];
+ px[0] = px[0] * alpha/255;
+ px[1] = px[1] * alpha/255;
+ px[2] = px[2] * alpha/255;
+ }
+ else
+ px[3] = 255;
+ px += 4;
+ }
+ }
+ dwLen = SetBitmapBits(hBitmap, dwLen, p);
+ free(p);
+ }
+}
+
+static void CorrectBitmap32Alpha(HBITMAP hBitmap)
+{
+ BITMAP bmp;
+ DWORD dwLen;
+ BYTE *p;
+ int x, y;
+ BOOL fixIt = TRUE;
+
+ GetObject(hBitmap, sizeof(bmp), &bmp);
+
+ if (bmp.bmBitsPixel != 32)
+ return;
+
+ dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8);
+ p = (BYTE *)malloc(dwLen);
+ if (p == NULL)
+ return;
+ memset(p, 0, dwLen);
+
+ GetBitmapBits(hBitmap, dwLen, p);
+
+ for (y = 0; y < bmp.bmHeight; ++y) {
+ BYTE *px = p + bmp.bmWidth * 4 * y;
+
+ for (x = 0; x < bmp.bmWidth; ++x)
+ {
+ if (px[3] != 0)
+ {
+ fixIt = FALSE;
+ }
+ else
+ {
+ px[3] = 255;
+ }
+
+ px += 4;
+ }
+ }
+
+ if (fixIt)
+ {
+ SetBitmapBits(hBitmap, bmp.bmWidth * bmp.bmHeight * 4, p);
+ }
+
+ free(p);
+}
+
+static HBITMAP LoadPNG(const char *szFilename, ImageItem *item)
+{
+ HBITMAP hBitmap = 0;
+
+ hBitmap = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)szFilename);
+ if(hBitmap != 0)
+ CorrectBitmap32Alpha(hBitmap);
+
+ return hBitmap;
+}
+
+static void IMG_CreateItem(ImageItem *item, const char *fileName, HDC hdc)
+{
+ HBITMAP hbm = LoadPNG(fileName, item);
+ BITMAP bm;
+
+ if(hbm) {
+ item->hbm = hbm;
+ item->bf.BlendFlags = 0;
+ item->bf.BlendOp = AC_SRC_OVER;
+ item->bf.AlphaFormat = 0;
+
+ GetObject(hbm, sizeof(bm), &bm);
+ if(bm.bmBitsPixel == 32) {
+ PreMultiply(hbm, 1);
+ item->dwFlags |= IMAGE_PERPIXEL_ALPHA;
+ item->bf.AlphaFormat = AC_SRC_ALPHA;
+ }
+ item->width = bm.bmWidth;
+ item->height = bm.bmHeight;
+ item->inner_height = item->height - item->bTop - item->bBottom;
+ item->inner_width = item->width - item->bLeft - item->bRight;
+ if(item->bTop && item->bBottom && item->bLeft && item->bRight) {
+ item->dwFlags |= IMAGE_FLAG_DIVIDED;
+ if(item->inner_height <= 0 || item->inner_width <= 0) {
+ DeleteObject(hbm);
+ item->hbm = 0;
+ return;
+ }
+ }
+ item->hdc = CreateCompatibleDC(hdc);
+ item->hbmOld = reinterpret_cast<HBITMAP>(SelectObject(item->hdc, item->hbm));
+ }
+}
+
+static void IMG_DeleteItem(ImageItem *item)
+{
+ if(!(item->dwFlags & IMAGE_GLYPH)) {
+ SelectObject(item->hdc, item->hbmOld);
+ DeleteObject(item->hbm);
+ DeleteDC(item->hdc);
+ }
+ if(item->fillBrush)
+ DeleteObject(item->fillBrush);
+}
+
+static void ReadItem(StatusItems_t *this_item, char *szItem, char *file)
+{
+ char buffer[512], def_color[20];
+ COLORREF clr;
+
+ StatusItems_t *defaults = &default_item;
+ GetPrivateProfileStringA(szItem, "BasedOn", "None", buffer, 400, file);
+
+
+ if(strcmp(buffer, "None")) {
+ int i;
+
+ for(i = 0; i <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; i++) {
+ if(!_stricmp(StatusItems[i].szName[0] == '{' ? &StatusItems[i].szName[3] : StatusItems[i].szName, buffer)) {
+ defaults = &StatusItems[i];
+ break;
+ }
+ }
+ }
+ this_item->ALPHA = (int)GetPrivateProfileIntA(szItem, "Alpha", defaults->ALPHA, file);
+ this_item->ALPHA = min(this_item->ALPHA, 100);
+
+ clr = RGB(GetBValue(defaults->COLOR), GetGValue(defaults->COLOR), GetRValue(defaults->COLOR));
+ _snprintf(def_color, 15, "%6.6x", clr);
+ GetPrivateProfileStringA(szItem, "Color1", def_color, buffer, 400, file);
+ this_item->COLOR = HexStringToLong(buffer);
+
+ clr = RGB(GetBValue(defaults->COLOR2), GetGValue(defaults->COLOR2), GetRValue(defaults->COLOR2));
+ _snprintf(def_color, 15, "%6.6x", clr);
+ GetPrivateProfileStringA(szItem, "Color2", def_color, buffer, 400, file);
+ this_item->COLOR2 = HexStringToLong(buffer);
+
+ this_item->COLOR2_TRANSPARENT = (BYTE)GetPrivateProfileIntA(szItem, "COLOR2_TRANSPARENT", defaults->COLOR2_TRANSPARENT, file);
+
+ this_item->CORNER = defaults->CORNER & CORNER_ACTIVE ? defaults->CORNER : 0;
+ GetPrivateProfileStringA(szItem, "Corner", "None", buffer, 400, file);
+ if(strstr(buffer, "tl"))
+ this_item->CORNER |= CORNER_TL;
+ if(strstr(buffer, "tr"))
+ this_item->CORNER |= CORNER_TR;
+ if(strstr(buffer, "bl"))
+ this_item->CORNER |= CORNER_BL;
+ if(strstr(buffer, "br"))
+ this_item->CORNER |= CORNER_BR;
+ if(this_item->CORNER)
+ this_item->CORNER |= CORNER_ACTIVE;
+
+ this_item->GRADIENT = defaults->GRADIENT & GRADIENT_ACTIVE ? defaults->GRADIENT : 0;
+ GetPrivateProfileStringA(szItem, "Gradient", "None", buffer, 400, file);
+ if(strstr(buffer, "left"))
+ this_item->GRADIENT = GRADIENT_RL;
+ else if(strstr(buffer, "right"))
+ this_item->GRADIENT = GRADIENT_LR;
+ else if(strstr(buffer, "up"))
+ this_item->GRADIENT = GRADIENT_BT;
+ else if(strstr(buffer, "down"))
+ this_item->GRADIENT = GRADIENT_TB;
+ if(this_item->GRADIENT)
+ this_item->GRADIENT |= GRADIENT_ACTIVE;
+
+ this_item->MARGIN_LEFT = GetPrivateProfileIntA(szItem, "Left", defaults->MARGIN_LEFT, file);
+ this_item->MARGIN_RIGHT = GetPrivateProfileIntA(szItem, "Right", defaults->MARGIN_RIGHT, file);
+ this_item->MARGIN_TOP = GetPrivateProfileIntA(szItem, "Top", defaults->MARGIN_TOP, file);
+ this_item->MARGIN_BOTTOM = GetPrivateProfileIntA(szItem, "Bottom", defaults->MARGIN_BOTTOM, file);
+ this_item->BORDERSTYLE = GetPrivateProfileIntA(szItem, "Borderstyle", defaults->BORDERSTYLE, file);
+
+ GetPrivateProfileStringA(szItem, "Textcolor", "ffffffff", buffer, 400, file);
+ this_item->TEXTCOLOR = HexStringToLong(buffer);
+}
+
+void IMG_ReadItem(const char *itemname, const char *szFileName)
+{
+ ImageItem tmpItem, *newItem = NULL;
+ char buffer[512], szItemNr[30];
+ char szFinalName[MAX_PATH];
+ HDC hdc = GetDC(pcli->hwndContactList);
+ int i, n;
+ BOOL alloced = FALSE;
+ char szDrive[MAX_PATH], szPath[MAX_PATH];
+
+ ZeroMemory(&tmpItem, sizeof(ImageItem));
+ GetPrivateProfileStringA(itemname, "Glyph", "None", buffer, 500, szFileName);
+ if(strcmp(buffer, "None")) {
+ sscanf(buffer, "%d,%d,%d,%d", &tmpItem.glyphMetrics[0], &tmpItem.glyphMetrics[1],
+ &tmpItem.glyphMetrics[2], &tmpItem.glyphMetrics[3]);
+ if(tmpItem.glyphMetrics[2] > tmpItem.glyphMetrics[0] && tmpItem.glyphMetrics[3] > tmpItem.glyphMetrics[1]) {
+ tmpItem.dwFlags |= IMAGE_GLYPH;
+ tmpItem.glyphMetrics[2] = (tmpItem.glyphMetrics[2] - tmpItem.glyphMetrics[0]) + 1;
+ tmpItem.glyphMetrics[3] = (tmpItem.glyphMetrics[3] - tmpItem.glyphMetrics[1]) + 1;
+ goto done_with_glyph;
+ }
+ }
+ GetPrivateProfileStringA(itemname, "Image", "None", buffer, 500, szFileName);
+ if(strcmp(buffer, "None")) {
+
+done_with_glyph:
+
+ strncpy(tmpItem.szName, &itemname[1], sizeof(tmpItem.szName));
+ tmpItem.szName[sizeof(tmpItem.szName) - 1] = 0;
+ _splitpath(szFileName, szDrive, szPath, NULL, NULL);
+ mir_snprintf(szFinalName, MAX_PATH, "%s\\%s\\%s", szDrive, szPath, buffer);
+ tmpItem.alpha = GetPrivateProfileIntA(itemname, "Alpha", 100, szFileName);
+ tmpItem.alpha = min(tmpItem.alpha, 100);
+ tmpItem.alpha = (BYTE)((FLOAT)(((FLOAT) tmpItem.alpha) / 100) * 255);
+ tmpItem.bf.SourceConstantAlpha = tmpItem.alpha;
+ tmpItem.bLeft = GetPrivateProfileIntA(itemname, "Left", 0, szFileName);
+ tmpItem.bRight = GetPrivateProfileIntA(itemname, "Right", 0, szFileName);
+ tmpItem.bTop = GetPrivateProfileIntA(itemname, "Top", 0, szFileName);
+ tmpItem.bBottom = GetPrivateProfileIntA(itemname, "Bottom", 0, szFileName);
+ if(tmpItem.dwFlags & IMAGE_GLYPH) {
+ tmpItem.width = tmpItem.glyphMetrics[2];
+ tmpItem.height = tmpItem.glyphMetrics[3];
+ tmpItem.inner_height = tmpItem.glyphMetrics[3] - tmpItem.bTop - tmpItem.bBottom;
+ tmpItem.inner_width = tmpItem.glyphMetrics[2] - tmpItem.bRight - tmpItem.bLeft;
+
+ if(tmpItem.bTop && tmpItem.bBottom && tmpItem.bLeft && tmpItem.bRight)
+ tmpItem.dwFlags |= IMAGE_FLAG_DIVIDED;
+ tmpItem.bf.BlendFlags = 0;
+ tmpItem.bf.BlendOp = AC_SRC_OVER;
+ tmpItem.bf.AlphaFormat = 0;
+ tmpItem.dwFlags |= IMAGE_PERPIXEL_ALPHA;
+ tmpItem.bf.AlphaFormat = AC_SRC_ALPHA;
+ if(tmpItem.inner_height <= 0 || tmpItem.inner_width <= 0) {
+ ReleaseDC(pcli->hwndContactList, hdc);
+ return;
+ }
+ }
+ GetPrivateProfileStringA(itemname, "Fillcolor", "None", buffer, 500, szFileName);
+ if(strcmp(buffer, "None")) {
+ COLORREF fillColor = HexStringToLong(buffer);
+ tmpItem.fillBrush = CreateSolidBrush(fillColor);
+ tmpItem.dwFlags |= IMAGE_FILLSOLID;
+ }
+ else
+ tmpItem.fillBrush = 0;
+
+ GetPrivateProfileStringA(itemname, "Stretch", "None", buffer, 500, szFileName);
+ if(buffer[0] == 'B' || buffer[0] == 'b')
+ tmpItem.bStretch = IMAGE_STRETCH_B;
+ else if(buffer[0] == 'h' || buffer[0] == 'H')
+ tmpItem.bStretch = IMAGE_STRETCH_V;
+ else if(buffer[0] == 'w' || buffer[0] == 'W')
+ tmpItem.bStretch = IMAGE_STRETCH_H;
+ tmpItem.hbm = 0;
+
+ if(!_stricmp(itemname, "$glyphs")) {
+ IMG_CreateItem(&tmpItem, szFinalName, hdc);
+ if(tmpItem.hbm) {
+ newItem = reinterpret_cast<ImageItem *>(malloc(sizeof(ImageItem)));
+ ZeroMemory(newItem, sizeof(ImageItem));
+ *newItem = tmpItem;
+ g_glyphItem = newItem;
+ }
+ goto imgread_done;
+ }
+ if(itemname[0] == '@') {
+ if(!(tmpItem.dwFlags & IMAGE_GLYPH))
+ IMG_CreateItem(&tmpItem, szFinalName, hdc);
+ if(tmpItem.hbm || tmpItem.dwFlags & IMAGE_GLYPH) {
+ ImageItem *pItem = g_ImageItems;
+
+ newItem = reinterpret_cast<ImageItem *>(malloc(sizeof(ImageItem)));
+ ZeroMemory(newItem, sizeof(ImageItem));
+ *newItem = tmpItem;
+
+ if(g_ImageItems == NULL)
+ g_ImageItems = newItem;
+ else {
+ ImageItem *pItem = g_ImageItems;
+
+ while(pItem->nextItem != 0)
+ pItem = pItem->nextItem;
+ pItem->nextItem = newItem;
+ }
+ }
+ goto imgread_done;
+ }
+ for(n = 0;;n++) {
+ mir_snprintf(szItemNr, 30, "Item%d", n);
+ GetPrivateProfileStringA(itemname, szItemNr, "None", buffer, 500, szFileName);
+ if(!strcmp(buffer, "None"))
+ break;
+ if(!strcmp(buffer, "CLUI")) {
+ if(!(tmpItem.dwFlags & IMAGE_GLYPH))
+ IMG_CreateItem(&tmpItem, szFinalName, hdc);
+ if(tmpItem.hbm || tmpItem.dwFlags & IMAGE_GLYPH) {
+ COLORREF clr;
+
+ newItem = reinterpret_cast<ImageItem *>(malloc(sizeof(ImageItem)));
+ ZeroMemory(newItem, sizeof(ImageItem));
+ *newItem = tmpItem;
+ g_CLUIImageItem = newItem;
+ GetPrivateProfileStringA(itemname, "Colorkey", "e5e5e5", buffer, 500, szFileName);
+ clr = HexStringToLong(buffer);
+ cfg::dat.colorkey = clr;
+ cfg::writeDword("CLUI", "ColorKey", clr);
+ if(g_CLUISkinnedBkColor)
+ DeleteObject(g_CLUISkinnedBkColor);
+ g_CLUISkinnedBkColor = CreateSolidBrush(clr);
+ g_CLUISkinnedBkColorRGB = clr;
+ }
+ continue;
+ }
+ for(i = 0; i <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; i++) {
+ if(!_stricmp(StatusItems[i].szName[0] == '{' ? &StatusItems[i].szName[3] : StatusItems[i].szName, buffer)) {
+ if(!alloced) {
+ if(!(tmpItem.dwFlags & IMAGE_GLYPH))
+ IMG_CreateItem(&tmpItem, szFinalName, hdc);
+ if(tmpItem.hbm || tmpItem.dwFlags & IMAGE_GLYPH) {
+ newItem = reinterpret_cast<ImageItem *>(malloc(sizeof(ImageItem)));
+ ZeroMemory(newItem, sizeof(ImageItem));
+ *newItem = tmpItem;
+ StatusItems[i].imageItem = newItem;
+ if(g_ImageItems == NULL)
+ g_ImageItems = newItem;
+ else {
+ ImageItem *pItem = g_ImageItems;
+
+ while(pItem->nextItem != 0)
+ pItem = pItem->nextItem;
+ pItem->nextItem = newItem;
+ }
+ alloced = TRUE;
+ }
+ }
+ else if(newItem != NULL)
+ StatusItems[i].imageItem = newItem;
+ }
+ }
+ }
+ }
+imgread_done:
+ ReleaseDC(pcli->hwndContactList, hdc);
+}
+
+void IMG_DeleteItems()
+{
+ ImageItem *pItem = g_ImageItems, *pNextItem;
+ ButtonItem *pbItem = g_ButtonItems, *pbNextItem;
+
+ int i;
+
+ while(pItem) {
+ IMG_DeleteItem(pItem);
+ pNextItem = pItem->nextItem;
+ free(pItem);
+ pItem = pNextItem;
+ }
+ g_ImageItems = NULL;
+ while(pbItem) {
+ DestroyWindow(pbItem->hWnd);
+ pbNextItem = pbItem->nextItem;
+ free(pbItem);
+ pbItem = pbNextItem;
+ }
+ g_ButtonItems = NULL;
+
+ if(g_CLUIImageItem) {
+ IMG_DeleteItem(g_CLUIImageItem);
+ free(g_CLUIImageItem);
+ }
+ g_CLUIImageItem = NULL;
+
+ if(g_glyphItem) {
+ IMG_DeleteItem(g_glyphItem);
+ free(g_glyphItem);
+ }
+ g_glyphItem = NULL;
+
+ for(i = 0; i <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; i++)
+ StatusItems[i].imageItem = NULL;
+}
+
+static UINT nextButtonID = IDC_TBFIRSTUID;
+
+static void BTN_ReadItem(char *itemName, char *file)
+{
+ ButtonItem tmpItem, *newItem;
+ char szBuffer[1024];
+ ImageItem *imgItem = g_ImageItems;
+
+ ZeroMemory(&tmpItem, sizeof(tmpItem));
+ mir_snprintf(tmpItem.szName, sizeof(tmpItem.szName), "%s", &itemName[1]);
+ tmpItem.width = GetPrivateProfileIntA(itemName, "Width", 16, file);
+ tmpItem.height = GetPrivateProfileIntA(itemName, "Height", 16, file);
+ tmpItem.xOff = GetPrivateProfileIntA(itemName, "xoff", 0, file);
+ tmpItem.yOff = GetPrivateProfileIntA(itemName, "yoff", 0, file);
+
+ tmpItem.dwFlags |= GetPrivateProfileIntA(itemName, "toggle", 0, file) ? BUTTON_ISTOGGLE : 0;
+
+ GetPrivateProfileStringA(itemName, "Pressed", "None", szBuffer, 1000, file);
+ if(!_stricmp(szBuffer, "default"))
+ tmpItem.imgPressed = StatusItems[ID_EXTBKTBBUTTONSPRESSED - ID_STATUS_OFFLINE].imageItem;
+ else {
+ while(imgItem) {
+ if(!_stricmp(imgItem->szName, szBuffer)) {
+ tmpItem.imgPressed = imgItem;
+ break;
+ }
+ imgItem = imgItem->nextItem;
+ }
+ }
+
+ imgItem = g_ImageItems;
+ GetPrivateProfileStringA(itemName, "Normal", "None", szBuffer, 1000, file);
+ if(!_stricmp(szBuffer, "default"))
+ tmpItem.imgNormal = StatusItems[ID_EXTBKTBBUTTONSNPRESSED - ID_STATUS_OFFLINE].imageItem;
+ else {
+ while(imgItem) {
+ if(!_stricmp(imgItem->szName, szBuffer)) {
+ tmpItem.imgNormal = imgItem;
+ break;
+ }
+ imgItem = imgItem->nextItem;
+ }
+ }
+
+ imgItem = g_ImageItems;
+ GetPrivateProfileStringA(itemName, "Hover", "None", szBuffer, 1000, file);
+ if(!_stricmp(szBuffer, "default"))
+ tmpItem.imgHover = StatusItems[ID_EXTBKTBBUTTONMOUSEOVER - ID_STATUS_OFFLINE].imageItem;
+ else {
+ while(imgItem) {
+ if(!_stricmp(imgItem->szName, szBuffer)) {
+ tmpItem.imgHover = imgItem;
+ break;
+ }
+ imgItem = imgItem->nextItem;
+ }
+ }
+
+ GetPrivateProfileStringA(itemName, "NormalGlyph", "0, 0, 0, 0", szBuffer, 1000, file);
+ sscanf(szBuffer, "%d,%d,%d,%d", &tmpItem.normalGlyphMetrics[0], &tmpItem.normalGlyphMetrics[1],
+ &tmpItem.normalGlyphMetrics[2], &tmpItem.normalGlyphMetrics[3]);
+ tmpItem.normalGlyphMetrics[2] = (tmpItem.normalGlyphMetrics[2] - tmpItem.normalGlyphMetrics[0]) + 1;
+ tmpItem.normalGlyphMetrics[3] = (tmpItem.normalGlyphMetrics[3] - tmpItem.normalGlyphMetrics[1]) + 1;
+
+ GetPrivateProfileStringA(itemName, "PressedGlyph", "0, 0, 0, 0", szBuffer, 1000, file);
+ sscanf(szBuffer, "%d,%d,%d,%d", &tmpItem.pressedGlyphMetrics[0], &tmpItem.pressedGlyphMetrics[1],
+ &tmpItem.pressedGlyphMetrics[2], &tmpItem.pressedGlyphMetrics[3]);
+ tmpItem.pressedGlyphMetrics[2] = (tmpItem.pressedGlyphMetrics[2] - tmpItem.pressedGlyphMetrics[0]) + 1;
+ tmpItem.pressedGlyphMetrics[3] = (tmpItem.pressedGlyphMetrics[3] - tmpItem.pressedGlyphMetrics[1]) + 1;
+
+
+ GetPrivateProfileStringA(itemName, "HoverGlyph", "0, 0, 0, 0", szBuffer, 1000, file);
+ sscanf(szBuffer, "%d,%d,%d,%d", &tmpItem.hoverGlyphMetrics[0], &tmpItem.hoverGlyphMetrics[1],
+ &tmpItem.hoverGlyphMetrics[2], &tmpItem.hoverGlyphMetrics[3]);
+ tmpItem.hoverGlyphMetrics[2] = (tmpItem.hoverGlyphMetrics[2] - tmpItem.hoverGlyphMetrics[0]) + 1;
+ tmpItem.hoverGlyphMetrics[3] = (tmpItem.hoverGlyphMetrics[3] - tmpItem.hoverGlyphMetrics[1]) + 1;
+
+ tmpItem.uId = IDC_TBFIRSTUID - 1;
+
+ GetPrivateProfileStringA(itemName, "Action", "Custom", szBuffer, 1000, file);
+ if(!_stricmp(szBuffer, "service")) {
+ tmpItem.szService[0] = 0;
+ GetPrivateProfileStringA(itemName, "Service", "None", szBuffer, 1000, file);
+ if(_stricmp(szBuffer, "None")) {
+ mir_snprintf(tmpItem.szService, 256, "%s", szBuffer);
+ tmpItem.dwFlags |= BUTTON_ISSERVICE;
+ tmpItem.uId = nextButtonID++;
+ }
+ }
+ else if(!_stricmp(szBuffer, "protoservice")) {
+ tmpItem.szService[0] = 0;
+ GetPrivateProfileStringA(itemName, "Service", "None", szBuffer, 1000, file);
+ if(_stricmp(szBuffer, "None")) {
+ mir_snprintf(tmpItem.szService, 256, "%s", szBuffer);
+ tmpItem.dwFlags |= BUTTON_ISPROTOSERVICE;
+ tmpItem.uId = nextButtonID++;
+ }
+ }
+ else if(!_stricmp(szBuffer, "database")) {
+ int n;
+
+ GetPrivateProfileStringA(itemName, "Module", "None", szBuffer, 1000, file);
+ if(_stricmp(szBuffer, "None"))
+ mir_snprintf(tmpItem.szModule, 256, "%s", szBuffer);
+ GetPrivateProfileStringA(itemName, "Setting", "None", szBuffer, 1000, file);
+ if(_stricmp(szBuffer, "None"))
+ mir_snprintf(tmpItem.szSetting, 256, "%s", szBuffer);
+ if(GetPrivateProfileIntA(itemName, "contact", 0, file) != 0)
+ tmpItem.dwFlags |= BUTTON_DBACTIONONCONTACT;
+
+ for(n = 0; n <= 1; n++) {
+ char szKey[20];
+ BYTE *pValue;
+
+ strcpy(szKey, n == 0 ? "dbonpush" : "dbonrelease");
+ pValue = (n == 0 ? tmpItem.bValuePush : tmpItem.bValueRelease);
+
+ GetPrivateProfileStringA(itemName, szKey, "None", szBuffer, 1000, file);
+ switch(szBuffer[0]) {
+ case 'b':
+ {
+ BYTE value = (BYTE)atol(&szBuffer[1]);
+ pValue[0] = value;
+ tmpItem.type = DBVT_BYTE;
+ break;
+ }
+ case 'w':
+ {
+ WORD value = (WORD)atol(&szBuffer[1]);
+ *((WORD *)&pValue[0]) = value;
+ tmpItem.type = DBVT_WORD;
+ break;
+ }
+ case 'd':
+ {
+ DWORD value = (DWORD)atol(&szBuffer[1]);
+ *((DWORD *)&pValue[0]) = value;
+ tmpItem.type = DBVT_DWORD;
+ break;
+ }
+ case 's':
+ {
+ mir_snprintf((char *)pValue, 256, &szBuffer[1]);
+ tmpItem.type = DBVT_ASCIIZ;
+ break;
+ }
+ }
+ }
+ if(tmpItem.szModule[0] && tmpItem.szSetting[0]) {
+ tmpItem.dwFlags |= BUTTON_ISDBACTION;
+ if(tmpItem.szModule[0] == '$' && (tmpItem.szModule[1] == 'c' || tmpItem.szModule[1] == 'C'))
+ tmpItem.dwFlags |= BUTTON_ISCONTACTDBACTION;
+ tmpItem.uId = nextButtonID++;
+ }
+ }
+ else if(_stricmp(szBuffer, "Custom")) {
+ int i = 0;
+
+ while(top_buttons[i].id) {
+ if(!_stricmp(top_buttons[i].szIcoLibIcon, szBuffer)) {
+ tmpItem.uId = top_buttons[i].id;
+ tmpItem.dwFlags |= BUTTON_ISINTERNAL;
+ break;
+ }
+ i++;
+ }
+ }
+ GetPrivateProfileStringA(itemName, "PassContact", "None", szBuffer, 1000, file);
+ if(_stricmp(szBuffer, "None")) {
+ if(szBuffer[0] == 'w' || szBuffer[0] == 'W')
+ tmpItem.dwFlags |= BUTTON_PASSHCONTACTW;
+ else if(szBuffer[0] == 'l' || szBuffer[0] == 'L')
+ tmpItem.dwFlags |= BUTTON_PASSHCONTACTL;
+ }
+
+ GetPrivateProfileStringA(itemName, "Tip", "None", szBuffer, 1000, file);
+ if(strcmp(szBuffer, "None")) {
+#if defined(_UNICODE)
+ MultiByteToWideChar(cfg::dat.langPackCP, 0, szBuffer, -1, tmpItem.szTip, 256);
+ tmpItem.szTip[255] = 0;
+#else
+ mir_snprintf(tmpItem.szTip, 256, "%s", szBuffer);
+#endif
+ }
+ else
+ tmpItem.szTip[0] = 0;
+
+ // create it
+
+ newItem = (ButtonItem *)malloc(sizeof(ButtonItem));
+ ZeroMemory(newItem, sizeof(ButtonItem));
+ if(g_ButtonItems == NULL) {
+ g_ButtonItems = newItem;
+ *newItem = tmpItem;
+ newItem->nextItem = 0;
+ }
+ else {
+ ButtonItem *curItem = g_ButtonItems;
+ while(curItem->nextItem)
+ curItem = curItem->nextItem;
+ *newItem = tmpItem;
+ newItem->nextItem = 0;
+ curItem->nextItem = newItem;
+ }
+ newItem->hWnd = CreateWindowEx(0, _T("CLCButtonClass"), _T(""), BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 5, 5, pcli->hwndContactList, (HMENU)newItem->uId, g_hInst, NULL);
+ SendMessage(newItem->hWnd, BM_SETBTNITEM, 0, (LPARAM)newItem);
+ SendMessage(newItem->hWnd, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(newItem->hWnd, BUTTONSETASFLATBTN + 10, 0, 0);
+ if(newItem->dwFlags & BUTTON_ISTOGGLE)
+ SendMessage(newItem->hWnd, BUTTONSETASPUSHBTN, 0, 0);
+
+ if(newItem->szTip[0])
+ SendMessage(newItem->hWnd, BUTTONADDTOOLTIP, (WPARAM)newItem->szTip, 0);
+ return;
+}
+
+void IMG_LoadItems()
+{
+ char *szSections = NULL;
+ char *p;
+ DBVARIANT dbv;
+ char szFileName[MAX_PATH];
+ TCHAR tszFileName[MAX_PATH];
+ int i = 0;
+
+ if(cfg::getTString(NULL, "CLC", "AdvancedSkin", &dbv))
+ return;
+
+ MY_pathToAbsolute(dbv.ptszVal, tszFileName);
+
+ /* TODO
+ * rewrite the skin loading in TCHAR manner
+ */
+
+#if defined(_UNICODE)
+ WideCharToMultiByte(CP_ACP, 0, tszFileName, MAX_PATH, szFileName, MAX_PATH, 0, 0);
+#endif
+
+ DBFreeVariant(&dbv);
+
+ if(!PathFileExists(tszFileName))
+ return;
+
+ IMG_DeleteItems();
+
+ szSections = reinterpret_cast<char *>(malloc(3002));
+ ZeroMemory(szSections, 3002);
+ p = szSections;
+ GetPrivateProfileSectionNamesA(szSections, 3000, szFileName);
+
+ szSections[3001] = szSections[3000] = 0;
+ p = szSections;
+ while(lstrlenA(p) > 1) {
+ if(p[0] == '$' || p[0] == '@')
+ IMG_ReadItem(p, szFileName);
+ p += (lstrlenA(p) + 1);
+ }
+ nextButtonID = IDC_TBFIRSTUID;
+ p = szSections;
+ while(lstrlenA(p) > 1) {
+ if(p[0] == '!')
+ BTN_ReadItem(p, szFileName);
+ p += (lstrlenA(p) + 1);
+ }
+ if(pcli && pcli->hwndContactList)
+ SetButtonStates(pcli->hwndContactList);
+ free(szSections);
+
+ if(g_ButtonItems) {
+ while(top_buttons[i].id) {
+ if(top_buttons[i].hwnd != 0 && top_buttons[i].id != IDC_TBGLOBALSTATUS && top_buttons[i].id != IDC_TBMENU) {
+ DestroyWindow(top_buttons[i].hwnd);
+ top_buttons[i].hwnd = 0;
+ }
+ i++;
+ }
+ cfg::dat.dwFlags &= ~CLUI_FRAME_SHOWTOPBUTTONS;
+ ConfigureCLUIGeometry(0);
+ }
+ if(g_ImageItems) {
+ cfg::writeByte("CLCExt", "bskinned", 1);
+ SetButtonToSkinned();
+ }
+ if(g_CLUIImageItem) {
+ cfg::dat.bFullTransparent = TRUE;
+ cfg::dat.dwFlags &= ~CLUI_FRAME_CLISTSUNKEN;
+ cfg::writeByte("CLUI", "fulltransparent", (BYTE)cfg::dat.bFullTransparent);
+ cfg::writeByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_NOBORDER);
+ ApplyCLUIBorderStyle(pcli->hwndContactList);
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED);
+ API::SetLayeredWindowAttributes(pcli->hwndContactList, cfg::dat.colorkey, 0, LWA_COLORKEY);
+ }
+ CoolSB_SetupScrollBar();
+}
+
+void LoadPerContactSkins(TCHAR *tszFileName)
+{
+ char *p, *szProto, *uid, szItem[100];
+ char *szSections = reinterpret_cast<char *>(malloc(3002));
+ StatusItems_t *items = NULL, *this_item;
+ HANDLE hContact;
+ int i = 1;
+#if defined(_UNICODE)
+ char file[MAX_PATH];
+ WideCharToMultiByte(CP_ACP, 0, tszFileName, MAX_PATH, file, MAX_PATH, 0, 0);
+ file[MAX_PATH - 1] = 0;
+#else
+ char *file = tszFileName;
+#endif
+
+ ReadItem(&default_item, "%Default", file);
+ ZeroMemory(szSections, 3000);
+ p = szSections;
+ GetPrivateProfileSectionNamesA(szSections, 3000, file);
+ szSections[3001] = szSections[3000] = 0;
+ p = szSections;
+ while(lstrlenA(p) > 1) {
+ if(p[0] == '%') {
+ p += (lstrlenA(p) + 1);
+ continue;
+ }
+ items = reinterpret_cast<StatusItems_t *>(realloc(items, i * sizeof(StatusItems_t)));
+ ZeroMemory(&items[i - 1], sizeof(StatusItems_t));
+ this_item = &items[i - 1];
+ GetPrivateProfileStringA(p, "Proto", "", this_item->szName, 40, file);
+ this_item->szName[39] = 0;
+ GetPrivateProfileStringA(p, "UIN", "", this_item->szDBname, 40, file);
+ this_item->szDBname[39] = 0;
+ this_item->IGNORED = 0;
+ GetPrivateProfileStringA(p, "Item", "", szItem, 100, file);
+ szItem[99] = 0;
+ //_DebugPopup(0, "Section: %s -> %s", p, szItem);
+ ReadItem(this_item, szItem, file);
+ p += (lstrlenA(p) + 1);
+ i++;
+ }
+
+ if(items) {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact) {
+ char UIN[40];
+ int j;
+
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(szProto) {
+ uid = (char *)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if ((INT_PTR) uid != CALLSERVICE_NOTFOUND && uid != NULL) {
+ DBVARIANT dbv = {0};
+
+ DBGetContactSetting(hContact, szProto, uid, &dbv);
+ switch(dbv.type) {
+ case DBVT_DWORD:
+ mir_snprintf(UIN, 40, "%d", dbv.dVal);
+ break;
+ case DBVT_ASCIIZ:
+ mir_snprintf(UIN, 40, "%s", dbv.pszVal);
+ DBFreeVariant(&dbv);
+ break;
+ default:
+ UIN[0] = 0;
+ break;
+ }
+ for(j = 0; j < i - 1; j++) {
+ if(!strcmp(szProto, items[j].szName) && !strcmp(UIN, items[j].szDBname)
+ && lstrlenA(szProto) == lstrlenA(items[j].szName) && lstrlenA(UIN) == lstrlenA(items[j].szDBname)) {
+
+ //_DebugPopup(hContact, "Found: %s, %s", szProto, UIN);
+ cfg::writeDword(hContact, "EXTBK", "TEXT", items[j].TEXTCOLOR);
+ cfg::writeDword(hContact, "EXTBK", "COLOR1", items[j].COLOR);
+ cfg::writeDword(hContact, "EXTBK", "COLOR2", items[j].COLOR2);
+ cfg::writeByte(hContact, "EXTBK", "ALPHA", (BYTE)items[j].ALPHA);
+
+ cfg::writeByte(hContact, "EXTBK", "LEFT", (BYTE)items[j].MARGIN_LEFT);
+ cfg::writeByte(hContact, "EXTBK", "RIGHT", (BYTE)items[j].MARGIN_RIGHT);
+ cfg::writeByte(hContact, "EXTBK", "TOP", (BYTE)items[j].MARGIN_TOP);
+ cfg::writeByte(hContact, "EXTBK", "BOTTOM", (BYTE)items[j].MARGIN_BOTTOM);
+
+ cfg::writeByte(hContact, "EXTBK", "TRANS", items[j].COLOR2_TRANSPARENT);
+ cfg::writeDword(hContact, "EXTBK", "BDR", items[j].BORDERSTYLE);
+
+ cfg::writeByte(hContact, "EXTBK", "CORNER", items[j].CORNER);
+ cfg::writeByte(hContact, "EXTBK", "GRAD", items[j].GRADIENT);
+ cfg::writeByte(hContact, "EXTBK", "TRANS", items[j].COLOR2_TRANSPARENT);
+
+ cfg::writeByte(hContact, "EXTBK", "VALID", 1);
+ break;
+ }
+ }
+ if(j == i - 1) { // disable the db copy if it has been disabled in the skin .ini file
+ if(cfg::getByte(hContact, "EXTBK", "VALID", 0))
+ cfg::writeByte(hContact, "EXTBK", "VALID", 0);
+ }
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ }
+ free(szSections);
+ free(items);
+}
+
+void extbk_import(char *file, HWND hwndDlg)
+{
+ int n, i;
+ char buffer[255];
+ char szKey[255], szSection[255];
+ DWORD data, version = 0;
+ int oldexIconScale = cfg::dat.exIconScale;
+
+ for (n = 0; n <= ID_EXTBK_LAST - ID_STATUS_OFFLINE; n++) {
+ if (StatusItems[n].statusID != ID_EXTBKSEPARATOR) {
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_ALPHA");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].ALPHA), sizeof(StatusItems[n].ALPHA), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].COLOR), sizeof(StatusItems[n].COLOR), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].COLOR2), sizeof(StatusItems[n].COLOR2), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_COLOR2_TRANSPARENT");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].COLOR2_TRANSPARENT), sizeof(StatusItems[n].COLOR2_TRANSPARENT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_TEXTCOLOR");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].TEXTCOLOR), sizeof(StatusItems[n].TEXTCOLOR), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_CORNER");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].CORNER), sizeof(StatusItems[n].CORNER), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_GRADIENT");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].GRADIENT), sizeof(StatusItems[n].GRADIENT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_IGNORED");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].IGNORED), sizeof(StatusItems[n].IGNORED), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_BOTTOM");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_BOTTOM), sizeof(StatusItems[n].MARGIN_BOTTOM), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_LEFT");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_LEFT), sizeof(StatusItems[n].MARGIN_LEFT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_RIGHT");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_RIGHT), sizeof(StatusItems[n].MARGIN_RIGHT), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_MARGIN_TOP");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].MARGIN_TOP), sizeof(StatusItems[n].MARGIN_TOP), file);
+ lstrcpyA(buffer, StatusItems[n].szDBname); lstrcatA(buffer, "_BORDERSTYLE");
+ GetPrivateProfileStructA("ExtBKSettings", buffer, &(StatusItems[n].BORDERSTYLE), sizeof(StatusItems[n].BORDERSTYLE), file);
+ }
+ }
+
+ data = 0;
+ GetPrivateProfileStructA("Global", "Version", &version, 4, file);
+ if(version >= 2) {
+ for(n = 0; n <= FONTID_LAST; n++) {
+ mir_snprintf(szSection, 255, "Font%d", n);
+
+ mir_snprintf(szKey, 255, "Font%dName", n);
+ GetPrivateProfileStringA(szSection, "Name", "Arial", buffer, sizeof(buffer), file);
+ cfg::writeString(NULL, "CLC", szKey, buffer);
+
+ mir_snprintf(szKey, 255, "Font%dSize", n);
+ data = 0;
+ GetPrivateProfileStructA(szSection, "Size", &data, 1, file);
+ cfg::writeByte("CLC", szKey, (BYTE)data);
+
+ mir_snprintf(szKey, 255, "Font%dSty", n);
+ data = 0;
+ GetPrivateProfileStructA(szSection, "Style", &data, 1, file);
+ cfg::writeByte("CLC", szKey, (BYTE)data);
+
+ mir_snprintf(szKey, 255, "Font%dSet", n);
+ data = 0;
+ GetPrivateProfileStructA(szSection, "Set", &data, 1, file);
+ cfg::writeByte("CLC", szKey, (BYTE)data);
+
+ mir_snprintf(szKey, 255, "Font%dCol", n);
+ data = 0;
+ GetPrivateProfileStructA(szSection, "Color", &data, 4, file);
+ cfg::writeDword("CLC", szKey, data);
+
+ mir_snprintf(szKey, 255, "Font%dFlags", n);
+ data = 0;
+ GetPrivateProfileStructA(szSection, "Flags", &data, 4, file);
+ cfg::writeDword("CLC", szKey, (WORD)data);
+
+ mir_snprintf(szKey, 255, "Font%dAs", n);
+ data = 0;
+ GetPrivateProfileStructA(szSection, "SameAs", &data, 2, file);
+ cfg::writeDword("CLC", szKey, (WORD)data);
+ }
+ }
+ i = 0;
+ if(version >= 3) {
+ char szString[MAX_PATH];
+ szString[0] = 0;
+
+ while(_tagSettings[i].szModule != NULL) {
+ data = 0;
+ GetPrivateProfileStructA("Global", _tagSettings[i].szSetting, &data, _tagSettings[i].size, file);
+ switch(_tagSettings[i].size) {
+ case 1:
+ cfg::writeByte(NULL, _tagSettings[i].szModule, _tagSettings[i].szSetting, (BYTE)data);
+ break;
+ case 4:
+ cfg::writeDword(NULL, _tagSettings[i].szModule, _tagSettings[i].szSetting, data);
+ break;
+ case 2:
+ cfg::writeWord( _tagSettings[i].szModule, _tagSettings[i].szSetting, (WORD)data);
+ break;
+ }
+ i++;
+ }
+ GetPrivateProfileStringA("Global", "BkBitmap", "", szString, MAX_PATH, file);
+ if(lstrlenA(szString) > 0)
+ cfg::writeString(NULL, "CLC", "BkBitmap", szString);
+ }
+
+ Reload3dBevelColors();
+ ReloadThemedOptions();
+ SetTBSKinned(cfg::dat.bSkinnedToolbar);
+ // refresh
+ if(hwndDlg && ServiceExists(MS_CLNSE_FILLBYCURRENTSEL))
+ CallService(MS_CLNSE_FILLBYCURRENTSEL, (WPARAM)hwndDlg, 0);
+ pcli->pfnClcOptionsChanged();
+ ConfigureCLUIGeometry(1);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ RedrawWindow(pcli->hwndContactList,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_FRAME|RDW_UPDATENOW|RDW_ALLCHILDREN);
+ if(oldexIconScale != cfg::dat.exIconScale) {
+ ImageList_SetIconSize(himlExtraImages, cfg::dat.exIconScale, cfg::dat.exIconScale);
+ if(cfg::dat.IcoLib_Avail)
+ IcoLibReloadIcons();
+ else {
+ CLN_LoadAllIcons(0);
+ //FYR: may be better to call pfnReloadProtoMenus
+ pcli->pfnReloadProtoMenus();
+ //FYR: Not necessary. It is already notified in pfnReloadProtoMenus
+ //NotifyEventHooks(pcli->hPreBuildStatusMenuEvent, 0, 0);
+ ReloadExtraIcons();
+ }
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ }
+}
+
+static void ApplyCLUISkin()
+{
+ DBVARIANT dbv = {0};
+ TCHAR tszFinalName[MAX_PATH];
+ char szFinalName[MAX_PATH];
+ if(!cfg::getTString(NULL, "CLC", "AdvancedSkin", &dbv)) {
+ MY_pathToAbsolute(dbv.ptszVal, tszFinalName);
+#if defined(_UNICODE)
+ WideCharToMultiByte(CP_ACP, 0, tszFinalName, MAX_PATH, szFinalName, MAX_PATH, 0, 0);
+#else
+ mir_sntprintf(szFinalName, MAX_PATH, _T("%s"), tszFinalName);
+#endif
+ if(cfg::getByte("CLUI", "skin_changed", 0)) {
+ extbk_import(szFinalName, 0);
+ SaveCompleteStructToDB();
+ cfg::writeByte("CLUI", "skin_changed", 0);
+ }
+ IMG_LoadItems();
+ ShowWindow(pcli->hwndContactList, SW_SHOWNORMAL);
+ SetWindowPos(pcli->hwndContactList, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_ERASE);
+ DBFreeVariant(&dbv);
+ }
+}
+
+static INT_PTR CALLBACK DlgProcSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ TranslateDialogDefault(hwndDlg);
+
+ CheckDlgButton(hwndDlg, IDC_EQUALSELECTION, (cfg::getByte("CLCExt", "EXBK_EqualSelection", 1) == 1) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SELBLEND, cfg::getByte("CLCExt", "EXBK_SelBlend", 1));
+ CheckDlgButton(hwndDlg, IDC_SETALLBUTTONSKINNED, cfg::getByte("CLCExt", "bskinned", 0));
+
+ SendDlgItemMessage(hwndDlg, IDC_CORNERSPIN, UDM_SETRANGE, 0, MAKELONG(10, 0));
+ SendDlgItemMessage(hwndDlg, IDC_CORNERSPIN, UDM_SETPOS, 0, cfg::dat.cornerRadius);
+
+ SendDlgItemMessage(hwndDlg, IDC_GRPPADDINGSPIN, UDM_SETRANGE, 0, MAKELONG(20, 0));
+ SendDlgItemMessage(hwndDlg, IDC_GRPPADDINGSPIN, UDM_SETPOS, 0, cfg::dat.group_padding);
+
+ SendDlgItemMessage(hwndDlg, IDC_LASTITEMPADDINGSPIN, UDM_SETRANGE, 0, MAKELONG(40, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LASTITEMPADDINGSPIN, UDM_SETPOS, 0, cfg::dat.titleBarHeight);
+
+ CheckDlgButton(hwndDlg, IDC_APPLYINDENTBG, cfg::dat.bApplyIndentToBg);
+ CheckDlgButton(hwndDlg, IDC_USEPERPROTO, cfg::dat.bUsePerProto);
+ CheckDlgButton(hwndDlg, IDC_OVERRIDEPERSTATUSCOLOR, cfg::dat.bOverridePerStatusColors);
+ CheckDlgButton(hwndDlg, IDC_FASTGRADIENT, cfg::dat.bWantFastGradients);
+ CheckDlgButton(hwndDlg, IDC_IGNORESELFORGROUPS, cfg::getByte("CLC", "IgnoreSelforGroups", 0) ? BST_CHECKED : BST_UNCHECKED);
+
+
+ if(!cfg::getString(NULL, "CLC", "ContactSkins", &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_SKINFILE, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ Utils::enableDlgControl(hwndDlg, IDC_RELOAD, TRUE);
+ }
+ else
+ Utils::enableDlgControl(hwndDlg, IDC_RELOAD, FALSE);
+ CheckDlgButton(hwndDlg, IDC_USESKIN, cfg::getByte("CLUI", "useskin", 0) ? BST_CHECKED : BST_UNCHECKED);
+ if(!cfg::getTString(NULL, "CLC", "AdvancedSkin", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_SKINFILENAME, dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ SetDlgItemText(hwndDlg, IDC_SKINFILENAME, _T(""));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_USESKIN:
+ {
+ int useskin = IsDlgButtonChecked(hwndDlg, IDC_USESKIN);
+
+ cfg::writeByte("CLUI", "useskin", (BYTE)(useskin ? 1 : 0));
+ break;
+ }
+ case IDC_UNLOAD:
+ IMG_DeleteItems();
+ CreateButtonBar(pcli->hwndContactList);
+ if(cfg::dat.bSkinnedToolbar)
+ SetTBSKinned(1);
+ ConfigureFrame();
+ SetButtonStates(pcli->hwndContactList);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ break;
+ case IDC_SELECTSKINFILE:
+ {
+ OPENFILENAME ofn = {0};
+ TCHAR str[MAX_PATH] = _T("*.clist"), final_path[MAX_PATH];
+
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ ofn.hInstance = NULL;
+ ofn.lpstrFilter = _T("*.clist\0");
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_DONTADDTORECENT;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = _T("");
+ if (!GetOpenFileName(&ofn))
+ break;
+ MY_pathToRelative(str, final_path);
+ if(PathFileExists(str)) {
+ int skinChanged = 0;
+ DBVARIANT dbv = {0};
+
+ if(!cfg::getTString(NULL, "CLC", "AdvancedSkin", &dbv)) {
+ if(_tcscmp(dbv.ptszVal, final_path))
+ skinChanged = TRUE;
+ DBFreeVariant(&dbv);
+ }
+ else
+ skinChanged = TRUE;
+ cfg::writeTString(NULL, "CLC", "AdvancedSkin", final_path);
+ cfg::writeByte("CLUI", "skin_changed", (BYTE)skinChanged);
+ SetDlgItemText(hwndDlg, IDC_SKINFILENAME, final_path);
+ }
+ break;
+ }
+ case IDC_RELOADSKIN:
+ cfg::writeByte("CLUI", "skin_changed", 1);
+ ApplyCLUISkin();
+ break;
+ case IDC_RELOAD:
+ {
+ TCHAR tszFilename[MAX_PATH], tszFinalPath[MAX_PATH];
+
+ GetDlgItemText(hwndDlg, IDC_SKINFILE, tszFilename, MAX_PATH);
+ tszFilename[MAX_PATH - 1] = 0;
+ MY_pathToAbsolute(tszFilename, tszFinalPath);
+ if(PathFileExists(tszFinalPath)) {
+ LoadPerContactSkins(tszFinalPath);
+ ReloadSkinItemsToCache();
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ }
+ break;
+ }
+ }
+ if ((LOWORD(wParam) == IDC_SKINFILE || LOWORD(wParam) == IDC_SKINFILENAME)
+ && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ SaveNonStatusItemsSettings(hwndDlg);
+ pcli->pfnClcOptionsChanged();
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int iInit = TRUE;
+ static HWND hwndSkinEdit = 0;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEM tci;
+ RECT rcClient;
+ int oPage = cfg::getByte("CLUI", "opage", 0);
+ SKINDESCRIPTION sd;
+
+ TranslateDialogDefault(hwnd);
+ GetClientRect(hwnd, &rcClient);
+ iInit = TRUE;
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+ tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SKIN), hwnd, DlgProcSkinOpts);
+ tci.pszText = TranslateT("Load and apply");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci);
+ MoveWindow((HWND)tci.lParam,5,25,rcClient.right-9,rcClient.bottom-60,1);
+ ShowWindow((HWND)tci.lParam, oPage == 0 ? SW_SHOW : SW_HIDE);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ if(ServiceExists(MS_CLNSE_INVOKE)) {
+ ZeroMemory(&sd, sizeof(sd));
+ sd.cbSize = sizeof(sd);
+ sd.StatusItems = StatusItems;
+ sd.hWndParent = hwnd;
+ sd.hWndTab = GetDlgItem(hwnd, IDC_OPTIONSTAB);
+ sd.pfnSaveCompleteStruct = SaveCompleteStructToDB;
+ sd.lastItem = ID_EXTBK_LAST;
+ sd.firstItem = ID_STATUS_OFFLINE;
+ sd.pfnClcOptionsChanged = pcli->pfnClcOptionsChanged;
+ sd.hwndCLUI = pcli->hwndContactList;
+ hwndSkinEdit = (HWND)CallService(MS_CLNSE_INVOKE, 0, (LPARAM)&sd);
+ }
+
+ if(hwndSkinEdit) {
+ ShowWindow(hwndSkinEdit, oPage == 1 ? SW_SHOW : SW_HIDE);
+ TabCtrl_SetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB), oPage);
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture(hwndSkinEdit, ETDT_ENABLETAB);
+ }
+
+ TabCtrl_SetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB), oPage);
+ Utils::enableDlgControl(hwnd, IDC_EXPORT, TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)) != 0);
+ Utils::enableDlgControl(hwnd, IDC_IMPORT, TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)) != 0);
+ iInit = FALSE;
+ return FALSE;
+ }
+
+ case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0);
+ if(!iInit)
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_EXPORT:
+ {
+ char str[MAX_PATH] = "*.clist";
+ OPENFILENAMEA ofn = {0};
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwnd;
+ ofn.hInstance = NULL;
+ ofn.lpstrFilter = "*.clist";
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_HIDEREADONLY;
+ ofn.nMaxFile = sizeof(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = "clist";
+ if (!GetSaveFileNameA(&ofn))
+ break;
+ extbk_export(str);
+ break;
+ }
+ case IDC_IMPORT:
+ {
+ char str[MAX_PATH] = "*.clist";
+ OPENFILENAMEA ofn = {0};
+
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwnd;
+ ofn.hInstance = NULL;
+ ofn.lpstrFilter = "*.clist";
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST;
+ ofn.nMaxFile = sizeof(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = "";
+ if (!GetOpenFileNameA(&ofn))
+ break;
+ extbk_import(str, hwndSkinEdit);
+ SendMessage(hwndSkinEdit, WM_USER + 101, 0, 0);
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ TCITEM tci;
+ int i,count;
+ tci.mask = TCIF_PARAM;
+ count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB));
+ for (i=0;i<count;i++)
+ {
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),i,&tci);
+ SendMessage((HWND)tci.lParam,WM_NOTIFY,0,lParam);
+ }
+ }
+ break;
+ }
+ break;
+ case IDC_OPTIONSTAB:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGING:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_HIDE);
+ }
+ break;
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_SHOW);
+ cfg::writeByte("CLUI", "opage", (BYTE)TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)));
+ Utils::enableDlgControl(hwnd, IDC_EXPORT, TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)) != 0);
+ Utils::enableDlgControl(hwnd, IDC_IMPORT, TabCtrl_GetCurSel(GetDlgItem(hwnd, IDC_OPTIONSTAB)) != 0);
+ }
+ break;
+ }
+ break;
+
+ }
+ break;
+ case WM_DESTROY:
+ hwndSkinEdit = 0;
+ break;
+ }
+ return FALSE;
+}
+
+int CoolSB_SetupScrollBar()
+{
+ /*
+ * a skinned scrollbar is only valid when ALL items are skinned with image items
+ * and no item is set to ignored
+ */
+
+ cfg::dat.bSkinnedScrollbar = !StatusItems[ID_EXTBKSCROLLBACK - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLBACKLOWER - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLTHUMB - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLTHUMBHOVER - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLTHUMBPRESSED - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLBUTTON - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLBUTTONHOVER - ID_STATUS_OFFLINE].IGNORED &&
+ !StatusItems[ID_EXTBKSCROLLBUTTONPRESSED - ID_STATUS_OFFLINE].IGNORED;
+
+
+ if(!StatusItems[ID_EXTBKSCROLLBACK - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLBACKLOWER - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLTHUMB - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLTHUMBHOVER - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLTHUMBPRESSED - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLBUTTON - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLBUTTONHOVER - ID_STATUS_OFFLINE].imageItem ||
+ !StatusItems[ID_EXTBKSCROLLBUTTONPRESSED - ID_STATUS_OFFLINE].imageItem)
+
+ cfg::dat.bSkinnedScrollbar = FALSE;
+
+ if(cfg::getByte("CLC", "NoVScrollBar", 0)) {
+ UninitializeCoolSB(pcli->hwndContactTree);
+ return 0;
+ }
+ if(cfg::dat.bSkinnedScrollbar) {
+ InitializeCoolSB(pcli->hwndContactTree);
+ CoolSB_SetStyle(pcli->hwndContactTree, SB_VERT, CSBS_HOTTRACKED);
+ }
+ else
+ UninitializeCoolSB(pcli->hwndContactTree);
+ return 0;
+}
diff --git a/plugins/Clist_nicer/SRC/init.cpp b/plugins/Clist_nicer/SRC/init.cpp
new file mode 100644
index 0000000000..59ada8931b
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/init.cpp
@@ -0,0 +1,416 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: init.cpp 13596 2011-04-15 19:07:23Z george.hazan $
+ *
+ */
+
+#include <commonheaders.h>
+#include "../cluiframes/cluiframes.h"
+
+HINSTANCE g_hInst = 0;
+PLUGINLINK *pluginLink;
+CLIST_INTERFACE* pcli = NULL;
+int hLangpack;
+
+#define DEFAULT_TB_VISIBILITY (1 | 2 | 4 | 8 | 16 | 32 | 64 | 8192)
+TCHAR *szNoevents = _T("No events...");
+//extern HICON im_clienthIcons[NR_CLIENTS];
+extern HICON overlayicons[10];
+
+extern int Docking_ProcessWindowMessage(WPARAM wParam, LPARAM lParam);
+extern int SetHideOffline(WPARAM wParam, LPARAM lParam);
+
+extern DWORD g_gdiplusToken;
+extern HIMAGELIST himlExtraImages;
+
+struct LIST_INTERFACE li;
+struct MM_INTERFACE mmi;
+TIME_API tmi;
+
+HMENU BuildGroupPopupMenu( struct ClcGroup* group );
+struct ClcContact* CreateClcContact( void );
+struct CListEvent* fnCreateEvent( void );
+void ReloadThemedOptions();
+void TrayIconUpdateBase(const char *szChangedProto);
+void RegisterCLUIFrameClasses();
+
+void GetDefaultFontSetting(int i, LOGFONT *lf, COLORREF *colour);
+int GetWindowVisibleState(HWND hWnd, int iStepX, int iStepY);
+int ShowHide(WPARAM wParam, LPARAM lParam);
+int ClcShutdown(WPARAM wParam, LPARAM lParam);
+
+void ( *saveLoadClcOptions )(HWND hwnd,struct ClcData *dat);
+void LoadClcOptions(HWND hwnd,struct ClcData *dat);
+
+int ( *saveAddContactToGroup )(struct ClcData *dat, struct ClcGroup *group, HANDLE hContact);
+int AddContactToGroup(struct ClcData *dat, struct ClcGroup *group, HANDLE hContact);
+
+struct ClcGroup* ( *saveRemoveItemFromGroup )(HWND hwnd, struct ClcGroup *group, struct ClcContact *contact, int updateTotalCount);
+struct ClcGroup* RemoveItemFromGroup(HWND hwnd, struct ClcGroup *group, struct ClcContact *contact, int updateTotalCount);
+
+struct CListEvent* ( *saveAddEvent )(CLISTEVENT *cle);
+struct CListEvent* AddEvent(CLISTEVENT *cle);
+
+int ( *saveAddInfoItemToGroup )(struct ClcGroup *group, int flags, const TCHAR *pszText);
+int AddInfoItemToGroup(struct ClcGroup *group, int flags, const TCHAR *pszText);
+
+struct ClcGroup* ( *saveAddGroup )(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers);
+struct ClcGroup* AddGroup(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers);
+
+LRESULT ( CALLBACK *saveContactListWndProc )(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK ContactListWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+LRESULT ( CALLBACK *saveContactListControlWndProc )(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK ContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int ( *saveIconFromStatusMode )( const char *szProto, int status, HANDLE hContact );
+
+LRESULT ( *saveProcessExternalMessages )(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam);
+LRESULT ProcessExternalMessages(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int ( *saveRemoveEvent )(HANDLE hContact, HANDLE hDbEvent);
+int RemoveEvent(HANDLE hContact, HANDLE hDbEvent);
+
+INT_PTR ( *saveTrayIconProcessMessage )(WPARAM wParam, LPARAM lParam);
+INT_PTR TrayIconProcessMessage(WPARAM wParam, LPARAM lParam);
+
+void ( *saveRecalcScrollBar )(HWND hwnd, struct ClcData *dat);
+void RecalcScrollBar(HWND hwnd, struct ClcData *dat);
+
+PLUGININFOEX pluginInfo = {
+#if defined(_UNICODE)
+ sizeof(PLUGININFOEX), "CList Nicer+ (Unicode)", PLUGIN_MAKE_VERSION(0, 9, 2, 1),
+#else
+ sizeof(PLUGININFOEX), "CList Nicer+", PLUGIN_MAKE_VERSION(0, 9, 2, 1),
+#endif
+ "Display contacts, event notifications, protocol status",
+ "Pixel, egoDust, cyreve, Nightwish", "", "Copyright 2000-2010 Miranda-IM project", "http://www.miranda-im.org",
+ UNICODE_AWARE,
+ DEFMOD_CLISTALL,
+#if defined(_UNICODE)
+ {0x8f79b4ee, 0xeb48, 0x4a03, { 0x87, 0x3e, 0x27, 0xbe, 0x6b, 0x7e, 0x9a, 0x25 }} //{8F79B4EE-EB48-4a03-873E-27BE6B7E9A25}
+#else
+ {0x5a070cec, 0xb2ab, 0x4bbe, { 0x8e, 0x48, 0x9c, 0x8d, 0xcd, 0xda, 0x14, 0xc3 }} //{5A070CEC-B2AB-4bbe-8E48-9C8DCDDA14C3}
+#endif
+};
+
+#if defined(_UNICODE)
+void _DebugTraceW(const wchar_t *fmt, ...)
+{
+#ifdef _DEBUG
+ wchar_t debug[2048];
+ int ibsize = 2047;
+ va_list va;
+ va_start(va, fmt);
+
+ lstrcpyW(debug, L"CLN: ");
+
+ _vsnwprintf(&debug[5], ibsize - 10, fmt, va);
+ OutputDebugStringW(debug);
+#endif
+}
+#endif
+
+void _DebugTraceA(const char *fmt, ...)
+{
+ char debug[2048];
+ int ibsize = 2047;
+ va_list va;
+ va_start(va, fmt);
+
+ lstrcpyA(debug, "CLN: ");
+ _vsnprintf(&debug[5], ibsize - 10, fmt, va);
+#ifdef _DEBUG
+ OutputDebugStringA(debug);
+#else
+ {
+ char szLogFileName[MAX_PATH], szDataPath[MAX_PATH];
+ FILE *f;
+
+ CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM)szDataPath);
+ mir_snprintf(szLogFileName, MAX_PATH, "%s\\%s", szDataPath, "clist_nicer.log");
+ f = fopen(szLogFileName, "a+");
+ if(f) {
+ fputs(debug, f);
+ fputs("\n", f);
+ fclose(f);
+ }
+ }
+#endif
+}
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved)
+{
+ g_hInst = hInstDLL;
+ DisableThreadLibraryCalls(g_hInst);
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 9, 0, 0)) {
+ MessageBox(0, _T("The installed version of the Clist Nicer+ plugin is not compatible with this Miranda installation. It requires Miranda core 0.9.0.0 or later"), _T("Clist Nicer+ error"), MB_OK);
+ return NULL;
+ }
+ return &pluginInfo;
+}
+
+static const MUUID interfaces[] = {MIID_CLIST, MIID_LAST};
+
+extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+int LoadContactListModule(void);
+int LoadCLCModule(void);
+void LoadCLUIModule( void );
+
+static int systemModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ GetSystemTime(&cfg::dat.st);
+ SystemTimeToFileTime(&cfg::dat.st, &cfg::dat.ft);
+ cfg::dat.bMetaAvail = ServiceExists(MS_MC_GETDEFAULTCONTACT) ? TRUE : FALSE;
+ if(cfg::dat.bMetaAvail)
+ mir_snprintf(cfg::dat.szMetaName, 256, "%s", (char *)CallService(MS_MC_GETPROTOCOLNAME, 0, 0));
+ else
+ strncpy(cfg::dat.szMetaName, "MetaContacts", 255);
+
+ if(ServiceExists(MS_MC_DISABLEHIDDENGROUP))
+ CallService(MS_MC_DISABLEHIDDENGROUP, 1, 0);
+ cfg::dat.bMetaEnabled = cfg::getByte(cfg::dat.szMetaName, "Enabled", 1);
+
+ cfg::dat.bAvatarServiceAvail = ServiceExists(MS_AV_GETAVATARBITMAP) ? TRUE : FALSE;
+ if(cfg::dat.bAvatarServiceAvail)
+ HookEvent(ME_AV_AVATARCHANGED, AvatarChanged);
+ cfg::dat.tabSRMM_Avail = ServiceExists("SRMsg_MOD/GetWindowFlags") ? TRUE : FALSE;
+ cfg::dat.IcoLib_Avail = ServiceExists(MS_SKIN2_ADDICON) ? TRUE : FALSE;
+
+ ZeroMemory((void *)overlayicons, sizeof(HICON) * 10);
+
+ CLN_LoadAllIcons(1);
+ LoadExtBkSettingsFromDB();
+ return 0;
+}
+
+static int fnIconFromStatusMode( const char* szProto, int status, HANDLE hContact )
+{ return IconFromStatusMode( szProto, status, hContact, NULL );
+}
+
+extern "C" int __declspec(dllexport) CListInitialise(PLUGINLINK * link)
+{
+ int rc = 0;
+ DBVARIANT dbv;
+ int i;
+ char szProfilePath[MAX_PATH];
+
+ pluginLink = link;
+#ifdef _DEBUG
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+ mir_getMMI(&mmi);
+ mir_getLI(&li);
+ mir_getTMI(&tmi);
+ mir_getLP( &pluginInfo );
+
+ API::onInit();
+ LoadCLCButtonModule();
+ RegisterCLUIFrameClasses();
+
+ ZeroMemory((void*) &cfg::dat, sizeof(cfg::dat));
+
+ int iCount = CallService(MS_DB_CONTACT_GETCOUNT, 0, 0);
+
+ iCount += 20;
+ if( iCount < 300 )
+ iCount = 300;
+
+ cfg::eCache = reinterpret_cast<TExtraCache *>(malloc(sizeof(TExtraCache) * iCount));
+ ZeroMemory(cfg::eCache, sizeof(struct TExtraCache) * iCount);
+ cfg::nextCacheEntry = 0;
+ cfg::maxCacheEntry = iCount;
+ cfg::init();
+
+ cfg::dat.toolbarVisibility = cfg::getDword("CLUI", "TBVisibility", DEFAULT_TB_VISIBILITY);
+ cfg::dat.hMenuButtons = GetSubMenu(LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)), 3);
+ cfg::dat.hMenuNotify = CreatePopupMenu();
+ cfg::dat.wNextMenuID = 1;
+ cfg::dat.sortTimer = cfg::getDword("CLC", "SortTimer", 150);
+ cfg::dat.szNoEvents = TranslateTS(szNoevents);
+ cfg::dat.avatarBorder = (COLORREF)cfg::getDword("CLC", "avatarborder", 0);
+ cfg::dat.avatarRadius = (COLORREF)cfg::getDword("CLC", "avatarradius", 4);
+ cfg::dat.hBrushAvatarBorder = CreateSolidBrush(cfg::dat.avatarBorder);
+ cfg::dat.avatarSize = cfg::getWord("CList", "AvatarSize", 24);
+ cfg::dat.dualRowMode = cfg::getByte("CLC", "DualRowMode", 0);
+ cfg::dat.avatarPadding = cfg::getByte("CList", "AvatarPadding", 0);
+ cfg::dat.isTransparent = cfg::getByte("CList", "Transparent", 0);
+ cfg::dat.alpha = cfg::getByte("CList", "Alpha", SETTING_ALPHA_DEFAULT);
+ cfg::dat.autoalpha = cfg::getByte("CList", "AutoAlpha", SETTING_ALPHA_DEFAULT);
+ cfg::dat.fadeinout = cfg::getByte("CLUI", "FadeInOut", 0);
+ cfg::dat.autosize = cfg::getByte("CLUI", "AutoSize", 0);
+ cfg::dat.dwExtraImageMask = cfg::getDword("CLUI", "ximgmask", 0);
+ cfg::dat.bNoOfflineAvatars = cfg::getByte("CList", "NoOfflineAV", 1);
+ cfg::dat.bFullTransparent = cfg::getByte("CLUI", "fulltransparent", 0);
+ cfg::dat.bDblClkAvatars = cfg::getByte("CLC", "dblclkav", 0);
+ cfg::dat.bEqualSections = cfg::getByte("CLUI", "EqualSections", 0);
+ cfg::dat.bCenterStatusIcons = cfg::getByte("CLC", "si_centered", 1);
+ cfg::dat.boldHideOffline = -1;
+ cfg::dat.bSecIMAvail = ServiceExists("SecureIM/IsContactSecured") ? 1 : 0;
+ cfg::dat.bNoTrayTips = cfg::getByte("CList", "NoTrayTips", 0);
+ cfg::dat.bShowLocalTime = cfg::getByte("CLC", "ShowLocalTime", 1);
+ cfg::dat.bShowLocalTimeSelective = cfg::getByte("CLC", "SelectiveLocalTime", 1);
+ cfg::dat.bDontSeparateOffline = cfg::getByte("CList", "DontSeparateOffline", 0);
+ cfg::dat.bShowXStatusOnSbar = cfg::getByte("CLUI", "xstatus_sbar", 0);
+ cfg::dat.bLayeredHack = cfg::getByte("CLUI", "layeredhack", 1);
+ cfg::dat.bFirstRun = cfg::getByte("CLUI", "firstrun", 1);
+ cfg::dat.langPackCP = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+ cfg::dat.realTimeSaving = cfg::getByte("CLUI", "save_pos_always", 0);
+
+ DWORD sortOrder = cfg::getDword("CList", "SortOrder", SORTBY_NAME);
+ cfg::dat.sortOrder[0] = LOBYTE(LOWORD(sortOrder));
+ cfg::dat.sortOrder[1] = HIBYTE(LOWORD(sortOrder));
+ cfg::dat.sortOrder[2] = LOBYTE(HIWORD(sortOrder));
+
+ if(cfg::dat.bFirstRun)
+ cfg::writeByte("CLUI", "firstrun", 0);
+
+ if(!cfg::getString(NULL, "CLUI", "exIconOrder", &dbv)) {
+ if(lstrlenA(dbv.pszVal) < EXICON_COUNT) {
+ for(i = 1; i <= EXICON_COUNT; i++)
+ cfg::dat.exIconOrder[i - 1] = i;
+ } else {
+ for(i = 0; i < EXICON_COUNT; i++)
+ if(dbv.pszVal[i] < EXICON_COUNT+1 && dbv.pszVal[i] >0)
+ cfg::dat.exIconOrder[i] = dbv.pszVal[i];
+ else
+ cfg::dat.exIconOrder[i] = i+1;
+ }
+ DBFreeVariant(&dbv);
+ } else {
+ for(i = 1; i <= EXICON_COUNT; i++)
+ cfg::dat.exIconOrder[i - 1] = i;
+ }
+ ReloadThemedOptions();
+ FLT_ReadOptions();
+ Reload3dBevelColors();
+ himlExtraImages = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16), 30, 2);
+ ImageList_SetIconSize(himlExtraImages, cfg::dat.exIconScale, cfg::dat.exIconScale);
+
+ cfg::dat.dwFlags = cfg::getDword("CLUI", "Frameflags", CLUI_FRAME_SHOWTOPBUTTONS | CLUI_FRAME_STATUSICONS |
+ CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_BUTTONSFLAT | CLUI_FRAME_CLISTSUNKEN);
+ cfg::dat.dwFlags |= (cfg::getByte("CLUI", "ShowSBar", 1) ? CLUI_FRAME_SBARSHOW : 0);
+ cfg::dat.soundsOff = cfg::getByte("CLUI", "NoSounds", 0);
+
+ CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM)szProfilePath);
+
+#if defined(_UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, szProfilePath, MAX_PATH, cfg::dat.tszProfilePath, MAX_PATH);
+ cfg::dat.tszProfilePath[MAX_PATH - 1] = 0;
+#else
+ mir_sntprintf(cfg::dat.tszProfilePath, MAX_PATH, "%s", szProfilePath);
+#endif
+
+ _tcslwr(cfg::dat.tszProfilePath);
+
+ if(cfg::getByte("Skin", "UseSound", 0) != cfg::dat.soundsOff)
+ cfg::writeByte("Skin", "UseSound", (BYTE)(cfg::dat.soundsOff ? 0 : 1));
+
+ // get the clist interface
+ pcli = ( CLIST_INTERFACE* )CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, (LPARAM)g_hInst);
+ if ( (INT_PTR)pcli == CALLSERVICE_NOTFOUND ) {
+LBL_Error:
+ MessageBoxA( NULL, "This plugin requires Miranda IM 0.8.0.9 or later", "Fatal error", MB_OK );
+ return 1;
+ }
+ if ( pcli->version < 6 ) // don't join it with the previous if()
+ goto LBL_Error;
+
+ pcli->pfnBuildGroupPopupMenu = BuildGroupPopupMenu;
+ pcli->pfnCluiProtocolStatusChanged = CluiProtocolStatusChanged;
+ pcli->pfnCompareContacts = CompareContacts;
+ pcli->pfnCreateClcContact = CreateClcContact;
+ pcli->pfnCreateEvent = fnCreateEvent;
+ pcli->pfnDocking_ProcessWindowMessage = Docking_ProcessWindowMessage;
+ pcli->pfnGetDefaultFontSetting = GetDefaultFontSetting;
+ pcli->pfnGetRowBottomY = RowHeight::getItemBottomY;
+ pcli->pfnGetRowHeight = RowHeight::getHeight;
+ pcli->pfnGetRowTopY = RowHeight::getItemTopY;
+ pcli->pfnGetRowTotalHeight = RowHeight::getTotalHeight;
+ pcli->pfnGetWindowVisibleState = GetWindowVisibleState;
+ pcli->pfnHitTest = HitTest;
+ pcli->pfnLoadContactTree = LoadContactTree;
+ pcli->pfnOnCreateClc = LoadCLUIModule;
+ pcli->pfnPaintClc = PaintClc;
+ pcli->pfnRebuildEntireList = RebuildEntireList;
+ pcli->pfnRowHitTest = RowHeight::hitTest;
+ pcli->pfnScrollTo = ScrollTo;
+ pcli->pfnTrayIconUpdateBase = TrayIconUpdateBase;
+ pcli->pfnSetHideOffline = SetHideOffline;
+ pcli->pfnShowHide = ShowHide;
+
+ saveAddContactToGroup = pcli->pfnAddContactToGroup; pcli->pfnAddContactToGroup = AddContactToGroup;
+ saveRemoveItemFromGroup = pcli->pfnRemoveItemFromGroup; pcli->pfnRemoveItemFromGroup = RemoveItemFromGroup;
+
+ saveAddEvent = pcli->pfnAddEvent; pcli->pfnAddEvent = AddEvent;
+ saveRemoveEvent = pcli->pfnRemoveEvent; pcli->pfnRemoveEvent = RemoveEvent;
+
+ saveAddGroup = pcli->pfnAddGroup; pcli->pfnAddGroup = AddGroup;
+ saveAddInfoItemToGroup = pcli->pfnAddInfoItemToGroup; pcli->pfnAddInfoItemToGroup = AddInfoItemToGroup;
+ saveContactListControlWndProc = pcli->pfnContactListControlWndProc; pcli->pfnContactListControlWndProc = ContactListControlWndProc;
+ saveContactListWndProc = pcli->pfnContactListWndProc; pcli->pfnContactListWndProc = ContactListWndProc;
+ saveIconFromStatusMode = pcli->pfnIconFromStatusMode; pcli->pfnIconFromStatusMode = fnIconFromStatusMode;
+ saveLoadClcOptions = pcli->pfnLoadClcOptions; pcli->pfnLoadClcOptions = LoadClcOptions;
+ saveProcessExternalMessages = pcli->pfnProcessExternalMessages; pcli->pfnProcessExternalMessages = ProcessExternalMessages;
+ saveRecalcScrollBar = pcli->pfnRecalcScrollBar; pcli->pfnRecalcScrollBar = RecalcScrollBar;
+ saveTrayIconProcessMessage = pcli->pfnTrayIconProcessMessage; pcli->pfnTrayIconProcessMessage = TrayIconProcessMessage;
+
+ rc = LoadContactListModule();
+ if (rc == 0)
+ rc = LoadCLCModule();
+ HookEvent(ME_SYSTEM_MODULESLOADED, systemModulesLoaded);
+ return rc;
+}
+
+// a plugin loader aware of CList exports will never call this.
+extern "C" int __declspec(dllexport) Load(PLUGINLINK * link)
+{
+ return 1;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ if (IsWindow(pcli->hwndContactList))
+ DestroyWindow(pcli->hwndContactList);
+ ImageList_Destroy(himlExtraImages);
+ ClcShutdown(0, 0);
+ UnLoadCLUIFramesModule();
+ return 0;
+}
+
diff --git a/plugins/Clist_nicer/SRC/rowheight_funcs.cpp b/plugins/Clist_nicer/SRC/rowheight_funcs.cpp
new file mode 100644
index 0000000000..bb06013fe0
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/rowheight_funcs.cpp
@@ -0,0 +1,287 @@
+/*
+ * astyle --force-indent=tab=4 --brackets=linux --indent-switches
+ * --pad=oper --one-line=keep-blocks --unpad=paren
+ *
+ * Miranda IM: the free IM client for Microsoft* Windows*
+ *
+ * Copyright 2000-2010 Miranda ICQ/IM project,
+ * all portions of this codebase are copyrighted to the people
+ * listed in contributors.txt.
+ *
+ * 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 clist_nicer plugin for Miranda.
+ *
+ * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
+ *
+ * $Id: rowheight_funcs.cpp 12484 2010-08-27 04:02:43Z silvercircle $
+ *
+ */
+
+#include <commonheaders.h>
+#include <rowheight_funcs.h>
+
+BOOL RowHeight::Init(ClcData *dat)
+{
+ dat->max_row_height = 0;
+ dat->row_heights_size = 0;
+ dat->row_heights_allocated = 0;
+ dat->row_heights = NULL;
+
+ return TRUE;
+}
+
+void RowHeight::Free(ClcData *dat)
+{
+ if (dat->row_heights != NULL)
+ {
+ free(dat->row_heights);
+ dat->row_heights = NULL;
+ }
+
+ dat->row_heights_allocated = 0;
+ dat->row_heights_size = 0;
+}
+
+void RowHeight::Clear(ClcData *dat)
+{
+ dat->row_heights_size = 0;
+}
+
+
+BOOL RowHeight::Alloc(ClcData *dat, int size)
+{
+ if (size > dat->row_heights_size)
+ {
+ if (size > dat->row_heights_allocated) {
+ int size_grow = size;
+
+ size_grow += 100 - (size_grow % 100);
+
+ if (dat->row_heights != NULL) {
+ int *tmp = (int *) realloc((void *)dat->row_heights, sizeof(int) * size_grow);
+
+ if (tmp == NULL) {
+ Free(dat);
+ return FALSE;
+ }
+
+ dat->row_heights = tmp;
+ }
+ else {
+ dat->row_heights = (int *) malloc(sizeof(int) * size_grow);
+
+ if (dat->row_heights == NULL) {
+ Free(dat);
+ return FALSE;
+ }
+ }
+ dat->row_heights_allocated = size_grow;
+ }
+ dat->row_heights_size = size;
+ }
+ return TRUE;
+}
+
+// Calc and store max row height
+int RowHeight::getMaxRowHeight(ClcData *dat, const HWND hwnd)
+{
+ int max_height = 0, i;
+ DWORD style=GetWindowLong(hwnd,GWL_STYLE);
+
+ int contact_fonts[] = {FONTID_CONTACTS, FONTID_INVIS, FONTID_OFFLINE, FONTID_NOTONLIST, FONTID_OFFINVIS};
+ int other_fonts[] = {FONTID_GROUPS, FONTID_GROUPCOUNTS, FONTID_DIVIDERS};
+
+ // Get contact font size
+ for (i = 0 ; i < MAX_REGS(contact_fonts) ; i++)
+ {
+ if (max_height < dat->fontInfo[contact_fonts[i]].fontHeight)
+ max_height = dat->fontInfo[contact_fonts[i]].fontHeight;
+ }
+
+ if (cfg::dat.dualRowMode == 1 && !dat->bisEmbedded)
+ max_height += ROW_SPACE_BEETWEEN_LINES + dat->fontInfo[FONTID_STATUS].fontHeight;
+
+ // Get other font sizes
+ for (i = 0 ; i < MAX_REGS(other_fonts) ; i++) {
+ if (max_height < dat->fontInfo[other_fonts[i]].fontHeight)
+ max_height = dat->fontInfo[other_fonts[i]].fontHeight;
+ }
+
+ // Avatar size
+ if (cfg::dat.dwFlags & CLUI_FRAME_AVATARS && !dat->bisEmbedded)
+ max_height = max(max_height, cfg::dat.avatarSize + cfg::dat.avatarPadding);
+
+ // Checkbox size
+ if (style&CLS_CHECKBOXES || style&CLS_GROUPCHECKBOXES)
+ max_height = max(max_height, dat->checkboxSize);
+
+ //max_height += 2 * dat->row_border;
+ // Min size
+ max_height = max(max_height, dat->min_row_heigh);
+ max_height += cfg::dat.bRowSpacing;
+
+ dat->max_row_height = max_height;
+
+ return max_height;
+}
+
+// Calc and store row height for all itens in the list
+void RowHeight::calcRowHeights(ClcData *dat, HWND hwnd)
+{
+ int indent, subindex, line_num;
+ struct ClcContact *Drawing;
+ struct ClcGroup *group;
+ DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
+
+ // Draw lines
+ group=&dat->list;
+ group->scanIndex=0;
+ indent=0;
+ //subindex=-1;
+ line_num = -1;
+
+ Clear(dat);
+
+ while(TRUE)
+ {
+ if (group->scanIndex==group->cl.count)
+ {
+ group=group->parent;
+ indent--;
+ if(group==NULL) break; // Finished list
+ group->scanIndex++;
+ continue;
+ }
+
+ // Get item to draw
+ Drawing = group->cl.items[group->scanIndex];
+ line_num++;
+
+ // Calc row height
+ getRowHeight(dat, hwnd, Drawing, line_num, dwStyle);
+
+ if(group->cl.items[group->scanIndex]->type==CLCIT_GROUP && /*!IsBadCodePtr((FARPROC)group->cl.items[group->scanIndex]->group) && */ (group->cl.items[group->scanIndex]->group->expanded & 0x0000ffff)) {
+ group=group->cl.items[group->scanIndex]->group;
+ indent++;
+ group->scanIndex=0;
+ subindex=-1;
+ continue;
+ }
+ group->scanIndex++;
+ }
+}
+
+
+// Calc item top Y (using stored data)
+int RowHeight::getItemTopY(ClcData *dat, int item)
+{
+ int i;
+ int y = 0;
+
+ if (item >= dat->row_heights_size)
+ return -1;
+
+ for (i = 0 ; i < item ; i++)
+ {
+ y += dat->row_heights[i];
+ }
+
+ return y;
+}
+
+
+// Calc item bottom Y (using stored data)
+int RowHeight::getItemBottomY(ClcData *dat, int item)
+{
+ int i;
+ int y = 0;
+
+ if (item >= dat->row_heights_size)
+ return -1;
+
+ for (i = 0 ; i <= item ; i++)
+ {
+ y += dat->row_heights[i];
+ }
+
+ return y;
+}
+
+
+// Calc total height of rows (using stored data)
+int RowHeight::getTotalHeight(ClcData *dat)
+{
+ int i;
+ int y = 0;
+
+ for (i = 0 ; i < dat->row_heights_size ; i++)
+ {
+ y += dat->row_heights[i];
+ }
+
+ return y;
+}
+
+// Return the line that pos_y is at or -1 (using stored data)
+int RowHeight::hitTest(ClcData *dat, int pos_y)
+{
+ int i;
+ int y = 0;
+
+ if (pos_y < 0)
+ return -1;
+
+ for (i = 0 ; i < dat->row_heights_size ; i++)
+ {
+ y += dat->row_heights[i];
+
+ if (pos_y < y)
+ return i;
+ }
+
+ return -1;
+}
+
+int RowHeight::getHeight(ClcData *dat, int item)
+{
+ if ( dat->row_heights == 0 )
+ return 0;
+
+ return dat->row_heights[ item ];
+}
+
+int RowHeight::getFloatingRowHeight(const ClcData *dat, HWND hwnd, ClcContact *contact, DWORD dwFlags)
+{
+ int height = 0;
+
+ height = dat->fontInfo[GetBasicFontID(contact)].fontHeight;
+
+ if(!dat->bisEmbedded) {
+ if(!(dwFlags & FLT_SIMPLE)){
+ if(dwFlags & FLT_DUALROW) {
+ height += (dat->fontInfo[FONTID_STATUS].fontHeight + cfg::dat.avatarPadding);
+ }
+ // Avatar size
+ if (dwFlags & FLT_AVATARS && contact->cFlags & ECF_AVATAR && contact->type == CLCIT_CONTACT && contact->ace != NULL && !(contact->ace->dwFlags & AVS_HIDEONCLIST))
+ height = max(height, cfg::dat.avatarSize + cfg::dat.avatarPadding);
+ }
+ }
+
+ height = max(height, dat->min_row_heigh);
+ height += cfg::dat.bRowSpacing;
+
+ return height;
+}
diff --git a/plugins/Clist_nicer/SRC/statusbar.cpp b/plugins/Clist_nicer/SRC/statusbar.cpp
new file mode 100644
index 0000000000..11308dac52
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/statusbar.cpp
@@ -0,0 +1,197 @@
+/*
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <commonheaders.h>
+#include "../CLUIFrames/cluiframes.h"
+
+WNDPROC OldStatusBarProc = 0;
+
+static POINT ptMouse = {0};
+static RECT rcMouse = {0};
+static int timer_set = 0, tooltip_active = 0;
+extern HANDLE hStatusBarShowToolTipEvent, hStatusBarHideToolTipEvent;
+extern StatusItems_t *StatusItems;
+extern HBRUSH g_CLUISkinnedBkColor;
+
+extern HANDLE (WINAPI *MyOpenThemeData)(HWND, LPCWSTR);
+extern HRESULT (WINAPI *MyCloseThemeData)(HANDLE);
+extern HRESULT (WINAPI *MyDrawThemeBackground)(HANDLE, HDC, int, int, const RECT *, const RECT *);
+
+#define TIMERID_HOVER 1000
+
+LRESULT CALLBACK NewStatusBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_SETCURSOR:
+ {
+ POINT pt;
+
+ GetCursorPos(&pt);
+ SendMessage(GetParent(hwnd),msg,wParam,lParam);
+ if (pt.x == ptMouse.x && pt.y == ptMouse.y)
+ return 1;//return(TestCursorOnBorders());
+
+ ptMouse = pt;
+ if (tooltip_active){
+ KillTimer(hwnd, TIMERID_HOVER);
+ if(!NotifyEventHooks(hStatusBarHideToolTipEvent, 0, 0))
+ CallService("mToolTip/HideTip", 0, 0);
+ tooltip_active = FALSE;
+ }
+ KillTimer(hwnd, TIMERID_HOVER);
+ SetTimer(hwnd, TIMERID_HOVER, 750, 0);
+ break;
+ }
+ case WM_NCHITTEST:
+ {
+ LRESULT lr = SendMessage(GetParent(hwnd), WM_NCHITTEST, wParam, lParam);
+ if(lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT
+ || lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT)
+ return HTTRANSPARENT;
+ break;
+ }
+ case WM_ERASEBKGND:
+ if(cfg::dat.bSkinnedStatusBar)
+ return 1;
+ return CallWindowProc(OldStatusBarProc, hwnd, msg, wParam, lParam);
+
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ KillTimer(hwnd, TIMERID_HOVER);
+ if(!NotifyEventHooks(hStatusBarHideToolTipEvent, 0, 0))
+ CallService("mToolTip/HideTip", 0, 0);
+ tooltip_active = FALSE;
+ break;
+
+ case WM_PAINT:
+ if(cfg::shutDown)
+ return 0;
+
+ if(cfg::dat.bSkinnedStatusBar) {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwnd, &ps);
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ HBITMAP hbmMem, hbmOld;
+ RECT rcClient, rcWindow;
+ StatusItems_t *item = NULL;
+ DRAWITEMSTRUCT dis = {0};
+ int nParts = 0;
+ int i;
+ HFONT hOldFont = 0;
+ POINT pt;
+ BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT);
+ LONG b_offset = cfg::dat.bClipBorder + (windowStyle == SETTING_WINDOWSTYLE_NOBORDER ? 2 : (windowStyle == SETTING_WINDOWSTYLE_THINBORDER ? 1 : 0));
+
+ GetClientRect(hwnd, &rcClient);
+ GetWindowRect(hwnd, &rcWindow);
+ pt.x = rcWindow.left;
+ pt.y = rcWindow.top;
+ ScreenToClient(pcli->hwndContactList, &pt);
+
+ hbmMem = CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom);
+ hbmOld = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, hbmMem));
+ SetBkMode(hdcMem, TRANSPARENT);
+ hOldFont = reinterpret_cast<HFONT>(SelectObject(hdcMem, GetStockObject(DEFAULT_GUI_FONT)));
+ BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY);
+ item = &StatusItems[ID_EXTBKSTATUSBAR - ID_STATUS_OFFLINE];
+ if(!item->IGNORED) {
+ RECT rc = rcClient;
+ rc.left += item->MARGIN_LEFT;
+ rc.right -= item->MARGIN_RIGHT;
+ rc.top += item->MARGIN_TOP;
+ rc.bottom -= item->MARGIN_BOTTOM;
+ DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT,
+ item->CORNER, item->BORDERSTYLE, item->imageItem);
+ SetTextColor(hdcMem, item->TEXTCOLOR);
+ }else{
+ SetTextColor(hdcMem, GetSysColor(COLOR_BTNTEXT));
+ }
+ dis.hwndItem = hwnd;
+ dis.hDC = hdcMem;
+ dis.CtlType = 0;
+ nParts = SendMessage(hwnd, SB_GETPARTS, 0, 0);
+ for(i = 0; i < nParts; i++) {
+ SendMessage(hwnd, SB_GETRECT, i, (LPARAM)&dis.rcItem);
+ OffsetRect(&dis.rcItem, 0, -b_offset);
+ dis.itemData = SendMessage(hwnd, SB_GETTEXTA, i, 0);
+ SendMessage(pcli->hwndContactList, WM_DRAWITEM, 0, (LPARAM)&dis);
+ }
+ BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY);
+ if(hOldFont)
+ SelectObject(hdcMem, hOldFont);
+ SelectObject(hdcMem, hbmOld);
+ DeleteObject(hbmMem);
+ DeleteDC(hdcMem);
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ break;
+
+ case WM_DESTROY:
+ break;
+
+ case WM_TIMER:
+ if(wParam == TIMERID_HOVER) {
+ POINT pt;
+ KillTimer(hwnd, TIMERID_HOVER);
+
+ GetCursorPos(&pt);
+ if (pt.x == ptMouse.x && pt.y == ptMouse.y) {
+ int i,nParts;
+ RECT rc;
+
+ ScreenToClient(hwnd, &pt);
+ nParts = SendMessage(hwnd, SB_GETPARTS, 0, 0);
+ for(i = 0; i < nParts; i++) {
+ SendMessage(hwnd, SB_GETRECT, i, (LPARAM)&rc);
+ if(PtInRect(&rc,pt)) {
+ ProtocolData *PD;
+ PD = (ProtocolData *)SendMessageA(hwnd, SB_GETTEXTA, i, 0);
+
+ if(PD) {
+ if(NotifyEventHooks(hStatusBarShowToolTipEvent, (WPARAM)PD->RealName, 0) > 0) // a plugin handled this event
+ tooltip_active = TRUE;
+ else if(cfg::getDword("mToolTip", "ShowStatusTip", 0)) {
+ CLCINFOTIP ti = {0};
+ BYTE isLocked = 0;
+ char szTipText[256], *szStatus = NULL;
+ WORD wStatus;
+
+ ti.cbSize = sizeof(ti);
+ ti.isTreeFocused = GetFocus() == pcli->hwndContactList ? 1 : 0;
+ wStatus = (WORD)CallProtoService(PD->RealName, PS_GETSTATUS, 0, 0);
+ isLocked = cfg::getByte(PD->RealName, "LockMainStatus", 0);
+ szStatus = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)wStatus, 0);
+ mir_snprintf(szTipText, 256, "<b>%s</b>: %s%s", PD->RealName, szStatus, isLocked ? " (LOCKED)" : "");
+ CallService("mToolTip/ShowTip", (WPARAM)szTipText, (LPARAM)&ti);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return CallWindowProc(OldStatusBarProc, hwnd, msg, wParam, lParam);
+}
diff --git a/plugins/Clist_nicer/SRC/statusfloater.cpp b/plugins/Clist_nicer/SRC/statusfloater.cpp
new file mode 100644
index 0000000000..acc3ba8dc0
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/statusfloater.cpp
@@ -0,0 +1,1240 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+------------------------
+
+implements a simple status floater as a layered (and skinnable) window with
+a minimalistic UI (change status, access main menu). It also may hold a copy
+of the event area.
+
+Also implementes floating contacts (FLT_*() functions)
+
+*/
+
+#include <commonheaders.h>
+
+#define SNAP_SCREEN_TOLERANCE 10
+#define SNAP_FLT_TOLERANCE 10
+#define TOOLTIP_TIMER 1
+
+#define MS_TOOLTIP_SHOWTIP "mToolTip/ShowTip"
+#define MS_TOOLTIP_HIDETIP "mToolTip/HideTip"
+
+BYTE __forceinline percent_to_byte(UINT32 percent)
+{
+ return(BYTE) ((FLOAT) (((FLOAT) percent) / 100) * 255);
+}
+
+void FLT_Update(struct ClcData *dat, struct ClcContact *contact);
+void FLT_ShowHideAll(int showCmd);
+void FLT_SnapToEdges(HWND hwnd);
+void FLT_SnapToFloater(HWND hwnd);
+
+HWND g_hwndSFL = 0;
+HDC g_SFLCachedDC = 0;
+HBITMAP g_SFLhbmOld = 0, g_SFLhbm = 0;
+struct ContactFloater *pFirstFloater = 0;
+BOOL hover = FALSE;
+BOOL tooltip = FALSE;
+UINT_PTR hTooltipTimer = 0;
+POINT start_pos;
+
+
+extern StatusItems_t *StatusItems;
+extern int g_padding_y;
+
+extern HIMAGELIST hCListImages;
+extern HWND g_hwndEventArea;
+extern HDC g_HDC;
+
+extern int g_list_avatars;
+
+FLOATINGOPTIONS g_floatoptions;
+
+static UINT padctrlIDs[] = { IDC_FLT_PADLEFTSPIN, IDC_FLT_PADRIGHTSPIN, IDC_FLT_PADTOPSPIN,
+ IDC_FLT_PADBOTTOMSPIN, 0 };
+
+/*
+ * floating contacts support functions
+ * simple linked list of allocated ContactFloater* structs
+ */
+
+static struct ContactFloater *FLT_AddToList(struct ContactFloater *pFloater) {
+ struct ContactFloater *pCurrent = pFirstFloater;
+
+ if (!pFirstFloater) {
+ pFirstFloater = pFloater;
+ pFirstFloater->pNextFloater = NULL;
+ return pFirstFloater;
+ } else {
+ while (pCurrent->pNextFloater != 0)
+ pCurrent = pCurrent->pNextFloater;
+ pCurrent->pNextFloater = pFloater;
+ pFloater->pNextFloater = NULL;
+ return pCurrent;
+ }
+}
+
+static struct ContactFloater *FLT_RemoveFromList(struct ContactFloater *pFloater) {
+ struct ContactFloater *pCurrent = pFirstFloater;
+
+ if (pFloater == pFirstFloater) {
+ if(pFloater->pNextFloater != NULL)
+ pFirstFloater = pFloater->pNextFloater;
+ else
+ pFirstFloater = NULL;
+ return pFirstFloater;
+ }
+
+ do {
+ if (pCurrent->pNextFloater == pFloater) {
+ pCurrent->pNextFloater = pCurrent->pNextFloater->pNextFloater;
+ return 0;
+ }
+ } while (pCurrent = pCurrent->pNextFloater);
+
+ return NULL;
+}
+
+void FLT_SnapToEdges(HWND hwnd)
+{
+ RECT dr;
+ MONITORINFO monInfo;
+ RECT rcWindow;
+ HMONITOR curMonitor;
+
+ if ( API::pfnMonitorFromWindow == NULL )
+ return;
+
+ curMonitor = API::pfnMonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+
+ monInfo.cbSize = sizeof(monInfo);
+ API::pfnGetMonitorInfo(curMonitor, &monInfo);
+
+ dr = monInfo.rcWork;
+ GetWindowRect(hwnd, &rcWindow);
+
+ if (rcWindow.left < dr.left + SNAP_SCREEN_TOLERANCE){
+ SetWindowPos(hwnd, HWND_TOPMOST, 0, rcWindow.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+ GetWindowRect(hwnd, &rcWindow);
+ }
+
+ if (rcWindow.top < dr.top + SNAP_SCREEN_TOLERANCE){
+ SetWindowPos(hwnd, HWND_TOPMOST, rcWindow.left, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+ GetWindowRect(hwnd, &rcWindow);
+ }
+
+ if (rcWindow.right > dr.right - SNAP_SCREEN_TOLERANCE)
+ SetWindowPos(hwnd, HWND_TOPMOST, dr.right - (rcWindow.right - rcWindow.left), rcWindow.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+
+ if (rcWindow.bottom > dr.bottom - SNAP_SCREEN_TOLERANCE)
+ SetWindowPos(hwnd, HWND_TOPMOST, rcWindow.left, dr.bottom - (rcWindow.bottom - rcWindow.top), 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+}
+
+void FLT_SnapToFloater(HWND hwnd)
+{
+ struct ContactFloater *pCurrent = pFirstFloater;
+ RECT rcWindow, rcBase;
+ int minTop = 0xFFFFFF, minBottom = 0xFFFFFF, minRight = 0xFFFFFF, minLeft = 0xFFFFFF;
+ int posTop = 0, posBottom = 0, posRight = 0, posLeft = 0;
+
+ GetWindowRect(hwnd, &rcBase);
+
+ //find the closest floater
+ while(pCurrent) {
+ GetWindowRect(pCurrent->hwnd, &rcWindow);
+ //top
+ if((rcWindow.top - rcBase.bottom > -SNAP_FLT_TOLERANCE) && (rcWindow.top - rcBase.bottom < minTop)){
+ posTop = rcWindow.top;
+ minTop = rcWindow.top - rcBase.bottom;
+ }
+ //bottom
+ if((rcBase.top - rcWindow.bottom > -SNAP_FLT_TOLERANCE) && (rcBase.top - rcWindow.bottom < minBottom)){
+ posBottom = rcWindow.bottom;
+ minBottom = rcBase.top - rcWindow.bottom;
+ }
+ //left
+ if((rcWindow.left - rcBase.right > -SNAP_FLT_TOLERANCE) && (rcWindow.left - rcBase.right < minLeft)){
+ posLeft= rcWindow.left;
+ minLeft = rcWindow.left - rcBase.right;
+ }
+ //right
+ if((rcBase.left - rcWindow.right > -SNAP_FLT_TOLERANCE) && (rcBase.left - rcWindow.right < minRight)){
+ posRight= rcWindow.right;
+ minRight = rcBase.left - rcWindow.right;
+ }
+ pCurrent = pCurrent->pNextFloater;
+ }
+
+ //snap to the closest floater if spacing is under SNAP_FLT_TOLERANCE
+ if (posTop && (rcBase.bottom > posTop - SNAP_FLT_TOLERANCE))
+ SetWindowPos(hwnd, HWND_TOPMOST, rcBase.left, posTop - (rcBase.bottom - rcBase.top), 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+
+ if (posBottom && (rcBase.top < posBottom + SNAP_FLT_TOLERANCE))
+ SetWindowPos(hwnd, HWND_TOPMOST, rcBase.left, posBottom, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+
+ if (posLeft && (rcBase.right > posLeft - SNAP_FLT_TOLERANCE))
+ SetWindowPos(hwnd, HWND_TOPMOST, posLeft - (rcBase.right - rcBase.left), rcBase.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+
+ if (posRight && (rcBase.left < posRight + SNAP_FLT_TOLERANCE))
+ SetWindowPos(hwnd, HWND_TOPMOST, posRight, rcBase.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+}
+
+/*
+ * dialog procedure for the floating contacts option page
+ */
+
+INT_PTR CALLBACK DlgProcFloatingContacts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ DWORD dwFlags = g_floatoptions.dwFlags;
+ int i = 0;
+
+ TranslateDialogDefault(hwndDlg);
+
+ CheckDlgButton(hwndDlg, IDC_FLT_ENABLED, g_floatoptions.enabled);
+ SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_FLT_ENABLED, 0);
+ CheckDlgButton(hwndDlg, IDC_FLT_SIMPLELAYOUT, dwFlags & FLT_SIMPLE);
+ SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_FLT_SIMPLELAYOUT, 0);
+ CheckDlgButton(hwndDlg, IDC_FLT_AVATARS, dwFlags & FLT_AVATARS);
+ CheckDlgButton(hwndDlg, IDC_FLT_DUALROWS, dwFlags & FLT_DUALROW);
+ CheckDlgButton(hwndDlg, IDC_FLT_EXTRAICONS, dwFlags & FLT_EXTRAICONS);
+ CheckDlgButton(hwndDlg, IDC_FLT_SYNCED, dwFlags & FLT_SYNCWITHCLIST);
+ CheckDlgButton(hwndDlg, IDC_FLT_AUTOHIDE, dwFlags & FLT_AUTOHIDE);
+ CheckDlgButton(hwndDlg, IDC_FLT_SNAP, dwFlags & FLT_SNAP);
+ CheckDlgButton(hwndDlg, IDC_FLT_BORDER, dwFlags & FLT_BORDER);
+ SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_FLT_BORDER, 0);
+ CheckDlgButton(hwndDlg, IDC_FLT_ROUNDED, dwFlags & FLT_ROUNDED);
+ CheckDlgButton(hwndDlg, IDC_FLT_FILLSTD, dwFlags & FLT_FILLSTDCOLOR);
+
+ SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_FLT_ROUNDED, 0);
+
+ if (ServiceExists(MS_TOOLTIP_SHOWTIP))
+ {
+ CheckDlgButton(hwndDlg, IDC_FLT_SHOWTOOLTIPS, dwFlags & FLT_SHOWTOOLTIPS);
+ SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_FLT_SHOWTOOLTIPS, 0);
+ CheckDlgButton(hwndDlg, IDC_FLT_DEFHOVERTIME, g_floatoptions.def_hover_time);
+ SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_FLT_DEFHOVERTIME, 0);
+ }
+ else
+ {
+ CheckDlgButton(hwndDlg, IDC_FLT_SHOWTOOLTIPS, 0);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_SHOWTOOLTIPS, 0);
+ }
+
+ for(i = 0; padctrlIDs[i] != 0; i++)
+ SendDlgItemMessage(hwndDlg, padctrlIDs[i], UDM_SETRANGE, 0, MAKELONG(20, 0));
+ SendDlgItemMessage(hwndDlg, IDC_FLT_WIDTHSPIN, UDM_SETRANGE, 0, MAKELONG(200, 50));
+ SendDlgItemMessage(hwndDlg, IDC_FLT_RADIUSSPIN, UDM_SETRANGE, 0, MAKELONG(20, 1));
+ SendDlgItemMessage(hwndDlg, IDC_FLT_HOVERTIMESPIN, UDM_SETRANGE, 0, MAKELONG(5000, 1));
+
+
+ SendDlgItemMessage(hwndDlg, IDC_FLT_PADLEFTSPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.pad_left);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_PADRIGHTSPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.pad_right);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_PADTOPSPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.pad_top);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_PADBOTTOMSPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.pad_top);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_WIDTHSPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.width);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_RADIUSSPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.radius);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_HOVERTIMESPIN, UDM_SETPOS, 0, (LPARAM)g_floatoptions.hover_time);
+
+ SendDlgItemMessage(hwndDlg, IDC_FLT_ACTIVEOPACITY, TBM_SETRANGE, FALSE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_FLT_ACTIVEOPACITY, TBM_SETPOS, TRUE, g_floatoptions.act_trans);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_OPACITY, TBM_SETRANGE, FALSE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_FLT_OPACITY, TBM_SETPOS, TRUE, g_floatoptions.trans);
+ SendMessage(hwndDlg, WM_HSCROLL, 0, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_FLT_BORDERCOLOUR, CPM_SETDEFAULTCOLOUR, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_BORDERCOLOUR, CPM_SETCOLOUR, 0, g_floatoptions.border_colour);
+
+ FLT_ShowHideAll(SW_SHOWNOACTIVATE);
+
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_FLT_ENABLED:
+ {
+ int isEnabled = IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED);
+ int isSimple = IsDlgButtonChecked(hwndDlg, IDC_FLT_SIMPLELAYOUT);
+ int isBorder = IsDlgButtonChecked(hwndDlg, IDC_FLT_BORDER);
+ int isRounded = IsDlgButtonChecked(hwndDlg, IDC_FLT_ROUNDED);
+ int isTooltip = IsDlgButtonChecked(hwndDlg, IDC_FLT_SHOWTOOLTIPS);
+ int isDefHoverTime = IsDlgButtonChecked(hwndDlg, IDC_FLT_DEFHOVERTIME);
+
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_SIMPLELAYOUT, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_SYNCED, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_AUTOHIDE, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_SNAP, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_ACTIVEOPACITY, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_OPACITY, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADLEFTSPIN, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADRIGHTSPIN, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADTOPSPIN, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADLEFT, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADRIGHT, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADTOP, isEnabled);
+ //EnableWindow(GetDlgItem(hwndDlg, IDC_FLT_PADBOTTOMSPIN), isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_PADBOTTOM, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_WIDTHSPIN, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_WIDTH, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_BORDER, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_ROUNDED, isEnabled);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_BORDERCOLOUR, isEnabled & isBorder);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_RADIUS, isEnabled & isRounded);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_RADIUSSPIN, isEnabled & isRounded);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_SHOWTOOLTIPS, isEnabled & ServiceExists(MS_TOOLTIP_SHOWTIP));
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_DEFHOVERTIME, isEnabled & isTooltip);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_HOVERTIME, isEnabled & isTooltip & !isDefHoverTime);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_HOVERTIMESPIN, isEnabled & isTooltip & !isDefHoverTime);
+
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_AVATARS, isEnabled & !isSimple);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_EXTRAICONS, isEnabled & !isSimple);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_DUALROWS, isEnabled & !isSimple);
+ }
+ break;
+ case IDC_FLT_SIMPLELAYOUT:
+ {
+ if (IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED)){
+ int isSimple = IsDlgButtonChecked(hwndDlg, IDC_FLT_SIMPLELAYOUT);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_AVATARS, !isSimple);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_EXTRAICONS, !isSimple);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_DUALROWS, !isSimple);
+ }
+ }
+ break;
+ case IDC_FLT_BORDER:
+ {
+ if (IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED)){
+ int isBorder = IsDlgButtonChecked(hwndDlg, IDC_FLT_BORDER);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_BORDERCOLOUR, isBorder);
+ }
+ }
+ break;
+ case IDC_FLT_ROUNDED:
+ {
+ if (IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED)){
+ int isRounded = IsDlgButtonChecked(hwndDlg, IDC_FLT_ROUNDED);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_RADIUS, isRounded);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_RADIUSSPIN, isRounded);
+ }
+ }
+ break;
+ case IDC_FLT_SHOWTOOLTIPS:
+ {
+ if (IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED)){
+ int isTooltip = IsDlgButtonChecked(hwndDlg, IDC_FLT_SHOWTOOLTIPS);
+ int isDefHoverTime = IsDlgButtonChecked(hwndDlg, IDC_FLT_DEFHOVERTIME);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_DEFHOVERTIME, isTooltip);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_HOVERTIME, isTooltip & !isDefHoverTime);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_HOVERTIMESPIN, isTooltip & !isDefHoverTime);
+ }
+ }
+ break;
+ case IDC_FLT_DEFHOVERTIME:
+ {
+ if (IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED) && IsDlgButtonChecked(hwndDlg, IDC_FLT_SHOWTOOLTIPS)){
+ int isDefHoverTime = IsDlgButtonChecked(hwndDlg, IDC_FLT_DEFHOVERTIME);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_HOVERTIME, !isDefHoverTime);
+ Utils::enableDlgControl(hwndDlg, IDC_FLT_HOVERTIMESPIN, !isDefHoverTime);
+ }
+ }
+ break;
+
+ case IDC_FLT_PADTOP:
+ {
+ if(HIWORD(wParam) == EN_CHANGE){
+ int value = SendDlgItemMessage(hwndDlg, IDC_FLT_PADTOPSPIN, UDM_GETPOS, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_FLT_PADBOTTOMSPIN, UDM_SETPOS, 0, (LPARAM)value);
+ }
+ }
+ break;
+ break;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_HSCROLL:
+ {
+ char str[10];
+ wsprintfA(str, "%d%%", 100 * SendDlgItemMessage(hwndDlg, IDC_FLT_ACTIVEOPACITY, TBM_GETPOS, 0, 0) / 255);
+ SetDlgItemTextA(hwndDlg, IDC_FLT_ACTIVEOPACITYVALUE, str);
+ wsprintfA(str, "%d%%", 100 * SendDlgItemMessage(hwndDlg, IDC_FLT_OPACITY, TBM_GETPOS, 0, 0) / 255);
+ SetDlgItemTextA(hwndDlg, IDC_FLT_OPACITYVALUE, str);
+
+ if (lParam)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ g_floatoptions.enabled = IsDlgButtonChecked(hwndDlg, IDC_FLT_ENABLED) ? 1 : 0;
+ g_floatoptions.dwFlags = 0;
+
+ if(IsDlgButtonChecked(hwndDlg, IDC_FLT_SIMPLELAYOUT))
+ g_floatoptions.dwFlags = FLT_SIMPLE;
+
+ g_floatoptions.dwFlags |= (IsDlgButtonChecked(hwndDlg, IDC_FLT_AVATARS) ? FLT_AVATARS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_DUALROWS) ? FLT_DUALROW : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_EXTRAICONS) ? FLT_EXTRAICONS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_SYNCED) ? FLT_SYNCWITHCLIST : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_AUTOHIDE) ? FLT_AUTOHIDE : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_SNAP) ? FLT_SNAP : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_BORDER) ? FLT_BORDER : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_FILLSTD) ? FLT_FILLSTDCOLOR : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_SHOWTOOLTIPS) ? FLT_SHOWTOOLTIPS : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_FLT_ROUNDED) ? FLT_ROUNDED : 0);
+
+ g_floatoptions.act_trans = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_ACTIVEOPACITY, TBM_GETPOS, 0, 0);
+ g_floatoptions.trans = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_OPACITY, TBM_GETPOS, 0, 0);
+ g_floatoptions.pad_left = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_PADLEFTSPIN, UDM_GETPOS, 0, 0);
+ g_floatoptions.pad_right = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_PADRIGHTSPIN, UDM_GETPOS, 0, 0);
+ g_floatoptions.pad_top = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_PADTOPSPIN, UDM_GETPOS, 0, 0);
+ g_floatoptions.pad_bottom = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_PADBOTTOMSPIN, UDM_GETPOS, 0, 0);
+ g_floatoptions.width = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_WIDTHSPIN, UDM_GETPOS, 0, 0);
+ g_floatoptions.radius = (BYTE)SendDlgItemMessage(hwndDlg, IDC_FLT_RADIUSSPIN, UDM_GETPOS, 0, 0);
+ g_floatoptions.border_colour = SendDlgItemMessage(hwndDlg, IDC_FLT_BORDERCOLOUR, CPM_GETCOLOUR, 0, 0);
+
+ g_floatoptions.def_hover_time= IsDlgButtonChecked(hwndDlg, IDC_FLT_DEFHOVERTIME) ? 1 : 0;
+ if (g_floatoptions.def_hover_time)
+ g_floatoptions.hover_time = cfg::getWord("CLC", "InfoTipHoverTime", 200);
+ else
+ g_floatoptions.hover_time = (WORD)SendDlgItemMessage(hwndDlg, IDC_FLT_HOVERTIMESPIN, UDM_GETPOS, 0, 0);
+
+ FLT_WriteOptions();
+ FLT_RefreshAll();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+void FLT_ReadOptions()
+{
+ DWORD dwPad;
+
+ ZeroMemory(&g_floatoptions, sizeof(FLOATINGOPTIONS));
+
+ g_floatoptions.enabled = cfg::getByte("CList", "flt_enabled", 0);
+ g_floatoptions.dwFlags = cfg::getDword("CList", "flt_flags", FLT_SIMPLE);
+ dwPad = cfg::getDword("CList", "flt_padding", 0);
+
+ g_floatoptions.pad_top = LOBYTE(LOWORD(dwPad));
+ g_floatoptions.pad_right = HIBYTE(LOWORD(dwPad));
+ g_floatoptions.pad_bottom = LOBYTE(HIWORD(dwPad));
+ g_floatoptions.pad_left = HIBYTE(HIWORD(dwPad));
+
+ g_floatoptions.width = cfg::getDword("CList", "flt_width", 100);
+ g_floatoptions.act_trans = cfg::getByte("CList", "flt_acttrans", 255);
+ g_floatoptions.trans = cfg::getByte("CList", "flt_trans", 255);
+ g_floatoptions.radius = cfg::getByte("CList", "flt_radius", 3);
+ g_floatoptions.border_colour = cfg::getDword("CList", "flt_bordercolour", 0);
+ g_floatoptions.def_hover_time = cfg::getByte("CList", "flt_defhovertime", 1);
+
+ if (g_floatoptions.def_hover_time)
+ g_floatoptions.hover_time = cfg::getWord("CLC", "InfoTipHoverTime", 200);
+ else
+ g_floatoptions.hover_time = cfg::getWord("CList", "flt_hovertime", 200);
+
+}
+
+void FLT_WriteOptions()
+{
+ DWORD dwPad;
+
+ cfg::writeByte("CList", "flt_enabled", g_floatoptions.enabled);
+ cfg::writeDword("CList", "flt_flags", g_floatoptions.dwFlags);
+ dwPad = MAKELONG(MAKEWORD(g_floatoptions.pad_top, g_floatoptions.pad_right),
+ MAKEWORD(g_floatoptions.pad_bottom, g_floatoptions.pad_left));
+ cfg::writeDword("CList", "flt_padding", dwPad);
+ cfg::writeDword("CList", "flt_width", g_floatoptions.width);
+ cfg::writeByte("CList", "flt_acttrans", g_floatoptions.act_trans);
+ cfg::writeByte("CList", "flt_trans", g_floatoptions.trans);
+ cfg::writeByte("CList", "flt_radius", g_floatoptions.radius);
+ cfg::writeDword("CList", "flt_bordercolour", g_floatoptions.border_colour);
+ cfg::writeByte("CList", "flt_defhovertime", g_floatoptions.def_hover_time);
+ if (!g_floatoptions.def_hover_time)
+ cfg::writeWord("CList", "flt_hovertime", g_floatoptions.hover_time);
+
+}
+
+LRESULT CALLBACK StatusFloaterClassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_DESTROY:
+ Utils_SaveWindowPosition(hwnd, 0, "CLUI", "sfl");
+ if(g_SFLCachedDC) {
+ SelectObject(g_SFLCachedDC, g_SFLhbmOld);
+ DeleteObject(g_SFLhbm);
+ DeleteDC(g_SFLCachedDC);
+ g_SFLCachedDC = 0;
+ }
+ break;
+ case WM_ERASEBKGND:
+ return TRUE;
+ case WM_PAINT:
+ {
+ HDC hdc;
+ PAINTSTRUCT ps;
+
+ hdc = BeginPaint(hwnd, &ps);
+ ps.fErase = FALSE;
+ EndPaint(hwnd, &ps);
+ return TRUE;
+ }
+ case WM_LBUTTONDOWN:
+ {
+ POINT ptMouse;
+ RECT rcWindow;
+
+ GetCursorPos(&ptMouse);
+ GetWindowRect(hwnd, &rcWindow);
+ rcWindow.right = rcWindow.left + 25;
+ if(!PtInRect(&rcWindow, ptMouse))
+ return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(ptMouse.x, ptMouse.y));
+ break;
+ }
+ case WM_LBUTTONUP:
+ {
+ HMENU hmenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0);
+ RECT rcWindow;
+ POINT pt;
+
+ GetCursorPos(&pt);
+ GetWindowRect(hwnd, &rcWindow);
+ if(cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS) {
+ if(pt.y > rcWindow.top + ((rcWindow.bottom - rcWindow.top) / 2))
+ SendMessage(g_hwndEventArea, WM_COMMAND, MAKEWPARAM(IDC_NOTIFYBUTTON, 0), 0);
+ else
+ TrackPopupMenu(hmenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, rcWindow.left, rcWindow.bottom, 0, pcli->hwndContactList, NULL);
+ }
+ else
+ TrackPopupMenu(hmenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, rcWindow.left, rcWindow.bottom, 0, pcli->hwndContactList, NULL);
+ return 0;
+ }
+ case WM_CONTEXTMENU:
+ {
+ HMENU hmenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0);
+ RECT rcWindow;
+
+ GetWindowRect(hwnd, &rcWindow);
+ TrackPopupMenu(hmenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, rcWindow.left, rcWindow.bottom, 0, pcli->hwndContactList, NULL);
+ return 0;
+ }
+
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+void CALLBACK ShowTooltip(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime){
+ struct ContactFloater *pCurrent = pFirstFloater;
+ POINT pt;
+ CLCINFOTIP ti = {0};
+
+ KillTimer(hwnd, TOOLTIP_TIMER);
+ hTooltipTimer = 0;
+
+ GetCursorPos(&pt);
+ if ((abs(pt.x - start_pos.x) > 3) && (abs(pt.y - start_pos.y) > 3)) return;
+
+ while(pCurrent->hwnd != hwnd)
+ pCurrent = pCurrent->pNextFloater;
+
+ ti.cbSize = sizeof(ti);
+ ti.isGroup = 0;
+ ti.isTreeFocused = 0;
+ ti.hItem = pCurrent->hContact;
+ ti.ptCursor = pt;
+ CallService(MS_TOOLTIP_SHOWTIP, 0, (LPARAM)&ti);
+ tooltip = TRUE;
+}
+
+LRESULT CALLBACK ContactFloaterClassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR iEntry = GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ struct TExtraCache *centry = NULL;
+
+ if(iEntry >= 0 && iEntry < cfg::nextCacheEntry)
+ centry = &cfg::eCache[iEntry];
+
+ switch(msg) {
+ case WM_NCCREATE:
+ {
+ CREATESTRUCT *cs = (CREATESTRUCT *)lParam;
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)cs->lpCreateParams);
+ iEntry = (int)cs->lpCreateParams;
+ if(iEntry >= 0 && iEntry < cfg::nextCacheEntry)
+ centry = &cfg::eCache[iEntry];
+ return TRUE;
+ }
+ case WM_DESTROY:
+ if(centry) {
+ WINDOWPLACEMENT wp = {0};
+
+ SelectObject(centry->floater->hdc, centry->floater->hbmOld);
+ DeleteObject(centry->floater->hbm);
+ DeleteDC(centry->floater->hdc);
+ FLT_RemoveFromList(centry->floater);
+ free(centry->floater);
+ centry->floater = 0;
+ Utils_SaveWindowPosition(hwnd, centry->hContact, "CList", "flt");
+ break;
+ }
+ case WM_ERASEBKGND:
+ return TRUE;
+ case WM_PAINT:
+ {
+ HDC hdc;
+ PAINTSTRUCT ps;
+
+ hdc = BeginPaint(hwnd, &ps);
+ ps.fErase = FALSE;
+ EndPaint(hwnd, &ps);
+ return TRUE;
+ }
+ case WM_LBUTTONDBLCLK:
+ if(centry)
+ CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)centry->hContact, 0);
+ return 0;
+ case WM_LBUTTONDOWN:
+ {
+ POINT ptMouse;
+ RECT rcWindow;
+
+ GetCursorPos(&ptMouse);
+ GetWindowRect(hwnd, &rcWindow);
+ rcWindow.right = rcWindow.left + 25;
+ if(!PtInRect(&rcWindow, ptMouse))
+ return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(ptMouse.x, ptMouse.y));
+ break;
+ }
+ case WM_MOUSEMOVE:
+ if( API::pfnTrackMouseEvent && !hover ) {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_HOVER | TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = 5;
+ API::pfnTrackMouseEvent(&tme);
+ hover = TRUE;
+ }
+ if ( ServiceExists( MS_TOOLTIP_SHOWTIP )) {
+ if ((g_floatoptions.dwFlags & FLT_SHOWTOOLTIPS) && !tooltip) {
+ GetCursorPos(&start_pos);
+ if (hTooltipTimer) KillTimer(hwnd, TOOLTIP_TIMER);
+ hTooltipTimer = SetTimer(hwnd, TOOLTIP_TIMER, g_floatoptions.hover_time, ShowTooltip);
+ }
+ }
+
+ return FALSE;
+
+ case WM_MOUSEHOVER:
+ {
+ struct ClcContact *contact = NULL;
+ struct ContactFloater *pCurrent = pFirstFloater;
+ int oldTrans = g_floatoptions.trans;
+
+ while(pCurrent->hwnd != hwnd)
+ pCurrent = pCurrent->pNextFloater;
+
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, pCurrent->hContact, &contact, NULL, 0)){
+ g_floatoptions.trans = g_floatoptions.act_trans;
+ FLT_Update(cfg::clcdat, contact);
+ g_floatoptions.trans = oldTrans;
+ }
+
+ break;
+ }
+ case WM_MOUSELEAVE:
+ {
+ struct ClcContact *contact = NULL;
+ struct ContactFloater *pCurrent = pFirstFloater;
+
+ while(pCurrent->hwnd != hwnd)
+ pCurrent = pCurrent->pNextFloater;
+
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, pCurrent->hContact, &contact, NULL, 0))
+ FLT_Update(cfg::clcdat, contact);
+
+ if (hTooltipTimer)
+ {
+ KillTimer(hwnd, TOOLTIP_TIMER);
+ hTooltipTimer = 0;
+ }
+
+ if (tooltip) CallService(MS_TOOLTIP_HIDETIP, 0, 0);
+
+ hover = FALSE;
+ tooltip = FALSE;
+
+
+ break;
+ }
+
+ case WM_MOVE:
+ {
+ if (g_floatoptions.dwFlags & FLT_SNAP)
+ FLT_SnapToEdges(hwnd);
+
+ if(GetKeyState(VK_CONTROL) < 0)
+ FLT_SnapToFloater(hwnd);
+
+ break;
+ }
+ case WM_MEASUREITEM:
+ return(CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam));
+ case WM_DRAWITEM:
+ return(CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam));
+ case WM_COMMAND:
+ return(CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKELONG(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)centry->hContact));
+ case WM_CONTEXTMENU:
+ {
+ if(centry) {
+ HMENU hContactMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)centry->hContact, 0);
+ RECT rcWindow;
+
+ GetWindowRect(hwnd, &rcWindow);
+ TrackPopupMenu(hContactMenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, rcWindow.left, rcWindow.bottom, 0, hwnd, NULL);
+ DestroyMenu(hContactMenu);
+ return 0;
+ }
+ break;
+ }
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+void SFL_RegisterWindowClass()
+{
+ WNDCLASS wndclass;
+
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = StatusFloaterClassProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = g_hInst;
+ wndclass.hIcon = 0;
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH) (COLOR_3DFACE);
+ wndclass.lpszMenuName = 0;
+ wndclass.lpszClassName = _T("StatusFloaterClass");
+ RegisterClass(&wndclass);
+
+ wndclass.style = CS_DBLCLKS;
+ wndclass.lpszClassName = _T("ContactFloaterClass");
+ wndclass.lpfnWndProc = ContactFloaterClassProc;
+ RegisterClass(&wndclass);
+}
+
+void SFL_UnregisterWindowClass()
+{
+ UnregisterClass(_T("StatusFloaterClass"), g_hInst);
+ UnregisterClass(_T("ContactFloaterClass"), g_hInst);
+}
+
+void SFL_Destroy()
+{
+ if(g_hwndSFL)
+ DestroyWindow(g_hwndSFL);
+ g_hwndSFL = 0;
+}
+
+static HICON sfl_hIcon = (HICON)-1;
+static int sfl_iIcon = -1;
+static TCHAR sfl_statustext[100] = _T("");
+
+void SFL_Update(HICON hIcon, int iIcon, HIMAGELIST hIml, const TCHAR *szText, BOOL refresh)
+{
+ RECT rcClient, rcWindow;
+ POINT ptDest, ptSrc = {0};
+ SIZE szDest, szT;
+ BLENDFUNCTION bf = {0};
+ HFONT hOldFont;
+ StatusItems_t *item = &StatusItems[ID_EXTBKSTATUSFLOATER - ID_STATUS_OFFLINE];
+ RECT rcStatusArea;
+ LONG cy;
+
+ if(g_hwndSFL == 0)
+ return;
+
+ GetClientRect(g_hwndSFL, &rcClient);
+ GetWindowRect(g_hwndSFL, &rcWindow);
+
+ ptDest.x = rcWindow.left;
+ ptDest.y = rcWindow.top;
+ szDest.cx = rcWindow.right - rcWindow.left;
+ szDest.cy = rcWindow.bottom - rcWindow.top;
+
+ if(item->IGNORED) {
+ FillRect(g_SFLCachedDC, &rcClient, GetSysColorBrush(COLOR_3DFACE));
+ SetTextColor(g_SFLCachedDC, GetSysColor(COLOR_BTNTEXT));
+ }
+ else {
+ FillRect(g_SFLCachedDC, &rcClient, GetSysColorBrush(COLOR_3DFACE));
+ DrawAlpha(g_SFLCachedDC, &rcClient, item->COLOR, 100, item->COLOR2, item->COLOR2_TRANSPARENT,
+ item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem);
+ SetTextColor(g_SFLCachedDC, item->TEXTCOLOR);
+ }
+ bf.BlendOp = AC_SRC_OVER;
+ bf.AlphaFormat = 0;
+ bf.SourceConstantAlpha = item->IGNORED ? 255 : percent_to_byte(item->ALPHA);
+
+ rcStatusArea = rcClient;
+
+ if(cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS)
+ rcStatusArea.bottom = 20;
+
+ cy = rcStatusArea.bottom - rcStatusArea.top;
+
+ if(szText != NULL && refresh) {
+ _tcsncpy(sfl_statustext, szText, 100);
+ sfl_statustext[99] = 0;
+ }
+
+ if(!hIcon) {
+ HICON p_hIcon;
+
+ if(refresh)
+ sfl_iIcon = iIcon;
+ if(sfl_iIcon != -1) {
+ p_hIcon = ImageList_ExtractIcon(0, hCListImages, sfl_iIcon);
+ DrawIconEx(g_SFLCachedDC, 5, (cy - 16) / 2, p_hIcon, 16, 16, 0, 0, DI_NORMAL);
+ DestroyIcon(p_hIcon);
+ }
+ }
+ else {
+ if(refresh)
+ sfl_hIcon = hIcon;
+ if(sfl_hIcon != (HICON)-1)
+ DrawIconEx(g_SFLCachedDC, 5, (cy - 16) / 2, sfl_hIcon, 16, 16, 0, 0, DI_NORMAL);
+ }
+
+ hOldFont = reinterpret_cast<HFONT>(SelectObject(g_SFLCachedDC, GetStockObject(DEFAULT_GUI_FONT)));
+ SetBkMode(g_SFLCachedDC, TRANSPARENT);
+ GetTextExtentPoint32(g_SFLCachedDC, sfl_statustext, lstrlen(sfl_statustext), &szT);
+ TextOut(g_SFLCachedDC, 24, (cy - szT.cy) / 2, sfl_statustext, lstrlen(sfl_statustext));
+
+ if(cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS) {
+ RECT rcNA = rcClient;
+
+ rcNA.top = 18;
+ PaintNotifyArea(g_SFLCachedDC, &rcNA);
+ }
+
+ SelectObject(g_SFLCachedDC, hOldFont);
+
+ if(API::pfnUpdateLayeredWindow)
+ API::pfnUpdateLayeredWindow(g_hwndSFL, 0, &ptDest, &szDest, g_SFLCachedDC, &ptSrc, GetSysColor(COLOR_3DFACE), &bf, ULW_ALPHA | ULW_COLORKEY);
+}
+
+/*
+ * set the floater
+ * mode = 0/1 forced hide/show
+ * OR -1 to set it depending on the clist state (visible/hidden) (this is actually reversed, because the function
+ * is called *before* the clist is shown or hidden)
+ */
+
+void SFL_SetState(int uMode)
+{
+ BYTE bClistState;
+
+ if(g_hwndSFL == 0 || !(cfg::dat.bUseFloater & CLUI_USE_FLOATER))
+ return;
+
+ if(uMode == -1) {
+ if(cfg::dat.bUseFloater & CLUI_FLOATER_AUTOHIDE) {
+ bClistState = cfg::getByte("CList", "State", SETTING_STATE_NORMAL);
+ ShowWindow(g_hwndSFL, bClistState == SETTING_STATE_NORMAL ? SW_SHOW : SW_HIDE);
+ }
+ else
+ ShowWindow(g_hwndSFL, SW_SHOW);
+ }
+ else
+ ShowWindow(g_hwndSFL, uMode ? SW_SHOW : SW_HIDE);
+}
+
+// XXX improve size calculations for the floater window.
+
+void SFL_SetSize()
+{
+ HDC hdc;
+ LONG lWidth;
+ RECT rcWindow;
+ SIZE sz;
+ char *szStatusMode;
+ HFONT oldFont;
+ int i;
+
+ GetWindowRect(g_hwndSFL, &rcWindow);
+ lWidth = rcWindow.right - rcWindow.left;
+
+ hdc = GetDC(g_hwndSFL);
+ oldFont = reinterpret_cast<HFONT>(SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)));
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) {
+ szStatusMode = Translate((char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)i, 0));
+ GetTextExtentPoint32A(hdc, szStatusMode, lstrlenA(szStatusMode), &sz);
+ lWidth = max(lWidth, sz.cx + 16 + 8);
+ }
+ SetWindowPos(g_hwndSFL, HWND_TOPMOST, rcWindow.left, rcWindow.top, lWidth, max(cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS ? 36 : 20, sz.cy + 4), SWP_SHOWWINDOW);
+ GetWindowRect(g_hwndSFL, &rcWindow);
+
+ if(g_SFLCachedDC) {
+ SelectObject(g_SFLCachedDC, g_SFLhbmOld);
+ DeleteObject(g_SFLhbm);
+ DeleteDC(g_SFLCachedDC);
+ g_SFLCachedDC = 0;
+ }
+
+ g_SFLCachedDC = CreateCompatibleDC(hdc);
+ g_SFLhbm = CreateCompatibleBitmap(hdc, lWidth, rcWindow.bottom - rcWindow.top);
+ g_SFLhbmOld = reinterpret_cast<HBITMAP>(SelectObject(g_SFLCachedDC, g_SFLhbm));
+
+ ReleaseDC(g_hwndSFL, hdc);
+ CluiProtocolStatusChanged(0, 0);
+}
+
+void SFL_Create()
+{
+ if(g_hwndSFL == 0 && cfg::dat.bUseFloater & CLUI_USE_FLOATER && API::pfnUpdateLayeredWindow != NULL)
+ g_hwndSFL = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_LAYERED, _T("StatusFloaterClass"), _T("sfl"), WS_VISIBLE, 0, 0, 0, 0, 0, 0, g_hInst, 0);
+ else
+ return;
+
+ SetWindowLong(g_hwndSFL, GWL_STYLE, GetWindowLong(g_hwndSFL, GWL_STYLE) & ~(WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW));
+
+ Utils_RestoreWindowPosition(g_hwndSFL, 0, "CLUI", "sfl");
+ SFL_SetSize();
+}
+
+void FLT_SetSize(struct TExtraCache *centry, LONG width, LONG height)
+{
+ HDC hdc;
+ RECT rcWindow;
+ HFONT oldFont;
+ int flags = SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOACTIVATE;
+
+ int iVis = pcli->pfnGetWindowVisibleState(pcli->hwndContactList, 0, 0);
+ if((g_floatoptions.dwFlags & FLT_AUTOHIDE) && (iVis == 2 || iVis == 4)) //2 = GWVS_VISIBLE, 4 = GWVS_PARTIALLY_COVERED
+ flags = SWP_NOMOVE | SWP_NOACTIVATE;
+
+ if(centry->floater) {
+ hdc = GetDC(centry->floater->hwnd);
+ oldFont = reinterpret_cast<HFONT>(SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)));
+
+ SetWindowPos(centry->floater->hwnd, HWND_TOPMOST, 0, 0, width, height, flags);
+ GetWindowRect(centry->floater->hwnd, &rcWindow);
+
+ if(centry->floater->hdc) {
+ SelectObject(centry->floater->hdc, centry->floater->hbmOld);
+ DeleteObject(centry->floater->hbm);
+ DeleteDC(centry->floater->hdc);
+ centry->floater->hdc = 0;
+ }
+
+ centry->floater->hdc = CreateCompatibleDC(hdc);
+ centry->floater->hbm = CreateCompatibleBitmap(hdc, width, rcWindow.bottom - rcWindow.top);
+ centry->floater->hbmOld= reinterpret_cast<HBITMAP>(SelectObject(centry->floater->hdc, centry->floater->hbm));
+
+ ReleaseDC(centry->floater->hwnd, hdc);
+ }
+}
+
+void FLT_Create(int iEntry)
+{
+ struct TExtraCache *centry = NULL;
+
+ if(iEntry >= 0 && iEntry < cfg::nextCacheEntry) {
+ struct ClcContact *contact = NULL;
+ struct ClcGroup *group = NULL;
+
+ centry = &cfg::eCache[iEntry];
+ if(centry->floater == 0 && API::pfnUpdateLayeredWindow != NULL) {
+
+ centry->floater = (struct ContactFloater *)malloc(sizeof(struct ContactFloater));
+ if(centry->floater == NULL)
+ return;
+ FLT_AddToList(centry->floater);
+ centry->floater->hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_LAYERED, _T("ContactFloaterClass"), _T("sfl"), WS_VISIBLE, 0, 0, 0, 0, 0, 0, g_hInst, (LPVOID)iEntry);
+ centry->floater->hContact = centry->hContact;
+ }
+ else if(centry->floater != NULL) {
+ ShowWindow(centry->floater->hwnd, SW_SHOWNOACTIVATE);
+ return;
+ }
+
+ SetWindowLong(centry->floater->hwnd, GWL_STYLE, GetWindowLong(centry->floater->hwnd, GWL_STYLE) & ~(WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW));
+
+ if(Utils_RestoreWindowPosition(centry->floater->hwnd, centry->hContact, "CList", "flt"))
+ if(Utils_RestoreWindowPositionNoMove(centry->floater->hwnd, centry->hContact, "CList", "flt"))
+ SetWindowPos(centry->floater->hwnd, 0, 50, 50, 150, 30, SWP_NOZORDER | SWP_NOACTIVATE);
+
+ //FLT_SetSize(centry, 100, 20);
+ ShowWindow(centry->floater->hwnd, SW_SHOWNOACTIVATE);
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, centry->hContact, &contact, &group, 0)) {
+ if(contact)
+ FLT_Update(cfg::clcdat, contact);
+ }
+ }
+}
+
+extern HDC hdcAV;
+extern HDC hdcTempAV;
+extern HBITMAP hbmTempAV, hbmTempOldAV;
+extern LONG g_maxAV_X, g_maxAV_Y;
+
+void FLT_Update(struct ClcData *dat, struct ClcContact *contact)
+{
+ RECT rcClient, rcWindow;
+ POINT ptDest, ptSrc = {0};
+ SIZE szDest;
+ BLENDFUNCTION bf = {0};
+ HWND hwnd;
+ HDC hdc;
+ BOOL firstDrawn = TRUE;
+ struct ClcGroup *group = NULL;
+ struct ClcContact *newContact = NULL;
+ HRGN rgn;
+ HBRUSH hbrBorder;
+ COLORREF clrKey;
+ HBRUSH brKey;
+ float greyLevel;
+
+ if(contact == NULL || dat == NULL)
+ return;
+
+ if(contact->extraCacheEntry < 0 || contact->extraCacheEntry >= cfg::nextCacheEntry)
+ return;
+
+ if(cfg::eCache[contact->extraCacheEntry].floater == NULL)
+ return;
+
+ FLT_SetSize(&cfg::eCache[contact->extraCacheEntry], g_floatoptions.width, RowHeight::getFloatingRowHeight(dat, pcli->hwndContactTree, contact, g_floatoptions.dwFlags) + (2*g_floatoptions.pad_top));
+
+ hwnd = cfg::eCache[contact->extraCacheEntry].floater->hwnd;
+ hdc = cfg::eCache[contact->extraCacheEntry].floater->hdc;
+
+ if(hwnd == 0)
+ return;
+
+ GetClientRect(hwnd, &rcClient);
+ GetWindowRect(hwnd, &rcWindow);
+
+ ptDest.x = rcWindow.left;
+ ptDest.y = rcWindow.top;
+ szDest.cx = rcWindow.right - rcWindow.left;
+ szDest.cy = rcWindow.bottom - rcWindow.top;
+
+ /*
+ * fill with a DESATURATED representation of the clist bg color and use this later as a color key
+ */
+
+ greyLevel = (float)(GetRValue(cfg::clcdat->bkColour) * 0.299 + GetGValue(cfg::clcdat->bkColour) * 0.587 + GetBValue(cfg::clcdat->bkColour) * 0.144);
+ if (greyLevel > 255)
+ greyLevel = 255;
+
+ clrKey = RGB((BYTE)greyLevel, (BYTE)greyLevel, (BYTE)greyLevel);
+ brKey = CreateSolidBrush(clrKey);
+ FillRect(hdc, &rcClient, brKey);
+ DeleteObject(brKey);
+
+ SetBkMode(hdc, TRANSPARENT);
+
+ if(g_floatoptions.dwFlags & FLT_ROUNDED){
+ rgn = CreateRoundRectRgn(0, 0, rcClient.right, rcClient.bottom, g_floatoptions.radius, g_floatoptions.radius);
+ SelectClipRgn(hdc, rgn);
+ if(g_floatoptions.dwFlags & FLT_FILLSTDCOLOR) {
+ HBRUSH br = CreateSolidBrush(cfg::clcdat->bkColour);
+ FillRect(hdc, &rcClient, br);
+ DeleteObject(br);
+ }
+ }
+
+ if(FindItem(pcli->hwndContactTree, dat, contact->hContact, &newContact, &group, 0)) {
+ DWORD oldFlags = cfg::dat.dwFlags;
+ BYTE oldPadding = cfg::dat.avatarPadding;
+ DWORD oldExtraImageMask = cfg::eCache[contact->extraCacheEntry].dwXMask;
+ struct avatarCacheEntry *ace_old = contact->ace;
+ BYTE oldDualRow = contact->bSecondLine;
+
+ int oldLeftMargin = dat->leftMargin;
+ int oldRightMargin = dat->rightMargin;
+
+ if(g_floatoptions.dwFlags & FLT_SIMPLE) {
+ contact->ace = 0;
+ contact->bSecondLine = MULTIROW_NEVER;
+ cfg::dat.dwFlags &= ~(CLUI_SHOWCLIENTICONS | CLUI_SHOWVISI);
+ cfg::eCache[contact->extraCacheEntry].dwXMask = 0;
+ }
+ else{
+ if(!(g_floatoptions.dwFlags & FLT_AVATARS)) {
+ contact->ace = 0;
+ g_list_avatars = 0;
+ }
+ else
+ g_list_avatars = 1;
+
+ if(!(g_floatoptions.dwFlags & FLT_DUALROW))
+ contact->bSecondLine = MULTIROW_NEVER;
+ else
+ contact->bSecondLine = MULTIROW_ALWAYS;
+
+ if(!(g_floatoptions.dwFlags & FLT_EXTRAICONS)) {
+ cfg::dat.dwFlags &= ~(CLUI_SHOWCLIENTICONS | CLUI_SHOWVISI);
+ cfg::eCache[contact->extraCacheEntry].dwXMask = 0;
+ }
+ }
+
+ //g_CluiData.avatarPadding = g_floatoptions.pad_top;
+ dat->leftMargin = g_floatoptions.pad_left;
+ dat->rightMargin = g_floatoptions.pad_right;
+
+ g_HDC = hdc;
+
+ hdcTempAV = CreateCompatibleDC(g_HDC);
+ hdcAV = CreateCompatibleDC(g_HDC);
+ hbmTempAV = CreateCompatibleBitmap(g_HDC, g_maxAV_X, g_maxAV_Y);
+ hbmTempOldAV = reinterpret_cast<HBITMAP>(SelectObject(hdcTempAV, hbmTempAV));
+
+ g_padding_y = g_floatoptions.pad_top;
+ PaintItem(hdc, group, contact, 0, 0, dat, -4, pcli->hwndContactTree, 0, &rcClient, &firstDrawn, 0, rcClient.bottom - rcClient.top);
+ g_padding_y = 0;
+
+ SelectObject(hdcTempAV, hbmTempOldAV);
+ DeleteObject(hbmTempAV);
+ DeleteDC(hdcTempAV);
+ DeleteDC(hdcAV);
+
+ cfg::dat.dwFlags = oldFlags;
+ cfg::dat.avatarPadding = oldPadding;
+ contact->ace = ace_old;
+ contact->bSecondLine = oldDualRow;
+ cfg::eCache[contact->extraCacheEntry].dwXMask = oldExtraImageMask;
+
+ dat->leftMargin = oldLeftMargin;
+ dat->rightMargin = oldRightMargin;
+ }
+
+ if(g_floatoptions.dwFlags & FLT_BORDER){
+ hbrBorder = CreateSolidBrush(g_floatoptions.border_colour);
+ if(g_floatoptions.dwFlags & FLT_ROUNDED)
+ FrameRgn(hdc, rgn, hbrBorder, 1, 1);
+ else
+ FrameRect(hdc, &rcClient, hbrBorder);
+
+ DeleteObject(hbrBorder);
+ }
+
+ if(g_floatoptions.dwFlags & FLT_ROUNDED)
+ DeleteObject(rgn);
+
+ bf.BlendOp = AC_SRC_OVER;
+ bf.AlphaFormat = 0;
+ bf.SourceConstantAlpha = g_floatoptions.trans;
+
+ if(API::pfnUpdateLayeredWindow)
+ API::pfnUpdateLayeredWindow(hwnd, 0, &ptDest, &szDest, hdc, &ptSrc, clrKey /*GetSysColor(COLOR_3DFACE)*/, &bf, ULW_COLORKEY | ULW_ALPHA);
+}
+
+/*
+ * syncs the floating contacts with clist contact visibility.
+ * will hide all floating contacts which are not visible on the list
+ * needed after a list rebuild
+ */
+
+void FLT_SyncWithClist()
+{
+ struct ClcContact *contact;
+ struct ContactFloater *pCurrent = pFirstFloater;
+ HWND hwnd;
+ int iVis = pcli->pfnGetWindowVisibleState(pcli->hwndContactList, 0, 0);
+
+ if(g_floatoptions.dwFlags & FLT_SYNCWITHCLIST){
+ while(pCurrent) {
+ hwnd = pCurrent->hwnd;
+ if(hwnd && IsWindow(hwnd)){
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, pCurrent->hContact, &contact, NULL, 0)) {
+ FLT_Update(cfg::clcdat, contact);
+ if(((g_floatoptions.dwFlags & FLT_AUTOHIDE) && (iVis == 2 || iVis == 4)) || !(g_floatoptions.dwFlags & FLT_AUTOHIDE))
+ ShowWindow(hwnd, SW_SHOWNOACTIVATE);
+ else
+ ShowWindow(hwnd, SW_HIDE);
+ }
+ else
+ ShowWindow(hwnd, SW_HIDE);
+ }
+ pCurrent = pCurrent->pNextFloater;
+ }
+ }
+}
+
+/*
+ * quickly show or hide all floating contacts
+ * used by autohide/show feature
+ */
+
+void FLT_ShowHideAll(int showCmd)
+{
+ struct ClcContact *contact;
+ struct ContactFloater *pCurrent = pFirstFloater;
+ HWND hwnd;
+
+ if(g_floatoptions.dwFlags & FLT_AUTOHIDE){
+ while(pCurrent) {
+ hwnd = pCurrent->hwnd;
+ if(hwnd && IsWindow(hwnd)){
+ if(showCmd == SW_SHOWNOACTIVATE && FindItem(pcli->hwndContactTree, cfg::clcdat, pCurrent->hContact, &contact, NULL, 0))
+ ShowWindow(hwnd, SW_SHOWNOACTIVATE);
+ else if(showCmd != SW_SHOWNOACTIVATE)
+ ShowWindow(hwnd, showCmd);
+ }
+ pCurrent = pCurrent->pNextFloater;
+ }
+ }
+}
+
+/*
+ * update/repaint all contact floaters
+ */
+
+void FLT_RefreshAll()
+{
+ struct ClcContact *contact = NULL;
+ struct ContactFloater *pCurrent = pFirstFloater;
+
+ while(pCurrent) {
+ if(FindItem(pcli->hwndContactTree, cfg::clcdat, pCurrent->hContact, &contact, NULL, 0)) {
+ HWND hwnd = pCurrent->hwnd;
+ if(hwnd && IsWindow(hwnd))
+ FLT_Update(cfg::clcdat, contact);
+ }
+ pCurrent = pCurrent->pNextFloater;
+ }
+}
+
diff --git a/plugins/Clist_nicer/SRC/viewmodes.cpp b/plugins/Clist_nicer/SRC/viewmodes.cpp
new file mode 100644
index 0000000000..ab51b0e121
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/viewmodes.cpp
@@ -0,0 +1,1265 @@
+/*
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+contact list view modes (CLVM)
+
+$Id: viewmodes.cpp 13824 2011-09-03 06:32:11Z borkra $
+
+*/
+
+#include <commonheaders.h>
+#include <m_variables.h>
+#include "../cluiframes/cluiframes.h"
+
+#define TIMERID_VIEWMODEEXPIRE 100
+
+extern HIMAGELIST hCListImages;
+extern HPEN g_hPenCLUIFrames;
+extern wndFrame *wndFrameViewMode;
+
+typedef int (__cdecl *pfnEnumCallback)(char *szName);
+static HWND clvmHwnd = 0;
+static int clvm_curItem = 0;
+HMENU hViewModeMenu = 0;
+
+static HWND hwndSelector = 0;
+static HIMAGELIST himlViewModes = 0;
+static HANDLE hInfoItem = 0;
+static int nullImage;
+static DWORD stickyStatusMask = 0;
+static char g_szModename[2048];
+
+static int g_ViewModeOptDlg = FALSE;
+
+static UINT _page1Controls[] = {IDC_STATIC1, IDC_STATIC2, IDC_STATIC3, IDC_STATIC5, IDC_STATIC4,
+ IDC_STATIC8, IDC_ADDVIEWMODE, IDC_DELETEVIEWMODE, IDC_NEWVIEMODE, IDC_GROUPS, IDC_PROTOCOLS,
+ IDC_VIEWMODES, IDC_STATUSMODES, IDC_STATIC12, IDC_STATIC13, IDC_STATIC14, IDC_PROTOGROUPOP, IDC_GROUPSTATUSOP,
+ IDC_AUTOCLEAR, IDC_AUTOCLEARVAL, IDC_AUTOCLEARSPIN, IDC_STATIC15, IDC_STATIC16,
+ IDC_LASTMESSAGEOP, IDC_LASTMESSAGEUNIT, IDC_LASTMSG, IDC_LASTMSGVALUE, 0};
+
+static UINT _page2Controls[] = {IDC_CLIST, IDC_STATIC9, IDC_STATIC8, IDC_CLEARALL, IDC_CURVIEWMODE2, 0};
+
+
+/*
+ * enumerate all view modes, call the callback function with the mode name
+ * useful for filling lists, menus and so on..
+ */
+
+int CLVM_EnumProc(const char *szSetting, LPARAM lParam)
+{
+ pfnEnumCallback EnumCallback = (pfnEnumCallback)lParam;
+ if (szSetting != NULL)
+ EnumCallback((char *)szSetting);
+ return(0);
+}
+
+void CLVM_EnumModes(pfnEnumCallback EnumCallback)
+{
+ DBCONTACTENUMSETTINGS dbces;
+
+ dbces.pfnEnumProc = CLVM_EnumProc;
+ dbces.szModule = CLVM_MODULE;
+ dbces.ofsSettings=0;
+ dbces.lParam = (LPARAM)EnumCallback;
+ CallService(MS_DB_CONTACT_ENUMSETTINGS,0,(LPARAM)&dbces);
+}
+
+int FillModes(char *szsetting)
+{
+ if(szsetting[0] == 'ö')
+ return 1;
+ SendDlgItemMessageA(clvmHwnd, IDC_VIEWMODES, LB_INSERTSTRING, -1, (LPARAM)szsetting);
+ return 1;
+}
+
+static void ShowPage(HWND hwnd, int page)
+{
+ int i = 0;
+ int pageChange = 0;
+
+ if(page == 0 && IsWindowVisible(GetDlgItem(hwnd, _page2Controls[0])))
+ pageChange = 1;
+
+ if(page == 1 && IsWindowVisible(GetDlgItem(hwnd, _page1Controls[0])))
+ pageChange = 1;
+
+ if(pageChange)
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
+
+ switch(page) {
+ case 0:
+ while(_page1Controls[i] != 0)
+ ShowWindow(GetDlgItem(hwnd, _page1Controls[i++]), SW_SHOW);
+ i = 0;
+ while(_page2Controls[i] != 0)
+ ShowWindow(GetDlgItem(hwnd, _page2Controls[i++]), SW_HIDE);
+ break;
+ case 1:
+ while(_page1Controls[i] != 0)
+ ShowWindow(GetDlgItem(hwnd, _page1Controls[i++]), SW_HIDE);
+ i = 0;
+ while(_page2Controls[i] != 0)
+ ShowWindow(GetDlgItem(hwnd, _page2Controls[i++]), SW_SHOW);
+ break;
+ }
+ if(pageChange) {
+ SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
+ }
+}
+
+static int UpdateClistItem(HANDLE hContact, DWORD mask)
+{
+ int i;
+
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++)
+ SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_SETEXTRAIMAGE, (WPARAM)hContact, MAKELONG(i - ID_STATUS_OFFLINE,
+ (1 << (i - ID_STATUS_OFFLINE)) & mask ? i - ID_STATUS_OFFLINE : nullImage));
+
+ return 0;
+}
+
+static DWORD GetMaskForItem(HANDLE hItem)
+{
+ int i;
+ DWORD dwMask = 0;
+
+ for(i = 0; i <= ID_STATUS_OUTTOLUNCH - ID_STATUS_OFFLINE; i++)
+ dwMask |= (SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i) == nullImage ? 0 : 1 << i);
+
+ return dwMask;
+}
+
+static void UpdateStickies()
+{
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ HANDLE hItem;
+ DWORD localMask;
+ int i;
+
+ while(hContact) {
+ hItem = (HANDLE)SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ if(hItem)
+ SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM)hItem, cfg::getByte(hContact, "CLVM", g_szModename, 0) ? 1 : 0);
+ localMask = HIWORD(cfg::getDword(hContact, "CLVM", g_szModename, 0));
+ UpdateClistItem(hItem, (localMask == 0 || localMask == stickyStatusMask) ? stickyStatusMask : localMask);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+
+ {
+ HANDLE hItem;
+
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++)
+ SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_SETEXTRAIMAGE, (WPARAM)hInfoItem, MAKELONG(i - ID_STATUS_OFFLINE, (1 << (i - ID_STATUS_OFFLINE)) & stickyStatusMask ? i - ID_STATUS_OFFLINE : ID_STATUS_OUTTOLUNCH - ID_STATUS_OFFLINE + 1));
+
+ hItem=(HANDLE)SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_GETNEXTITEM,CLGN_ROOT,0);
+ hItem=(HANDLE)SendDlgItemMessage(clvmHwnd, IDC_CLIST,CLM_GETNEXTITEM,CLGN_NEXTGROUP, (LPARAM)hItem);
+ while(hItem) {
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++)
+ SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELONG(i - ID_STATUS_OFFLINE, nullImage));
+ hItem=(HANDLE)SendDlgItemMessage(clvmHwnd, IDC_CLIST,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hItem);
+ }
+ ShowPage(clvmHwnd, 0);
+ }
+}
+
+static int FillDialog(HWND hwnd)
+{
+ LVCOLUMN lvc = {0};
+ HWND hwndList = GetDlgItem(hwnd, IDC_PROTOCOLS);
+ LVITEMA item = {0};
+ int protoCount = 0, i, newItem;
+ PROTOACCOUNT **accs = 0;
+
+ CLVM_EnumModes(FillModes);
+ ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_PROTOCOLS), LVS_EX_CHECKBOXES);
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(GetDlgItem(hwnd, IDC_PROTOCOLS), 0, &lvc);
+
+ // fill protocols...
+
+ ProtoEnumAccounts( &protoCount, &accs );
+ item.mask = LVIF_TEXT;
+ item.iItem = 1000;
+ for (i = 0; i < protoCount; i++) {
+ item.pszText = accs[i]->szModuleName;
+ newItem = SendMessageA(hwndList, LVM_INSERTITEMA, 0, (LPARAM)&item);
+ }
+
+ ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
+ ListView_Arrange(hwndList, LVA_ALIGNLEFT | LVA_ALIGNTOP);
+
+ // fill groups
+ {
+ LVITEM item = {0};
+ char buf[20];
+ DBVARIANT dbv = {0};
+
+ hwndList = GetDlgItem(hwnd, IDC_GROUPS);
+
+ ListView_SetExtendedListViewStyle(hwndList, LVS_EX_CHECKBOXES);
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(hwndList, 0, &lvc);
+
+ item.mask = LVIF_TEXT;
+ item.iItem = 1000;
+
+ item.pszText = TranslateT("Ungrouped contacts");
+ newItem = SendMessage(hwndList, LVM_INSERTITEM, 0, (LPARAM)&item);
+
+ for(i = 0;;i++) {
+ mir_snprintf(buf, 20, "%d", i);
+ if(cfg::getTString(NULL, "CListGroups", buf, &dbv))
+ break;
+
+ item.pszText = &dbv.ptszVal[1];
+ newItem = SendMessage(hwndList, LVM_INSERTITEM, 0, (LPARAM)&item);
+ DBFreeVariant(&dbv);
+ }
+ ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
+ ListView_Arrange(hwndList, LVA_ALIGNLEFT | LVA_ALIGNTOP);
+ }
+ hwndList = GetDlgItem(hwnd, IDC_STATUSMODES);
+ ListView_SetExtendedListViewStyle(hwndList, LVS_EX_CHECKBOXES);
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(hwndList, 0, &lvc);
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) {
+ item.pszText = Translate((char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)i, 0));
+ item.iItem = i - ID_STATUS_OFFLINE;
+ newItem = SendMessageA(hwndList, LVM_INSERTITEMA, 0, (LPARAM)&item);
+ }
+ ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
+ ListView_Arrange(hwndList, LVA_ALIGNLEFT | LVA_ALIGNTOP);
+
+ SendDlgItemMessage(hwnd, IDC_PROTOGROUPOP, CB_INSERTSTRING, -1, (LPARAM)TranslateT("And"));
+ SendDlgItemMessage(hwnd, IDC_PROTOGROUPOP, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Or"));
+ SendDlgItemMessage(hwnd, IDC_GROUPSTATUSOP, CB_INSERTSTRING, -1, (LPARAM)TranslateT("And"));
+ SendDlgItemMessage(hwnd, IDC_GROUPSTATUSOP, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Or"));
+
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEOP, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Older than"));
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEOP, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Newer than"));
+
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEUNIT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Minutes"));
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEUNIT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Hours"));
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEUNIT, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Days"));
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEOP, CB_SETCURSEL, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_LASTMESSAGEUNIT, CB_SETCURSEL, 0, 0);
+ SetDlgItemInt(hwnd, IDC_LASTMSGVALUE, 0, 0);
+ return 0;
+}
+
+static void SetAllChildIcons(HWND hwndList,HANDLE hFirstItem,int iColumn,int iImage)
+{
+ int typeOfFirst,iOldIcon;
+ HANDLE hItem,hChildItem;
+
+ typeOfFirst=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem,0);
+ //check groups
+ if(typeOfFirst==CLCIT_GROUP) hItem=hFirstItem;
+ else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hFirstItem);
+ while(hItem) {
+ hChildItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem);
+ if(hChildItem)
+ SetAllChildIcons(hwndList,hChildItem,iColumn,iImage);
+ hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hItem);
+ }
+ //check contacts
+ if(typeOfFirst==CLCIT_CONTACT) hItem=hFirstItem;
+ else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hFirstItem);
+ while(hItem) {
+ iOldIcon=SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn);
+ if(iOldIcon!=0xFF && iOldIcon!=iImage) SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage));
+ hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem);
+ }
+}
+
+static void SetIconsForColumn(HWND hwndList,HANDLE hItem,HANDLE hItemAll,int iColumn,int iImage)
+{
+ int itemType;
+
+ itemType=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hItem,0);
+ if(itemType==CLCIT_CONTACT) {
+ int oldiImage = SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn);
+ if (oldiImage!=0xFF&&oldiImage!=iImage)
+ SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage));
+ }
+ else if(itemType==CLCIT_INFO) {
+ int oldiImage = SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn);
+ if (oldiImage!=0xFF&&oldiImage!=iImage)
+ SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage));
+ if(hItem == hItemAll)
+ SetAllChildIcons(hwndList,hItem,iColumn,iImage);
+ else
+ SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage)); //hItemUnknown
+ }
+ else if(itemType==CLCIT_GROUP) {
+ int oldiImage = SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn);
+ if (oldiImage!=0xFF&&oldiImage!=iImage)
+ SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage));
+ hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem);
+ if(hItem)
+ SetAllChildIcons(hwndList,hItem,iColumn,iImage);
+ }
+}
+
+void SaveViewMode(const char *name, const TCHAR *szGroupFilter, const char *szProtoFilter, DWORD statusMask, DWORD stickyStatusMask, unsigned int options,
+ unsigned int stickies, unsigned int operators, unsigned int lmdat)
+{
+ char szSetting[512];
+
+ mir_snprintf(szSetting, 512, "%c%s_PF", 246, name);
+ cfg::writeString(NULL, CLVM_MODULE, szSetting, szProtoFilter);
+ mir_snprintf(szSetting, 512, "%c%s_GF", 246, name);
+ cfg::writeTString(NULL, CLVM_MODULE, szSetting, szGroupFilter);
+ mir_snprintf(szSetting, 512, "%c%s_SM", 246, name);
+ cfg::writeDword(CLVM_MODULE, szSetting, statusMask);
+ mir_snprintf(szSetting, 512, "%c%s_SSM", 246, name);
+ cfg::writeDword(CLVM_MODULE, szSetting, stickyStatusMask);
+ mir_snprintf(szSetting, 512, "%c%s_OPT", 246, name);
+ cfg::writeDword(CLVM_MODULE, szSetting, options);
+ mir_snprintf(szSetting, 512, "%c%s_LM", 246, name);
+ cfg::writeDword(CLVM_MODULE, szSetting, lmdat);
+
+ cfg::writeDword(CLVM_MODULE, name, MAKELONG((unsigned short)operators, (unsigned short)stickies));
+}
+
+/*
+ * saves the state of the filter definitions for the current item
+ */
+
+void SaveState()
+{
+ TCHAR newGroupFilter[2048] = _T("|");
+ char newProtoFilter[2048] = "|";
+ int i, iLen;
+ HWND hwndList;
+ char *szModeName = NULL;
+ DWORD statusMask = 0;
+ HANDLE hContact, hItem;
+ DWORD operators = 0;
+
+ if(clvm_curItem == -1)
+ return;
+
+ {
+ LVITEMA item = {0};
+ char szTemp[256];
+
+ hwndList = GetDlgItem(clvmHwnd, IDC_PROTOCOLS);
+ for(i = 0; i < ListView_GetItemCount(hwndList); i++) {
+ if(ListView_GetCheckState(hwndList, i)) {
+ item.mask = LVIF_TEXT;
+ item.pszText = szTemp;
+ item.cchTextMax = 255;
+ item.iItem = i;
+ SendMessageA(hwndList, LVM_GETITEMA, 0, (LPARAM)&item);
+ strncat(newProtoFilter, szTemp, 2048);
+ strncat(newProtoFilter, "|", 2048);
+ newProtoFilter[2047] = 0;
+ }
+ }
+ }
+
+ {
+ LVITEM item = {0};
+ TCHAR szTemp[256];
+
+ hwndList = GetDlgItem(clvmHwnd, IDC_GROUPS);
+
+ operators |= ListView_GetCheckState(hwndList, 0) ? CLVM_INCLUDED_UNGROUPED : 0;
+
+ for(i = 0; i < ListView_GetItemCount(hwndList); i++) {
+ if(ListView_GetCheckState(hwndList, i)) {
+ item.mask = LVIF_TEXT;
+ item.pszText = szTemp;
+ item.cchTextMax = 255;
+ item.iItem = i;
+ SendMessage(hwndList, LVM_GETITEM, 0, (LPARAM)&item);
+ _tcsncat(newGroupFilter, szTemp, 2048);
+ _tcsncat(newGroupFilter, _T("|"), 2048);
+ newGroupFilter[2047] = 0;
+ }
+ }
+ }
+ hwndList = GetDlgItem(clvmHwnd, IDC_STATUSMODES);
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) {
+ if(ListView_GetCheckState(hwndList, i - ID_STATUS_OFFLINE))
+ statusMask |= (1 << (i - ID_STATUS_OFFLINE));
+ }
+ iLen = SendMessageA(GetDlgItem(clvmHwnd, IDC_VIEWMODES), LB_GETTEXTLEN, clvm_curItem, 0);
+ if(iLen) {
+ unsigned int stickies = 0;
+ DWORD dwGlobalMask, dwLocalMask;
+ BOOL translated;
+
+ szModeName = ( char* )malloc(iLen + 1);
+ if(szModeName) {
+ DWORD options, lmdat;
+ //char *vastring = NULL;
+ //int len = GetWindowTextLengthA(GetDlgItem(clvmHwnd, IDC_VARIABLES)) + 1;
+
+ //vastring = (char *)malloc(len);
+ //if(vastring)
+ // GetDlgItemTextA(clvmHwnd, IDC_VARIABLES, vastring, len);
+ SendDlgItemMessageA(clvmHwnd, IDC_VIEWMODES, LB_GETTEXT, clvm_curItem, (LPARAM)szModeName);
+ dwGlobalMask = GetMaskForItem(hInfoItem);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact) {
+ hItem = (HANDLE)SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ if(hItem) {
+ if(SendDlgItemMessage(clvmHwnd, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) {
+ dwLocalMask = GetMaskForItem(hItem);
+ cfg::writeDword(hContact, "CLVM", szModeName, MAKELONG(1, (unsigned short)dwLocalMask));
+ stickies++;
+ }
+ else {
+ if(cfg::getDword(hContact, "CLVM", szModeName, 0))
+ cfg::writeDword(hContact, "CLVM", szModeName, 0);
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ operators |= ((SendDlgItemMessage(clvmHwnd, IDC_PROTOGROUPOP, CB_GETCURSEL, 0, 0) == 1 ? CLVM_PROTOGROUP_OP : 0) |
+ (SendDlgItemMessage(clvmHwnd, IDC_GROUPSTATUSOP, CB_GETCURSEL, 0, 0) == 1 ? CLVM_GROUPSTATUS_OP : 0) |
+ (IsDlgButtonChecked(clvmHwnd, IDC_AUTOCLEAR) ? CLVM_AUTOCLEAR : 0) |
+ (IsDlgButtonChecked(clvmHwnd, IDC_LASTMSG) ? CLVM_USELASTMSG : 0));
+
+ options = SendDlgItemMessage(clvmHwnd, IDC_AUTOCLEARSPIN, UDM_GETPOS, 0, 0);
+
+ lmdat = MAKELONG(GetDlgItemInt(clvmHwnd, IDC_LASTMSGVALUE, &translated, FALSE),
+ MAKEWORD(SendDlgItemMessage(clvmHwnd, IDC_LASTMESSAGEOP, CB_GETCURSEL, 0, 0),
+ SendDlgItemMessage(clvmHwnd, IDC_LASTMESSAGEUNIT, CB_GETCURSEL, 0, 0)));
+
+ SaveViewMode(szModeName, newGroupFilter, newProtoFilter, statusMask, dwGlobalMask, options,
+ stickies, operators, lmdat);
+ //free(vastring);
+ free(szModeName);
+ }
+ }
+ Utils::enableDlgControl(clvmHwnd, IDC_APPLY, FALSE);
+}
+
+
+/*
+ * updates the filter list boxes with the data taken from the filtering string
+ */
+
+void UpdateFilters()
+{
+ DBVARIANT dbv_pf = {0};
+ DBVARIANT dbv_gf = {0};
+ char szSetting[128];
+ char *szBuf = NULL;
+ int iLen;
+ DWORD statusMask = 0, localMask = 0;
+ DWORD dwFlags;
+ DWORD opt;
+ char szTemp[100];
+
+ if(clvm_curItem == LB_ERR)
+ return;
+
+ iLen = SendDlgItemMessageA(clvmHwnd, IDC_VIEWMODES, LB_GETTEXTLEN, clvm_curItem, 0);
+
+ if(iLen == 0)
+ return;
+
+ szBuf = (char *)malloc(iLen + 1);
+ SendDlgItemMessageA(clvmHwnd, IDC_VIEWMODES, LB_GETTEXT, clvm_curItem, (LPARAM)szBuf);
+ strncpy(g_szModename, szBuf, sizeof(g_szModename));
+ g_szModename[sizeof(g_szModename) - 1] = 0;
+ mir_snprintf(szTemp, 100, Translate("Current view mode: %s"), g_szModename);
+ SetDlgItemTextA(clvmHwnd, IDC_CURVIEWMODE2, szTemp);
+ mir_snprintf(szSetting, 128, "%c%s_PF", 246, szBuf);
+ if(DBGetContactSetting(NULL, CLVM_MODULE, szSetting, &dbv_pf))
+ goto cleanup;
+ mir_snprintf(szSetting, 128, "%c%s_GF", 246, szBuf);
+ if(cfg::getTString(NULL, CLVM_MODULE, szSetting, &dbv_gf))
+ goto cleanup;
+ mir_snprintf(szSetting, 128, "%c%s_OPT", 246, szBuf);
+ if((opt = cfg::getDword(NULL, CLVM_MODULE, szSetting, -1)) != -1) {
+ SendDlgItemMessage(clvmHwnd, IDC_AUTOCLEARSPIN, UDM_SETPOS, 0, MAKELONG(LOWORD(opt), 0));
+ }
+ mir_snprintf(szSetting, 128, "%c%s_SM", 246, szBuf);
+ statusMask = cfg::getDword(CLVM_MODULE, szSetting, -1);
+ mir_snprintf(szSetting, 128, "%c%s_SSM", 246, szBuf);
+ stickyStatusMask = cfg::getDword(CLVM_MODULE, szSetting, -1);
+ dwFlags = cfg::getDword(CLVM_MODULE, szBuf, 0);
+ {
+ LVITEMA item = {0};
+ char szTemp[256];
+ char szMask[256];
+ int i;
+ HWND hwndList = GetDlgItem(clvmHwnd, IDC_PROTOCOLS);
+
+ item.mask = LVIF_TEXT;
+ item.pszText = szTemp;
+ item.cchTextMax = 255;
+
+ for(i = 0; i < ListView_GetItemCount(hwndList); i++) {
+ item.iItem = i;
+ SendMessageA(hwndList, LVM_GETITEMA, 0, (LPARAM)&item);
+ mir_snprintf(szMask, 256, "%s|", szTemp);
+ if(dbv_pf.pszVal && strstr(dbv_pf.pszVal, szMask))
+ ListView_SetCheckState(hwndList, i, TRUE)
+ else
+ ListView_SetCheckState(hwndList, i, FALSE);
+ }
+ }
+ {
+ LVITEM item = {0};
+ TCHAR szTemp[256];
+ TCHAR szMask[256];
+ int i;
+ HWND hwndList = GetDlgItem(clvmHwnd, IDC_GROUPS);
+
+ item.mask = LVIF_TEXT;
+ item.pszText = szTemp;
+ item.cchTextMax = 255;
+
+ ListView_SetCheckState(hwndList, 0, dwFlags & CLVM_INCLUDED_UNGROUPED ? TRUE : FALSE);
+
+ for(i = 1; i < ListView_GetItemCount(hwndList); i++) {
+ item.iItem = i;
+ SendMessage(hwndList, LVM_GETITEM, 0, (LPARAM)&item);
+ _sntprintf(szMask, 256, _T("%s|"), szTemp);
+ if(dbv_gf.ptszVal && _tcsstr(dbv_gf.ptszVal, szMask))
+ ListView_SetCheckState(hwndList, i, TRUE)
+ else
+ ListView_SetCheckState(hwndList, i, FALSE);
+ }
+ }
+ {
+ HWND hwndList = GetDlgItem(clvmHwnd, IDC_STATUSMODES);
+ int i;
+
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) {
+ if((1 << (i - ID_STATUS_OFFLINE)) & statusMask)
+ ListView_SetCheckState(hwndList, i - ID_STATUS_OFFLINE, TRUE)
+ else
+ ListView_SetCheckState(hwndList, i - ID_STATUS_OFFLINE, FALSE);
+ }
+ }
+ SendDlgItemMessage(clvmHwnd, IDC_PROTOGROUPOP, CB_SETCURSEL, dwFlags & CLVM_PROTOGROUP_OP ? 1 : 0, 0);
+ SendDlgItemMessage(clvmHwnd, IDC_GROUPSTATUSOP, CB_SETCURSEL, dwFlags & CLVM_GROUPSTATUS_OP ? 1 : 0, 0);
+ CheckDlgButton(clvmHwnd, IDC_AUTOCLEAR, dwFlags & CLVM_AUTOCLEAR ? 1 : 0);
+ UpdateStickies();
+
+ {
+ int useLastMsg = dwFlags & CLVM_USELASTMSG;
+ DWORD lmdat;
+ BYTE bTmp;
+
+ CheckDlgButton(clvmHwnd, IDC_LASTMSG, useLastMsg);
+ Utils::enableDlgControl(clvmHwnd, IDC_LASTMESSAGEOP, useLastMsg);
+ Utils::enableDlgControl(clvmHwnd, IDC_LASTMSGVALUE, useLastMsg);
+ Utils::enableDlgControl(clvmHwnd, IDC_LASTMESSAGEUNIT, useLastMsg);
+
+ mir_snprintf(szSetting, 128, "%c%s_LM", 246, szBuf);
+ lmdat = cfg::getDword(CLVM_MODULE, szSetting, 0);
+
+ SetDlgItemInt(clvmHwnd, IDC_LASTMSGVALUE, LOWORD(lmdat), FALSE);
+ bTmp = LOBYTE(HIWORD(lmdat));
+ SendDlgItemMessage(clvmHwnd, IDC_LASTMESSAGEOP, CB_SETCURSEL, bTmp, 0);
+ bTmp = HIBYTE(HIWORD(lmdat));
+ SendDlgItemMessage(clvmHwnd, IDC_LASTMESSAGEUNIT, CB_SETCURSEL, bTmp, 0);
+ }
+
+ ShowPage(clvmHwnd, 0);
+cleanup:
+ DBFreeVariant(&dbv_pf);
+ DBFreeVariant(&dbv_gf);
+ free(szBuf);
+}
+
+INT_PTR CALLBACK DlgProcViewModesSetup(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ clvmHwnd = hwndDlg;
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ int i = 0;
+ TCITEMA tci;
+ RECT rcClient;
+ CLCINFOITEM cii = {0};
+ HICON hIcon;
+
+ if(IS_THEMED)
+ API::pfnEnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB);
+
+ himlViewModes = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16), 12, 0);
+ for(i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++)
+ ImageList_AddIcon(himlViewModes, LoadSkinnedProtoIcon(NULL, i));
+
+ hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MINIMIZE), IMAGE_ICON, 16, 16, 0);
+ nullImage = ImageList_AddIcon(himlViewModes, hIcon);
+ DestroyIcon(hIcon);
+ GetClientRect(hwndDlg, &rcClient);
+
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+ tci.lParam = 0;
+ tci.pszText = Translate("Sticky contacts");
+ SendMessageA(GetDlgItem(hwndDlg, IDC_TAB), TCM_INSERTITEMA, (WPARAM)0, (LPARAM)&tci);
+
+ tci.pszText = Translate("Filtering");
+ SendMessageA(GetDlgItem(hwndDlg, IDC_TAB), TCM_INSERTITEMA, (WPARAM)0, (LPARAM)&tci);
+
+ TabCtrl_SetCurSel(GetDlgItem(hwndDlg, IDC_TAB), 0);
+
+ TranslateDialogDefault(hwndDlg);
+ FillDialog(hwndDlg);
+ Utils::enableDlgControl(hwndDlg, IDC_ADDVIEWMODE, FALSE);
+
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)himlViewModes);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETEXTRACOLUMNS, ID_STATUS_OUTTOLUNCH - ID_STATUS_OFFLINE, 0);
+ cii.cbSize = sizeof(cii);
+ cii.hParentGroup = 0;
+ cii.pszText = _T("*** All contacts ***");
+ hInfoItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM)&cii);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETHIDEEMPTYGROUPS, 1, 0);
+ if(SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_SETCURSEL, 0, 0) != LB_ERR) {
+ clvm_curItem = 0;
+ UpdateFilters();
+ }
+ else
+ clvm_curItem = -1;
+ g_ViewModeOptDlg = TRUE;
+ i = 0;
+ while(_page2Controls[i] != 0)
+ ShowWindow(GetDlgItem(hwndDlg, _page2Controls[i++]), SW_HIDE);
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ Utils::enableDlgControl(hwndDlg, IDC_APPLY, FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_AUTOCLEARSPIN, UDM_SETRANGE, 0, MAKELONG(1000, 0));
+ SetWindowText(hwndDlg, TranslateT("Configure view modes"));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_PROTOGROUPOP:
+ case IDC_GROUPSTATUSOP:
+ case IDC_LASTMESSAGEUNIT:
+ case IDC_LASTMESSAGEOP:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE);
+ break;
+ case IDC_AUTOCLEAR:
+ Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE);
+ break;
+ case IDC_LASTMSG:
+ {
+ int bUseLastMsg = IsDlgButtonChecked(hwndDlg, IDC_LASTMSG);
+ Utils::enableDlgControl(hwndDlg, IDC_LASTMESSAGEOP, bUseLastMsg);
+ Utils::enableDlgControl(hwndDlg, IDC_LASTMESSAGEUNIT, bUseLastMsg);
+ Utils::enableDlgControl(hwndDlg, IDC_LASTMSGVALUE, bUseLastMsg);
+ Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE);
+ break;
+ }
+ case IDC_AUTOCLEARVAL:
+ case IDC_LASTMSGVALUE:
+ if(HIWORD(wParam) == EN_CHANGE && GetFocus() == (HWND)lParam)
+ Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE);
+ break;
+ case IDC_DELETEVIEWMODE:
+ {
+ if(MessageBoxA(0, Translate("Really delete this view mode? This cannot be undone"), Translate("Delete a view mode"), MB_YESNO | MB_ICONQUESTION) == IDYES) {
+ char szSetting[256];
+ int iLen = SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_GETTEXTLEN, SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_GETCURSEL, 0, 0), 0);
+ if(iLen) {
+ char *szBuf = ( char* )malloc(iLen + 1);
+ if(szBuf) {
+ HANDLE hContact;
+
+ SendDlgItemMessageA(hwndDlg, IDC_VIEWMODES, LB_GETTEXT, SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_GETCURSEL, 0, 0), (LPARAM)szBuf);
+ mir_snprintf(szSetting, 256, "%c%s_PF", 246, szBuf);
+ DBDeleteContactSetting(NULL, CLVM_MODULE, szSetting);
+ mir_snprintf(szSetting, 256, "%c%s_GF", 246, szBuf);
+ DBDeleteContactSetting(NULL, CLVM_MODULE, szSetting);
+ mir_snprintf(szSetting, 256, "%c%s_SM", 246, szBuf);
+ DBDeleteContactSetting(NULL, CLVM_MODULE, szSetting);
+ mir_snprintf(szSetting, 256, "%c%s_VA", 246, szBuf);
+ DBDeleteContactSetting(NULL, CLVM_MODULE, szSetting);
+ mir_snprintf(szSetting, 256, "%c%s_SSM", 246, szBuf);
+ DBDeleteContactSetting(NULL, CLVM_MODULE, szSetting);
+ DBDeleteContactSetting(NULL, CLVM_MODULE, szBuf);
+ if(!strcmp(cfg::dat.current_viewmode, szBuf) && lstrlenA(szBuf) == lstrlenA(cfg::dat.current_viewmode)) {
+ cfg::dat.bFilterEffective = 0;
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ SetWindowTextA(hwndSelector, Translate("No view mode"));
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact) {
+ if(cfg::getDword(hContact, "CLVM", szBuf, -1) != -1)
+ cfg::writeDword(hContact, "CLVM", szBuf, 0);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_DELETESTRING, SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_GETCURSEL, 0, 0), 0);
+ if(SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_SETCURSEL, 0, 0) != LB_ERR) {
+ clvm_curItem = 0;
+ UpdateFilters();
+ }
+ else
+ clvm_curItem = -1;
+ free(szBuf);
+ }
+ }
+ }
+ break;
+ }
+ case IDC_ADDVIEWMODE:
+ {
+ char szBuf[256];
+
+ szBuf[0] = 0;
+ GetDlgItemTextA(hwndDlg, IDC_NEWVIEMODE, szBuf, 256);
+ szBuf[255] = 0;
+
+ if(lstrlenA(szBuf) > 2) {
+ if(cfg::getDword(CLVM_MODULE, szBuf, -1) != -1)
+ MessageBox(0, TranslateT("A view mode with this name does alredy exist"), TranslateT("Duplicate name"), MB_OK);
+ else {
+ int iNewItem = SendDlgItemMessageA(hwndDlg, IDC_VIEWMODES, LB_INSERTSTRING, -1, (LPARAM)szBuf);
+ if(iNewItem != LB_ERR) {
+ SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_SETCURSEL, (WPARAM)iNewItem, 0);
+ SaveViewMode(szBuf, _T(""), "", -1, -1, 0, 0, 0, 0);
+ clvm_curItem = iNewItem;
+ UpdateStickies();
+ SendDlgItemMessage(hwndDlg, IDC_PROTOGROUPOP, CB_SETCURSEL, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_GROUPSTATUSOP, CB_SETCURSEL, 0, 0);
+ }
+ }
+ SetDlgItemTextA(hwndDlg, IDC_NEWVIEMODE, "");
+ }
+ Utils::enableDlgControl(hwndDlg, IDC_ADDVIEWMODE, FALSE);
+ break;
+ }
+ case IDC_CLEARALL:
+ {
+ HANDLE hItem;
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ while(hContact) {
+ hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ if(hItem)
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM)hItem, 0);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ }
+ case IDOK:
+ case IDC_APPLY:
+ SaveState();
+ if(cfg::dat.bFilterEffective)
+ ApplyViewMode(cfg::dat.current_viewmode);
+ if(LOWORD(wParam) == IDOK)
+ DestroyWindow(hwndDlg);
+ break;
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ if(LOWORD(wParam) == IDC_NEWVIEMODE && HIWORD(wParam) == EN_CHANGE)
+ Utils::enableDlgControl(hwndDlg, IDC_ADDVIEWMODE, TRUE);
+ if(LOWORD(wParam) == IDC_VIEWMODES && HIWORD(wParam) == LBN_SELCHANGE) {
+ SaveState();
+ clvm_curItem = SendDlgItemMessage(hwndDlg, IDC_VIEWMODES, LB_GETCURSEL, 0, 0);
+ UpdateFilters();
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case IDC_GROUPS:
+ case IDC_STATUSMODES:
+ case IDC_PROTOCOLS:
+ case IDC_CLIST:
+ if (((LPNMHDR) lParam)->code == NM_CLICK || ((LPNMHDR) lParam)->code == CLN_CHECKCHANGED)
+ Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE);
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case CLN_NEWCONTACT:
+ case CLN_LISTREBUILT:
+ //SetAllContactIcons(GetDlgItem(hwndDlg,IDC_CLIST));
+ //fall through
+ /*
+ case CLN_CONTACTMOVED:
+ SetListGroupIcons(GetDlgItem(hwndDlg,IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETNEXTITEM,CLGN_ROOT,0),hItemAll,NULL);
+ break;
+ case CLN_OPTIONSCHANGED:
+ ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST));
+ break;
+ case CLN_CHECKCHANGED:
+ {
+ HANDLE hItem;
+ NMCLISTCONTROL *nm=(NMCLISTCONTROL*)lParam;
+ int typeOfItem = SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETITEMTYPE,(WPARAM)nm->hItem, 0);
+ break;
+ }*/
+ case NM_CLICK:
+ {
+ HANDLE hItem;
+ NMCLISTCONTROL *nm=(NMCLISTCONTROL*)lParam;
+ DWORD hitFlags;
+ int iImage;
+
+ if(nm->iColumn==-1)
+ break;
+ hItem = (HANDLE)SendDlgItemMessage(hwndDlg,IDC_CLIST,CLM_HITTEST,(WPARAM)&hitFlags,MAKELPARAM(nm->pt.x,nm->pt.y));
+ if(hItem==NULL) break;
+ if(!(hitFlags&CLCHT_ONITEMEXTRA))
+ break;
+ iImage = SendDlgItemMessage(hwndDlg,IDC_CLIST,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(nm->iColumn,0));
+ if(iImage == nullImage)
+ iImage = nm->iColumn;
+ else if(iImage!=0xFF)
+ iImage = nullImage;
+ SetIconsForColumn(GetDlgItem(hwndDlg,IDC_CLIST),hItem,hInfoItem,nm->iColumn,iImage);
+ //SetListGroupIcons(GetDlgItem(hwndDlg,IDC_CLIST),(HANDLE)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETNEXTITEM,CLGN_ROOT,0),hInfoItem,NULL);
+ break;
+ }
+ }
+ break;
+ case IDC_TAB:
+ if (((LPNMHDR) lParam)->code == TCN_SELCHANGE) {
+ int id = TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TAB));
+ if(id == 0)
+ ShowPage(hwndDlg, 0);
+ else
+ ShowPage(hwndDlg, 1);
+ break;
+ }
+
+ }
+ break;
+ }
+ case WM_DESTROY:
+ ImageList_RemoveAll(himlViewModes);
+ ImageList_Destroy(himlViewModes);
+ g_ViewModeOptDlg = FALSE;
+ break;
+ }
+ return FALSE;
+}
+
+static int menuCounter = 0;
+
+static int FillMenuCallback(char *szSetting)
+{
+ if(szSetting[0] == (char)246)
+ return 1;
+
+ AppendMenuA(hViewModeMenu, MF_STRING, menuCounter++, szSetting);
+ return 1;
+}
+
+void BuildViewModeMenu()
+{
+ if(hViewModeMenu)
+ DestroyMenu(hViewModeMenu);
+
+ menuCounter = 100;
+ hViewModeMenu = CreatePopupMenu();
+ CLVM_EnumModes(FillMenuCallback);
+
+ if(GetMenuItemCount(hViewModeMenu) > 0)
+ AppendMenu(hViewModeMenu, MF_SEPARATOR, 0, NULL);
+
+ AppendMenu(hViewModeMenu, MF_STRING, 10001, TranslateT("Setup View Modes..."));
+ AppendMenu(hViewModeMenu, MF_STRING, 10002, TranslateT("Clear current View Mode"));
+
+}
+
+static UINT _buttons[] = {IDC_RESETMODES, IDC_SELECTMODE, IDC_CONFIGUREMODES, 0};
+
+LRESULT CALLBACK ViewModeFrameWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_CREATE:
+ {
+ HWND hwndButton;
+
+ hwndSelector = CreateWindowEx(0, _T("CLCButtonClass"), _T(""), BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20,
+ hwnd, (HMENU) IDC_SELECTMODE, g_hInst, NULL);
+ SendMessage(hwndSelector, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Select a view mode"), 0);
+ SendMessage(hwndSelector, BM_SETASMENUACTION, 1, 0);
+ hwndButton = CreateWindowEx(0, _T("CLCButtonClass"), _T(""), BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20,
+ hwnd, (HMENU) IDC_CONFIGUREMODES, g_hInst, NULL);
+ SendMessage(hwndButton, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Setup view modes"), 0);
+ hwndButton = CreateWindowEx(0, _T("CLCButtonClass"), _T(""), BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20,
+ hwnd, (HMENU) IDC_RESETMODES, g_hInst, NULL);
+ SendMessage(hwndButton, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Clear view mode and return to default display"), 0);
+ SendMessage(hwnd, WM_USER + 100, 0, 0);
+ return FALSE;
+ }
+ case WM_NCCALCSIZE:
+ {
+ BOOL hasTitleBar = wndFrameViewMode ? wndFrameViewMode->TitleBar.ShowTitleBar : 0;
+ return FrameNCCalcSize(hwnd, DefWindowProc, wParam, lParam, hasTitleBar);
+ }
+ case WM_NCPAINT:
+ {
+ BOOL hasTitleBar = wndFrameViewMode ? wndFrameViewMode->TitleBar.ShowTitleBar : 0;
+ return FrameNCPaint(hwnd, DefWindowProc, wParam, lParam, hasTitleBar);
+ }
+ case WM_SIZE:
+ {
+ RECT rcCLVMFrame;
+ HDWP PosBatch = BeginDeferWindowPos(3);
+ GetClientRect(hwnd, &rcCLVMFrame);
+ PosBatch = DeferWindowPos(PosBatch, GetDlgItem(hwnd, IDC_RESETMODES), 0,
+ rcCLVMFrame.right - 23, 1, 22, 20, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
+ PosBatch = DeferWindowPos(PosBatch, GetDlgItem(hwnd, IDC_CONFIGUREMODES), 0,
+ rcCLVMFrame.right - 45, 1, 22, 20, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
+ PosBatch = DeferWindowPos(PosBatch, GetDlgItem(hwnd, IDC_SELECTMODE), 0,
+ 1, 1, rcCLVMFrame.right - 46, 20, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
+ EndDeferWindowPos(PosBatch);
+ break;
+ }
+ case WM_USER + 100:
+ if(cfg::dat.IcoLib_Avail) {
+ SendMessage(GetDlgItem(hwnd, IDC_RESETMODES), BM_SETIMAGE, IMAGE_ICON, (LPARAM)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"CLN_CLVM_reset"));
+ SendMessage(GetDlgItem(hwnd, IDC_CONFIGUREMODES), BM_SETIMAGE, IMAGE_ICON, (LPARAM)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"CLN_CLVM_options"));
+ SendMessage(GetDlgItem(hwnd, IDC_SELECTMODE), BM_SETIMAGE, IMAGE_ICON, (LPARAM)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"CLN_CLVM_select"));
+ }
+ else {
+ SendMessage(GetDlgItem(hwnd, IDC_RESETMODES), BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_DELETE), IMAGE_ICON, 16, 16, LR_SHARED));
+ SendMessage(GetDlgItem(hwnd, IDC_CONFIGUREMODES), BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_CLVM_OPTIONS), IMAGE_ICON, 16, 16, LR_SHARED));
+ SendMessage(GetDlgItem(hwnd, IDC_SELECTMODE), BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_CLVM_SELECT), IMAGE_ICON, 16, 16, LR_SHARED));
+ }
+ {
+ int bSkinned = cfg::getByte("CLCExt", "bskinned", 0);
+ int i = 0;
+
+ while(_buttons[i] != 0) {
+ SendMessage(GetDlgItem(hwnd, _buttons[i]), BM_SETSKINNED, 0, bSkinned);
+ if(bSkinned) {
+ SendDlgItemMessage(hwnd, _buttons[i], BUTTONSETASFLATBTN, 0, 0);
+ SendDlgItemMessage(hwnd, _buttons[i], BUTTONSETASFLATBTN + 10, 0, 0);
+ }
+ else {
+ SendDlgItemMessage(hwnd, _buttons[i], BUTTONSETASFLATBTN, 0, 1);
+ SendDlgItemMessage(hwnd, _buttons[i], BUTTONSETASFLATBTN + 10, 0, 1);
+ }
+ i++;
+ }
+ }
+ if(cfg::dat.bFilterEffective)
+ SetWindowTextA(GetDlgItem(hwnd, IDC_SELECTMODE), cfg::dat.current_viewmode);
+ else
+ SetWindowText(GetDlgItem(hwnd, IDC_SELECTMODE), TranslateT("No view mode"));
+ break;
+
+ case WM_ERASEBKGND:
+ break;
+
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwnd, &ps);
+ RECT rc;
+ //HDC hdc = (HDC)wParam;
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ HBITMAP hbm, hbmold;
+
+ GetClientRect(hwnd, &rc);
+ hbm = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
+ hbmold = (HBITMAP)SelectObject(hdcMem, hbm);
+
+ if(cfg::dat.bWallpaperMode)
+ SkinDrawBg(hwnd, hdcMem);
+ else
+ FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE));
+
+ BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY);
+ SelectObject(hdcMem, hbmold);
+ DeleteObject(hbm);
+ DeleteDC(hdcMem);
+ //InvalidateRect(GetDlgItem(hwnd, IDC_RESETMODES), NULL, FALSE);
+ //InvalidateRect(GetDlgItem(hwnd, IDC_CONFIGUREMODES), NULL, FALSE);
+ //InvalidateRect(GetDlgItem(hwnd, IDC_SELECTMODE), NULL, FALSE);
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ case WM_TIMER:
+ {
+ switch(wParam) {
+ case TIMERID_VIEWMODEEXPIRE:
+ {
+ POINT pt;
+ RECT rcCLUI;
+
+ GetWindowRect(pcli->hwndContactList, &rcCLUI);
+ GetCursorPos(&pt);
+ if(PtInRect(&rcCLUI, pt))
+ break;
+
+ KillTimer(hwnd, wParam);
+ if(!cfg::dat.old_viewmode[0])
+ SendMessage(hwnd, WM_COMMAND, IDC_RESETMODES, 0);
+ else
+ ApplyViewMode((const char *)cfg::dat.old_viewmode);
+ break;
+ } }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam)) {
+ case IDC_SELECTMODE:
+ {
+ RECT rc;
+ POINT pt;
+ int selection;
+ MENUITEMINFOA mii = {0};
+ char szTemp[256];
+
+ BuildViewModeMenu();
+ //GetWindowRect(GetDlgItem(hwnd, IDC_SELECTMODE), &rc);
+ GetWindowRect((HWND)lParam, &rc);
+ pt.x = rc.left;
+ pt.y = rc.bottom;
+ selection = TrackPopupMenu(hViewModeMenu,TPM_RETURNCMD|TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
+ if(selection) {
+
+ if(selection == 10001)
+ goto clvm_config_command;
+ else if(selection == 10002)
+ goto clvm_reset_command;
+
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING;
+ mii.dwTypeData = szTemp;
+ mii.cch = 256;
+ GetMenuItemInfoA(hViewModeMenu, selection, FALSE, &mii);
+ ApplyViewMode(szTemp);
+ }
+ break;
+ }
+ case IDC_RESETMODES:
+clvm_reset_command:
+ cfg::dat.bFilterEffective = 0;
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ SetWindowTextA(GetDlgItem(hwnd, IDC_SELECTMODE), Translate("No view mode"));
+ CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)cfg::dat.boldHideOffline, 0);
+ cfg::dat.boldHideOffline = (BYTE)-1;
+ SetButtonStates(pcli->hwndContactList);
+ cfg::dat.current_viewmode[0] = 0;
+ cfg::dat.old_viewmode[0] = 0;
+ cfg::writeString(NULL, "CList", "LastViewMode", "");
+ break;
+ case IDC_CONFIGUREMODES:
+clvm_config_command:
+ if(!g_ViewModeOptDlg)
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_OPT_VIEWMODES), 0, DlgProcViewModesSetup, 0);
+ break;
+ }
+ break;
+ }
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return TRUE;
+}
+
+static HWND hCLVMFrame;
+HWND g_hwndViewModeFrame;
+
+void CreateViewModeFrame()
+{
+ CLISTFrame frame = {0};
+ WNDCLASS wndclass = {0};
+
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = ViewModeFrameWndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = g_hInst;
+ wndclass.hIcon = 0;
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH) (COLOR_3DFACE);
+ wndclass.lpszMenuName = 0;
+ wndclass.lpszClassName = _T("CLVMFrameWindow");
+
+ RegisterClass(&wndclass);
+
+ ZeroMemory(&frame, sizeof(frame));
+ frame.cbSize = sizeof(frame);
+ frame.tname = _T("View modes");
+ frame.TBtname = TranslateT("View Modes");
+ frame.hIcon = 0;
+ frame.height = 22;
+ frame.Flags=F_VISIBLE|F_SHOWTBTIP|F_NOBORDER|F_TCHAR;
+ frame.align = alBottom;
+ frame.hWnd = CreateWindowEx(0, _T("CLVMFrameWindow"), _T("CLVM"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_CLIPCHILDREN, 0, 0, 20, 20, pcli->hwndContactList, (HMENU) 0, g_hInst, NULL);
+ g_hwndViewModeFrame = frame.hWnd;
+ hCLVMFrame = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&frame,(LPARAM)0);
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)hCLVMFrame, FU_FMPOS);
+}
+
+const char *MakeVariablesString(const char *src, const char *UIN);
+
+void ApplyViewMode(const char *name)
+{
+ char szSetting[256];
+ DBVARIANT dbv = {0};
+
+ cfg::dat.bFilterEffective = 0;
+
+ mir_snprintf(szSetting, 256, "%c%s_PF", 246, name);
+ if(!cfg::getString(NULL, CLVM_MODULE, szSetting, &dbv)) {
+ if(lstrlenA(dbv.pszVal) >= 2) {
+ strncpy(cfg::dat.protoFilter, dbv.pszVal, sizeof(cfg::dat.protoFilter));
+ cfg::dat.protoFilter[sizeof(cfg::dat.protoFilter) - 1] = 0;
+ cfg::dat.bFilterEffective |= CLVM_FILTER_PROTOS;
+ }
+ mir_free(dbv.pszVal);
+ }
+ mir_snprintf(szSetting, 256, "%c%s_GF", 246, name);
+ if(!cfg::getTString(NULL, CLVM_MODULE, szSetting, &dbv)) {
+ if(lstrlen(dbv.ptszVal) >= 2) {
+ _tcsncpy(cfg::dat.groupFilter, dbv.ptszVal, safe_sizeof(cfg::dat.groupFilter));
+ cfg::dat.groupFilter[safe_sizeof(cfg::dat.groupFilter) - 1] = 0;
+ cfg::dat.bFilterEffective |= CLVM_FILTER_GROUPS;
+ }
+ mir_free(dbv.ptszVal);
+ }
+ mir_snprintf(szSetting, 256, "%c%s_SM", 246, name);
+ cfg::dat.statusMaskFilter = cfg::getDword(CLVM_MODULE, szSetting, -1);
+ if(cfg::dat.statusMaskFilter >= 1)
+ cfg::dat.bFilterEffective |= CLVM_FILTER_STATUS;
+
+ mir_snprintf(szSetting, 256, "%c%s_SSM", 246, name);
+ cfg::dat.stickyMaskFilter = cfg::getDword(CLVM_MODULE, szSetting, -1);
+ if(cfg::dat.stickyMaskFilter != -1)
+ cfg::dat.bFilterEffective |= CLVM_FILTER_STICKYSTATUS;
+
+ /*
+ mir_snprintf(szSetting, 256, "%c%s_VA", 246, name);
+ if(!DBGetContactSettingString(NULL, CLVM_MODULE, szSetting, &dbv)) {
+ strncpy(g_CluiData.varFilter, dbv.pszVal, sizeof(g_CluiData.varFilter));
+ g_CluiData.varFilter[sizeof(g_CluiData.varFilter) - 1] = 0;
+ if(lstrlenA(g_CluiData.varFilter) > 10 && ServiceExists(MS_VARS_FORMATSTRING))
+ g_CluiData.bFilterEffective |= CLVM_FILTER_VARIABLES;
+ mir_free(dbv.ptszVal);
+ if(g_CluiData.bFilterEffective & CLVM_FILTER_VARIABLES) {
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ char UIN[256];
+ char *id, *szProto;
+ const char *varstring;
+ char *temp;
+ FORMATINFO fi;
+
+ while(hContact) {
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(szProto) {
+ id = (char*) CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if(id) {
+ if(!DBGetContactSetting(hContact, szProto, id, &dbv)) {
+ if(dbv.type == DBVT_ASCIIZ) {
+ mir_snprintf(UIN, 256, "<%s:%s>", szProto, dbv.pszVal);
+ }
+ else {
+ mir_snprintf(UIN, 256, "<%s:%d>", szProto, dbv.dVal);
+ }
+ varstring = MakeVariablesString(g_CluiData.varFilter, UIN);
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.szFormat = varstring;
+ fi.szSource = "";
+ fi.hContact = 0;
+ temp = (char *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if(temp && atol(temp) > 0)
+ _DebugPopup(hContact, "%s, %d, %d, %d", temp, temp, fi.pCount, fi.eCount);
+ variables_free(temp);
+ DBFreeVariant(&dbv);
+ }
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ }
+ }*/
+
+ cfg::dat.filterFlags = cfg::getDword(CLVM_MODULE, name, 0);
+
+ KillTimer(g_hwndViewModeFrame, TIMERID_VIEWMODEEXPIRE);
+
+ if(cfg::dat.filterFlags & CLVM_AUTOCLEAR) {
+ DWORD timerexpire;
+ mir_snprintf(szSetting, 256, "%c%s_OPT", 246, name);
+ timerexpire = LOWORD(cfg::getDword(CLVM_MODULE, szSetting, 0));
+ strncpy(cfg::dat.old_viewmode, cfg::dat.current_viewmode, 256);
+ cfg::dat.old_viewmode[255] = 0;
+ SetTimer(g_hwndViewModeFrame, TIMERID_VIEWMODEEXPIRE, timerexpire * 1000, NULL);
+ }
+ strncpy(cfg::dat.current_viewmode, name, 256);
+ cfg::dat.current_viewmode[255] = 0;
+
+ if(cfg::dat.filterFlags & CLVM_USELASTMSG) {
+ DWORD unit;
+ int i;
+ BYTE bSaved = cfg::dat.sortOrder[0];
+
+ cfg::dat.sortOrder[0] = SORTBY_LASTMSG;
+ for(i = 0; i < cfg::nextCacheEntry; i++)
+ cfg::eCache[i].dwLastMsgTime = INTSORT_GetLastMsgTime(cfg::eCache[i].hContact);
+
+ cfg::dat.sortOrder[0] = bSaved;
+
+ cfg::dat.bFilterEffective |= CLVM_FILTER_LASTMSG;
+ mir_snprintf(szSetting, 256, "%c%s_LM", 246, name);
+ cfg::dat.lastMsgFilter = cfg::getDword(CLVM_MODULE, szSetting, 0);
+ if(LOBYTE(HIWORD(cfg::dat.lastMsgFilter)))
+ cfg::dat.bFilterEffective |= CLVM_FILTER_LASTMSG_NEWERTHAN;
+ else
+ cfg::dat.bFilterEffective |= CLVM_FILTER_LASTMSG_OLDERTHAN;
+ unit = LOWORD(cfg::dat.lastMsgFilter);
+ switch(HIBYTE(HIWORD(cfg::dat.lastMsgFilter))) {
+ case 0:
+ unit *= 60;
+ break;
+ case 1:
+ unit *= 3600;
+ break;
+ case 2:
+ unit *= 86400;
+ break;
+ }
+ cfg::dat.lastMsgFilter = unit;
+ }
+
+ if(HIWORD(cfg::dat.filterFlags) > 0)
+ cfg::dat.bFilterEffective |= CLVM_STICKY_CONTACTS;
+
+ if(cfg::dat.boldHideOffline == (BYTE)-1)
+ cfg::dat.boldHideOffline = cfg::getByte("CList", "HideOffline", 0);
+
+ CallService(MS_CLIST_SETHIDEOFFLINE, 0, 0);
+ SetWindowTextA(hwndSelector, name);
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ SetButtonStates(pcli->hwndContactList);
+
+ cfg::writeString(NULL, "CList", "LastViewMode", cfg::dat.current_viewmode);
+}
+
+
diff --git a/plugins/Clist_nicer/SRC/wallpaper.cpp b/plugins/Clist_nicer/SRC/wallpaper.cpp
new file mode 100644
index 0000000000..1e16afe50a
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/wallpaper.cpp
@@ -0,0 +1,56 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <commonheaders.h>
+
+typedef enum {
+ WPS_TILED=0,
+ WPS_CENTERED,
+ WPS_STRETCHED
+} wallpaperstyle_t;
+
+HBITMAP hPattern;
+HBITMAP hAsSeenOnDesk;
+
+/*
+void GetWallpaperPattern()
+{
+ // \Control Panel\Desktop
+ char wpbuf[MAX_PATH];
+ if(hPattern) {DeleteObject(hPattern); hPattern=NULL;}
+ SystemParametersInfo(SPI_GETDESKWALLPAPER,MAX_PATH,wpbuf,NULL);
+
+ if (strlen(wpbuf)>0)
+ {
+ hPattern = (HBITMAP)CallService(MS_UTILS_LOADBITMAP,0,(LPARAM)wpbuf);
+ }
+}
+
+void GetWallpaperStyle()
+{
+ HKEY regk;
+ char buff[256];
+ RegOpenKeyEx(HKEY_CURRENT_USER,"\\Control Panel\\Desktop",0,KEY_READ,&regk);
+ RegQueryValueEx(regk,"OriginalWallpaper",0,NULL,&buff,256);
+ MessageBox(0,buff,"",0);
+}*/ \ No newline at end of file