From 214398573273e4d5744b86d1f6e16e4efa4e7dc7 Mon Sep 17 00:00:00 2001 From: Rozhuk Ivan Date: Wed, 26 Nov 2014 00:52:45 +0000 Subject: Clist_nicer code cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@11076 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Clist_nicer/src/CLUIFrames/cluiframes.cpp | 6483 +++++++++++---------- plugins/Clist_nicer/src/clui.cpp | 4230 +++++++------- 2 files changed, 5356 insertions(+), 5357 deletions(-) (limited to 'plugins/Clist_nicer/src') diff --git a/plugins/Clist_nicer/src/CLUIFrames/cluiframes.cpp b/plugins/Clist_nicer/src/CLUIFrames/cluiframes.cpp index 53f13990c4..b75315df51 100644 --- a/plugins/Clist_nicer/src/CLUIFrames/cluiframes.cpp +++ b/plugins/Clist_nicer/src/CLUIFrames/cluiframes.cpp @@ -1,3241 +1,3242 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-03 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 -#include "cluiframes.h" -HFONT __fastcall ChangeToFont(HDC hdc, struct ClcData *dat, int id, int *fontHeight); - -extern HWND g_hwndViewModeFrame, g_hwndEventArea; -extern int mf_updatethread_running; - -extern HANDLE hThreadMFUpdate; - -void MF_UpdateThread(LPVOID); - -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 - -static int UpdateTBToolTip(int framepos); -INT_PTR CLUIFrameSetFloat(WPARAM wParam, LPARAM lParam); -int CLUIFrameResizeFloatingFrame(int framepos); -extern int InitFramesMenus(void); -static int CLUIFramesReSort(); - -boolean FramesSysNotStarted = TRUE; -HPEN g_hPenCLUIFrames = 0; - -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; -} - -static FRAMEWND *Frames = NULL; - -FRAMEWND *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 HGENMENU MainMIRoot = (HGENMENU)-1; - -// others -static int ContactListHeight; -static int LastStoreTick = 0; - -static int lbypos = -1; -static int oldframeheight = -1; -static int curdragbar = -1; -static mir_cs csFrameHook; - -static BOOLEAN CLUIFramesFitInSize(void); -HWND hWndExplorerToolBar; -static int GapBetweenFrames = 1; - -static int RemoveItemFromList(int pos, FRAMEWND **lpFrames, int *FrameItemCount) -{ - memcpy(&((*lpFrames)[pos]), &((*lpFrames)[pos + 1]), sizeof(FRAMEWND) * (*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); -} - -static FRAMEWND *FindFrameByWnd(HWND hwnd) -{ - if (hwnd == NULL) - return NULL; - - BOOL bFound = FALSE; - for (int i = 0; i < nFramescount; i++) - if ((Frames[i].floating) && (Frames[i].ContainerWnd == hwnd)) - return (&Frames[i]); - - return NULL; -} - -static void DockThumbs(FRAMEWND *pThumbLeft, FRAMEWND *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(FRAMEWND *pThumb1, FRAMEWND *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(FRAMEWND *pThumb, short nX, short nY) -{ - FRAMEWND *pCurThumb = &Frames[0]; - FRAMEWND *pDockThumb = pThumb; - FRAMEWND fakeMainWindow; - FRAMEWND fakeTaskBarWindow; - RECT rc; - RECT rcThumb; - RECT rcOld; - SIZE sizeScreen; - int nOffs = 10; - POINT pt; - RECT rcLeft; - RECT rcTop; - RECT rcRight; - RECT rcBottom; - int frmidx = 0; - - if (pThumb == NULL) - return; - - sizeScreen.cx = GetSystemMetrics(SM_CXSCREEN); - sizeScreen.cy = GetSystemMetrics(SM_CYSCREEN); - - // Get thumb dimnsions - GetWindowRect(pThumb->ContainerWnd, &rcThumb); - int nWidth = rcThumb.right - rcThumb.left; - int nHeight = rcThumb.bottom - rcThumb.top; - - // Docking to the edges of the screen - int nNewX = nX < nOffs ? 0 : nX; - nNewX = nNewX > (sizeScreen.cx - nWidth - nOffs) ? (sizeScreen.cx - nWidth) : nNewX; - int nNewY = nY < nOffs ? 0 : nY; - nNewY = nNewY > (sizeScreen.cy - nHeight - nOffs) ? (sizeScreen.cy - nHeight) : nNewY; - - bool 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; - - bool bDockedLeft = false, bDockedRight = false, bDocked = false; - - // Upper-left - pt.x = rcThumb.left; - pt.y = rcThumb.top; - - 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) -{ - if (Frames[Frameid].name == NULL) return -1; - - for (int i = 0; i < maxstored; i++) { - char settingname[255]; - mir_snprintf(settingname, sizeof(settingname), "Name%d", i); - ptrT frmname(db_get_tsa(0, CLUIFrameModule, settingname)); - if (frmname == NULL) continue; - if (lstrcmpi(frmname, Frames[Frameid].name) == 0) - return i; - } - 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; - - mir_cslock lck(csFrameHook); - for (i = 0;i < nFramescount;i++) - CLUIFramesStoreFrameSettings(i); - return 0; -} - -// Get client frame -int CLUIFramesGetalClientFrame(void) -{ - int i; - if (FramesSysNotStarted) - return -1; - - 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* )) -{ - HGENMENU menuid; - int framepos = id2pos(frameid); - - if (FramesSysNotStarted) - return NULL; - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA); - mi.pszPopupName = (char *)root; - mi.popupPosition = frameid; - mi.position = popuppos++; - mi.pszName = LPGEN("&FrameTitle"); - mi.flags = CMIF_CHILDPOPUP | CMIF_GRAYED; - mi.pszContactOwner = 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 = 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 title bar"); - mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED; - mi.pszService = MS_CLIST_FRAMES_SHFRAMETITLEBAR; - mi.pszContactOwner = 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 = 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 = 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 = 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 = 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 = 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 CallService(MS_CLIST_MODIFYMENUITEM, wParam, lParam); -} - -static int CLUIFramesModifyContextMenuForFrame(WPARAM wParam, LPARAM lParam) -{ - if (FramesSysNotStarted) - return -1; - - mir_cslock lck(csFrameHook); - int pos = id2pos((INT_PTR)wParam); - if (pos >= 0 && pos < nFramescount) { - CLISTMENUITEM mi = { 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); - } - return 0; -} - -INT_PTR CLUIFramesModifyMainMenuItems(WPARAM wParam, LPARAM lParam) -{ - if (FramesSysNotStarted) - return -1; - - mir_cslock lck(csFrameHook); - int pos = id2pos((INT_PTR)wParam); - - if (pos >= 0 && pos < nFramescount) { - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIM_NAME | CMIF_CHILDPOPUP | CMIF_TCHAR; - mi.ptszName = Frames[pos].TitleBar.tbname ? Frames[pos].TitleBar.tbname : Frames[pos].name; - Menu_ModifyItem(Frames[pos].MenuHandles.MITitle, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if (Frames[pos].visible) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MIVisible, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if (Frames[pos].Locked) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MILock, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if (Frames[pos].TitleBar.ShowTitleBar) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MITBVisible, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if (Frames[pos].floating) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MIFloating, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if ((Frames[pos].UseBorder)) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MIBorder, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if ((Frames[pos].Skinned)) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MISkinned, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | ((Frames[pos].align & alClient) ? CMIF_GRAYED : 0); - if (Frames[pos].align&alTop) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MIAlignTop, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; - if (Frames[pos].align&alClient) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MIAlignClient, &mi); - - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | ((Frames[pos].align & alClient) ? CMIF_GRAYED : 0); - if (Frames[pos].align&alBottom) mi.flags |= CMIF_CHECKED; - Menu_ModifyItem(Frames[pos].MenuHandles.MIAlignBottom, &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; - Menu_ModifyItem(Frames[pos].MenuHandles.MIColl, &mi); - } - return 0; -} - -INT_PTR CLUIFramesGetFrameOptions(WPARAM wParam, LPARAM lParam) -{ - if (FramesSysNotStarted) return -1; - - mir_cslock lck(csFrameHook); - int pos = id2pos(HIWORD(wParam)); - if (pos < 0 || pos >= nFramescount) - return -1; - - switch (LOWORD(wParam)) { - case FO_NAME: - return (INT_PTR)Frames[pos].name; - - case FO_TBNAME: - return (INT_PTR)Frames[pos].TitleBar.tbname; - - case FO_TBTIPNAME: - return (INT_PTR)Frames[pos].TitleBar.tooltip; - - case FO_TBSTYLE: - return GetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE); - - case FO_TBEXSTYLE: - return GetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_EXSTYLE); - - case FO_ICON: - return (INT_PTR)Frames[pos].TitleBar.hicon; - - case FO_HEIGHT: - return (INT_PTR)Frames[pos].height; - - case FO_ALIGN: - return (INT_PTR)Frames[pos].align; - - case FO_FLOATING: - return (int)Frames[pos].floating; - - case FO_FLAGS: - INT_PTR dwFlags = 0; - if (Frames[pos].visible) dwFlags |= F_VISIBLE; - if (!Frames[pos].collapsed) dwFlags |= F_UNCOLLAPSED; - if (Frames[pos].Locked) dwFlags |= F_LOCKED; - if (Frames[pos].TitleBar.ShowTitleBar) dwFlags |= F_SHOWTB; - if (Frames[pos].TitleBar.ShowTitleBarTip) dwFlags |= F_SHOWTBTIP; - if (Frames[pos].Skinned) dwFlags |= F_SKINNED; - if (!(GetWindowLongPtr(Frames[pos].hWnd, GWL_STYLE)&WS_BORDER)) dwFlags |= F_NOBORDER; - return dwFlags; - } - - return -1; -} - -INT_PTR CLUIFramesSetFrameOptions(WPARAM wParam, LPARAM lParam) -{ - int retval; // value to be returned - - if (FramesSysNotStarted) - return -1; - - mir_cslockfull lck(csFrameHook); - int pos = id2pos(HIWORD(wParam)); - if (pos < 0 || pos >= nFramescount) - return -1; - - switch (LOWORD(wParam) & ~FO_UNICODETEXT) { - case FO_FLAGS: - { - int flag = lParam; - LONG_PTR 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 = 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_PTR)style); - SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE, (LONG_PTR)style & ~(WS_VSCROLL | WS_HSCROLL)); - lck.unlock(); - - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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 == 0) - return -1; - - mir_free(Frames[pos].name); - Frames[pos].name = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam); - return 0; - - case FO_TBNAME: - if (lParam == 0) - return -1; - - mir_free(Frames[pos].TitleBar.tbname); - Frames[pos].TitleBar.tbname = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam); - lck.unlock(); - - if (Frames[pos].floating && (Frames[pos].TitleBar.tbname != NULL)) - SetWindowText(Frames[pos].ContainerWnd, Frames[pos].TitleBar.tbname); - return 0; - - case FO_TBTIPNAME: - if (lParam == 0) - 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); - return 0; - - case FO_TBSTYLE: - SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE, lParam); - return 0; - - case FO_TBEXSTYLE: - SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_EXSTYLE, lParam); - return 0; - - case FO_ICON: - Frames[pos].TitleBar.hicon = (HICON)lParam; - return 0; - - case FO_HEIGHT: - if (lParam < 0) - return -1; - - if (Frames[pos].Skinned) { - int uID = (Frames[pos].TitleBar.ShowTitleBar ? ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE : ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE); - lParam += (arStatusItems[uID]->MARGIN_BOTTOM + arStatusItems[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,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; - } - return retval; - - case FO_FLOATING: - if (lParam < 0) - return -1; - else { - int id = Frames[pos].id; - Frames[pos].floating = !(lParam); - lck.unlock(); - - CLUIFrameSetFloat(id, 1);//lparam=1 use stored width and height - } - return wParam; - - case FO_ALIGN: - if ( !(lParam&alTop || lParam&alBottom || lParam&alClient)) - return -1; - - if ((lParam&alClient) && (CLUIFramesGetalClientFrame() >= 0)) { //only one alClient frame possible - alclientFrame = -1;//recalc it - return -1; - } - Frames[pos].align = lParam; - return 0; - } - lck.unlock(); - - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0); - return -1; -} - -static INT_PTR CLUIFramesShowAll(WPARAM wParam, LPARAM lParam) -{ - if (FramesSysNotStarted) - return -1; - - for (int i = 0;i < nFramescount;i++) - Frames[i].visible = TRUE; - - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0); - return 0; -} - -INT_PTR CLUIFramesShowAllTitleBars(WPARAM wParam, LPARAM lParam) -{ - if (FramesSysNotStarted) - return -1; - - for (int 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, 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) -{ - if (FramesSysNotStarted) - return -1; - - for (int 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, 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) -{ - if (FramesSysNotStarted) - return -1; - - int pos; - { - mir_cslock lck(csFrameHook); - 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); - } - } - - if (!Frames[pos].floating) - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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) -{ - if (FramesSysNotStarted) - return -1; - - { - mir_cslock lck(csFrameHook); - int 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); - } - } - - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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 i, tmpval; - - if (FramesSysNotStarted) - return -1; - - mir_cslockfull lck(csFrameHook); - int pos = id2pos((INT_PTR)wParam); - if (pos < 0 || pos >= nFramescount) - return 0; - - int curpos = Frames[pos].order; - int curalign = Frames[pos].align; - int 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) - 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; - } - } - } - lck.unlock(); - - CLUIFramesReSort(); - 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) -{ - if (FramesSysNotStarted) - return -1; - - mir_cslock lck(csFrameHook); - int pos = id2pos((INT_PTR)wParam); - if (pos >= 0 && (int)pos < nFramescount) { - Frames[pos].Locked = !Frames[pos].Locked; - CLUIFramesStoreFrameSettings(pos); - } - return 0; -} - -//wparam=frameid -INT_PTR CLUIFramesSetUnSetBorder(WPARAM wParam, LPARAM lParam) -{ - if (FramesSysNotStarted) - return -1; - - HWND hw; - int FrameId, oldflags; - { - mir_cslock lck(csFrameHook); - FrameId = id2pos((INT_PTR)wParam); - if (FrameId == -1) - return -1; - - 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; - } - - 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) -{ - if (FramesSysNotStarted) - return -1; - - HWND hw; - int FrameId, oldflags; - { - mir_cslock lck(csFrameHook); - FrameId = id2pos((INT_PTR)wParam); - if (FrameId == -1) - return -1; - - 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; - } - - 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) -{ - if (FramesSysNotStarted) - return -1; - - TitleBarH = cfg::dat.titleBarHeight; - - mir_cslockfull lck(csFrameHook); - int FrameId = id2pos((INT_PTR)wParam); - if (FrameId < 0 || FrameId >= nFramescount) - return -1; - - 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)) - return 0; - - if (cfg::getByte("CLUI", "AutoSize", 0)) - 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(); - lck.unlock(); - RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); - return 0; - - } - if (Frames[FrameId].Locked || (!Frames[FrameId].visible)) - 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 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; - 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); - return -1; - } - } - } - lck.unlock(); - 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; -} - -static int CLUIFramesLoadMainMenu() -{ - if (FramesSysNotStarted) - return -1; - - if (MainMIRoot != (HANDLE)-1) { - CallService(MO_REMOVEMENUITEM, (WPARAM)MainMIRoot, 0); - MainMIRoot = (HGENMENU)-1; - } - - // create root menu - CLISTMENUITEM mi = { sizeof(mi) }; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_FRAME); - mi.flags = CMIF_ROOTHANDLE; - mi.position = 3000090000; - mi.pszPopupName = (char*)-1; - mi.pszName = LPGEN("Frames"); - mi.pszService = 0; - MainMIRoot = Menu_AddMainMenuItem(&mi); - - // create frames menu - int separator = (int)3000200000; - for (int i = 0; i < nFramescount; i++) { - mi.hIcon = Frames[i].TitleBar.hicon; - mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; - mi.position = separator; - mi.hParentMenu = 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_ROOTHANDLE; - mi.position = separator++; - mi.hParentMenu = 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.hParentMenu = MainMIRoot; - mi.flags = CMIF_CHILDPOPUP; - mi.pszName = LPGEN("Show all title bars"); - 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.hParentMenu = MainMIRoot; - mi.flags = CMIF_CHILDPOPUP; - mi.pszName = LPGEN("Hide all title bars"); - mi.pszService = MS_CLIST_FRAMES_HIDEALLFRAMESTB; - Menu_AddMainMenuItem(&mi); - - return 0; -} - -static HFONT CLUILoadTitleBarFont() -{ - char facename[] = "MS Shell Dlg"; - LOGFONT logfont; - memset(&logfont, 0, sizeof(logfont)); - memcpy(logfont.lfFaceName, facename, sizeof(facename)); - logfont.lfWeight = FW_NORMAL; - logfont.lfHeight = -10; - return CreateFontIndirect(&logfont); -} - -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, 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 = (arStatusItems.getCount() != 0) ? (hasTitleBar ? arStatusItems[ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE] : arStatusItems[ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE]) : 0; - 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; - - HBITMAP hbmDraw, hbmOld; - HDC realDC = hdc = GetWindowDC(hwnd); - if (hwnd == pcli->hwndContactTree) { - realDC = CreateCompatibleDC(hdc); - hbmDraw = CreateCompatibleBitmap(hdc, rc.right, rc.bottom); - hbmOld = reinterpret_cast(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; - } - - if (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_BORDER) { - hdc = GetWindowDC(hwnd); - HPEN hPenOld = reinterpret_cast(SelectObject(hdc, g_hPenCLUIFrames)); - GetWindowRect(hwnd, &rcWindow); - rc.left = rc.top = 0; - rc.right = rcWindow.right - rcWindow.left; - rc.bottom = rcWindow.bottom - rcWindow.top; - HBRUSH brold = reinterpret_cast(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 = (arStatusItems.getCount() != 0) ? (hasTitleBar ? arStatusItems[ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE] : arStatusItems[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; - } - - 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; - - mir_cslock lck(csFrameHook); - 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(); - return 0; -} - -//wparam=(CLISTFrame*)clfrm -INT_PTR CLUIFramesAddFrame(WPARAM wParam, LPARAM lParam) -{ - int style; - char * CustomName = NULL; - CLISTFrame *clfrm = (CLISTFrame *)wParam; - - if (pcli->hwndContactList == 0) return -1; - if (FramesSysNotStarted) return -1; - if (clfrm->cbSize != sizeof(CLISTFrame)) return -1; - - mir_cslockfull lck(csFrameHook); - if (nFramescount >= MAX_FRAMES) - return -1; - - if (Frames == NULL) { - Frames = (FRAMEWND*)malloc(sizeof(FRAMEWND) * (MAX_FRAMES + 2)); - ZeroMemory(Frames, sizeof(FRAMEWND) * (MAX_FRAMES + 2)); - } - memset(&Frames[nFramescount], 0, sizeof(FRAMEWND)); - - 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 = { 0 }; - ti.cbSize = sizeof(ti); - ti.lpszText = ""; - ti.hinst = g_hInst; - ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - ti.uId = (UINT_PTR)Frames[nFramescount].TitleBar.hwnd; - SendMessageA(Frames[nFramescount].TitleBar.hwndTip, TTM_ADDTOOL, 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); - - int 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; - - lck.unlock(); - - 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) -{ - if (FramesSysNotStarted) - return -1; - - { - mir_cslock lck(csFrameHook); - int pos = id2pos((INT_PTR)wParam); - if (pos < 0 || pos > nFramescount) - return -1; - - FRAMEWND* 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); - } - - 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 FRAMEWND *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 FRAMEWND *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 FRAMEWND *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() -{ - if (pcli->hwndContactList == NULL) - return 0; - - int i, tbh, clientfrm, sumheight = 0; - RECT border; - int allbord = 0; - { - mir_cslock lck(csFrameHook); - - 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; - } - } - } - - GetBorderSize(pcli->hwndContactList, &border); - return(sumheight + border.top + border.bottom + allbord + tbh + 3); -} - -int SizeMoveNewSizes() -{ - for (int 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, 0); - return 0; - } - - if (lParam & FU_FMPOS) - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 1); - - mir_cslock lck(csFrameHook); - pos = id2pos((INT_PTR)wParam); - if (pos < 0 || pos >= nFramescount) - return -1; - - if (lParam & FU_TBREDRAW) - CLUIFramesForceUpdateTB(&Frames[pos]); - if (lParam & FU_FMREDRAW) - CLUIFramesForceUpdateFrame(&Frames[pos]); - return 0; -} - -int dock_prevent_moving = 0; - -int CLUIFramesApplyNewSizes(int mode) -{ - dock_prevent_moving = 0; - - for (int 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; - - mir_cslock lck(csFrameHook); - 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(); - } - } - return 0; -} - -int CLUIFramesOnClistResize(WPARAM wParam, LPARAM lParam) -{ - GapBetweenFrames = cfg::dat.gapBetweenFrames; - - if (FramesSysNotStarted || cfg::shutDown) - return -1; - - RECT nRect, rcStatus; - int tick; - { - mir_cslock lck(csFrameHook); - - 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); - } - - 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 (!db_get(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) -{ - StatusItems_t *item = arStatusItems[ID_EXTBKFRAMETITLE - ID_STATUS_OFFLINE]; - - /* - * no need to redraw anything while shutting down - */ - if (cfg::shutDown) - return 0; - - TitleBarH = cfg::dat.titleBarHeight; - HDC hdcMem = CreateCompatibleDC(dc); - HBITMAP hBmpOsb = CreateCompatibleBitmap(dc, rect.right, rect.bottom); - HBITMAP hoBmp = reinterpret_cast(SelectObject(hdcMem, hBmpOsb)); - - SetBkMode(hdcMem, TRANSPARENT); - - HBRUSH hBack = GetSysColorBrush(COLOR_3DFACE); - HBRUSH hoBrush = reinterpret_cast(SelectObject(hdcMem, hBack)); - { - mir_cslock lck(csFrameHook); - int 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(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); - } - } - - 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, framepos; - - 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_COMMAND: - if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), 0), Frameid)) - break; - - if (HIWORD(wParam) == 0) {//mouse events for self created menu - 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, 0); - } - break; - - case WM_RBUTTONDOWN: - { - HMENU hmenu; - if (ServiceExists(MS_CLIST_MENUBUILDFRAMECONTEXT)) - hmenu = (HMENU)CallService(MS_CLIST_MENUBUILDFRAMECONTEXT, Frameid, 0); - else { - framepos = id2pos(Frameid); - - mir_cslock lck(csFrameHook); - if (framepos == -1) - 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 title bar")); - else - AppendMenu(hmenu, MF_STRING, frame_menu_showtitlebar, TranslateT("Show title bar")); - - 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")); - } - POINT pt; - GetCursorPos(&pt); - 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: - framepos = id2pos(Frameid); - { - mir_cslock lck(csFrameHook); - if (framepos == -1) - 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); - 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; - } - } - SetCapture(hwnd); - break; - - case WM_MOUSEMOVE: - { - char TBcapt[255]; - - mir_cslock lck(csFrameHook); - int pos = id2pos(Frameid); - if (pos != -1) { - int oldflags; - mir_snprintf(TBcapt, SIZEOF(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), 0); - if (!(oldflags&F_SHOWTBTIP)) - oldflags |= F_SHOWTBTIP; - } - } - if (wParam & MK_LBUTTON) { - RECT rcMiranda; - RECT rcwnd, rcOverlap; - POINT newpt, ofspt, curpt, newpos; - - mir_cslockfull lck(csFrameHook); - - int 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; - - lck.unlock(); - 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); - - lck.lock(); - Frames[pos].TitleBar.oldpos = curpt; - 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)) { - lck.unlock(); - 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); - - lck.lock(); - 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; - return 0; - } - } - } - if (wParam & MK_LBUTTON) { - int newh = -1, prevold; - - if (GetCapture() != hwnd) - break; - - POINT pt, pt2; - mir_cslockfull lck(csFrameHook); - int pos = id2pos(Frameid); - - if (Frames[pos].floating) { - RECT wndr; - 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); - - POINT ptNew = pt; - - nLeft += (short)ptNew.x - ptOld.x; - nTop += (short)ptNew.y - ptOld.y; - - 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; - } - return 0; - } - if (Frames[pos].prevvisframe != -1) { - GetCursorPos(&pt); - - if ((Frames[pos].TitleBar.oldpos.x == pt.x) && (Frames[pos].TitleBar.oldpos.y == pt.y)) - 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) - break; - if (curdragbar != -1 && curdragbar != pos) - break; - - if (lbypos == -1) { - curdragbar = pos; - lbypos = ypos; - oldframeheight = Frames[Framemod].height; - SetCapture(hwnd); - break; - } - newh = oldframeheight + direction * (ypos - lbypos); - if (newh > 0) { - prevold = Frames[Framemod].height; - Frames[Framemod].height = newh; - if (!CLUIFramesFitInSize()) { - Frames[Framemod].height = prevold; - return TRUE; - } - Frames[Framemod].height = newh; - if (newh > 3) Frames[Framemod].collapsed = TRUE; - - } - Frames[pos].TitleBar.oldpos = pt; - } - lck.unlock(); - - if (newh > 0) - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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(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(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: - { - PAINTSTRUCT paintStruct; - HDC 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) -{ - if (!Frames[framepos].floating) - return 0; - if (Frames[framepos].ContainerWnd == 0) - return 0; - - RECT rect; - GetClientRect(Frames[framepos].ContainerWnd, &rect); - - int width = rect.right - rect.left; - int height = rect.bottom - rect.top; - int 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) -{ - int framepos; - RECT rect; - INT_PTR Frameid = GetWindowLongPtr(hwnd, GWLP_USERDATA); - - switch (msg) { - case WM_CREATE: - { - mir_cslockfull lck(csFrameHook); - framepos = id2pos(Frameid); - } - return 0; - - case WM_GETMINMAXINFO: - TitleBarH = cfg::dat.titleBarHeight; - { - mir_cslock lck(csFrameHook); - framepos = id2pos(Frameid); - if (framepos < 0 || framepos >= nFramescount) - break; - - if (!Frames[framepos].minmaxenabled) - break; - - if (Frames[framepos].ContainerWnd == 0) - 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; - } - - MINMAXINFO minmax; - memset(&minmax, 0, sizeof(minmax)); - if (SendMessage(Frames[framepos].hWnd, WM_GETMINMAXINFO, 0, (LPARAM)&minmax) != 0) - return DefWindowProc(hwnd, msg, wParam, lParam); - - 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; - } - } - - case WM_MOVE: - { - mir_cslock lck(csFrameHook); - framepos = id2pos(Frameid); - if (framepos < 0 || framepos >= nFramescount) - break; - - if (Frames[framepos].ContainerWnd == 0) - 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); - } - return 0; - - case WM_SIZE: - { - mir_cslock lck(csFrameHook); - framepos = id2pos(Frameid); - if (framepos < 0 || framepos >= nFramescount) - break; - - if (Frames[framepos].ContainerWnd == 0) - return 0; - - CLUIFrameResizeFloatingFrame(framepos); - - RECT rect; - 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); - } - 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; - { - mir_cslock lck(csFrameHook); - wParam = id2pos((INT_PTR)wParam); - if ((int)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; - } - - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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 = mir_forkthread(MF_UpdateThread, 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(g_hEventThread); - - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIVisible, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMITitle, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMITBVisible, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMILock, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIColl, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIFloating, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignRoot, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignTop, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignClient, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignBottom, 0); - CallService(MO_REMOVEMENUITEM, (LPARAM)contMIBorder, 0); - return 0; -} - -/* - * wparam=hIcon - * return hImage on success,-1 on failure - */ - -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*/ | CS_DROPSHADOW; - 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; - 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() -{ - hStatusBarShowToolTipEvent = CreateHookableEvent(ME_CLIST_FRAMES_SB_SHOW_TOOLTIP); - hStatusBarHideToolTipEvent = CreateHookableEvent(ME_CLIST_FRAMES_SB_HIDE_TOOLTIP); -} - -int UnLoadCLUIFramesModule(void) -{ - CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0); - CLUIFramesStoreAllFrames(); - DeleteObject(g_hPenCLUIFrames); - - mir_cslock lck(csFrameHook); - FramesSysNotStarted = TRUE; - for (int 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); - } - free(Frames); - Frames = NULL; - nFramescount = 0; - UnregisterClass(CLUIFrameTitleBarClassName, g_hInst); - return 0; -} +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-03 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 +#include "cluiframes.h" +HFONT __fastcall ChangeToFont(HDC hdc, struct ClcData *dat, int id, int *fontHeight); + +extern HWND g_hwndViewModeFrame, g_hwndEventArea; +extern int mf_updatethread_running; + +extern HANDLE hThreadMFUpdate; + +void MF_UpdateThread(LPVOID); + +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 + +static int UpdateTBToolTip(int framepos); +INT_PTR CLUIFrameSetFloat(WPARAM wParam, LPARAM lParam); +int CLUIFrameResizeFloatingFrame(int framepos); +extern int InitFramesMenus(void); +static int CLUIFramesReSort(); + +boolean FramesSysNotStarted = TRUE; +HPEN g_hPenCLUIFrames = 0; + +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; +} + +static FRAMEWND *Frames = NULL; + +FRAMEWND *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 HGENMENU MainMIRoot = (HGENMENU)-1; + +// others +static int ContactListHeight; +static int LastStoreTick = 0; + +static int lbypos = -1; +static int oldframeheight = -1; +static int curdragbar = -1; +static mir_cs csFrameHook; + +static BOOLEAN CLUIFramesFitInSize(void); +HWND hWndExplorerToolBar; +static int GapBetweenFrames = 1; + +static int RemoveItemFromList(int pos, FRAMEWND **lpFrames, int *FrameItemCount) +{ + memcpy(&((*lpFrames)[pos]), &((*lpFrames)[pos + 1]), sizeof(FRAMEWND) * (*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); +} + +static FRAMEWND *FindFrameByWnd(HWND hwnd) +{ + if (hwnd == NULL) + return NULL; + + BOOL bFound = FALSE; + for (int i = 0; i < nFramescount; i++) + if ((Frames[i].floating) && (Frames[i].ContainerWnd == hwnd)) + return (&Frames[i]); + + return NULL; +} + +static void DockThumbs(FRAMEWND *pThumbLeft, FRAMEWND *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(FRAMEWND *pThumb1, FRAMEWND *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(FRAMEWND *pThumb, short nX, short nY) +{ + FRAMEWND *pCurThumb = &Frames[0]; + FRAMEWND *pDockThumb = pThumb; + FRAMEWND fakeMainWindow; + FRAMEWND fakeTaskBarWindow; + RECT rc; + RECT rcThumb; + RECT rcOld; + SIZE sizeScreen; + int nOffs = 10; + POINT pt; + RECT rcLeft; + RECT rcTop; + RECT rcRight; + RECT rcBottom; + int frmidx = 0; + + if (pThumb == NULL) + return; + + sizeScreen.cx = GetSystemMetrics(SM_CXSCREEN); + sizeScreen.cy = GetSystemMetrics(SM_CYSCREEN); + + // Get thumb dimnsions + GetWindowRect(pThumb->ContainerWnd, &rcThumb); + int nWidth = rcThumb.right - rcThumb.left; + int nHeight = rcThumb.bottom - rcThumb.top; + + // Docking to the edges of the screen + int nNewX = nX < nOffs ? 0 : nX; + nNewX = nNewX > (sizeScreen.cx - nWidth - nOffs) ? (sizeScreen.cx - nWidth) : nNewX; + int nNewY = nY < nOffs ? 0 : nY; + nNewY = nNewY > (sizeScreen.cy - nHeight - nOffs) ? (sizeScreen.cy - nHeight) : nNewY; + + bool 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; + + bool bDockedLeft = false, bDockedRight = false, bDocked = false; + + // Upper-left + pt.x = rcThumb.left; + pt.y = rcThumb.top; + + 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) +{ + if (Frames[Frameid].name == NULL) return -1; + + for (int i = 0; i < maxstored; i++) { + char settingname[255]; + mir_snprintf(settingname, sizeof(settingname), "Name%d", i); + ptrT frmname(db_get_tsa(0, CLUIFrameModule, settingname)); + if (frmname == NULL) continue; + if (lstrcmpi(frmname, Frames[Frameid].name) == 0) + return i; + } + 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; + + mir_cslock lck(csFrameHook); + for (i = 0;i < nFramescount;i++) + CLUIFramesStoreFrameSettings(i); + return 0; +} + +// Get client frame +int CLUIFramesGetalClientFrame(void) +{ + int i; + if (FramesSysNotStarted) + return -1; + + 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* )) +{ + HGENMENU menuid; + int framepos = id2pos(frameid); + + if (FramesSysNotStarted) + return NULL; + + CLISTMENUITEM mi = { sizeof(mi) }; + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA); + mi.pszPopupName = (char *)root; + mi.popupPosition = frameid; + mi.position = popuppos++; + mi.pszName = LPGEN("&FrameTitle"); + mi.flags = CMIF_CHILDPOPUP | CMIF_GRAYED; + mi.pszContactOwner = 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 = 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 title bar"); + mi.flags = CMIF_CHILDPOPUP | CMIF_CHECKED; + mi.pszService = MS_CLIST_FRAMES_SHFRAMETITLEBAR; + mi.pszContactOwner = 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 = 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 = 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 = 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 = 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 = 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 CallService(MS_CLIST_MODIFYMENUITEM, wParam, lParam); +} + +static int CLUIFramesModifyContextMenuForFrame(WPARAM wParam, LPARAM lParam) +{ + if (FramesSysNotStarted) + return -1; + + mir_cslock lck(csFrameHook); + int pos = id2pos((INT_PTR)wParam); + if (pos >= 0 && pos < nFramescount) { + CLISTMENUITEM mi = { 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); + } + return 0; +} + +INT_PTR CLUIFramesModifyMainMenuItems(WPARAM wParam, LPARAM lParam) +{ + if (FramesSysNotStarted) + return -1; + + mir_cslock lck(csFrameHook); + int pos = id2pos((INT_PTR)wParam); + + if (pos >= 0 && pos < nFramescount) { + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_NAME | CMIF_CHILDPOPUP | CMIF_TCHAR; + mi.ptszName = Frames[pos].TitleBar.tbname ? Frames[pos].TitleBar.tbname : Frames[pos].name; + Menu_ModifyItem(Frames[pos].MenuHandles.MITitle, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if (Frames[pos].visible) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MIVisible, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if (Frames[pos].Locked) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MILock, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if (Frames[pos].TitleBar.ShowTitleBar) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MITBVisible, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if (Frames[pos].floating) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MIFloating, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if ((Frames[pos].UseBorder)) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MIBorder, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if ((Frames[pos].Skinned)) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MISkinned, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | ((Frames[pos].align & alClient) ? CMIF_GRAYED : 0); + if (Frames[pos].align&alTop) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MIAlignTop, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP; + if (Frames[pos].align&alClient) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MIAlignClient, &mi); + + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | ((Frames[pos].align & alClient) ? CMIF_GRAYED : 0); + if (Frames[pos].align&alBottom) mi.flags |= CMIF_CHECKED; + Menu_ModifyItem(Frames[pos].MenuHandles.MIAlignBottom, &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; + Menu_ModifyItem(Frames[pos].MenuHandles.MIColl, &mi); + } + return 0; +} + +INT_PTR CLUIFramesGetFrameOptions(WPARAM wParam, LPARAM lParam) +{ + if (FramesSysNotStarted) return -1; + + mir_cslock lck(csFrameHook); + int pos = id2pos(HIWORD(wParam)); + if (pos < 0 || pos >= nFramescount) + return -1; + + switch (LOWORD(wParam)) { + case FO_NAME: + return (INT_PTR)Frames[pos].name; + + case FO_TBNAME: + return (INT_PTR)Frames[pos].TitleBar.tbname; + + case FO_TBTIPNAME: + return (INT_PTR)Frames[pos].TitleBar.tooltip; + + case FO_TBSTYLE: + return GetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE); + + case FO_TBEXSTYLE: + return GetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_EXSTYLE); + + case FO_ICON: + return (INT_PTR)Frames[pos].TitleBar.hicon; + + case FO_HEIGHT: + return (INT_PTR)Frames[pos].height; + + case FO_ALIGN: + return (INT_PTR)Frames[pos].align; + + case FO_FLOATING: + return (int)Frames[pos].floating; + + case FO_FLAGS: + INT_PTR dwFlags = 0; + if (Frames[pos].visible) dwFlags |= F_VISIBLE; + if (!Frames[pos].collapsed) dwFlags |= F_UNCOLLAPSED; + if (Frames[pos].Locked) dwFlags |= F_LOCKED; + if (Frames[pos].TitleBar.ShowTitleBar) dwFlags |= F_SHOWTB; + if (Frames[pos].TitleBar.ShowTitleBarTip) dwFlags |= F_SHOWTBTIP; + if (Frames[pos].Skinned) dwFlags |= F_SKINNED; + if (!(GetWindowLongPtr(Frames[pos].hWnd, GWL_STYLE)&WS_BORDER)) dwFlags |= F_NOBORDER; + return dwFlags; + } + + return -1; +} + +INT_PTR CLUIFramesSetFrameOptions(WPARAM wParam, LPARAM lParam) +{ + int retval; // value to be returned + + if (FramesSysNotStarted) + return -1; + + mir_cslockfull lck(csFrameHook); + int pos = id2pos(HIWORD(wParam)); + if (pos < 0 || pos >= nFramescount) + return -1; + + switch (LOWORD(wParam) & ~FO_UNICODETEXT) { + case FO_FLAGS: + { + int flag = lParam; + LONG_PTR 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 = 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_PTR)style); + SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE, (LONG_PTR)style & ~(WS_VSCROLL | WS_HSCROLL)); + lck.unlock(); + + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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 == 0) + return -1; + + mir_free(Frames[pos].name); + Frames[pos].name = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam); + return 0; + + case FO_TBNAME: + if (lParam == 0) + return -1; + + mir_free(Frames[pos].TitleBar.tbname); + Frames[pos].TitleBar.tbname = (wParam & FO_UNICODETEXT) ? mir_u2t((LPWSTR)lParam) : mir_a2t((LPSTR)lParam); + lck.unlock(); + + if (Frames[pos].floating && (Frames[pos].TitleBar.tbname != NULL)) + SetWindowText(Frames[pos].ContainerWnd, Frames[pos].TitleBar.tbname); + return 0; + + case FO_TBTIPNAME: + if (lParam == 0) + 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); + return 0; + + case FO_TBSTYLE: + SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_STYLE, lParam); + return 0; + + case FO_TBEXSTYLE: + SetWindowLongPtr(Frames[pos].TitleBar.hwnd, GWL_EXSTYLE, lParam); + return 0; + + case FO_ICON: + Frames[pos].TitleBar.hicon = (HICON)lParam; + return 0; + + case FO_HEIGHT: + if (lParam < 0) + return -1; + + if (Frames[pos].Skinned) { + int uID = (Frames[pos].TitleBar.ShowTitleBar ? ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE : ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE); + lParam += (arStatusItems[uID]->MARGIN_BOTTOM + arStatusItems[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,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; + } + return retval; + + case FO_FLOATING: + if (lParam < 0) + return -1; + else { + int id = Frames[pos].id; + Frames[pos].floating = !(lParam); + lck.unlock(); + + CLUIFrameSetFloat(id, 1);//lparam=1 use stored width and height + } + return wParam; + + case FO_ALIGN: + if ( !(lParam&alTop || lParam&alBottom || lParam&alClient)) + return -1; + + if ((lParam&alClient) && (CLUIFramesGetalClientFrame() >= 0)) { //only one alClient frame possible + alclientFrame = -1;//recalc it + return -1; + } + Frames[pos].align = lParam; + return 0; + } + lck.unlock(); + + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0); + return -1; +} + +static INT_PTR CLUIFramesShowAll(WPARAM wParam, LPARAM lParam) +{ + if (FramesSysNotStarted) + return -1; + + for (int i = 0;i < nFramescount;i++) + Frames[i].visible = TRUE; + + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0); + return 0; +} + +INT_PTR CLUIFramesShowAllTitleBars(WPARAM wParam, LPARAM lParam) +{ + if (FramesSysNotStarted) + return -1; + + for (int 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, 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) +{ + if (FramesSysNotStarted) + return -1; + + for (int 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, 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) +{ + if (FramesSysNotStarted) + return -1; + + int pos; + { + mir_cslock lck(csFrameHook); + 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); + } + } + + if (!Frames[pos].floating) + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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) +{ + if (FramesSysNotStarted) + return -1; + + { + mir_cslock lck(csFrameHook); + int 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); + } + } + + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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 i, tmpval; + + if (FramesSysNotStarted) + return -1; + + mir_cslockfull lck(csFrameHook); + int pos = id2pos((INT_PTR)wParam); + if (pos < 0 || pos >= nFramescount) + return 0; + + int curpos = Frames[pos].order; + int curalign = Frames[pos].align; + int 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) + 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; + } + } + } + lck.unlock(); + + CLUIFramesReSort(); + 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) +{ + if (FramesSysNotStarted) + return -1; + + mir_cslock lck(csFrameHook); + int pos = id2pos((INT_PTR)wParam); + if (pos >= 0 && (int)pos < nFramescount) { + Frames[pos].Locked = !Frames[pos].Locked; + CLUIFramesStoreFrameSettings(pos); + } + return 0; +} + +//wparam=frameid +INT_PTR CLUIFramesSetUnSetBorder(WPARAM wParam, LPARAM lParam) +{ + if (FramesSysNotStarted) + return -1; + + HWND hw; + int FrameId, oldflags; + { + mir_cslock lck(csFrameHook); + FrameId = id2pos((INT_PTR)wParam); + if (FrameId == -1) + return -1; + + 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; + } + + 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) +{ + if (FramesSysNotStarted) + return -1; + + HWND hw; + int FrameId, oldflags; + { + mir_cslock lck(csFrameHook); + FrameId = id2pos((INT_PTR)wParam); + if (FrameId == -1) + return -1; + + 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; + } + + 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) +{ + if (FramesSysNotStarted) + return -1; + + TitleBarH = cfg::dat.titleBarHeight; + + mir_cslockfull lck(csFrameHook); + int FrameId = id2pos((INT_PTR)wParam); + if (FrameId < 0 || FrameId >= nFramescount) + return -1; + + 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)) + return 0; + + if (cfg::getByte("CLUI", "AutoSize", 0)) + 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(); + lck.unlock(); + RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); + return 0; + + } + if (Frames[FrameId].Locked || (!Frames[FrameId].visible)) + 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 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; + 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); + return -1; + } + } + } + lck.unlock(); + 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; +} + +static int CLUIFramesLoadMainMenu() +{ + if (FramesSysNotStarted) + return -1; + + if (MainMIRoot != (HANDLE)-1) { + CallService(MO_REMOVEMENUITEM, (WPARAM)MainMIRoot, 0); + MainMIRoot = (HGENMENU)-1; + } + + // create root menu + CLISTMENUITEM mi = { sizeof(mi) }; + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_FRAME); + mi.flags = CMIF_ROOTHANDLE; + mi.position = 3000090000; + mi.pszPopupName = (char*)-1; + mi.pszName = LPGEN("Frames"); + mi.pszService = 0; + MainMIRoot = Menu_AddMainMenuItem(&mi); + + // create frames menu + int separator = (int)3000200000; + for (int i = 0; i < nFramescount; i++) { + mi.hIcon = Frames[i].TitleBar.hicon; + mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; + mi.position = separator; + mi.hParentMenu = 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_ROOTHANDLE; + mi.position = separator++; + mi.hParentMenu = 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.hParentMenu = MainMIRoot; + mi.flags = CMIF_CHILDPOPUP; + mi.pszName = LPGEN("Show all title bars"); + 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.hParentMenu = MainMIRoot; + mi.flags = CMIF_CHILDPOPUP; + mi.pszName = LPGEN("Hide all title bars"); + mi.pszService = MS_CLIST_FRAMES_HIDEALLFRAMESTB; + Menu_AddMainMenuItem(&mi); + + return 0; +} + +static HFONT CLUILoadTitleBarFont() +{ + char facename[] = "MS Shell Dlg"; + LOGFONT logfont; + memset(&logfont, 0, sizeof(logfont)); + memcpy(logfont.lfFaceName, facename, sizeof(facename)); + logfont.lfWeight = FW_NORMAL; + logfont.lfHeight = -10; + return CreateFontIndirect(&logfont); +} + +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, 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 = 0; + + if (pcli == NULL) + return 0; + if (hwndParent != pcli->hwndContactList || !cfg::dat.bSkinnedScrollbar) + result = CallWindowProc(oldWndProc, hwnd, WM_NCPAINT, wParam, lParam); + if (!pcli->hwndContactList || hwndParent != pcli->hwndContactList) + return result; + + if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SKINNEDFRAME) { + StatusItems_t *item = (arStatusItems.getCount() != 0) ? (hasTitleBar ? arStatusItems[ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE] : arStatusItems[ID_EXTBKOWNEDFRAMEBORDER - ID_STATUS_OFFLINE]) : 0; + 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; + + HBITMAP hbmDraw, hbmOld; + HDC realDC = hdc = GetWindowDC(hwnd); + if (hwnd == pcli->hwndContactTree) { + realDC = CreateCompatibleDC(hdc); + hbmDraw = CreateCompatibleBitmap(hdc, rc.right, rc.bottom); + hbmOld = reinterpret_cast(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; + } + + if (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_BORDER) { + hdc = GetWindowDC(hwnd); + HPEN hPenOld = reinterpret_cast(SelectObject(hdc, g_hPenCLUIFrames)); + GetWindowRect(hwnd, &rcWindow); + rc.left = rc.top = 0; + rc.right = rcWindow.right - rcWindow.left; + rc.bottom = rcWindow.bottom - rcWindow.top; + HBRUSH brold = reinterpret_cast(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 = (arStatusItems.getCount() != 0) ? (hasTitleBar ? arStatusItems[ID_EXTBKOWNEDFRAMEBORDERTB - ID_STATUS_OFFLINE] : arStatusItems[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 == NULL) + 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; + } + + 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; + + mir_cslock lck(csFrameHook); + 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(); + return 0; +} + +//wparam=(CLISTFrame*)clfrm +INT_PTR CLUIFramesAddFrame(WPARAM wParam, LPARAM lParam) +{ + int style; + char * CustomName = NULL; + CLISTFrame *clfrm = (CLISTFrame *)wParam; + + if (pcli->hwndContactList == 0) return -1; + if (FramesSysNotStarted) return -1; + if (clfrm->cbSize != sizeof(CLISTFrame)) return -1; + + mir_cslockfull lck(csFrameHook); + if (nFramescount >= MAX_FRAMES) + return -1; + + if (Frames == NULL) { + Frames = (FRAMEWND*)malloc(sizeof(FRAMEWND) * (MAX_FRAMES + 2)); + ZeroMemory(Frames, sizeof(FRAMEWND) * (MAX_FRAMES + 2)); + } + memset(&Frames[nFramescount], 0, sizeof(FRAMEWND)); + + 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 = { 0 }; + ti.cbSize = sizeof(ti); + ti.lpszText = ""; + ti.hinst = g_hInst; + ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + ti.uId = (UINT_PTR)Frames[nFramescount].TitleBar.hwnd; + SendMessageA(Frames[nFramescount].TitleBar.hwndTip, TTM_ADDTOOL, 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); + + int 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; + + lck.unlock(); + + 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) +{ + if (FramesSysNotStarted) + return -1; + + { + mir_cslock lck(csFrameHook); + int pos = id2pos((INT_PTR)wParam); + if (pos < 0 || pos > nFramescount) + return -1; + + FRAMEWND* 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); + } + + 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 FRAMEWND *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 FRAMEWND *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 FRAMEWND *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() +{ + if (pcli->hwndContactList == NULL) + return 0; + + int i, tbh, clientfrm, sumheight = 0; + RECT border; + int allbord = 0; + { + mir_cslock lck(csFrameHook); + + 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; + } + } + } + + GetBorderSize(pcli->hwndContactList, &border); + return(sumheight + border.top + border.bottom + allbord + tbh + 3); +} + +int SizeMoveNewSizes() +{ + for (int 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, 0); + return 0; + } + + if (lParam & FU_FMPOS) + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 1); + + mir_cslock lck(csFrameHook); + pos = id2pos((INT_PTR)wParam); + if (pos < 0 || pos >= nFramescount) + return -1; + + if (lParam & FU_TBREDRAW) + CLUIFramesForceUpdateTB(&Frames[pos]); + if (lParam & FU_FMREDRAW) + CLUIFramesForceUpdateFrame(&Frames[pos]); + return 0; +} + +int dock_prevent_moving = 0; + +int CLUIFramesApplyNewSizes(int mode) +{ + dock_prevent_moving = 0; + + for (int 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; + + mir_cslock lck(csFrameHook); + 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(); + } + } + return 0; +} + +int CLUIFramesOnClistResize(WPARAM wParam, LPARAM lParam) +{ + GapBetweenFrames = cfg::dat.gapBetweenFrames; + + if (FramesSysNotStarted || cfg::shutDown) + return -1; + + RECT nRect, rcStatus; + int tick; + { + mir_cslock lck(csFrameHook); + + 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); + } + + 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 (!db_get(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) +{ + StatusItems_t *item = arStatusItems[ID_EXTBKFRAMETITLE - ID_STATUS_OFFLINE]; + + /* + * no need to redraw anything while shutting down + */ + if (cfg::shutDown) + return 0; + + TitleBarH = cfg::dat.titleBarHeight; + HDC hdcMem = CreateCompatibleDC(dc); + HBITMAP hBmpOsb = CreateCompatibleBitmap(dc, rect.right, rect.bottom); + HBITMAP hoBmp = reinterpret_cast(SelectObject(hdcMem, hBmpOsb)); + + SetBkMode(hdcMem, TRANSPARENT); + + HBRUSH hBack = GetSysColorBrush(COLOR_3DFACE); + HBRUSH hoBrush = reinterpret_cast(SelectObject(hdcMem, hBack)); + { + mir_cslock lck(csFrameHook); + int 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(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); + } + } + + 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, framepos; + + 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_COMMAND: + if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), 0), Frameid)) + break; + + if (HIWORD(wParam) == 0) {//mouse events for self created menu + 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, 0); + } + break; + + case WM_RBUTTONDOWN: + { + HMENU hmenu; + if (ServiceExists(MS_CLIST_MENUBUILDFRAMECONTEXT)) + hmenu = (HMENU)CallService(MS_CLIST_MENUBUILDFRAMECONTEXT, Frameid, 0); + else { + framepos = id2pos(Frameid); + + mir_cslock lck(csFrameHook); + if (framepos == -1) + 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 title bar")); + else + AppendMenu(hmenu, MF_STRING, frame_menu_showtitlebar, TranslateT("Show title bar")); + + 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")); + } + POINT pt; + GetCursorPos(&pt); + 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: + framepos = id2pos(Frameid); + { + mir_cslock lck(csFrameHook); + if (framepos == -1) + 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); + 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; + } + } + SetCapture(hwnd); + break; + + case WM_MOUSEMOVE: + { + char TBcapt[255]; + + mir_cslock lck(csFrameHook); + int pos = id2pos(Frameid); + if (pos != -1) { + int oldflags; + mir_snprintf(TBcapt, SIZEOF(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), 0); + if (!(oldflags&F_SHOWTBTIP)) + oldflags |= F_SHOWTBTIP; + } + } + if (wParam & MK_LBUTTON) { + RECT rcMiranda; + RECT rcwnd, rcOverlap; + POINT newpt, ofspt, curpt, newpos; + + mir_cslockfull lck(csFrameHook); + + int 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; + + lck.unlock(); + 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); + + lck.lock(); + Frames[pos].TitleBar.oldpos = curpt; + 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)) { + lck.unlock(); + 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); + + lck.lock(); + 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; + return 0; + } + } + } + if (wParam & MK_LBUTTON) { + int newh = -1, prevold; + + if (GetCapture() != hwnd) + break; + + POINT pt, pt2; + mir_cslockfull lck(csFrameHook); + int pos = id2pos(Frameid); + + if (Frames[pos].floating) { + RECT wndr; + 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); + + POINT ptNew = pt; + + nLeft += (short)ptNew.x - ptOld.x; + nTop += (short)ptNew.y - ptOld.y; + + 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; + } + return 0; + } + if (Frames[pos].prevvisframe != -1) { + GetCursorPos(&pt); + + if ((Frames[pos].TitleBar.oldpos.x == pt.x) && (Frames[pos].TitleBar.oldpos.y == pt.y)) + 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) + break; + if (curdragbar != -1 && curdragbar != pos) + break; + + if (lbypos == -1) { + curdragbar = pos; + lbypos = ypos; + oldframeheight = Frames[Framemod].height; + SetCapture(hwnd); + break; + } + newh = oldframeheight + direction * (ypos - lbypos); + if (newh > 0) { + prevold = Frames[Framemod].height; + Frames[Framemod].height = newh; + if (!CLUIFramesFitInSize()) { + Frames[Framemod].height = prevold; + return TRUE; + } + Frames[Framemod].height = newh; + if (newh > 3) Frames[Framemod].collapsed = TRUE; + + } + Frames[pos].TitleBar.oldpos = pt; + } + lck.unlock(); + + if (newh > 0) + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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(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(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: + { + PAINTSTRUCT paintStruct; + HDC 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) +{ + if (!Frames[framepos].floating) + return 0; + if (Frames[framepos].ContainerWnd == 0) + return 0; + + RECT rect; + GetClientRect(Frames[framepos].ContainerWnd, &rect); + + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + int 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) +{ + int framepos; + RECT rect; + INT_PTR Frameid = GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch (msg) { + case WM_CREATE: + { + mir_cslockfull lck(csFrameHook); + framepos = id2pos(Frameid); + } + return 0; + + case WM_GETMINMAXINFO: + TitleBarH = cfg::dat.titleBarHeight; + { + mir_cslock lck(csFrameHook); + framepos = id2pos(Frameid); + if (framepos < 0 || framepos >= nFramescount) + break; + + if (!Frames[framepos].minmaxenabled) + break; + + if (Frames[framepos].ContainerWnd == 0) + 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; + } + + MINMAXINFO minmax; + memset(&minmax, 0, sizeof(minmax)); + if (SendMessage(Frames[framepos].hWnd, WM_GETMINMAXINFO, 0, (LPARAM)&minmax) != 0) + return DefWindowProc(hwnd, msg, wParam, lParam); + + 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; + } + } + + case WM_MOVE: + { + mir_cslock lck(csFrameHook); + framepos = id2pos(Frameid); + if (framepos < 0 || framepos >= nFramescount) + break; + + if (Frames[framepos].ContainerWnd == 0) + 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); + } + return 0; + + case WM_SIZE: + { + mir_cslock lck(csFrameHook); + framepos = id2pos(Frameid); + if (framepos < 0 || framepos >= nFramescount) + break; + + if (Frames[framepos].ContainerWnd == 0) + return 0; + + CLUIFrameResizeFloatingFrame(framepos); + + RECT rect; + 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); + } + 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; + { + mir_cslock lck(csFrameHook); + wParam = id2pos((INT_PTR)wParam); + if ((int)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; + } + + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 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 = mir_forkthread(MF_UpdateThread, 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(g_hEventThread); + + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIVisible, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMITitle, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMITBVisible, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMILock, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIColl, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIFloating, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignRoot, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignTop, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignClient, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIAlignBottom, 0); + CallService(MO_REMOVEMENUITEM, (LPARAM)contMIBorder, 0); + return 0; +} + +/* + * wparam=hIcon + * return hImage on success,-1 on failure + */ + +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*/ | CS_DROPSHADOW; + 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; + 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() +{ + hStatusBarShowToolTipEvent = CreateHookableEvent(ME_CLIST_FRAMES_SB_SHOW_TOOLTIP); + hStatusBarHideToolTipEvent = CreateHookableEvent(ME_CLIST_FRAMES_SB_HIDE_TOOLTIP); +} + +int UnLoadCLUIFramesModule(void) +{ + CLUIFramesOnClistResize((WPARAM)pcli->hwndContactList, 0); + CLUIFramesStoreAllFrames(); + DeleteObject(g_hPenCLUIFrames); + + mir_cslock lck(csFrameHook); + FramesSysNotStarted = TRUE; + for (int 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); + } + free(Frames); + Frames = NULL; + nFramescount = 0; + UnregisterClass(CLUIFrameTitleBarClassName, g_hInst); + return 0; +} diff --git a/plugins/Clist_nicer/src/clui.cpp b/plugins/Clist_nicer/src/clui.cpp index 19da78521a..50d6214b04 100644 --- a/plugins/Clist_nicer/src/clui.cpp +++ b/plugins/Clist_nicer/src/clui.cpp @@ -1,2116 +1,2114 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-03 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 -#include -#include "../cluiframes/cluiframes.h" -#include "../coolsb/coolscroll.h" - -#define TM_AUTOALPHA 1 -#define TIMERID_AUTOSIZE 100 -#define MENU_MIRANDAMENU 0xFFFF1234 - -int g_fading_active = 0; - -static RECT g_PreSizeRect, g_SizingRect; -static int g_sizingmethod; -static LONG g_CLUI_x_off, g_CLUI_y_off, g_CLUI_y1_off, g_CLUI_x1_off; -static RECT rcWPC; - -static int transparentFocus = 1; -static byte oldhideoffline; -static int disableautoupd = 1; -HANDLE hFrameContactTree; -extern HIMAGELIST hCListImages; -extern PLUGININFOEX pluginInfo; -extern RECT old_window_rect, new_window_rect; - -extern BOOL g_trayTooltipActive; -extern POINT tray_hover_pos; -extern HWND g_hwndViewModeFrame, g_hwndEventArea, g_hwndToolbarFrame; - -extern ImageItem *g_CLUIImageItem; -extern HBRUSH g_CLUISkinnedBkColor; -extern HWND g_hwndSFL; -extern ButtonItem *g_ButtonItems; -extern COLORREF g_CLUISkinnedBkColorRGB; -extern FRAMEWND *wndFrameCLC; -extern HPEN g_hPenCLUIFrames; - -static BYTE old_cliststate, show_on_first_autosize = FALSE; - -RECT cluiPos; - -TCHAR *statusNames[12]; - -extern LRESULT CALLBACK EventAreaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -extern HANDLE hNotifyFrame; - -int SortList(WPARAM wParam, LPARAM lParam); -int LoadCluiServices(void); -void InitGroupMenus(); -void FS_RegisterFonts(); -void LoadExtraIconModule(); -void RemoveFromTaskBar(HWND hWnd); -void DestroyTrayMenu(HMENU hMenu); - -extern LONG g_cxsmIcon, g_cysmIcon; - -SIZE g_oldSize = {0}; -POINT g_oldPos = {0}; -int during_sizing = 0; -extern int dock_prevent_moving; - -static HDC hdcLockedPoint = 0; -static HBITMAP hbmLockedPoint = 0, hbmOldLockedPoint = 0; - -HICON overlayicons[10]; - -static IconItem myIcons[] = { - { LPGEN("Toggle show online/offline"), "CLN_online", IDI_HIDEOFFLINE }, - { LPGEN("Toggle groups"), "CLN_groups", IDI_HIDEGROUPS }, - { LPGEN("Find contacts"), "CLN_findadd", IDI_FINDANDADD }, - { LPGEN("Open preferences"), "CLN_options", IDI_TBOPTIONS }, - { LPGEN("Toggle sounds"), "CLN_sound", IDI_SOUNDSON }, - { LPGEN("Minimize contact list"), "CLN_minimize", IDI_MINIMIZE }, - { LPGEN("Show TabSRMM session list"), "CLN_slist", IDI_TABSRMMSESSIONLIST }, - { LPGEN("Show TabSRMM menu"), "CLN_menu", IDI_TABSRMMMENU }, - { LPGEN("Sounds are off"), "CLN_soundsoff", IDI_SOUNDSOFF }, - { LPGEN("Select view mode"), "CLN_CLVM_select", IDI_CLVM_SELECT }, - { LPGEN("Reset view mode"), "CLN_CLVM_reset", IDI_DELETE }, - { LPGEN("Configure view modes"), "CLN_CLVM_options", IDI_CLVM_OPTIONS }, - { LPGEN("Show menu"), "CLN_topmenu", IDI_TBTOPMENU }, - { LPGEN("Setup accounts"), "CLN_accounts", IDI_TBACCOUNTS } -}; - -HWND hTbMenu, hTbGlobalStatus; - -static void Tweak_It(COLORREF clr) -{ - SetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED); - SetLayeredWindowAttributes(pcli->hwndContactList, clr, 0, LWA_COLORKEY); - cfg::dat.colorkey = clr; -} - -static void LayoutButtons(HWND hwnd, RECT *rc) -{ - RECT rect; - BYTE rightButton = 1, leftButton = 0; - BYTE left_offset = cfg::dat.bCLeft - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0); - BYTE right_offset = cfg::dat.bCRight - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0); - BYTE delta = left_offset + right_offset; - ButtonItem *btnItems = g_ButtonItems; - - if (rc == NULL) - GetClientRect(hwnd, &rect); - else - rect = *rc; - - rect.bottom -= cfg::dat.bCBottom; - - if (g_ButtonItems) { - while (btnItems) { - LONG x = (btnItems->xOff >= 0) ? rect.left + btnItems->xOff : rect.right - abs(btnItems->xOff); - LONG y = (btnItems->yOff >= 0) ? rect.top + btnItems->yOff : rect.bottom - cfg::dat.statusBarHeight; - - SetWindowPos(btnItems->hWnd, 0, x, y, btnItems->width, btnItems->height, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW); - btnItems = btnItems->nextItem; - } - } - - SetWindowPos(hTbMenu, 0, 2 + left_offset, rect.bottom - cfg::dat.statusBarHeight - 21 - 1, - 21 * 3, 21 + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW); - - SetWindowPos(hTbGlobalStatus, 0, left_offset + (3 * 21) + 3, rect.bottom - cfg::dat.statusBarHeight - 21 - 1, - rect.right - delta - (3 * 21 + 5), 21 + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW); - -} - -static int FS_FontsChanged(WPARAM wParam, LPARAM lParam) -{ - COLORREF clr_cluiframes = cfg::getDword("CLUI", "clr_frameborder", RGB(40, 40, 40)); - - if (g_hPenCLUIFrames) - DeleteObject(g_hPenCLUIFrames); - g_hPenCLUIFrames = CreatePen(PS_SOLID, 1, clr_cluiframes); - - pcli->pfnClcOptionsChanged(); - RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); - return 0; -} - -// create the CLC control, but not yet the frame. The frame containing the CLC should be created as the -// last frame of all. -static HWND PreCreateCLC(HWND parent) -{ - pcli->hwndContactTree = CreateWindow(_T(CLISTCONTROL_CLASS), _T(""), - WS_CHILD | CLS_CONTACTLIST - | (cfg::getByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ? CLS_USEGROUPS : 0) - | CLS_HIDEOFFLINE - //| (db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ? CLS_HIDEOFFLINE : 0) - | (cfg::getByte(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) ? CLS_HIDEEMPTYGROUPS : 0) - | CLS_MULTICOLUMN, - 0, 0, 0, 0, parent, NULL, g_hInst, (LPVOID)0xff00ff00); - - cfg::clcdat = (struct ClcData *)GetWindowLongPtr(pcli->hwndContactTree, 0); - return pcli->hwndContactTree; -} - -// create internal frames, including the last frame (actual CLC control) -static int CreateCLC(HWND parent) -{ - pcli->pfnReloadExtraIcons(); - CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)oldhideoffline, 0); - disableautoupd = 0; - - { - CLISTFrame frame = {0}; - frame.cbSize = sizeof(frame); - frame.tname = _T("EventArea"); - frame.TBtname = TranslateT("Event area"); - frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_FRAME); - frame.height = 20; - frame.Flags = F_VISIBLE | F_SHOWTBTIP | F_NOBORDER | F_TCHAR; - frame.align = alBottom; - frame.hWnd = CreateWindowExA(0, "EventAreaClass", "evt", WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, pcli->hwndContactList, (HMENU)0, g_hInst, NULL); - g_hwndEventArea = frame.hWnd; - hNotifyFrame = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&frame, 0); - CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)hNotifyFrame, FU_FMPOS); - HideShowNotifyFrame(); - CreateViewModeFrame(); - } - - { - CLISTFrame Frame = {0}; - memset(&Frame, 0, sizeof(Frame)); - Frame.cbSize = sizeof(CLISTFrame); - Frame.hWnd = pcli->hwndContactTree; - Frame.align = alClient; - Frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_FRAME); - Frame.Flags = F_VISIBLE | F_SHOWTB | F_SHOWTBTIP | F_NOBORDER | F_TCHAR; - Frame.tname = _T("My contacts"); - Frame.TBtname = TranslateT("My contacts"); - Frame.height = 200; - hFrameContactTree = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0); - //free(Frame.name); - CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_TBTIPNAME, hFrameContactTree), (LPARAM)Translate("My contacts")); - - // ugly, but working hack. Prevent that annoying little scroll bar from appearing in the "My Contacts" title bar - DWORD flags = (DWORD)CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hFrameContactTree), 0); - flags |= F_VISIBLE; - CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hFrameContactTree), flags); - } - - SetButtonToSkinned(); - return 0; -} - -static int CluiModulesLoaded(WPARAM, LPARAM) -{ - FS_RegisterFonts(); - HookEvent(ME_FONT_RELOAD, FS_FontsChanged); - return 0; -} - -static HICON hIconSaved = 0; - -void ClearIcons(int mode) -{ - for (int i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) { - if (overlayicons[i - IDI_OVL_OFFLINE] != 0) { - if (mode) - DestroyIcon(overlayicons[i - IDI_OVL_OFFLINE]); - overlayicons[i - IDI_OVL_OFFLINE] = 0; - } - } -} - -static void CacheClientIcons() -{ - ClearIcons(0); - - for (int i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) { - char szBuffer[128]; - mir_snprintf(szBuffer, sizeof(szBuffer), "cln_ovl_%d", ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE)); - overlayicons[i - IDI_OVL_OFFLINE] = Skin_GetIcon(szBuffer); - } -} - -static void InitIcoLib() -{ - Icon_Register(g_hInst, LPGEN("Contact list")"/"LPGEN("Default"), myIcons, SIZEOF(myIcons)); - - for (int i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) { - char szBuffer[128]; - mir_snprintf(szBuffer, sizeof(szBuffer), "cln_ovl_%d", ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE)); - IconItemT icon = { pcli->pfnGetStatusModeDescription(ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE), GSMDF_TCHAR), szBuffer, i }; - Icon_RegisterT(g_hInst, LPGENT("Contact list")_T("/")LPGENT("Overlay icons"), &icon, 1); - } - - PROTOACCOUNT **accs = NULL; - int p_count = 0; - ProtoEnumAccounts(&p_count, &accs); - for (int k = 0; k < p_count; k++) { - if (!IsAccountEnabled(accs[k]) || CallProtoService(accs[k]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) == 0) - continue; - - TCHAR szDescr[128]; - mir_sntprintf(szDescr, SIZEOF(szDescr), TranslateT("%s connecting"), accs[k]->tszAccountName); - IconItemT icon = { szDescr, "conn", IDI_PROTOCONNECTING }; - Icon_RegisterT(g_hInst, LPGENT("Contact list")_T("/")LPGENT("Connecting icons"), &icon, 1, accs[k]->szModuleName); - } -} - -static int IcoLibChanged(WPARAM, LPARAM) -{ - IcoLibReloadIcons(); - return 0; -} - -void CreateButtonBar(HWND hWnd) -{ - hTbMenu = CreateWindowEx(0, MIRANDABUTTONCLASS, _T(""), BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, hWnd, (HMENU)IDC_TBMENU, g_hInst, NULL); - CustomizeButton(hTbMenu, false, false, false); - SetWindowText(hTbMenu, TranslateT("Menu")); - SendMessage(hTbMenu, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MAINMENU)); - SendMessage(hTbMenu, BUTTONSETSENDONDOWN, TRUE, 0); - SendMessage(hTbMenu, BUTTONADDTOOLTIP, (WPARAM)LPGEN("Open main menu"), 0); - - hTbGlobalStatus = CreateWindowEx(0, MIRANDABUTTONCLASS, _T(""), BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, hWnd, (HMENU)IDC_TBGLOBALSTATUS, g_hInst, NULL); - CustomizeButton(hTbGlobalStatus, false, false, false); - SetWindowText(hTbGlobalStatus, TranslateT("Offline")); - SendMessage(hTbGlobalStatus, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_STATUS_OFFLINE)); - SendMessage(hTbGlobalStatus, BUTTONSETSENDONDOWN, TRUE, 0); - SendMessage(hTbGlobalStatus, BUTTONADDTOOLTIP, (WPARAM)LPGEN("Set status modes"), 0); -} - -// if mode != 0 we do first time init, otherwise only reload the extra icon stuff -void CLN_LoadAllIcons(BOOL mode) -{ - if (mode) { - InitIcoLib(); - HookEvent(ME_SKIN2_ICONSCHANGED, IcoLibChanged); - } - CacheClientIcons(); -} - -void ConfigureEventArea(HWND hwnd) -{ - int iCount = GetMenuItemCount(cfg::dat.hMenuNotify); - DWORD dwFlags = cfg::dat.dwFlags; - int oldstate = cfg::dat.notifyActive; - int dwVisible = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hNotifyFrame), 0) & F_VISIBLE; - - if (dwVisible) { - if (dwFlags & CLUI_FRAME_AUTOHIDENOTIFY) - cfg::dat.notifyActive = iCount > 0 ? 1 : 0; - else - cfg::dat.notifyActive = 1; - } - else - cfg::dat.notifyActive = 0; - - if (oldstate != cfg::dat.notifyActive) - HideShowNotifyFrame(); -} - -void ConfigureFrame() -{ - int show = cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? SW_SHOW : SW_HIDE; - ShowWindow(hTbMenu,show); - ShowWindow(hTbGlobalStatus, show); -} - -void IcoLibReloadIcons() -{ - CacheClientIcons(); - pcli->pfnReloadExtraIcons(); - pcli->pfnSetAllExtraIcons(NULL); - - pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0); - SendMessage(g_hwndViewModeFrame, WM_USER + 100, 0, 0); -} - -void ConfigureCLUIGeometry(int mode) -{ - RECT rcStatus; - DWORD clmargins = cfg::getDword("CLUI", "clmargins", 0); - - cfg::dat.bCLeft = LOBYTE(LOWORD(clmargins)); - cfg::dat.bCRight = HIBYTE(LOWORD(clmargins)); - cfg::dat.bCTop = LOBYTE(HIWORD(clmargins)); - cfg::dat.bCBottom = HIBYTE(HIWORD(clmargins)); - - if (mode) { - if (cfg::dat.dwFlags & CLUI_FRAME_SBARSHOW) { - SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0); - GetWindowRect(pcli->hwndStatus, &rcStatus); - cfg::dat.statusBarHeight = (rcStatus.bottom - rcStatus.top); - } - else - cfg::dat.statusBarHeight = 0; - } - - cfg::dat.topOffset = cfg::dat.bCTop; - cfg::dat.bottomOffset = (cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? 2 + 21 : 0) + cfg::dat.bCBottom; - - if (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN) { - cfg::dat.topOffset += 2; - cfg::dat.bottomOffset += 2; - cfg::dat.bCLeft += 3; - cfg::dat.bCRight += 3; - } -} - -// set the states of defined database action buttons (only if button is a toggle) -void SetDBButtonStates(MCONTACT hPassedContact) -{ - ButtonItem *buttonItem = g_ButtonItems; - MCONTACT hContact = 0, hFinalContact = 0; - char *szModule, *szSetting; - int sel = cfg::clcdat ? cfg::clcdat->selection : -1; - ClcContact *contact = 0; - - if (sel != -1 && hPassedContact == 0) { - sel = pcli->pfnGetRowByIndex(cfg::clcdat, cfg::clcdat->selection, &contact, NULL); - if (contact && contact->type == CLCIT_CONTACT) { - hContact = contact->hContact; - } - } - - while (buttonItem) { - BOOL result = FALSE; - - if (!(buttonItem->dwFlags & BUTTON_ISTOGGLE && buttonItem->dwFlags & BUTTON_ISDBACTION)) { - buttonItem = buttonItem->nextItem; - continue; - } - szModule = buttonItem->szModule; - szSetting = buttonItem->szSetting; - if (buttonItem->dwFlags & BUTTON_DBACTIONONCONTACT || buttonItem->dwFlags & BUTTON_ISCONTACTDBACTION) { - if (hContact == 0) { - SendMessage(buttonItem->hWnd, BM_SETCHECK, BST_UNCHECKED, 0); - buttonItem = buttonItem->nextItem; - continue; - } - if (buttonItem->dwFlags & BUTTON_ISCONTACTDBACTION) - szModule = GetContactProto(hContact); - hFinalContact = hContact; - } - else - hFinalContact = 0; - - if (buttonItem->type == DBVT_ASCIIZ) { - DBVARIANT dbv = {0}; - - if (!cfg::getString(hFinalContact, szModule, szSetting, &dbv)) { - result = !strcmp((char *)buttonItem->bValuePush, dbv.pszVal); - db_free(&dbv); - } - } - else { - switch (buttonItem->type) { - case DBVT_BYTE: { - BYTE val = cfg::getByte(hFinalContact, szModule, szSetting, 0); - result = (val == buttonItem->bValuePush[0]); - break; - } - case DBVT_WORD: { - WORD val = cfg::getWord(hFinalContact, szModule, szSetting, 0); - result = (val == *((WORD *)&buttonItem->bValuePush)); - break; - } - case DBVT_DWORD: { - DWORD val = cfg::getDword(hFinalContact, szModule, szSetting, 0); - result = (val == *((DWORD *)&buttonItem->bValuePush)); - break; - } - } - } - SendMessage(buttonItem->hWnd, BM_SETCHECK, (WPARAM)result, 0); - buttonItem = buttonItem->nextItem; - } -} - -// set states of standard buttons (pressed/unpressed) -void SetButtonStates(HWND hwnd) -{ - ButtonItem *buttonItem = g_ButtonItems; - - if (g_ButtonItems) { - while (buttonItem) { - if (buttonItem->dwFlags & BUTTON_ISINTERNAL) { - switch (buttonItem->uId) { - case IDC_STBSOUND: - SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::dat.soundsOff ? BST_CHECKED : BST_UNCHECKED, 0); - break; - case IDC_STBHIDEOFFLINE: - SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::getByte("CList", "HideOffline", 0) ? BST_CHECKED : BST_UNCHECKED, 0); - break; - case IDC_STBHIDEGROUPS: - SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::getByte("CList", "UseGroups", 0) ? BST_CHECKED : BST_UNCHECKED, 0); - break; - } - } - buttonItem = buttonItem->nextItem; - } - } -} - -void BlitWallpaper(HDC hdc, RECT *rc, RECT *rcPaint, struct ClcData *dat) -{ - int x, y; - int bitx, bity; - int maxx, maxy; - int destw, desth, height, width; - BITMAP *bmp = &cfg::dat.bminfoBg; - LONG clip = cfg::dat.bClipBorder; - - if (dat == 0) - return; - - SetStretchBltMode(hdc, HALFTONE); - - y = rc->top; - - rc->left = max(rc->left, clip); - rc->right = min(rc->right - clip, rc->right); - rc->top = max(rc->top, clip); - rc->bottom = min(rc->bottom - clip, rc->bottom); - - width = rc->right - rc->left; - height = rc->bottom - rc->top; - HRGN my_rgn = CreateRectRgn(rc->left, rc->top, rc->right, rc->bottom); - SelectClipRgn(hdc, my_rgn); - maxx = dat->backgroundBmpUse & CLBF_TILEH ? rc->right : rc->left + 1; - maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rc->bottom : y + 1; - switch (dat->backgroundBmpUse & CLBM_TYPE) { - case CLB_STRETCH: - if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { - if (width * bmp->bmHeight < height * bmp->bmWidth) { - desth = height; - destw = desth * bmp->bmWidth / bmp->bmHeight; - } - else { - destw = width; - desth = destw * bmp->bmHeight / bmp->bmWidth; - } - } - else { - destw = width; - desth = height; - } - break; - case CLB_STRETCHH: - if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { - destw = width; - desth = destw * bmp->bmHeight / bmp->bmWidth; - } - else { - destw = width; - desth = bmp->bmHeight; - } - break; - case CLB_STRETCHV: - if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { - desth = height; - destw = desth * bmp->bmWidth / bmp->bmHeight; - } - else { - destw = bmp->bmWidth; - desth = height; - } - break; - default: - //clb_topleft - destw = bmp->bmWidth; - desth = bmp->bmHeight; - break; - } - - bitx = 0; - bity = 0; - for (; y < maxy; y += desth) { - for (x = rc->left; x < maxx; x += destw) - StretchBlt(hdc, x, y, destw, desth, cfg::dat.hdcPic, bitx, bity, bmp->bmWidth, bmp->bmHeight, SRCCOPY); - } - SelectClipRgn(hdc, NULL); - DeleteObject(my_rgn); -} - -void ReloadThemedOptions() -{ - cfg::dat.bSkinnedStatusBar = cfg::getByte("CLUI", "sb_skinned", 0); - cfg::dat.bUsePerProto = cfg::getByte("CLCExt", "useperproto", 0); - cfg::dat.bOverridePerStatusColors = cfg::getByte("CLCExt", "override_status", 0); - cfg::dat.bRowSpacing = cfg::getByte("CLC", "RowGap", 0); - cfg::dat.bApplyIndentToBg = cfg::getByte("CLCExt", "applyindentbg", 0); - cfg::dat.bWallpaperMode = cfg::getByte("CLUI", "UseBkSkin", 1); - cfg::dat.bClipBorder = cfg::getByte("CLUI", "clipborder", 0); - cfg::dat.cornerRadius = cfg::getByte("CLCExt", "CornerRad", 6); - cfg::dat.gapBetweenFrames = (BYTE)cfg::getDword("CLUIFrames", "GapBetweenFrames", 1); - cfg::dat.bUseDCMirroring = cfg::getByte("CLC", "MirrorDC", 0); - cfg::dat.bGroupAlign = cfg::getByte("CLC", "GroupAlign", 0); - if (cfg::dat.hBrushColorKey) - DeleteObject(cfg::dat.hBrushColorKey); - cfg::dat.hBrushColorKey = CreateSolidBrush(RGB(255, 0, 255)); - cfg::dat.bWantFastGradients = cfg::getByte("CLCExt", "FastGradients", 0); - cfg::dat.titleBarHeight = cfg::getByte("CLCExt", "frame_height", DEFAULT_TITLEBAR_HEIGHT); - cfg::dat.group_padding = cfg::getDword("CLCExt", "grp_padding", 0); -} - -static RECT rcWindow = {0}; - -static void sttProcessResize(HWND hwnd, NMCLISTCONTROL *nmc) -{ - RECT rcTree, rcWorkArea, rcOld; - int maxHeight, newHeight; - int winstyle, skinHeight = 0; - - if (disableautoupd) - return; - - if (!cfg::getByte("CLUI", "AutoSize", 0)) - return; - - if (Docking_IsDocked(0, 0)) - return; - if (hFrameContactTree == 0) - return; - - maxHeight = cfg::getByte("CLUI", "MaxSizeHeight", 75); - rcOld = rcWindow; - - GetWindowRect(hwnd, &rcWindow); - GetWindowRect(pcli->hwndContactTree, &rcTree); - winstyle = GetWindowLongPtr(pcli->hwndContactTree, GWL_STYLE); - - SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); - HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof(mi); - if (GetMonitorInfo(hMon, &mi)) - rcWorkArea = mi.rcWork; - - if (nmc->pt.y > (rcWorkArea.bottom - rcWorkArea.top)) { - nmc->pt.y = (rcWorkArea.bottom - rcWorkArea.top); - } - - if (winstyle & CLS_SKINNEDFRAME) { - BOOL hasTitleBar = wndFrameCLC ? wndFrameCLC->TitleBar.ShowTitleBar : 0; - StatusItems_t *item = arStatusItems[(hasTitleBar ? ID_EXTBKOWNEDFRAMEBORDERTB : ID_EXTBKOWNEDFRAMEBORDER) - ID_STATUS_OFFLINE]; - skinHeight = item->IGNORED ? 0 : item->MARGIN_BOTTOM + item->MARGIN_TOP; - } - - newHeight = max(nmc->pt.y, 3) + 1 + ((winstyle & WS_BORDER) ? 2 : 0) + skinHeight + (rcWindow.bottom - rcWindow.top) - (rcTree.bottom - rcTree.top); - if (newHeight == (rcWindow.bottom - rcWindow.top) && show_on_first_autosize == FALSE) - return; - - if (newHeight > (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100) - newHeight = (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100; - if (cfg::getByte("CLUI", "AutoSizeUpward", 0)) { - rcWindow.top = rcWindow.bottom - newHeight; - if (rcWindow.top < rcWorkArea.top) rcWindow.top = rcWorkArea.top; - } - else { - rcWindow.bottom = rcWindow.top + newHeight; - if (rcWindow.bottom > rcWorkArea.bottom) rcWindow.bottom = rcWorkArea.bottom; - } - if (cfg::dat.szOldCTreeSize.cx != rcTree.right - rcTree.left) { - cfg::dat.szOldCTreeSize.cx = rcTree.right - rcTree.left; - return; - } - KillTimer(hwnd, TIMERID_AUTOSIZE); - SetTimer(hwnd, TIMERID_AUTOSIZE, 100, 0); -} - -int CustomDrawScrollBars(NMCSBCUSTOMDRAW *nmcsbcd) -{ - switch (nmcsbcd->hdr.code) { - case NM_COOLSB_CUSTOMDRAW: - static HDC hdcScroll = 0; - static HBITMAP hbmScroll, hbmScrollOld; - static LONG scrollLeft, scrollRight, scrollHeight, scrollYmin, scrollYmax; - - switch (nmcsbcd->dwDrawStage) { - case CDDS_PREPAINT: - if (cfg::dat.bSkinnedScrollbar) // XXX fix (verify skin items to be complete, otherwise don't draw - return CDRF_SKIPDEFAULT; - return CDRF_DODEFAULT; - - case CDDS_POSTPAINT: - return 0; - - case CDDS_ITEMPREPAINT: - HDC hdc = nmcsbcd->hdc; - StatusItems_t *item = 0, *arrowItem = 0; - UINT uItemID = ID_EXTBKSCROLLBACK; - RECT rcWindow; - POINT pt; - DWORD dfcFlags; - HRGN rgn = 0; - GetWindowRect(pcli->hwndContactTree, &rcWindow); - pt.x = rcWindow.left; - pt.y = rcWindow.top; - ScreenToClient(pcli->hwndContactList, &pt); - hdcScroll = hdc; - BitBlt(hdcScroll, nmcsbcd->rect.left, nmcsbcd->rect.top, nmcsbcd->rect.right - nmcsbcd->rect.left, - nmcsbcd->rect.bottom - nmcsbcd->rect.top, cfg::dat.hdcBg, pt.x + nmcsbcd->rect.left, pt.y + nmcsbcd->rect.top, SRCCOPY); - - switch (nmcsbcd->uItem) { - case HTSCROLL_UP: - case HTSCROLL_DOWN: - uItemID = (nmcsbcd->uState == CDIS_DEFAULT || nmcsbcd->uState == CDIS_DISABLED) ? ID_EXTBKSCROLLBUTTON : - (nmcsbcd->uState == CDIS_HOT ? ID_EXTBKSCROLLBUTTONHOVER : ID_EXTBKSCROLLBUTTONPRESSED); - break; - case HTSCROLL_PAGEGDOWN: - case HTSCROLL_PAGEGUP: - uItemID = nmcsbcd->uItem == HTSCROLL_PAGEGUP ? ID_EXTBKSCROLLBACK : ID_EXTBKSCROLLBACKLOWER; - rgn = CreateRectRgn(nmcsbcd->rect.left, nmcsbcd->rect.top, nmcsbcd->rect.right, nmcsbcd->rect.bottom); - SelectClipRgn(hdcScroll, rgn); - break; - case HTSCROLL_THUMB: - uItemID = nmcsbcd->uState == CDIS_SELECTED ? ID_EXTBKSCROLLTHUMBPRESSED : ID_EXTBKSCROLLTHUMB; - break; - default: - break; - } - - uItemID -= ID_STATUS_OFFLINE; - item = arStatusItems[uItemID]; - if (!item->IGNORED) { - int alpha = nmcsbcd->uState == CDIS_DISABLED ? item->ALPHA - 50 : item->ALPHA; - DrawAlpha(hdcScroll, &nmcsbcd->rect, item->COLOR, alpha, item->COLOR2, item->COLOR2_TRANSPARENT, - item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem); - } - dfcFlags = DFCS_FLAT | (nmcsbcd->uState == CDIS_DISABLED ? DFCS_INACTIVE : - (nmcsbcd->uState == CDIS_HOT ? DFCS_HOT : - (nmcsbcd->uState == CDIS_SELECTED ? DFCS_PUSHED : 0))); - - if (nmcsbcd->uItem == HTSCROLL_UP) - arrowItem = arStatusItems[ID_EXTBKSCROLLARROWUP - ID_STATUS_OFFLINE]; - if (nmcsbcd->uItem == HTSCROLL_DOWN) - arrowItem = arStatusItems[ID_EXTBKSCROLLARROWDOWN - ID_STATUS_OFFLINE]; - if (arrowItem && !arrowItem->IGNORED) - DrawAlpha(hdcScroll, &nmcsbcd->rect, arrowItem->COLOR, arrowItem->ALPHA, arrowItem->COLOR2, arrowItem->COLOR2_TRANSPARENT, - arrowItem->GRADIENT, arrowItem->CORNER, arrowItem->BORDERSTYLE, arrowItem->imageItem); - else if (arrowItem) - DrawFrameControl(hdcScroll, &nmcsbcd->rect, DFC_SCROLL, (nmcsbcd->uItem == HTSCROLL_UP ? DFCS_SCROLLUP : DFCS_SCROLLDOWN) | dfcFlags); - - if (rgn) { - SelectClipRgn(hdcScroll, NULL); - DeleteObject(rgn); - } - } - } - return 0; -} - -static int ServiceParamsOK(ButtonItem *item, WPARAM *wParam, LPARAM *lParam, MCONTACT hContact) -{ - if (item->dwFlags & BUTTON_PASSHCONTACTW || item->dwFlags & BUTTON_PASSHCONTACTL || item->dwFlags & BUTTON_ISCONTACTDBACTION) { - if (hContact == 0) - return 0; - - if (item->dwFlags & BUTTON_PASSHCONTACTW) - *wParam = hContact; - else if (item->dwFlags & BUTTON_PASSHCONTACTL) - *lParam = hContact; - } - return 1; -} - -static void ShowCLUI(HWND hwnd) -{ - int state = old_cliststate; - int onTop = cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT); - - SendMessage(hwnd, WM_SETREDRAW, FALSE, FALSE); - if (!cfg::getByte("CLUI", "ShowMainMenu", SETTING_SHOWMAINMENU_DEFAULT)) - SetMenu(pcli->hwndContactList, NULL); - if (state == SETTING_STATE_NORMAL) { - SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0); - ShowWindow(pcli->hwndContactList, SW_SHOWNORMAL); - SendMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0); - } - else if (state == SETTING_STATE_MINIMIZED) { - cfg::dat.forceResize = TRUE; - ShowWindow(pcli->hwndContactList, SW_HIDE); - } - else if (state == SETTING_STATE_HIDDEN) { - cfg::dat.forceResize = TRUE; - ShowWindow(pcli->hwndContactList, SW_HIDE); - } - SetWindowPos(pcli->hwndContactList, onTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOSENDCHANGING); - DrawMenuBar(hwnd); - if (cfg::dat.autosize) { - SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0); - SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0); - } -} - -static void GetButtonRect(HWND hwnd, RECT *rc) -{ - if (hwnd) - GetWindowRect(hwnd, rc); - else { - POINT pt; - GetCursorPos(&pt); - rc->bottom = rc->top = pt.y; - rc->left = rc->right = pt.x; - } -} - -LRESULT CALLBACK ContactListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CREATE: - { - int flags = WS_CHILD | CCS_BOTTOM; - flags |= cfg::getByte("CLUI", "ShowSBar", 1) ? WS_VISIBLE : 0; - flags |= cfg::getByte("CLUI", "ShowGrip", 1) ? SBARS_SIZEGRIP : 0; - pcli->hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, flags, 0, 0, 0, 0, hwnd, NULL, g_hInst, NULL); - if (flags & WS_VISIBLE) { - ShowWindow(pcli->hwndStatus, SW_SHOW); - SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0); - } - mir_subclassWindow(pcli->hwndStatus, NewStatusBarWndProc); - SetClassLong(pcli->hwndStatus, GCL_STYLE, GetClassLong(pcli->hwndStatus, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW)); - } - g_oldSize.cx = g_oldSize.cy = 0; - old_cliststate = cfg::getByte("CList", "State", SETTING_STATE_NORMAL); - cfg::writeByte("CList", "State", SETTING_STATE_HIDDEN); - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_VISIBLE); - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | WS_CLIPCHILDREN); - if (!cfg::dat.bFirstRun) - ConfigureEventArea(hwnd); - ConfigureCLUIGeometry(0); - CluiProtocolStatusChanged(0, 0); - - for (int i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) - statusNames[i - ID_STATUS_OFFLINE] = pcli->pfnGetStatusModeDescription(i, 0); - - //delay creation of CLC so that it can get the status icons right the first time (needs protocol modules loaded) - if (cfg::dat.bLayeredHack) { - SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | (WS_EX_LAYERED)); - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 255, LWA_ALPHA); - } - - if (cfg::dat.isTransparent) { - SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - } - transparentFocus = 1; - - TranslateMenu(GetMenu(hwnd)); - PostMessage(hwnd, M_CREATECLC, 0, 0); - return FALSE; - - case WM_NCCREATE: - { - LPCREATESTRUCT p = (LPCREATESTRUCT)lParam; - p->style &= ~(CS_HREDRAW | CS_VREDRAW); - } - break; - - case M_CREATECLC: { - if (cfg::getByte("CLUI", "useskin", 0)) - IMG_LoadItems(); - CreateButtonBar(hwnd); - //FYR: to be checked: otherwise it raises double xStatus items - //NotifyEventHooks(pcli->hPreBuildStatusMenuEvent, 0, 0); - SendMessage(hwnd, WM_SETREDRAW, FALSE, FALSE); - { - LONG style; - BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_TOOLWINDOW); - ShowWindow(pcli->hwndContactList, SW_HIDE); - style = GetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE); - if (windowStyle != SETTING_WINDOWSTYLE_DEFAULT) { - style |= WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE; - style &= ~WS_EX_APPWINDOW; - } - else { - style &= ~(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE); - if (cfg::getByte("CList", "AlwaysHideOnTB", 1)) - style &= ~WS_EX_APPWINDOW; - else - style |= WS_EX_APPWINDOW; - } - - SetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE, style); - ApplyCLUIBorderStyle(pcli->hwndContactList); - - SetWindowPos(pcli->hwndContactList, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE); - } - - if (cfg::dat.bSkinnedButtonMode) - SetButtonToSkinned(); - ConfigureFrame(); - SetButtonStates(hwnd); - - CreateCLC(hwnd); - cfg::clcdat = (struct ClcData *)GetWindowLongPtr(pcli->hwndContactTree, 0); - - if (cfg::dat.bFullTransparent) { - if (g_CLUISkinnedBkColorRGB) - Tweak_It(g_CLUISkinnedBkColorRGB); - else if (cfg::dat.bClipBorder || (cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME)) - Tweak_It(RGB(255, 0, 255)); - else - Tweak_It(cfg::clcdat->bkColour); - } - - cfg::writeByte("CList", "State", old_cliststate); - - if (cfg::getByte("CList", "AutoApplyLastViewMode", 0)) { - DBVARIANT dbv = {0}; - if (!db_get(NULL, "CList", "LastViewMode", &dbv)) { - if (lstrlenA(dbv.pszVal) > 2) { - if (cfg::getDword(NULL, CLVM_MODULE, dbv.pszVal, -1) != 0xffffffff) - ApplyViewMode((char *)dbv.pszVal); - } - db_free(&dbv); - } - } - if (!cfg::dat.autosize) - ShowCLUI(hwnd); - else { - show_on_first_autosize = TRUE; - RecalcScrollBar(pcli->hwndContactTree, cfg::clcdat); - } - return 0; - } - case WM_ERASEBKGND: - return TRUE; - /* - if (cfg::dat.bSkinnedButtonMode) - return TRUE; - return DefWindowProc(hwnd, msg, wParam, lParam); - */ - - case WM_PAINT: - { - PAINTSTRUCT ps; - RECT rc, rcFrame, rcClient; - HDC hdc; - HRGN rgn = 0; - HDC hdcReal = BeginPaint(hwnd, &ps); - - if (during_sizing) - rcClient = rcWPC; - else - GetClientRect(hwnd, &rcClient); - CopyRect(&rc, &rcClient); - - if (!cfg::dat.hdcBg || rc.right > cfg::dat.dcSize.cx || rc.bottom + cfg::dat.statusBarHeight > cfg::dat.dcSize.cy) { - RECT rcWorkArea; - - SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); - HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof(mi); - if (GetMonitorInfo(hMon, &mi)) - rcWorkArea = mi.rcWork; - - cfg::dat.dcSize.cy = max(rc.bottom + cfg::dat.statusBarHeight, rcWorkArea.bottom - rcWorkArea.top); - cfg::dat.dcSize.cx = max(rc.right, (rcWorkArea.right - rcWorkArea.left) / 2); - - if (cfg::dat.hdcBg) { - SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBgOld); - DeleteObject(cfg::dat.hbmBg); - DeleteDC(cfg::dat.hdcBg); - } - cfg::dat.hdcBg = CreateCompatibleDC(hdcReal); - cfg::dat.hbmBg = CreateCompatibleBitmap(hdcReal, cfg::dat.dcSize.cx, cfg::dat.dcSize.cy); - cfg::dat.hbmBgOld = reinterpret_cast(SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBg)); - } - - if (cfg::shutDown) { - EndPaint(hwnd, &ps); - return 0; - } - - hdc = cfg::dat.hdcBg; - - CopyRect(&rcFrame, &rcClient); - if (g_CLUISkinnedBkColor) { - if (cfg::dat.fOnDesktop) { - HDC dc = GetDC(0); - RECT rcWin; - - GetWindowRect(hwnd, &rcWin); - BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, dc, rcWin.left, rcWin.top, SRCCOPY); - } - else - FillRect(hdc, &rcClient, g_CLUISkinnedBkColor); - } - - if (cfg::dat.bClipBorder != 0 || cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME) { - int docked = CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0); - int clip = cfg::dat.bClipBorder; - - if (!g_CLUISkinnedBkColor) - FillRect(hdc, &rcClient, cfg::dat.hBrushColorKey); - if (cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME) - rgn = CreateRoundRectRgn(clip, docked ? 0 : clip, rcClient.right - clip + 1, rcClient.bottom - (docked ? 0 : clip - 1), 8 + clip, 8 + clip); - else - rgn = CreateRectRgn(clip, docked ? 0 : clip, rcClient.right - clip, rcClient.bottom - (docked ? 0 : clip)); - SelectClipRgn(hdc, rgn); - } - - if (g_CLUIImageItem) { - IMG_RenderImageItem(hdc, g_CLUIImageItem, &rcFrame); - cfg::dat.ptW.x = cfg::dat.ptW.y = 0; - ClientToScreen(hwnd, &cfg::dat.ptW); - goto skipbg; - } - - if (cfg::dat.bWallpaperMode) - FillRect(hdc, &rcClient, cfg::dat.hBrushCLCBk); - else - FillRect(hdc, &rcClient, GetSysColorBrush(COLOR_3DFACE)); - - rcFrame.left += (cfg::dat.bCLeft - 1); - rcFrame.right -= (cfg::dat.bCRight - 1); - rcFrame.bottom++; - rcFrame.bottom -= cfg::dat.statusBarHeight; - rcFrame.top += (cfg::dat.topOffset - 1); - - if (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN) { - if (cfg::dat.bWallpaperMode && cfg::clcdat != NULL) { - InflateRect(&rcFrame, -1, -1); - if (cfg::dat.bmpBackground) - BlitWallpaper(hdc, &rcFrame, &ps.rcPaint, cfg::clcdat); - cfg::dat.ptW.x = cfg::dat.ptW.y = 0; - ClientToScreen(hwnd, &cfg::dat.ptW); - } - InflateRect(&rcFrame, 1, 1); - if (cfg::dat.bSkinnedButtonMode) - rcFrame.bottom -= (cfg::dat.bottomOffset); - DrawEdge(hdc, &rcFrame, BDR_SUNKENOUTER, BF_RECT); - } - else if (cfg::dat.bWallpaperMode && cfg::clcdat != NULL) { - if (cfg::dat.bmpBackground) - BlitWallpaper(hdc, &rcFrame, &ps.rcPaint, cfg::clcdat); - cfg::dat.ptW.x = cfg::dat.ptW.y = 0; - ClientToScreen(hwnd, &cfg::dat.ptW); - } -skipbg: - BitBlt(hdcReal, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdc, 0, 0, SRCCOPY); - if (rgn) { - SelectClipRgn(hdc, NULL); - DeleteObject(rgn); - } - EndPaint(hwnd, &ps); - } - return 0; - - case WM_ENTERSIZEMOVE: - { - RECT rc; - POINT pt = {0}; - - GetWindowRect(hwnd, &g_PreSizeRect); - GetClientRect(hwnd, &rc); - ClientToScreen(hwnd, &pt); - g_CLUI_x_off = pt.x - g_PreSizeRect.left; - g_CLUI_y_off = pt.y - g_PreSizeRect.top; - pt.x = rc.right; - ClientToScreen(hwnd, &pt); - g_CLUI_x1_off = g_PreSizeRect.right - pt.x; - pt.x = 0; - pt.y = rc.bottom; - ClientToScreen(hwnd, &pt); - g_CLUI_y1_off = g_PreSizeRect.bottom - pt.y; - } - break; - - case WM_EXITSIZEMOVE: - PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0); - break; - - case WM_SIZING: - break; - /* - RECT *szrect = (RECT *)lParam; - if (Docking_IsDocked(0, 0)) - break; - g_SizingRect = *((RECT *)lParam); - if (wParam != WMSZ_BOTTOM && wParam != WMSZ_BOTTOMRIGHT && wParam != WMSZ_BOTTOMLEFT) - szrect->bottom = g_PreSizeRect.bottom; - if (wParam != WMSZ_RIGHT && wParam != WMSZ_BOTTOMRIGHT && wParam != WMSZ_TOPRIGHT) - szrect->right = g_PreSizeRect.right; - */ - return TRUE; - - case WM_WINDOWPOSCHANGED: - if (Docking_IsDocked(0, 0)) - break; - - case WM_WINDOWPOSCHANGING: - if (pcli->hwndContactList != NULL) { - WINDOWPOS *wp = (WINDOWPOS *)lParam; - if (wp && wp->flags & SWP_NOSIZE) - return FALSE; - - RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); - during_sizing = true; - - new_window_rect.left = 0; - new_window_rect.right = wp->cx - (g_CLUI_x_off + g_CLUI_x1_off); - new_window_rect.top = 0; - new_window_rect.bottom = wp->cy - g_CLUI_y_off - g_CLUI_y1_off; - - if (cfg::dat.dwFlags & CLUI_FRAME_SBARSHOW) { - RECT rcStatus; - SetWindowPos(pcli->hwndStatus, 0, 0, new_window_rect.bottom - 20, new_window_rect.right, 20, SWP_NOZORDER); - GetWindowRect(pcli->hwndStatus, &rcStatus); - cfg::dat.statusBarHeight = (rcStatus.bottom - rcStatus.top); - if (wp->cx != g_oldSize.cx) - SendMessage(hwnd, CLUIINTM_STATUSBARUPDATE, 0, 0); - RedrawWindow(pcli->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); - } - else - cfg::dat.statusBarHeight = 0; - - SizeFramesByWindowRect(&new_window_rect); - dock_prevent_moving = 0; - LayoutButtons(hwnd, &new_window_rect); - dock_prevent_moving = 1; - g_oldPos.x = wp->x; - g_oldPos.y = wp->y; - g_oldSize.cx = wp->cx; - g_oldSize.cy = wp->cy; - rcWPC = new_window_rect; - } - during_sizing = false; - return 0; - - case WM_SIZE: - if ((wParam == 0 && lParam == 0) || Docking_IsDocked(0, 0)) { - - if (IsZoomed(hwnd)) - ShowWindow(hwnd, SW_SHOWNORMAL); - - if (pcli->hwndContactList != 0) { - SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0); - RECT rc; - GetWindowRect(hwnd, &rc); - WINDOWPOS wp = {0}; - wp.cx = rc.right - rc.left; - wp.cy = rc.bottom - rc.top; - wp.x = rc.left; - wp.y = rc.top; - wp.flags = 0; - SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp); - SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0); - } - } - - case WM_MOVE: - if (!IsIconic(hwnd)) { - RECT rc; - GetWindowRect(hwnd, &rc); - - if (!Docking_IsDocked(0, 0)) { - cluiPos.bottom = (DWORD)(rc.bottom - rc.top); - cluiPos.left = rc.left; - cluiPos.top = rc.top; - } - cluiPos.right = rc.right - rc.left; - if (cfg::dat.realTimeSaving) { - RECT rc; - GetWindowRect(hwnd, &rc); - - // if docked, dont remember pos (except for width) - if (!CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) { - cfg::writeDword("CList", "Height", (DWORD)(rc.bottom - rc.top)); - cfg::writeDword("CList", "x", (DWORD)rc.left); - cfg::writeDword("CList", "y", (DWORD)rc.top); - } - cfg::writeDword("CList", "Width", (DWORD)(rc.right - rc.left)); - } - } - return TRUE; - - case WM_SETFOCUS: - SetFocus(pcli->hwndContactTree); - return 0; - - case CLUIINTM_REMOVEFROMTASKBAR: { - BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT); - if (windowStyle == SETTING_WINDOWSTYLE_DEFAULT && cfg::getByte("CList", "AlwaysHideOnTB", 0)) - RemoveFromTaskBar(hwnd); - return 0; - } - case WM_ACTIVATE: - if (g_fading_active) { - if (wParam != WA_INACTIVE && cfg::dat.isTransparent) - transparentFocus = 1; - return DefWindowProc(hwnd, msg, wParam, lParam); - } - if (wParam == WA_INACTIVE) { - if ((HWND)wParam != hwnd) - if (cfg::dat.isTransparent) - if (transparentFocus) - SetTimer(hwnd, TM_AUTOALPHA, 250, NULL); - } - else { - if (cfg::dat.isTransparent) { - KillTimer(hwnd, TM_AUTOALPHA); - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - transparentFocus = 1; - } - SetWindowPos(pcli->hwndContactList, cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING); - } - PostMessage(hwnd, CLUIINTM_REMOVEFROMTASKBAR, 0, 0); - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_SETCURSOR: - if (cfg::dat.isTransparent) { - if (!transparentFocus && GetForegroundWindow() != hwnd) { - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - transparentFocus = 1; - SetTimer(hwnd, TM_AUTOALPHA, 250, NULL); - } - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_NCHITTEST: { - LRESULT result; - RECT r; - POINT pt; - int k = 0; - int clip = cfg::dat.bClipBorder; - - GetWindowRect(hwnd, &r); - GetCursorPos(&pt); - if (pt.y <= r.bottom && pt.y >= r.bottom - clip - 6 && !cfg::getByte("CLUI", "AutoSize", 0)) { - if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10) - return HTBOTTOM; - if (pt.x < r.left + clip + 10) - return HTBOTTOMLEFT; - if (pt.x > r.right - clip - 10) - return HTBOTTOMRIGHT; - } - else if (pt.y >= r.top && pt.y <= r.top + 3 && !cfg::getByte("CLUI", "AutoSize", 0)) { - if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10) - return HTTOP; - if (pt.x < r.left + clip + 10) - return HTTOPLEFT; - if (pt.x > r.right - clip - 10) - return HTTOPRIGHT; - } - else if (pt.x >= r.left && pt.x <= r.left + clip + 6) - return HTLEFT; - else if (pt.x >= r.right - clip - 6 && pt.x <= r.right) - return HTRIGHT; - - result = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam); - if (result == HTSIZE || result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT || result == HTBOTTOM || result == HTBOTTOMRIGHT || result == HTBOTTOMLEFT) - if (cfg::dat.autosize) - return HTCLIENT; - return result; - } - - case WM_TIMER: - if ((int)wParam == TM_AUTOALPHA) { - int inwnd; - - if (GetForegroundWindow() == hwnd) { - KillTimer(hwnd, TM_AUTOALPHA); - inwnd = 1; - } - else { - POINT pt; - HWND hwndPt; - pt.x = (short)LOWORD(GetMessagePos()); - pt.y = (short)HIWORD(GetMessagePos()); - hwndPt = WindowFromPoint(pt); - inwnd = (hwndPt == hwnd || GetParent(hwndPt) == hwnd); - } - if (inwnd != transparentFocus) { - //change - transparentFocus = inwnd; - if (transparentFocus) - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - else - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.autoalpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - } - if (!transparentFocus) - KillTimer(hwnd, TM_AUTOALPHA); - } - else if (wParam == TIMERID_AUTOSIZE) { - KillTimer(hwnd, wParam); - SetWindowPos(hwnd, 0, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); - PostMessage(hwnd, WM_SIZE, 0, 0); - PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0); - } - return TRUE; - - case WM_SHOWWINDOW: - { - static int noRecurse = 0; - DWORD thisTick, startTick; - int sourceAlpha, destAlpha; - - if (cfg::dat.forceResize && wParam != SW_HIDE) { - cfg::dat.forceResize = FALSE; - if (0) { //!g_CluiData.fadeinout && MySetLayeredWindowAttributes && g_CluiData.bLayeredHack) { - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), 0, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - SendMessage(hwnd, WM_SIZE, 0, 0); - ShowWindow(hwnd, SW_SHOW); - RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), 255, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - } - else { - SendMessage(hwnd, WM_SIZE, 0, 0); - PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0); - } - } - PostMessage(hwnd, CLUIINTM_REMOVEFROMTASKBAR, 0, 0); - - if (lParam) - return DefWindowProc(hwnd, msg, wParam, lParam); - if (noRecurse) - return DefWindowProc(hwnd, msg, wParam, lParam); - if (!cfg::dat.fadeinout) - return DefWindowProc(hwnd, msg, wParam, lParam); - - g_fading_active = 1; - - if (wParam) { - sourceAlpha = 0; - destAlpha = cfg::dat.isTransparent ? cfg::dat.alpha : 255; - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? (COLORREF)cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)sourceAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - noRecurse = 1; - ShowWindow(hwnd, SW_SHOW); - RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - noRecurse = 0; - } - else { - sourceAlpha = cfg::dat.isTransparent ? (transparentFocus ? cfg::dat.alpha : cfg::dat.autoalpha) : 255; - destAlpha = 0; - } - for (startTick = GetTickCount(); ;) { - thisTick = GetTickCount(); - if (thisTick >= startTick + 200) { - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)destAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - g_fading_active = 0; - return DefWindowProc(hwnd, msg, wParam, lParam); - } - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)(sourceAlpha + (destAlpha - sourceAlpha) * (int)(thisTick - startTick) / 200), LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - } - SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)destAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_SYSCOMMAND: - { - BYTE bWindowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT); - if (SETTING_WINDOWSTYLE_DEFAULT == bWindowStyle) { - if (wParam == SC_RESTORE) { - CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); - SendMessage(hwnd, WM_SIZE, 0, 0); - SendMessage(hwnd, CLUIINTM_REDRAW, 0, 0); - SendMessage(hwnd, CLUIINTM_STATUSBARUPDATE, 0, 0); - cfg::writeByte("CList", "State", SETTING_STATE_NORMAL); - break; - } - } - - if (wParam == SC_MAXIMIZE) - return 0; - - if (wParam == SC_MINIMIZE) { - if (SETTING_WINDOWSTYLE_DEFAULT == bWindowStyle && !cfg::getByte("CList", "AlwaysHideOnTB", 0)) { - cfg::writeByte("CList", "State", SETTING_STATE_MINIMIZED); - break; - } - pcli->pfnShowHide(0, 0); - return 0; - } - if (wParam == SC_RESTORE) { - pcli->pfnShowHide(0, 0); - return 0; - } - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_COMMAND: - { - DWORD dwOldFlags = cfg::dat.dwFlags; - if (HIWORD(wParam) == BN_CLICKED && lParam != 0) { - if (LOWORD(wParam) == IDC_TBFIRSTUID - 1) - break; - - else if (LOWORD(wParam) >= IDC_TBFIRSTUID) { // skinnable buttons handling - ButtonItem *item = g_ButtonItems; - WPARAM wwParam = 0; - LPARAM llParam = 0; - MCONTACT hContact = 0; - ClcContact *contact = 0; - int sel = cfg::clcdat ? cfg::clcdat->selection : -1; - int serviceFailure = FALSE; - - if (sel != -1) { - sel = pcli->pfnGetRowByIndex(cfg::clcdat, cfg::clcdat->selection, &contact, NULL); - if (contact && contact->type == CLCIT_CONTACT) { - hContact = contact->hContact; - } - } - while (item) { - if (item->uId == (DWORD)LOWORD(wParam)) { - int contactOK = ServiceParamsOK(item, &wwParam, &llParam, hContact); - - if (item->dwFlags & BUTTON_ISSERVICE) { - if (ServiceExists(item->szService) && contactOK) - CallService(item->szService, wwParam, llParam); - else if (contactOK) - serviceFailure = TRUE; - } - else if (item->dwFlags & BUTTON_ISPROTOSERVICE && cfg::clcdat) { - if (contactOK) { - char *szProto = GetContactProto(hContact); - if (ProtoServiceExists(szProto, item->szService)) - ProtoCallService(szProto, item->szService, wwParam, llParam); - else - serviceFailure = TRUE; - } - } - else if (item->dwFlags & BUTTON_ISDBACTION) { - BYTE *pValue; - char *szModule = item->szModule; - char *szSetting = item->szSetting; - MCONTACT finalhContact = 0; - - if (item->dwFlags & BUTTON_ISCONTACTDBACTION || item->dwFlags & BUTTON_DBACTIONONCONTACT) { - contactOK = ServiceParamsOK(item, &wwParam, &llParam, hContact); - if (contactOK && item->dwFlags & BUTTON_ISCONTACTDBACTION) - szModule = GetContactProto(hContact); - finalhContact = hContact; - } - else - contactOK = 1; - - if (contactOK) { - BOOL fDelete = FALSE; - - if (item->dwFlags & BUTTON_ISTOGGLE) { - BOOL fChecked = (SendMessage(item->hWnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED); - - pValue = fChecked ? item->bValueRelease : item->bValuePush; - if (fChecked && pValue[0] == 0) - fDelete = TRUE; - } - else - pValue = item->bValuePush; - - if (fDelete) - db_unset(finalhContact, szModule, szSetting); - else { - switch (item->type) { - case DBVT_BYTE: - cfg::writeByte(finalhContact, szModule, szSetting, pValue[0]); - break; - case DBVT_WORD: - cfg::writeWord(finalhContact, szModule, szSetting, *((WORD *)&pValue[0])); - break; - case DBVT_DWORD: - cfg::writeDword(finalhContact, szModule, szSetting, *((DWORD *)&pValue[0])); - break; - case DBVT_ASCIIZ: - cfg::writeString(finalhContact, szModule, szSetting, (char *)pValue); - break; - } - } - } - else if (item->dwFlags & BUTTON_ISTOGGLE) - SendMessage(item->hWnd, BM_SETCHECK, 0, 0); - } - if (!contactOK) - MessageBox(0, TranslateT("The requested action requires a valid contact selection. Please select a contact from the contact list and repeat."), TranslateT("Parameter mismatch"), MB_OK); - if (serviceFailure) { - char szError[512]; - - mir_snprintf(szError, SIZEOF(szError), Translate("The service %s specified by the %s button definition was not found. You may need to install additional plugins."), item->szService, item->szName); - MessageBoxA(0, szError, Translate("Service failure"), MB_OK); - } - break; - } - item = item->nextItem; - } - goto buttons_done; - } - - switch (LOWORD(wParam)) { - case IDC_TBMENU: - case IDC_TBTOPMENU: - case IDC_STBTOPMENU: - { - RECT rc; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); - GetButtonRect(GetDlgItem(hwnd, LOWORD(wParam)), &rc); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, LOWORD(wParam) == IDC_TBMENU ? rc.top : rc.bottom, 0, hwnd, NULL); - } - return 0; - - case IDC_TBTOPSTATUS: - case IDC_STBTOPSTATUS: - case IDC_TBGLOBALSTATUS: - { - RECT rc; - HMENU hmenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - GetButtonRect(GetDlgItem(hwnd, LOWORD(wParam)), &rc); - TrackPopupMenu(hmenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, LOWORD(wParam) == IDC_TBGLOBALSTATUS ? rc.top : rc.bottom, 0, hwnd, NULL); - } - return 0; - - - case IDC_TBSOUND: - case IDC_STBSOUND: - cfg::dat.soundsOff = !cfg::dat.soundsOff; - cfg::writeByte("CLUI", "NoSounds", (BYTE)cfg::dat.soundsOff); - cfg::writeByte("Skin", "UseSound", (BYTE)(cfg::dat.soundsOff ? 0 : 1)); - return 0; - - case IDC_TBSELECTVIEWMODE: - case IDC_STBSELECTVIEWMODE: - SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_SELECTMODE, lParam); - break; - case IDC_TBCLEARVIEWMODE: - case IDC_STBCLEARVIEWMODE: - SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_RESETMODES, lParam); - break; - case IDC_TBCONFIGUREVIEWMODE: - case IDC_STBCONFIGUREVIEWMODE: - SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_CONFIGUREMODES, lParam); - break; - case IDC_TBFINDANDADD: - case IDC_STBFINDANDADD: - CallService(MS_FINDADD_FINDADD, 0, 0); - return 0; - case IDC_TBACCOUNTS: - case IDC_STBACCOUNTS: - CallService(MS_PROTO_SHOWACCMGR, 0, 0); - break; - case IDC_TBOPTIONS: - case IDC_STBOPTIONS: - CallService("Options/OptionsCommand", 0, 0); - return 0; - } - } - else if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), (LPARAM)(HANDLE)NULL)) - return 0; - -buttons_done: - switch (LOWORD(wParam)) { - case ID_TRAY_EXIT: - case ID_ICQ_EXIT: - cfg::shutDown = 1; - if (CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) - DestroyWindow(hwnd); - break; - case ID_TRAY_HIDE: - case IDC_TBMINIMIZE: - case IDC_STBMINIMIZE: - pcli->pfnShowHide(0, 0); - break; - case POPUP_NEWGROUP: - SendMessage(pcli->hwndContactTree, CLM_SETHIDEEMPTYGROUPS, 0, 0); - SendMessage(pcli->hwndContactTree, CLM_SETUSEGROUPS, 1, 0); - Clist_CreateGroup(NULL, NULL); - break; - case POPUP_HIDEOFFLINE: - case IDC_TBHIDEOFFLINE: - case IDC_STBHIDEOFFLINE: - CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)(-1), 0); - break; - case POPUP_HIDEOFFLINEROOT: - SendMessage(pcli->hwndContactTree, CLM_SETHIDEOFFLINEROOT, !SendMessage(pcli->hwndContactTree, CLM_GETHIDEOFFLINEROOT, 0, 0), 0); - break; - case POPUP_HIDEEMPTYGROUPS: - { - int newVal = !(GetWindowLongPtr(pcli->hwndContactTree, GWL_STYLE) & CLS_HIDEEMPTYGROUPS); - cfg::writeByte("CList", "HideEmptyGroups", (BYTE)newVal); - SendMessage(pcli->hwndContactTree, CLM_SETHIDEEMPTYGROUPS, newVal, 0); - } - break; - case IDC_TBHIDEGROUPS: - case IDC_STBHIDEGROUPS: - case POPUP_DISABLEGROUPS: - { - int newVal = !(GetWindowLongPtr(pcli->hwndContactTree, GWL_STYLE) & CLS_USEGROUPS); - cfg::writeByte("CList", "UseGroups", (BYTE)newVal); - SendMessage(pcli->hwndContactTree, CLM_SETUSEGROUPS, newVal, 0); - ClcSetButtonState(IDC_TBHIDEGROUPS, newVal); - SetButtonStates(hwnd); - } - break; - case POPUP_HIDEMIRANDA: - pcli->pfnShowHide(0, 0); - break; - case POPUP_SHOWMETAICONS: - cfg::dat.dwFlags ^= CLUI_USEMETAICONS; - pcli->pfnInitAutoRebuild(hwnd); - break; - case POPUP_FRAME: - cfg::dat.dwFlags ^= CLUI_FRAME_CLISTSUNKEN; - break; - case POPUP_BUTTONS: - cfg::dat.dwFlags ^= CLUI_FRAME_SHOWBOTTOMBUTTONS; - break; - case POPUP_SHOWSTATUSICONS: - cfg::dat.dwFlags ^= CLUI_FRAME_STATUSICONS; - break; - } - if (dwOldFlags != cfg::dat.dwFlags) { - InvalidateRect(pcli->hwndContactTree, NULL, FALSE); - cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags); - if ((dwOldFlags & (CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_CLISTSUNKEN)) != (cfg::dat.dwFlags & (CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_CLISTSUNKEN))) { - ConfigureFrame(); - ConfigureCLUIGeometry(1); - } - ConfigureEventArea(pcli->hwndContactList); - PostMessage(pcli->hwndContactList, WM_SIZE, 0, 0); - PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0); - } - } - return FALSE; - - case WM_LBUTTONDOWN: - if (g_ButtonItems) { - POINT ptMouse, pt; - - GetCursorPos(&ptMouse); - pt = ptMouse; - return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); - } - break; - - case WM_DISPLAYCHANGE: - SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0); //forces it to send a cln_listsizechanged - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->hwndFrom == pcli->hwndContactTree) { - switch (((LPNMHDR)lParam)->code) { - case CLN_LISTSIZECHANGE: - sttProcessResize(hwnd, (NMCLISTCONTROL *)lParam); - return FALSE; - - case NM_CLICK: - { - NMCLISTCONTROL *nm = (NMCLISTCONTROL *)lParam; - DWORD hitFlags; - HANDLE hItem; - - hItem = (HANDLE)SendMessage(pcli->hwndContactTree, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); - - if ((hitFlags & (CLCHT_NOWHERE | CLCHT_INLEFTMARGIN | CLCHT_BELOWITEMS)) == 0) - break; - if (cfg::getByte("CLUI", "ClientAreaDrag", SETTING_CLIENTDRAG_DEFAULT)) { - POINT pt; - pt = nm->pt; - ClientToScreen(pcli->hwndContactTree, &pt); - return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); - } - } - return FALSE; - } - } - break; - - case WM_CONTEXTMENU: - { - RECT rc; - POINT pt; - - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - // x/y might be -1 if it was generated by a kb click - GetWindowRect(pcli->hwndContactTree, &rc); - if (pt.x == -1 && pt.y == -1) { - // all this is done in screen-coords! - GetCursorPos(&pt); - // the mouse isnt near the window, so put it in the middle of the window - if (!PtInRect(&rc, pt)) { - pt.x = rc.left + (rc.right - rc.left) / 2; - pt.y = rc.top + (rc.bottom - rc.top) / 2; - } - } - if (PtInRect(&rc, pt)) { - HMENU hMenu; - hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDGROUP, 0, 0); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); - DestroyTrayMenu(hMenu); - return 0; - } - GetWindowRect(pcli->hwndStatus, &rc); - if (PtInRect(&rc, pt)) { - HMENU hMenu; - if (cfg::getByte("CLUI", "SBarRightClk", 0)) - hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); - else - hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); - return 0; - } - } - break; - - case WM_MEASUREITEM: - if (((LPMEASUREITEMSTRUCT)lParam)->itemData == MENU_MIRANDAMENU) { - ((LPMEASUREITEMSTRUCT)lParam)->itemWidth = g_cxsmIcon * 4 / 3; - ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = 0; - return TRUE; - } - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; - - if (hbmLockedPoint == 0) { - RECT rc = {0, 0, 5, 5}; - - hdcLockedPoint = CreateCompatibleDC(dis->hDC); - hbmLockedPoint = CreateCompatibleBitmap(dis->hDC, 5, 5); - hbmOldLockedPoint = reinterpret_cast(SelectObject(hdcLockedPoint, hbmLockedPoint)); - } - if (dis->hwndItem == pcli->hwndStatus) { - ProtocolData *pd = (ProtocolData *)dis->itemData; - if (IsBadCodePtr((FARPROC)pd)) - return TRUE; - if (cfg::shutDown) - return TRUE; - - int nParts = SendMessage(pcli->hwndStatus, SB_GETPARTS, 0, 0); - SIZE textSize; - BYTE showOpts = cfg::getByte("CLUI", "SBarShow", 1); - char *szProto = pd->RealName; - int status = CallProtoService(szProto, PS_GETSTATUS, 0, 0); - SetBkMode(dis->hDC, TRANSPARENT); - int x = dis->rcItem.left; - - if (showOpts & 1) { - HICON hIcon; - - if (status >= ID_STATUS_CONNECTING && status < ID_STATUS_OFFLINE) { - char szBuffer[128]; - mir_snprintf(szBuffer, SIZEOF(szBuffer), "%s_conn", pd->RealName); - hIcon = Skin_GetIcon(szBuffer); - } - else if (cfg::dat.bShowXStatusOnSbar && status > ID_STATUS_OFFLINE) { - int xStatus; - CUSTOM_STATUS cst = { sizeof(cst) }; - cst.flags = CSSF_MASK_STATUS; - cst.status = &xStatus; - if (ProtoServiceExists(pd->RealName, PS_GETCUSTOMSTATUSEX) && !ProtoCallService(pd->RealName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cst) && xStatus > 0) - hIcon = (HICON)CallProtoService(pd->RealName, PS_GETCUSTOMSTATUSICON, 0, LR_SHARED); // get OWN xStatus icon (if set) - else - hIcon = LoadSkinnedProtoIcon(szProto, status); - } - else - hIcon = LoadSkinnedProtoIcon(szProto, status); - - if (!(showOpts & 6) && cfg::dat.bEqualSections) - x = (dis->rcItem.left + dis->rcItem.right - 16) >> 1; - if (pd->protopos == 0) - x += (cfg::dat.bEqualSections ? (cfg::dat.bCLeft / 2) : cfg::dat.bCLeft); - else if (pd->protopos == nParts - 1) - x -= (cfg::dat.bCRight / 2); - DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - 16) >> 1, hIcon, 16, 16, 0, NULL, DI_NORMAL); - Skin_ReleaseIcon(hIcon); - - if (cfg::getByte("CLUI", "sbar_showlocked", 1)) { - if (cfg::getByte(szProto, "LockMainStatus", 0)) { - hIcon = LoadSkinnedIcon(SKINICON_OTHER_STATUS_LOCKED); - if (hIcon != NULL) { - DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - 16) >> 1, hIcon, 16, 16, 0, NULL, DI_NORMAL); - Skin_ReleaseIcon(hIcon); - } - } - } - x += 18; - } - else { - x += 2; - if (pd->protopos == 0) - x += (cfg::dat.bEqualSections ? (cfg::dat.bCLeft / 2) : cfg::dat.bCLeft); - else if (pd->protopos == nParts - 1) - x -= (cfg::dat.bCRight / 2); - } - - if (showOpts & 2) { - TCHAR szName[64]; - PROTOACCOUNT *pa = ProtoGetAccount(szProto); - if (pa) { - lstrcpyn(szName, pa->tszAccountName, SIZEOF(szName)); - szName[SIZEOF(szName) - 1] = 0; - } - else - szName[0] = 0; - - if (lstrlen(szName) < sizeof(szName) - 1) - lstrcat(szName, _T(" ")); - GetTextExtentPoint32(dis->hDC, szName, lstrlen(szName), &textSize); - TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szName, lstrlen(szName)); - x += textSize.cx; - } - if (showOpts & 4) { - TCHAR *szStatus = pcli->pfnGetStatusModeDescription(status, 0); - GetTextExtentPoint32(dis->hDC, szStatus, lstrlen(szStatus), &textSize); - TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szStatus, lstrlen(szStatus)); - } - } - else if (dis->CtlType == ODT_MENU) { - if (dis->itemData == MENU_MIRANDAMENU) - break; - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - } - return 0; - - case WM_CLOSE: - if (SETTING_WINDOWSTYLE_DEFAULT == cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT) && !cfg::getByte("CList", "AlwaysHideOnTB", 0)) { - PostMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); - return 0; - } - pcli->pfnShowHide(0, 0); - return 0; - - case CLUIINTM_REDRAW: - if (show_on_first_autosize) { - show_on_first_autosize = FALSE; - ShowCLUI(hwnd); - } - RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); - return 0; - - case CLUIINTM_STATUSBARUPDATE: - CluiProtocolStatusChanged(0, 0); - return 0; - - case WM_THEMECHANGED: - API::updateState(); - break; - - case WM_DESTROY: - if (cfg::dat.hdcBg) { - SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBgOld); - DeleteObject(cfg::dat.hbmBg); - DeleteDC(cfg::dat.hdcBg); - cfg::dat.hdcBg = NULL; - } - if (cfg::dat.bmpBackground) { - SelectObject(cfg::dat.hdcPic, cfg::dat.hbmPicOld); - DeleteDC(cfg::dat.hdcPic); - DeleteObject(cfg::dat.bmpBackground); - cfg::dat.bmpBackground = NULL; - } - FreeProtocolData(); - if (hdcLockedPoint) { - SelectObject(hdcLockedPoint, hbmOldLockedPoint); - DeleteObject(hbmLockedPoint); - DeleteDC(hdcLockedPoint); - } - // if this has not yet been set, do it now. - // indicates that clist is shutting down and prevents various things - // from happening at shutdown. - if (!cfg::shutDown) - cfg::shutDown = 1; - CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)hFrameContactTree, 0); - break; - } - - return coreCli.pfnContactListWndProc(hwnd, msg, wParam, lParam); -} - -#ifndef CS_DROPSHADOW -#define CS_DROPSHADOW 0x00020000 -#endif - -static int MetaChanged(WPARAM wParam, LPARAM lParam) -{ - pcli->pfnClcBroadcast(INTM_METACHANGEDEVENT, wParam, lParam); - return 0; -} - -static BOOL g_AboutDlgActive = 0; - -INT_PTR CALLBACK DlgProcAbout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - COLORREF url_visited = RGB(128, 0, 128); - COLORREF url_unvisited = RGB(0, 0, 255); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - int h; - HFONT hFont; - LOGFONT lf; - - g_AboutDlgActive = TRUE; - hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_GETFONT, 0, 0); - GetObject(hFont, sizeof(lf), &lf); - h = lf.lfHeight; - lf.lfHeight = (int)(lf.lfHeight * 1.5); - lf.lfWeight = FW_BOLD; - hFont = CreateFontIndirect(&lf); - SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_SETFONT, (WPARAM)hFont, 0); - lf.lfHeight = h; - hFont = CreateFontIndirect(&lf); - SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, (WPARAM)hFont, 0); - } - { - char str[64]; - DWORD v = pluginInfo.version; - mir_snprintf(str, sizeof(str), "%s %d.%d.%d.%d", Translate("Version"), HIBYTE(HIWORD(v)), LOBYTE(HIWORD(v)), HIBYTE(LOWORD(v)), LOBYTE(LOWORD(v))); - SetDlgItemTextA(hwndDlg, IDC_VERSION, str); - } - { - HICON hIcon = LoadIcon(GetModuleHandleA("miranda32.exe"), MAKEINTRESOURCE(102)); - SendDlgItemMessage(hwndDlg, IDC_LOGO, STM_SETICON, (WPARAM)hIcon, 0); - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); - DestroyIcon(hIcon); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - case IDCANCEL: - DestroyWindow(hwndDlg); - return TRUE; - case IDC_SUPPORT: - CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://miranda-ng.org/"); - break; - } - break; - - case WM_CTLCOLOREDIT: - case WM_CTLCOLORSTATIC: - if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_WHITERECT) - || (HWND)lParam == GetDlgItem(hwndDlg, IDC_CLNICER) - || (HWND)lParam == GetDlgItem(hwndDlg, IDC_VERSION) - || (HWND)lParam == GetDlgItem(hwndDlg, IDC_COPYRIGHT) - || (HWND)lParam == GetDlgItem(hwndDlg, IDC_SUPPORT) - || (HWND)lParam == GetDlgItem(hwndDlg, IDC_LOGO)) - { - if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_CLNICER)) - SetTextColor((HDC)wParam, RGB(180, 10, 10)); - else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_VERSION)) - SetTextColor((HDC)wParam, RGB(70, 70, 70)); - else - SetTextColor((HDC)wParam, RGB(0, 0, 0)); - SetBkColor((HDC)wParam, RGB(255, 255, 255)); - return (INT_PTR)GetStockObject(WHITE_BRUSH); - } - break; - - case WM_DESTROY: - { - HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_GETFONT, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0), 0); - DeleteObject(hFont); - hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_GETFONT, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0), 0); - DeleteObject(hFont); - g_AboutDlgActive = FALSE; - } - break; - } - return FALSE; -} - -static INT_PTR CLN_ShowAbout(WPARAM wParam, LPARAM lParam) -{ - if (!g_AboutDlgActive) - CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CLNABOUT), 0, DlgProcAbout, 0); - return 0; -} - -static INT_PTR CLN_ShowMainMenu(WPARAM wParam, LPARAM lParam) -{ - HMENU hMenu; - POINT pt; - - hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); - GetCursorPos(&pt); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL); - return 0; -} - -static INT_PTR CLN_ShowStatusMenu(WPARAM wParam, LPARAM lParam) -{ - HMENU hMenu; - POINT pt; - - hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - GetCursorPos(&pt); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL); - return 0; -} - -#define MS_CLUI_SHOWMAINMENU "CList/ShowMainMenu" -#define MS_CLUI_SHOWSTATUSMENU "CList/ShowStatusMenu" - -void LoadCLUIModule(void) -{ - HookEvent(ME_SYSTEM_MODULESLOADED, CluiModulesLoaded); - - WNDCLASS wndclass; - wndclass.style = 0; - wndclass.lpfnWndProc = EventAreaWndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = 0; - wndclass.hInstance = g_hInst; - wndclass.hIcon = 0; - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.hbrBackground = (HBRUSH)COLOR_3DFACE; - wndclass.lpszMenuName = 0; - wndclass.lpszClassName = _T("EventAreaClass"); - RegisterClass(&wndclass); - - oldhideoffline = cfg::getByte("CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT); - cluiPos.left = cfg::getDword("CList", "x", 600); - cluiPos.top = cfg::getDword("CList", "y", 200); - cluiPos.right = cfg::getDword("CList", "Width", 150); - cluiPos.bottom = cfg::getDword("CList", "Height", 350); - - LoadExtraIconModule(); - LoadCLUIFramesModule(); - - CreateServiceFunction("CLN/About", CLN_ShowAbout); - CreateServiceFunction(MS_CLUI_SHOWMAINMENU, CLN_ShowMainMenu); - CreateServiceFunction(MS_CLUI_SHOWSTATUSMENU, CLN_ShowStatusMenu); - - if (cfg::getByte("CLUI", "FloaterMode", 0)) { - MessageBox(NULL, - TranslateT("You need the FloatingContacts plugin, cause the embedded floating contacts were removed."), - TranslateT("Warning"), MB_OK | MB_ICONWARNING); - db_unset(NULL, "CLUI", "FloaterMode"); - } -} - -void OnCreateClc() -{ - HookEvent(ME_MC_DEFAULTTCHANGED, MetaChanged); - HookEvent(ME_MC_SUBCONTACTSCHANGED, MetaChanged); - - InitGroupMenus(); - LoadExtBkSettingsFromDB(); - PreCreateCLC(pcli->hwndContactList); -} - -struct -{ - const TCHAR *tszName; - int iMask; -} -static clistFontDescr[] = { - { LPGENT("Standard contacts"), FIDF_CLASSGENERAL }, - { LPGENT("Online contacts to whom you have a different visibility"), FIDF_CLASSGENERAL }, - { LPGENT("Offline contacts"), FIDF_CLASSGENERAL }, - { LPGENT("Contacts which are 'not on list'"), FIDF_CLASSGENERAL }, - { LPGENT("Groups"), FIDF_CLASSHEADER }, - { LPGENT("Group member counts"), FIDF_CLASSHEADER }, - { LPGENT("Dividers"), FIDF_CLASSSMALL }, - { LPGENT("Offline contacts to whom you have a different visibility"), FIDF_CLASSGENERAL }, - { LPGENT("Status mode"), FIDF_CLASSGENERAL }, - { LPGENT("Frame titles"), FIDF_CLASSGENERAL }, - { LPGENT("Event area"), FIDF_CLASSGENERAL }, - { LPGENT("Contact list local time"), FIDF_CLASSGENERAL } -}; - -void FS_RegisterFonts() -{ - FontIDT fid = { sizeof(fid) }; - _tcsncpy(fid.group, LPGENT("Contact list"), SIZEOF(fid.group)); - strncpy(fid.dbSettingsGroup, "CLC", 5); - fid.flags = FIDF_DEFAULTVALID | FIDF_ALLOWEFFECTS | FIDF_APPENDNAME | FIDF_SAVEPOINTSIZE; - - HDC hdc = GetDC(NULL); - for (int i = 0; i < SIZEOF(clistFontDescr); i++) { - LOGFONT lf; - pcli->pfnGetFontSetting(i, &lf, &fid.deffontsettings.colour); - lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72); - - _tcsncpy_s(fid.deffontsettings.szFace, lf.lfFaceName, _TRUNCATE); - fid.deffontsettings.charset = lf.lfCharSet; - fid.deffontsettings.size = (char)lf.lfHeight; - fid.deffontsettings.style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0); - - fid.flags &= ~FIDF_CLASSMASK; - fid.flags |= clistFontDescr[i].iMask; - - _tcsncpy(fid.name, clistFontDescr[i].tszName, SIZEOF(fid.name)); - - char idstr[10]; - mir_snprintf(idstr, SIZEOF(idstr), "Font%d", i); - strncpy(fid.prefix, idstr, SIZEOF(fid.prefix)); - fid.order = i; - FontRegisterT(&fid); - } - ReleaseDC(NULL, hdc); - - // and colours - ColourIDT colourid = {0}; - colourid.cbSize = sizeof(colourid); - colourid.order = 0; - strncpy(colourid.dbSettingsGroup, "CLC", sizeof(colourid.dbSettingsGroup)); - - strncpy(colourid.setting, "BkColour", sizeof(colourid.setting)); - _tcsncpy(colourid.name, LPGENT("Background"), SIZEOF(colourid.name)); - _tcsncpy(colourid.group, LPGENT("Contact list"), SIZEOF(colourid.group)); - colourid.defcolour = CLCDEFAULT_BKCOLOUR; - ColourRegisterT(&colourid); - - strncpy(colourid.setting, "SelTextColour", sizeof(colourid.setting)); - _tcsncpy(colourid.name, LPGENT("Selected text"), SIZEOF(colourid.name)); - colourid.order = 1; - colourid.defcolour = CLCDEFAULT_SELTEXTCOLOUR; - ColourRegisterT(&colourid); - - strncpy(colourid.setting, "HotTextColour", sizeof(colourid.setting)); - _tcsncpy(colourid.name, LPGENT("Hottrack text"), SIZEOF(colourid.name)); - colourid.order = 1; - colourid.defcolour = CLCDEFAULT_HOTTEXTCOLOUR; - ColourRegisterT(&colourid); - - strncpy(colourid.setting, "QuickSearchColour", sizeof(colourid.setting)); - _tcsncpy(colourid.name, LPGENT("Quicksearch text"), SIZEOF(colourid.name)); - colourid.order = 1; - colourid.defcolour = CLCDEFAULT_QUICKSEARCHCOLOUR; - ColourRegisterT(&colourid); - - strncpy(colourid.dbSettingsGroup, "CLUI", sizeof(colourid.dbSettingsGroup)); - strncpy(colourid.setting, "clr_frameborder", sizeof(colourid.setting)); - _tcsncpy(colourid.name, LPGENT("Embedded frames border"), SIZEOF(colourid.name)); - colourid.order = 1; - colourid.defcolour = RGB(40, 40, 40); - ColourRegisterT(&colourid); -} +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-03 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 +#include +#include "../cluiframes/cluiframes.h" +#include "../coolsb/coolscroll.h" + +#define TM_AUTOALPHA 1 +#define TIMERID_AUTOSIZE 100 +#define MENU_MIRANDAMENU 0xFFFF1234 + +int g_fading_active = 0; + +static RECT g_PreSizeRect, g_SizingRect; +static int g_sizingmethod; +static LONG g_CLUI_x_off, g_CLUI_y_off, g_CLUI_y1_off, g_CLUI_x1_off; +static RECT rcWPC; + +static int transparentFocus = 1; +static byte oldhideoffline; +static int disableautoupd = 1; +HANDLE hFrameContactTree; +extern HIMAGELIST hCListImages; +extern PLUGININFOEX pluginInfo; +extern RECT old_window_rect, new_window_rect; + +extern BOOL g_trayTooltipActive; +extern POINT tray_hover_pos; +extern HWND g_hwndViewModeFrame, g_hwndEventArea, g_hwndToolbarFrame; + +extern ImageItem *g_CLUIImageItem; +extern HBRUSH g_CLUISkinnedBkColor; +extern HWND g_hwndSFL; +extern ButtonItem *g_ButtonItems; +extern COLORREF g_CLUISkinnedBkColorRGB; +extern FRAMEWND *wndFrameCLC; +extern HPEN g_hPenCLUIFrames; + +static BYTE old_cliststate, show_on_first_autosize = FALSE; + +RECT cluiPos; + +TCHAR *statusNames[12]; + +extern LRESULT CALLBACK EventAreaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern HANDLE hNotifyFrame; + +int SortList(WPARAM wParam, LPARAM lParam); +int LoadCluiServices(void); +void InitGroupMenus(); +void FS_RegisterFonts(); +void LoadExtraIconModule(); +void RemoveFromTaskBar(HWND hWnd); +void DestroyTrayMenu(HMENU hMenu); + +extern LONG g_cxsmIcon, g_cysmIcon; + +SIZE g_oldSize = {0}; +POINT g_oldPos = {0}; +int during_sizing = 0; +extern int dock_prevent_moving; + +static HDC hdcLockedPoint = 0; +static HBITMAP hbmLockedPoint = 0, hbmOldLockedPoint = 0; + +HICON overlayicons[10]; + +static IconItem myIcons[] = { + { LPGEN("Toggle show online/offline"), "CLN_online", IDI_HIDEOFFLINE }, + { LPGEN("Toggle groups"), "CLN_groups", IDI_HIDEGROUPS }, + { LPGEN("Find contacts"), "CLN_findadd", IDI_FINDANDADD }, + { LPGEN("Open preferences"), "CLN_options", IDI_TBOPTIONS }, + { LPGEN("Toggle sounds"), "CLN_sound", IDI_SOUNDSON }, + { LPGEN("Minimize contact list"), "CLN_minimize", IDI_MINIMIZE }, + { LPGEN("Show TabSRMM session list"), "CLN_slist", IDI_TABSRMMSESSIONLIST }, + { LPGEN("Show TabSRMM menu"), "CLN_menu", IDI_TABSRMMMENU }, + { LPGEN("Sounds are off"), "CLN_soundsoff", IDI_SOUNDSOFF }, + { LPGEN("Select view mode"), "CLN_CLVM_select", IDI_CLVM_SELECT }, + { LPGEN("Reset view mode"), "CLN_CLVM_reset", IDI_DELETE }, + { LPGEN("Configure view modes"), "CLN_CLVM_options", IDI_CLVM_OPTIONS }, + { LPGEN("Show menu"), "CLN_topmenu", IDI_TBTOPMENU }, + { LPGEN("Setup accounts"), "CLN_accounts", IDI_TBACCOUNTS } +}; + +HWND hTbMenu, hTbGlobalStatus; + +static void Tweak_It(COLORREF clr) +{ + SetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED); + SetLayeredWindowAttributes(pcli->hwndContactList, clr, 0, LWA_COLORKEY); + cfg::dat.colorkey = clr; +} + +static void LayoutButtons(HWND hwnd, RECT *rc) +{ + RECT rect; + BYTE rightButton = 1, leftButton = 0; + BYTE left_offset = cfg::dat.bCLeft - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0); + BYTE right_offset = cfg::dat.bCRight - (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN ? 3 : 0); + BYTE delta = left_offset + right_offset; + ButtonItem *btnItems = g_ButtonItems; + + if (rc == NULL) + GetClientRect(hwnd, &rect); + else + rect = *rc; + + rect.bottom -= cfg::dat.bCBottom; + + if (g_ButtonItems) { + while (btnItems) { + LONG x = (btnItems->xOff >= 0) ? rect.left + btnItems->xOff : rect.right - abs(btnItems->xOff); + LONG y = (btnItems->yOff >= 0) ? rect.top + btnItems->yOff : rect.bottom - cfg::dat.statusBarHeight; + + SetWindowPos(btnItems->hWnd, 0, x, y, btnItems->width, btnItems->height, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW); + btnItems = btnItems->nextItem; + } + } + + SetWindowPos(hTbMenu, 0, 2 + left_offset, rect.bottom - cfg::dat.statusBarHeight - 21 - 1, + 21 * 3, 21 + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW); + + SetWindowPos(hTbGlobalStatus, 0, left_offset + (3 * 21) + 3, rect.bottom - cfg::dat.statusBarHeight - 21 - 1, + rect.right - delta - (3 * 21 + 5), 21 + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOREDRAW); + +} + +static int FS_FontsChanged(WPARAM wParam, LPARAM lParam) +{ + COLORREF clr_cluiframes = cfg::getDword("CLUI", "clr_frameborder", RGB(40, 40, 40)); + + if (g_hPenCLUIFrames) + DeleteObject(g_hPenCLUIFrames); + g_hPenCLUIFrames = CreatePen(PS_SOLID, 1, clr_cluiframes); + + pcli->pfnClcOptionsChanged(); + RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); + return 0; +} + +// create the CLC control, but not yet the frame. The frame containing the CLC should be created as the +// last frame of all. +static HWND PreCreateCLC(HWND parent) +{ + pcli->hwndContactTree = CreateWindow(_T(CLISTCONTROL_CLASS), _T(""), + WS_CHILD | CLS_CONTACTLIST + | (cfg::getByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ? CLS_USEGROUPS : 0) + | CLS_HIDEOFFLINE + //| (db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ? CLS_HIDEOFFLINE : 0) + | (cfg::getByte(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) ? CLS_HIDEEMPTYGROUPS : 0) + | CLS_MULTICOLUMN, + 0, 0, 0, 0, parent, NULL, g_hInst, (LPVOID)0xff00ff00); + + cfg::clcdat = (struct ClcData *)GetWindowLongPtr(pcli->hwndContactTree, 0); + return pcli->hwndContactTree; +} + +// create internal frames, including the last frame (actual CLC control) +static int CreateCLC(HWND parent) +{ + pcli->pfnReloadExtraIcons(); + CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)oldhideoffline, 0); + disableautoupd = 0; + + { + CLISTFrame frame = {0}; + frame.cbSize = sizeof(frame); + frame.tname = _T("EventArea"); + frame.TBtname = TranslateT("Event area"); + frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_FRAME); + frame.height = 20; + frame.Flags = F_VISIBLE | F_SHOWTBTIP | F_NOBORDER | F_TCHAR; + frame.align = alBottom; + frame.hWnd = CreateWindowExA(0, "EventAreaClass", "evt", WS_VISIBLE | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, pcli->hwndContactList, (HMENU)0, g_hInst, NULL); + g_hwndEventArea = frame.hWnd; + hNotifyFrame = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&frame, 0); + CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)hNotifyFrame, FU_FMPOS); + HideShowNotifyFrame(); + CreateViewModeFrame(); + } + + { + CLISTFrame Frame = {0}; + memset(&Frame, 0, sizeof(Frame)); + Frame.cbSize = sizeof(CLISTFrame); + Frame.hWnd = pcli->hwndContactTree; + Frame.align = alClient; + Frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_FRAME); + Frame.Flags = F_VISIBLE | F_SHOWTB | F_SHOWTBTIP | F_NOBORDER | F_TCHAR; + Frame.tname = _T("My contacts"); + Frame.TBtname = TranslateT("My contacts"); + Frame.height = 200; + hFrameContactTree = (HWND)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0); + //free(Frame.name); + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_TBTIPNAME, hFrameContactTree), (LPARAM)Translate("My contacts")); + + // ugly, but working hack. Prevent that annoying little scroll bar from appearing in the "My Contacts" title bar + DWORD flags = (DWORD)CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hFrameContactTree), 0); + flags |= F_VISIBLE; + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hFrameContactTree), flags); + } + + SetButtonToSkinned(); + return 0; +} + +static int CluiModulesLoaded(WPARAM, LPARAM) +{ + FS_RegisterFonts(); + HookEvent(ME_FONT_RELOAD, FS_FontsChanged); + return 0; +} + +static HICON hIconSaved = 0; + +void ClearIcons(int mode) +{ + for (int i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) { + if (overlayicons[i - IDI_OVL_OFFLINE] != 0) { + if (mode) + DestroyIcon(overlayicons[i - IDI_OVL_OFFLINE]); + overlayicons[i - IDI_OVL_OFFLINE] = 0; + } + } +} + +static void CacheClientIcons() +{ + ClearIcons(0); + + for (int i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) { + char szBuffer[128]; + mir_snprintf(szBuffer, sizeof(szBuffer), "cln_ovl_%d", ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE)); + overlayicons[i - IDI_OVL_OFFLINE] = Skin_GetIcon(szBuffer); + } +} + +static void InitIcoLib() +{ + Icon_Register(g_hInst, LPGEN("Contact list")"/"LPGEN("Default"), myIcons, SIZEOF(myIcons)); + + for (int i = IDI_OVL_OFFLINE; i <= IDI_OVL_OUTTOLUNCH; i++) { + char szBuffer[128]; + mir_snprintf(szBuffer, sizeof(szBuffer), "cln_ovl_%d", ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE)); + IconItemT icon = { pcli->pfnGetStatusModeDescription(ID_STATUS_OFFLINE + (i - IDI_OVL_OFFLINE), GSMDF_TCHAR), szBuffer, i }; + Icon_RegisterT(g_hInst, LPGENT("Contact list")_T("/")LPGENT("Overlay icons"), &icon, 1); + } + + PROTOACCOUNT **accs = NULL; + int p_count = 0; + ProtoEnumAccounts(&p_count, &accs); + for (int k = 0; k < p_count; k++) { + if (!IsAccountEnabled(accs[k]) || CallProtoService(accs[k]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) == 0) + continue; + + TCHAR szDescr[128]; + mir_sntprintf(szDescr, SIZEOF(szDescr), TranslateT("%s connecting"), accs[k]->tszAccountName); + IconItemT icon = { szDescr, "conn", IDI_PROTOCONNECTING }; + Icon_RegisterT(g_hInst, LPGENT("Contact list")_T("/")LPGENT("Connecting icons"), &icon, 1, accs[k]->szModuleName); + } +} + +static int IcoLibChanged(WPARAM, LPARAM) +{ + IcoLibReloadIcons(); + return 0; +} + +void CreateButtonBar(HWND hWnd) +{ + hTbMenu = CreateWindowEx(0, MIRANDABUTTONCLASS, _T(""), BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, hWnd, (HMENU)IDC_TBMENU, g_hInst, NULL); + CustomizeButton(hTbMenu, false, false, false); + SetWindowText(hTbMenu, TranslateT("Menu")); + SendMessage(hTbMenu, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MAINMENU)); + SendMessage(hTbMenu, BUTTONSETSENDONDOWN, TRUE, 0); + SendMessage(hTbMenu, BUTTONADDTOOLTIP, (WPARAM)LPGEN("Open main menu"), 0); + + hTbGlobalStatus = CreateWindowEx(0, MIRANDABUTTONCLASS, _T(""), BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 0, 0, 20, 20, hWnd, (HMENU)IDC_TBGLOBALSTATUS, g_hInst, NULL); + CustomizeButton(hTbGlobalStatus, false, false, false); + SetWindowText(hTbGlobalStatus, TranslateT("Offline")); + SendMessage(hTbGlobalStatus, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_STATUS_OFFLINE)); + SendMessage(hTbGlobalStatus, BUTTONSETSENDONDOWN, TRUE, 0); + SendMessage(hTbGlobalStatus, BUTTONADDTOOLTIP, (WPARAM)LPGEN("Set status modes"), 0); +} + +// if mode != 0 we do first time init, otherwise only reload the extra icon stuff +void CLN_LoadAllIcons(BOOL mode) +{ + if (mode) { + InitIcoLib(); + HookEvent(ME_SKIN2_ICONSCHANGED, IcoLibChanged); + } + CacheClientIcons(); +} + +void ConfigureEventArea(HWND hwnd) +{ + int iCount = GetMenuItemCount(cfg::dat.hMenuNotify); + DWORD dwFlags = cfg::dat.dwFlags; + int oldstate = cfg::dat.notifyActive; + int dwVisible = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, hNotifyFrame), 0) & F_VISIBLE; + + if (dwVisible) { + if (dwFlags & CLUI_FRAME_AUTOHIDENOTIFY) + cfg::dat.notifyActive = iCount > 0 ? 1 : 0; + else + cfg::dat.notifyActive = 1; + } + else + cfg::dat.notifyActive = 0; + + if (oldstate != cfg::dat.notifyActive) + HideShowNotifyFrame(); +} + +void ConfigureFrame() +{ + int show = cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? SW_SHOW : SW_HIDE; + ShowWindow(hTbMenu,show); + ShowWindow(hTbGlobalStatus, show); +} + +void IcoLibReloadIcons() +{ + CacheClientIcons(); + pcli->pfnReloadExtraIcons(); + pcli->pfnSetAllExtraIcons(NULL); + + pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0); + SendMessage(g_hwndViewModeFrame, WM_USER + 100, 0, 0); +} + +void ConfigureCLUIGeometry(int mode) +{ + RECT rcStatus; + DWORD clmargins = cfg::getDword("CLUI", "clmargins", 0); + + cfg::dat.bCLeft = LOBYTE(LOWORD(clmargins)); + cfg::dat.bCRight = HIBYTE(LOWORD(clmargins)); + cfg::dat.bCTop = LOBYTE(HIWORD(clmargins)); + cfg::dat.bCBottom = HIBYTE(HIWORD(clmargins)); + + if (mode) { + if (cfg::dat.dwFlags & CLUI_FRAME_SBARSHOW) { + SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0); + GetWindowRect(pcli->hwndStatus, &rcStatus); + cfg::dat.statusBarHeight = (rcStatus.bottom - rcStatus.top); + } + else + cfg::dat.statusBarHeight = 0; + } + + cfg::dat.topOffset = cfg::dat.bCTop; + cfg::dat.bottomOffset = (cfg::dat.dwFlags & CLUI_FRAME_SHOWBOTTOMBUTTONS ? 2 + 21 : 0) + cfg::dat.bCBottom; + + if (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN) { + cfg::dat.topOffset += 2; + cfg::dat.bottomOffset += 2; + cfg::dat.bCLeft += 3; + cfg::dat.bCRight += 3; + } +} + +// set the states of defined database action buttons (only if button is a toggle) +void SetDBButtonStates(MCONTACT hPassedContact) +{ + ButtonItem *buttonItem = g_ButtonItems; + MCONTACT hContact = 0, hFinalContact = 0; + char *szModule, *szSetting; + ClcContact *contact = 0; + + if (cfg::clcdat && hPassedContact == 0) { + pcli->pfnGetRowByIndex(cfg::clcdat, cfg::clcdat->selection, &contact, NULL); + if (contact && contact->type == CLCIT_CONTACT) { + hContact = contact->hContact; + } + } + + while (buttonItem) { + BOOL result = FALSE; + + if (!(buttonItem->dwFlags & BUTTON_ISTOGGLE && buttonItem->dwFlags & BUTTON_ISDBACTION)) { + buttonItem = buttonItem->nextItem; + continue; + } + szModule = buttonItem->szModule; + szSetting = buttonItem->szSetting; + if (buttonItem->dwFlags & BUTTON_DBACTIONONCONTACT || buttonItem->dwFlags & BUTTON_ISCONTACTDBACTION) { + if (hContact == 0) { + SendMessage(buttonItem->hWnd, BM_SETCHECK, BST_UNCHECKED, 0); + buttonItem = buttonItem->nextItem; + continue; + } + if (buttonItem->dwFlags & BUTTON_ISCONTACTDBACTION) + szModule = GetContactProto(hContact); + hFinalContact = hContact; + } + else + hFinalContact = 0; + + if (buttonItem->type == DBVT_ASCIIZ) { + DBVARIANT dbv = {0}; + + if (!cfg::getString(hFinalContact, szModule, szSetting, &dbv)) { + result = !strcmp((char *)buttonItem->bValuePush, dbv.pszVal); + db_free(&dbv); + } + } + else { + switch (buttonItem->type) { + case DBVT_BYTE: { + BYTE val = cfg::getByte(hFinalContact, szModule, szSetting, 0); + result = (val == buttonItem->bValuePush[0]); + break; + } + case DBVT_WORD: { + WORD val = cfg::getWord(hFinalContact, szModule, szSetting, 0); + result = (val == *((WORD *)&buttonItem->bValuePush)); + break; + } + case DBVT_DWORD: { + DWORD val = cfg::getDword(hFinalContact, szModule, szSetting, 0); + result = (val == *((DWORD *)&buttonItem->bValuePush)); + break; + } + } + } + SendMessage(buttonItem->hWnd, BM_SETCHECK, (WPARAM)result, 0); + buttonItem = buttonItem->nextItem; + } +} + +// set states of standard buttons (pressed/unpressed) +void SetButtonStates(HWND hwnd) +{ + ButtonItem *buttonItem = g_ButtonItems; + + if (g_ButtonItems) { + while (buttonItem) { + if (buttonItem->dwFlags & BUTTON_ISINTERNAL) { + switch (buttonItem->uId) { + case IDC_STBSOUND: + SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::dat.soundsOff ? BST_CHECKED : BST_UNCHECKED, 0); + break; + case IDC_STBHIDEOFFLINE: + SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::getByte("CList", "HideOffline", 0) ? BST_CHECKED : BST_UNCHECKED, 0); + break; + case IDC_STBHIDEGROUPS: + SendMessage(buttonItem->hWnd, BM_SETCHECK, cfg::getByte("CList", "UseGroups", 0) ? BST_CHECKED : BST_UNCHECKED, 0); + break; + } + } + buttonItem = buttonItem->nextItem; + } + } +} + +void BlitWallpaper(HDC hdc, RECT *rc, RECT *rcPaint, struct ClcData *dat) +{ + int x, y; + int bitx, bity; + int maxx, maxy; + int destw, desth, height, width; + BITMAP *bmp = &cfg::dat.bminfoBg; + LONG clip = cfg::dat.bClipBorder; + + if (dat == 0) + return; + + SetStretchBltMode(hdc, HALFTONE); + + y = rc->top; + + rc->left = max(rc->left, clip); + rc->right = min(rc->right - clip, rc->right); + rc->top = max(rc->top, clip); + rc->bottom = min(rc->bottom - clip, rc->bottom); + + width = rc->right - rc->left; + height = rc->bottom - rc->top; + HRGN my_rgn = CreateRectRgn(rc->left, rc->top, rc->right, rc->bottom); + SelectClipRgn(hdc, my_rgn); + maxx = dat->backgroundBmpUse & CLBF_TILEH ? rc->right : rc->left + 1; + maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rc->bottom : y + 1; + switch (dat->backgroundBmpUse & CLBM_TYPE) { + case CLB_STRETCH: + if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { + if (width * bmp->bmHeight < height * bmp->bmWidth) { + desth = height; + destw = desth * bmp->bmWidth / bmp->bmHeight; + } + else { + destw = width; + desth = destw * bmp->bmHeight / bmp->bmWidth; + } + } + else { + destw = width; + desth = height; + } + break; + case CLB_STRETCHH: + if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { + destw = width; + desth = destw * bmp->bmHeight / bmp->bmWidth; + } + else { + destw = width; + desth = bmp->bmHeight; + } + break; + case CLB_STRETCHV: + if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { + desth = height; + destw = desth * bmp->bmWidth / bmp->bmHeight; + } + else { + destw = bmp->bmWidth; + desth = height; + } + break; + default: + //clb_topleft + destw = bmp->bmWidth; + desth = bmp->bmHeight; + break; + } + + bitx = 0; + bity = 0; + for (; y < maxy; y += desth) { + for (x = rc->left; x < maxx; x += destw) + StretchBlt(hdc, x, y, destw, desth, cfg::dat.hdcPic, bitx, bity, bmp->bmWidth, bmp->bmHeight, SRCCOPY); + } + SelectClipRgn(hdc, NULL); + DeleteObject(my_rgn); +} + +void ReloadThemedOptions() +{ + cfg::dat.bSkinnedStatusBar = cfg::getByte("CLUI", "sb_skinned", 0); + cfg::dat.bUsePerProto = cfg::getByte("CLCExt", "useperproto", 0); + cfg::dat.bOverridePerStatusColors = cfg::getByte("CLCExt", "override_status", 0); + cfg::dat.bRowSpacing = cfg::getByte("CLC", "RowGap", 0); + cfg::dat.bApplyIndentToBg = cfg::getByte("CLCExt", "applyindentbg", 0); + cfg::dat.bWallpaperMode = cfg::getByte("CLUI", "UseBkSkin", 1); + cfg::dat.bClipBorder = cfg::getByte("CLUI", "clipborder", 0); + cfg::dat.cornerRadius = cfg::getByte("CLCExt", "CornerRad", 6); + cfg::dat.gapBetweenFrames = (BYTE)cfg::getDword("CLUIFrames", "GapBetweenFrames", 1); + cfg::dat.bUseDCMirroring = cfg::getByte("CLC", "MirrorDC", 0); + cfg::dat.bGroupAlign = cfg::getByte("CLC", "GroupAlign", 0); + if (cfg::dat.hBrushColorKey) + DeleteObject(cfg::dat.hBrushColorKey); + cfg::dat.hBrushColorKey = CreateSolidBrush(RGB(255, 0, 255)); + cfg::dat.bWantFastGradients = cfg::getByte("CLCExt", "FastGradients", 0); + cfg::dat.titleBarHeight = cfg::getByte("CLCExt", "frame_height", DEFAULT_TITLEBAR_HEIGHT); + cfg::dat.group_padding = cfg::getDword("CLCExt", "grp_padding", 0); +} + +static RECT rcWindow = {0}; + +static void sttProcessResize(HWND hwnd, NMCLISTCONTROL *nmc) +{ + RECT rcTree, rcWorkArea, rcOld; + int maxHeight, newHeight; + int winstyle, skinHeight = 0; + + if (disableautoupd) + return; + + if (!cfg::getByte("CLUI", "AutoSize", 0)) + return; + + if (Docking_IsDocked(0, 0)) + return; + if (hFrameContactTree == 0) + return; + + maxHeight = cfg::getByte("CLUI", "MaxSizeHeight", 75); + rcOld = rcWindow; + + GetWindowRect(hwnd, &rcWindow); + GetWindowRect(pcli->hwndContactTree, &rcTree); + winstyle = GetWindowLongPtr(pcli->hwndContactTree, GWL_STYLE); + + SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); + HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi; + mi.cbSize = sizeof(mi); + if (GetMonitorInfo(hMon, &mi)) + rcWorkArea = mi.rcWork; + + if (nmc->pt.y > (rcWorkArea.bottom - rcWorkArea.top)) { + nmc->pt.y = (rcWorkArea.bottom - rcWorkArea.top); + } + + if (winstyle & CLS_SKINNEDFRAME) { + BOOL hasTitleBar = wndFrameCLC ? wndFrameCLC->TitleBar.ShowTitleBar : 0; + StatusItems_t *item = arStatusItems[(hasTitleBar ? ID_EXTBKOWNEDFRAMEBORDERTB : ID_EXTBKOWNEDFRAMEBORDER) - ID_STATUS_OFFLINE]; + skinHeight = item->IGNORED ? 0 : item->MARGIN_BOTTOM + item->MARGIN_TOP; + } + + newHeight = max(nmc->pt.y, 3) + 1 + ((winstyle & WS_BORDER) ? 2 : 0) + skinHeight + (rcWindow.bottom - rcWindow.top) - (rcTree.bottom - rcTree.top); + if (newHeight == (rcWindow.bottom - rcWindow.top) && show_on_first_autosize == FALSE) + return; + + if (newHeight > (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100) + newHeight = (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100; + if (cfg::getByte("CLUI", "AutoSizeUpward", 0)) { + rcWindow.top = rcWindow.bottom - newHeight; + if (rcWindow.top < rcWorkArea.top) rcWindow.top = rcWorkArea.top; + } + else { + rcWindow.bottom = rcWindow.top + newHeight; + if (rcWindow.bottom > rcWorkArea.bottom) rcWindow.bottom = rcWorkArea.bottom; + } + if (cfg::dat.szOldCTreeSize.cx != rcTree.right - rcTree.left) { + cfg::dat.szOldCTreeSize.cx = rcTree.right - rcTree.left; + return; + } + KillTimer(hwnd, TIMERID_AUTOSIZE); + SetTimer(hwnd, TIMERID_AUTOSIZE, 100, 0); +} + +int CustomDrawScrollBars(NMCSBCUSTOMDRAW *nmcsbcd) +{ + switch (nmcsbcd->hdr.code) { + case NM_COOLSB_CUSTOMDRAW: + static HDC hdcScroll = 0; + static HBITMAP hbmScroll, hbmScrollOld; + static LONG scrollLeft, scrollRight, scrollHeight, scrollYmin, scrollYmax; + + switch (nmcsbcd->dwDrawStage) { + case CDDS_PREPAINT: + if (cfg::dat.bSkinnedScrollbar) // XXX fix (verify skin items to be complete, otherwise don't draw + return CDRF_SKIPDEFAULT; + return CDRF_DODEFAULT; + + case CDDS_POSTPAINT: + return 0; + + case CDDS_ITEMPREPAINT: + HDC hdc = nmcsbcd->hdc; + StatusItems_t *item = 0, *arrowItem = 0; + UINT uItemID = ID_EXTBKSCROLLBACK; + RECT rcWindow; + POINT pt; + DWORD dfcFlags; + HRGN rgn = 0; + GetWindowRect(pcli->hwndContactTree, &rcWindow); + pt.x = rcWindow.left; + pt.y = rcWindow.top; + ScreenToClient(pcli->hwndContactList, &pt); + hdcScroll = hdc; + BitBlt(hdcScroll, nmcsbcd->rect.left, nmcsbcd->rect.top, nmcsbcd->rect.right - nmcsbcd->rect.left, + nmcsbcd->rect.bottom - nmcsbcd->rect.top, cfg::dat.hdcBg, pt.x + nmcsbcd->rect.left, pt.y + nmcsbcd->rect.top, SRCCOPY); + + switch (nmcsbcd->uItem) { + case HTSCROLL_UP: + case HTSCROLL_DOWN: + uItemID = (nmcsbcd->uState == CDIS_DEFAULT || nmcsbcd->uState == CDIS_DISABLED) ? ID_EXTBKSCROLLBUTTON : + (nmcsbcd->uState == CDIS_HOT ? ID_EXTBKSCROLLBUTTONHOVER : ID_EXTBKSCROLLBUTTONPRESSED); + break; + case HTSCROLL_PAGEGDOWN: + case HTSCROLL_PAGEGUP: + uItemID = nmcsbcd->uItem == HTSCROLL_PAGEGUP ? ID_EXTBKSCROLLBACK : ID_EXTBKSCROLLBACKLOWER; + rgn = CreateRectRgn(nmcsbcd->rect.left, nmcsbcd->rect.top, nmcsbcd->rect.right, nmcsbcd->rect.bottom); + SelectClipRgn(hdcScroll, rgn); + break; + case HTSCROLL_THUMB: + uItemID = nmcsbcd->uState == CDIS_SELECTED ? ID_EXTBKSCROLLTHUMBPRESSED : ID_EXTBKSCROLLTHUMB; + break; + default: + break; + } + + uItemID -= ID_STATUS_OFFLINE; + item = arStatusItems[uItemID]; + if (!item->IGNORED) { + int alpha = nmcsbcd->uState == CDIS_DISABLED ? item->ALPHA - 50 : item->ALPHA; + DrawAlpha(hdcScroll, &nmcsbcd->rect, item->COLOR, alpha, item->COLOR2, item->COLOR2_TRANSPARENT, + item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem); + } + dfcFlags = DFCS_FLAT | (nmcsbcd->uState == CDIS_DISABLED ? DFCS_INACTIVE : + (nmcsbcd->uState == CDIS_HOT ? DFCS_HOT : + (nmcsbcd->uState == CDIS_SELECTED ? DFCS_PUSHED : 0))); + + if (nmcsbcd->uItem == HTSCROLL_UP) + arrowItem = arStatusItems[ID_EXTBKSCROLLARROWUP - ID_STATUS_OFFLINE]; + if (nmcsbcd->uItem == HTSCROLL_DOWN) + arrowItem = arStatusItems[ID_EXTBKSCROLLARROWDOWN - ID_STATUS_OFFLINE]; + if (arrowItem && !arrowItem->IGNORED) + DrawAlpha(hdcScroll, &nmcsbcd->rect, arrowItem->COLOR, arrowItem->ALPHA, arrowItem->COLOR2, arrowItem->COLOR2_TRANSPARENT, + arrowItem->GRADIENT, arrowItem->CORNER, arrowItem->BORDERSTYLE, arrowItem->imageItem); + else if (arrowItem) + DrawFrameControl(hdcScroll, &nmcsbcd->rect, DFC_SCROLL, (nmcsbcd->uItem == HTSCROLL_UP ? DFCS_SCROLLUP : DFCS_SCROLLDOWN) | dfcFlags); + + if (rgn) { + SelectClipRgn(hdcScroll, NULL); + DeleteObject(rgn); + } + } + } + return 0; +} + +static int ServiceParamsOK(ButtonItem *item, WPARAM *wParam, LPARAM *lParam, MCONTACT hContact) +{ + if (item->dwFlags & BUTTON_PASSHCONTACTW || item->dwFlags & BUTTON_PASSHCONTACTL || item->dwFlags & BUTTON_ISCONTACTDBACTION) { + if (hContact == 0) + return 0; + + if (item->dwFlags & BUTTON_PASSHCONTACTW) + *wParam = hContact; + else if (item->dwFlags & BUTTON_PASSHCONTACTL) + *lParam = hContact; + } + return 1; +} + +static void ShowCLUI(HWND hwnd) +{ + int state = old_cliststate; + int onTop = cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT); + + SendMessage(hwnd, WM_SETREDRAW, FALSE, FALSE); + if (!cfg::getByte("CLUI", "ShowMainMenu", SETTING_SHOWMAINMENU_DEFAULT)) + SetMenu(pcli->hwndContactList, NULL); + if (state == SETTING_STATE_NORMAL) { + SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0); + ShowWindow(pcli->hwndContactList, SW_SHOWNORMAL); + SendMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0); + } + else if (state == SETTING_STATE_MINIMIZED) { + cfg::dat.forceResize = TRUE; + ShowWindow(pcli->hwndContactList, SW_HIDE); + } + else if (state == SETTING_STATE_HIDDEN) { + cfg::dat.forceResize = TRUE; + ShowWindow(pcli->hwndContactList, SW_HIDE); + } + SetWindowPos(pcli->hwndContactList, onTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOSENDCHANGING); + DrawMenuBar(hwnd); + if (cfg::dat.autosize) { + SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0); + SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0); + } +} + +static void GetButtonRect(HWND hwnd, RECT *rc) +{ + if (hwnd) + GetWindowRect(hwnd, rc); + else { + POINT pt; + GetCursorPos(&pt); + rc->bottom = rc->top = pt.y; + rc->left = rc->right = pt.x; + } +} + +LRESULT CALLBACK ContactListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_CREATE: + { + int flags = WS_CHILD | CCS_BOTTOM; + flags |= cfg::getByte("CLUI", "ShowSBar", 1) ? WS_VISIBLE : 0; + flags |= cfg::getByte("CLUI", "ShowGrip", 1) ? SBARS_SIZEGRIP : 0; + pcli->hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, flags, 0, 0, 0, 0, hwnd, NULL, g_hInst, NULL); + if (flags & WS_VISIBLE) { + ShowWindow(pcli->hwndStatus, SW_SHOW); + SendMessage(pcli->hwndStatus, WM_SIZE, 0, 0); + } + mir_subclassWindow(pcli->hwndStatus, NewStatusBarWndProc); + SetClassLong(pcli->hwndStatus, GCL_STYLE, GetClassLong(pcli->hwndStatus, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW)); + } + g_oldSize.cx = g_oldSize.cy = 0; + old_cliststate = cfg::getByte("CList", "State", SETTING_STATE_NORMAL); + cfg::writeByte("CList", "State", SETTING_STATE_HIDDEN); + SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_VISIBLE); + SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | WS_CLIPCHILDREN); + if (!cfg::dat.bFirstRun) + ConfigureEventArea(hwnd); + ConfigureCLUIGeometry(0); + CluiProtocolStatusChanged(0, 0); + + for (int i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + statusNames[i - ID_STATUS_OFFLINE] = pcli->pfnGetStatusModeDescription(i, 0); + + //delay creation of CLC so that it can get the status icons right the first time (needs protocol modules loaded) + if (cfg::dat.bLayeredHack) { + SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | (WS_EX_LAYERED)); + SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 255, LWA_ALPHA); + } + + if (cfg::dat.isTransparent) { + SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + } + transparentFocus = 1; + + TranslateMenu(GetMenu(hwnd)); + PostMessage(hwnd, M_CREATECLC, 0, 0); + return FALSE; + + case WM_NCCREATE: + { + LPCREATESTRUCT p = (LPCREATESTRUCT)lParam; + p->style &= ~(CS_HREDRAW | CS_VREDRAW); + } + break; + + case M_CREATECLC: { + if (cfg::getByte("CLUI", "useskin", 0)) + IMG_LoadItems(); + CreateButtonBar(hwnd); + //FYR: to be checked: otherwise it raises double xStatus items + //NotifyEventHooks(pcli->hPreBuildStatusMenuEvent, 0, 0); + SendMessage(hwnd, WM_SETREDRAW, FALSE, FALSE); + { + LONG style; + BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_TOOLWINDOW); + ShowWindow(pcli->hwndContactList, SW_HIDE); + style = GetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE); + if (windowStyle != SETTING_WINDOWSTYLE_DEFAULT) { + style |= WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE; + style &= ~WS_EX_APPWINDOW; + } + else { + style &= ~(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE); + if (cfg::getByte("CList", "AlwaysHideOnTB", 1)) + style &= ~WS_EX_APPWINDOW; + else + style |= WS_EX_APPWINDOW; + } + + SetWindowLongPtr(pcli->hwndContactList, GWL_EXSTYLE, style); + ApplyCLUIBorderStyle(pcli->hwndContactList); + + SetWindowPos(pcli->hwndContactList, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE); + } + + if (cfg::dat.bSkinnedButtonMode) + SetButtonToSkinned(); + ConfigureFrame(); + SetButtonStates(hwnd); + + CreateCLC(hwnd); + cfg::clcdat = (struct ClcData *)GetWindowLongPtr(pcli->hwndContactTree, 0); + + if (cfg::dat.bFullTransparent) { + if (g_CLUISkinnedBkColorRGB) + Tweak_It(g_CLUISkinnedBkColorRGB); + else if (cfg::dat.bClipBorder || (cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME)) + Tweak_It(RGB(255, 0, 255)); + else + Tweak_It(cfg::clcdat->bkColour); + } + + cfg::writeByte("CList", "State", old_cliststate); + + if (cfg::getByte("CList", "AutoApplyLastViewMode", 0)) { + DBVARIANT dbv = {0}; + if (!db_get(NULL, "CList", "LastViewMode", &dbv)) { + if (lstrlenA(dbv.pszVal) > 2) { + if (cfg::getDword(NULL, CLVM_MODULE, dbv.pszVal, -1) != 0xffffffff) + ApplyViewMode((char *)dbv.pszVal); + } + db_free(&dbv); + } + } + if (!cfg::dat.autosize) + ShowCLUI(hwnd); + else { + show_on_first_autosize = TRUE; + RecalcScrollBar(pcli->hwndContactTree, cfg::clcdat); + } + return 0; + } + case WM_ERASEBKGND: + return TRUE; + /* + if (cfg::dat.bSkinnedButtonMode) + return TRUE; + return DefWindowProc(hwnd, msg, wParam, lParam); + */ + + case WM_PAINT: + { + PAINTSTRUCT ps; + RECT rc, rcFrame, rcClient; + HDC hdc; + HRGN rgn = 0; + HDC hdcReal = BeginPaint(hwnd, &ps); + + if (during_sizing) + rcClient = rcWPC; + else + GetClientRect(hwnd, &rcClient); + CopyRect(&rc, &rcClient); + + if (!cfg::dat.hdcBg || rc.right > cfg::dat.dcSize.cx || rc.bottom + cfg::dat.statusBarHeight > cfg::dat.dcSize.cy) { + RECT rcWorkArea; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); + HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi; + mi.cbSize = sizeof(mi); + if (GetMonitorInfo(hMon, &mi)) + rcWorkArea = mi.rcWork; + + cfg::dat.dcSize.cy = max(rc.bottom + cfg::dat.statusBarHeight, rcWorkArea.bottom - rcWorkArea.top); + cfg::dat.dcSize.cx = max(rc.right, (rcWorkArea.right - rcWorkArea.left) / 2); + + if (cfg::dat.hdcBg) { + SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBgOld); + DeleteObject(cfg::dat.hbmBg); + DeleteDC(cfg::dat.hdcBg); + } + cfg::dat.hdcBg = CreateCompatibleDC(hdcReal); + cfg::dat.hbmBg = CreateCompatibleBitmap(hdcReal, cfg::dat.dcSize.cx, cfg::dat.dcSize.cy); + cfg::dat.hbmBgOld = reinterpret_cast(SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBg)); + } + + if (cfg::shutDown) { + EndPaint(hwnd, &ps); + return 0; + } + + hdc = cfg::dat.hdcBg; + + CopyRect(&rcFrame, &rcClient); + if (g_CLUISkinnedBkColor) { + if (cfg::dat.fOnDesktop) { + HDC dc = GetDC(0); + RECT rcWin; + + GetWindowRect(hwnd, &rcWin); + BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, dc, rcWin.left, rcWin.top, SRCCOPY); + } + else + FillRect(hdc, &rcClient, g_CLUISkinnedBkColor); + } + + if (cfg::dat.bClipBorder != 0 || cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME) { + int docked = CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0); + int clip = cfg::dat.bClipBorder; + + if (!g_CLUISkinnedBkColor) + FillRect(hdc, &rcClient, cfg::dat.hBrushColorKey); + if (cfg::dat.dwFlags & CLUI_FRAME_ROUNDEDFRAME) + rgn = CreateRoundRectRgn(clip, docked ? 0 : clip, rcClient.right - clip + 1, rcClient.bottom - (docked ? 0 : clip - 1), 8 + clip, 8 + clip); + else + rgn = CreateRectRgn(clip, docked ? 0 : clip, rcClient.right - clip, rcClient.bottom - (docked ? 0 : clip)); + SelectClipRgn(hdc, rgn); + } + + if (g_CLUIImageItem) { + IMG_RenderImageItem(hdc, g_CLUIImageItem, &rcFrame); + cfg::dat.ptW.x = cfg::dat.ptW.y = 0; + ClientToScreen(hwnd, &cfg::dat.ptW); + goto skipbg; + } + + if (cfg::dat.bWallpaperMode) + FillRect(hdc, &rcClient, cfg::dat.hBrushCLCBk); + else + FillRect(hdc, &rcClient, GetSysColorBrush(COLOR_3DFACE)); + + rcFrame.left += (cfg::dat.bCLeft - 1); + rcFrame.right -= (cfg::dat.bCRight - 1); + rcFrame.bottom++; + rcFrame.bottom -= cfg::dat.statusBarHeight; + rcFrame.top += (cfg::dat.topOffset - 1); + + if (cfg::dat.dwFlags & CLUI_FRAME_CLISTSUNKEN) { + if (cfg::dat.bWallpaperMode && cfg::clcdat != NULL) { + InflateRect(&rcFrame, -1, -1); + if (cfg::dat.bmpBackground) + BlitWallpaper(hdc, &rcFrame, &ps.rcPaint, cfg::clcdat); + cfg::dat.ptW.x = cfg::dat.ptW.y = 0; + ClientToScreen(hwnd, &cfg::dat.ptW); + } + InflateRect(&rcFrame, 1, 1); + if (cfg::dat.bSkinnedButtonMode) + rcFrame.bottom -= (cfg::dat.bottomOffset); + DrawEdge(hdc, &rcFrame, BDR_SUNKENOUTER, BF_RECT); + } + else if (cfg::dat.bWallpaperMode && cfg::clcdat != NULL) { + if (cfg::dat.bmpBackground) + BlitWallpaper(hdc, &rcFrame, &ps.rcPaint, cfg::clcdat); + cfg::dat.ptW.x = cfg::dat.ptW.y = 0; + ClientToScreen(hwnd, &cfg::dat.ptW); + } +skipbg: + BitBlt(hdcReal, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdc, 0, 0, SRCCOPY); + if (rgn) { + SelectClipRgn(hdc, NULL); + DeleteObject(rgn); + } + EndPaint(hwnd, &ps); + } + return 0; + + case WM_ENTERSIZEMOVE: + { + RECT rc; + POINT pt = {0}; + + GetWindowRect(hwnd, &g_PreSizeRect); + GetClientRect(hwnd, &rc); + ClientToScreen(hwnd, &pt); + g_CLUI_x_off = pt.x - g_PreSizeRect.left; + g_CLUI_y_off = pt.y - g_PreSizeRect.top; + pt.x = rc.right; + ClientToScreen(hwnd, &pt); + g_CLUI_x1_off = g_PreSizeRect.right - pt.x; + pt.x = 0; + pt.y = rc.bottom; + ClientToScreen(hwnd, &pt); + g_CLUI_y1_off = g_PreSizeRect.bottom - pt.y; + } + break; + + case WM_EXITSIZEMOVE: + PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0); + break; + + case WM_SIZING: + break; + /* + RECT *szrect = (RECT *)lParam; + if (Docking_IsDocked(0, 0)) + break; + g_SizingRect = *((RECT *)lParam); + if (wParam != WMSZ_BOTTOM && wParam != WMSZ_BOTTOMRIGHT && wParam != WMSZ_BOTTOMLEFT) + szrect->bottom = g_PreSizeRect.bottom; + if (wParam != WMSZ_RIGHT && wParam != WMSZ_BOTTOMRIGHT && wParam != WMSZ_TOPRIGHT) + szrect->right = g_PreSizeRect.right; + */ + return TRUE; + + case WM_WINDOWPOSCHANGED: + if (Docking_IsDocked(0, 0)) + break; + + case WM_WINDOWPOSCHANGING: + if (pcli->hwndContactList != NULL) { + WINDOWPOS *wp = (WINDOWPOS *)lParam; + if (wp && wp->flags & SWP_NOSIZE) + return FALSE; + + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + during_sizing = true; + + new_window_rect.left = 0; + new_window_rect.right = wp->cx - (g_CLUI_x_off + g_CLUI_x1_off); + new_window_rect.top = 0; + new_window_rect.bottom = wp->cy - g_CLUI_y_off - g_CLUI_y1_off; + + if (cfg::dat.dwFlags & CLUI_FRAME_SBARSHOW) { + RECT rcStatus; + SetWindowPos(pcli->hwndStatus, 0, 0, new_window_rect.bottom - 20, new_window_rect.right, 20, SWP_NOZORDER); + GetWindowRect(pcli->hwndStatus, &rcStatus); + cfg::dat.statusBarHeight = (rcStatus.bottom - rcStatus.top); + if (wp->cx != g_oldSize.cx) + SendMessage(hwnd, CLUIINTM_STATUSBARUPDATE, 0, 0); + RedrawWindow(pcli->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + else + cfg::dat.statusBarHeight = 0; + + SizeFramesByWindowRect(&new_window_rect); + dock_prevent_moving = 0; + LayoutButtons(hwnd, &new_window_rect); + dock_prevent_moving = 1; + g_oldPos.x = wp->x; + g_oldPos.y = wp->y; + g_oldSize.cx = wp->cx; + g_oldSize.cy = wp->cy; + rcWPC = new_window_rect; + } + during_sizing = false; + return 0; + + case WM_SIZE: + if ((wParam == 0 && lParam == 0) || Docking_IsDocked(0, 0)) { + + if (IsZoomed(hwnd)) + ShowWindow(hwnd, SW_SHOWNORMAL); + + if (pcli->hwndContactList != 0) { + SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0); + RECT rc; + GetWindowRect(hwnd, &rc); + WINDOWPOS wp = {0}; + wp.cx = rc.right - rc.left; + wp.cy = rc.bottom - rc.top; + wp.x = rc.left; + wp.y = rc.top; + wp.flags = 0; + SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp); + SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0); + } + } + + case WM_MOVE: + if (!IsIconic(hwnd)) { + RECT rc; + GetWindowRect(hwnd, &rc); + + if (!Docking_IsDocked(0, 0)) { + cluiPos.bottom = (DWORD)(rc.bottom - rc.top); + cluiPos.left = rc.left; + cluiPos.top = rc.top; + } + cluiPos.right = rc.right - rc.left; + if (cfg::dat.realTimeSaving) { + RECT rc; + GetWindowRect(hwnd, &rc); + + // if docked, dont remember pos (except for width) + if (!CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) { + cfg::writeDword("CList", "Height", (DWORD)(rc.bottom - rc.top)); + cfg::writeDword("CList", "x", (DWORD)rc.left); + cfg::writeDword("CList", "y", (DWORD)rc.top); + } + cfg::writeDword("CList", "Width", (DWORD)(rc.right - rc.left)); + } + } + return TRUE; + + case WM_SETFOCUS: + SetFocus(pcli->hwndContactTree); + return 0; + + case CLUIINTM_REMOVEFROMTASKBAR: { + BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT); + if (windowStyle == SETTING_WINDOWSTYLE_DEFAULT && cfg::getByte("CList", "AlwaysHideOnTB", 0)) + RemoveFromTaskBar(hwnd); + return 0; + } + case WM_ACTIVATE: + if (g_fading_active) { + if (wParam != WA_INACTIVE && cfg::dat.isTransparent) + transparentFocus = 1; + return DefWindowProc(hwnd, msg, wParam, lParam); + } + if (wParam == WA_INACTIVE) { + if ((HWND)wParam != hwnd) + if (cfg::dat.isTransparent) + if (transparentFocus) + SetTimer(hwnd, TM_AUTOALPHA, 250, NULL); + } + else { + if (cfg::dat.isTransparent) { + KillTimer(hwnd, TM_AUTOALPHA); + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + transparentFocus = 1; + } + SetWindowPos(pcli->hwndContactList, cfg::getByte("CList", "OnTop", SETTING_ONTOP_DEFAULT) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING); + } + PostMessage(hwnd, CLUIINTM_REMOVEFROMTASKBAR, 0, 0); + return DefWindowProc(hwnd, msg, wParam, lParam); + + case WM_SETCURSOR: + if (cfg::dat.isTransparent) { + if (!transparentFocus && GetForegroundWindow() != hwnd) { + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + transparentFocus = 1; + SetTimer(hwnd, TM_AUTOALPHA, 250, NULL); + } + } + return DefWindowProc(hwnd, msg, wParam, lParam); + + case WM_NCHITTEST: { + LRESULT result; + RECT r; + POINT pt; + int k = 0; + int clip = cfg::dat.bClipBorder; + + GetWindowRect(hwnd, &r); + GetCursorPos(&pt); + if (pt.y <= r.bottom && pt.y >= r.bottom - clip - 6 && !cfg::getByte("CLUI", "AutoSize", 0)) { + if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10) + return HTBOTTOM; + if (pt.x < r.left + clip + 10) + return HTBOTTOMLEFT; + if (pt.x > r.right - clip - 10) + return HTBOTTOMRIGHT; + } + else if (pt.y >= r.top && pt.y <= r.top + 3 && !cfg::getByte("CLUI", "AutoSize", 0)) { + if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10) + return HTTOP; + if (pt.x < r.left + clip + 10) + return HTTOPLEFT; + if (pt.x > r.right - clip - 10) + return HTTOPRIGHT; + } + else if (pt.x >= r.left && pt.x <= r.left + clip + 6) + return HTLEFT; + else if (pt.x >= r.right - clip - 6 && pt.x <= r.right) + return HTRIGHT; + + result = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam); + if (result == HTSIZE || result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT || result == HTBOTTOM || result == HTBOTTOMRIGHT || result == HTBOTTOMLEFT) + if (cfg::dat.autosize) + return HTCLIENT; + return result; + } + + case WM_TIMER: + if ((int)wParam == TM_AUTOALPHA) { + int inwnd; + + if (GetForegroundWindow() == hwnd) { + KillTimer(hwnd, TM_AUTOALPHA); + inwnd = 1; + } + else { + POINT pt; + HWND hwndPt; + pt.x = (short)LOWORD(GetMessagePos()); + pt.y = (short)HIWORD(GetMessagePos()); + hwndPt = WindowFromPoint(pt); + inwnd = (hwndPt == hwnd || GetParent(hwndPt) == hwnd); + } + if (inwnd != transparentFocus) { + //change + transparentFocus = inwnd; + if (transparentFocus) + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.alpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + else + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), cfg::dat.autoalpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + } + if (!transparentFocus) + KillTimer(hwnd, TM_AUTOALPHA); + } + else if (wParam == TIMERID_AUTOSIZE) { + KillTimer(hwnd, wParam); + SetWindowPos(hwnd, 0, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); + PostMessage(hwnd, WM_SIZE, 0, 0); + PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0); + } + return TRUE; + + case WM_SHOWWINDOW: + { + static int noRecurse = 0; + DWORD thisTick, startTick; + int sourceAlpha, destAlpha; + + if (cfg::dat.forceResize && wParam != SW_HIDE) { + cfg::dat.forceResize = FALSE; + if (0) { //!g_CluiData.fadeinout && MySetLayeredWindowAttributes && g_CluiData.bLayeredHack) { + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), 0, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + SendMessage(hwnd, WM_SIZE, 0, 0); + ShowWindow(hwnd, SW_SHOW); + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), 255, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + } + else { + SendMessage(hwnd, WM_SIZE, 0, 0); + PostMessage(hwnd, CLUIINTM_REDRAW, 0, 0); + } + } + PostMessage(hwnd, CLUIINTM_REMOVEFROMTASKBAR, 0, 0); + + if (lParam) + return DefWindowProc(hwnd, msg, wParam, lParam); + if (noRecurse) + return DefWindowProc(hwnd, msg, wParam, lParam); + if (!cfg::dat.fadeinout) + return DefWindowProc(hwnd, msg, wParam, lParam); + + g_fading_active = 1; + + if (wParam) { + sourceAlpha = 0; + destAlpha = cfg::dat.isTransparent ? cfg::dat.alpha : 255; + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? (COLORREF)cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)sourceAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + noRecurse = 1; + ShowWindow(hwnd, SW_SHOW); + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + noRecurse = 0; + } + else { + sourceAlpha = cfg::dat.isTransparent ? (transparentFocus ? cfg::dat.alpha : cfg::dat.autoalpha) : 255; + destAlpha = 0; + } + for (startTick = GetTickCount(); ;) { + thisTick = GetTickCount(); + if (thisTick >= startTick + 200) { + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)destAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + g_fading_active = 0; + return DefWindowProc(hwnd, msg, wParam, lParam); + } + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)(sourceAlpha + (destAlpha - sourceAlpha) * (int)(thisTick - startTick) / 200), LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + } + SetLayeredWindowAttributes(hwnd, cfg::dat.bFullTransparent ? cfg::dat.colorkey : RGB(0, 0, 0), (BYTE)destAlpha, LWA_ALPHA | (cfg::dat.bFullTransparent ? LWA_COLORKEY : 0)); + } + return DefWindowProc(hwnd, msg, wParam, lParam); + + case WM_SYSCOMMAND: + { + BYTE bWindowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT); + if (SETTING_WINDOWSTYLE_DEFAULT == bWindowStyle) { + if (wParam == SC_RESTORE) { + CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); + SendMessage(hwnd, WM_SIZE, 0, 0); + SendMessage(hwnd, CLUIINTM_REDRAW, 0, 0); + SendMessage(hwnd, CLUIINTM_STATUSBARUPDATE, 0, 0); + cfg::writeByte("CList", "State", SETTING_STATE_NORMAL); + break; + } + } + + if (wParam == SC_MAXIMIZE) + return 0; + + if (wParam == SC_MINIMIZE) { + if (SETTING_WINDOWSTYLE_DEFAULT == bWindowStyle && !cfg::getByte("CList", "AlwaysHideOnTB", 0)) { + cfg::writeByte("CList", "State", SETTING_STATE_MINIMIZED); + break; + } + pcli->pfnShowHide(0, 0); + return 0; + } + if (wParam == SC_RESTORE) { + pcli->pfnShowHide(0, 0); + return 0; + } + } + return DefWindowProc(hwnd, msg, wParam, lParam); + + case WM_COMMAND: + { + DWORD dwOldFlags = cfg::dat.dwFlags; + if (HIWORD(wParam) == BN_CLICKED && lParam != 0) { + if (LOWORD(wParam) == IDC_TBFIRSTUID - 1) + break; + + else if (LOWORD(wParam) >= IDC_TBFIRSTUID) { // skinnable buttons handling + ButtonItem *item = g_ButtonItems; + WPARAM wwParam = 0; + LPARAM llParam = 0; + MCONTACT hContact = 0; + ClcContact *contact = 0; + int serviceFailure = FALSE; + + if (cfg::clcdat) { + pcli->pfnGetRowByIndex(cfg::clcdat, cfg::clcdat->selection, &contact, NULL); + if (contact && contact->type == CLCIT_CONTACT) { + hContact = contact->hContact; + } + } + while (item) { + if (item->uId == (DWORD)LOWORD(wParam)) { + int contactOK = ServiceParamsOK(item, &wwParam, &llParam, hContact); + + if (item->dwFlags & BUTTON_ISSERVICE) { + if (ServiceExists(item->szService) && contactOK) + CallService(item->szService, wwParam, llParam); + else if (contactOK) + serviceFailure = TRUE; + } + else if (item->dwFlags & BUTTON_ISPROTOSERVICE && cfg::clcdat) { + if (contactOK) { + char *szProto = GetContactProto(hContact); + if (ProtoServiceExists(szProto, item->szService)) + ProtoCallService(szProto, item->szService, wwParam, llParam); + else + serviceFailure = TRUE; + } + } + else if (item->dwFlags & BUTTON_ISDBACTION) { + BYTE *pValue; + char *szModule = item->szModule; + char *szSetting = item->szSetting; + MCONTACT finalhContact = 0; + + if (item->dwFlags & BUTTON_ISCONTACTDBACTION || item->dwFlags & BUTTON_DBACTIONONCONTACT) { + contactOK = ServiceParamsOK(item, &wwParam, &llParam, hContact); + if (contactOK && item->dwFlags & BUTTON_ISCONTACTDBACTION) + szModule = GetContactProto(hContact); + finalhContact = hContact; + } + else + contactOK = 1; + + if (contactOK) { + BOOL fDelete = FALSE; + + if (item->dwFlags & BUTTON_ISTOGGLE) { + BOOL fChecked = (SendMessage(item->hWnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED); + + pValue = fChecked ? item->bValueRelease : item->bValuePush; + if (fChecked && pValue[0] == 0) + fDelete = TRUE; + } + else + pValue = item->bValuePush; + + if (fDelete) + db_unset(finalhContact, szModule, szSetting); + else { + switch (item->type) { + case DBVT_BYTE: + cfg::writeByte(finalhContact, szModule, szSetting, pValue[0]); + break; + case DBVT_WORD: + cfg::writeWord(finalhContact, szModule, szSetting, *((WORD *)&pValue[0])); + break; + case DBVT_DWORD: + cfg::writeDword(finalhContact, szModule, szSetting, *((DWORD *)&pValue[0])); + break; + case DBVT_ASCIIZ: + cfg::writeString(finalhContact, szModule, szSetting, (char *)pValue); + break; + } + } + } + else if (item->dwFlags & BUTTON_ISTOGGLE) + SendMessage(item->hWnd, BM_SETCHECK, 0, 0); + } + if (!contactOK) + MessageBox(0, TranslateT("The requested action requires a valid contact selection. Please select a contact from the contact list and repeat."), TranslateT("Parameter mismatch"), MB_OK); + if (serviceFailure) { + char szError[512]; + + mir_snprintf(szError, SIZEOF(szError), Translate("The service %s specified by the %s button definition was not found. You may need to install additional plugins."), item->szService, item->szName); + MessageBoxA(0, szError, Translate("Service failure"), MB_OK); + } + break; + } + item = item->nextItem; + } + goto buttons_done; + } + + switch (LOWORD(wParam)) { + case IDC_TBMENU: + case IDC_TBTOPMENU: + case IDC_STBTOPMENU: + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); + GetButtonRect(GetDlgItem(hwnd, LOWORD(wParam)), &rc); + TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, LOWORD(wParam) == IDC_TBMENU ? rc.top : rc.bottom, 0, hwnd, NULL); + } + return 0; + + case IDC_TBTOPSTATUS: + case IDC_STBTOPSTATUS: + case IDC_TBGLOBALSTATUS: + { + RECT rc; + HMENU hmenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); + GetButtonRect(GetDlgItem(hwnd, LOWORD(wParam)), &rc); + TrackPopupMenu(hmenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, LOWORD(wParam) == IDC_TBGLOBALSTATUS ? rc.top : rc.bottom, 0, hwnd, NULL); + } + return 0; + + + case IDC_TBSOUND: + case IDC_STBSOUND: + cfg::dat.soundsOff = !cfg::dat.soundsOff; + cfg::writeByte("CLUI", "NoSounds", (BYTE)cfg::dat.soundsOff); + cfg::writeByte("Skin", "UseSound", (BYTE)(cfg::dat.soundsOff ? 0 : 1)); + return 0; + + case IDC_TBSELECTVIEWMODE: + case IDC_STBSELECTVIEWMODE: + SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_SELECTMODE, lParam); + break; + case IDC_TBCLEARVIEWMODE: + case IDC_STBCLEARVIEWMODE: + SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_RESETMODES, lParam); + break; + case IDC_TBCONFIGUREVIEWMODE: + case IDC_STBCONFIGUREVIEWMODE: + SendMessage(g_hwndViewModeFrame, WM_COMMAND, IDC_CONFIGUREMODES, lParam); + break; + case IDC_TBFINDANDADD: + case IDC_STBFINDANDADD: + CallService(MS_FINDADD_FINDADD, 0, 0); + return 0; + case IDC_TBACCOUNTS: + case IDC_STBACCOUNTS: + CallService(MS_PROTO_SHOWACCMGR, 0, 0); + break; + case IDC_TBOPTIONS: + case IDC_STBOPTIONS: + CallService("Options/OptionsCommand", 0, 0); + return 0; + } + } + else if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), (LPARAM)(HANDLE)NULL)) + return 0; + +buttons_done: + switch (LOWORD(wParam)) { + case ID_TRAY_EXIT: + case ID_ICQ_EXIT: + cfg::shutDown = 1; + if (CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) + DestroyWindow(hwnd); + break; + case ID_TRAY_HIDE: + case IDC_TBMINIMIZE: + case IDC_STBMINIMIZE: + pcli->pfnShowHide(0, 0); + break; + case POPUP_NEWGROUP: + SendMessage(pcli->hwndContactTree, CLM_SETHIDEEMPTYGROUPS, 0, 0); + SendMessage(pcli->hwndContactTree, CLM_SETUSEGROUPS, 1, 0); + Clist_CreateGroup(NULL, NULL); + break; + case POPUP_HIDEOFFLINE: + case IDC_TBHIDEOFFLINE: + case IDC_STBHIDEOFFLINE: + CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM)(-1), 0); + break; + case POPUP_HIDEOFFLINEROOT: + SendMessage(pcli->hwndContactTree, CLM_SETHIDEOFFLINEROOT, !SendMessage(pcli->hwndContactTree, CLM_GETHIDEOFFLINEROOT, 0, 0), 0); + break; + case POPUP_HIDEEMPTYGROUPS: + { + int newVal = !(GetWindowLongPtr(pcli->hwndContactTree, GWL_STYLE) & CLS_HIDEEMPTYGROUPS); + cfg::writeByte("CList", "HideEmptyGroups", (BYTE)newVal); + SendMessage(pcli->hwndContactTree, CLM_SETHIDEEMPTYGROUPS, newVal, 0); + } + break; + case IDC_TBHIDEGROUPS: + case IDC_STBHIDEGROUPS: + case POPUP_DISABLEGROUPS: + { + int newVal = !(GetWindowLongPtr(pcli->hwndContactTree, GWL_STYLE) & CLS_USEGROUPS); + cfg::writeByte("CList", "UseGroups", (BYTE)newVal); + SendMessage(pcli->hwndContactTree, CLM_SETUSEGROUPS, newVal, 0); + ClcSetButtonState(IDC_TBHIDEGROUPS, newVal); + SetButtonStates(hwnd); + } + break; + case POPUP_HIDEMIRANDA: + pcli->pfnShowHide(0, 0); + break; + case POPUP_SHOWMETAICONS: + cfg::dat.dwFlags ^= CLUI_USEMETAICONS; + pcli->pfnInitAutoRebuild(hwnd); + break; + case POPUP_FRAME: + cfg::dat.dwFlags ^= CLUI_FRAME_CLISTSUNKEN; + break; + case POPUP_BUTTONS: + cfg::dat.dwFlags ^= CLUI_FRAME_SHOWBOTTOMBUTTONS; + break; + case POPUP_SHOWSTATUSICONS: + cfg::dat.dwFlags ^= CLUI_FRAME_STATUSICONS; + break; + } + if (dwOldFlags != cfg::dat.dwFlags) { + InvalidateRect(pcli->hwndContactTree, NULL, FALSE); + cfg::writeDword("CLUI", "Frameflags", cfg::dat.dwFlags); + if ((dwOldFlags & (CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_CLISTSUNKEN)) != (cfg::dat.dwFlags & (CLUI_FRAME_SHOWBOTTOMBUTTONS | CLUI_FRAME_CLISTSUNKEN))) { + ConfigureFrame(); + ConfigureCLUIGeometry(1); + } + ConfigureEventArea(pcli->hwndContactList); + PostMessage(pcli->hwndContactList, WM_SIZE, 0, 0); + PostMessage(pcli->hwndContactList, CLUIINTM_REDRAW, 0, 0); + } + } + return FALSE; + + case WM_LBUTTONDOWN: + if (g_ButtonItems) { + POINT ptMouse, pt; + + GetCursorPos(&ptMouse); + pt = ptMouse; + return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); + } + break; + + case WM_DISPLAYCHANGE: + SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0); //forces it to send a cln_listsizechanged + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->hwndFrom == pcli->hwndContactTree) { + switch (((LPNMHDR)lParam)->code) { + case CLN_LISTSIZECHANGE: + sttProcessResize(hwnd, (NMCLISTCONTROL *)lParam); + return FALSE; + + case NM_CLICK: + { + NMCLISTCONTROL *nm = (NMCLISTCONTROL *)lParam; + DWORD hitFlags; + HANDLE hItem; + + hItem = (HANDLE)SendMessage(pcli->hwndContactTree, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); + + if ((hitFlags & (CLCHT_NOWHERE | CLCHT_INLEFTMARGIN | CLCHT_BELOWITEMS)) == 0) + break; + if (cfg::getByte("CLUI", "ClientAreaDrag", SETTING_CLIENTDRAG_DEFAULT)) { + POINT pt; + pt = nm->pt; + ClientToScreen(pcli->hwndContactTree, &pt); + return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); + } + } + return FALSE; + } + } + break; + + case WM_CONTEXTMENU: + { + RECT rc; + POINT pt; + + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + // x/y might be -1 if it was generated by a kb click + GetWindowRect(pcli->hwndContactTree, &rc); + if (pt.x == -1 && pt.y == -1) { + // all this is done in screen-coords! + GetCursorPos(&pt); + // the mouse isnt near the window, so put it in the middle of the window + if (!PtInRect(&rc, pt)) { + pt.x = rc.left + (rc.right - rc.left) / 2; + pt.y = rc.top + (rc.bottom - rc.top) / 2; + } + } + if (PtInRect(&rc, pt)) { + HMENU hMenu; + hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDGROUP, 0, 0); + TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); + DestroyTrayMenu(hMenu); + return 0; + } + GetWindowRect(pcli->hwndStatus, &rc); + if (PtInRect(&rc, pt)) { + HMENU hMenu; + if (cfg::getByte("CLUI", "SBarRightClk", 0)) + hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); + else + hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); + TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); + return 0; + } + } + break; + + case WM_MEASUREITEM: + if (((LPMEASUREITEMSTRUCT)lParam)->itemData == MENU_MIRANDAMENU) { + ((LPMEASUREITEMSTRUCT)lParam)->itemWidth = g_cxsmIcon * 4 / 3; + ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = 0; + return TRUE; + } + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; + + if (hbmLockedPoint == 0) { + RECT rc = {0, 0, 5, 5}; + + hdcLockedPoint = CreateCompatibleDC(dis->hDC); + hbmLockedPoint = CreateCompatibleBitmap(dis->hDC, 5, 5); + hbmOldLockedPoint = reinterpret_cast(SelectObject(hdcLockedPoint, hbmLockedPoint)); + } + if (dis->hwndItem == pcli->hwndStatus) { + ProtocolData *pd = (ProtocolData *)dis->itemData; + if (IsBadCodePtr((FARPROC)pd)) + return TRUE; + if (cfg::shutDown) + return TRUE; + + int nParts = SendMessage(pcli->hwndStatus, SB_GETPARTS, 0, 0); + SIZE textSize; + BYTE showOpts = cfg::getByte("CLUI", "SBarShow", 1); + char *szProto = pd->RealName; + int status = CallProtoService(szProto, PS_GETSTATUS, 0, 0); + SetBkMode(dis->hDC, TRANSPARENT); + int x = dis->rcItem.left; + + if (showOpts & 1) { + HICON hIcon; + + if (status >= ID_STATUS_CONNECTING && status < ID_STATUS_OFFLINE) { + char szBuffer[128]; + mir_snprintf(szBuffer, SIZEOF(szBuffer), "%s_conn", pd->RealName); + hIcon = Skin_GetIcon(szBuffer); + } + else if (cfg::dat.bShowXStatusOnSbar && status > ID_STATUS_OFFLINE) { + int xStatus; + CUSTOM_STATUS cst = { sizeof(cst) }; + cst.flags = CSSF_MASK_STATUS; + cst.status = &xStatus; + if (ProtoServiceExists(pd->RealName, PS_GETCUSTOMSTATUSEX) && !ProtoCallService(pd->RealName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cst) && xStatus > 0) + hIcon = (HICON)CallProtoService(pd->RealName, PS_GETCUSTOMSTATUSICON, 0, LR_SHARED); // get OWN xStatus icon (if set) + else + hIcon = LoadSkinnedProtoIcon(szProto, status); + } + else + hIcon = LoadSkinnedProtoIcon(szProto, status); + + if (!(showOpts & 6) && cfg::dat.bEqualSections) + x = (dis->rcItem.left + dis->rcItem.right - 16) >> 1; + if (pd->protopos == 0) + x += (cfg::dat.bEqualSections ? (cfg::dat.bCLeft / 2) : cfg::dat.bCLeft); + else if (pd->protopos == nParts - 1) + x -= (cfg::dat.bCRight / 2); + DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - 16) >> 1, hIcon, 16, 16, 0, NULL, DI_NORMAL); + Skin_ReleaseIcon(hIcon); + + if (cfg::getByte("CLUI", "sbar_showlocked", 1)) { + if (cfg::getByte(szProto, "LockMainStatus", 0)) { + hIcon = LoadSkinnedIcon(SKINICON_OTHER_STATUS_LOCKED); + if (hIcon != NULL) { + DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - 16) >> 1, hIcon, 16, 16, 0, NULL, DI_NORMAL); + Skin_ReleaseIcon(hIcon); + } + } + } + x += 18; + } + else { + x += 2; + if (pd->protopos == 0) + x += (cfg::dat.bEqualSections ? (cfg::dat.bCLeft / 2) : cfg::dat.bCLeft); + else if (pd->protopos == nParts - 1) + x -= (cfg::dat.bCRight / 2); + } + + if (showOpts & 2) { + TCHAR szName[64]; + PROTOACCOUNT *pa = ProtoGetAccount(szProto); + if (pa) { + lstrcpyn(szName, pa->tszAccountName, SIZEOF(szName)); + szName[SIZEOF(szName) - 1] = 0; + } + else + szName[0] = 0; + + if (lstrlen(szName) < sizeof(szName) - 1) + lstrcat(szName, _T(" ")); + GetTextExtentPoint32(dis->hDC, szName, lstrlen(szName), &textSize); + TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szName, lstrlen(szName)); + x += textSize.cx; + } + if (showOpts & 4) { + TCHAR *szStatus = pcli->pfnGetStatusModeDescription(status, 0); + GetTextExtentPoint32(dis->hDC, szStatus, lstrlen(szStatus), &textSize); + TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szStatus, lstrlen(szStatus)); + } + } + else if (dis->CtlType == ODT_MENU) { + if (dis->itemData == MENU_MIRANDAMENU) + break; + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + } + } + return 0; + + case WM_CLOSE: + if (SETTING_WINDOWSTYLE_DEFAULT == cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT) && !cfg::getByte("CList", "AlwaysHideOnTB", 0)) { + PostMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); + return 0; + } + pcli->pfnShowHide(0, 0); + return 0; + + case CLUIINTM_REDRAW: + if (show_on_first_autosize) { + show_on_first_autosize = FALSE; + ShowCLUI(hwnd); + } + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); + return 0; + + case CLUIINTM_STATUSBARUPDATE: + CluiProtocolStatusChanged(0, 0); + return 0; + + case WM_THEMECHANGED: + API::updateState(); + break; + + case WM_DESTROY: + if (cfg::dat.hdcBg) { + SelectObject(cfg::dat.hdcBg, cfg::dat.hbmBgOld); + DeleteObject(cfg::dat.hbmBg); + DeleteDC(cfg::dat.hdcBg); + cfg::dat.hdcBg = NULL; + } + if (cfg::dat.bmpBackground) { + SelectObject(cfg::dat.hdcPic, cfg::dat.hbmPicOld); + DeleteDC(cfg::dat.hdcPic); + DeleteObject(cfg::dat.bmpBackground); + cfg::dat.bmpBackground = NULL; + } + FreeProtocolData(); + if (hdcLockedPoint) { + SelectObject(hdcLockedPoint, hbmOldLockedPoint); + DeleteObject(hbmLockedPoint); + DeleteDC(hdcLockedPoint); + } + // if this has not yet been set, do it now. + // indicates that clist is shutting down and prevents various things + // from happening at shutdown. + if (!cfg::shutDown) + cfg::shutDown = 1; + CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)hFrameContactTree, 0); + break; + } + + return coreCli.pfnContactListWndProc(hwnd, msg, wParam, lParam); +} + +#ifndef CS_DROPSHADOW +#define CS_DROPSHADOW 0x00020000 +#endif + +static int MetaChanged(WPARAM wParam, LPARAM lParam) +{ + pcli->pfnClcBroadcast(INTM_METACHANGEDEVENT, wParam, lParam); + return 0; +} + +static BOOL g_AboutDlgActive = 0; + +INT_PTR CALLBACK DlgProcAbout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + COLORREF url_visited = RGB(128, 0, 128); + COLORREF url_unvisited = RGB(0, 0, 255); + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + { + int h; + HFONT hFont; + LOGFONT lf; + + g_AboutDlgActive = TRUE; + hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_GETFONT, 0, 0); + GetObject(hFont, sizeof(lf), &lf); + h = lf.lfHeight; + lf.lfHeight = (int)(lf.lfHeight * 1.5); + lf.lfWeight = FW_BOLD; + hFont = CreateFontIndirect(&lf); + SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_SETFONT, (WPARAM)hFont, 0); + lf.lfHeight = h; + hFont = CreateFontIndirect(&lf); + SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, (WPARAM)hFont, 0); + } + { + char str[64]; + DWORD v = pluginInfo.version; + mir_snprintf(str, sizeof(str), "%s %d.%d.%d.%d", Translate("Version"), HIBYTE(HIWORD(v)), LOBYTE(HIWORD(v)), HIBYTE(LOWORD(v)), LOBYTE(LOWORD(v))); + SetDlgItemTextA(hwndDlg, IDC_VERSION, str); + } + { + HICON hIcon = LoadIcon(GetModuleHandleA("miranda32.exe"), MAKEINTRESOURCE(102)); + SendDlgItemMessage(hwndDlg, IDC_LOGO, STM_SETICON, (WPARAM)hIcon, 0); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); + DestroyIcon(hIcon); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + case IDCANCEL: + DestroyWindow(hwndDlg); + return TRUE; + case IDC_SUPPORT: + CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://miranda-ng.org/"); + break; + } + break; + + case WM_CTLCOLOREDIT: + case WM_CTLCOLORSTATIC: + if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_WHITERECT) + || (HWND)lParam == GetDlgItem(hwndDlg, IDC_CLNICER) + || (HWND)lParam == GetDlgItem(hwndDlg, IDC_VERSION) + || (HWND)lParam == GetDlgItem(hwndDlg, IDC_COPYRIGHT) + || (HWND)lParam == GetDlgItem(hwndDlg, IDC_SUPPORT) + || (HWND)lParam == GetDlgItem(hwndDlg, IDC_LOGO)) + { + if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_CLNICER)) + SetTextColor((HDC)wParam, RGB(180, 10, 10)); + else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_VERSION)) + SetTextColor((HDC)wParam, RGB(70, 70, 70)); + else + SetTextColor((HDC)wParam, RGB(0, 0, 0)); + SetBkColor((HDC)wParam, RGB(255, 255, 255)); + return (INT_PTR)GetStockObject(WHITE_BRUSH); + } + break; + + case WM_DESTROY: + { + HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_GETFONT, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_CLNICER, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0), 0); + DeleteObject(hFont); + hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_GETFONT, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0), 0); + DeleteObject(hFont); + g_AboutDlgActive = FALSE; + } + break; + } + return FALSE; +} + +static INT_PTR CLN_ShowAbout(WPARAM wParam, LPARAM lParam) +{ + if (!g_AboutDlgActive) + CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CLNABOUT), 0, DlgProcAbout, 0); + return 0; +} + +static INT_PTR CLN_ShowMainMenu(WPARAM wParam, LPARAM lParam) +{ + HMENU hMenu; + POINT pt; + + hMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); + GetCursorPos(&pt); + TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL); + return 0; +} + +static INT_PTR CLN_ShowStatusMenu(WPARAM wParam, LPARAM lParam) +{ + HMENU hMenu; + POINT pt; + + hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); + GetCursorPos(&pt); + TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, pcli->hwndContactList, NULL); + return 0; +} + +#define MS_CLUI_SHOWMAINMENU "CList/ShowMainMenu" +#define MS_CLUI_SHOWSTATUSMENU "CList/ShowStatusMenu" + +void LoadCLUIModule(void) +{ + HookEvent(ME_SYSTEM_MODULESLOADED, CluiModulesLoaded); + + WNDCLASS wndclass; + wndclass.style = 0; + wndclass.lpfnWndProc = EventAreaWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = g_hInst; + wndclass.hIcon = 0; + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)COLOR_3DFACE; + wndclass.lpszMenuName = 0; + wndclass.lpszClassName = _T("EventAreaClass"); + RegisterClass(&wndclass); + + oldhideoffline = cfg::getByte("CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT); + cluiPos.left = cfg::getDword("CList", "x", 600); + cluiPos.top = cfg::getDword("CList", "y", 200); + cluiPos.right = cfg::getDword("CList", "Width", 150); + cluiPos.bottom = cfg::getDword("CList", "Height", 350); + + LoadExtraIconModule(); + LoadCLUIFramesModule(); + + CreateServiceFunction("CLN/About", CLN_ShowAbout); + CreateServiceFunction(MS_CLUI_SHOWMAINMENU, CLN_ShowMainMenu); + CreateServiceFunction(MS_CLUI_SHOWSTATUSMENU, CLN_ShowStatusMenu); + + if (cfg::getByte("CLUI", "FloaterMode", 0)) { + MessageBox(NULL, + TranslateT("You need the FloatingContacts plugin, cause the embedded floating contacts were removed."), + TranslateT("Warning"), MB_OK | MB_ICONWARNING); + db_unset(NULL, "CLUI", "FloaterMode"); + } +} + +void OnCreateClc() +{ + HookEvent(ME_MC_DEFAULTTCHANGED, MetaChanged); + HookEvent(ME_MC_SUBCONTACTSCHANGED, MetaChanged); + + InitGroupMenus(); + LoadExtBkSettingsFromDB(); + PreCreateCLC(pcli->hwndContactList); +} + +struct +{ + const TCHAR *tszName; + int iMask; +} +static clistFontDescr[] = { + { LPGENT("Standard contacts"), FIDF_CLASSGENERAL }, + { LPGENT("Online contacts to whom you have a different visibility"), FIDF_CLASSGENERAL }, + { LPGENT("Offline contacts"), FIDF_CLASSGENERAL }, + { LPGENT("Contacts which are 'not on list'"), FIDF_CLASSGENERAL }, + { LPGENT("Groups"), FIDF_CLASSHEADER }, + { LPGENT("Group member counts"), FIDF_CLASSHEADER }, + { LPGENT("Dividers"), FIDF_CLASSSMALL }, + { LPGENT("Offline contacts to whom you have a different visibility"), FIDF_CLASSGENERAL }, + { LPGENT("Status mode"), FIDF_CLASSGENERAL }, + { LPGENT("Frame titles"), FIDF_CLASSGENERAL }, + { LPGENT("Event area"), FIDF_CLASSGENERAL }, + { LPGENT("Contact list local time"), FIDF_CLASSGENERAL } +}; + +void FS_RegisterFonts() +{ + FontIDT fid = { sizeof(fid) }; + _tcsncpy(fid.group, LPGENT("Contact list"), SIZEOF(fid.group)); + strncpy(fid.dbSettingsGroup, "CLC", 5); + fid.flags = FIDF_DEFAULTVALID | FIDF_ALLOWEFFECTS | FIDF_APPENDNAME | FIDF_SAVEPOINTSIZE; + + HDC hdc = GetDC(NULL); + for (int i = 0; i < SIZEOF(clistFontDescr); i++) { + LOGFONT lf; + pcli->pfnGetFontSetting(i, &lf, &fid.deffontsettings.colour); + lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72); + + _tcsncpy_s(fid.deffontsettings.szFace, lf.lfFaceName, _TRUNCATE); + fid.deffontsettings.charset = lf.lfCharSet; + fid.deffontsettings.size = (char)lf.lfHeight; + fid.deffontsettings.style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0); + + fid.flags &= ~FIDF_CLASSMASK; + fid.flags |= clistFontDescr[i].iMask; + + _tcsncpy(fid.name, clistFontDescr[i].tszName, SIZEOF(fid.name)); + + char idstr[10]; + mir_snprintf(idstr, SIZEOF(idstr), "Font%d", i); + strncpy(fid.prefix, idstr, SIZEOF(fid.prefix)); + fid.order = i; + FontRegisterT(&fid); + } + ReleaseDC(NULL, hdc); + + // and colours + ColourIDT colourid = {0}; + colourid.cbSize = sizeof(colourid); + colourid.order = 0; + strncpy(colourid.dbSettingsGroup, "CLC", sizeof(colourid.dbSettingsGroup)); + + strncpy(colourid.setting, "BkColour", sizeof(colourid.setting)); + _tcsncpy(colourid.name, LPGENT("Background"), SIZEOF(colourid.name)); + _tcsncpy(colourid.group, LPGENT("Contact list"), SIZEOF(colourid.group)); + colourid.defcolour = CLCDEFAULT_BKCOLOUR; + ColourRegisterT(&colourid); + + strncpy(colourid.setting, "SelTextColour", sizeof(colourid.setting)); + _tcsncpy(colourid.name, LPGENT("Selected text"), SIZEOF(colourid.name)); + colourid.order = 1; + colourid.defcolour = CLCDEFAULT_SELTEXTCOLOUR; + ColourRegisterT(&colourid); + + strncpy(colourid.setting, "HotTextColour", sizeof(colourid.setting)); + _tcsncpy(colourid.name, LPGENT("Hottrack text"), SIZEOF(colourid.name)); + colourid.order = 1; + colourid.defcolour = CLCDEFAULT_HOTTEXTCOLOUR; + ColourRegisterT(&colourid); + + strncpy(colourid.setting, "QuickSearchColour", sizeof(colourid.setting)); + _tcsncpy(colourid.name, LPGENT("Quicksearch text"), SIZEOF(colourid.name)); + colourid.order = 1; + colourid.defcolour = CLCDEFAULT_QUICKSEARCHCOLOUR; + ColourRegisterT(&colourid); + + strncpy(colourid.dbSettingsGroup, "CLUI", sizeof(colourid.dbSettingsGroup)); + strncpy(colourid.setting, "clr_frameborder", sizeof(colourid.setting)); + _tcsncpy(colourid.name, LPGENT("Embedded frames border"), SIZEOF(colourid.name)); + colourid.order = 1; + colourid.defcolour = RGB(40, 40, 40); + ColourRegisterT(&colourid); +} -- cgit v1.2.3