/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2007 Artem Shpynov Copyright 2000-2008 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 "hdr/modern_commonheaders.h" #include "hdr/modern_commonprototypes.h" #include "./m_api/m_skinbutton.h" #include "m_toolbar.h" #include "hdr/modern_sync.h" //external definition COLORREF sttGetColor(char * module, char * color, COLORREF defColor); #define MS_CLUI_SHOWMAINMENU "CList/ShowMainMenu" #define MS_CLUI_SHOWSTATUSMENU "CList/ShowStatusMenu" #define MS_TTB_TOGGLEHIDEOFFLINE "CList/ToggleHideOffline" #define MIRANDATOOLBARCLASSNAME "MirandaToolBar" #define tbcheck if (!g_CluiData.hEventToolBarModuleLoaded) return #define tblock EnterCriticalSection(&tbdat.cs) #define tbunlock LeaveCriticalSection(&tbdat.cs) enum { MTBM_FIRST = WM_USER, MTBM_ADDBUTTON, // will be broad casted thought bars to add button MTBM_REPOSBUTTONS, MTBM_LAYEREDPAINT, MTBM_SETBUTTONSTATE, MTBM_SETBUTTONSTATEBYID, MTBM_GETBUTTONSTATE, MTBM_GETBUTTONSTATEBYID, MTBM_REMOVE_ALL_BUTTONS, MTBM_UPDATEFRAMEVISIBILITY, MTBM_REMOVEBUTTON, MTBM_LAST }; enum { SEPARATOR_NOT=0, SEPARATOR_FIXED, SEPARATOR_FLEX }; typedef struct _tag_MTB_BUTTONINFO { HWND hWindow; HWND hwndToolBar; char * szButtonID; // char * szButtonName; // The name of button (untranslated) char * szService; // Service to be executed TCHAR * szTooltip; TCHAR * szTooltipPressed; int nOrderValue; // Order of button BYTE position; BOOL bPushButton; // 2 icon state button. BYTE bSeparator; //0 - No, 2- flex, 1 -fixed HANDLE hPrimaryIconHandle; HANDLE hSecondaryIconHandle; BOOL bVisible; BYTE bPanelID; LPARAM lParam; void (*ParamDestructor)(void *); //will be called on parameters deletion }MTB_BUTTONINFO; typedef struct _tagMTBInfo { int cbSize; HANDLE hFrame; HWND hWnd; SortedList * pButtonList; int nButtonWidth; int nButtonHeight; int nButtonSpace; BOOL bFlatButtons; XPTHANDLE mtbXPTheme; BOOL fAutoSize; int nLineCount; WORD wLastHeight; BOOL fSingleLine; }MTBINFO; typedef struct _tag_MTB_GLOBALDAT { HANDLE hToolBarWindowList; //hooks and services handles HANDLE hehModulesLoaded; HANDLE hehSystemShutdown; HANDLE hehSettingsChanged; HANDLE hehOptInit; HANDLE hsvcToolBarAddButton; HANDLE hsvcToolBarRemoveButton; HANDLE hsvcToolBarGetButtonState; HANDLE hsvcToolBarSetButtonState; HBITMAP mtb_hBmpBackground; COLORREF mtb_bkColour; WORD mtb_backgroundBmpUse; BOOL mtb_useWinColors; HANDLE hHideOfflineButton; SortedList * listOfButtons; CRITICAL_SECTION cs; } MTB_GLOBALDAT; static INT_PTR svcToolBarAddButton(WPARAM wParam, LPARAM lParam); static INT_PTR svcToolBarRemoveButton(WPARAM wParam, LPARAM lParam); static INT_PTR svcToolBarGetButtonState(WPARAM wParam, LPARAM lParam); static INT_PTR svcToolBarGetButtonStateById(WPARAM wParam, LPARAM lParam); static INT_PTR svcToolBarSetButtonState(WPARAM wParam, LPARAM lParam); static INT_PTR svcToolBarSetButtonStateById(WPARAM wParam, LPARAM lParam); static int ehhToolbarModulesLoaded(WPARAM wParam, LPARAM lParam); static int ehhToolBarSystemShutdown(WPARAM wParam, LPARAM lParam); static int ehhToolBarSettingsChanged( WPARAM wParam, LPARAM lParam ); static int ehhToolBarBackgroundSettingsChanged(WPARAM wParam, LPARAM lParam); static int ehhToolbarOptInit(WPARAM wParam, LPARAM lParam); static MTB_BUTTONINFO * ToolBar_AddButtonToBars(MTB_BUTTONINFO * mtbi); static LRESULT CALLBACK ToolBar_WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); static LRESULT CALLBACK ToolBar_OptDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam); static int ToolBar_LayeredPaintProc(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData); static void ToolBar_DefaultButtonRegistration(); static void sttSetButtonPressed( char * szButton, BOOL bPressed ); static HWND sttCreateToolBarFrame( HWND hwndParent, char * szCaption, int nHeight ); static void sttGetButtonSettings(char * ID, BYTE * pbVisible, DWORD * pdwOrder, BYTE * pbPanelID); static void sttReloadButtons(); static void sttTBButton2MTBBUTTONINFO(TBButton * bi, MTB_BUTTONINFO * mtbi); static int sttSortButtons(const void * vmtbi1, const void * vmtbi2); static MTB_GLOBALDAT tbdat ={0}; //destructor for MTB_BUTTONINFO static void delete_MTB_BUTTONINFO(void * input) { MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)input; if (mtbi->hWindow && IsWindow(mtbi->hWindow)) DestroyWindow(mtbi->hWindow); mir_safe_free(mtbi->szButtonID); mir_safe_free(mtbi->szButtonName); mir_safe_free(mtbi->szService); mir_safe_free(mtbi->szTooltip); mir_safe_free(mtbi->szTooltipPressed); mir_safe_free(mtbi); } HRESULT ToolbarLoadModule() { tbdat.hehModulesLoaded=ModernHookEvent(ME_SYSTEM_MODULESLOADED, ehhToolbarModulesLoaded); tbdat.hehSystemShutdown=ModernHookEvent(ME_SYSTEM_SHUTDOWN, ehhToolBarSystemShutdown); { //create window class WNDCLASS wndclass={0}; if (GetClassInfo(g_hInst,_T(MIRANDATOOLBARCLASSNAME),&wndclass) ==0) { wndclass.style = 0; wndclass.lpfnWndProc = ToolBar_WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = g_hInst; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = _T(MIRANDATOOLBARCLASSNAME); RegisterClass(&wndclass); } } tbdat.listOfButtons=li.List_Create(0,1); InitializeCriticalSection(&tbdat.cs); return S_OK; } static int ehhToolbarModulesLoaded(WPARAM wParam, LPARAM lParam) { CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)"ToolBar Background/ToolBar",0); ModernHookEvent(ME_BACKGROUNDCONFIG_CHANGED,ehhToolBarBackgroundSettingsChanged); tbdat.hehOptInit=ModernHookEvent(ME_OPT_INITIALISE,ehhToolbarOptInit); ehhToolBarBackgroundSettingsChanged(0,0); tbdat.hehSettingsChanged=ModernHookEvent(ME_DB_CONTACT_SETTINGCHANGED, ehhToolBarSettingsChanged ); tbdat.hToolBarWindowList=(HANDLE) CallService(MS_UTILS_ALLOCWINDOWLIST,0,0); CreateServiceFunction(MS_TB_ADDBUTTON,svcToolBarAddButton); CreateServiceFunction(MS_TB_REMOVEBUTTON, svcToolBarRemoveButton); CreateServiceFunction(MS_TB_SETBUTTONSTATE, svcToolBarSetButtonState); CreateServiceFunction(MS_TB_SETBUTTONSTATEBYID, svcToolBarSetButtonStateById); CreateServiceFunction(MS_TB_GETBUTTONSTATE, svcToolBarGetButtonState); CreateServiceFunction(MS_TB_GETBUTTONSTATEBYID, svcToolBarGetButtonStateById); HWND hwndClist=(HWND) CallService(MS_CLUI_GETHWND,0,0); sttCreateToolBarFrame( hwndClist, ("ToolBar"), 24); NotifyEventHooks(g_CluiData.hEventToolBarModuleLoaded, 0, 0); return 0; } static int ehhToolBarSystemShutdown(WPARAM wParam, LPARAM lParam) { //Remove services; ModernUnhookEvent(tbdat.hehSettingsChanged); ModernUnhookEvent(tbdat.hehModulesLoaded); ModernUnhookEvent(tbdat.hehSystemShutdown); ModernUnhookEvent(tbdat.hehOptInit); EnterCriticalSection(&tbdat.cs); g_CluiData.hEventToolBarModuleLoaded=NULL; li_ListDestruct(tbdat.listOfButtons,delete_MTB_BUTTONINFO); LeaveCriticalSection(&tbdat.cs); DeleteCriticalSection(&tbdat.cs); return 0; } static int ehhToolBarSettingsChanged( WPARAM wParam, LPARAM lParam ) { DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam; if ((HANDLE)wParam!=NULL) return 0; if (!mir_strcmp(cws->szModule,"CList")) { if (!mir_strcmp(cws->szSetting,"HideOffline")) sttSetButtonPressed("ShowHideOffline", (BOOL) ModernGetSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ); else if (!mir_strcmp(cws->szSetting,"UseGroups")) sttSetButtonPressed( "UseGroups", (BOOL) ModernGetSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ); } else if (!mir_strcmp(cws->szModule,"Skin")) { if (!mir_strcmp(cws->szSetting,"UseSound")) sttSetButtonPressed( "EnableSounds", (BOOL) ModernGetSettingByte(NULL, "Skin", "UseSound", SETTING_ENABLESOUNDS_DEFAULT ) ); } return 0; } static int ehhToolBarBackgroundSettingsChanged(WPARAM wParam, LPARAM lParam) { if(tbdat.mtb_hBmpBackground) { DeleteObject(tbdat.mtb_hBmpBackground); tbdat.mtb_hBmpBackground=NULL; } if (g_CluiData.fDisableSkinEngine) { DBVARIANT dbv; tbdat.mtb_bkColour=sttGetColor("ToolBar","BkColour",CLCDEFAULT_BKCOLOUR); if(ModernGetSettingByte(NULL,"ToolBar","UseBitmap",CLCDEFAULT_USEBITMAP)) { if (!ModernGetSettingString(NULL,"ToolBar","BkBitmap",&dbv)) { tbdat.mtb_hBmpBackground=(HBITMAP)CallService(MS_UTILS_LOADBITMAP,0,(LPARAM)dbv.pszVal); ModernDBFreeVariant(&dbv); } } tbdat.mtb_useWinColors = ModernGetSettingByte(NULL, "ToolBar", "UseWinColours", CLCDEFAULT_USEWINDOWSCOLOURS); tbdat.mtb_backgroundBmpUse = ModernGetSettingWord(NULL, "ToolBar", "BkBmpUse", CLCDEFAULT_BKBMPUSE); } PostMessage(pcli->hwndContactList,WM_SIZE,0,0); return 0; } static int ehhToolbarOptInit(WPARAM wParam, LPARAM lParam) { OPTIONSDIALOGPAGE odp; ZeroMemory(&odp,sizeof(odp)); odp.cbSize=sizeof(odp); odp.position=0; odp.hInstance=g_hInst; odp.ptszGroup=LPGENT("Contact List"); odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_TOOLBAR); odp.ptszTitle=LPGENT("ToolBar"); odp.pfnDlgProc=(DLGPROC)ToolBar_OptDlgProc; odp.flags=ODPF_BOLDGROUPS|ODPF_TCHAR; CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); return 0; } static INT_PTR svcToolBarAddButton(WPARAM wParam, LPARAM lParam) { INT_PTR result=0; BYTE bVisible; BYTE bPanel; DWORD dwOrder; TBButton * bi=(TBButton *)lParam; bVisible=(bi->tbbFlags&TBBF_VISIBLE ? TRUE : FALSE); if (!ServiceExists(bi->pszServiceName)) return 0; tbcheck 0; tblock; { MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)mir_calloc(sizeof(MTB_BUTTONINFO)); sttTBButton2MTBBUTTONINFO(bi,mtbi); sttGetButtonSettings(mtbi->szButtonID, &bVisible, &dwOrder, &bPanel); mtbi->nOrderValue = dwOrder ? dwOrder : bi->defPos; mtbi->bVisible = bVisible; mtbi->bPanelID = bPanel; li.List_InsertPtr(tbdat.listOfButtons,mtbi); if (mtbi->bVisible) result=(INT_PTR)ToolBar_AddButtonToBars(mtbi); } tbunlock; return result; } static INT_PTR svcToolBarRemoveButton(WPARAM wParam, LPARAM lParam) { HANDLE hButton=(HANDLE)wParam; tbcheck 0; tblock; WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_REMOVEBUTTON, wParam, lParam); tbunlock; return 0; } static INT_PTR svcToolBarGetButtonState(WPARAM wParam, LPARAM lParam) { int res=-1; WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_GETBUTTONSTATE, wParam, (LPARAM) &res); return res; } static INT_PTR svcToolBarGetButtonStateById(WPARAM wParam, LPARAM lParam) { int res=-1; WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_GETBUTTONSTATEBYID, wParam, (LPARAM) &res); return res; } static INT_PTR svcToolBarSetButtonState(WPARAM wParam, LPARAM lParam) { WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_SETBUTTONSTATE, wParam, lParam); return 0; } static INT_PTR svcToolBarSetButtonStateById(WPARAM wParam, LPARAM lParam) { WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_SETBUTTONSTATEBYID, wParam, lParam); return 0; } static void sttTBButton2MTBBUTTONINFO(TBButton * bi, MTB_BUTTONINFO * mtbi) { // Convert TBButton struct to MTB_BUTTONINFO if (!bi || !mtbi) return; if (!(bi->tbbFlags&TBBF_ISSEPARATOR)) { mtbi->szButtonName=mir_strdup(bi->pszButtonName); mtbi->szService=mir_strdup(bi->pszServiceName); mtbi->szButtonID=mir_strdup(bi->pszButtonID); mtbi->bPushButton=(bi->tbbFlags&TBBF_PUSHED)?TRUE:FALSE; mtbi->szTooltip=mir_a2t(Translate(bi->pszTooltipUp)); mtbi->szTooltipPressed=mir_a2t(Translate(bi->pszTooltipDn)); mtbi->bSeparator=SEPARATOR_NOT; mtbi->hPrimaryIconHandle=bi->hPrimaryIconHandle; mtbi->hSecondaryIconHandle=bi->hSecondaryIconHandle; mtbi->lParam=bi->lParam; } else { mtbi->nOrderValue=bi->defPos; mtbi->bSeparator= (((bi->tbbFlags & TBBF_FLEXSIZESEPARATOR) == TBBF_FLEXSIZESEPARATOR)? SEPARATOR_FLEX : ((bi->tbbFlags & TBBF_ISSEPARATOR) == TBBF_ISSEPARATOR)? SEPARATOR_FIXED : SEPARATOR_NOT); } mtbi->bVisible = ((bi->tbbFlags&TBBF_VISIBLE)!=0); } static void sttUpdateButtonState(MTB_BUTTONINFO * mtbi) { HANDLE ilIcon; ilIcon=(mtbi->bPushButton)?mtbi->hSecondaryIconHandle:mtbi->hPrimaryIconHandle; SendMessage(mtbi->hWindow, MBM_SETICOLIBHANDLE, 0, (LPARAM) ilIcon ); SendMessage(mtbi->hWindow, BUTTONADDTOOLTIP, (WPARAM)((mtbi->bPushButton) ? mtbi->szTooltipPressed : mtbi->szTooltip), 0); } static int sttSortButtons(const void * vmtbi1, const void * vmtbi2) { MTB_BUTTONINFO * mtbi1=(MTB_BUTTONINFO *)*((MTB_BUTTONINFO ** )vmtbi1); MTB_BUTTONINFO * mtbi2=(MTB_BUTTONINFO *)*((MTB_BUTTONINFO ** )vmtbi2); if (mtbi1==NULL || mtbi2==NULL) return (mtbi1-mtbi2); return mtbi1->nOrderValue-mtbi2->nOrderValue; } static int sttReposButtons(MTBINFO * mti) { RECT rcClient; HDWP hdwp; int nBarSize; int nFlexSeparatorsCount=0; int nUsedWidth=0; int i=0; int nextX=0; int nFreeSpace; BOOL bWasButttonBefore=FALSE; int iFirstButtonId=0; int iLastButtonId=0; int y=0; // firstly let sort it by order qsort(mti->pButtonList->items,mti->pButtonList->realCount,sizeof(MTB_BUTTONINFO *),sttSortButtons); GetClientRect(mti->hWnd, &rcClient); nBarSize=rcClient.right-rcClient.left; if (nBarSize == 0) return 0; mti->nLineCount=0; hdwp=BeginDeferWindowPos( mti->pButtonList->realCount ); do { ++mti->nLineCount; bWasButttonBefore=FALSE; nUsedWidth=0; //calculating count of visible buttons and separators in line for (i=iFirstButtonId; ipButtonList->realCount; i++) { MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)mti->pButtonList->items[i]; if ( mtbi->bSeparator==2 ) nFlexSeparatorsCount++; else { int width=(mtbi->bSeparator==1)? 4 : mti->nButtonWidth+(bWasButttonBefore ? mti->nButtonSpace : 0); if (nUsedWidth+width>nBarSize) break; nUsedWidth+=width; } iLastButtonId=i+1; bWasButttonBefore= (mtbi->bSeparator == 0) ? TRUE : FALSE; } nFreeSpace=nBarSize-nUsedWidth; for (i=iFirstButtonId; ipButtonList->items[i]; if (mtbi->hWindow) { if (hdwp) { //if (nextX+mti->nButtonWidth +mti->nButtonSpace <= nBarSize) hdwp=DeferWindowPos(hdwp, mtbi->hWindow, NULL, nextX, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW/*|SWP_NOREDRAW*/); //else break; // hdwp=DeferWindowPos(hdwp, mtbi->hWindow, NULL, nextX, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_HIDEWINDOW|SWP_NOREDRAW); } nextX+=mti->nButtonWidth+mti->nButtonSpace; } else if ( mtbi->bSeparator==1 ) { nextX+=4; } else if (nFlexSeparatorsCount>0) { nextX+=nFreeSpace/nFlexSeparatorsCount; nFreeSpace-=nFreeSpace/nFlexSeparatorsCount; nFlexSeparatorsCount--; } } if ( iFirstButtonId == iLastButtonId ) break; iFirstButtonId = iLastButtonId; y+=mti->nButtonHeight+mti->nButtonSpace; nextX=0; if (mti->fSingleLine) break; } while (iFirstButtonIdpButtonList->realCount && y >= 0 &&(mti->fAutoSize || (y+mti->nButtonHeight <= rcClient.bottom-rcClient.top))); for (i=iFirstButtonId; i< mti->pButtonList->realCount; i++) { MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)mti->pButtonList->items[i]; if (mtbi->hWindow && hdwp) { hdwp=DeferWindowPos(hdwp, mtbi->hWindow, NULL, nextX, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_HIDEWINDOW/*|SWP_NOREDRAW*/); } } if (hdwp) EndDeferWindowPos(hdwp); return (mti->nButtonHeight+mti->nButtonSpace)*mti->nLineCount-mti->nButtonSpace; } static HWND sttCreateToolBarFrame( HWND hwndParent, char * szCaption, int nHeight ) { TCHAR * Caption=mir_a2t(szCaption); HWND hwnd=CreateWindow(_T(MIRANDATOOLBARCLASSNAME), TranslateTS(Caption), WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN,0,0,0,nHeight,hwndParent,NULL,g_hInst, (void*) szCaption); mir_free(Caption); return hwnd; } static int sttButtonPressed(MTBINFO * pMTBInfo, HWND hwndbutton) { MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)GetWindowLongPtr(hwndbutton, GWLP_USERDATA); if (mtbi && mtbi->hWindow==hwndbutton && mtbi->hwndToolBar==pMTBInfo->hWnd) { if (mtbi->szService && ServiceExists(mtbi->szService)) return CallService(mtbi->szService, 0, mtbi->lParam); } return 0; } static BOOL sttDrawToolBarBackground(HWND hwnd, HDC hdc, RECT * rect, MTBINFO * pMTBInfo) { BOOL bFloat = (GetParent(hwnd)!=pcli->hwndContactList); if (g_CluiData.fDisableSkinEngine || !g_CluiData.fLayered || bFloat) { RECT rc; HBRUSH hbr; if (rect) rc=*rect; else GetClientRect(hwnd,&rc); if (!(tbdat.mtb_backgroundBmpUse && tbdat.mtb_hBmpBackground) && tbdat.mtb_useWinColors) { if (xpt_IsThemed(pMTBInfo->mtbXPTheme)) { xpt_DrawTheme(pMTBInfo->mtbXPTheme,pMTBInfo->hWnd, hdc, 0, 0, &rc, &rc); } else { hbr=GetSysColorBrush(COLOR_3DFACE); FillRect(hdc, &rc, hbr); } } else if (!tbdat.mtb_hBmpBackground && !tbdat.mtb_useWinColors) { hbr=CreateSolidBrush(tbdat.mtb_bkColour); FillRect(hdc, &rc, hbr); DeleteObject(hbr); } else { DrawBackGround(hwnd,hdc,tbdat.mtb_hBmpBackground,tbdat.mtb_bkColour,tbdat.mtb_backgroundBmpUse); } } return TRUE; } static void sttRegisterToolBarButton(char * pszButtonID, char * pszButtonName, char * pszServiceName, char * pszTooltipUp, char * pszTooltipDn, int icoDefIdx, int defResource, int defResource2, BOOL bVisByDefault) { TBButton tbb; static int defPos=0; defPos+=100; memset(&tbb,0, sizeof(TBButton)); tbb.cbSize=sizeof(TBButton); if (pszButtonID) { tbb.defPos=defPos; tbb.pszButtonID=pszButtonID; tbb.pszButtonName=pszButtonName; tbb.pszServiceName=pszServiceName; tbb.pszTooltipUp=pszTooltipUp; tbb.pszTooltipDn=pszTooltipDn; { char buf[255]; mir_snprintf(buf,SIZEOF(buf),"%s%s%s",TOOLBARBUTTON_ICONIDPREFIX, pszButtonID, TOOLBARBUTTON_ICONIDPRIMARYSUFFIX); tbb.hPrimaryIconHandle=RegisterIcolibIconHandle( buf, "ToolBar", pszButtonName , _T("icons\\toolbar_icons.dll"),-icoDefIdx, g_hInst, defResource ); } if (pszTooltipDn) { char buf[255]; mir_snprintf(buf,SIZEOF(buf),"%s%s%s",TOOLBARBUTTON_ICONIDPREFIX, pszButtonID, TOOLBARBUTTON_ICONIDSECONDARYSUFFIX); tbb.hSecondaryIconHandle=RegisterIcolibIconHandle( buf, "ToolBar", pszTooltipDn , _T("icons\\toolbar_icons.dll"),-(icoDefIdx+1), g_hInst, defResource2 ); } } else { if ( pszButtonName[0] == 'D' ) tbb.tbbFlags=TBBF_FLEXSIZESEPARATOR; else tbb.tbbFlags=TBBF_ISSEPARATOR; } tbb.tbbFlags|=(bVisByDefault ? TBBF_VISIBLE :0 ); CallService(MS_TB_ADDBUTTON,0, (LPARAM)&tbb); } static void sttSetButtonPressed( char * hButton, BOOL bPressed ) { CallService(MS_TB_SETBUTTONSTATEBYID, (WPARAM) hButton, (LPARAM) (bPressed ? TBST_PUSHED : TBST_RELEASED) ); } static void sttAddStaticSeparator( BOOL bVisibleByDefault ) { sttRegisterToolBarButton( NULL, "Separator", NULL, NULL, NULL, 0, 0, 0, bVisibleByDefault ); } static void sttAddDynamicSeparator( BOOL bVisibleByDefault ) { sttRegisterToolBarButton( NULL, "Dynamic separator", NULL, NULL, NULL, 0, 0, 0, bVisibleByDefault ); } static void sttGetButtonSettings(char * ID, BYTE * pbVisible, DWORD * pdwOrder, BYTE * pbPanelID) { char key[255]={0}; BYTE vis=1; DWORD ord; BYTE panel; if (pbVisible) vis=*pbVisible; mir_snprintf(key, SIZEOF(key), "visible_%s", ID); vis=ModernGetSettingByte(NULL,"ModernToolBar", key, vis); mir_snprintf(key, SIZEOF(key), "order_%s", ID); ord=ModernGetSettingDword(NULL,"ModernToolBar", key, 0); mir_snprintf(key, SIZEOF(key), "panel_%s", ID); panel=ModernGetSettingByte(NULL,"ModernToolBar", key, 0); if (pbVisible) *pbVisible=vis; if (pdwOrder) *pdwOrder=ord; if (pbPanelID) *pbPanelID=panel; } static void sttReloadButtons() { int i=0; tbcheck ; tblock; { int vis=ModernGetSettingByte(NULL,"CLUI","ShowButtonBar",SETTINGS_SHOWBUTTONBAR_DEFAULT); WindowList_Broadcast(tbdat.hToolBarWindowList,MTBM_UPDATEFRAMEVISIBILITY,(WPARAM)ModernGetSettingByte(NULL,"CLUI","ShowButtonBar",SETTINGS_SHOWBUTTONBAR_DEFAULT),0); } WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_REMOVE_ALL_BUTTONS, 0,0); for (i=0; irealCount; i++) { BYTE bVisible; BYTE bPanel; DWORD dwOrder; MTB_BUTTONINFO * mtbi = (MTB_BUTTONINFO *)tbdat.listOfButtons->items[i]; bVisible=mtbi->bVisible; sttGetButtonSettings(mtbi->szButtonID, &bVisible, &dwOrder, &bPanel); mtbi->nOrderValue = dwOrder ? dwOrder : mtbi->nOrderValue; mtbi->bVisible = bVisible; mtbi->bPanelID = bPanel; if (mtbi->bVisible) ToolBar_AddButtonToBars(mtbi); } tbunlock; sttSetButtonPressed( "ShowHideOffline", (BOOL) ModernGetSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ); sttSetButtonPressed( "UseGroups", (BOOL) ModernGetSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ); sttSetButtonPressed( "EnableSounds", (BOOL) ModernGetSettingByte(NULL, "Skin", "UseSound", SETTING_ENABLESOUNDS_DEFAULT ) ); } static int sttDBEnumProc (const char *szSetting,LPARAM lParam) { if (szSetting==NULL) return 0; if (!strncmp(szSetting,"order_",6)) ModernDeleteSetting(NULL, "ModernToolBar", szSetting); return 0; }; static void sttDeleteOrderSettings() { DBCONTACTENUMSETTINGS dbces; dbces.pfnEnumProc=sttDBEnumProc; dbces.szModule="ToolBar"; dbces.ofsSettings=0; CallService(MS_DB_CONTACT_ENUMSETTINGS,0,(LPARAM)&dbces); } static MTB_BUTTONINFO * ToolBar_AddButtonToBars(MTB_BUTTONINFO * mtbi) { int result=0; if (!mtbi->bVisible) return 0; WindowList_Broadcast(tbdat.hToolBarWindowList, MTBM_ADDBUTTON, (WPARAM)mtbi, 0); if (mtbi->hWindow) sttUpdateButtonState( mtbi ); if (mtbi->hwndToolBar) SendMessage( mtbi->hwndToolBar, MTBM_REPOSBUTTONS, 0, 0); return mtbi; } static int ToolBar_LayeredPaintProc(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData) { return SendMessage(hWnd, MTBM_LAYEREDPAINT,(WPARAM)hDC,0); } static void ToolBar_DefaultButtonRegistration() { sttRegisterToolBarButton( "MainMenu", "Main Menu", MS_CLUI_SHOWMAINMENU, "Main menu", NULL, 100 , IDI_RESETVIEW, IDI_RESETVIEW, TRUE ); sttRegisterToolBarButton( "StatusMenu", "Status Menu", MS_CLUI_SHOWSTATUSMENU, "Status menu", NULL, 105 , IDI_RESETVIEW, IDI_RESETVIEW, TRUE ); sttRegisterToolBarButton( "AccoMgr", "Accounts", MS_PROTO_SHOWACCMGR, "Accounts...", NULL, 282 , IDI_ACCMGR, IDI_ACCMGR, TRUE ); sttRegisterToolBarButton( "ShowHideOffline","Show/Hide offline contacts", MS_CLIST_TOGGLEHIDEOFFLINE, "Hide offline contacts", "Show offline contacts", 110 /*and 111 */ , IDI_RESETVIEW, IDI_RESETVIEW, TRUE ); sttSetButtonPressed( "ShowHideOffline", (BOOL) ModernGetSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ); sttRegisterToolBarButton( "DatabaseEditor","DBEditor++", "DBEditorpp/MenuCommand", "Database Editor", NULL, 130 , IDI_RESETVIEW, IDI_RESETVIEW, TRUE ); sttRegisterToolBarButton( "FindUser","Find User", "FindAdd/FindAddCommand", "Find User", NULL, 140 , IDI_RESETVIEW, IDI_RESETVIEW, TRUE ); sttRegisterToolBarButton( "Options","Options", "Options/OptionsCommand", "Options", NULL, 150 , IDI_RESETVIEW, IDI_RESETVIEW, TRUE ); sttRegisterToolBarButton( "UseGroups","Use/Disable groups", MS_CLIST_TOGGLEGROUPS, "Use groups", "Disable Groups", 160 /*and 161 */ , IDI_RESETVIEW, IDI_RESETVIEW, FALSE ); sttSetButtonPressed( "UseGroups", (BOOL) ModernGetSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ); sttRegisterToolBarButton( "EnableSounds","Enable/Disable sounds", MS_CLIST_TOGGLESOUNDS, "Enable sounds", "Disable Sounds", 170 /*and 171 */ , IDI_RESETVIEW, IDI_RESETVIEW, FALSE ); sttSetButtonPressed( "EnableSounds", (BOOL) ModernGetSettingByte(NULL, "Skin", "UseSound", SETTING_ENABLESOUNDS_DEFAULT ) ); sttAddDynamicSeparator(FALSE); sttRegisterToolBarButton( "Minimize","Minimize", "CList/ShowHide", "Minimize", NULL, 180 , IDI_RESETVIEW, IDI_RESETVIEW, FALSE ); sttReloadButtons(); } static void sttDrawNonLayeredSkinedBar(HWND hwnd, HDC hdc) { HDC hdc2; HBITMAP hbmp,hbmpo; RECT rc={0}; GetClientRect(hwnd,&rc); rc.right++; rc.bottom++; hdc2=CreateCompatibleDC(hdc); hbmp=ske_CreateDIB32(rc.right,rc.bottom); hbmpo=(HBITMAP)SelectObject(hdc2,hbmp); if (GetParent(hwnd)!=pcli->hwndContactList) { HBRUSH br=GetSysColorBrush(COLOR_3DFACE); FillRect(hdc2,&rc,br); } else ske_BltBackImage(hwnd,hdc2,&rc); SendMessage(hwnd,MTBM_LAYEREDPAINT, (WPARAM)hdc2, 0); BitBlt(hdc,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top, hdc2,rc.left,rc.top,SRCCOPY); SelectObject(hdc2,hbmpo); DeleteObject(hbmp); mod_DeleteDC(hdc2); SelectObject(hdc,(HFONT)GetStockObject(DEFAULT_GUI_FONT)); ValidateRect(hwnd,NULL); } static LRESULT CALLBACK ToolBar_WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { static BOOL supressRepos=FALSE; MTBINFO * pMTBInfo=(MTBINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch (msg) { case WM_CREATE: { HANDLE hFrame=NULL; CLISTFrame Frame={0}; CREATESTRUCT * lpcs = (CREATESTRUCT *) lParam; //create internal info MTBINFO * pMTBInfo = (MTBINFO *) mir_calloc( sizeof(MTBINFO) ); pMTBInfo->cbSize = sizeof(MTBINFO); SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR) pMTBInfo ); pMTBInfo->nButtonWidth = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnWidth", SETTINGS_BARBTNWIDTH_DEFAULT); pMTBInfo->nButtonHeight= ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnHeight", SETTINGS_BARBTNHEIGHT_DEFAULT); pMTBInfo->nButtonSpace = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnSpace", SETTINGS_BARBTNSPACE_DEFAULT); pMTBInfo->fAutoSize = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Autosize", SETTINGS_BARAUTOSIZE_DEFAULT); pMTBInfo->fSingleLine = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Multiline", SETTINGS_BARMULTILINE_DEFAULT)==0; //register self frame Frame.cbSize=sizeof(CLISTFrame); Frame.hWnd=hwnd; Frame.align=alTop; Frame.hIcon=LoadSkinnedIcon (SKINICON_OTHER_MIRANDA); Frame.Flags=(ModernGetSettingByte(NULL,"CLUI","ShowButtonBar",SETTINGS_SHOWBUTTONBAR_DEFAULT)?F_VISIBLE:0)|F_LOCKED|F_NOBORDER|F_NO_SUBCONTAINER; Frame.height=ModernGetSettingDword(NULL, "ModernToolBar", "option_Bar0_OldHeight", pMTBInfo->nButtonHeight); pMTBInfo->wLastHeight=Frame.height; pMTBInfo->nLineCount = 1; pMTBInfo->pButtonList=li.List_Create(0,1); Frame.name=(char*) lpcs->lpCreateParams; hFrame=(HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&Frame,(LPARAM)0); CallService(MS_SKINENG_REGISTERPAINTSUB,(WPARAM)Frame.hWnd,(LPARAM)ToolBar_LayeredPaintProc); //$$$$$ register sub for frame pMTBInfo->hFrame = hFrame; pMTBInfo->hWnd = hwnd; //add self to window list WindowList_Add(tbdat.hToolBarWindowList, hwnd, NULL); pMTBInfo->mtbXPTheme=xpt_AddThemeHandle(hwnd,L"TOOLBAR"); ToolBar_DefaultButtonRegistration(); //SetTimer(hwnd,123,1000,NULL); return 0; } case WM_TIMER: { //KillTimer(hwnd,123); //ToolBar_DefaultButtonRegistration(); return 0; } case WM_SHOWWINDOW: { { int res; int ID; ID= Sync( FindFrameID, hwnd ); if (ID) { res=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS,ID),0); if (res>=0) ModernWriteSettingByte(0,"CLUI","ShowButtonBar",(BYTE)(wParam/*(res&F_VISIBLE)*/?1:0)); if (wParam) SendMessage(hwnd, MTBM_REPOSBUTTONS, 0, 0); } } break; } case MTBM_UPDATEFRAMEVISIBILITY: { BOOL vis=(BOOL)wParam; INT_PTR frameopt; BOOL curvis=IsWindowVisible(hwnd); BOOL bResize=FALSE; int frameID=Sync( FindFrameID, hwnd ); int Height; pMTBInfo->nButtonWidth = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnWidth", SETTINGS_BARBTNWIDTH_DEFAULT); pMTBInfo->nButtonHeight= ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnHeight", SETTINGS_BARBTNHEIGHT_DEFAULT); pMTBInfo->nButtonSpace = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnSpace", SETTINGS_BARBTNSPACE_DEFAULT); pMTBInfo->fAutoSize = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Autosize", SETTINGS_BARAUTOSIZE_DEFAULT); pMTBInfo->fSingleLine = ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Multiline", SETTINGS_BARMULTILINE_DEFAULT)==0; Height=sttReposButtons( pMTBInfo ); if (pMTBInfo->fAutoSize) { frameopt=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT,frameID),0); if (Height!=frameopt) { frameopt=Height; CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_HEIGHT,frameID),frameopt); bResize=TRUE; } } if ((curvis!=vis || bResize) && vis !=-1) { frameopt=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS,frameID),0); frameopt&=~F_VISIBLE; frameopt|=vis ? F_VISIBLE : 0; CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,frameID),frameopt); } break; } case WM_DESTROY: { xpt_FreeThemeForWindow(hwnd); WindowList_Remove( tbdat.hToolBarWindowList, hwnd ); SendMessage(hwnd, MTBM_REMOVE_ALL_BUTTONS, 0, 0 ); li.List_Destroy( pMTBInfo->pButtonList ); mir_free( pMTBInfo->pButtonList ); SetWindowLongPtr( hwnd, GWLP_USERDATA, 0 ); mir_free( pMTBInfo ); return 0; } case WM_COMMAND: { if (HIWORD(wParam)==BN_CLICKED && lParam!=0 ) sttButtonPressed(pMTBInfo, (HWND) lParam ); return TRUE; } case MTBM_ADDBUTTON: { //Adding button MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO * )wParam; HWND hwndButton = NULL; if (!(mtbi->bSeparator)) hwndButton= CreateWindow(SKINBUTTONCLASS /*MIRANDABUTTONCLASS*/, _T(""), BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP , 0, 0, pMTBInfo->nButtonWidth, pMTBInfo->nButtonHeight, hwnd, (HMENU) NULL, g_hInst, NULL); mtbi->hWindow=hwndButton; mtbi->hwndToolBar=hwnd; li.List_Insert(pMTBInfo->pButtonList, mtbi, pMTBInfo->pButtonList->realCount); //just insert pointer. such object are managed in global tbbutton list if (hwndButton) { char * buttonId=(char *)_alloca(sizeof("ToolBar.")+strlen(mtbi->szButtonID)+2); strcpy(buttonId,"ToolBar."); strcat(buttonId,mtbi->szButtonID); SendMessage(hwndButton, BUTTONSETID, 0 ,(LPARAM) buttonId ); if (pMTBInfo->bFlatButtons) SendMessage(hwndButton, BUTTONSETASFLATBTN, 0, 1 ); SetWindowLongPtr(hwndButton,GWLP_USERDATA,(LONG_PTR)mtbi); SendMessage(hwndButton, MBM_UPDATETRANSPARENTFLAG, 0, 2); } return (LRESULT)hwndButton; } case MTBM_REMOVE_ALL_BUTTONS: { int i; for (i=0; ipButtonList->realCount; i++ ) { MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)pMTBInfo->pButtonList->items[i]; if (mtbi->hWindow && mtbi->hwndToolBar==hwnd) { DestroyWindow(mtbi->hWindow); mtbi->hWindow = NULL; mtbi->hwndToolBar = NULL; } } li.List_Destroy( pMTBInfo->pButtonList ); mir_free( pMTBInfo->pButtonList ); pMTBInfo->pButtonList=li.List_Create(0,1); break; } case WM_SIZE: if (pMTBInfo->wLastHeight!=HIWORD(lParam)) { ModernWriteSettingDword(NULL, "ModernToolBar", "option_Bar0_OldHeight", HIWORD(lParam)); pMTBInfo->wLastHeight=HIWORD(lParam); } if (supressRepos) { supressRepos=FALSE; break; } //fall through case MTBM_REPOSBUTTONS: { if (pMTBInfo && pMTBInfo->hWnd == hwnd) { int Height=sttReposButtons(pMTBInfo); if ( pMTBInfo->fAutoSize) { RECT rcClient; GetClientRect(pMTBInfo->hWnd, &rcClient); if (rcClient.bottom-rcClient.top != Height && Height) { supressRepos=TRUE; PostMessage(pMTBInfo->hWnd,MTBM_UPDATEFRAMEVISIBILITY, -1, 0); } } return 0; } break; } case WM_ERASEBKGND: if (g_CluiData.fDisableSkinEngine) return sttDrawToolBarBackground(hwnd, (HDC)wParam, NULL, pMTBInfo); else return 0; case WM_NCPAINT: case WM_PAINT: { BOOL ret=FALSE; PAINTSTRUCT ps; BOOL bFloat = (GetParent(hwnd)!=pcli->hwndContactList); if (g_CluiData.fDisableSkinEngine|| !g_CluiData.fLayered || bFloat ) { BeginPaint(hwnd,&ps); if ((!g_CluiData.fLayered || bFloat) && !g_CluiData.fDisableSkinEngine) { sttDrawNonLayeredSkinedBar(hwnd, ps.hdc); } else ret=sttDrawToolBarBackground(hwnd, ps.hdc, &ps.rcPaint, pMTBInfo); EndPaint(hwnd,&ps); } return DefWindowProc(hwnd, msg, wParam, lParam); } case WM_NOTIFY: { if (((LPNMHDR) lParam)->code==BUTTONNEEDREDRAW) pcli->pfnInvalidateRect(hwnd, NULL, FALSE); return 0; } case MTBM_LAYEREDPAINT: { int i; RECT MyRect={0}; HDC hDC=(HDC)wParam; GetWindowRect(hwnd,&MyRect); { RECT rcClient; GetClientRect(hwnd, &rcClient); SkinDrawGlyph(hDC,&rcClient,&rcClient,"Bar,ID=ToolBar,Part=Background"); } for (i=0; ipButtonList->realCount; i++) { RECT childRect; POINT Offset; MTB_BUTTONINFO * mtbi=(MTB_BUTTONINFO *)pMTBInfo->pButtonList->items[i]; GetWindowRect(mtbi->hWindow,&childRect); Offset.x=childRect.left-MyRect.left;; Offset.y=childRect.top-MyRect.top; SendMessage(mtbi->hWindow, BUTTONDRAWINPARENT, (WPARAM)hDC,(LPARAM)&Offset); } return 0; } case MTBM_SETBUTTONSTATEBYID: case MTBM_SETBUTTONSTATE: { char * hButtonId=(msg==MTBM_SETBUTTONSTATEBYID) ? (char *) wParam : NULL; void * hButton=(msg==MTBM_SETBUTTONSTATE) ? (void *)wParam : NULL; MTB_BUTTONINFO *mtbi=NULL; int i; for (i=0; ipButtonList->realCount; i++) { mtbi=(MTB_BUTTONINFO*)pMTBInfo->pButtonList->items[i]; if ((hButtonId && !strcmp(mtbi->szButtonID, hButtonId)) || (hButton == mtbi)) { mtbi->bPushButton=(BOOL)lParam; sttUpdateButtonState(mtbi); pcli->pfnInvalidateRect(hwnd, NULL, FALSE); break; } } break; } case MTBM_GETBUTTONSTATEBYID: case MTBM_GETBUTTONSTATE: { int * res= (int*)lParam; if (res==NULL) break; char * hButtonId=(msg==MTBM_GETBUTTONSTATEBYID) ? (char *) wParam : NULL; void * hButton=(msg==MTBM_GETBUTTONSTATE) ? (void *)wParam : NULL; MTB_BUTTONINFO *mtbi=NULL; int i; for (i=0; ipButtonList->realCount; i++) { mtbi=(MTB_BUTTONINFO*)pMTBInfo->pButtonList->items[i]; if ((hButtonId && !strcmp(mtbi->szButtonID, hButtonId)) || (hButton == mtbi)) { *res=0; *res |= mtbi->bPushButton ? TBST_PUSHED : TBST_RELEASED; break; } } break; } case MTBM_REMOVEBUTTON: { MTB_BUTTONINFO *mtbi=NULL; for (int i=0; ipButtonList->realCount; i++) { mtbi=(MTB_BUTTONINFO*)pMTBInfo->pButtonList->items[i]; if (mtbi==(MTB_BUTTONINFO*)wParam) { li.List_Remove(pMTBInfo->pButtonList,i); for (int j=0; jrealCount; j++) if (mtbi==(MTB_BUTTONINFO*)tbdat.listOfButtons->items[j]) { li.List_Remove(tbdat.listOfButtons,j); break; } li.List_RemovePtr(tbdat.listOfButtons,mtbi); delete_MTB_BUTTONINFO((void*)mtbi); mtbi=NULL; pcli->pfnInvalidateRect(hwnd, NULL, FALSE); break; } } break; } default : return DefWindowProc(hwnd, msg, wParam, lParam); } return TRUE; } static int ControlIDS[]={IDC_TEXT_W, IDC_SPIN_W, IDC_STATIC_W, IDC_TEXT_H, IDC_SPIN_H, IDC_STATIC_H,IDC_TEXT_S, IDC_SPIN_S, IDC_STATIC_S, IDC_BTNORDER, IDC_CHECK_MULTILINE, IDC_CHECK_AUTOSIZE }; static LRESULT CALLBACK ToolBar_OptDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) { static HIMAGELIST himlButtonIcons=NULL; static BOOL dragging=FALSE; static HANDLE hDragItem=NULL; switch (msg) { case WM_DESTROY: ImageList_Destroy(himlButtonIcons); break; case WM_INITDIALOG: { HWND hTree=GetDlgItem(hwndDlg,IDC_BTNORDER); TranslateDialogDefault(hwndDlg); SetWindowLongPtr(hTree,GWL_STYLE,GetWindowLongPtr(hTree,GWL_STYLE)|TVS_NOHSCROLL); { himlButtonIcons=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,2,2); TreeView_SetImageList(hTree,himlButtonIcons,TVSIL_NORMAL); } TreeView_DeleteAllItems(hTree); tblock; qsort(tbdat.listOfButtons->items,tbdat.listOfButtons->realCount,sizeof(MTB_BUTTONINFO *),sttSortButtons); { int i=0; for (i=0; irealCount; i++) { TVINSERTSTRUCT tvis={0}; HTREEITEM hti; MTB_BUTTONINFO * mtbi = (MTB_BUTTONINFO*) tbdat.listOfButtons->items[i]; TCHAR * szTempName=mir_a2t(mtbi->szButtonName); HICON hIcon = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)mtbi->hPrimaryIconHandle); int index = ImageList_AddIcon(himlButtonIcons, hIcon); CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); tvis.hParent=NULL; tvis.hInsertAfter=TVI_LAST; tvis.item.mask=TVIF_PARAM|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_STATE; tvis.item.lParam=(LPARAM)(mtbi); tvis.item.pszText=TranslateTS(szTempName); tvis.item.iImage=tvis.item.iSelectedImage=index; hti=TreeView_InsertItem(hTree,&tvis); TreeView_SetCheckState(hTree, hti, mtbi->bVisible ); mir_free(szTempName); } } tbunlock; SendDlgItemMessage(hwndDlg,IDC_SPIN_W,UDM_SETRANGE,0,MAKELONG(50,10)); SendDlgItemMessage(hwndDlg,IDC_SPIN_W,UDM_SETPOS,0,MAKELONG(ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnWidth", SETTINGS_BARBTNWIDTH_DEFAULT),0)); SendDlgItemMessage(hwndDlg,IDC_SPIN_H,UDM_SETRANGE,0,MAKELONG(50,10)); SendDlgItemMessage(hwndDlg,IDC_SPIN_H,UDM_SETPOS,0,MAKELONG(ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnHeight", SETTINGS_BARBTNHEIGHT_DEFAULT),0)); SendDlgItemMessage(hwndDlg,IDC_SPIN_S,UDM_SETRANGE,0,MAKELONG(20,0)); SendDlgItemMessage(hwndDlg,IDC_SPIN_S,UDM_SETPOS,0,MAKELONG(ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_BtnSpace", SETTINGS_BARBTNSPACE_DEFAULT),0)); CheckDlgButton(hwndDlg, IDC_CHECK_AUTOSIZE, ModernGetSettingByte(NULL, "ModernToolBar", "option_Bar0_Autosize", SETTINGS_BARAUTOSIZE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECK_MULTILINE, ModernGetSettingByte(NULL,"ModernToolBar", "option_Bar0_Multiline", SETTINGS_BARMULTILINE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_TBSHOW, ModernGetSettingByte(NULL,"CLUI","ShowButtonBar",SETTINGS_SHOWBUTTONBAR_DEFAULT) ? BST_CHECKED : BST_UNCHECKED); { int i; BOOL en=IsDlgButtonChecked(hwndDlg,IDC_TBSHOW); for (i=0; iidFrom) { case 0: { switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { int order=100; HWND hTree=GetDlgItem(hwndDlg,IDC_BTNORDER); int count=TreeView_GetCount(hTree); HTREEITEM hItem; sttDeleteOrderSettings(); hItem=TreeView_GetRoot(hTree); do { TVITEM tvi={0}; MTB_BUTTONINFO *mtbi; tvi.mask=TBIF_LPARAM|TVIF_HANDLE; tvi.hItem=hItem; TreeView_GetItem(hTree, &tvi); mtbi=(MTB_BUTTONINFO *)tvi.lParam; if (mtbi) { char szTempSetting[200]; mir_snprintf(szTempSetting, SIZEOF(szTempSetting), "order_%s", mtbi->szButtonID); ModernWriteSettingDword(NULL, "ModernToolBar", szTempSetting, order); order+=10; mir_snprintf(szTempSetting, SIZEOF(szTempSetting), "visible_%s", mtbi->szButtonID); ModernWriteSettingByte(NULL, "ModernToolBar", szTempSetting, TreeView_GetCheckState(hTree,hItem)); } hItem=TreeView_GetNextSibling(hTree,hItem); } while (hItem!=NULL); ModernWriteSettingByte(NULL,"CLUI","ShowButtonBar",(BYTE)IsDlgButtonChecked(hwndDlg,IDC_TBSHOW)); ModernWriteSettingByte(NULL,"ModernToolBar","option_Bar0_BtnWidth", (BYTE)SendDlgItemMessage(hwndDlg,IDC_SPIN_W,UDM_GETPOS,0,0)); ModernWriteSettingByte(NULL,"ModernToolBar","option_Bar0_BtnHeight",(BYTE)SendDlgItemMessage(hwndDlg,IDC_SPIN_H,UDM_GETPOS,0,0)); ModernWriteSettingByte(NULL,"ModernToolBar","option_Bar0_BtnSpace", (BYTE)SendDlgItemMessage(hwndDlg,IDC_SPIN_S,UDM_GETPOS,0,0)); ModernWriteSettingByte(NULL, "ModernToolBar", "option_Bar0_Autosize", (BYTE)IsDlgButtonChecked(hwndDlg,IDC_CHECK_AUTOSIZE)); ModernWriteSettingByte(NULL,"ModernToolBar", "option_Bar0_Multiline", (BYTE)IsDlgButtonChecked(hwndDlg,IDC_CHECK_MULTILINE)); sttReloadButtons(); return TRUE; } } break; } case IDC_BTNORDER: { switch (((LPNMHDR)lParam)->code) { case TVN_BEGINDRAGA: case TVN_BEGINDRAGW: SetCapture(hwndDlg); dragging=TRUE; hDragItem=((LPNMTREEVIEWA)lParam)->itemNew.hItem; TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_BTNORDER),hDragItem); break; case NM_CLICK: { TVHITTESTINFO hti; hti.pt.x=(short)LOWORD(GetMessagePos()); hti.pt.y=(short)HIWORD(GetMessagePos()); ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt); if(TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti)) if(hti.flags&TVHT_ONITEMSTATEICON) SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); }; } break; } } break; } case WM_MOUSEMOVE: { if (!dragging) break; { TVHITTESTINFO hti; hti.pt.x=(short)LOWORD(lParam); hti.pt.y=(short)HIWORD(lParam); ClientToScreen(hwndDlg,&hti.pt); ScreenToClient(GetDlgItem(hwndDlg,IDC_BTNORDER),&hti.pt); TreeView_HitTest(GetDlgItem(hwndDlg,IDC_BTNORDER),&hti); if(hti.flags&(TVHT_ONITEM|TVHT_ONITEMRIGHT)) { HTREEITEM it=hti.hItem; hti.pt.y-=TreeView_GetItemHeight(GetDlgItem(hwndDlg,IDC_BTNORDER))/2; TreeView_HitTest(GetDlgItem(hwndDlg,IDC_BTNORDER),&hti); if (!(hti.flags&TVHT_ABOVE)) TreeView_SetInsertMark(GetDlgItem(hwndDlg,IDC_BTNORDER),hti.hItem,1); else TreeView_SetInsertMark(GetDlgItem(hwndDlg,IDC_BTNORDER),it,0); } else { if(hti.flags&TVHT_ABOVE) SendDlgItemMessage(hwndDlg,IDC_BTNORDER,WM_VSCROLL,MAKEWPARAM(SB_LINEUP,0),0); if(hti.flags&TVHT_BELOW) SendDlgItemMessage(hwndDlg,IDC_BTNORDER,WM_VSCROLL,MAKEWPARAM(SB_LINEDOWN,0),0); TreeView_SetInsertMark(GetDlgItem(hwndDlg,IDC_BTNORDER),NULL,0); } } } break; case WM_LBUTTONUP: { if (!dragging) break; TreeView_SetInsertMark(GetDlgItem(hwndDlg,IDC_BTNORDER),NULL,0); dragging=0; ReleaseCapture(); { TVHITTESTINFO hti; TVITEM tvi; hti.pt.x=(short)LOWORD(lParam); hti.pt.y=(short)HIWORD(lParam); ClientToScreen(hwndDlg,&hti.pt); ScreenToClient(GetDlgItem(hwndDlg,IDC_BTNORDER),&hti.pt); hti.pt.y-=TreeView_GetItemHeight(GetDlgItem(hwndDlg,IDC_BTNORDER))/2; TreeView_HitTest(GetDlgItem(hwndDlg,IDC_BTNORDER),&hti); if(hDragItem==hti.hItem) break; if (hti.flags&TVHT_ABOVE) hti.hItem=TVI_FIRST; tvi.mask=TVIF_HANDLE|TVIF_PARAM; tvi.hItem=(HTREEITEM)hDragItem; TreeView_GetItem(GetDlgItem(hwndDlg,IDC_BTNORDER),&tvi); if(hti.flags&(TVHT_ONITEM|TVHT_ONITEMRIGHT)||(hti.hItem==TVI_FIRST)) { TVINSERTSTRUCT tvis; TCHAR name[128]; tvis.item.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_STATE; tvis.item.stateMask=0xFFFFFFFF; tvis.item.pszText=name; tvis.item.cchTextMax=sizeof(name); tvis.item.hItem=(HTREEITEM)hDragItem; //tvis.item.iImage=tvis.item.iSelectedImage=((MTB_BUTTONINFO *)tvi.lParam)->bVisible; TreeView_GetItem(GetDlgItem(hwndDlg,IDC_BTNORDER),&tvis.item); TreeView_DeleteItem(GetDlgItem(hwndDlg,IDC_BTNORDER),hDragItem); tvis.hParent=NULL; tvis.hInsertAfter=hti.hItem; TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_BTNORDER),TreeView_InsertItem(GetDlgItem(hwndDlg,IDC_BTNORDER),&tvis)); SendMessage((GetParent(hwndDlg)), PSM_CHANGED, (WPARAM)hwndDlg, 0); } } } break; case WM_COMMAND: if (LOWORD(wParam)==IDC_TBSHOW) { { int i; BOOL en=IsDlgButtonChecked(hwndDlg,IDC_TBSHOW); for (i=0; i