summaryrefslogtreecommitdiff
path: root/plugins/Clist_nicer/SRC/CLUIFrames
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Clist_nicer/SRC/CLUIFrames')
-rw-r--r--plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.cpp3584
-rw-r--r--plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.h105
-rw-r--r--plugins/Clist_nicer/SRC/CLUIFrames/framesmenu.cpp228
-rw-r--r--plugins/Clist_nicer/SRC/CLUIFrames/groupmenu.cpp704
-rw-r--r--plugins/Clist_nicer/SRC/CLUIFrames/movetogroup.cpp60
5 files changed, 4681 insertions, 0 deletions
diff --git a/plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.cpp b/plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.cpp
new file mode 100644
index 0000000000..8fbaa547e6
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.cpp
@@ -0,0 +1,3584 @@
+/*
+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-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.h"
+HFONT __fastcall ChangeToFont(HDC hdc, struct ClcData *dat, int id, int *fontHeight);
+
+extern HIMAGELIST himlExtraImages;
+extern HWND g_hwndViewModeFrame, g_hwndEventArea;
+extern StatusItems_t *StatusItems;
+extern int mf_updatethread_running;
+
+extern DWORD WINAPI MF_UpdateThread(LPVOID p);
+extern HANDLE hThreadMFUpdate;;
+
+HANDLE hExtraImageListRebuilding, hExtraImageApplying;
+HANDLE hStatusBarShowToolTipEvent, hStatusBarHideToolTipEvent;
+HANDLE g_hEventThread = 0;
+
+//not needed,now use MS_CLIST_FRAMEMENUNOTIFY service
+//HANDLE hPreBuildFrameMenuEvent;//external event from clistmenus
+
+LOGFONT TitleBarLogFont = {0};
+
+extern HINSTANCE g_hInst;
+
+//we use dynamic frame list,
+//but who wants so huge number of frames ??
+#define MAX_FRAMES 40
+
+#define UNCOLLAPSED_FRAME_SIZE 0
+
+//legacy menu support
+#define frame_menu_lock 1
+#define frame_menu_visible 2
+#define frame_menu_showtitlebar 3
+#define frame_menu_floating 4
+#define frame_menu_skinned 5
+
+extern INT_PTR ModifyMenuItemProxy(WPARAM wParam, LPARAM lParam);
+static int UpdateTBToolTip(int framepos);
+INT_PTR CLUIFrameSetFloat(WPARAM wParam, LPARAM lParam);
+int CLUIFrameResizeFloatingFrame(int framepos);
+extern int ProcessCommandProxy(WPARAM wParam, LPARAM lParam);
+extern int InitFramesMenus(void);
+extern int UnitFramesMenu();
+static int CLUIFramesReSort();
+
+boolean FramesSysNotStarted = TRUE;
+HPEN g_hPenCLUIFrames = 0;
+
+typedef struct {
+ int order;
+ int realpos;
+} SortData;
+
+static SortData g_sd[MAX_FRAMES];
+
+static HHOOK g_hFrameHook = 0;
+
+static int sortfunc(const void *a, const void *b)
+{
+ SortData *sd1, *sd2;
+ sd1 = (SortData *)a;
+ sd2 = (SortData *)b;
+ if (sd1->order > sd2->order)
+ return(1);
+ if (sd1->order < sd2->order)
+ return(-1);
+ return(0);
+}
+
+#define CLUIFRAMESSETALIGN "CLUIFramesSetAlign"
+#define CLUIFRAMESSETALIGNALTOP "CLUIFramesSetAlignalTop"
+#define CLUIFRAMESSETALIGNALCLIENT "CLUIFramesSetAlignalClient"
+#define CLUIFRAMESSETALIGNALBOTTOM "CLUIFramesSetAlignalBottom"
+#define CLUIFRAMESMOVEUP "CLUIFramesMoveUp"
+#define CLUIFRAMESMOVEDOWN "CLUIFramesMoveDown"
+
+static wndFrame *Frames = NULL;
+
+wndFrame *wndFrameCLC = NULL, *wndFrameEventArea = NULL, *wndFrameViewMode = NULL;
+
+static int nFramescount = 0;
+static int alclientFrame = -1;//for fast access to frame with alclient properties
+static int NextFrameId = 100;
+
+static int TitleBarH = DEFAULT_TITLEBAR_HEIGHT;
+static boolean resizing = FALSE;
+
+// menus
+static HANDLE contMIVisible, contMITitle, contMITBVisible, contMILock, contMIColl, contMIFloating;
+static HANDLE contMIAlignRoot;
+static HANDLE contMIAlignTop, contMIAlignClient, contMIAlignBottom;
+static HANDLE contMIBorder, contMISkinned;
+static HANDLE MainMIRoot = (HANDLE) - 1;
+
+// others
+static int ContactListHeight;
+static int LastStoreTick = 0;
+
+static int lbypos = -1;
+static int oldframeheight = -1;
+static int curdragbar = -1;
+static CRITICAL_SECTION csFrameHook;
+
+static BOOLEAN CLUIFramesFitInSize(void);
+HWND hWndExplorerToolBar;
+static int GapBetweenFrames = 1;
+
+static int RemoveItemFromList(int pos, wndFrame **lpFrames, int *FrameItemCount)
+{
+ memcpy(&((*lpFrames)[pos]), &((*lpFrames)[pos+1]), sizeof(wndFrame)*(*FrameItemCount - pos - 1));
+ (*FrameItemCount)--;
+ return 0;
+}
+
+static int id2pos(int id)
+{
+ int i;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ for (i = 0;i < nFramescount;i++) {
+ if (Frames[i].id == id)
+ return(i);
+ }
+ return(-1);
+}
+
+int __forceinline btoint(BOOLEAN b)
+{
+ return(b ? 1 : 0);
+}
+
+void __forceinline lockfrm()
+{
+ if (FramesSysNotStarted == FALSE)
+ EnterCriticalSection(&csFrameHook);
+}
+
+void __forceinline ulockfrm()
+{
+ LeaveCriticalSection(&csFrameHook);
+}
+
+static wndFrame* FindFrameByWnd(HWND hwnd)
+{
+ BOOL bFound = FALSE;
+ int i;
+
+ if (hwnd == NULL)
+ return(NULL);
+
+ for (i = 0;i < nFramescount;i++) {
+ if ((Frames[i].floating) && (Frames[i].ContainerWnd == hwnd))
+ return(&Frames[i]);
+ }
+ return(NULL);
+}
+
+
+static void DockThumbs(wndFrame *pThumbLeft, wndFrame *pThumbRight, BOOL bMoveLeft)
+{
+ if ((pThumbRight->dockOpt.hwndLeft == NULL) && (pThumbLeft->dockOpt.hwndRight == NULL)) {
+ pThumbRight->dockOpt.hwndLeft = pThumbLeft->ContainerWnd;
+ pThumbLeft->dockOpt.hwndRight = pThumbRight->ContainerWnd;
+ }
+}
+
+
+static void UndockThumbs(wndFrame *pThumb1, wndFrame *pThumb2)
+{
+ if ((pThumb1 == NULL) || (pThumb2 == NULL))
+ return;
+
+ if (pThumb1->dockOpt.hwndRight == pThumb2->ContainerWnd)
+ pThumb1->dockOpt.hwndRight = NULL;
+
+ if (pThumb1->dockOpt.hwndLeft == pThumb2->ContainerWnd)
+ pThumb1->dockOpt.hwndLeft = NULL;
+
+ if (pThumb2->dockOpt.hwndRight == pThumb1->ContainerWnd)
+ pThumb2->dockOpt.hwndRight = NULL;
+
+ if (pThumb2->dockOpt.hwndLeft == pThumb1->ContainerWnd)
+ pThumb2->dockOpt.hwndLeft = NULL;
+}
+
+BOOLEAN bMoveTogether;
+
+static void PositionThumb(wndFrame *pThumb, short nX, short nY)
+{
+ wndFrame *pCurThumb = &Frames[0];
+ wndFrame *pDockThumb = pThumb;
+ wndFrame fakeMainWindow;
+ wndFrame fakeTaskBarWindow;
+ RECT rc;
+ RECT rcThumb;
+ RECT rcOld;
+ SIZE sizeScreen;
+ int nNewX;
+ int nNewY;
+ int nOffs = 10;
+ int nWidth;
+ int nHeight;
+ POINT pt;
+ RECT rcLeft;
+ RECT rcTop;
+ RECT rcRight;
+ RECT rcBottom;
+ BOOL bDocked;
+ BOOL bDockedLeft;
+ BOOL bDockedRight;
+ BOOL bLeading;
+ int frmidx = 0;
+
+ if (pThumb == NULL)
+ return;
+
+ sizeScreen.cx = GetSystemMetrics(SM_CXSCREEN);
+ sizeScreen.cy = GetSystemMetrics(SM_CYSCREEN);
+
+ // Get thumb dimnsions
+ GetWindowRect(pThumb->ContainerWnd, &rcThumb);
+ nWidth = rcThumb.right - rcThumb.left;
+ nHeight = rcThumb.bottom - rcThumb.top;
+
+ // Docking to the edges of the screen
+ nNewX = nX < nOffs ? 0 : nX;
+ nNewX = nNewX > (sizeScreen.cx - nWidth - nOffs) ? (sizeScreen.cx - nWidth) : nNewX;
+ nNewY = nY < nOffs ? 0 : nY;
+ nNewY = nNewY > (sizeScreen.cy - nHeight - nOffs) ? (sizeScreen.cy - nHeight) : nNewY;
+
+ bLeading = pThumb->dockOpt.hwndRight != NULL;
+
+ if (bMoveTogether) {
+ UndockThumbs(pThumb, FindFrameByWnd(pThumb->dockOpt.hwndLeft));
+ GetWindowRect(pThumb->ContainerWnd, &rcOld);
+ }
+
+ memset(&fakeMainWindow, 0, sizeof(fakeMainWindow));
+ fakeMainWindow.ContainerWnd = pcli->hwndContactList;
+ fakeMainWindow.floating = TRUE;
+
+ memset(&fakeTaskBarWindow, 0, sizeof(fakeTaskBarWindow));
+ fakeTaskBarWindow.ContainerWnd = hWndExplorerToolBar;
+ fakeTaskBarWindow.floating = TRUE;
+
+
+ while (pCurThumb != NULL) {
+ if (pCurThumb->floating) {
+
+ if (pCurThumb != pThumb) {
+ GetWindowRect(pThumb->ContainerWnd, &rcThumb);
+ OffsetRect(&rcThumb, nX - rcThumb.left, nY - rcThumb.top);
+
+ GetWindowRect(pCurThumb->ContainerWnd, &rc);
+
+ rcLeft.left = rc.left - nOffs;
+ rcLeft.top = rc.top - nOffs;
+ rcLeft.right = rc.left + nOffs;
+ rcLeft.bottom = rc.bottom + nOffs;
+
+ rcTop.left = rc.left - nOffs;
+ rcTop.top = rc.top - nOffs;
+ rcTop.right = rc.right + nOffs;
+ rcTop.bottom = rc.top + nOffs;
+
+ rcRight.left = rc.right - nOffs;
+ rcRight.top = rc.top - nOffs;
+ rcRight.right = rc.right + nOffs;
+ rcRight.bottom = rc.bottom + nOffs;
+
+ rcBottom.left = rc.left - nOffs;
+ rcBottom.top = rc.bottom - nOffs;
+ rcBottom.right = rc.right + nOffs;
+ rcBottom.bottom = rc.bottom + nOffs;
+
+
+ bDockedLeft = FALSE;
+ bDockedRight = FALSE;
+
+ // Upper-left
+ pt.x = rcThumb.left;
+ pt.y = rcThumb.top;
+ bDocked = FALSE;
+
+ if (PtInRect(&rcRight, pt)) {
+ nNewX = rc.right;
+ bDocked = TRUE;
+ }
+
+ if (PtInRect(&rcBottom, pt)) {
+ nNewY = rc.bottom;
+
+ if (PtInRect(&rcLeft, pt))
+ nNewX = rc.left;
+ }
+
+ if (PtInRect(&rcTop, pt)) {
+ nNewY = rc.top;
+ bDockedLeft = bDocked;
+ }
+
+ // Upper-right
+ pt.x = rcThumb.right;
+ pt.y = rcThumb.top;
+ bDocked = FALSE;
+
+ if (!bLeading && PtInRect(&rcLeft, pt)) {
+ if (!bDockedLeft) {
+ nNewX = rc.left - nWidth;
+ bDocked = TRUE;
+ } else if (rc.right == rcThumb.left)
+ bDocked = TRUE;
+ }
+
+
+ if (PtInRect(&rcBottom, pt)) {
+ nNewY = rc.bottom;
+
+ if (PtInRect(&rcRight, pt))
+ nNewX = rc.right - nWidth;
+ }
+
+ if (!bLeading && PtInRect(&rcTop, pt)) {
+ nNewY = rc.top;
+ bDockedRight = bDocked;
+ }
+
+ if (bMoveTogether) {
+ if (bDockedRight) {
+ DockThumbs(pThumb, pCurThumb, TRUE);
+ }
+
+ if (bDockedLeft) {
+ DockThumbs(pCurThumb, pThumb, FALSE);
+ }
+ }
+
+ // Lower-left
+ pt.x = rcThumb.left;
+ pt.y = rcThumb.bottom;
+
+ if (PtInRect(&rcRight, pt)) {
+ nNewX = rc.right;
+ }
+
+ if (PtInRect(&rcTop, pt)) {
+ nNewY = rc.top - nHeight;
+
+ if (PtInRect(&rcLeft, pt)) {
+ nNewX = rc.left;
+ }
+ }
+
+
+ // Lower-right
+ pt.x = rcThumb.right;
+ pt.y = rcThumb.bottom;
+
+ if (!bLeading && PtInRect(&rcLeft, pt)) {
+ nNewX = rc.left - nWidth;
+ }
+
+ if (!bLeading && PtInRect(&rcTop, pt)) {
+ nNewY = rc.top - nHeight;
+
+ if (PtInRect(&rcRight, pt)) {
+ nNewX = rc.right - nWidth;
+ }
+ }
+ }
+
+ };
+ frmidx++;
+ if (pCurThumb->ContainerWnd == fakeTaskBarWindow.ContainerWnd)
+ break;
+ if (pCurThumb->ContainerWnd == fakeMainWindow.ContainerWnd) {
+ pCurThumb = &fakeTaskBarWindow;
+ continue;
+ }
+ if (frmidx == nFramescount) {
+ pCurThumb = &fakeMainWindow;
+ continue;
+ }
+ pCurThumb = &Frames[frmidx];
+ }
+
+ // Adjust coords once again
+ nNewX = nNewX < nOffs ? 0 : nNewX;
+ nNewX = nNewX > (sizeScreen.cx - nWidth - nOffs) ? (sizeScreen.cx - nWidth) : nNewX;
+ nNewY = nNewY < nOffs ? 0 : nNewY;
+ nNewY = nNewY > (sizeScreen.cy - nHeight - nOffs) ? (sizeScreen.cy - nHeight) : nNewY;
+
+ SetWindowPos(pThumb->ContainerWnd,
+ 0,
+ nNewX,
+ nNewY,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER);
+
+
+ // OK, move all docked thumbs
+ if (bMoveTogether) {
+ pDockThumb = FindFrameByWnd(pDockThumb->dockOpt.hwndRight);
+
+ PositionThumb(pDockThumb, (short)(nNewX + nWidth), (short)nNewY);
+ }
+}
+
+void GetBorderSize(HWND hwnd, RECT *rect)
+{
+ RECT wr, cr;
+ POINT pt1, pt2;
+
+ GetWindowRect(hwnd, &wr);
+ GetClientRect(hwnd, &cr);
+ pt1.y = cr.top;
+ pt1.x = cr.left;
+ pt2.y = cr.bottom;
+ pt2.x = cr.right;
+
+ ClientToScreen(hwnd, &pt1);
+ ClientToScreen(hwnd, &pt2);
+
+ cr.top = pt1.y;
+ cr.left = pt1.x;
+ cr.bottom = pt2.y;
+ cr.right = pt2.x;
+
+ rect->top = cr.top - wr.top;
+ rect->left = cr.left - wr.left;
+ rect->right = wr.right - cr.right;
+ rect->bottom = wr.bottom - cr.bottom;
+}
+
+//append string
+char __forceinline *AS(char *str, const char *setting, char *addstr)
+{
+ if (str != NULL) {
+ strcpy(str, setting);
+ strcat(str, addstr);
+ }
+ return str;
+}
+
+int DBLoadFrameSettingsAtPos(int pos, int Frameid)
+{
+ char sadd[15];
+ char buf[255];
+
+ _itoa(pos, sadd, 10);
+
+ Frames[Frameid].collapsed = cfg::getByte(CLUIFrameModule, AS(buf, "Collapse", sadd), Frames[Frameid].collapsed);
+
+ Frames[Frameid].Locked = cfg::getByte(CLUIFrameModule, AS(buf, "Locked", sadd), Frames[Frameid].Locked);
+ Frames[Frameid].visible = cfg::getByte(CLUIFrameModule, AS(buf, "Visible", sadd), Frames[Frameid].visible);
+ Frames[Frameid].TitleBar.ShowTitleBar = cfg::getByte(CLUIFrameModule, AS(buf, "TBVisile", sadd), Frames[Frameid].TitleBar.ShowTitleBar);
+
+ Frames[Frameid].height = cfg::getWord(CLUIFrameModule, AS(buf, "Height", sadd), Frames[Frameid].height);
+ Frames[Frameid].HeightWhenCollapsed = cfg::getWord(CLUIFrameModule, AS(buf, "HeightCollapsed", sadd), 0);
+ Frames[Frameid].align = cfg::getWord(CLUIFrameModule, AS(buf, "Align", sadd), Frames[Frameid].align);
+
+ Frames[Frameid].FloatingPos.x = DBGetContactSettingRangedWord(0, CLUIFrameModule, AS(buf, "FloatX", sadd), 100, 0, 1024);
+ Frames[Frameid].FloatingPos.y = DBGetContactSettingRangedWord(0, CLUIFrameModule, AS(buf, "FloatY", sadd), 100, 0, 1024);
+ Frames[Frameid].FloatingSize.x = DBGetContactSettingRangedWord(0, CLUIFrameModule, AS(buf, "FloatW", sadd), 100, 0, 1024);
+ Frames[Frameid].FloatingSize.y = DBGetContactSettingRangedWord(0, CLUIFrameModule, AS(buf, "FloatH", sadd), 100, 0, 1024);
+
+ Frames[Frameid].floating = cfg::getByte(CLUIFrameModule, AS(buf, "Floating", sadd), 0);
+ Frames[Frameid].order = cfg::getWord(CLUIFrameModule, AS(buf, "Order", sadd), 0);
+
+ Frames[Frameid].UseBorder = cfg::getByte(CLUIFrameModule, AS(buf, "UseBorder", sadd), Frames[Frameid].UseBorder);
+ Frames[Frameid].Skinned = cfg::getByte(CLUIFrameModule, AS(buf, "Skinned", sadd), Frames[Frameid].Skinned);
+ return 0;
+}
+
+int DBStoreFrameSettingsAtPos(int pos, int Frameid)
+{
+ char sadd[16];
+ char buf[255];
+
+ _itoa(pos, sadd, 10);
+
+ cfg::writeTString(0, CLUIFrameModule, AS(buf, "Name", sadd), Frames[Frameid].name);
+ //boolean
+ cfg::writeByte(0, CLUIFrameModule, AS(buf, "Collapse", sadd), (BYTE)btoint(Frames[Frameid].collapsed));
+ cfg::writeByte(0, CLUIFrameModule, AS(buf, "Locked", sadd), (BYTE)btoint(Frames[Frameid].Locked));
+ cfg::writeByte(0, CLUIFrameModule, AS(buf, "Visible", sadd), (BYTE)btoint(Frames[Frameid].visible));
+ cfg::writeByte(0, CLUIFrameModule, AS(buf, "TBVisile", sadd), (BYTE)btoint(Frames[Frameid].TitleBar.ShowTitleBar));
+
+ cfg::writeWord(CLUIFrameModule, AS(buf, "Height", sadd), (WORD)Frames[Frameid].height);
+ cfg::writeWord(CLUIFrameModule, AS(buf, "HeightCollapsed", sadd), (WORD)Frames[Frameid].HeightWhenCollapsed);
+ cfg::writeWord(CLUIFrameModule, AS(buf, "Align", sadd), (WORD)Frames[Frameid].align);
+ //FloatingPos
+ cfg::writeWord(CLUIFrameModule, AS(buf, "FloatX", sadd), (WORD)Frames[Frameid].FloatingPos.x);
+ cfg::writeWord(CLUIFrameModule, AS(buf, "FloatY", sadd), (WORD)Frames[Frameid].FloatingPos.y);
+ cfg::writeWord(CLUIFrameModule, AS(buf, "FloatW", sadd), (WORD)Frames[Frameid].FloatingSize.x);
+ cfg::writeWord(0, CLUIFrameModule, AS(buf, "FloatH", sadd), (WORD)Frames[Frameid].FloatingSize.y);
+
+ cfg::writeByte(0, CLUIFrameModule, AS(buf, "Floating", sadd), (BYTE)btoint(Frames[Frameid].floating));
+ cfg::writeByte(0, CLUIFrameModule, AS(buf, "UseBorder", sadd), (BYTE)btoint(Frames[Frameid].UseBorder));
+ cfg::writeWord(0, CLUIFrameModule, AS(buf, "Order", sadd), (WORD)Frames[Frameid].order);
+
+ cfg::writeByte(CLUIFrameModule, AS(buf, "Skinned", sadd), Frames[Frameid].Skinned);
+ return 0;
+}
+
+int LocateStorePosition(int Frameid, int maxstored)
+{
+ int i;
+ LPTSTR frmname;
+ char settingname[255];
+ if (Frames[Frameid].name == NULL) return -1;
+
+ for (i = 0;i < maxstored;i++) {
+ mir_snprintf(settingname, sizeof(settingname), "Name%d", i);
+ frmname = DBGetStringT(0, CLUIFrameModule, settingname);
+ if (frmname == NULL) continue;
+ if (lstrcmpi(frmname, Frames[Frameid].name) == 0) {
+ mir_free(frmname);
+ return i;
+ }
+ mir_free(frmname);
+ }
+ return -1;
+}
+
+int CLUIFramesLoadFrameSettings(int Frameid)
+{
+ int storpos, maxstored;
+
+ if (FramesSysNotStarted) return -1;
+
+ if (Frameid < 0 || Frameid >= nFramescount)
+ return -1;
+
+ maxstored = cfg::getWord(CLUIFrameModule, "StoredFrames", -1);
+ if (maxstored == -1)
+ return 0;
+
+ storpos = LocateStorePosition(Frameid, maxstored);
+ if (storpos == -1)
+ return 0;
+
+ DBLoadFrameSettingsAtPos(storpos, Frameid);
+ return 0;
+}
+
+int CLUIFramesStoreFrameSettings(int Frameid)
+{
+ int maxstored, storpos;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ if (Frameid < 0 || Frameid >= nFramescount)
+ return -1;
+
+ maxstored = cfg::getWord(CLUIFrameModule, "StoredFrames", -1);
+ if (maxstored == -1)
+ maxstored = 0;
+
+ storpos = LocateStorePosition(Frameid, maxstored);
+ if (storpos == -1) {
+ storpos = maxstored;
+ maxstored++;
+ }
+
+ DBStoreFrameSettingsAtPos(storpos, Frameid);
+ cfg::writeWord(CLUIFrameModule, "StoredFrames", (WORD)maxstored);
+ return 0;
+}
+
+int CLUIFramesStoreAllFrames()
+{
+ int i;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ if (cfg::shutDown)
+ return -1;
+
+ lockfrm();
+ for (i = 0;i < nFramescount;i++)
+ CLUIFramesStoreFrameSettings(i);
+ ulockfrm();
+ return 0;
+}
+
+// Get client frame
+int CLUIFramesGetalClientFrame(void)
+{
+ int i;
+ if (FramesSysNotStarted)
+ return -1;
+
+ if (alclientFrame != -1)
+ return alclientFrame;
+
+ if (alclientFrame != -1) {
+ /* this value could become invalid if RemoveItemFromList was called,
+ * so we double-check */
+ if (alclientFrame < nFramescount) {
+ if (Frames[alclientFrame].align == alClient) {
+ return alclientFrame;
+ }
+ }
+ }
+
+ for (i = 0;i < nFramescount;i++)
+ if (Frames[i].align == alClient) {
+ alclientFrame = i;
+ return i;
+ }
+ return -1;
+}
+
+HMENU CLUIFramesCreateMenuForFrame(int frameid, int root, int popuppos, HGENMENU (*pfnAdd )( CLISTMENUITEM* ))
+{
+ CLISTMENUITEM mi;
+ //TMO_MenuItem tmi;
+ HANDLE menuid;
+ int framepos = id2pos(frameid);
+
+ if (FramesSysNotStarted) return NULL;
+
+ ZeroMemory(&mi, sizeof(mi));
+
+ mi.cbSize = sizeof(mi);
+ mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA); //LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_MIRANDA));
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&FrameTitle");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_GRAYED | CMIF_ICONFROMICOLIB;
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMITitle = menuid;
+ else Frames[framepos].MenuHandles.MITitle = menuid;
+
+ popuppos += 100000;
+ mi.hIcon = NULL;
+ mi.cbSize = sizeof(mi);
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Visible");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED;
+ mi.pszContactOwner = (char *)0;
+ mi.pszService = MS_CLIST_FRAMES_SHFRAME;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIVisible = menuid;
+ else Frames[framepos].MenuHandles.MIVisible = menuid;
+
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Show TitleBar");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED;
+ mi.pszService = MS_CLIST_FRAMES_SHFRAMETITLEBAR;
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMITBVisible = menuid;
+ else Frames[framepos].MenuHandles.MITBVisible = menuid;
+
+
+ popuppos += 100000;
+
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Locked");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED;
+ mi.pszService = MS_CLIST_FRAMES_ULFRAME;
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMILock = menuid;
+ else Frames[framepos].MenuHandles.MILock = menuid;
+
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Collapsed");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED;
+ mi.pszService = MS_CLIST_FRAMES_UCOLLFRAME;
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIColl = menuid;
+ else Frames[framepos].MenuHandles.MIColl = menuid;
+
+ //floating
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Floating Mode");
+ mi.flags = CMIF_CHILDPOPUP;
+ mi.pszService = "Set_Floating";
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIFloating = menuid;
+ else Frames[framepos].MenuHandles.MIFloating = menuid;
+
+
+ popuppos += 100000;
+
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Border");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED;
+ mi.pszService = MS_CLIST_FRAMES_SETUNBORDER;
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIBorder = menuid;
+ else Frames[framepos].MenuHandles.MIBorder = menuid;
+
+ popuppos += 100000;
+
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Skinned frame");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED;
+ mi.pszService = MS_CLIST_FRAMES_SETSKINNED;
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMISkinned = menuid;
+ else Frames[framepos].MenuHandles.MISkinned = menuid;
+
+ popuppos += 100000;
+
+ {
+ //alignment root
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Align");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_ROOTPOPUP;
+ mi.pszService = "";
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIAlignRoot = menuid;
+ else Frames[framepos].MenuHandles.MIAlignRoot = menuid;
+
+ mi.flags = CMIF_CHILDPOPUP;
+ //align top
+ mi.pszPopupName = (char *)menuid;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Top");
+ mi.pszService = CLUIFRAMESSETALIGNALTOP;
+ mi.pszContactOwner = (char *)alTop;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIAlignTop = menuid;
+ else Frames[framepos].MenuHandles.MIAlignTop = menuid;
+
+
+ //align client
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Client");
+ mi.pszService = CLUIFRAMESSETALIGNALCLIENT;
+ mi.pszContactOwner = (char *)alClient;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIAlignClient = menuid;
+ else Frames[framepos].MenuHandles.MIAlignClient = menuid;
+
+ //align bottom
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Bottom");
+ mi.pszService = CLUIFRAMESSETALIGNALBOTTOM;
+ mi.pszContactOwner = (char *)alBottom;
+ menuid = pfnAdd(&mi);
+ if (frameid == -1) contMIAlignBottom = menuid;
+ else Frames[framepos].MenuHandles.MIAlignBottom = menuid;
+
+ }
+
+ { //position
+ //position root
+ mi.pszPopupName = (char *)root;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Position");
+ mi.flags = CMIF_CHILDPOPUP | CMIF_ROOTPOPUP;
+ mi.pszService = "";
+ mi.pszContactOwner = (char *)0;
+ menuid = pfnAdd(&mi);
+
+ mi.pszPopupName = (char *)menuid;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Up");
+ mi.flags = CMIF_CHILDPOPUP;
+ mi.pszService = CLUIFRAMESMOVEUP;
+ mi.pszContactOwner = (char *)1;
+ pfnAdd(&mi);
+
+ mi.pszPopupName = (char *)menuid;
+ mi.popupPosition = frameid;
+ mi.position = popuppos++;
+ mi.pszName = LPGEN("&Down");
+ mi.flags = CMIF_CHILDPOPUP;
+ mi.pszService = CLUIFRAMESMOVEDOWN;
+ mi.pszContactOwner = (char *) - 1;
+ pfnAdd(&mi);
+ }
+
+ return 0;
+}
+
+int ModifyMItem(WPARAM wParam, LPARAM lParam)
+{
+ return ModifyMenuItemProxy(wParam, lParam);
+};
+
+
+static int CLUIFramesModifyContextMenuForFrame(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+ CLISTMENUITEM mi;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+
+ if (pos >= 0 && pos < nFramescount) {
+ memset(&mi, 0, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_NAME | CMIF_CHILDPOPUP | CMIF_TCHAR;
+ mi.ptszName = Frames[pos].TitleBar.tbname ? Frames[pos].TitleBar.tbname : Frames[pos].name;
+ ModifyMItem((WPARAM)contMITitle, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].visible) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMIVisible, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].Locked) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMILock, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].TitleBar.ShowTitleBar) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMITBVisible, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].floating) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMIFloating, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if ((Frames[pos].UseBorder)) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMIBorder, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if ((Frames[pos].Skinned)) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMISkinned, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].align&alTop) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMIAlignTop, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].align&alClient) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMIAlignClient, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].align&alBottom) mi.flags |= CMIF_CHECKED;
+ ModifyMItem((WPARAM)contMIAlignBottom, (LPARAM)&mi);
+
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (!Frames[pos].collapsed) mi.flags |= CMIF_CHECKED;
+ if ((!Frames[pos].visible) || (Frames[pos].Locked) || (pos == CLUIFramesGetalClientFrame())) mi.flags |= CMIF_GRAYED;
+ ModifyMItem((WPARAM)contMIColl, (LPARAM)&mi);
+ }
+ ulockfrm();
+ return 0;
+}
+
+INT_PTR CLUIFramesModifyMainMenuItems(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+ CLISTMENUITEM mi;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+
+ if (pos >= 0 && pos < nFramescount) {
+ memset(&mi, 0, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_NAME | CMIF_CHILDPOPUP | CMIF_TCHAR;
+ mi.ptszName = Frames[pos].TitleBar.tbname ? Frames[pos].TitleBar.tbname : Frames[pos].name;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MITitle, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].visible) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIVisible, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].Locked) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MILock, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].TitleBar.ShowTitleBar) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MITBVisible, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].floating) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIFloating, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if ((Frames[pos].UseBorder)) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIBorder, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if ((Frames[pos].Skinned)) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MISkinned, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | ((Frames[pos].align & alClient) ? CMIF_GRAYED : 0);
+ if (Frames[pos].align&alTop) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIAlignTop, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (Frames[pos].align&alClient) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIAlignClient, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | ((Frames[pos].align & alClient) ? CMIF_GRAYED : 0);
+ if (Frames[pos].align&alBottom) mi.flags |= CMIF_CHECKED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIAlignBottom, (LPARAM)&mi);
+
+ mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP;
+ if (!Frames[pos].collapsed) mi.flags |= CMIF_CHECKED;
+ if ((!Frames[pos].visible) || Frames[pos].Locked || (pos == CLUIFramesGetalClientFrame())) mi.flags |= CMIF_GRAYED;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)Frames[pos].MenuHandles.MIColl, (LPARAM)&mi);
+ }
+ ulockfrm();
+ return 0;
+}
+
+INT_PTR CLUIFramesGetFrameOptions(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+ INT_PTR retval;
+
+ if (FramesSysNotStarted) return -1;
+
+ lockfrm();
+ pos = id2pos(HIWORD(wParam));
+ if (pos < 0 || pos >= nFramescount) {
+ ulockfrm();
+ return -1;
+ }
+
+ switch (LOWORD(wParam)) {
+ case FO_FLAGS:
+ retval = 0;
+ if (Frames[pos].visible) retval |= F_VISIBLE;
+ if (!Frames[pos].collapsed) retval |= F_UNCOLLAPSED;
+ if (Frames[pos].Locked) retval |= F_LOCKED;
+ if (Frames[pos].TitleBar.ShowTitleBar) retval |= F_SHOWTB;
+ if (Frames[pos].TitleBar.ShowTitleBarTip) retval |= F_SHOWTBTIP;
+ if (Frames[pos].Skinned) retval |= F_SKINNED;
+ if (!(GetWindowLongPtr(Frames[pos].hWnd, GWL_STYLE)&WS_BORDER)) retval |= F_NOBORDER;
+ break;
+
+ case FO_NAME:
+ retval = (INT_PTR)Frames[pos].name;
+ break;
+
+ case FO_TBNAME:
+ retval = (INT_PTR)Frames[pos].TitleBar.tbname;
+ break;
+
+ case FO_TBTIPNAME:
+ retval = (INT_PTR)Frames[pos].TitleBar.tooltip;
+ break;
+
+ case FO_TBSTYLE:
+ retval = GetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE);
+ break;
+
+ case FO_TBEXSTYLE:
+ retval = GetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_EXSTYLE);
+ break;
+
+ case FO_ICON:
+ retval = (INT_PTR)Frames[pos].TitleBar.hicon;
+ break;
+
+ case FO_HEIGHT:
+ retval = (INT_PTR)Frames[pos].height;
+ break;
+
+ case FO_ALIGN:
+ retval = (INT_PTR)Frames[pos].align;
+ break;
+ case FO_FLOATING:
+ retval = (int)Frames[pos].floating;
+ break;
+ default:
+ retval = -1;
+ break;
+ }
+ ulockfrm();
+ return retval;
+}
+
+INT_PTR CLUIFramesSetFrameOptions(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+ int retval; // value to be returned
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos(HIWORD(wParam));
+ if (pos < 0 || pos >= nFramescount) {
+ ulockfrm();
+ return -1;
+ }
+
+ switch (LOWORD(wParam) & ~FO_UNICODETEXT) {
+ case FO_FLAGS: {
+ int flag = lParam;
+ int style;
+
+ Frames[pos].dwFlags = flag;
+ Frames[pos].visible = FALSE;
+ if (flag&F_VISIBLE) Frames[pos].visible = TRUE;
+
+ Frames[pos].collapsed = TRUE;
+ if (flag&F_UNCOLLAPSED) Frames[pos].collapsed = FALSE;
+
+ Frames[pos].Locked = FALSE;
+ if (flag&F_LOCKED) Frames[pos].Locked = TRUE;
+
+ Frames[pos].UseBorder = TRUE;
+ if (flag&F_NOBORDER) Frames[pos].UseBorder = FALSE;
+
+ Frames[pos].TitleBar.ShowTitleBar = FALSE;
+ if (flag&F_SHOWTB) Frames[pos].TitleBar.ShowTitleBar = TRUE;
+
+ Frames[pos].TitleBar.ShowTitleBarTip = FALSE;
+ if (flag&F_SHOWTBTIP) Frames[pos].TitleBar.ShowTitleBarTip = TRUE;
+
+ SendMessage(Frames[pos].TitleBar.hwndTip, TTM_ACTIVATE, (WPARAM)Frames[pos].TitleBar.ShowTitleBarTip, 0);
+
+ style = (int)GetWindowLongPtr(Frames[pos].hWnd, GWL_STYLE);
+ style |= WS_BORDER;
+ style |= CLS_SKINNEDFRAME;
+
+ if (flag&F_NOBORDER)
+ style &= (~WS_BORDER);
+
+ Frames[pos].Skinned = FALSE;
+ if (flag & F_SKINNED)
+ Frames[pos].Skinned = TRUE;
+
+ if (!(flag & F_SKINNED))
+ style &= ~CLS_SKINNEDFRAME;
+
+ SetWindowLongPtr(Frames[pos].hWnd, GWL_STYLE, (LONG)style);
+ SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE, (LONG)style & ~(WS_VSCROLL | WS_HSCROLL));
+
+ ulockfrm();
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ SetWindowPos(Frames[pos].TitleBar.hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ return 0;
+ }
+
+ case FO_NAME:
+ if (lParam == (LPARAM)NULL) {
+ ulockfrm();
+ return -1;
+ }
+ mir_free(Frames[pos].name);
+ Frames[pos].name = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam);
+ ulockfrm();
+ return 0;
+
+ case FO_TBNAME:
+ if (lParam == (LPARAM)NULL) {
+ ulockfrm();
+ return(-1);
+ }
+ mir_free(Frames[pos].TitleBar.tbname);
+ Frames[pos].TitleBar.tbname = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam);
+ ulockfrm();
+ if (Frames[pos].floating && (Frames[pos].TitleBar.tbname != NULL))
+ SetWindowText(Frames[pos].ContainerWnd, Frames[pos].TitleBar.tbname);
+ return 0;
+
+ case FO_TBTIPNAME:
+ if (lParam == (LPARAM)NULL) {
+ ulockfrm();
+ return(-1);
+ }
+ mir_free(Frames[pos].TitleBar.tooltip);
+ Frames[pos].TitleBar.tooltip = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam);
+ UpdateTBToolTip(pos);
+ ulockfrm();
+ return 0;
+
+ case FO_TBSTYLE:
+ SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE, lParam);
+ ulockfrm();
+ return 0;
+
+ case FO_TBEXSTYLE:
+ SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_EXSTYLE, lParam);
+ ulockfrm();
+ return 0;
+
+ case FO_ICON:
+ Frames[pos].TitleBar.hicon = (HICON)lParam;
+ ulockfrm();
+ return 0;
+
+ case FO_HEIGHT:
+ {
+ if (lParam < 0) {
+ ulockfrm();
+ return -1;
+ }
+ if(Frames[pos].Skinned) {
+ int uID = (Frames[pos].TitleBar.ShowTitleBar ? ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE : ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE);
+ lParam += (StatusItems[uID].MARGIN_BOTTOM + StatusItems[uID].MARGIN_TOP);
+ }
+ if (Frames[pos].collapsed) {
+ int oldHeight = Frames[pos].height;
+ retval = Frames[pos].height;
+ Frames[pos].height = lParam;
+ if (!CLUIFramesFitInSize())
+ Frames[pos].height = retval;
+ retval = Frames[pos].height;
+
+ if (Frames[pos].height != oldHeight) {
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList,(LPARAM)0);
+ if(Frames[pos].Skinned)
+ RedrawWindow(Frames[pos].hWnd, 0, 0, RDW_FRAME|RDW_UPDATENOW|RDW_INVALIDATE);
+ }
+ }
+ else {
+ retval = Frames[pos].HeightWhenCollapsed;
+ Frames[pos].HeightWhenCollapsed = lParam;
+ if (!CLUIFramesFitInSize())
+ Frames[pos].HeightWhenCollapsed = retval;
+ retval = Frames[pos].HeightWhenCollapsed;
+ }
+ ulockfrm();
+ return(retval);
+ }
+
+ case FO_FLOATING:
+ if (lParam < 0) {
+ ulockfrm();
+ return -1;
+ }
+ {
+ int id = Frames[pos].id;
+ Frames[pos].floating = !(lParam);
+ ulockfrm();
+
+ CLUIFrameSetFloat(id, 1);//lparam=1 use stored width and height
+ return(wParam);
+ }
+ case FO_ALIGN:
+ if (!(lParam&alTop || lParam&alBottom || lParam&alClient)) {
+ ulockfrm();
+ return(-1);
+ }
+ if ((lParam&alClient) && (CLUIFramesGetalClientFrame() >= 0)) { //only one alClient frame possible
+ alclientFrame = -1;//recalc it
+ ulockfrm();
+ return -1;
+ }
+ Frames[pos].align = lParam;
+ ulockfrm();
+ return(0);
+ }
+ ulockfrm();
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ return -1;
+}
+
+static INT_PTR CLUIFramesShowAll(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ if (FramesSysNotStarted) return -1;
+
+ for (i = 0;i < nFramescount;i++)
+ Frames[i].visible = TRUE;
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ return 0;
+}
+
+INT_PTR CLUIFramesShowAllTitleBars(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ if (FramesSysNotStarted) return -1;
+
+ for (i = 0;i < nFramescount;i++) {
+ Frames[i].TitleBar.ShowTitleBar = TRUE;
+ SetWindowPos(Frames[i].hWnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ }
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+}
+
+//wparam=lparam=0
+INT_PTR CLUIFramesHideAllTitleBars(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ if (FramesSysNotStarted) return -1;
+
+ for (i = 0;i < nFramescount;i++) {
+ Frames[i].TitleBar.ShowTitleBar = FALSE;
+ SetWindowPos(Frames[i].hWnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ }
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+}
+
+//wparam=frameid
+INT_PTR CLUIFramesShowHideFrame(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+ if (pos >= 0 && !lstrcmp(Frames[pos].name, _T("My Contacts")))
+ Frames[pos].visible = 1;
+ else {
+ if (pos >= 0 && (int)pos < nFramescount)
+ Frames[pos].visible = !Frames[pos].visible;
+ if (Frames[pos].floating)
+ CLUIFrameResizeFloatingFrame(pos);
+ }
+ ulockfrm();
+ if (!Frames[pos].floating)
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+}
+
+//wparam=frameid
+INT_PTR CLUIFramesShowHideFrameTitleBar(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+ if (pos >= 0 && (int)pos < nFramescount) {
+ Frames[pos].TitleBar.ShowTitleBar = !Frames[pos].TitleBar.ShowTitleBar;
+ SetWindowPos(Frames[pos].hWnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ }
+ ulockfrm();
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+}
+
+
+//wparam=frameid
+//lparam=-1 up ,1 down
+INT_PTR CLUIFramesMoveUpDown(WPARAM wParam, LPARAM lParam)
+{
+ int pos, i, curpos, curalign, v, tmpval;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+ if (pos >= 0 && (int)pos < nFramescount) {
+ curpos = Frames[pos].order;
+ curalign = Frames[pos].align;
+ v = 0;
+ memset(g_sd, 0, sizeof(SortData) * MAX_FRAMES);
+ for (i = 0;i < nFramescount;i++) {
+ if (Frames[i].floating || (!Frames[i].visible) || (Frames[i].align != curalign))
+ continue;
+ g_sd[v].order = Frames[i].order;
+ g_sd[v].realpos = i;
+ v++;
+ }
+ if (v == 0) {
+ ulockfrm();
+ return(0);
+ }
+ qsort(g_sd, v, sizeof(SortData), sortfunc);
+ for (i = 0;i < v;i++) {
+ if (g_sd[i].realpos == pos) {
+ if (lParam == -1) {
+ if (i < 1) break;
+ tmpval = Frames[g_sd[i-1].realpos].order;
+ Frames[g_sd[i-1].realpos].order = Frames[pos].order;
+ Frames[pos].order = tmpval;
+ break;
+ }
+ if (lParam == 1) {
+ if (i > v - 1) break;
+ tmpval = Frames[g_sd[i+1].realpos].order;
+ Frames[g_sd[i+1].realpos].order = Frames[pos].order;
+ Frames[pos].order = tmpval;
+ break;
+ }
+ }
+ }
+ ulockfrm();
+ CLUIFramesReSort();
+ //CLUIFramesStoreAllFrames();
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0);
+ PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0);
+ }
+ return(0);
+}
+
+static INT_PTR CLUIFramesMoveUp(WPARAM wParam, LPARAM lParam)
+{
+ return(CLUIFramesMoveUpDown(wParam, -1));
+}
+
+static INT_PTR CLUIFramesMoveDown(WPARAM wParam, LPARAM lParam)
+{
+ return(CLUIFramesMoveUpDown(wParam, 1));
+}
+
+
+//wparam=frameid
+//lparam=alignment
+INT_PTR CLUIFramesSetAlign(WPARAM wParam, LPARAM lParam)
+{
+ if (FramesSysNotStarted) return -1;
+
+ CLUIFramesSetFrameOptions(MAKEWPARAM(FO_ALIGN, wParam), lParam);
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return(0);
+}
+INT_PTR CLUIFramesSetAlignalTop(WPARAM wParam, LPARAM lParam)
+{
+ if (FramesSysNotStarted) return -1;
+
+ return CLUIFramesSetAlign(wParam, alTop);
+}
+INT_PTR CLUIFramesSetAlignalBottom(WPARAM wParam, LPARAM lParam)
+{
+ if (FramesSysNotStarted) return -1;
+
+ return CLUIFramesSetAlign(wParam, alBottom);
+}
+INT_PTR CLUIFramesSetAlignalClient(WPARAM wParam, LPARAM lParam)
+{
+ if (FramesSysNotStarted) return -1;
+
+ return CLUIFramesSetAlign(wParam, alClient);
+}
+
+
+//wparam=frameid
+INT_PTR CLUIFramesLockUnlockFrame(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+ if (pos >= 0 && (int)pos < nFramescount) {
+ Frames[pos].Locked = !Frames[pos].Locked;
+ CLUIFramesStoreFrameSettings(pos);
+ }
+ ulockfrm();
+ return 0;
+}
+
+//wparam=frameid
+INT_PTR CLUIFramesSetUnSetBorder(WPARAM wParam, LPARAM lParam)
+{
+ RECT rc;
+ int FrameId, oldflags;
+ HWND hw;
+ boolean flt;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ FrameId = id2pos((INT_PTR)wParam);
+ if (FrameId == -1) {
+ ulockfrm();
+ return(-1);
+ }
+ flt = oldflags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, wParam), 0);
+
+ if (oldflags&F_NOBORDER)
+ oldflags &= (~F_NOBORDER);
+ else
+ oldflags |= F_NOBORDER;
+
+ hw = Frames[FrameId].hWnd;
+ GetWindowRect(hw, &rc);
+ ulockfrm();
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, wParam), oldflags);
+ SetWindowPos(hw, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME | SWP_NOZORDER);
+ return(0);
+}
+
+//wparam=frameid
+INT_PTR CLUIFramesSetUnSetSkinned(WPARAM wParam, LPARAM lParam)
+{
+ RECT rc;
+ int FrameId, oldflags;
+ HWND hw;
+ boolean flt;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ FrameId = id2pos((INT_PTR)wParam);
+ if (FrameId == -1) {
+ ulockfrm();
+ return(-1);
+ }
+ flt = oldflags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, wParam), 0);
+
+ if (oldflags & F_SKINNED)
+ oldflags &= ~F_SKINNED;
+ else
+ oldflags |= F_SKINNED;
+
+ hw = Frames[FrameId].hWnd;
+ GetWindowRect(hw, &rc);
+ ulockfrm();
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, wParam), oldflags);
+ SetWindowPos(hw, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME | SWP_NOZORDER);
+ return(0);
+}
+
+//wparam=frameid
+INT_PTR CLUIFramesCollapseUnCollapseFrame(WPARAM wParam, LPARAM lParam)
+{
+ int FrameId;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ TitleBarH = cfg::dat.titleBarHeight;
+ lockfrm();
+ FrameId = id2pos((INT_PTR)wParam);
+ if (FrameId >= 0 && FrameId < nFramescount) {
+ int oldHeight;
+
+ // do not collapse/uncollapse client/locked/invisible frames
+ if (Frames[FrameId].align == alClient && !(Frames[FrameId].Locked || (!Frames[FrameId].visible) || Frames[FrameId].floating)) {
+ RECT rc;
+ if (CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) {
+ ulockfrm();
+ return 0;
+ }
+ if (cfg::getByte("CLUI", "AutoSize", 0)) {
+ ulockfrm();
+ return 0;
+ }
+ GetWindowRect(pcli->hwndContactList, &rc);
+
+ if (Frames[FrameId].collapsed == TRUE) {
+ rc.bottom -= rc.top;
+ rc.bottom -= Frames[FrameId].height;
+ Frames[FrameId].HeightWhenCollapsed = Frames[FrameId].height;
+ Frames[FrameId].collapsed = FALSE;
+ } else {
+ rc.bottom -= rc.top;
+ rc.bottom += Frames[FrameId].HeightWhenCollapsed;
+ Frames[FrameId].collapsed = TRUE;
+ }
+
+ SetWindowPos(pcli->hwndContactList, NULL, 0, 0, rc.right - rc.left, rc.bottom, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
+
+ CLUIFramesStoreAllFrames();
+ ulockfrm();
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return 0;
+
+ }
+ if (Frames[FrameId].Locked || (!Frames[FrameId].visible)) {
+ ulockfrm();
+ return 0;
+ }
+
+ oldHeight = Frames[FrameId].height;
+
+ // if collapsed, uncollapse
+ if (Frames[FrameId].collapsed == TRUE) {
+ Frames[FrameId].HeightWhenCollapsed = Frames[FrameId].height;
+ Frames[FrameId].height = UNCOLLAPSED_FRAME_SIZE;
+ Frames[FrameId].collapsed = FALSE;
+ }
+ // if uncollapsed, collapse
+ else {
+ Frames[FrameId].height = Frames[FrameId].HeightWhenCollapsed;
+ Frames[FrameId].collapsed = TRUE;
+ }
+
+ if (!Frames[FrameId].floating) {
+
+ if (!CLUIFramesFitInSize()) {
+ //cant collapse,we can resize only for height<alclient frame height
+ int alfrm = CLUIFramesGetalClientFrame();
+
+ if (alfrm != -1) {
+ Frames[FrameId].collapsed = FALSE;
+ if (Frames[alfrm].height > 2*UNCOLLAPSED_FRAME_SIZE) {
+ oldHeight = Frames[alfrm].height - UNCOLLAPSED_FRAME_SIZE;
+ Frames[FrameId].collapsed = TRUE;
+ }
+ } else {
+ int i, sumheight = 0;
+
+ for (i = 0;i < nFramescount;i++) {
+ if ((Frames[i].align != alClient) && (!Frames[i].floating) && (Frames[i].visible) && (!Frames[i].needhide)) {
+ sumheight += (Frames[i].height) + (TitleBarH * btoint(Frames[i].TitleBar.ShowTitleBar)) + 2;
+ ulockfrm();
+ return FALSE;
+ }
+ if (sumheight > ContactListHeight - 0 - 2)
+ Frames[FrameId].height = (ContactListHeight - 0 - 2) - sumheight;
+ }
+ }
+ Frames[FrameId].height = oldHeight;
+ if (Frames[FrameId].collapsed == FALSE) {
+ if (Frames[FrameId].floating)
+ SetWindowPos(Frames[FrameId].ContainerWnd, HWND_TOP, 0, 0, Frames[FrameId].wndSize.right - Frames[FrameId].wndSize.left + 6, Frames[FrameId].height + DEFAULT_TITLEBAR_HEIGHT + 4, SWP_SHOWWINDOW | SWP_NOMOVE);
+ ulockfrm();
+ return -1;
+ }
+ }
+ }
+ ulockfrm();
+ if (!Frames[FrameId].floating)
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0);
+ else {
+ RECT contwnd;
+ GetWindowRect(Frames[FrameId].ContainerWnd, &contwnd);
+ contwnd.top = contwnd.bottom - contwnd.top;//height
+ contwnd.left = contwnd.right - contwnd.left;//width
+
+ contwnd.top -= (oldHeight - Frames[FrameId].height);//newheight
+ SetWindowPos(Frames[FrameId].ContainerWnd, HWND_TOP, 0, 0, contwnd.left, contwnd.top, SWP_SHOWWINDOW | SWP_NOMOVE);
+ }
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ CLUIFramesStoreAllFrames();
+ return(0);
+ } else {
+ ulockfrm();
+ return -1;
+ }
+ ulockfrm();
+ return 0;
+}
+
+static int CLUIFramesLoadMainMenu()
+{
+ CLISTMENUITEM mi;
+ int i, separator;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ if (MainMIRoot != (HANDLE) - 1) {
+ CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)MainMIRoot, 0);
+ MainMIRoot = (HANDLE) - 1;
+ }
+
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+
+ // create root menu
+ mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA); //LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_MIRANDA));
+ mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB;
+ mi.position = (int)3000090000;
+ mi.pszPopupName = (char*) - 1;
+ mi.pszName = LPGEN("Frames");
+ mi.pszService = 0;
+ MainMIRoot = Menu_AddMainMenuItem(&mi);
+
+ // create frames menu
+ separator = (int)3000200000;
+ for (i = 0;i < nFramescount;i++) {
+ mi.hIcon = Frames[i].TitleBar.hicon;
+ mi.flags = CMIF_CHILDPOPUP | CMIF_ROOTPOPUP | CMIF_TCHAR;
+ mi.position = separator;
+ mi.pszPopupName = (char*)MainMIRoot;
+ mi.ptszName = Frames[i].TitleBar.tbname ? Frames[i].TitleBar.tbname : Frames[i].name;
+ mi.pszService = 0;
+ Frames[i].MenuHandles.MainMenuItem = Menu_AddMainMenuItem(&mi);
+ CLUIFramesCreateMenuForFrame(Frames[i].id, (int)Frames[i].MenuHandles.MainMenuItem, separator, Menu_AddMainMenuItem);
+ CLUIFramesModifyMainMenuItems(Frames[i].id, 0);
+ //NotifyEventHooks(hPreBuildFrameMenuEvent,i,(LPARAM)Frames[i].MenuHandles.MainMenuItem);
+ CallService(MS_CLIST_FRAMEMENUNOTIFY, (WPARAM)Frames[i].id, (LPARAM)Frames[i].MenuHandles.MainMenuItem);
+ separator++;
+ }
+
+ separator += 100000;
+
+ // create "show all frames" menu
+ mi.hIcon = NULL;//LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_MIRANDA));
+ mi.flags = CMIF_CHILDPOPUP;
+ mi.position = separator++;
+ mi.pszPopupName = (char*)MainMIRoot;
+ mi.pszName = LPGEN("Show All Frames");
+ mi.pszService = MS_CLIST_FRAMES_SHOWALLFRAMES;
+ Menu_AddMainMenuItem(&mi);
+
+ // create "show all titlebars" menu
+ mi.hIcon = NULL;//LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_HELP));
+ mi.position = separator++;
+ mi.pszPopupName = (char*)MainMIRoot;
+ mi.flags = CMIF_CHILDPOPUP;
+ mi.pszName = LPGEN("Show All Titlebars");
+ mi.pszService = MS_CLIST_FRAMES_SHOWALLFRAMESTB;
+ Menu_AddMainMenuItem(&mi);
+
+ // create "hide all titlebars" menu
+ mi.hIcon = NULL;//LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_HELP));
+ mi.position = separator++;
+ mi.pszPopupName = (char*)MainMIRoot;
+ mi.flags = CMIF_CHILDPOPUP;
+ mi.pszName = LPGEN("Hide All Titlebars");
+ mi.pszService = MS_CLIST_FRAMES_HIDEALLFRAMESTB;
+ Menu_AddMainMenuItem(&mi);
+
+ return 0;
+}
+
+static HFONT CLUILoadTitleBarFont()
+{
+ char facename[] = "MS Shell Dlg";
+ HFONT hfont;
+ LOGFONT logfont;
+ memset(&logfont, 0, sizeof(logfont));
+ memcpy(logfont.lfFaceName, facename, sizeof(facename));
+ logfont.lfWeight = FW_NORMAL;
+ logfont.lfHeight = -10;
+ hfont = CreateFontIndirect(&logfont);
+ return hfont;
+}
+
+static int UpdateTBToolTip(int framepos)
+{
+ {
+ TOOLINFO ti;
+
+ ZeroMemory(&ti, sizeof(ti));
+ ti.cbSize = sizeof(ti);
+ ti.lpszText = Frames[framepos].TitleBar.tooltip;
+ ti.hinst = g_hInst;
+ ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS ;
+ ti.uId = (UINT_PTR)Frames[framepos].TitleBar.hwnd;
+
+ return(SendMessage(Frames[framepos].TitleBar.hwndTip, TTM_UPDATETIPTEXT, (WPARAM)0, (LPARAM)&ti));
+ }
+
+};
+
+int FrameNCPaint(HWND hwnd, WNDPROC oldWndProc, WPARAM wParam, LPARAM lParam, BOOL hasTitleBar)
+{
+ HDC hdc;
+ RECT rcWindow, rc;
+ HWND hwndParent = GetParent(hwnd);
+ LRESULT result;
+
+ if (hwndParent != pcli->hwndContactList || !cfg::dat.bSkinnedScrollbar)
+ result = CallWindowProc(oldWndProc, hwnd, WM_NCPAINT, wParam, lParam);
+ else
+ result = 0;
+
+ if (pcli && pcli->hwndContactList && GetParent(hwnd) == pcli->hwndContactList) {
+ if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SKINNEDFRAME) {
+ StatusItems_t *item = StatusItems ? (hasTitleBar ? &StatusItems[ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE] : &StatusItems[ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE]) : 0;
+ HDC realDC;
+ HBITMAP hbmDraw, hbmOld;
+
+ if (item == 0)
+ return 0;
+
+ GetWindowRect(hwnd, &rcWindow);
+ rc.left = rc.top = 0;
+ rc.right = rcWindow.right - rcWindow.left;
+ rc.bottom = rcWindow.bottom - rcWindow.top;
+
+ hdc = realDC = GetWindowDC(hwnd);
+ if (hwnd == pcli->hwndContactTree) {
+ realDC = CreateCompatibleDC(hdc);
+ hbmDraw = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
+ hbmOld = reinterpret_cast<HBITMAP>(SelectObject(realDC, hbmDraw));
+ }
+
+ ExcludeClipRect(realDC, item->MARGIN_LEFT, item->MARGIN_TOP, rc.right - item->MARGIN_RIGHT, rc.bottom - item->MARGIN_BOTTOM);
+
+ BitBlt(realDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, cfg::dat.hdcBg, rcWindow.left - cfg::dat.ptW.x, rcWindow.top - cfg::dat.ptW.y, SRCCOPY);
+
+ DrawAlpha(realDC, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT,
+ item->CORNER, item->BORDERSTYLE, item->imageItem);
+ if (hwnd == pcli->hwndContactTree) {
+ ExcludeClipRect(hdc, item->MARGIN_LEFT, item->MARGIN_TOP, rc.right - item->MARGIN_RIGHT, rc.bottom - item->MARGIN_BOTTOM);
+ BitBlt(hdc, 0, 0, rc.right, rc.bottom, realDC, 0, 0, SRCCOPY);
+ SelectObject(realDC, hbmOld);
+ DeleteObject(hbmDraw);
+ DeleteDC(realDC);
+ }
+ ReleaseDC(hwnd, hdc);
+ return 0;
+ } else if (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_BORDER) {
+ HPEN hPenOld;
+ HBRUSH brold;
+
+ hdc = GetWindowDC(hwnd);
+ hPenOld = reinterpret_cast<HPEN>(SelectObject(hdc, g_hPenCLUIFrames));
+ GetWindowRect(hwnd, &rcWindow);
+ rc.left = rc.top = 0;
+ rc.right = rcWindow.right - rcWindow.left;
+ rc.bottom = rcWindow.bottom - rcWindow.top;
+ brold = reinterpret_cast<HBRUSH>(SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)));
+ Rectangle(hdc, 0, 0, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top);
+ SelectObject(hdc, hPenOld);
+ SelectObject(hdc, brold);
+ ReleaseDC(hwnd, hdc);
+ return 0;
+ }
+ }
+ return result;
+}
+
+int FrameNCCalcSize(HWND hwnd, WNDPROC oldWndProc, WPARAM wParam, LPARAM lParam, BOOL hasTitleBar)
+{
+ StatusItems_t *item = StatusItems ? (hasTitleBar ? &StatusItems[ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE] : &StatusItems[ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE]) : 0;
+ LRESULT orig = oldWndProc ? CallWindowProc(oldWndProc, hwnd, WM_NCCALCSIZE, wParam, lParam) : 0;
+ NCCALCSIZE_PARAMS *nccp = (NCCALCSIZE_PARAMS *)lParam;
+ DWORD dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
+
+ if (item == 0 || pcli == 0)
+ return orig;
+
+ if (item->IGNORED || !(dwStyle & CLS_SKINNEDFRAME) || GetParent(hwnd) != pcli->hwndContactList)
+ return orig;
+
+ nccp->rgrc[0].left += item->MARGIN_LEFT;
+ nccp->rgrc[0].right -= item->MARGIN_RIGHT;
+ nccp->rgrc[0].bottom -= item->MARGIN_BOTTOM;
+ nccp->rgrc[0].top += item->MARGIN_TOP;
+ return WVR_REDRAW;
+}
+
+static LRESULT CALLBACK FramesSubClassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ WNDPROC oldWndProc = 0;
+ BOOL hasTitleBar = FALSE;
+
+ for (i = 0; i < nFramescount; i++) {
+ if (Frames[i].hWnd == hwnd) {
+ oldWndProc = Frames[i].wndProc;
+ hasTitleBar = Frames[i].TitleBar.ShowTitleBar;
+ }
+ }
+ switch (msg) {
+ case WM_NCPAINT: {
+ return FrameNCPaint(hwnd, oldWndProc ? oldWndProc : DefWindowProc, wParam, lParam, hasTitleBar);
+ }
+ case WM_NCCALCSIZE: {
+ return FrameNCCalcSize(hwnd, oldWndProc, wParam, lParam, hasTitleBar);
+ }
+ case WM_PRINTCLIENT:
+ return 0;
+ default:
+ break;
+ }
+ if (oldWndProc)
+ return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam);
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+/*
+ * re-sort all frames and correct frame ordering
+ */
+
+static int CLUIFramesReSort()
+{
+ int v = 0, i;
+ int order = 1;
+
+ lockfrm();
+ memset(g_sd, 0, sizeof(SortData) * MAX_FRAMES);
+ for (i = 0;i < nFramescount;i++) {
+ if (Frames[i].align != alTop)
+ continue;
+ g_sd[v].order = Frames[i].order;
+ g_sd[v].realpos = i;
+ v++;
+ }
+ if (v > 0) {
+ qsort(g_sd, v, sizeof(SortData), sortfunc);
+ for (i = 0; i < v; i++)
+ Frames[g_sd[i].realpos].order = order++;
+ }
+
+ memset(g_sd, 0, sizeof(SortData) * MAX_FRAMES);
+ v = 0;
+ for (i = 0;i < nFramescount;i++) {
+ if (Frames[i].align != alBottom)
+ continue;
+ g_sd[v].order = Frames[i].order;
+ g_sd[v].realpos = i;
+ v++;
+ }
+ if (v > 0) {
+ qsort(g_sd, v, sizeof(SortData), sortfunc);
+ for (i = 0; i < v; i++)
+ Frames[g_sd[i].realpos].order = order++;
+ }
+ CLUIFramesStoreAllFrames();
+ ulockfrm();
+ return(0);
+}
+
+//wparam=(CLISTFrame*)clfrm
+INT_PTR CLUIFramesAddFrame(WPARAM wParam, LPARAM lParam)
+{
+ int style, retval;
+ char * CustomName = NULL;
+ CLISTFrame *clfrm = (CLISTFrame *)wParam;
+
+ if (pcli->hwndContactList == 0) return -1;
+ if (FramesSysNotStarted) return -1;
+ if (clfrm->cbSize != sizeof(CLISTFrame)) return -1;
+
+ lockfrm();
+ if (nFramescount >= MAX_FRAMES) {
+ ulockfrm();
+ return -1;
+ }
+ if (Frames == NULL) {
+ Frames = (wndFrame*)malloc(sizeof(wndFrame) * (MAX_FRAMES + 2));
+ ZeroMemory(Frames, sizeof(wndFrame) * (MAX_FRAMES + 2));
+ }
+ memset(&Frames[nFramescount], 0, sizeof(wndFrame));
+
+ Frames[nFramescount].id = NextFrameId++;
+ Frames[nFramescount].align = clfrm->align;
+ Frames[nFramescount].hWnd = clfrm->hWnd;
+ Frames[nFramescount].height = clfrm->height;
+ Frames[nFramescount].TitleBar.hicon = clfrm->hIcon;
+ //Frames[nFramescount].TitleBar.BackColour;
+ Frames[nFramescount].floating = FALSE;
+
+ if (clfrm->Flags & F_NO_SUBCONTAINER)
+ Frames[nFramescount].OwnerWindow = (HWND) - 2;
+ else
+ Frames[nFramescount].OwnerWindow = pcli->hwndContactList;
+
+ SetClassLong(clfrm->hWnd, GCL_STYLE, GetClassLong(clfrm->hWnd, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW));
+ SetWindowLongPtr(clfrm->hWnd, GWL_STYLE, GetWindowLongPtr(clfrm->hWnd, GWL_STYLE) | WS_CLIPCHILDREN);
+
+ if (GetCurrentThreadId() == GetWindowThreadProcessId(clfrm->hWnd, NULL)) {
+ if (clfrm->hWnd != pcli->hwndContactTree && clfrm->hWnd != g_hwndViewModeFrame && clfrm->hWnd != g_hwndEventArea) {
+ Frames[nFramescount].wndProc = (WNDPROC)GetWindowLongPtr(clfrm->hWnd, GWLP_WNDPROC);
+ SetWindowLongPtr(clfrm->hWnd, GWLP_WNDPROC, (LONG_PTR)FramesSubClassProc);
+ }
+ }
+
+ if (clfrm->hWnd == g_hwndEventArea)
+ wndFrameEventArea = &Frames[nFramescount];
+ else if (clfrm->hWnd == pcli->hwndContactTree)
+ wndFrameCLC = &Frames[nFramescount];
+ else if (clfrm->hWnd == g_hwndViewModeFrame)
+ wndFrameViewMode = &Frames[nFramescount];
+
+ Frames[nFramescount].dwFlags = clfrm->Flags;
+
+ if (clfrm->name == NULL || ((clfrm->Flags&F_UNICODE) ? lstrlenW(clfrm->wname) : lstrlenA(clfrm->name)) == 0) {
+ TCHAR ptszClassName[ 256 ];
+ GetClassName(Frames[nFramescount].hWnd, ptszClassName, SIZEOF(ptszClassName));
+ Frames[nFramescount].name = mir_tstrdup(ptszClassName);
+ } else Frames[nFramescount].name = (clfrm->Flags & F_UNICODE) ? mir_u2t(clfrm->wname) : mir_a2t(clfrm->name);
+
+ if (IsBadCodePtr((FARPROC)clfrm->TBname) || clfrm->TBname == NULL
+ || ((clfrm->Flags&F_UNICODE) ? lstrlenW(clfrm->TBwname) : lstrlenA(clfrm->TBname)) == 0)
+ Frames[nFramescount].TitleBar.tbname = mir_tstrdup(Frames[nFramescount].name);
+ else
+ Frames[nFramescount].TitleBar.tbname = (clfrm->Flags & F_UNICODE) ? mir_u2t(clfrm->TBwname) : mir_a2t(clfrm->TBname);
+ Frames[nFramescount].needhide = FALSE;
+ Frames[nFramescount].TitleBar.ShowTitleBar = (clfrm->Flags & F_SHOWTB ? TRUE : FALSE);
+ Frames[nFramescount].TitleBar.ShowTitleBarTip = (clfrm->Flags & F_SHOWTBTIP ? TRUE : FALSE);
+
+ Frames[nFramescount].collapsed = clfrm->Flags & F_UNCOLLAPSED ? FALSE : TRUE;
+ Frames[nFramescount].Locked = clfrm->Flags & F_LOCKED ? TRUE : FALSE;
+ Frames[nFramescount].visible = clfrm->Flags & F_VISIBLE ? TRUE : FALSE;
+
+ Frames[nFramescount].UseBorder = (clfrm->Flags & F_NOBORDER) ? FALSE : TRUE;
+ Frames[nFramescount].Skinned = (clfrm->Flags & F_SKINNED) ? TRUE : FALSE;
+
+ // create frame
+ Frames[nFramescount].TitleBar.hwnd =
+ CreateWindow(CLUIFrameTitleBarClassName, Frames[nFramescount].name,
+ (cfg::getByte(CLUIFrameModule, "RemoveAllTitleBarBorders", 1) ? 0 : WS_BORDER)
+ | WS_CHILD | WS_CLIPCHILDREN | (Frames[nFramescount].TitleBar.ShowTitleBar ? WS_VISIBLE : 0) |
+ WS_CLIPCHILDREN, 0, 0, 0, 0, pcli->hwndContactList, NULL, g_hInst, NULL);
+
+ SetWindowLongPtr(Frames[nFramescount].TitleBar.hwnd, GWLP_USERDATA, Frames[nFramescount].id);
+
+ Frames[nFramescount].TitleBar.hwndTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ pcli->hwndContactList, NULL, g_hInst, NULL);
+
+ SetWindowPos(Frames[nFramescount].TitleBar.hwndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ {
+ TOOLINFOA ti;
+ int res;
+
+ ZeroMemory(&ti, sizeof(ti));
+ ti.cbSize = sizeof(ti);
+ ti.lpszText = "";
+ ti.hinst = g_hInst;
+ ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS ;
+ ti.uId = (UINT_PTR)Frames[nFramescount].TitleBar.hwnd;
+ res = SendMessageA(Frames[nFramescount].TitleBar.hwndTip, TTM_ADDTOOL, (WPARAM)0, (LPARAM) & ti);
+ }
+
+ SendMessage(Frames[nFramescount].TitleBar.hwndTip, TTM_ACTIVATE, (WPARAM)Frames[nFramescount].TitleBar.ShowTitleBarTip, 0);
+
+ Frames[nFramescount].oldstyles = GetWindowLongPtr(Frames[nFramescount].hWnd, GWL_STYLE);
+ Frames[nFramescount].TitleBar.oldstyles = GetWindowLongPtr(Frames[nFramescount].TitleBar.hwnd, GWL_STYLE);
+ //Frames[nFramescount].FloatingPos.x=
+
+ retval = Frames[nFramescount].id;
+ Frames[nFramescount].order = nFramescount + 1;
+ nFramescount++;
+
+ CLUIFramesLoadFrameSettings(id2pos(retval));
+ style = GetWindowLongPtr(Frames[nFramescount-1].hWnd, GWL_STYLE);
+ style &= ~(WS_BORDER);
+ style |= ((Frames[nFramescount-1].UseBorder) ? WS_BORDER : 0);
+
+ style |= Frames[nFramescount-1].Skinned ? CLS_SKINNEDFRAME : 0;
+
+ SetWindowLongPtr(Frames[nFramescount-1].hWnd, GWL_STYLE, style);
+ SetWindowLongPtr(Frames[nFramescount-1].TitleBar.hwnd, GWL_STYLE, style & ~(WS_VSCROLL | WS_HSCROLL));
+
+ if (Frames[nFramescount-1].order == 0) {
+ Frames[nFramescount-1].order = nFramescount;
+ }
+
+ ulockfrm();
+
+ alclientFrame = -1;//recalc it
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0);
+
+ if (Frames[nFramescount-1].floating) {
+ Frames[nFramescount-1].floating = FALSE;
+ CLUIFrameSetFloat(retval, 1);//lparam=1 use stored width and height
+ }
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ return retval;
+}
+
+static INT_PTR CLUIFramesRemoveFrame(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+ if (FramesSysNotStarted)
+ return -1;
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+
+ if (pos < 0 || pos > nFramescount) {
+ ulockfrm();
+ return(-1);
+ }
+
+ {
+ wndFrame* F = &Frames[pos];
+ if (F->hWnd == g_hwndEventArea)
+ wndFrameEventArea = NULL;
+ else if (F->hWnd == pcli->hwndContactTree)
+ wndFrameCLC = NULL;
+ else if (F->hWnd == g_hwndViewModeFrame)
+ wndFrameViewMode = NULL;
+
+ mir_free(F->name);
+ mir_free(F->TitleBar.tbname);
+ mir_free(F->TitleBar.tooltip);
+
+ DestroyWindow(F->hWnd);
+ F->hWnd = (HWND) - 1;
+ DestroyWindow(F->TitleBar.hwnd);
+ F->TitleBar.hwnd = (HWND) - 1;
+ DestroyWindow(F->ContainerWnd);
+ F->ContainerWnd = (HWND) - 1;
+ DestroyMenu(F->TitleBar.hmenu);
+ }
+
+ RemoveItemFromList(pos, &Frames, &nFramescount);
+
+ ulockfrm();
+ if (!cfg::shutDown) {
+ InvalidateRect(pcli->hwndContactList, NULL, TRUE);
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ }
+ return(0);
+}
+
+INT_PTR CLUIFramesForceUpdateTB(const wndFrame *Frame)
+{
+ if (Frame->TitleBar.hwnd != 0)
+ RedrawWindow(Frame->TitleBar.hwnd, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
+ return 0;
+}
+
+INT_PTR CLUIFramesForceUpdateFrame(const wndFrame *Frame)
+{
+ if (Frame->hWnd != 0)
+ RedrawWindow(Frame->hWnd, NULL, NULL, RDW_UPDATENOW | RDW_FRAME | RDW_ERASE | RDW_INVALIDATE);
+
+ if (Frame->floating)
+ if (Frame->ContainerWnd != 0) RedrawWindow(Frame->ContainerWnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
+ return 0;
+}
+
+int CLUIFrameMoveResize(const wndFrame *Frame)
+{
+ TitleBarH = cfg::dat.titleBarHeight;
+ // we need to show or hide the frame?
+ if (Frame->visible && (!Frame->needhide)) {
+ ShowWindow(Frame->hWnd, SW_SHOW);
+ ShowWindow(Frame->TitleBar.hwnd, Frame->TitleBar.ShowTitleBar == TRUE ? SW_SHOW : SW_HIDE);
+ } else {
+ ShowWindow(Frame->hWnd, SW_HIDE);
+ ShowWindow(Frame->TitleBar.hwnd, SW_HIDE);
+ return(0);
+ }
+
+ SetWindowPos(Frame->hWnd, NULL, Frame->wndSize.left + cfg::dat.bCLeft, Frame->wndSize.top + cfg::dat.topOffset,
+ (Frame->wndSize.right - Frame->wndSize.left),
+ (Frame->wndSize.bottom - Frame->wndSize.top), SWP_NOZORDER | SWP_NOREDRAW);
+ if (Frame->TitleBar.ShowTitleBar) {
+ SetWindowPos(Frame->TitleBar.hwnd, NULL, Frame->wndSize.left + cfg::dat.bCLeft, Frame->wndSize.top + cfg::dat.topOffset - TitleBarH,
+ (Frame->wndSize.right - Frame->wndSize.left),
+ TitleBarH + (Frame->UseBorder ? (!Frame->collapsed ? (Frame->align == alClient ? 0 : 2) : 1) : 0), SWP_NOZORDER);
+ }
+ return 0;
+}
+
+BOOLEAN CLUIFramesFitInSize(void)
+{
+ int i;
+ int sumheight = 0;
+ int tbh = 0; // title bar height
+ int clientfrm;
+
+ TitleBarH = cfg::dat.titleBarHeight;
+
+ clientfrm = CLUIFramesGetalClientFrame();
+ if (clientfrm != -1)
+ tbh = TitleBarH * btoint(Frames[clientfrm].TitleBar.ShowTitleBar);
+
+ for (i = 0;i < nFramescount;i++) {
+ if ((Frames[i].align != alClient) && (!Frames[i].floating) && (Frames[i].visible) && (!Frames[i].needhide)) {
+ sumheight += (Frames[i].height) + (TitleBarH * btoint(Frames[i].TitleBar.ShowTitleBar)) + 2/*+btoint(Frames[i].UseBorder)*2*/;
+ if (sumheight > ContactListHeight - tbh - 2)
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+int CLUIFramesGetMinHeight()
+{
+ int i, tbh, clientfrm, sumheight = 0;
+ RECT border;
+ int allbord = 0;
+
+ if (pcli->hwndContactList == NULL)
+ return 0;
+
+ lockfrm();
+
+ TitleBarH = cfg::dat.titleBarHeight;
+ // search for alClient frame and get the titlebar's height
+ tbh = 0;
+ clientfrm = CLUIFramesGetalClientFrame();
+ if (clientfrm != -1)
+ tbh = TitleBarH * btoint(Frames[clientfrm].TitleBar.ShowTitleBar);
+
+ for (i = 0;i < nFramescount;i++) {
+ if ((Frames[i].align != alClient) && (Frames[i].visible) && (!Frames[i].needhide) && (!Frames[i].floating)) {
+ RECT wsize;
+
+ GetWindowRect(Frames[i].hWnd, &wsize);
+ sumheight += (wsize.bottom - wsize.top) + (TitleBarH * btoint(Frames[i].TitleBar.ShowTitleBar)) + 3;
+ }
+ }
+ ulockfrm();
+ GetBorderSize(pcli->hwndContactList, &border);
+ return(sumheight + border.top + border.bottom + allbord + tbh + 3);
+}
+
+int SizeMoveNewSizes()
+{
+ int i;
+ for (i = 0;i < nFramescount;i++) {
+
+ if (Frames[i].floating) {
+ CLUIFrameResizeFloatingFrame(i);
+ } else {
+ CLUIFrameMoveResize(&Frames[i]);
+ };
+ }
+ return 0;
+}
+
+/*
+ * changed Nightwish
+ * gap calculation was broken. Now, it doesn't calculate and store the gaps in Frames[] anymore.
+ * instead, it remembers the smallest wndSize.top value (which has to be the top frame) and then passes
+ * the gap to all following frame(s) to the actual resizing function which just adds the gap to
+ * wndSize.top and corrects the frame height accordingly.
+
+ * Title bar gap has been removed (can be simulated by using a clist_nicer skin item for frame title bars
+ * and setting the bottom margin of the skin item
+ */
+
+int CLUIFramesResize(const RECT newsize)
+{
+ int sumheight = 9999999, newheight;
+ int prevframe, prevframebottomline;
+ int tbh, curfrmtbh;
+ int drawitems;
+ int clientfrm, clientframe = -1;
+ int i, j;
+ int sepw;
+ int topOff = 0, botOff = 0, last_bottomtop;;
+
+ GapBetweenFrames = cfg::dat.gapBetweenFrames;
+ sepw = GapBetweenFrames;
+
+ if (nFramescount < 1 || cfg::shutDown)
+ return 0;
+
+ newheight = newsize.bottom - newsize.top;
+ TitleBarH = cfg::dat.titleBarHeight;
+
+ // search for alClient frame and get the titlebar's height
+ tbh = 0;
+ clientfrm = CLUIFramesGetalClientFrame();
+ if (clientfrm != -1)
+ tbh = (TitleBarH) * btoint(Frames[clientfrm].TitleBar.ShowTitleBar);
+
+ for (i = 0;i < nFramescount;i++) {
+ if (!Frames[i].floating) {
+ Frames[i].needhide = FALSE;
+ Frames[i].wndSize.left = 0;
+ Frames[i].wndSize.right = newsize.right - newsize.left;
+ }
+ }
+ {
+ //sorting stuff
+ memset(g_sd, 0, sizeof(SortData) * MAX_FRAMES);
+ for (i = 0;i < nFramescount;i++) {
+ g_sd[i].order = Frames[i].order;
+ g_sd[i].realpos = i;
+ }
+ qsort(g_sd, nFramescount, sizeof(SortData), sortfunc);
+
+ }
+ drawitems = nFramescount;
+ while (sumheight > (newheight - tbh) && drawitems > 0) {
+ sumheight = 0;
+ drawitems = 0;
+ for (i = 0;i < nFramescount;i++) {
+ if (((Frames[i].align != alClient)) && (!Frames[i].floating) && (Frames[i].visible) && (!Frames[i].needhide)) {
+ drawitems++;
+ curfrmtbh = (TitleBarH) * btoint(Frames[i].TitleBar.ShowTitleBar);
+ sumheight += (Frames[i].height) + curfrmtbh + (i > 0 ? sepw : 0) + (Frames[i].UseBorder ? 2 : 0);
+ if (sumheight > newheight - tbh) {
+ sumheight -= (Frames[i].height) + curfrmtbh + (i > 0 ? sepw : 0);
+ Frames[i].needhide = TRUE;
+ drawitems--;
+ break;
+ }
+ }
+ }
+ }
+
+ prevframe = -1;
+ prevframebottomline = 0;
+ for (j = 0;j < nFramescount;j++) {
+ //move all alTop frames
+ i = g_sd[j].realpos;
+ if ((!Frames[i].needhide) && (!Frames[i].floating) && (Frames[i].visible) && (Frames[i].align == alTop)) {
+ curfrmtbh = (TitleBarH) * btoint(Frames[i].TitleBar.ShowTitleBar);
+ Frames[i].wndSize.top = prevframebottomline + (prevframebottomline > 0 ? sepw : 0) + (curfrmtbh);
+ Frames[i].wndSize.bottom = Frames[i].height + Frames[i].wndSize.top + (Frames[i].UseBorder ? 2 : 0);
+ Frames[i].prevvisframe = prevframe;
+ prevframe = i;
+ prevframebottomline = Frames[i].wndSize.bottom;
+ topOff = prevframebottomline;
+ }
+ }
+
+ if (sumheight < newheight) {
+ for (j = 0;j < nFramescount;j++) {
+ //move alClient frame
+ i = g_sd[j].realpos;
+ if ((!Frames[i].needhide) && (!Frames[i].floating) && (Frames[i].visible) && (Frames[i].align == alClient)) {
+ int oldh;
+ Frames[i].wndSize.top = prevframebottomline + (prevframebottomline > 0 ? sepw : 0) + (tbh);
+ Frames[i].wndSize.bottom = Frames[i].wndSize.top + newheight - sumheight - tbh - ((prevframebottomline > 0) ? sepw : 0);
+ clientframe = i;
+ oldh = Frames[i].height;
+ Frames[i].height = Frames[i].wndSize.bottom - Frames[i].wndSize.top;
+ Frames[i].prevvisframe = prevframe;
+ prevframe = i;
+ prevframebottomline = Frames[i].wndSize.bottom;
+ if (prevframebottomline > newheight) {
+ //prevframebottomline-=Frames[i].height+(tbh+1);
+ //Frames[i].needhide=TRUE;
+ }
+ break;
+ }
+ }
+ }
+
+ //newheight
+ prevframebottomline = last_bottomtop = newheight;
+ //prevframe=-1;
+ for (j = nFramescount - 1;j >= 0;j--) {
+ //move all alBottom frames
+ i = g_sd[j].realpos;
+ if ((Frames[i].visible) && (!Frames[i].floating) && (!Frames[i].needhide) && (Frames[i].align == alBottom)) {
+ curfrmtbh = (TitleBarH) * btoint(Frames[i].TitleBar.ShowTitleBar);
+ Frames[i].wndSize.bottom = prevframebottomline - ((prevframebottomline < newheight) ? sepw : 0);
+ Frames[i].wndSize.top = Frames[i].wndSize.bottom - Frames[i].height - (Frames[i].UseBorder ? 2 : 0);
+ Frames[i].prevvisframe = prevframe;
+ prevframe = i;
+ prevframebottomline = Frames[i].wndSize.top - curfrmtbh;
+ botOff = prevframebottomline;
+ last_bottomtop = Frames[i].wndSize.top - curfrmtbh;
+ }
+ }
+
+ // correct client frame bottom gap if there is no other top frame.
+
+ if (clientframe != -1) {
+ Frames[clientframe].wndSize.bottom = last_bottomtop - (last_bottomtop < newheight ? sepw : 0);
+ Frames[clientframe].height = Frames[clientframe].wndSize.bottom - Frames[clientframe].wndSize.top;
+ }
+ return 0;
+}
+
+INT_PTR CLUIFramesUpdateFrame(WPARAM wParam, LPARAM lParam)
+{
+ int pos;
+ if (FramesSysNotStarted)
+ return -1;
+ if (wParam == -1) {
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ return 0;
+ }
+ if (lParam&FU_FMPOS)
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 1);
+
+ lockfrm();
+ pos = id2pos((INT_PTR)wParam);
+ if (pos < 0 || pos >= nFramescount) {
+ ulockfrm();
+ return -1;
+ }
+ if (lParam&FU_TBREDRAW)
+ CLUIFramesForceUpdateTB(&Frames[pos]);
+ if (lParam&FU_FMREDRAW)
+ CLUIFramesForceUpdateFrame(&Frames[pos]);
+ ulockfrm();
+ return 0;
+}
+
+int dock_prevent_moving = 0;
+
+int CLUIFramesApplyNewSizes(int mode)
+{
+ int i;
+ dock_prevent_moving = 0;
+ for (i = 0;i < nFramescount;i++) {
+ if ((mode == 1 && Frames[i].OwnerWindow != (HWND) - 2 && Frames[i].OwnerWindow) ||
+ (mode == 2 && Frames[i].OwnerWindow == (HWND) - 2) ||
+ (mode == 3))
+ if (Frames[i].floating)
+ CLUIFrameResizeFloatingFrame(i);
+ else
+ CLUIFrameMoveResize(&Frames[i]);
+ }
+ dock_prevent_moving = 1;
+ return 0;
+}
+
+RECT old_window_rect = {0}, new_window_rect = {0};
+
+int SizeFramesByWindowRect(RECT *r)
+{
+ RECT nRect;
+ DWORD noSize = 0;
+
+ if (FramesSysNotStarted)
+ return -1;
+
+ TitleBarH = cfg::dat.titleBarHeight;
+ lockfrm();
+ GapBetweenFrames = cfg::dat.gapBetweenFrames;
+
+ nRect = *r;
+
+ nRect.bottom -= (cfg::dat.statusBarHeight + cfg::dat.bottomOffset);
+ nRect.right -= cfg::dat.bCRight;
+ nRect.left = cfg::dat.bCLeft;
+ nRect.top = cfg::dat.topOffset;
+ ContactListHeight = nRect.bottom - nRect.top;
+
+ CLUIFramesResize(nRect);
+ {
+ int i;
+ for (i = 0;i < nFramescount;i++) {
+ int dx;
+ int dy;
+ dx = new_window_rect.left - old_window_rect.left;
+ dy = new_window_rect.top - old_window_rect.top;
+ if (!Frames[i].floating) {
+ if (Frames[i].OwnerWindow && Frames[i].OwnerWindow != (HWND) - 2) {
+ /*
+ if(Frames[i].wndSize.right - Frames[i].wndSize.left == Frames[i].oldWndSize.right - Frames[i].oldWndSize.left &&
+ Frames[i].wndSize.bottom - Frames[i].wndSize.top == Frames[i].oldWndSize.bottom - Frames[i].oldWndSize.top)
+ noSize = SWP_NOSIZE;
+ else {
+ noSize = 0;
+ CopyRect(&Frames[i].oldWndSize, &Frames[i].wndSize);
+ }*/
+ SetWindowPos(Frames[i].hWnd, NULL, Frames[i].wndSize.left + cfg::dat.bCLeft, Frames[i].wndSize.top + cfg::dat.topOffset,
+ (Frames[i].wndSize.right - Frames[i].wndSize.left),
+ (Frames[i].wndSize.bottom - Frames[i].wndSize.top), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS | noSize);
+
+ if (Frames[i].TitleBar.ShowTitleBar) {
+ SetWindowPos(Frames[i].TitleBar.hwnd, NULL, Frames[i].wndSize.left + cfg::dat.bCLeft, Frames[i].wndSize.top + cfg::dat.topOffset - TitleBarH,
+ (Frames[i].wndSize.right - Frames[i].wndSize.left),
+ TitleBarH + (Frames[i].UseBorder ? (!Frames[i].collapsed ? (Frames[i].align == alClient ? 0 : 2) : 1) : 0), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
+ }
+ } else {
+ int res = 0;
+ // set frame position
+ SetWindowPos(Frames[i].hWnd, NULL, Frames[i].wndSize.left + cfg::dat.bCLeft, Frames[i].wndSize.top + cfg::dat.topOffset,
+ (Frames[i].wndSize.right - Frames[i].wndSize.left),
+ (Frames[i].wndSize.bottom - Frames[i].wndSize.top), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOREDRAW);
+
+ // set titlebar position
+ if (Frames[i].TitleBar.ShowTitleBar) {
+ SetWindowPos(Frames[i].TitleBar.hwnd, NULL, Frames[i].wndSize.left + cfg::dat.bCLeft, Frames[i].wndSize.top + cfg::dat.topOffset - TitleBarH,
+ (Frames[i].wndSize.right - Frames[i].wndSize.left),
+ TitleBarH + (Frames[i].UseBorder ? (!Frames[i].collapsed ? (Frames[i].align == alClient ? 0 : 2) : 1) : 0), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOREDRAW);
+ }
+ //UpdateWindow(Frames[i].hWnd);
+ if (Frames[i].TitleBar.ShowTitleBar)
+ UpdateWindow(Frames[i].TitleBar.hwnd);
+ };
+ }
+
+ }
+ if (GetTickCount() - LastStoreTick > 1000) {
+ CLUIFramesStoreAllFrames();
+ LastStoreTick = GetTickCount();
+ }
+ }
+ ulockfrm();
+ return 0;
+}
+
+int CLUIFramesOnClistResize(WPARAM wParam, LPARAM lParam)
+{
+ RECT nRect, rcStatus;
+ int tick;
+ GapBetweenFrames = cfg::dat.gapBetweenFrames;
+
+ if (FramesSysNotStarted || cfg::shutDown)
+ return -1;
+
+ lockfrm();
+
+ GetClientRect(pcli->hwndContactList, &nRect);
+ if (lParam && lParam != 1) {
+ RECT oldRect;
+ POINT pt;
+ RECT * newRect = (RECT *)lParam;
+ int dl, dt, dr, db;
+ GetWindowRect((HWND)wParam, &oldRect);
+ pt.x = nRect.left;
+ pt.y = nRect.top;
+ ClientToScreen(pcli->hwndContactList, &pt);
+ dl = pt.x - oldRect.left;
+ dt = pt.y - oldRect.top;
+ dr = (oldRect.right - oldRect.left) - (nRect.right - nRect.left) - dl;
+ db = (oldRect.bottom - oldRect.top) - (nRect.bottom - nRect.top) - dt;
+ nRect.left = newRect->left + dl;
+ nRect.top = newRect->top + dt;
+ nRect.bottom = newRect->bottom - db;
+ nRect.right = newRect->right - dr;
+ }
+
+ rcStatus.top = rcStatus.bottom = 0;
+
+ nRect.bottom -= (cfg::dat.statusBarHeight + cfg::dat.bottomOffset);
+ nRect.right -= cfg::dat.bCRight;
+ nRect.left = cfg::dat.bCLeft;
+ nRect.top = cfg::dat.topOffset;
+ ContactListHeight = nRect.bottom - nRect.top;
+
+ tick = GetTickCount();
+
+ CLUIFramesResize(nRect);
+ CLUIFramesApplyNewSizes(3);
+
+ ulockfrm();
+ tick = GetTickCount() - tick;
+
+ if (pcli->hwndContactList != 0)
+ InvalidateRect(pcli->hwndContactList, NULL, TRUE);
+ if (pcli->hwndContactList != 0)
+ UpdateWindow(pcli->hwndContactList);
+
+ Sleep(0);
+
+ if (GetTickCount() - LastStoreTick > 2000) {
+ CLUIFramesStoreAllFrames();
+ LastStoreTick = GetTickCount();
+ }
+ return 0;
+}
+
+static HBITMAP hBmpBackground;
+static int backgroundBmpUse;
+static COLORREF bkColour;
+static COLORREF SelBkColour;
+boolean AlignCOLLIconToLeft; //will hide frame icon
+
+int OnFrameTitleBarBackgroundChange()
+{
+ DBVARIANT dbv;
+
+ AlignCOLLIconToLeft = cfg::getByte("FrameTitleBar", "AlignCOLLIconToLeft", 0);
+
+ bkColour = cfg::getDword("FrameTitleBar", "BkColour", CLCDEFAULT_BKCOLOUR);
+
+ if (hBmpBackground) {
+ DeleteObject(hBmpBackground);
+ hBmpBackground = NULL;
+ }
+ if (cfg::getByte("FrameTitleBar", "UseBitmap", CLCDEFAULT_USEBITMAP)) {
+ if (!DBGetContactSetting(NULL, "FrameTitleBar", "BkBitmap", &dbv)) {
+ hBmpBackground = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)dbv.pszVal);
+ mir_free(dbv.pszVal);
+ }
+ }
+ backgroundBmpUse = cfg::getWord("FrameTitleBar", "BkBmpUse", CLCDEFAULT_BKBMPUSE);
+
+ CLUIFramesOnClistResize(0, 0);
+ return 0;
+}
+
+static int DrawTitleBar(HDC dc, RECT rect, int Frameid)
+{
+ HDC hdcMem;
+ HBITMAP hBmpOsb, hoBmp;
+ HBRUSH hBack, hoBrush;
+ int pos;
+ StatusItems_t *item = &StatusItems[ID_EXTBKFRAMETITLE - ID_STATUS_OFFLINE];
+
+ /*
+ * no need to redraw anything while shutting down
+ */
+ if (cfg::shutDown)
+ return 0;
+
+ TitleBarH = cfg::dat.titleBarHeight;
+ hdcMem = CreateCompatibleDC(dc);
+ hBmpOsb = CreateCompatibleBitmap(dc, rect.right, rect.bottom);
+ hoBmp = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, hBmpOsb));
+
+ SetBkMode(hdcMem, TRANSPARENT);
+
+ hBack = GetSysColorBrush(COLOR_3DFACE);
+ hoBrush = reinterpret_cast<HBRUSH>(SelectObject(hdcMem, hBack));
+
+ lockfrm();
+ pos = id2pos(Frameid);
+
+ if (pos >= 0 && pos < nFramescount) {
+ HFONT oFont;
+ int fHeight, fontTop;
+ GetClientRect(Frames[pos].TitleBar.hwnd, &Frames[pos].TitleBar.wndSize);
+
+ if (cfg::clcdat) {
+ oFont = ChangeToFont(hdcMem, cfg::clcdat, FONTID_FRAMETITLE, &fHeight);
+ } else {
+ oFont = reinterpret_cast<HFONT>(SelectObject(hdcMem, GetStockObject(DEFAULT_GUI_FONT)));
+ fHeight = 10;
+ }
+ fontTop = (TitleBarH - fHeight) / 2;
+
+ if (cfg::dat.bWallpaperMode && !Frames[pos].floating)
+ SkinDrawBg(Frames[pos].TitleBar.hwnd, hdcMem);
+
+ if (!item->IGNORED) {
+ RECT rc = Frames[pos].TitleBar.wndSize;
+ 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);
+ } else if (cfg::clcdat) {
+ FillRect(hdcMem, &rect, hBack);
+ SetTextColor(hdcMem, cfg::clcdat->fontInfo[FONTID_FRAMETITLE].colour);
+ } else {
+ FillRect(hdcMem, &rect, hBack);
+ SetTextColor(hdcMem, GetSysColor(COLOR_BTNTEXT));
+ }
+
+
+ if (!AlignCOLLIconToLeft) {
+ if (Frames[pos].TitleBar.hicon != NULL) {
+ DrawIconEx(hdcMem, 6 + cfg::dat.bClipBorder, ((TitleBarH >> 1) - 8), Frames[pos].TitleBar.hicon, 16, 16, 0, NULL, DI_NORMAL);
+ TextOut(hdcMem, 24 + cfg::dat.bClipBorder, fontTop, Frames[pos].TitleBar.tbname, lstrlen(Frames[pos].TitleBar.tbname));
+ } else
+ TextOut(hdcMem, 6 + cfg::dat.bClipBorder, fontTop, Frames[pos].TitleBar.tbname, lstrlen(Frames[pos].TitleBar.tbname));
+ } else
+ TextOut(hdcMem, 18 + cfg::dat.bClipBorder, fontTop, Frames[pos].TitleBar.tbname, lstrlen(Frames[pos].TitleBar.tbname));
+
+
+ if (!AlignCOLLIconToLeft)
+ DrawIconEx(hdcMem, Frames[pos].TitleBar.wndSize.right - 22, ((TitleBarH >> 1) - 8), Frames[pos].collapsed ? LoadSkinnedIcon(SKINICON_OTHER_GROUPOPEN) : LoadSkinnedIcon(SKINICON_OTHER_GROUPSHUT), 16, 16, 0, NULL, DI_NORMAL);
+ else
+ DrawIconEx(hdcMem, 0, ((TitleBarH >> 1) - 8), Frames[pos].collapsed ? LoadSkinnedIcon(SKINICON_OTHER_GROUPOPEN) : LoadSkinnedIcon(SKINICON_OTHER_GROUPSHUT), 16, 16, 0, NULL, DI_NORMAL);
+ SelectObject(hdcMem, oFont);
+ }
+ ulockfrm();
+ BitBlt(dc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcMem, rect.left, rect.top, SRCCOPY);
+ SelectObject(hdcMem, hoBmp);
+ SelectObject(hdcMem, hoBrush);
+ DeleteDC(hdcMem);
+ DeleteObject(hBack);
+ DeleteObject(hBmpOsb);
+ return 0;
+}
+
+#define MPCF_CONTEXTFRAMEMENU 3
+POINT ptOld;
+short nLeft = 0;
+short nTop = 0;
+
+LRESULT CALLBACK CLUIFrameTitleBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ RECT rect;
+ int Frameid, Framemod, direction;
+ int xpos, ypos;
+
+ Frameid = GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ memset(&rect, 0, sizeof(rect));
+
+ switch (msg) {
+ case WM_CREATE:
+ return FALSE;
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ case WM_DRAWITEM:
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+
+ case WM_ENABLE:
+ if (hwnd != 0) InvalidateRect(hwnd, NULL, FALSE);
+ return 0;
+ case WM_SIZE:
+ return 0;
+ /*
+ case WM_PRINT:
+ case WM_PRINTCLIENT:
+ InvalidateRect(hwnd,NULL,FALSE);
+ {
+ RECT rect;
+ HDC dc;
+ GetClientRect(hwnd,&rect);
+ //DrawTitleBar(wParam,rect,Frameid);
+ SendMessage(hwnd,WM_PAINT,0,0);
+ SendMessage(hwnd,WM_NCPAINT,1,0);
+ dc=GetDC(hwnd);
+ SendMessage(hwnd,WM_ERASEBKGND,dc,0);
+ ReleaseDC(hwnd,dc);
+ SendMessage(hwnd,WM_PAINT,0,0);
+ // UpdateWindow(hwnd);
+ return(0);
+ }
+ */
+ /*
+ case WM_NCPAINT:
+ {
+
+ // if(wParam==1) break;
+ { POINT ptTopLeft={0,0};
+ HRGN hClientRgn;
+ ClientToScreen(hwnd,&ptTopLeft);
+ hClientRgn=CreateRectRgn(0,0,1,1);
+ CombineRgn(hClientRgn,(HRGN)wParam,NULL,RGN_COPY);
+ OffsetRgn(hClientRgn,-ptTopLeft.x,-ptTopLeft.y);
+ InvalidateRgn(hwnd,hClientRgn,FALSE);
+ DeleteObject(hClientRgn);
+ UpdateWindow(hwnd);
+ }
+ //return(0);
+ };
+ */
+
+
+ case WM_COMMAND:
+ if (ServiceExists(MO_CREATENEWMENUOBJECT)) {
+ if (ProcessCommandProxy(MAKEWPARAM(LOWORD(wParam), 0), (LPARAM)Frameid))
+ break;
+ } else {
+ if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTEXTFRAMEMENU), (LPARAM)Frameid))
+ break;
+ }
+
+ if (HIWORD(wParam) == 0) {//mouse events for self created menu
+ int framepos = id2pos(Frameid);
+ if (framepos == -1)
+ break;
+
+ switch (LOWORD(wParam)) {
+ case frame_menu_lock:
+ Frames[framepos].Locked = !Frames[framepos].Locked;
+ break;
+ case frame_menu_visible:
+ Frames[framepos].visible = !Frames[framepos].visible;
+ break;
+ case frame_menu_showtitlebar:
+ Frames[framepos].TitleBar.ShowTitleBar = !Frames[framepos].TitleBar.ShowTitleBar;
+ break;
+ case frame_menu_floating:
+ CLUIFrameSetFloat(Frameid, 0);
+ break;
+ }
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ }
+
+ break;
+ case WM_RBUTTONDOWN: {
+ HMENU hmenu;
+ POINT pt;
+ GetCursorPos(&pt);
+
+ if (ServiceExists(MS_CLIST_MENUBUILDFRAMECONTEXT)) {
+ hmenu = (HMENU)CallService(MS_CLIST_MENUBUILDFRAMECONTEXT, Frameid, 0);
+ } else {
+ int framepos = id2pos(Frameid);
+
+ lockfrm();
+ if (framepos == -1) {
+ ulockfrm();
+ break;
+ }
+ hmenu = CreatePopupMenu();
+ AppendMenu(hmenu, MF_STRING | MF_DISABLED | MF_GRAYED, 15, Frames[framepos].name);
+ AppendMenu(hmenu, MF_SEPARATOR, 16, _T(""));
+
+ if (Frames[framepos].Locked)
+ AppendMenu(hmenu, MF_STRING | MF_CHECKED, frame_menu_lock, TranslateT("Lock Frame"));
+ else
+ AppendMenu(hmenu, MF_STRING, frame_menu_lock, TranslateT("Lock Frame"));
+
+ if (Frames[framepos].visible)
+ AppendMenu(hmenu, MF_STRING | MF_CHECKED, frame_menu_visible, TranslateT("Visible"));
+ else
+ AppendMenu(hmenu, MF_STRING, frame_menu_visible, TranslateT("Visible"));
+
+ if (Frames[framepos].TitleBar.ShowTitleBar)
+ AppendMenu(hmenu, MF_STRING | MF_CHECKED, frame_menu_showtitlebar, TranslateT("Show TitleBar"));
+ else
+ AppendMenu(hmenu, MF_STRING, frame_menu_showtitlebar, TranslateT("Show TitleBar"));
+
+ if (Frames[framepos].Skinned)
+ AppendMenu(hmenu, MF_STRING | MF_CHECKED, frame_menu_skinned, TranslateT("Skinned frame"));
+ else
+ AppendMenu(hmenu, MF_STRING, frame_menu_skinned, TranslateT("Skinned frame"));
+
+ if (Frames[framepos].floating)
+ AppendMenu(hmenu, MF_STRING | MF_CHECKED, frame_menu_floating, TranslateT("Floating"));
+ else
+ AppendMenu(hmenu, MF_STRING, frame_menu_floating, TranslateT("Floating"));
+
+ ulockfrm();
+ }
+ TrackPopupMenu(hmenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, 0);
+ DestroyMenu(hmenu);
+ }
+ break;
+ case WM_LBUTTONDBLCLK: {
+ Framemod = -1;
+ lbypos = -1;
+ oldframeheight = -1;
+ ReleaseCapture();
+ CallService(MS_CLIST_FRAMES_UCOLLFRAME, Frameid, 0);
+ lbypos = -1;
+ oldframeheight = -1;
+ ReleaseCapture();
+ }
+ break;
+
+ case WM_LBUTTONUP: {
+ if (GetCapture() != hwnd) {
+ break;
+ };
+ curdragbar = -1;
+ lbypos = -1;
+ oldframeheight = -1;
+ ReleaseCapture();
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN);
+ break;
+ };
+ case WM_LBUTTONDOWN: {
+
+ int framepos = id2pos(Frameid);
+ lockfrm();
+ if (framepos == -1) {
+ ulockfrm();
+ break;
+ }
+ if (Frames[framepos].floating) {
+
+ POINT pt;
+ GetCursorPos(&pt);
+ Frames[framepos].TitleBar.oldpos = pt;
+ }
+
+ if ((!(wParam&MK_CONTROL)) && Frames[framepos].Locked && (!(Frames[framepos].floating))) {
+ if (cfg::getByte("CLUI", "ClientAreaDrag", 0)) {
+ POINT pt;
+ GetCursorPos(&pt);
+ ulockfrm();
+ return SendMessage(GetParent(hwnd), WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ }
+ }
+ if (Frames[framepos].floating) {
+ RECT rc;
+ GetCursorPos(&ptOld);
+ GetWindowRect(hwnd, &rc);
+ nLeft = (short)rc.left;
+ nTop = (short)rc.top;
+ }
+ ulockfrm();
+ SetCapture(hwnd);
+ break;
+ }
+ case WM_MOUSEMOVE: {
+ POINT pt, pt2;
+ RECT wndr;
+ int pos;
+ {
+ char TBcapt[255];
+
+ lockfrm();
+ pos = id2pos(Frameid);
+
+ if (pos != -1) {
+ int oldflags;
+ wsprintfA(TBcapt, "%s - h:%d, vis:%d, fl:%d, fl:(%d,%d,%d,%d),or: %d",
+ Frames[pos].name, Frames[pos].height, Frames[pos].visible, Frames[pos].floating,
+ Frames[pos].FloatingPos.x, Frames[pos].FloatingPos.y,
+ Frames[pos].FloatingSize.x, Frames[pos].FloatingSize.y,
+ Frames[pos].order
+ );
+
+ oldflags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, Frames[pos].id), (LPARAM)0);
+ if (!(oldflags&F_SHOWTBTIP))
+ oldflags |= F_SHOWTBTIP;
+ }
+ ulockfrm();
+ }
+ if ((wParam&MK_LBUTTON)/*&&(wParam&MK_CONTROL)*/) {
+ RECT rcMiranda;
+ RECT rcwnd, rcOverlap;
+ POINT newpt, ofspt, curpt, newpos;
+
+ lockfrm();
+
+ pos = id2pos(Frameid);
+ if (Frames[pos].floating) {
+ GetCursorPos(&curpt);
+ rcwnd.bottom = curpt.y + 5;
+ rcwnd.top = curpt.y;
+ rcwnd.left = curpt.x;
+ rcwnd.right = curpt.x + 5;
+
+ GetWindowRect(pcli->hwndContactList, &rcMiranda);
+ if (IsWindowVisible(pcli->hwndContactList) && IntersectRect(&rcOverlap, &rcwnd, &rcMiranda)) {
+ int id = Frames[pos].id;
+
+ ulockfrm();
+ ofspt.x = 0;
+ ofspt.y = 0;
+ ClientToScreen(Frames[pos].TitleBar.hwnd, &ofspt);
+ ofspt.x = curpt.x - ofspt.x;
+ ofspt.y = curpt.y - ofspt.y;
+
+ CLUIFrameSetFloat(id, 0);
+ newpt.x = 0;
+ newpt.y = 0;
+ ClientToScreen(Frames[pos].TitleBar.hwnd, &newpt);
+ SetCursorPos(newpt.x + ofspt.x, newpt.y + ofspt.y);
+ GetCursorPos(&curpt);
+ lockfrm();
+ Frames[pos].TitleBar.oldpos = curpt;
+ ulockfrm();
+ return(0);
+ }
+ } else {
+ int id = Frames[pos].id;
+
+ GetCursorPos(&curpt);
+ rcwnd.bottom = curpt.y + 5;
+ rcwnd.top = curpt.y;
+ rcwnd.left = curpt.x;
+ rcwnd.right = curpt.x + 5;
+
+ GetWindowRect(pcli->hwndContactList, &rcMiranda);
+
+ if (!IntersectRect(&rcOverlap, &rcwnd, &rcMiranda)) {
+ ulockfrm();
+ GetCursorPos(&curpt);
+ GetWindowRect(Frames[pos].hWnd, &rcwnd);
+ rcwnd.left = rcwnd.right - rcwnd.left;
+ rcwnd.top = rcwnd.bottom - rcwnd.top;
+ newpos.x = curpt.x;
+ newpos.y = curpt.y;
+ if (curpt.x >= (rcMiranda.right - 1)) {
+ newpos.x = curpt.x + 5;
+ }
+ if (curpt.x <= (rcMiranda.left + 1)) {
+ newpos.x = curpt.x - (rcwnd.left) - 5;
+ }
+ if (curpt.y >= (rcMiranda.bottom - 1)) {
+ newpos.y = curpt.y + 5;
+ }
+ if (curpt.y <= (rcMiranda.top + 1)) {
+ newpos.y = curpt.y - (rcwnd.top) - 5;
+ };
+ ofspt.x = 0;
+ ofspt.y = 0;
+ GetWindowRect(Frames[pos].TitleBar.hwnd, &rcwnd);
+ ofspt.x = curpt.x - ofspt.x;
+ ofspt.y = curpt.y - ofspt.y;
+ Frames[pos].FloatingPos.x = newpos.x;
+ Frames[pos].FloatingPos.y = newpos.y;
+ CLUIFrameSetFloat(id, 0);
+ lockfrm();
+ newpt.x = 0;
+ newpt.y = 0;
+ ClientToScreen(Frames[pos].TitleBar.hwnd, &newpt);
+ GetWindowRect(Frames[pos].hWnd, &rcwnd);
+ SetCursorPos(newpt.x + (rcwnd.right - rcwnd.left) / 2, newpt.y + (rcwnd.bottom - rcwnd.top) / 2);
+ GetCursorPos(&curpt);
+ Frames[pos].TitleBar.oldpos = curpt;
+ ulockfrm();
+ return(0);
+ }
+ }
+ ulockfrm();
+ }
+ if (wParam&MK_LBUTTON) {
+ int newh = -1, prevold;
+
+ if (GetCapture() != hwnd)
+ break;
+
+ lockfrm();
+ pos = id2pos(Frameid);
+
+ if (Frames[pos].floating) {
+ GetCursorPos(&pt);
+ if ((Frames[pos].TitleBar.oldpos.x != pt.x) || (Frames[pos].TitleBar.oldpos.y != pt.y)) {
+
+ pt2 = pt;
+ ScreenToClient(hwnd, &pt2);
+ GetWindowRect(Frames[pos].ContainerWnd, &wndr);
+ {
+ int dX, dY;
+ POINT ptNew;
+
+ ptNew.x = pt.x;
+ ptNew.y = pt.y;
+
+ dX = ptNew.x - ptOld.x;
+ dY = ptNew.y - ptOld.y;
+
+ nLeft += (short)dX;
+ nTop += (short)dY;
+
+ if (!(wParam&MK_CONTROL)) {
+ PositionThumb(&Frames[pos], nLeft, nTop);
+ } else {
+
+ SetWindowPos(Frames[pos].ContainerWnd,
+ 0,
+ nLeft,
+ nTop,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER);
+ }
+ ptOld = ptNew;
+ }
+ pt.x = nLeft;
+ pt.y = nTop;
+ Frames[pos].TitleBar.oldpos = pt;
+ }
+ ulockfrm();
+ return(0);
+ }
+ if (Frames[pos].prevvisframe != -1) {
+ GetCursorPos(&pt);
+
+ if ((Frames[pos].TitleBar.oldpos.x == pt.x) && (Frames[pos].TitleBar.oldpos.y == pt.y)) {
+ ulockfrm();
+ break;
+ }
+
+ ypos = rect.top + pt.y;
+ xpos = rect.left + pt.x;
+ Framemod = -1;
+
+ if (Frames[pos].align == alBottom) {
+ direction = -1;
+ Framemod = pos;
+ } else {
+ direction = 1;
+ Framemod = Frames[pos].prevvisframe;
+ }
+ if (Frames[Framemod].Locked) {
+ ulockfrm();
+ break;
+ }
+ if (curdragbar != -1 && curdragbar != pos) {
+ ulockfrm();
+ break;
+ }
+
+ if (lbypos == -1) {
+ curdragbar = pos;
+ lbypos = ypos;
+ oldframeheight = Frames[Framemod].height;
+ SetCapture(hwnd);
+ ulockfrm();
+ break;;
+ }
+ newh = oldframeheight + direction * (ypos - lbypos);
+ if (newh > 0) {
+ prevold = Frames[Framemod].height;
+ Frames[Framemod].height = newh;
+ if (!CLUIFramesFitInSize()) {
+ Frames[Framemod].height = prevold;
+ ulockfrm();
+ return TRUE;
+ }
+ Frames[Framemod].height = newh;
+ if (newh > 3) Frames[Framemod].collapsed = TRUE;
+
+ }
+ Frames[pos].TitleBar.oldpos = pt;
+ }
+ ulockfrm();
+ if (newh > 0) {
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ }
+ break;
+ }
+ curdragbar = -1;
+ lbypos = -1;
+ oldframeheight = -1;
+ ReleaseCapture();
+ }
+ break;
+ case WM_NCPAINT: {
+ if (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_BORDER) {
+ HDC hdc = GetWindowDC(hwnd);
+ HPEN hPenOld = reinterpret_cast<HPEN>(SelectObject(hdc, g_hPenCLUIFrames));
+ RECT rcWindow, rc;
+ HBRUSH brold;
+
+ CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
+ GetWindowRect(hwnd, &rcWindow);
+ rc.left = rc.top = 0;
+ rc.right = rcWindow.right - rcWindow.left;
+ rc.bottom = rcWindow.bottom - rcWindow.top;
+ brold = reinterpret_cast<HBRUSH>(SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)));
+ Rectangle(hdc, 0, 0, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top);
+ SelectObject(hdc, hPenOld);
+ SelectObject(hdc, brold);
+ ReleaseDC(hwnd, hdc);
+ return 0;
+ }
+ break;
+ }
+ case WM_PRINT:
+ case WM_PRINTCLIENT: {
+ GetClientRect(hwnd, &rect);
+ DrawTitleBar((HDC)wParam, rect, Frameid);
+ }
+ case WM_PAINT: {
+ HDC paintDC;
+ PAINTSTRUCT paintStruct;
+
+ paintDC = BeginPaint(hwnd, &paintStruct);
+ rect = paintStruct.rcPaint;
+ DrawTitleBar(paintDC, rect, Frameid);
+ EndPaint(hwnd, &paintStruct);
+ return 0;
+ }
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return TRUE;
+}
+int CLUIFrameResizeFloatingFrame(int framepos)
+{
+
+ int width, height, floatingHeight;
+ RECT rect;
+
+ if (!Frames[framepos].floating)
+ return(0);
+ if (Frames[framepos].ContainerWnd == 0)
+ return(0);
+ GetClientRect(Frames[framepos].ContainerWnd, &rect);
+
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ floatingHeight = cfg::dat.titleBarHeight;
+
+ if(floatingHeight <= 0 || floatingHeight > 50)
+ floatingHeight = 18;
+
+ Frames[framepos].visible ? ShowWindow(Frames[framepos].ContainerWnd, SW_SHOWNOACTIVATE) : ShowWindow(Frames[framepos].ContainerWnd, SW_HIDE);
+
+ if (Frames[framepos].TitleBar.ShowTitleBar) {
+ ShowWindow(Frames[framepos].TitleBar.hwnd, SW_SHOWNOACTIVATE);
+ Frames[framepos].height = height - floatingHeight;
+ SetWindowPos(Frames[framepos].TitleBar.hwnd, HWND_TOP, 0, 0, width, floatingHeight, SWP_SHOWWINDOW | SWP_DRAWFRAME | SWP_NOACTIVATE);
+ InvalidateRect(Frames[framepos].TitleBar.hwnd, NULL, FALSE);
+ SetWindowPos(Frames[framepos].hWnd, HWND_TOP, 0, floatingHeight, width, height - floatingHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE);
+
+ } else {
+ Frames[framepos].height = height;
+ ShowWindow(Frames[framepos].TitleBar.hwnd, SW_HIDE);
+ SetWindowPos(Frames[framepos].hWnd, HWND_TOP, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOACTIVATE);
+ }
+
+ if (Frames[framepos].ContainerWnd != 0)
+ UpdateWindow(Frames[framepos].ContainerWnd);
+ GetWindowRect(Frames[framepos].hWnd, &Frames[framepos].wndSize);
+
+ if (Frames[framepos].TitleBar.ShowTitleBar)
+ RedrawWindow(Frames[framepos].TitleBar.hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
+ RedrawWindow(Frames[framepos].hWnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
+
+ return(0);
+}
+
+static int CLUIFrameOnMainMenuBuild(WPARAM wParam, LPARAM lParam)
+{
+ CLUIFramesLoadMainMenu();
+ return 0;
+}
+
+LRESULT CALLBACK CLUIFrameContainerWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ RECT rect;
+ INT_PTR Frameid = GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ memset(&rect, 0, sizeof(rect));
+ switch (msg) {
+ case WM_CREATE: {
+ int framepos;
+ lockfrm();
+ framepos = id2pos(Frameid);
+ ulockfrm();
+ return(0);
+ }
+ case WM_GETMINMAXINFO: {
+ int framepos;
+ MINMAXINFO minmax;
+
+ TitleBarH = cfg::dat.titleBarHeight;
+ lockfrm();
+
+ framepos = id2pos(Frameid);
+ if (framepos < 0 || framepos >= nFramescount) {
+ ulockfrm();
+ break;
+ }
+ if (!Frames[framepos].minmaxenabled) {
+ ulockfrm();
+ break;
+ }
+ if (Frames[framepos].ContainerWnd == 0) {
+ ulockfrm();
+ break;
+ }
+ if (Frames[framepos].Locked) {
+ RECT rct;
+
+ GetWindowRect(hwnd, &rct);
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = rct.right - rct.left;
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = rct.bottom - rct.top;
+ ((LPMINMAXINFO)lParam)->ptMaxTrackSize.x = rct.right - rct.left;
+ ((LPMINMAXINFO)lParam)->ptMaxTrackSize.y = rct.bottom - rct.top;
+ }
+
+ memset(&minmax, 0, sizeof(minmax));
+ if (SendMessage(Frames[framepos].hWnd, WM_GETMINMAXINFO, (WPARAM)0, (LPARAM)&minmax) == 0) {
+ RECT border;
+ int tbh = TitleBarH * btoint(Frames[framepos].TitleBar.ShowTitleBar);
+ GetBorderSize(hwnd, &border);
+ if (minmax.ptMaxTrackSize.x != 0 && minmax.ptMaxTrackSize.y != 0) {
+
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = minmax.ptMinTrackSize.x;
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = minmax.ptMinTrackSize.y;
+ ((LPMINMAXINFO)lParam)->ptMaxTrackSize.x = minmax.ptMaxTrackSize.x + border.left + border.right;
+ ((LPMINMAXINFO)lParam)->ptMaxTrackSize.y = minmax.ptMaxTrackSize.y + tbh + border.top + border.bottom;
+ }
+ } else {
+ ulockfrm();
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+ }
+ ulockfrm();
+ }
+ case WM_MOVE: {
+ int framepos;
+ RECT rect;
+
+ lockfrm();
+ framepos = id2pos(Frameid);
+
+ if (framepos < 0 || framepos >= nFramescount) {
+ ulockfrm();
+ break;
+ }
+ if (Frames[framepos].ContainerWnd == 0) {
+ ulockfrm();
+ return(0);
+ }
+ GetWindowRect(Frames[framepos].ContainerWnd, &rect);
+ Frames[framepos].FloatingPos.x = rect.left;
+ Frames[framepos].FloatingPos.y = rect.top;
+ Frames[framepos].FloatingSize.x = rect.right - rect.left;
+ Frames[framepos].FloatingSize.y = rect.bottom - rect.top;
+ CLUIFramesStoreFrameSettings(framepos);
+ ulockfrm();
+ return(0);
+ }
+ case WM_SIZE: {
+ int framepos;
+ RECT rect;
+ lockfrm();
+
+ framepos = id2pos(Frameid);
+
+ if (framepos < 0 || framepos >= nFramescount) {
+ ulockfrm();
+ break;
+ }
+ if (Frames[framepos].ContainerWnd == 0) {
+ ulockfrm();
+ return(0);
+ }
+ CLUIFrameResizeFloatingFrame(framepos);
+
+ GetWindowRect(Frames[framepos].ContainerWnd, &rect);
+ Frames[framepos].FloatingPos.x = rect.left;
+ Frames[framepos].FloatingPos.y = rect.top;
+ Frames[framepos].FloatingSize.x = rect.right - rect.left;
+ Frames[framepos].FloatingSize.y = rect.bottom - rect.top;
+
+ CLUIFramesStoreFrameSettings(framepos);
+ ulockfrm();
+ return(0);
+ }
+ case WM_CLOSE: {
+ DestroyWindow(hwnd);
+ break;
+ }
+ case WM_DESTROY:
+ return(0);
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static HWND CreateContainerWindow(HWND parent, int x, int y, int width, int height)
+{
+ return(CreateWindowA("FramesContainer", "aaaa", WS_POPUP | WS_THICKFRAME, x, y, width, height, parent, 0, g_hInst, 0));
+}
+
+
+INT_PTR CLUIFrameSetFloat(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwndtmp, hwndtooltiptmp;
+
+ lockfrm();
+ wParam = id2pos((INT_PTR)wParam);
+ if (wParam >= 0 && (int)wParam < nFramescount)
+ if (Frames[wParam].floating) {
+ SetParent(Frames[wParam].hWnd, pcli->hwndContactList);
+ SetParent(Frames[wParam].TitleBar.hwnd, pcli->hwndContactList);
+ Frames[wParam].floating = FALSE;
+ DestroyWindow(Frames[wParam].ContainerWnd);
+ Frames[wParam].ContainerWnd = 0;
+ } else {
+ RECT recttb, rectw, border;
+ int temp;
+ int neww, newh;
+ BOOLEAN locked;
+
+ Frames[wParam].oldstyles = GetWindowLongPtr(Frames[wParam].hWnd, GWL_STYLE);
+ Frames[wParam].TitleBar.oldstyles = GetWindowLongPtr(Frames[wParam].TitleBar.hwnd, GWL_STYLE);
+ locked = Frames[wParam].Locked;
+ Frames[wParam].Locked = FALSE;
+ Frames[wParam].minmaxenabled = FALSE;
+
+ GetWindowRect(Frames[wParam].hWnd, &rectw);
+ GetWindowRect(Frames[wParam].TitleBar.hwnd, &recttb);
+ if (!Frames[wParam].TitleBar.ShowTitleBar) {
+ recttb.top = recttb.bottom = recttb.left = recttb.right = 0;
+ }
+ Frames[wParam].ContainerWnd = CreateContainerWindow(pcli->hwndContactList, Frames[wParam].FloatingPos.x, Frames[wParam].FloatingPos.y, 10, 10);
+
+ SetParent(Frames[wParam].hWnd, Frames[wParam].ContainerWnd);
+ SetParent(Frames[wParam].TitleBar.hwnd, Frames[wParam].ContainerWnd);
+
+ GetBorderSize(Frames[wParam].ContainerWnd, &border);
+
+ SetWindowLongPtr(Frames[wParam].ContainerWnd, GWLP_USERDATA, Frames[wParam].id);
+ if ((lParam == 1)) {
+ if ((Frames[wParam].FloatingPos.x != 0) && (Frames[wParam].FloatingPos.y != 0)) {
+ if (Frames[wParam].FloatingPos.x < 20) {
+ Frames[wParam].FloatingPos.x = 40;
+ }
+ if (Frames[wParam].FloatingPos.y < 20) {
+ Frames[wParam].FloatingPos.y = 40;
+ }
+ SetWindowPos(Frames[wParam].ContainerWnd, HWND_TOPMOST, Frames[wParam].FloatingPos.x, Frames[wParam].FloatingPos.y, Frames[wParam].FloatingSize.x, Frames[wParam].FloatingSize.y, SWP_HIDEWINDOW);
+ } else {
+ SetWindowPos(Frames[wParam].ContainerWnd, HWND_TOPMOST, 120, 120, 140, 140, SWP_HIDEWINDOW);
+ }
+ } else {
+ neww = rectw.right - rectw.left + border.left + border.right;
+ newh = (rectw.bottom - rectw.top) + (recttb.bottom - recttb.top) + border.top + border.bottom;
+ if (neww < 20) {
+ neww = 40;
+ }
+ if (newh < 20) {
+ newh = 40;
+ }
+ if (Frames[wParam].FloatingPos.x < 20) {
+ Frames[wParam].FloatingPos.x = 40;
+ }
+ if (Frames[wParam].FloatingPos.y < 20) {
+ Frames[wParam].FloatingPos.y = 40;
+ }
+ SetWindowPos(Frames[wParam].ContainerWnd, HWND_TOPMOST, Frames[wParam].FloatingPos.x, Frames[wParam].FloatingPos.y, neww, newh, SWP_HIDEWINDOW);
+ }
+ SetWindowText(Frames[wParam].ContainerWnd, Frames[wParam].TitleBar.tbname);
+ temp = GetWindowLongPtr(Frames[wParam].ContainerWnd, GWL_EXSTYLE);
+ temp |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST ;
+ SetWindowLongPtr(Frames[wParam].ContainerWnd, GWL_EXSTYLE, temp);
+ Frames[wParam].floating = TRUE;
+ Frames[wParam].Locked = locked;
+
+ }
+ CLUIFramesStoreFrameSettings(wParam);
+ Frames[wParam].minmaxenabled = TRUE;
+ hwndtooltiptmp = Frames[wParam].TitleBar.hwndTip;
+
+ hwndtmp = Frames[wParam].ContainerWnd;
+ ulockfrm();
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, (LPARAM)0);
+ SendMessage(hwndtmp, WM_SIZE, 0, 0);
+ SetWindowPos(hwndtooltiptmp, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ return 0;
+}
+
+TCHAR g_ptszEventName[100];
+
+static int CLUIFrameOnModulesLoad(WPARAM wParam, LPARAM lParam)
+{
+ mir_sntprintf(g_ptszEventName, SIZEOF(g_ptszEventName), _T("mf_update_evt_%d"), GetCurrentThreadId());
+ g_hEventThread = CreateEvent(NULL, TRUE, FALSE, g_ptszEventName);
+ hThreadMFUpdate = (HANDLE)mir_forkthreadex(reinterpret_cast<pThreadFuncEx>(MF_UpdateThread), NULL, NULL);
+ SetThreadPriority(hThreadMFUpdate, THREAD_PRIORITY_IDLE);
+ CLUIFramesLoadMainMenu();
+ CLUIFramesCreateMenuForFrame(-1, -1, 000010000, Menu_AddContextFrameMenuItem);
+ return 0;
+}
+
+static int CLUIFrameOnModulesUnload(WPARAM wParam, LPARAM lParam)
+{
+ mf_updatethread_running = FALSE;
+
+ SetThreadPriority(hThreadMFUpdate, THREAD_PRIORITY_NORMAL);
+ SetEvent(g_hEventThread);
+ WaitForSingleObject(hThreadMFUpdate, 2000);
+ CloseHandle(hThreadMFUpdate);
+ CloseHandle(g_hEventThread);
+
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIVisible, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMITitle, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMITBVisible, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMILock, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIColl, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIFloating, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIAlignRoot, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIAlignTop, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIAlignClient, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIAlignBottom, 0);
+ CallService(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM, (LPARAM)contMIBorder, 0);
+ return 0;
+}
+
+static INT_PTR SetIconForExtraColumn(WPARAM wParam, LPARAM lParam)
+{
+ pIconExtraColumn piec;
+
+ if (pcli->hwndContactTree == 0)
+ return -1;
+
+ if (wParam == 0 || lParam == 0 || IsBadCodePtr((FARPROC)lParam))
+ return -1;
+
+ piec = (pIconExtraColumn)lParam;
+
+ if (piec->cbSize != sizeof(IconExtraColumn))
+ return -1;
+
+ if (cfg::dat.bMetaAvail && cfg::dat.bMetaEnabled && cfg::getByte((HANDLE)wParam, cfg::dat.szMetaName, "IsSubcontact", 0))
+ PostMessage(pcli->hwndContactTree, CLM_SETEXTRAIMAGEINTMETA, wParam, MAKELONG((WORD)piec->ColumnType, (WORD)piec->hImage));
+ else
+ PostMessage(pcli->hwndContactTree, CLM_SETEXTRAIMAGEINT, wParam, MAKELONG((WORD)piec->ColumnType, (WORD)piec->hImage));
+ return 0;
+}
+
+/*
+ * wparam=hIcon
+ * return hImage on success,-1 on failure
+ */
+static INT_PTR AddIconToExtraImageList(WPARAM wParam, LPARAM lParam)
+{
+ if (himlExtraImages == 0 || wParam == 0)
+ return -1;
+
+ return((int)ImageList_AddIcon(himlExtraImages, (HICON)wParam));
+}
+
+/*
+static INT_PTR SkinDrawBgService(WPARAM wParam, LPARAM lParam)
+{
+ StatusItems_t item;
+ HWND hwnd;
+ RECT rc;
+
+ SKINDRAWREQUEST *sdrq = (SKINDRAWREQUEST *)wParam;
+
+ if(wParam == 0 || IsBadCodePtr((FARPROC)wParam) || pDrawAlpha == NULL)
+ return 0;
+
+ hwnd = WindowFromDC(sdrq->hDC);
+ GetClientRect(hwnd, &rc);
+ if(strstr(sdrq->szObjectID, "/Background") && EqualRect(&sdrq->rcClipRect, &sdrq->rcDestRect)) {
+ SkinDrawBg(hwnd, sdrq->hDC);
+ GetItemByStatus(ID_EXTBKEVTAREA, &item);
+ if(item.IGNORED)
+ FillRect(sdrq->hDC, &(sdrq->rcClipRect), GetSysColorBrush(COLOR_3DFACE));
+ else {
+ DrawAlpha(sdrq->hDC, &(sdrq->rcClipRect), item.COLOR, item.ALPHA, item.COLOR2, item.COLOR2_TRANSPARENT,
+ item.GRADIENT, item.CORNER, item.BORDERSTYLE, item.imageItem);
+ }
+ }
+ else {
+ GetItemByStatus(ID_EXTBKEVTAREA, &item);
+ if(item.IGNORED)
+ FillRect(sdrq->hDC, &(sdrq->rcClipRect), GetSysColorBrush(COLOR_3DFACE));
+ else {
+ DrawAlpha(sdrq->hDC, &(sdrq->rcClipRect), item.COLOR, item.ALPHA, item.COLOR2, item.COLOR2_TRANSPARENT,
+ item.GRADIENT, item.CORNER, item.BORDERSTYLE, item.imageItem);
+ }
+ }
+}
+*/
+
+void RegisterCLUIFrameClasses()
+{
+ WNDCLASS wndclass;
+ WNDCLASS cntclass;
+
+ wndclass.style = CS_DBLCLKS;//|CS_HREDRAW|CS_VREDRAW ;
+ wndclass.lpfnWndProc = CLUIFrameTitleBarProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = g_hInst;
+ wndclass.hIcon = NULL;
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = NULL;
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = CLUIFrameTitleBarClassName;
+ RegisterClass(&wndclass);
+
+ cntclass.style = CS_DBLCLKS/*|CS_HREDRAW|CS_VREDRAW*/ | (IsWinVerXPPlus() ? CS_DROPSHADOW : 0);
+ cntclass.lpfnWndProc = CLUIFrameContainerWndProc;
+ cntclass.cbClsExtra = 0;
+ cntclass.cbWndExtra = 0;
+ cntclass.hInstance = g_hInst;
+ cntclass.hIcon = NULL;
+ cntclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ cntclass.hbrBackground = NULL;
+ cntclass.lpszMenuName = NULL;
+ cntclass.lpszClassName = _T("FramesContainer");
+ RegisterClass(&cntclass);
+}
+
+int LoadCLUIFramesModule(void)
+{
+ GapBetweenFrames = cfg::dat.gapBetweenFrames;
+
+ nFramescount = 0;
+ InitializeCriticalSection(&csFrameHook);
+ InitFramesMenus();
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, CLUIFrameOnModulesLoad);
+ HookEvent(ME_CLIST_PREBUILDFRAMEMENU, CLUIFramesModifyContextMenuForFrame);
+ HookEvent(ME_CLIST_PREBUILDMAINMENU, CLUIFrameOnMainMenuBuild);
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, CLUIFrameOnModulesUnload);
+
+ CreateServiceFunction(MS_CLIST_FRAMES_ADDFRAME, CLUIFramesAddFrame);
+ CreateServiceFunction(MS_CLIST_FRAMES_REMOVEFRAME, CLUIFramesRemoveFrame);
+
+ CreateServiceFunction(MS_CLIST_FRAMES_SETFRAMEOPTIONS, CLUIFramesSetFrameOptions);
+ CreateServiceFunction(MS_CLIST_FRAMES_GETFRAMEOPTIONS, CLUIFramesGetFrameOptions);
+ CreateServiceFunction(MS_CLIST_FRAMES_UPDATEFRAME, CLUIFramesUpdateFrame);
+
+ CreateServiceFunction(MS_CLIST_FRAMES_SHFRAMETITLEBAR, CLUIFramesShowHideFrameTitleBar);
+ CreateServiceFunction(MS_CLIST_FRAMES_SHOWALLFRAMESTB, CLUIFramesShowAllTitleBars);
+ CreateServiceFunction(MS_CLIST_FRAMES_HIDEALLFRAMESTB, CLUIFramesHideAllTitleBars);
+ CreateServiceFunction(MS_CLIST_FRAMES_SHFRAME, CLUIFramesShowHideFrame);
+ CreateServiceFunction(MS_CLIST_FRAMES_SHOWALLFRAMES, CLUIFramesShowAll);
+
+ CreateServiceFunction(MS_CLIST_FRAMES_ULFRAME, CLUIFramesLockUnlockFrame);
+ CreateServiceFunction(MS_CLIST_FRAMES_UCOLLFRAME, CLUIFramesCollapseUnCollapseFrame);
+ CreateServiceFunction(MS_CLIST_FRAMES_SETUNBORDER, CLUIFramesSetUnSetBorder);
+ CreateServiceFunction(MS_CLIST_FRAMES_SETSKINNED, CLUIFramesSetUnSetSkinned);
+
+ CreateServiceFunction(CLUIFRAMESSETALIGN, CLUIFramesSetAlign);
+ CreateServiceFunction(CLUIFRAMESMOVEDOWN, CLUIFramesMoveDown);
+ CreateServiceFunction(CLUIFRAMESMOVEUP, CLUIFramesMoveUp);
+
+ CreateServiceFunction(CLUIFRAMESSETALIGNALTOP, CLUIFramesSetAlignalTop);
+ CreateServiceFunction(CLUIFRAMESSETALIGNALCLIENT, CLUIFramesSetAlignalClient);
+ CreateServiceFunction(CLUIFRAMESSETALIGNALBOTTOM, CLUIFramesSetAlignalBottom);
+
+ CreateServiceFunction("Set_Floating", CLUIFrameSetFloat);
+ hWndExplorerToolBar = FindWindowExA(0, 0, "Shell_TrayWnd", NULL);
+ OnFrameTitleBarBackgroundChange();
+
+ FramesSysNotStarted = FALSE;
+ g_hPenCLUIFrames = CreatePen(PS_SOLID, 1, cfg::getDword("CLUI", "clr_frameborder", GetSysColor(COLOR_3DDKSHADOW)));
+ return 0;
+}
+
+void LoadExtraIconModule()
+{
+ CreateServiceFunction(MS_CLIST_EXTRA_SET_ICON, SetIconForExtraColumn);
+ CreateServiceFunction(MS_CLIST_EXTRA_ADD_ICON, AddIconToExtraImageList);
+
+ hExtraImageListRebuilding = CreateHookableEvent(ME_CLIST_EXTRA_LIST_REBUILD);
+ hExtraImageApplying = CreateHookableEvent(ME_CLIST_EXTRA_IMAGE_APPLY);
+
+ hStatusBarShowToolTipEvent = CreateHookableEvent(ME_CLIST_FRAMES_SB_SHOW_TOOLTIP);
+ hStatusBarHideToolTipEvent = CreateHookableEvent(ME_CLIST_FRAMES_SB_HIDE_TOOLTIP);
+}
+
+int UnLoadCLUIFramesModule(void)
+{
+ int i;
+ CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0);
+ CLUIFramesStoreAllFrames();
+ DeleteObject(g_hPenCLUIFrames);
+ EnterCriticalSection(&csFrameHook);
+ FramesSysNotStarted = TRUE;
+ for (i = 0;i < nFramescount;i++) {
+ DestroyWindow(Frames[i].hWnd);
+ Frames[i].hWnd = (HWND) - 1;
+ DestroyWindow(Frames[i].TitleBar.hwnd);
+ Frames[i].TitleBar.hwnd = (HWND) - 1;
+ DestroyWindow(Frames[i].ContainerWnd);
+ Frames[i].ContainerWnd = (HWND) - 1;
+ DestroyMenu(Frames[i].TitleBar.hmenu);
+
+ if (Frames[i].name != NULL)
+ mir_free(Frames[i].name);
+ if (Frames[i].TitleBar.tbname != NULL)
+ mir_free(Frames[i].TitleBar.tbname);
+ }
+ if (Frames)
+ free(Frames);
+ Frames = NULL;
+ nFramescount = 0;
+ UnregisterClass(CLUIFrameTitleBarClassName, g_hInst);
+ LeaveCriticalSection(&csFrameHook);
+ DeleteCriticalSection(&csFrameHook);
+ UnitFramesMenu();
+ return 0;
+}
+
+void ReloadExtraIcons()
+{
+ NotifyEventHooks(hExtraImageListRebuilding, 0, 0);
+}
diff --git a/plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.h b/plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.h
new file mode 100644
index 0000000000..083066ca6d
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/CLUIFrames/cluiframes.h
@@ -0,0 +1,105 @@
+/*
+Miranda ICQ: the free icq client for MS Windows
+Copyright (C) 2000-2 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+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.
+*/
+
+int LoadCLUIFramesModule(void);
+int UnLoadCLUIFramesModule(void);
+int CLUIFramesGetMinHeight();
+int CLUIFramesOnClistResize(WPARAM wParam,LPARAM lParam);
+int SizeFramesByWindowRect(RECT *r);
+int CLUIFramesResizeFrames(RECT *rc);
+
+typedef struct tagProtocolData {
+ char *RealName;
+ int statusbarpos;
+ boolean show;
+} ProtocolData;
+
+#define OFFSET_PROTOPOS 200
+#define OFFSET_VISIBLE 400
+
+#define CLUIFrameTitleBarClassName _T("CLUIFrameTitleBar")
+#define CLUIFrameModule "CLUIFrames"
+
+//integrated menu module
+#define MS_INT_MENUMEASUREITEM "CLUIFrames/IntMenuMeasureItem"
+#define MS_INT_MENUDRAWITEM "CLUIFrames/IntMenuDrawItem"
+#define MS_INT_MENUPROCESSCOMMAND "CLUIFrames/IntMenuProcessCommand"
+#define MS_INT_MODIFYMENUITEM "CLUIFrames/IntModifyMenuItem"
+
+typedef struct _DockOpt {
+ HWND hwndLeft;
+ HWND hwndRight;
+}
+DockOpt;
+
+typedef struct tagMenuHandles {
+ HANDLE MainMenuItem;
+ HANDLE MIVisible,MITitle,MITBVisible,MILock,MIColl,MIFloating,MIAlignRoot;
+ HANDLE MIAlignTop,MIAlignClient,MIAlignBottom;
+ HANDLE MIBorder, MISkinned;
+} FrameMenuHandles;
+
+typedef struct tagFrameTitleBar {
+ HWND hwnd;
+ HWND TitleBarbutt;
+ HWND hwndTip;
+
+ LPTSTR tbname;
+ LPTSTR tooltip;
+ HMENU hmenu;
+ HICON hicon;
+
+ BOOLEAN ShowTitleBar;
+ BOOLEAN ShowTitleBarTip;
+ int oldstyles;
+ POINT oldpos;
+ RECT wndSize;
+} FrameTitleBar;
+
+typedef struct {
+ int id;
+ HWND hWnd ;
+ RECT wndSize;
+ RECT oldWndSize;
+ LPTSTR name;
+ int align;
+ int height;
+ int dwFlags;
+ BOOLEAN Locked;
+ BOOLEAN Skinned;
+ BOOLEAN visible;
+ BOOLEAN needhide;
+ BOOLEAN collapsed;
+ int prevvisframe;
+ int HeightWhenCollapsed;
+ FrameTitleBar TitleBar;
+ FrameMenuHandles MenuHandles;
+ int oldstyles;
+ BOOLEAN floating;
+ HWND ContainerWnd;
+ POINT FloatingPos;
+ POINT FloatingSize;
+ BOOLEAN minmaxenabled;
+ BOOLEAN UseBorder;
+ int order;
+ DockOpt dockOpt;
+ HWND OwnerWindow;
+ WNDPROC wndProc;
+} wndFrame;
+
diff --git a/plugins/Clist_nicer/SRC/CLUIFrames/framesmenu.cpp b/plugins/Clist_nicer/SRC/CLUIFrames/framesmenu.cpp
new file mode 100644
index 0000000000..07b6ebc4e6
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/CLUIFrames/framesmenu.cpp
@@ -0,0 +1,228 @@
+#include <commonheaders.h>
+#include "cluiframes.h"
+
+//==========================Frames
+HANDLE hFrameMenuObject;
+static HANDLE hPreBuildFrameMenuEvent;
+extern int InitCustomMenus(void);
+
+//contactmenu exec param(ownerdata)
+//also used in checkservice
+typedef struct{
+ char *szServiceName;
+ int Frameid;
+ INT_PTR param1;
+}FrameMenuExecParam,*lpFrameMenuExecParam;
+
+void FreeAndNil( void **p )
+{
+ if (p!=NULL)
+ {
+ if (*p!=NULL)
+ {
+ if (!IsBadCodePtr((FARPROC)*p))
+ {
+ mir_free(*p);
+ }
+ *p=NULL;
+ }
+ }
+}
+
+INT_PTR FreeOwnerDataFrameMenu (WPARAM wParam,LPARAM lParam)
+{
+
+ lpFrameMenuExecParam cmep;
+
+ cmep=(lpFrameMenuExecParam)lParam;
+ if (cmep!=NULL){
+ FreeAndNil((void **)&cmep->szServiceName);
+ FreeAndNil((void **)&cmep);
+ }
+ return(0);
+}
+
+static INT_PTR AddContextFrameMenuItem(WPARAM wParam,LPARAM lParam)
+{
+ TMO_MenuItem tmi;
+ CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam;
+ if ( !pcli->pfnConvertMenu(mi, &tmi))
+ return NULL;
+
+ tmi.root = (mi->flags & CMIF_ROOTHANDLE) ? mi->hParentMenu : NULL;
+
+ lpFrameMenuExecParam fmep = (lpFrameMenuExecParam)mir_alloc(sizeof(FrameMenuExecParam));
+ if (fmep == NULL)
+ return 0;
+
+ fmep->szServiceName = mir_strdup(mi->pszService);
+ fmep->Frameid = mi->popupPosition;
+ fmep->param1 = (INT_PTR)mi->pszContactOwner;
+ tmi.ownerdata = fmep;
+
+ return CallService(MO_ADDNEWMENUITEM,(WPARAM)hFrameMenuObject,(LPARAM)&tmi);
+}
+
+static INT_PTR RemoveContextFrameMenuItem(WPARAM wParam,LPARAM lParam)
+{
+ /* this do by free service
+ lpFrameMenuExecParam fmep;
+ fmep=(lpFrameMenuExecParam)CallService(MO_MENUITEMGETOWNERDATA,wParam,lParam);
+ if (fmep!=NULL){
+ if (fmep->szServiceName!=NULL){
+ mir_free(fmep->szServiceName);
+ fmep->szServiceName=NULL;
+ };
+ mir_free(fmep);
+ }
+ */
+ CallService(MO_REMOVEMENUITEM,wParam,0);
+ return 0;
+}
+
+//called with:
+//wparam - ownerdata
+//lparam - lparam from winproc
+INT_PTR FrameMenuExecService(WPARAM wParam,LPARAM lParam) {
+ lpFrameMenuExecParam fmep=(lpFrameMenuExecParam)wParam;
+ if (fmep==NULL)
+ return(-1);
+
+ CallService(fmep->szServiceName,lParam,fmep->param1);
+ RedrawWindow(pcli->hwndContactList,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_FRAME|RDW_UPDATENOW|RDW_ALLCHILDREN);
+ return(0);
+}
+
+//true - ok,false ignore
+INT_PTR FrameMenuCheckService(WPARAM wParam,LPARAM lParam) {
+
+ PCheckProcParam pcpp=(PCheckProcParam)wParam;
+ lpFrameMenuExecParam fmep;
+ TMO_MenuItem mi;
+
+ if (pcpp==NULL){return(FALSE);};
+ if (CallService(MO_GETMENUITEM,(WPARAM)pcpp->MenuItemHandle,(LPARAM)&mi)==0)
+ {
+ fmep = reinterpret_cast<lpFrameMenuExecParam>(mi.ownerdata);
+ if (fmep!=NULL)
+ {
+ //pcpp->wParam - frameid
+ if (((WPARAM)fmep->Frameid==pcpp->wParam)||fmep->Frameid==-1) return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+static INT_PTR ContextFrameMenuNotify(WPARAM wParam,LPARAM lParam)
+{
+ NotifyEventHooks(hPreBuildFrameMenuEvent,wParam,lParam);
+ return(0);
+}
+
+static INT_PTR BuildContextFrameMenu(WPARAM wParam,LPARAM lParam)
+{
+ CLISTMENUITEM *mi=(CLISTMENUITEM*)lParam;
+ HMENU hMenu;
+ ListParam param = { 0 };
+ param.MenuObjectHandle=hFrameMenuObject;
+ param.wParam=wParam;
+ param.lParam=lParam;
+
+ hMenu=CreatePopupMenu();
+ //NotifyEventHooks(hPreBuildFrameMenuEvent,wParam,-1);
+ ContextFrameMenuNotify(wParam,-1);
+ CallService(MO_BUILDMENU,(WPARAM)hMenu,(LPARAM)&param);
+ return (INT_PTR)hMenu;
+}
+
+//==========================Frames end
+boolean InternalGenMenuModule=FALSE;
+
+INT_PTR MeasureItemProxy(WPARAM wParam,LPARAM lParam)
+{
+ int val;
+ if (InternalGenMenuModule)
+ {
+ val=CallService(MS_INT_MENUMEASUREITEM,wParam,lParam);
+ if (val) return(val);
+ }
+
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+}
+
+INT_PTR DrawItemProxy(WPARAM wParam,LPARAM lParam)
+{
+ if (InternalGenMenuModule)
+ {
+ int val;
+ val=CallService(MS_INT_MENUDRAWITEM,wParam,lParam);
+ if (val) return(val);
+ }
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+}
+
+int ProcessCommandProxy(WPARAM wParam,LPARAM lParam)
+{
+ if (InternalGenMenuModule) {
+ int val;
+ val=CallService(MS_INT_MENUPROCESSCOMMAND,wParam,lParam);
+ if (val)
+ return(val);
+ }
+ return CallService(MS_CLIST_MENUPROCESSCOMMAND,wParam,lParam);
+}
+
+INT_PTR ModifyMenuItemProxy(WPARAM wParam,LPARAM lParam)
+{
+ if (InternalGenMenuModule)
+ {
+ int val;
+ val=CallService(MS_INT_MODIFYMENUITEM,wParam,lParam);
+ if (val) return(val);
+ }
+
+ return CallService(MS_CLIST_MODIFYMENUITEM,wParam,lParam);
+}
+
+int InitFramesMenus(void)
+{
+ TMenuParam tmp;
+
+ if (!ServiceExists(MO_REMOVEMENUOBJECT))
+ InternalGenMenuModule=TRUE;
+
+ if (ServiceExists(MO_REMOVEMENUOBJECT))
+ {
+ CreateServiceFunction("FrameMenuExecService",FrameMenuExecService);
+ CreateServiceFunction("FrameMenuCheckService",FrameMenuCheckService);
+ CreateServiceFunction("FrameMenuFreeService",FreeOwnerDataFrameMenu);
+
+
+ CreateServiceFunction(MS_CLIST_REMOVECONTEXTFRAMEMENUITEM,RemoveContextFrameMenuItem);
+ CreateServiceFunction("CList/AddContextFrameMenuItem",AddContextFrameMenuItem);
+ CreateServiceFunction(MS_CLIST_MENUBUILDFRAMECONTEXT,BuildContextFrameMenu);
+ CreateServiceFunction(MS_CLIST_FRAMEMENUNOTIFY,ContextFrameMenuNotify);
+ hPreBuildFrameMenuEvent=CreateHookableEvent(ME_CLIST_PREBUILDFRAMEMENU);
+
+ //frame menu object
+ memset(&tmp,0,sizeof(tmp));
+ tmp.cbSize=sizeof(tmp);
+ tmp.CheckService="FrameMenuCheckService";
+ tmp.ExecService="FrameMenuExecService";
+ tmp.name="Frames_Menu";
+ hFrameMenuObject=(HANDLE)CallService(MO_CREATENEWMENUOBJECT,0,(LPARAM)&tmp);
+ {
+ OptParam op;
+ op.Handle=hFrameMenuObject;
+ op.Setting=OPT_MENUOBJECT_SET_FREE_SERVICE;
+ op.Value=(INT_PTR)"FrameMenuFreeService";
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+ }
+ }
+ return 0;
+}
+
+int UnitFramesMenu()
+{
+ return(0);
+}
diff --git a/plugins/Clist_nicer/SRC/CLUIFrames/groupmenu.cpp b/plugins/Clist_nicer/SRC/CLUIFrames/groupmenu.cpp
new file mode 100644
index 0000000000..a784e30883
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/CLUIFrames/groupmenu.cpp
@@ -0,0 +1,704 @@
+/*
+
+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>
+
+//////////////////////////////Group MENU/////////////////////////
+HANDLE hGroupMenuObject;
+
+HANDLE hGroupMainMenuItemProxy;
+HANDLE hHideShowMainMenuItem;
+HANDLE hGroupStatusMenuItemProxy;
+HANDLE hPreBuildGroupMenuEvent;
+HANDLE hAppearanceMenuItemProxy;
+HANDLE hEventAreaMenuItemProxy;
+
+static HMENU hMenuOldContext;
+
+HANDLE hHideOfflineUsersMenuItem;
+HANDLE hHideOfflineUsersOutHereMenuItem;
+HANDLE hHideEmptyGroupsMenuItem;
+HANDLE hDisableGroupsMenuItem;
+HANDLE hNewGroupMenuItem;
+HANDLE hNewSubGroupMenuItem;
+
+int NewGroupIconidx;
+
+extern HIMAGELIST hCListImages;
+extern HICON LoadIconFromExternalFile (char *filename,int i,boolean UseLibrary,boolean registerit,char *IconName,char *SectName,char *Description,int internalidx);
+
+void InitSubGroupMenus(void);
+
+//Groupmenu exec param(ownerdata)
+typedef struct {
+ char *szServiceName;
+ int Param1,Param2;
+}GroupMenuExecParam,*lpGroupMenuExecParam;
+
+/*
+wparam=handle to the menu item returned by MS_CLIST_ADDCONTACTMENUITEM
+return 0 on success.
+*/
+static INT_PTR RemoveGroupMenuItem(WPARAM wParam,LPARAM lParam)
+{
+ CallService(MO_REMOVEMENUITEM,wParam,0);
+ return 0;
+}
+
+
+static INT_PTR BuildGroupMenu(WPARAM wParam,LPARAM lParam)
+{
+ int tick;
+ HMENU hMenu;
+ ListParam param = { 0 };
+ param.MenuObjectHandle=hGroupMenuObject;
+
+ //hMenu=hMainMenu;
+ hMenu=CreatePopupMenu();
+ //hMenu=wParam;
+ tick=GetTickCount();
+
+ NotifyEventHooks(hPreBuildGroupMenuEvent,0,0);
+
+ CallService(MO_BUILDMENU,(WPARAM)hMenu,(LPARAM)&param);
+ //DrawMenuBar((HWND)CallService("CLUI/GetHwnd",0,0));
+ tick=GetTickCount()-tick;
+ return(INT_PTR)hMenu;
+}
+
+static INT_PTR AddGroupMenuItem(WPARAM wParam,LPARAM lParam)
+{
+ TMO_MenuItem tmi;
+ CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam;
+ if ( !pcli->pfnConvertMenu(mi, &tmi))
+ return NULL;
+
+ lpGroupMenuExecParam mmep = (lpGroupMenuExecParam)mir_alloc(sizeof(GroupMenuExecParam));
+ if (mmep == NULL)
+ return 0;
+
+ //we need just one parametr.
+ mmep->szServiceName = mir_strdup(mi->pszService);
+ mmep->Param1 = mi->popupPosition;
+ lpGroupMenuParam gmp=(lpGroupMenuParam)wParam;
+ if (gmp != NULL) {
+ mmep->Param1 = gmp->wParam;
+ mmep->Param2 = gmp->lParam;
+ }
+ tmi.ownerdata=mmep;
+
+ char buf[1024];
+ sprintf(buf,"%s/%s",mi->pszService,mi->pszName);
+
+ OptParam op;
+ op.Handle=(HANDLE)CallService(MO_ADDNEWMENUITEM,(WPARAM)hGroupMenuObject,(LPARAM)&tmi);
+ op.Setting=OPT_MENUITEMSETUNIQNAME;
+ op.Value=(INT_PTR)buf;
+ CallService(MO_SETOPTIONSMENUITEM,(WPARAM)0,(LPARAM)&op);
+ return (INT_PTR)op.Handle;
+}
+
+INT_PTR GroupMenuCheckService(WPARAM wParam,LPARAM lParam)
+{
+ return 0;
+}
+
+INT_PTR GroupMenuonAddService(WPARAM wParam,LPARAM lParam) {
+
+ MENUITEMINFO *mii=(MENUITEMINFO* )wParam;
+ if (mii==NULL) return 0;
+
+ if (hHideShowMainMenuItem==(HANDLE)lParam) {
+ mii->fMask|=MIIM_STATE;
+ mii->fState|=MFS_DEFAULT;
+
+ }
+ if (hGroupMainMenuItemProxy==(HANDLE)lParam) {
+ mii->fMask|=MIIM_SUBMENU;
+ //mi.fType=MFT_STRING;
+ mii->hSubMenu=(HMENU)CallService(MS_CLIST_MENUGETMAIN,0,0);
+ }
+
+ if (hGroupStatusMenuItemProxy==(HANDLE)lParam) {
+ mii->fMask|=MIIM_SUBMENU;
+ //mi.fType=MFT_STRING;
+ mii->hSubMenu=(HMENU)CallService(MS_CLIST_MENUGETSTATUS,0,0);
+ }
+ if (hAppearanceMenuItemProxy==(HANDLE)lParam) {
+ hMenuOldContext = GetSubMenu(LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)), 3);
+ TranslateMenu(hMenuOldContext);
+
+ CheckMenuItem(hMenuOldContext, POPUP_VISIBILITY, MF_BYCOMMAND | (cfg::dat.dwFlags & CLUI_SHOWVISI ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenuOldContext, POPUP_FRAME, MF_BYCOMMAND | (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenuOldContext, POPUP_BUTTONS, MF_BYCOMMAND | (cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenuOldContext, POPUP_SHOWMETAICONS, MF_BYCOMMAND | (cfg::dat.dwFlags & CLUI_USEMETAICONS ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenuOldContext, POPUP_SHOWSTATUSICONS, MF_BYCOMMAND | (cfg::dat.dwFlags & CLUI_FRAME_STATUSICONS ? MF_CHECKED : MF_UNCHECKED));
+
+ // floater menu items
+
+ EnableMenuItem(hMenuOldContext, POPUP_FLOATER_AUTOHIDE, MF_BYCOMMAND | (cfg::dat.bUseFloater & CLUI_USE_FLOATER ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(hMenuOldContext, POPUP_FLOATER_EVENTS, MF_BYCOMMAND | (cfg::dat.bUseFloater & CLUI_USE_FLOATER ? MF_ENABLED : MF_GRAYED));
+ CheckMenuItem(hMenuOldContext, POPUP_FLOATER, MF_BYCOMMAND | (cfg::dat.bUseFloater & CLUI_USE_FLOATER ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenuOldContext, POPUP_FLOATER_AUTOHIDE, MF_BYCOMMAND | (cfg::dat.bUseFloater & CLUI_FLOATER_AUTOHIDE ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(hMenuOldContext, POPUP_FLOATER_EVENTS, MF_BYCOMMAND | (cfg::dat.bUseFloater & CLUI_FLOATER_EVENTS ? MF_CHECKED : MF_UNCHECKED));
+
+ mii->fMask|=MIIM_SUBMENU;
+ //mi.fType=MFT_STRING;
+ mii->hSubMenu=(HMENU)hMenuOldContext;
+ }
+ return(TRUE);
+};
+
+
+//called with:
+//wparam - ownerdata
+//lparam - lparam from winproc
+INT_PTR GroupMenuExecService(WPARAM wParam,LPARAM lParam) {
+ if (wParam!=0) {
+ lpGroupMenuExecParam mmep=(lpGroupMenuExecParam)wParam;
+ if (!strcmp(mmep->szServiceName,"Help/AboutCommand")) {
+ //bug in help.c,it used wparam as parent window handle without reason.
+ mmep->Param1=0;
+ CallService(mmep->szServiceName,mmep->Param1,lParam);
+ }
+ else {
+ CallService(mmep->szServiceName,mmep->Param1,mmep->Param2);
+ }
+
+ };
+ return(1);
+};
+INT_PTR FreeOwnerDataGroupMenu (WPARAM wParam,LPARAM lParam)
+{
+
+ lpGroupMenuExecParam mmep;
+ mmep=(lpGroupMenuExecParam)lParam;
+ if (mmep!=NULL) {
+ FreeAndNil((void **)&mmep->szServiceName);
+ FreeAndNil((void **)&mmep);
+ }
+
+ return(0);
+};
+
+INT_PTR HideGroupsHelper(WPARAM wParam,LPARAM lParam)
+{
+ int newVal=!(GetWindowLongPtr((HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),GWL_STYLE)&CLS_HIDEEMPTYGROUPS);
+ cfg::writeByte("CList","HideEmptyGroups",(BYTE)newVal);
+ SendMessage((HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),CLM_SETHIDEEMPTYGROUPS,newVal,0);
+ return 0;
+}
+
+INT_PTR UseGroupsHelper(WPARAM wParam,LPARAM lParam)
+{
+ int newVal=!(GetWindowLongPtr((HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),GWL_STYLE)&CLS_USEGROUPS);
+ cfg::writeByte("CList","UseGroups",(BYTE)newVal);
+ SendMessage((HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),CLM_SETUSEGROUPS,newVal,0);
+ return 0;
+}
+
+INT_PTR HideOfflineRootHelper(WPARAM wParam,LPARAM lParam)
+{
+ SendMessage(
+ (HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),
+ CLM_SETHIDEOFFLINEROOT,
+ !SendMessage((HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),CLM_GETHIDEOFFLINEROOT,0,0),
+ 0);
+ return 0;
+};
+
+static int OnBuildGroupMenu(WPARAM wParam,LPARAM lParam)
+{
+ CLISTMENUITEM mi;
+
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | (cfg::getByte("CList","HideOffline",SETTING_HIDEOFFLINE_DEFAULT)?CMIF_CHECKED:0);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hHideOfflineUsersMenuItem, (LPARAM)&mi);
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | (SendMessage(pcli->hwndContactTree,CLM_GETHIDEOFFLINEROOT,0,0)?CMIF_CHECKED:0);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hHideOfflineUsersOutHereMenuItem, (LPARAM)&mi);
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | (GetWindowLongPtr(pcli->hwndContactTree,GWL_STYLE)&CLS_HIDEEMPTYGROUPS?CMIF_CHECKED:0);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hHideEmptyGroupsMenuItem, (LPARAM)&mi);
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | (GetWindowLongPtr(pcli->hwndContactTree,GWL_STYLE)&CLS_USEGROUPS?0:CMIF_CHECKED);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hDisableGroupsMenuItem, (LPARAM)&mi);
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hGroupMainMenuItemProxy, (LPARAM)&mi);
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hAppearanceMenuItemProxy, (LPARAM)&mi);
+
+ return 0;
+};
+
+int static OnIconLibIconChanged(WPARAM wParam,LPARAM lParam)
+{
+ HICON hicon;
+ CLISTMENUITEM clmi={0};
+
+ //hicon=LoadIconFromExternalFile("clisticons.dll",2,TRUE,FALSE,"NewGroup","Contact List","New Group",-IDI_NEWGROUP);
+ NewGroupIconidx=ImageList_ReplaceIcon(hCListImages,NewGroupIconidx,hicon);
+
+ clmi.cbSize=sizeof(clmi);
+ clmi.flags=CMIM_ICON;
+ clmi.hIcon=ImageList_GetIcon(hCListImages,NewGroupIconidx,0);
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hNewSubGroupMenuItem,(LPARAM)&clmi);
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hNewGroupMenuItem,(LPARAM)&clmi);
+ //
+
+
+ return 0;
+};
+
+void InitGroupMenus(void)
+{
+ TMenuParam tmp;
+ OptParam op;
+ //hicon=LoadIconFromExternalFile("clisticons.dll",2,TRUE,TRUE,"NewGroup","Contact List","New Group",-IDI_NEWGROUP2);
+ //NewGroupIconidx=ImageList_AddIcon(hCListImages,hicon );
+
+ CreateServiceFunction("CLISTMENUSGroup/ExecService",GroupMenuExecService);
+ CreateServiceFunction("CLISTMENUSGroup/FreeOwnerDataGroupMenu",FreeOwnerDataGroupMenu);
+ CreateServiceFunction("CLISTMENUSGroup/GroupMenuonAddService",GroupMenuonAddService);
+ CreateServiceFunction("CLISTMENUSGroup/HideGroupsHelper",HideGroupsHelper);
+ CreateServiceFunction("CLISTMENUSGroup/UseGroupsHelper",UseGroupsHelper);
+ CreateServiceFunction("CLISTMENUSGroup/HideOfflineRootHelper",HideOfflineRootHelper);
+
+ CreateServiceFunction("CList/AddGroupMenuItem",AddGroupMenuItem);
+ CreateServiceFunction(MS_CLIST_REMOVEGROUPMENUITEM,RemoveGroupMenuItem);
+ CreateServiceFunction(MS_CLIST_MENUBUILDGROUP,BuildGroupMenu);
+ hPreBuildGroupMenuEvent=CreateHookableEvent(ME_CLIST_PREBUILDGROUPMENU);
+ HookEvent(ME_CLIST_PREBUILDGROUPMENU,OnBuildGroupMenu);
+
+ InitSubGroupMenus();
+
+ //Group menu
+ memset(&tmp,0,sizeof(tmp));
+ tmp.cbSize=sizeof(tmp);
+ tmp.CheckService=NULL;
+ tmp.ExecService="CLISTMENUSGroup/ExecService";
+ tmp.name="GroupMenu";
+ hGroupMenuObject=(HANDLE)CallService(MO_CREATENEWMENUOBJECT,(WPARAM)0,(LPARAM)&tmp);
+
+
+ op.Handle=hGroupMenuObject;
+ op.Setting=OPT_USERDEFINEDITEMS;
+ op.Value=TRUE;
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+
+ op.Handle=hGroupMenuObject;
+ op.Setting=OPT_MENUOBJECT_SET_FREE_SERVICE;
+ op.Value=(INT_PTR)"CLISTMENUSGroup/FreeOwnerDataGroupMenu";
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+
+ op.Handle=hGroupMenuObject;
+ op.Setting=OPT_MENUOBJECT_SET_ONADD_SERVICE;
+ op.Value=(INT_PTR)"CLISTMENUSGroup/GroupMenuonAddService";
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+
+ {
+ //add exit command to menu
+ CLISTMENUITEM mi;
+ GroupMenuParam gmp;
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=1900000;
+ mi.pszService="CloseAction";
+ mi.pszName=LPGEN("E&xit");
+ AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=500;
+ mi.pszService=MS_CLIST_SHOWHIDE;
+ mi.pszName=LPGEN("&Hide/Show");
+ hHideShowMainMenuItem=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=200000;
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem=LoadSkinnedIconHandle(SKINICON_OTHER_FINDUSER); //LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_FINDUSER));
+ mi.pszService="FindAdd/FindAddCommand";
+ mi.pszName=LPGEN("&Find/Add Contacts...");
+ AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=300000;
+ mi.pszService="";
+ mi.pszName=LPGEN("&Main Menu");
+ hGroupMainMenuItemProxy=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=300100;
+ mi.pszService="";
+ mi.pszName=LPGEN("&Status");
+ hGroupStatusMenuItemProxy=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=390100;
+ mi.pszService="";
+ mi.pszName=LPGEN("Appearance");
+ hAppearanceMenuItemProxy=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=400000;
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem=LoadSkinnedIconHandle(SKINICON_OTHER_OPTIONS); //LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_OPTIONS));
+ mi.pszService="Options/OptionsCommand";
+ mi.pszName=LPGEN("&Options...");
+
+ AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=500000;
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem=LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA); //LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_MIRANDA));
+ mi.pszService="CLN/About";
+ mi.pszName=LPGEN("&About the contact list...");
+
+ AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=100000;
+ mi.hIcon=ImageList_GetIcon(hCListImages,NewGroupIconidx,0);
+ //mi.pszService=MS_CLIST_GROUPCREATE;
+ mi.pszService="CLISTMENUSSubGroup/GroupMenuExecProxy";
+ //mi.pszService="CLISTMENUSGroup/ExecService";
+ mi.pszName=LPGEN("&New Group");
+ gmp.lParam=0;gmp.wParam=POPUP_NEWGROUP;
+ hNewGroupMenuItem=(HANDLE)AddGroupMenuItem((WPARAM)&gmp,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=100001;
+ mi.hIcon=NULL;
+ mi.pszService=MS_CLIST_SETHIDEOFFLINE;
+ mi.pszName=LPGEN("&Hide Offline Users");
+ gmp.lParam=0;gmp.wParam=-1;
+ hHideOfflineUsersMenuItem=(HANDLE)AddGroupMenuItem((WPARAM)&gmp,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=100002;
+ mi.hIcon=NULL;
+ mi.pszService="CLISTMENUSGroup/HideOfflineRootHelper";
+ mi.pszName=LPGEN("Hide &Offline Users out here");
+ hHideOfflineUsersOutHereMenuItem=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=100003;
+ mi.hIcon=NULL;
+ mi.pszService="CLISTMENUSGroup/HideGroupsHelper";
+ mi.pszName=LPGEN("Hide &Empty Groups");
+ hHideEmptyGroupsMenuItem=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=100004;
+ mi.hIcon=NULL;
+ mi.pszService="CLISTMENUSGroup/UseGroupsHelper";
+ mi.pszName=LPGEN("Disable &Groups");
+ hDisableGroupsMenuItem=(HANDLE)AddGroupMenuItem((WPARAM)0,(LPARAM)&mi);
+
+
+ //MS_CLIST_GROUPCREATE
+
+ };
+}
+
+HANDLE hSubGroupMenuObject;
+
+HANDLE hSubGroupMainMenuItemProxy;
+//HANDLE hHideShowMainMenuItem;
+HANDLE hSubGroupStatusMenuItemProxy;
+HANDLE hPreBuildSubGroupMenuEvent;
+HANDLE hHideOfflineUsersHereMenuItem;
+
+//SubGroupmenu exec param(ownerdata)
+typedef struct {
+ char *szServiceName;
+ int Param1,Param2;
+}SubGroupMenuExecParam,*lpSubGroupMenuExecParam;
+
+/*
+wparam=handle to the menu item returned by MS_CLIST_ADDCONTACTMENUITEM
+return 0 on success.
+*/
+static INT_PTR RemoveSubGroupMenuItem(WPARAM wParam,LPARAM lParam)
+{
+ CallService(MO_REMOVEMENUITEM,wParam,0);
+ return 0;
+}
+
+static int OnBuildSubGroupMenu(WPARAM wParam,LPARAM lParam)
+{
+ ClcGroup *group=(struct ClcGroup *)wParam;
+ if (group == 0)
+ return 0;
+
+ //contact->group
+ CLISTMENUITEM mi = { 0 };
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | (group->hideOffline?CMIF_CHECKED:0);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hHideOfflineUsersHereMenuItem, (LPARAM)&mi);
+
+ return 0;
+}
+
+static INT_PTR BuildSubGroupMenu(WPARAM wParam,LPARAM lParam)
+{
+ ListParam param = { 0 };
+ param.MenuObjectHandle = hSubGroupMenuObject;
+ param.wParam = wParam;
+
+ HMENU hMenu = CreatePopupMenu();
+ int tick = GetTickCount();
+ NotifyEventHooks(hPreBuildSubGroupMenuEvent,wParam,0);
+
+ CallService(MO_BUILDMENU,(WPARAM)hMenu,(LPARAM)&param);
+ tick = GetTickCount()-tick;
+ return(INT_PTR)hMenu;
+}
+
+static INT_PTR AddSubGroupMenuItem(WPARAM wParam,LPARAM lParam)
+{
+ TMO_MenuItem tmi;
+ CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam;
+ if ( !pcli->pfnConvertMenu(mi, &tmi))
+ return NULL;
+
+ lpSubGroupMenuExecParam mmep = (lpSubGroupMenuExecParam)mir_alloc(sizeof(SubGroupMenuExecParam));
+ if (mmep == NULL)
+ return 0;
+
+ //we need just one parametr.
+ lpGroupMenuParam gmp=(lpGroupMenuParam)wParam;
+ mmep->szServiceName = mir_strdup(mi->pszService);
+ mmep->Param1 = mi->popupPosition;
+ if (gmp != NULL) {
+ mmep->Param1 = gmp->wParam;
+ mmep->Param2 = gmp->lParam;
+ }
+ tmi.ownerdata = mmep;
+
+ char buf[1024];
+ sprintf(buf,"%s/%s",mi->pszService,mi->pszName);
+
+ OptParam op;
+ op.Handle=(HANDLE)CallService(MO_ADDNEWMENUITEM,(WPARAM)hSubGroupMenuObject,(LPARAM)&tmi);
+ op.Setting=OPT_MENUITEMSETUNIQNAME;
+ op.Value=(INT_PTR)buf;
+ CallService(MO_SETOPTIONSMENUITEM,(WPARAM)0,(LPARAM)&op);
+ return (INT_PTR)op.Handle;
+}
+
+INT_PTR SubGroupMenuCheckService(WPARAM wParam,LPARAM lParam) {
+ //not used
+ return(0);
+};
+
+INT_PTR SubGroupMenuonAddService(WPARAM wParam,LPARAM lParam) {
+
+ MENUITEMINFO *mii=(MENUITEMINFO* )wParam;
+
+ if (mii==NULL) return 0;
+
+ /*
+ if (hHideShowMainMenuItem==(HANDLE)lParam)
+ {
+ mii->fMask|=MIIM_STATE;
+ mii->fState|=MFS_DEFAULT;
+
+ }
+ if (hSubGroupMainMenuItemProxy==(HANDLE)lParam)
+ {
+ mii->fMask|=MIIM_SUBMENU;
+ //mi.fType=MFT_STRING;
+ mii->hSubMenu=(HMENU)CallService(MS_CLIST_MENUGETMAIN,0,0);
+ }
+
+ if (hSubGroupStatusMenuItemProxy==(HANDLE)lParam)
+ {
+ mii->fMask|=MIIM_SUBMENU;
+ //mi.fType=MFT_STRING;
+ mii->hSubMenu=(HMENU)CallService(MS_CLIST_MENUGETSTATUS,0,0);
+ }
+ */
+ return(TRUE);
+};
+
+
+//called with:
+//wparam - ownerdata
+//lparam - lparam from winproc
+INT_PTR SubGroupMenuExecService(WPARAM wParam,LPARAM lParam) {
+ if (wParam!=0) {
+ lpSubGroupMenuExecParam mmep=(lpSubGroupMenuExecParam)wParam;
+ if (!strcmp(mmep->szServiceName,"Help/AboutCommand")) {
+ //bug in help.c,it used wparam as parent window handle without reason.
+ mmep->Param1=0;
+ CallService(mmep->szServiceName,mmep->Param1,lParam);
+ }
+ else {
+ CallService(mmep->szServiceName,mmep->Param1,mmep->Param2);
+ }
+ }
+ return(1);
+}
+
+INT_PTR FreeOwnerDataSubGroupMenu (WPARAM wParam,LPARAM lParam)
+{
+ lpSubGroupMenuExecParam mmep;
+ mmep=(lpSubGroupMenuExecParam)lParam;
+ if (mmep!=NULL) {
+ FreeAndNil((void **)&mmep->szServiceName);
+ FreeAndNil((void **)&mmep);
+ }
+
+ return(0);
+}
+
+//wparam menu handle to pass to clc.c
+INT_PTR GroupMenuExecProxy(WPARAM wParam,LPARAM lParam)
+{
+ SendMessage((HWND)CallService(MS_CLUI_GETHWNDTREE,0,0),WM_COMMAND,wParam,0);
+ return 0;
+}
+
+void InitSubGroupMenus(void)
+{
+ TMenuParam tmp;
+ OptParam op;
+
+ CreateServiceFunction("CLISTMENUSSubGroup/ExecService",SubGroupMenuExecService);
+ CreateServiceFunction("CLISTMENUSSubGroup/FreeOwnerDataSubGroupMenu",FreeOwnerDataSubGroupMenu);
+ CreateServiceFunction("CLISTMENUSSubGroup/SubGroupMenuonAddService",SubGroupMenuonAddService);
+ CreateServiceFunction("CLISTMENUSSubGroup/GroupMenuExecProxy",GroupMenuExecProxy);
+
+ //CreateServiceFunction("CLISTMENUSSubGroup/HideSubGroupsHelper",HideSubGroupsHelper);
+ //CreateServiceFunction("CLISTMENUSSubGroup/UseSubGroupsHelper",UseSubGroupsHelper);
+ //CreateServiceFunction("CLISTMENUSSubGroup/HideOfflineRootHelper",HideOfflineRootHelper);
+
+ CreateServiceFunction("CList/AddSubGroupMenuItem",AddSubGroupMenuItem);
+ CreateServiceFunction(MS_CLIST_REMOVESUBGROUPMENUITEM,RemoveSubGroupMenuItem);
+ CreateServiceFunction(MS_CLIST_MENUBUILDSUBGROUP,BuildSubGroupMenu);
+ hPreBuildSubGroupMenuEvent=CreateHookableEvent(ME_CLIST_PREBUILDSUBGROUPMENU);
+ HookEvent(ME_CLIST_PREBUILDSUBGROUPMENU,OnBuildSubGroupMenu);
+
+
+ //SubGroup menu
+ memset(&tmp,0,sizeof(tmp));
+ tmp.cbSize=sizeof(tmp);
+ tmp.CheckService=NULL;
+ tmp.ExecService="CLISTMENUSSubGroup/ExecService";
+ tmp.name="SubGroupMenu";
+ hSubGroupMenuObject=(HANDLE)CallService(MO_CREATENEWMENUOBJECT,(WPARAM)0,(LPARAM)&tmp);
+
+
+ op.Handle=hSubGroupMenuObject;
+ op.Setting=OPT_USERDEFINEDITEMS;
+ op.Value=TRUE;
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+
+ op.Handle=hSubGroupMenuObject;
+ op.Setting=OPT_MENUOBJECT_SET_FREE_SERVICE;
+ op.Value=(INT_PTR)"CLISTMENUSSubGroup/FreeOwnerDataSubGroupMenu";
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+
+ op.Handle=hSubGroupMenuObject;
+ op.Setting=OPT_MENUOBJECT_SET_ONADD_SERVICE;
+ op.Value=(INT_PTR)"CLISTMENUSSubGroup/SubGroupMenuonAddService";
+ CallService(MO_SETOPTIONSMENUOBJECT,(WPARAM)0,(LPARAM)&op);
+
+ {
+ //add exit command to menu
+ CLISTMENUITEM mi;
+ GroupMenuParam gmp;
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=1000;
+ mi.hIcon=ImageList_GetIcon(hCListImages,NewGroupIconidx,0);
+ mi.pszService="CLISTMENUSSubGroup/GroupMenuExecProxy";
+ mi.pszName=LPGEN("&New SubGroup");
+ gmp.lParam=0;gmp.wParam=POPUP_NEWSUBGROUP;
+ hNewSubGroupMenuItem=(HANDLE)AddSubGroupMenuItem((WPARAM)&gmp,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=1001;
+ mi.hIcon=NULL;
+ mi.pszService="CLISTMENUSSubGroup/GroupMenuExecProxy";
+ mi.pszName=LPGEN("&Hide Offline Users in here");
+ gmp.lParam=0;gmp.wParam=POPUP_GROUPHIDEOFFLINE;
+ hHideOfflineUsersHereMenuItem=(HANDLE)AddSubGroupMenuItem((WPARAM)&gmp,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=900001;
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem=LoadSkinnedIconHandle(SKINICON_OTHER_RENAME); //LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_RENAME));
+ mi.pszService="CLISTMENUSSubGroup/GroupMenuExecProxy";
+ mi.pszName=LPGEN("&Rename Group");
+ gmp.lParam=0;gmp.wParam=POPUP_RENAMEGROUP;
+ AddSubGroupMenuItem((WPARAM)&gmp,(LPARAM)&mi);
+
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=900002;
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem=LoadSkinnedIconHandle(SKINICON_OTHER_DELETE); //LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_DELETE));
+ mi.pszService="CLISTMENUSSubGroup/GroupMenuExecProxy";
+ mi.pszName=LPGEN("&Delete Group");
+ gmp.lParam=0;gmp.wParam=POPUP_DELETEGROUP;
+ AddSubGroupMenuItem((WPARAM)&gmp,(LPARAM)&mi);
+ }
+}
+
+//////////////////////////////END SubGroup MENU/////////////////////////
diff --git a/plugins/Clist_nicer/SRC/CLUIFrames/movetogroup.cpp b/plugins/Clist_nicer/SRC/CLUIFrames/movetogroup.cpp
new file mode 100644
index 0000000000..89bc2a42e4
--- /dev/null
+++ b/plugins/Clist_nicer/SRC/CLUIFrames/movetogroup.cpp
@@ -0,0 +1,60 @@
+#include <commonheaders.h>
+
+HANDLE hOnCntMenuBuild;
+HANDLE hPriorityItem = 0, hFloatingItem = 0;
+
+static int OnContactMenuBuild(WPARAM wParam,LPARAM lParam)
+{
+ CLISTMENUITEM mi;
+ BYTE bSetting;
+
+ // Menu Item - Floating Contact
+ bSetting = cfg::getByte("CList", "flt_enabled", 0);
+ if (bSetting && !hFloatingItem)
+ {
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=200000;
+ mi.pszPopupName=(char *)-1;
+ mi.pszService="CList/SetContactFloating";
+ mi.pszName=LPGEN("&Floating Contact");
+ if (pcli)
+ {
+ if (SendMessage(pcli->hwndContactTree, CLM_QUERYFLOATINGCONTACT, wParam, 0))
+ mi.flags=CMIF_CHECKED;
+ }
+ hFloatingItem = Menu_AddContactMenuItem(&mi);
+ }
+ else if (!bSetting && hFloatingItem)
+ {
+ CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hFloatingItem, 0);
+ hFloatingItem = 0;
+ }
+ else
+ {
+ memset(&mi,0,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.flags=CMIM_FLAGS;
+ if (pcli)
+ {
+ if (SendMessage(pcli->hwndContactTree, CLM_QUERYFLOATINGCONTACT, wParam, 0))
+ mi.flags |= CMIF_CHECKED;
+ }
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hFloatingItem, (LPARAM)&mi);
+ }
+ return 0;
+}
+
+int MTG_OnmodulesLoad(WPARAM wParam,LPARAM lParam)
+{
+ hOnCntMenuBuild=HookEvent(ME_CLIST_PREBUILDCONTACTMENU,OnContactMenuBuild);
+ return 0;
+}
+
+int UnloadMoveToGroup(void)
+{
+ if (hOnCntMenuBuild)
+ UnhookEvent(hOnCntMenuBuild);
+
+ return 0;
+}