#include "commonheaders.h" static HANDLE hButtonsBarAddButton; static HANDLE hButtonsBarRemoveButton; static HANDLE hButtonsBarGetButtonState; static HANDLE hButtonsBarSetButtonState; static HANDLE hButtonsBarModifyButton; HANDLE hHookButtonPressedEvt; HANDLE hHookToolBarLoadedEvt; static SortedList * RButtonsList; static SortedList * LButtonsList; DWORD LastCID = 4000; DWORD dwSepCount = 0; BOOL bNeedResort = FALSE; CRITICAL_SECTION ToolBarCS; typedef void (*ItemDestuctor)(void*); ////////////////////////////////////////////////////////////////////////////////// // //some code parts from ClistModern toolbar by FYR // ///////////////////////////////////////////////////////////////////////////////// static int sstSortButtons(const void * vmtbi1, const void * vmtbi2) { CustomButtonData * mtbi1 = (CustomButtonData *) * ((CustomButtonData **)vmtbi1); CustomButtonData * mtbi2 = (CustomButtonData *) * ((CustomButtonData **)vmtbi2); if (mtbi1 == NULL || mtbi2 == NULL) return (mtbi1 - mtbi2); return mtbi1->dwPosition - mtbi2->dwPosition; } static void li_ListDestruct(SortedList *pList, ItemDestuctor pItemDestructor) { int i = 0; if (!pList) return; for (i=0; i < pList->realCount; i++) pItemDestructor(pList->items[i]); List_Destroy(pList); mir_free(pList); } static void li_RemoveDestruct(SortedList *pList, int index, ItemDestuctor pItemDestructor) { if (index >= 0 && index < pList->realCount) { pItemDestructor(pList->items[index]); List_Remove(pList, index); } } static void li_RemovePtrDestruct(SortedList *pList, void * ptr, ItemDestuctor pItemDestructor) { if (List_RemovePtr(pList, ptr)) pItemDestructor(ptr); } static void li_SortList(SortedList *pList, FSortFunc pSortFunct) { FSortFunc pOldSort = pList->sortFunc; int i; if (!pSortFunct) pSortFunct = pOldSort; pList->sortFunc = NULL; for (i=0; i < pList->realCount - 1; i++) if (pOldSort(pList->items[i], pList->items[i+1]) < 0) { void * temp = pList->items[i]; pList->items[i] = pList->items[i+1]; pList->items[i+1] = temp; i--; if (i > 0) i--; } pList->sortFunc = pOldSort; } static void listdestructor(void * input) { CustomButtonData * cbdi = (CustomButtonData *)input; if (cbdi->pszModuleName) mir_free(cbdi->pszModuleName); if (cbdi->ptszTooltip) mir_free(cbdi->ptszTooltip); mir_free(cbdi); } //from "advanced auto away" plugin by P. Boon struct RemoveSettings { char *szPrefix; int count; char **szSettings; }; static int DBRemoveEnumProc(const char *szSetting, LPARAM lParam) { struct RemoveSettings *rs = (struct RemoveSettings *)lParam; if (!rs->szPrefix || !strncmp(szSetting, rs->szPrefix, strlen(rs->szPrefix))) { rs->szSettings = (char **)realloc(rs->szSettings, (rs->count + 1) * sizeof(char *)); rs->szSettings[rs->count] = _strdup(szSetting); rs->count += 1; } return 0; } static int Hlp_RemoveDatabaseSettings(HANDLE hContact, char *szModule, char *szPrefix) { DBCONTACTENUMSETTINGS dbces; struct RemoveSettings rs; int i, count; ZeroMemory(&rs, sizeof(struct RemoveSettings)); rs.szPrefix = szPrefix; ZeroMemory(&dbces, sizeof(DBCONTACTENUMSETTINGS)); dbces.pfnEnumProc = DBRemoveEnumProc; dbces.lParam = (LPARAM)& rs; dbces.szModule = szModule; if (CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)(HANDLE)hContact, (LPARAM)&dbces) == -1) { return -1; } count = 0; if (rs.szSettings != NULL) { for (i=0; i < rs.count; i++) { if (rs.szSettings[i] != NULL) { if (!db_unset(hContact, szModule, rs.szSettings[i])) { count += 1; } free(rs.szSettings[i]); } } free(rs.szSettings); } return count; } void CB_InitCustomButtons() { LButtonsList = List_Create(0, 1); RButtonsList = List_Create(0, 1); InitializeCriticalSection(&ToolBarCS); dwSepCount = M->GetDword("TabSRMM_Toolbar", "SeparatorsCount", 0); //dwSepCount = db_get_dw(NULL, "TabSRMM_Toolbar", "SeparatorsCount", 0); hButtonsBarAddButton = CreateServiceFunction(MS_BB_ADDBUTTON, CB_AddButton); hButtonsBarRemoveButton = CreateServiceFunction(MS_BB_REMOVEBUTTON, CB_RemoveButton); hButtonsBarModifyButton = CreateServiceFunction(MS_BB_MODIFYBUTTON, CB_ModifyButton); hButtonsBarGetButtonState = CreateServiceFunction(MS_BB_GETBUTTONSTATE, CB_GetButtonState); hButtonsBarSetButtonState = CreateServiceFunction(MS_BB_SETBUTTONSTATE, CB_SetButtonState); hHookToolBarLoadedEvt = CreateHookableEvent(ME_MSG_TOOLBARLOADED); hHookButtonPressedEvt = CreateHookableEvent(ME_MSG_BUTTONPRESSED); } void CB_DeInitCustomButtons() { DeleteCriticalSection(&ToolBarCS); li_ListDestruct(LButtonsList, listdestructor); li_ListDestruct(RButtonsList, listdestructor); DestroyHookableEvent(hHookToolBarLoadedEvt); DestroyHookableEvent(hHookButtonPressedEvt); DestroyServiceFunction(hButtonsBarAddButton); DestroyServiceFunction(hButtonsBarRemoveButton); DestroyServiceFunction(hButtonsBarModifyButton); DestroyServiceFunction(hButtonsBarGetButtonState); DestroyServiceFunction(hButtonsBarSetButtonState); } void CB_DestroyAllButtons(HWND hwndDlg, struct TWindowData *dat) { int i; HWND hwndBtn = NULL; for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; { hwndBtn = GetDlgItem(hwndDlg, cbd->dwButtonCID); if (hwndBtn) DestroyWindow(hwndBtn); } } for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; { hwndBtn = GetDlgItem(hwndDlg, cbd->dwButtonCID); if (hwndBtn) DestroyWindow(hwndBtn); } } } void CB_DestroyButton(HWND hwndDlg, struct TWindowData *dat, DWORD dwButtonCID, DWORD dwFlags) { HWND hwndBtn = GetDlgItem(hwndDlg, dwButtonCID); RECT rc = {0}; if (hwndBtn) { GetClientRect(hwndBtn, &rc); if (dwFlags&BBBF_ISLSIDEBUTTON) dat->bbLSideWidth -= rc.right; else if (dwFlags&BBBF_ISRSIDEBUTTON) dat->bbRSideWidth -= rc.right; DestroyWindow(hwndBtn); BB_SetButtonsPos(dat); } } void CB_ChangeButton(HWND hwndDlg, struct TWindowData *dat, CustomButtonData* cbd) { HWND hwndBtn = GetDlgItem(hwndDlg, cbd->dwButtonCID); if (hwndBtn) { if (cbd->hIcon) SendMessage(hwndBtn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(cbd->hIcon)); if (cbd->ptszTooltip) SendMessage(hwndBtn, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(cbd->ptszTooltip), 0); SendMessage(hwndBtn, BUTTONSETCONTAINER, (LPARAM)dat->pContainer, 0); } } void CB_ReInitCustomButtons() { int i; for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; //GetButtonSettings(NULL,cbd); if (cbd->opFlags&BBSF_NTBSWAPED || cbd->opFlags&BBSF_NTBDESTRUCT) { cbd->opFlags ^= BBSF_NTBSWAPED; if (!(cbd->opFlags&BBSF_NTBDESTRUCT)) List_InsertPtr(RButtonsList, cbd); List_Remove(LButtonsList, i); i--; } } for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (cbd->opFlags&BBSF_NTBSWAPED || cbd->opFlags&BBSF_NTBDESTRUCT) { cbd->opFlags ^= BBSF_NTBSWAPED; if (!(cbd->opFlags&BBSF_NTBDESTRUCT)) List_InsertPtr(LButtonsList, cbd); List_Remove(RButtonsList, i); i--; } } M->BroadcastMessage(DM_BBNEEDUPDATE, 0, 0); M->BroadcastMessage(DM_LOADBUTTONBARICONS, 0, 0); } void CB_HardReInit() { M->BroadcastMessage(DM_CBDESTROY, 0, 0); EnterCriticalSection(&ToolBarCS); li_ListDestruct(LButtonsList, listdestructor); li_ListDestruct(RButtonsList, listdestructor); LButtonsList = List_Create(0, 1); RButtonsList = List_Create(0, 1); LeaveCriticalSection(&ToolBarCS); LastCID = 4000; dwSepCount = 0; CB_InitDefaultButtons(); NotifyEventHooks(hHookToolBarLoadedEvt, 0, 0); } static INT_PTR CB_AddButton(WPARAM wParam, LPARAM lParam) { BBButton *bbdi = (BBButton *)lParam; bNeedResort = TRUE; if (bbdi->cbSize != sizeof(BBButton)) return 1; CustomButtonData *cbd = (CustomButtonData *)mir_alloc(sizeof(CustomButtonData)); memset(cbd, 0, sizeof(CustomButtonData)); if (!bbdi->iButtonWidth && (bbdi->bbbFlags & BBBF_ISARROWBUTTON)) cbd->iButtonWidth = DPISCALEX_S(34); else if (!bbdi->iButtonWidth) cbd->iButtonWidth = DPISCALEX_S(22); else cbd->iButtonWidth = DPISCALEX_S(bbdi->iButtonWidth); cbd->pszModuleName = mir_strdup(bbdi->pszModuleName); if (bbdi->ptszTooltip) { if (bbdi->bbbFlags & BBBF_ANSITOOLTIP) cbd->ptszTooltip = mir_a2u(bbdi->pszTooltip); else cbd->ptszTooltip = mir_tstrdup(bbdi->ptszTooltip); } else cbd->ptszTooltip = NULL; cbd->dwButtonOrigID = bbdi->dwButtonID; cbd->hIcon = bbdi->hIcon; cbd->dwPosition = bbdi->dwDefPos; cbd->dwButtonCID = (bbdi->bbbFlags & BBBF_CREATEBYID) ? bbdi->dwButtonID : LastCID; //ugly workaround for smileys plugins cbd->dwArrowCID = (bbdi->bbbFlags & BBBF_ISARROWBUTTON) ? (cbd->dwButtonCID == IDOK ? IDC_SENDMENU : (cbd->dwButtonCID + 1)) : 0 ; cbd->bHidden = (bbdi->bbbFlags & BBBF_HIDDEN) ? 1 : 0; cbd->bLSided = (bbdi->bbbFlags & BBBF_ISLSIDEBUTTON) ? 1 : 0; cbd->bRSided = (bbdi->bbbFlags & BBBF_ISRSIDEBUTTON) ? 1 : 0; cbd->bCanBeHidden = (bbdi->bbbFlags & BBBF_CANBEHIDDEN) ? 1 : 0; cbd->bDummy = (bbdi->bbbFlags & BBBF_ISDUMMYBUTTON) ? 1 : 0; cbd->bChatButton = (bbdi->bbbFlags & BBBF_ISCHATBUTTON) ? 1 : 0; cbd->bIMButton = (bbdi->bbbFlags & BBBF_ISIMBUTTON) ? 1 : 0; cbd->bDisabled = (bbdi->bbbFlags & BBBF_DISABLED) ? 1 : 0; cbd->bPushButton = (bbdi->bbbFlags & BBBF_ISPUSHBUTTON) ? 1 : 0; CB_GetButtonSettings(NULL, cbd); if (cbd->bLSided) List_InsertPtr(LButtonsList, cbd); else if (cbd->bRSided) List_InsertPtr(RButtonsList, cbd); else return 1; if (cbd->dwButtonCID != cbd->dwButtonOrigID) LastCID++; if (cbd->dwArrowCID == LastCID) LastCID++; M->BroadcastMessage(DM_BBNEEDUPDATE, 0, 0); return 0; } static INT_PTR CB_GetButtonState(WPARAM wParam, LPARAM lParam) { HWND hwndDlg = NULL; int i; DWORD tempCID = 0; BOOL realbutton = 0; BBButton * bbdi = (BBButton *)lParam; bbdi->bbbFlags = 0; for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { realbutton = 1; tempCID = cbd->dwButtonCID; } } if (!realbutton) for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { realbutton = 1; tempCID = cbd->dwButtonCID; } } if (!realbutton) return 1; hwndDlg = M->FindWindow((HANDLE)wParam); bbdi->bbbFlags = (IsDlgButtonChecked(hwndDlg, tempCID) ? BBSF_PUSHED : BBSF_RELEASED) | (IsWindowVisible(GetDlgItem(hwndDlg, tempCID)) ? 0 : BBSF_HIDDEN) | (IsWindowEnabled(GetDlgItem(hwndDlg, tempCID)) ? 0 : BBSF_DISABLED); return 0; } static INT_PTR CB_SetButtonState(WPARAM wParam, LPARAM lParam) { HWND hwndDlg; int i; BOOL realbutton = 0; DWORD tempCID = 0; BBButton * bbdi = (BBButton *)lParam; for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { realbutton = 1; tempCID = cbd->dwButtonCID; } } if (!realbutton) for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { realbutton = 1; tempCID = cbd->dwButtonCID; } } if (!realbutton || !wParam) return 1; hwndDlg = M->FindWindow((HANDLE)wParam); if (hwndDlg && realbutton && bbdi->hIcon) SendMessage(GetDlgItem(hwndDlg, tempCID), BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(bbdi->hIcon)); if (hwndDlg && realbutton && bbdi->pszTooltip) { if (bbdi->bbbFlags&BBBF_ANSITOOLTIP) SendMessage(GetDlgItem(hwndDlg, tempCID), BUTTONADDTOOLTIP, (WPARAM)mir_a2u(bbdi->pszTooltip), 0); else SendMessage(GetDlgItem(hwndDlg, tempCID), BUTTONADDTOOLTIP, (WPARAM)bbdi->ptszTooltip, 0); } if (hwndDlg && realbutton && bbdi->bbbFlags) { Utils::showDlgControl(hwndDlg, tempCID, (bbdi->bbbFlags&BBSF_HIDDEN) ? SW_HIDE : SW_SHOW); Utils::enableDlgControl(hwndDlg, tempCID, (bbdi->bbbFlags&BBSF_DISABLED) ? 0 : 1); CheckDlgButton(hwndDlg, tempCID, (bbdi->bbbFlags&BBSF_PUSHED) ? 1 : 0); CheckDlgButton(hwndDlg, tempCID, (bbdi->bbbFlags&BBSF_RELEASED) ? 0 : 1); } return 0; } static INT_PTR CB_RemoveButton(WPARAM wParam, LPARAM lParam) { int i; DWORD tempCID = 0; DWORD dwFlags = 0; BBButton * bbdi = (BBButton *)lParam; EnterCriticalSection(&ToolBarCS); for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { tempCID = cbd->dwButtonCID; dwFlags = cbd->bLSided ? BBBF_ISLSIDEBUTTON : BBBF_ISRSIDEBUTTON; List_Remove(LButtonsList, i); i--; } } if (tempCID) qsort(LButtonsList->items, LButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); if (!tempCID) { for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { tempCID = cbd->dwButtonCID; dwFlags = cbd->bLSided ? BBBF_ISLSIDEBUTTON : BBBF_ISRSIDEBUTTON; List_Remove(RButtonsList, i); i--; } } if (tempCID) qsort(RButtonsList->items, RButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); } LeaveCriticalSection(&ToolBarCS); if (tempCID) M->BroadcastMessage(DM_CBDESTROY, (WPARAM)tempCID, (LPARAM)dwFlags); return 0; } static INT_PTR CB_ModifyButton(WPARAM wParam, LPARAM lParam) { int i; BOOL bFound = 0; CustomButtonData* cbd = NULL; BBButton * bbdi = (BBButton *)lParam; EnterCriticalSection(&ToolBarCS); for (i=0; i < LButtonsList->realCount; i++) { cbd = (CustomButtonData *)LButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { bFound = 1; break; } } if (!bFound) { cbd = NULL; for (i=0; i < RButtonsList->realCount; i++) { cbd = (CustomButtonData *)RButtonsList->items[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { bFound = 1; break; } } } if (bFound) { if (bbdi->pszTooltip) { if (cbd->ptszTooltip) mir_free(cbd->ptszTooltip); if (bbdi->bbbFlags&BBBF_ANSITOOLTIP) cbd->ptszTooltip = mir_a2u(bbdi->pszTooltip); else cbd->ptszTooltip = mir_tstrdup(bbdi->ptszTooltip); } if (bbdi->hIcon) cbd->hIcon = bbdi->hIcon; if (bbdi->bbbFlags) { cbd->bHidden = (bbdi->bbbFlags & BBBF_HIDDEN) ? 1 : 0; cbd->bLSided = (bbdi->bbbFlags & BBBF_ISLSIDEBUTTON) ? 1 : 0; cbd->bRSided = (bbdi->bbbFlags & BBBF_ISRSIDEBUTTON) ? 1 : 0; cbd->bCanBeHidden = (bbdi->bbbFlags & BBBF_CANBEHIDDEN) ? 1 : 0; cbd->bChatButton = (bbdi->bbbFlags & BBBF_ISCHATBUTTON) ? 1 : 0; cbd->bIMButton = (bbdi->bbbFlags & BBBF_ISIMBUTTON) ? 1 : 0; cbd->bDisabled = (bbdi->bbbFlags & BBBF_DISABLED) ? 1 : 0; } } LeaveCriticalSection(&ToolBarCS); if (bFound) M->BroadcastMessage(DM_BBNEEDUPDATE, 0, (LPARAM)cbd); return 0; } void BB_UpdateIcons(HWND hdlg, struct TWindowData *dat) { int i; HWND hwndBtn = NULL; qsort(LButtonsList->items, LButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (cbd) { if (!cbd->bDummy) hwndBtn = GetDlgItem(hdlg, cbd->dwButtonCID); if (hwndBtn && cbd->hIcon) SendMessage(hwndBtn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(cbd->hIcon)); } } hwndBtn = NULL; qsort(RButtonsList->items, RButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (cbd) { if (!cbd->bDummy) hwndBtn = GetDlgItem(hdlg, cbd->dwButtonCID); if (hwndBtn && cbd->hIcon) SendMessage(hwndBtn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(cbd->hIcon)); } } } void TSAPI BB_InitDlgButtons(TWindowData *dat) { RECT rect; int i; int lwidth = 0, rwidth = 0; HWND hwndBtn = NULL; RECT rcSplitter; POINT ptSplitter; int splitterY; BYTE gap = DPISCALEX_S(PluginConfig.g_iButtonsBarGap); BOOL isThemed = PluginConfig.m_bIsXP; int cx = 0, cy = 0; int lcount = LButtonsList->realCount; int rcount = RButtonsList->realCount; HWND hdlg = dat->hwnd; if (dat == 0 || hdlg == 0) {return;} if (CSkin::m_skinEnabled && !SkinItems[ID_EXTBKBUTTONSNPRESSED].IGNORED && !SkinItems[ID_EXTBKBUTTONSPRESSED].IGNORED && !SkinItems[ID_EXTBKBUTTONSMOUSEOVER].IGNORED) { isThemed = FALSE; } GetWindowRect(GetDlgItem(hdlg, (dat->bType == SESSIONTYPE_IM) ? IDC_SPLITTER : IDC_SPLITTERY), &rcSplitter); ptSplitter.x = 0; ptSplitter.y = rcSplitter.top; ScreenToClient(hdlg, &ptSplitter); GetClientRect(hdlg, &rect); splitterY = ptSplitter.y - DPISCALEY_S(1); hwndBtn = NULL; qsort(RButtonsList->items, RButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (((dat->bType == SESSIONTYPE_IM && cbd->bIMButton) || (dat->bType == SESSIONTYPE_CHAT && cbd->bChatButton))) { if (!cbd->bHidden) rwidth += cbd->iButtonWidth + gap; if (!cbd->bHidden && !cbd->bCanBeHidden) dat->iButtonBarReallyNeeds += cbd->iButtonWidth + gap; if (!cbd->bDummy && !GetDlgItem(hdlg, cbd->dwButtonCID)) hwndBtn = CreateWindowEx(0, _T("TSButtonClass"), _T(""), WS_CHILD | WS_VISIBLE | WS_TABSTOP, rect.right - rwidth + gap, splitterY, cbd->iButtonWidth, DPISCALEY_S(22), hdlg, (HMENU) cbd->dwButtonCID, g_hInst, NULL); if (!cbd->bDummy && hwndBtn) { SendMessage(hwndBtn, BUTTONSETASFLATBTN, TRUE, 0); SendMessage(hwndBtn, BUTTONSETASTHEMEDBTN, isThemed != 0, 0); if (cbd->hIcon) SendMessage(hwndBtn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(cbd->hIcon)); if (cbd->ptszTooltip) SendMessage(hwndBtn, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(cbd->ptszTooltip), 0); SendMessage(hwndBtn, BUTTONSETCONTAINER, (LPARAM)dat->pContainer, 0); SendMessage(hwndBtn, BUTTONSETASTOOLBARBUTTON, TRUE, 0); if (hwndBtn && cbd->dwArrowCID) SendMessage(hwndBtn, BUTTONSETARROW, cbd->dwArrowCID, 0); if (hwndBtn && cbd->bPushButton) SendMessage(hwndBtn, BUTTONSETASPUSHBTN, TRUE, 0); } } else if (GetDlgItem(hdlg, cbd->dwButtonCID)) DestroyWindow(GetDlgItem(hdlg, cbd->dwButtonCID)); if (cbd->bDisabled) EnableWindow(hwndBtn, 0); if (cbd->bHidden) ShowWindow(hwndBtn, SW_HIDE); } hwndBtn = NULL; qsort(LButtonsList->items, LButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (((dat->bType == SESSIONTYPE_IM && cbd->bIMButton) || (dat->bType == SESSIONTYPE_CHAT && cbd->bChatButton))) { if (!cbd->bDummy && !GetDlgItem(hdlg, cbd->dwButtonCID)) hwndBtn = CreateWindowEx(0, _T("TSButtonClass"), _T(""), WS_CHILD | WS_VISIBLE | WS_TABSTOP, 2 + lwidth, splitterY, cbd->iButtonWidth, DPISCALEY_S(22), hdlg, (HMENU) cbd->dwButtonCID, g_hInst, NULL); if (!cbd->bHidden) lwidth += cbd->iButtonWidth + gap; if (!cbd->bHidden && !cbd->bCanBeHidden) dat->iButtonBarReallyNeeds += cbd->iButtonWidth + gap; if (!cbd->bDummy && hwndBtn) { SendMessage(hwndBtn, BUTTONSETASFLATBTN, TRUE, 0); SendMessage(hwndBtn, BUTTONSETASTHEMEDBTN, isThemed != 0, 0); if (cbd->hIcon) SendMessage(hwndBtn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(cbd->hIcon)); if (cbd->ptszTooltip) SendMessage(hwndBtn, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(cbd->ptszTooltip), 0); SendMessage(hwndBtn, BUTTONSETCONTAINER, (LPARAM)dat->pContainer, 0); SendMessage(hwndBtn, BUTTONSETASTOOLBARBUTTON, TRUE, 0); if (hwndBtn && cbd->dwArrowCID) SendMessage(hwndBtn, BUTTONSETARROW, cbd->dwArrowCID, 0); if (hwndBtn && cbd->bPushButton) SendMessage(hwndBtn, BUTTONSETASPUSHBTN, TRUE, 0); } } else if (GetDlgItem(hdlg, cbd->dwButtonCID)) DestroyWindow(GetDlgItem(hdlg, cbd->dwButtonCID)); if (cbd->bDisabled) EnableWindow(hwndBtn, 0); if (cbd->bHidden) ShowWindow(hwndBtn, SW_HIDE); } dat->bbLSideWidth = lwidth; dat->bbRSideWidth = rwidth; } void TSAPI BB_RedrawButtons(TWindowData *dat) { int i; CustomButtonData* cbd; HWND hwnd; for (i=0; i < LButtonsList->realCount; i++) { cbd = reinterpret_cast(LButtonsList->items[i]); if (cbd) { hwnd = GetDlgItem(dat->hwnd, cbd->dwButtonCID); if (hwnd) InvalidateRect(hwnd, 0, TRUE); } } for (i=0; i < RButtonsList->realCount; i++) { cbd = reinterpret_cast(RButtonsList->items[i]); if (cbd) { hwnd = GetDlgItem(dat->hwnd, cbd->dwButtonCID); if (hwnd) InvalidateRect(hwnd, 0, TRUE); } } HWND hwndToggleSideBar = GetDlgItem(dat->hwnd, dat->bType == SESSIONTYPE_IM ? IDC_TOGGLESIDEBAR : IDC_CHAT_TOGGLESIDEBAR); if (hwndToggleSideBar && IsWindow(hwndToggleSideBar)) InvalidateRect(hwndToggleSideBar, 0, TRUE); } BOOL TSAPI BB_SetButtonsPos(TWindowData *dat) { RECT rect; int i; HWND hwndBtn = 0; int lwidth = 0, rwidth = 0; RECT rcSplitter; POINT ptSplitter; int splitterY, iOff; BYTE gap = DPISCALEX_S(PluginConfig.g_iButtonsBarGap); int foravatar = 0; BOOL showToolbar = dat->pContainer->dwFlags & CNT_HIDETOOLBAR ? 0 : 1; BOOL bBottomToolbar = dat->pContainer->dwFlags & CNT_BOTTOMTOOLBAR ? 1 : 0; int tempL = dat->bbLSideWidth; int tempR = dat->bbRSideWidth; HWND hwnd = dat->hwnd; HDWP hdwp = BeginDeferWindowPos(LButtonsList->realCount + RButtonsList->realCount + 1); HWND hwndToggleSideBar = GetDlgItem(dat->hwnd, dat->bType == SESSIONTYPE_IM ? IDC_TOGGLESIDEBAR : IDC_CHAT_TOGGLESIDEBAR); if (!dat || !IsWindowVisible(hwnd)) return 0; ShowWindow(hwndToggleSideBar, (showToolbar && dat->pContainer->SideBar->isActive()) ? SW_SHOW : SW_HIDE); EnterCriticalSection(&ToolBarCS); GetWindowRect(GetDlgItem(hwnd, (dat->bType == SESSIONTYPE_IM) ? IDC_SPLITTER : IDC_SPLITTERY), &rcSplitter); ptSplitter.x = 0; ptSplitter.y = rcSplitter.top; ScreenToClient(hwnd, &ptSplitter); if (PluginConfig.g_DPIscaleY > 1.0) iOff = dat->bType == SESSIONTYPE_IM ? DPISCALEY_S(22) : DPISCALEY_S(23); else iOff = DPISCALEY_S(22); GetClientRect(hwnd, &rect); if (!bBottomToolbar) splitterY = ptSplitter.y - DPISCALEY_S(1); else splitterY = rect.bottom; if ((rect.bottom - ptSplitter.y - (rcSplitter.bottom - rcSplitter.top) /*- DPISCALEY(2)*/ - (bBottomToolbar ? DPISCALEY_S(24) : 0) < dat->pic.cy - DPISCALEY_S(2)) && dat->showPic && !PluginConfig.m_AlwaysFullToolbarWidth) foravatar = dat->pic.cx + gap; if (bNeedResort) qsort(LButtonsList->items, LButtonsList->realCount, sizeof(BBButton *), sstSortButtons); if ((dat->pContainer->dwFlags & CNT_SIDEBAR) && (dat->pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT)) { DeferWindowPos(hdwp, hwndToggleSideBar , NULL, 4, 2 + splitterY - iOff, 0, 0, SWP_NOZORDER | SWP_NOSIZE);// | SWP_NOCOPYBITS); lwidth += 10; tempL -= 10; } for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (((dat->bType == SESSIONTYPE_IM) && cbd->bIMButton) || ((dat->bType == SESSIONTYPE_CHAT) && cbd->bChatButton)) { hwndBtn = GetDlgItem(hwnd, cbd->dwButtonCID); if (!showToolbar) { ShowWindow(hwndBtn, SW_HIDE); DeferWindowPos(hdwp, hwndBtn , NULL, lwidth, splitterY - iOff, 0, 0, SWP_NOZORDER | SWP_NOSIZE);// | SWP_NOCOPYBITS); if (IsWindowVisible(hwndBtn) || (cbd->bDummy && !(cbd->bAutoHidden || cbd->bHidden))) lwidth += cbd->iButtonWidth + gap; if (!IsWindowEnabled(hwndBtn) && !IsWindowVisible(hwndBtn) && !cbd->bAutoHidden) cbd->bAutoHidden = 1; continue; } else if (!cbd->bCanBeHidden && !cbd->bHidden && !(!IsWindowEnabled(hwndBtn) && !IsWindowVisible(hwndBtn) && !cbd->bAutoHidden)) { ShowWindow(hwndBtn, SW_SHOW); cbd->bAutoHidden = 0; } if (!cbd->bDummy && !IsWindowVisible(hwndBtn) && !IsWindowEnabled(hwndBtn) && !cbd->bAutoHidden) tempL -= cbd->iButtonWidth + gap; if (cbd->bCanBeHidden && !cbd->bHidden && (cbd->bDummy || !((!IsWindowEnabled(hwndBtn) && !IsWindowVisible(hwndBtn)) && !cbd->bAutoHidden))) { if (tempL + tempR > (rect.right - foravatar)) { ShowWindow(hwndBtn, SW_HIDE); cbd->bAutoHidden = 1; tempL -= cbd->iButtonWidth + gap; } else if (cbd->bAutoHidden) { ShowWindow(hwndBtn, SW_SHOW); cbd->bAutoHidden = 0; } } DeferWindowPos(hdwp, hwndBtn , NULL, lwidth, splitterY - iOff, 0, 0, SWP_NOZORDER | SWP_NOSIZE);// SWP_NOCOPYBITS); if (IsWindowVisible(hwndBtn) || (cbd->bDummy && !(cbd->bAutoHidden || cbd->bHidden))) lwidth += cbd->iButtonWidth + gap; } } if (bNeedResort) { qsort(RButtonsList->items, RButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); bNeedResort = FALSE; } if ((dat->pContainer->dwFlags & CNT_SIDEBAR) && (dat->pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_RIGHT)) { DeferWindowPos(hdwp, hwndToggleSideBar , NULL, rect.right - foravatar - 10, 2 + splitterY - iOff, 0, 0, SWP_NOZORDER | SWP_NOSIZE);// | SWP_NOCOPYBITS); rwidth += 12; tempR -= 12; } for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (((dat->bType == SESSIONTYPE_IM) && cbd->bIMButton) || ((dat->bType == SESSIONTYPE_CHAT) && cbd->bChatButton)) { hwndBtn = GetDlgItem(hwnd, cbd->dwButtonCID); if (!showToolbar) { ShowWindow(hwndBtn, SW_HIDE); if (IsWindowVisible(hwndBtn) || (cbd->bDummy && !(cbd->bAutoHidden || cbd->bHidden))) rwidth += cbd->iButtonWidth + gap; DeferWindowPos(hdwp, hwndBtn , NULL, rect.right - foravatar - rwidth + gap, splitterY - iOff, 0, 0, SWP_NOZORDER | SWP_NOSIZE);// SWP_NOCOPYBITS); if (!IsWindowEnabled(hwndBtn) && !IsWindowVisible(hwndBtn) && !cbd->bAutoHidden) cbd->bAutoHidden = 1; continue; } else if (!cbd->bCanBeHidden && !cbd->bHidden && !((!IsWindowEnabled(hwndBtn) && !IsWindowVisible(hwndBtn)) && !cbd->bAutoHidden)) { ShowWindow(hwndBtn, SW_SHOW); cbd->bAutoHidden = 0; } if (!cbd->bDummy && !IsWindowVisible(hwndBtn) && !IsWindowEnabled(hwndBtn) && !cbd->bAutoHidden) tempR -= cbd->iButtonWidth + gap; if (cbd->bCanBeHidden && !cbd->bHidden && (cbd->bDummy || !((!IsWindowEnabled(hwndBtn) && !IsWindowVisible(hwndBtn)) && !cbd->bAutoHidden))) { if (tempL + tempR > (rect.right - foravatar)) { ShowWindow(hwndBtn, SW_HIDE); cbd->bAutoHidden = 1; tempR -= cbd->iButtonWidth + gap; } else if (cbd->bAutoHidden) { ShowWindow(hwndBtn, SW_SHOW); cbd->bAutoHidden = 0; } } if (IsWindowVisible(hwndBtn) || (cbd->bDummy && !(cbd->bAutoHidden || cbd->bHidden))) rwidth += cbd->iButtonWidth + gap; DeferWindowPos(hdwp, hwndBtn , NULL, rect.right - foravatar - rwidth + gap, splitterY - iOff, 0, 0, SWP_NOZORDER | SWP_NOSIZE);// SWP_NOCOPYBITS); } } LeaveCriticalSection(&ToolBarCS); return (EndDeferWindowPos(hdwp)); } void TSAPI BB_CustomButtonClick(struct TWindowData *dat, DWORD idFrom, HWND hwndFrom, BOOL code) { RECT rc; int i; BOOL bFromArrow = 0; CustomButtonClickData cbcd = {0}; GetWindowRect(hwndFrom, &rc); cbcd.pt.x = rc.left; cbcd.pt.y = rc.bottom; for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; if (cbd->dwButtonCID == idFrom) { cbcd.pszModule = cbd->pszModuleName; cbcd.dwButtonId = cbd->dwButtonOrigID; } else if (cbd->dwArrowCID == idFrom) { bFromArrow = 1; cbcd.pszModule = cbd->pszModuleName; cbcd.dwButtonId = cbd->dwButtonOrigID; } } if (!cbcd.pszModule) for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; if (cbd->dwButtonCID == idFrom) { cbcd.pszModule = cbd->pszModuleName; cbcd.dwButtonId = cbd->dwButtonOrigID; } else if (cbd->dwArrowCID == idFrom) { bFromArrow = 1; cbcd.pszModule = cbd->pszModuleName; cbcd.dwButtonId = cbd->dwButtonOrigID; } } cbcd.cbSize = sizeof(CustomButtonClickData); cbcd.hwndFrom = dat->hwnd; cbcd.hContact = dat->hContact; cbcd.flags = (code ? BBCF_RIGHTBUTTON : 0) | (GetKeyState(VK_SHIFT) & 0x8000 ? BBCF_SHIFTPRESSED : 0) | (GetKeyState(VK_CONTROL) & 0x8000 ? BBCF_CONTROLPRESSED : 0) | (bFromArrow ? BBCF_ARROWCLICKED : 0); NotifyEventHooks(hHookButtonPressedEvt, (WPARAM)dat->hContact, (LPARAM)&cbcd); } void CB_GetButtonSettings(HANDLE hContact, CustomButtonData *cbd) { DBVARIANT dbv = {0}; char SettingName[1024] = {'\0'}; char* token = NULL; //modulename_buttonID, position_inIM_inCHAT_isLSide_isRSide_CanBeHidden mir_snprintf(SettingName, sizeof(SettingName), "%s_%d", cbd->pszModuleName, cbd->dwButtonOrigID); if (!db_get_s(hContact, "TabSRMM_Toolbar", SettingName, &dbv)) { token = strtok(dbv.pszVal, "_"); cbd->dwPosition = (DWORD)atoi(token); token = strtok(NULL, "_"); cbd->bIMButton = (BOOL)atoi(token); token = strtok(NULL, "_"); cbd->bChatButton = (BOOL)atoi(token); token = strtok(NULL, "_"); cbd->bLSided = (BOOL)atoi(token); token = strtok(NULL, "_"); cbd->bRSided = (BOOL)atoi(token); token = strtok(NULL, "_"); cbd->bCanBeHidden = (BOOL)atoi(token); db_free(&dbv); } } void CB_WriteButtonSettings(HANDLE hContact, CustomButtonData *cbd) { char SettingName[1024] = {'\0'}; char SettingParameter[1024] = {'\0'}; //modulename_buttonID, position_inIM_inCHAT_isLSide_isRSide_CanBeHidden mir_snprintf(SettingName, sizeof(SettingName), "%s_%d", cbd->pszModuleName, cbd->dwButtonOrigID); mir_snprintf(SettingParameter, sizeof(SettingParameter), "%d_%u_%u_%u_%u_%u", cbd->dwPosition, cbd->bIMButton, cbd->bChatButton, cbd->bLSided, cbd->bRSided, cbd->bCanBeHidden); if (!(cbd->opFlags&BBSF_NTBDESTRUCT)) db_set_s(hContact, "TabSRMM_Toolbar", SettingName, SettingParameter); else db_unset(hContact, "TabSRMM_Toolbar", SettingName); } void BB_RegisterSeparators() { BBButton bbd = {0}; DWORD i = 0; bbd.cbSize = sizeof(BBButton); bbd.pszModuleName = "Tabsrmm_sep"; for (; dwSepCount > i; i++) { bbd.bbbFlags = BBBF_ISDUMMYBUTTON | BBBF_ISIMBUTTON | BBBF_ISLSIDEBUTTON; bbd.dwButtonID = i + 1; bbd.dwDefPos = 410 + i; CB_AddButton(0, (LPARAM)&bbd); } } void BB_RefreshTheme(const TWindowData *dat) { int i; for (i=0; i < RButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)RButtonsList->items[i]; SendMessage(GetDlgItem(dat->hwnd, cbd->dwButtonCID), WM_THEMECHANGED, 0, 0); } for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData* cbd = (CustomButtonData *)LButtonsList->items[i]; SendMessage(GetDlgItem(dat->hwnd, cbd->dwButtonCID), WM_THEMECHANGED, 0, 0); } } void CB_InitDefaultButtons() { BBButton bbd = {0}; bbd.cbSize = sizeof(BBButton); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISARROWBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_PROTOCOL; bbd.dwDefPos = 10; bbd.hIcon = LoadSkinnedIconHandle(SKINICON_OTHER_CONNECTING); bbd.pszModuleName = "Tabsrmm"; bbd.ptszTooltip = LPGENT("Protocol Button"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISARROWBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_NAME; bbd.dwDefPos = 20; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[20]; bbd.ptszTooltip = LPGENT("Info button"); CB_AddButton(0, (LPARAM)&bbd); if (PluginConfig.g_SmileyAddAvail) { bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_SMILEYBTN; bbd.iButtonWidth = 0; bbd.dwDefPos = 30; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[9]; bbd.ptszTooltip = LPGENT("Insert Emoticon"); CB_AddButton(0, (LPARAM)&bbd); } bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISPUSHBUTTON | BBBF_CANBEHIDDEN | BBBF_CREATEBYID; bbd.dwButtonID = IDC_FONTBOLD; bbd.dwDefPos = 40; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[10]; bbd.ptszTooltip = LPGENT("Bold text"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISPUSHBUTTON | BBBF_CANBEHIDDEN | BBBF_CREATEBYID; bbd.dwButtonID = IDC_FONTITALIC; bbd.dwDefPos = 50; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[11]; bbd.ptszTooltip = LPGENT("Italic text"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISPUSHBUTTON | BBBF_CANBEHIDDEN | BBBF_CREATEBYID; bbd.dwButtonID = IDC_FONTUNDERLINE; bbd.dwDefPos = 60; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[12]; bbd.ptszTooltip = LPGENT("Underlined text"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISPUSHBUTTON | BBBF_CANBEHIDDEN | BBBF_CREATEBYID; bbd.dwButtonID = IDC_FONTSTRIKEOUT; bbd.dwDefPos = 70; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[15]; bbd.ptszTooltip = LPGENT("Strike-through text"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_CANBEHIDDEN | BBBF_CREATEBYID; bbd.dwButtonID = IDC_FONTFACE; bbd.dwDefPos = 80; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[14]; bbd.ptszTooltip = LPGENT("Select font color"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISRSIDEBUTTON | BBBF_ISARROWBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDOK; bbd.dwDefPos = 10; bbd.iButtonWidth = 51; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[6]; bbd.ptszTooltip = LPGENT("Send message\nClick dropdown arrow for sending options"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_SAVE; bbd.dwDefPos = 20; bbd.iButtonWidth = 0; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[8]; bbd.ptszTooltip = LPGENT("Close session"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_QUOTE; bbd.dwDefPos = 30; bbd.iButtonWidth = 0; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[4]; bbd.ptszTooltip = LPGENT("Quote last message OR selected text"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_TIME; bbd.dwDefPos = 40; bbd.iButtonWidth = 0; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[2]; bbd.ptszTooltip = LPGENT("Message Log Options"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISCHATBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_HISTORY; bbd.dwDefPos = 50; bbd.iButtonWidth = 0; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[0]; bbd.ptszTooltip = LPGENT("View User's History"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISIMBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_PIC; bbd.dwDefPos = 60; bbd.iButtonWidth = 0; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[7]; bbd.ptszTooltip = LPGENT("Edit user notes"); CB_AddButton(0, (LPARAM)&bbd); //chat buttons bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISDUMMYBUTTON; bbd.dwButtonID = 1; bbd.pszModuleName = "tb_splitter"; bbd.dwDefPos = 31; bbd.iButtonWidth = 22; bbd.hIcon = 0; bbd.pszTooltip = 0; CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISDUMMYBUTTON; bbd.dwButtonID = 2; bbd.dwDefPos = 22; bbd.iButtonWidth = 22; bbd.hIcon = 0; bbd.pszTooltip = 0; CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISDUMMYBUTTON; bbd.dwButtonID = 3; bbd.dwDefPos = 71; bbd.iButtonWidth = 22; bbd.hIcon = 0; bbd.pszTooltip = 0; CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISLSIDEBUTTON | BBBF_ISPUSHBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_BKGCOLOR; bbd.pszModuleName = "Tabsrmm"; bbd.dwDefPos = 81; bbd.iButtonWidth = 22; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[16]; bbd.ptszTooltip = LPGENT("Change background color"); CB_AddButton(0, (LPARAM)&bbd); // bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_SHOWNICKLIST; bbd.dwDefPos = 22; bbd.iButtonWidth = 22; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[19]; bbd.ptszTooltip = LPGENT("Toggle nick list"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_FILTER; bbd.dwDefPos = 24; bbd.iButtonWidth = 22; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[18]; bbd.ptszTooltip = LPGENT("Event filter - right click to setup, left click to activate/deactivate"); CB_AddButton(0, (LPARAM)&bbd); bbd.bbbFlags = BBBF_ISCHATBUTTON | BBBF_ISRSIDEBUTTON | BBBF_CREATEBYID; bbd.dwButtonID = IDC_CHANMGR; bbd.dwDefPos = 33; bbd.iButtonWidth = 22; bbd.hIcon = PluginConfig.g_buttonBarIconHandles[17]; bbd.ptszTooltip = LPGENT("Channel manager"); CB_AddButton(0, (LPARAM)&bbd); BB_RegisterSeparators(); } #define MIDDLE_SEPARATOR _T(">-------M-------<") static int SaveTree(HWND hToolBarTree) { TVITEM tvi; HTREEITEM hItem = NULL; BOOL RSide = FALSE; int count = 10; DWORD loc_sepcout = 0; TCHAR strbuf[128]; CustomButtonData* cbd = NULL; tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE; tvi.hItem = TreeView_GetRoot(hToolBarTree); tvi.pszText = strbuf; tvi.cchTextMax = sizeof(strbuf); EnterCriticalSection(&ToolBarCS); while (tvi.hItem != NULL) { TreeView_GetItem(hToolBarTree, &tvi); if (_tcscmp(tvi.pszText, MIDDLE_SEPARATOR) == 0) { RSide = TRUE; count = TreeView_GetCount(hToolBarTree) * 10 - count; tvi.hItem = TreeView_GetNextSibling(hToolBarTree, tvi.hItem); continue; } cbd = (CustomButtonData*)tvi.lParam; if (cbd) { if (cbd->opFlags) { cbd->bIMButton = (cbd->opFlags & BBSF_IMBUTTON) ? 1 : 0; cbd->bChatButton = (cbd->opFlags & BBSF_CHATBUTTON) ? 1 : 0; cbd->bCanBeHidden = (cbd->opFlags & BBSF_CANBEHIDDEN) ? 1 : 0; } if (RSide && cbd->bLSided) { cbd->bLSided = FALSE; cbd->bRSided = TRUE; cbd->opFlags |= BBSF_NTBSWAPED; } else if (!RSide && cbd->bRSided) { cbd->bLSided = TRUE; cbd->bRSided = FALSE; cbd->opFlags |= BBSF_NTBSWAPED; } if (!TreeView_GetCheckState(hToolBarTree, tvi.hItem)) { cbd->bIMButton = FALSE; cbd->bChatButton = FALSE; if (cbd->bDummy && !strcmp(cbd->pszModuleName, "Tabsrmm_sep")) cbd->opFlags = BBSF_NTBDESTRUCT; } else { if (!cbd->bIMButton && !cbd->bChatButton) cbd->bIMButton = TRUE; if (cbd->bDummy && !strcmp(cbd->pszModuleName, "Tabsrmm_sep")) { cbd->bHidden = 0; cbd->opFlags &= ~BBSF_NTBDESTRUCT; ++loc_sepcout; } } cbd->dwPosition = (DWORD)count; CB_WriteButtonSettings(NULL, cbd); if (!(cbd->opFlags&BBSF_NTBDESTRUCT)) (RSide) ? (count -= 10) : (count += 10); } hItem = TreeView_GetNextSibling(hToolBarTree, tvi.hItem); if (cbd->opFlags&BBSF_NTBDESTRUCT) TreeView_DeleteItem(hToolBarTree, tvi.hItem); tvi.hItem = hItem; } LeaveCriticalSection(&ToolBarCS); M->WriteDword("TabSRMM_Toolbar", "SeparatorsCount", loc_sepcout); dwSepCount = loc_sepcout; bNeedResort = TRUE; return 1; } HIMAGELIST himgl = NULL; static int BuildMenuObjectsTree(HWND hToolBarTree) { TVINSERTSTRUCT tvis; HTREEITEM hti; int iImage = 0; int i; tvis.hParent = NULL; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE; TreeView_DeleteAllItems(hToolBarTree); himgl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 2, 2); ImageList_AddIcon(himgl, LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT)); ImageList_Destroy( TreeView_GetImageList(hToolBarTree, TVSIL_NORMAL)); TreeView_SetImageList(hToolBarTree, himgl, TVSIL_NORMAL); if ((RButtonsList->realCount + LButtonsList->realCount) == 0) return FALSE; EnterCriticalSection(&ToolBarCS); qsort(LButtonsList->items, LButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); for (i=0; i < LButtonsList->realCount; i++) { CustomButtonData * cbd = (CustomButtonData *)LButtonsList->items[i]; tvis.item.lParam = (LPARAM)cbd; if (cbd->bDummy) { tvis.item.pszText = TranslateT(""); tvis.item.iImage = tvis.item.iSelectedImage = 0; } else { tvis.item.pszText = TranslateTS(cbd->ptszTooltip); iImage = ImageList_AddIcon(himgl, Skin_GetIconByHandle(cbd->hIcon)); tvis.item.iImage = tvis.item.iSelectedImage = iImage; } cbd->opFlags = 0; hti = TreeView_InsertItem(hToolBarTree, &tvis); TreeView_SetCheckState(hToolBarTree, hti, (cbd->bIMButton || cbd->bChatButton)); } if (TRUE) { tvis.item.lParam = 0; tvis.item.mask |= TVIF_STATE; tvis.item.pszText = MIDDLE_SEPARATOR; tvis.item.stateMask = TVIS_BOLD; tvis.item.state = TVIS_BOLD; tvis.item.iImage = tvis.item.iSelectedImage = -1; hti = TreeView_InsertItem(hToolBarTree, &tvis); TreeView_SetCheckState(hToolBarTree, hti, 1); } qsort(RButtonsList->items, RButtonsList->realCount, sizeof(CustomButtonData *), sstSortButtons); for (i = RButtonsList->realCount; i > 0; i--) { CustomButtonData * cbd = (CustomButtonData *)RButtonsList->items[i-1]; tvis.item.lParam = (LPARAM)cbd; if (cbd->bDummy) { tvis.item.pszText = TranslateT(""); tvis.item.iImage = tvis.item.iSelectedImage = -1; } else { tvis.item.pszText = TranslateTS(cbd->ptszTooltip); iImage = ImageList_AddIcon(himgl, Skin_GetIconByHandle(cbd->hIcon)); tvis.item.iImage = tvis.item.iSelectedImage = iImage; } tvis.item.state = 0; cbd->opFlags = 0; hti = TreeView_InsertItem(hToolBarTree, &tvis); TreeView_SetCheckState(hToolBarTree, hti, (cbd->bIMButton || cbd->bChatButton)); } LeaveCriticalSection(&ToolBarCS); return 1; } BOOL drag = FALSE, bOptionsInit = TRUE; HANDLE hDragItem = NULL; HWND hToolBarTree = NULL; INT_PTR CALLBACK DlgProcToolBar(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HTREEITEM hti; switch (uMsg) { case WM_INITDIALOG: hToolBarTree = GetDlgItem(hwndDlg, IDC_TOOLBARTREE); { LONG_PTR style = GetWindowLongPtr(hToolBarTree, GWL_STYLE); style ^= TVS_CHECKBOXES; SetWindowLongPtr(hToolBarTree, GWL_STYLE, style); style |= TVS_CHECKBOXES; style |= TVS_NOHSCROLL; SetWindowLongPtr(hToolBarTree, GWL_STYLE, style); } EnterCriticalSection(&ToolBarCS); BuildMenuObjectsTree((HWND)hToolBarTree); LeaveCriticalSection(&ToolBarCS); Utils::enableDlgControl(hwndDlg, IDC_IMCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CHATCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CANBEHIDDEN, FALSE); SendDlgItemMessage(hwndDlg, IDC_SPIN1, UDM_SETRANGE, 0, MAKELONG(10, 0)); SendDlgItemMessage(hwndDlg, IDC_SPIN1, UDM_SETPOS, 0, MAKELONG(PluginConfig.g_iButtonsBarGap, 0)); TranslateDialogDefault(hwndDlg); bOptionsInit = FALSE; break; case WM_LBUTTONUP: if (drag) { TreeView_SetInsertMark(hToolBarTree, NULL, 0); drag = 0; ReleaseCapture(); TVHITTESTINFO hti; TVITEM tvi; hti.pt.x = (short)LOWORD(lParam); hti.pt.y = (short)HIWORD(lParam); ClientToScreen(hwndDlg, &hti.pt); ScreenToClient(hToolBarTree, &hti.pt); hti.pt.y -= TreeView_GetItemHeight(hToolBarTree) / 2; TreeView_HitTest(hToolBarTree, &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(hToolBarTree, &tvi); if (hti.flags&(TVHT_ONITEM | TVHT_ONITEMRIGHT) || (hti.hItem == TVI_FIRST)) { TVINSERTSTRUCT tvis; TCHAR strbuf[128]; tvis.item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; tvis.item.stateMask = 0xFFFFFFFF; tvis.item.pszText = strbuf; tvis.item.cchTextMax = sizeof(strbuf); tvis.item.hItem = (HTREEITEM)hDragItem; TreeView_GetItem(hToolBarTree, &tvis.item); TreeView_DeleteItem(hToolBarTree, hDragItem); tvis.hParent = NULL; tvis.hInsertAfter = hti.hItem; TreeView_SelectItem(hToolBarTree, TreeView_InsertItem(hToolBarTree, &tvis)); SendMessage((GetParent(hwndDlg)), PSM_CHANGED, 0, 0); } } break; case WM_MOUSEMOVE: if (drag) { TVHITTESTINFO hti; hti.pt.x = (short)LOWORD(lParam); hti.pt.y = (short)HIWORD(lParam); ClientToScreen(hwndDlg, &hti.pt); ScreenToClient(hToolBarTree, &hti.pt); TreeView_HitTest(hToolBarTree, &hti); if (hti.flags&(TVHT_ONITEM | TVHT_ONITEMRIGHT)) { HTREEITEM it = hti.hItem; hti.pt.y -= TreeView_GetItemHeight(hToolBarTree) / 2; TreeView_HitTest(hToolBarTree, &hti); if (!(hti.flags&TVHT_ABOVE)) TreeView_SetInsertMark(hToolBarTree, hti.hItem, 1); else TreeView_SetInsertMark(hToolBarTree, it, 0); } else { if (hti.flags&TVHT_ABOVE) SendMessage(hToolBarTree, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); if (hti.flags&TVHT_BELOW) SendMessage(hToolBarTree, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); TreeView_SetInsertMark(hToolBarTree, NULL, 0); } } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED && GetFocus() == (HWND)lParam && (HWND)lParam != hToolBarTree) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); if ((HIWORD(wParam) == EN_CHANGE) && ((HWND)lParam == GetFocus())) if (!bOptionsInit) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); switch (LOWORD(wParam)) { case IDC_BBRESET: Hlp_RemoveDatabaseSettings(NULL, "TabSRMM_Toolbar", 0); CB_HardReInit(); BuildMenuObjectsTree(hToolBarTree); break; case IDC_SEPARATOR: hti = TreeView_GetSelection(hToolBarTree); if (!hti) hti = TVI_FIRST; CustomButtonData *cbd = (CustomButtonData *)mir_alloc(sizeof(CustomButtonData)); ZeroMemory(cbd, sizeof(CustomButtonData)); cbd->bDummy = 1; cbd->bHidden = 1; cbd->bIMButton = 1; cbd->bLSided = 1; cbd->dwButtonOrigID = ++dwSepCount; cbd->pszModuleName = "Tabsrmm_sep"; cbd->iButtonWidth = 22; cbd->opFlags = BBSF_NTBDESTRUCT; List_InsertPtr(LButtonsList, cbd); TVINSERTSTRUCT tvis; tvis.hParent = NULL; tvis.hInsertAfter = hti; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvis.item.pszText = TranslateT(""); tvis.item.iImage = tvis.item.iSelectedImage = -1; tvis.item.lParam = (LPARAM)cbd; hti = TreeView_InsertItem(hToolBarTree, &tvis); TreeView_SetCheckState(hToolBarTree, hti, (cbd->bIMButton || cbd->bChatButton)); } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_RESET: CB_ReInitCustomButtons(); dwSepCount = M->GetDword("TabSRMM_Toolbar", "SeparatorsCount", 0); return 1; case PSN_APPLY: hti = TreeView_GetSelection(hToolBarTree); if (hti) { TVITEM tvi; tvi.mask = TVIF_HANDLE | TVIF_PARAM; tvi.hItem = hti; TreeView_GetItem(hToolBarTree, &tvi); if (tvi.lParam) { CustomButtonData *cbd = (CustomButtonData*)tvi.lParam; if (cbd) { cbd->bIMButton = IsDlgButtonChecked(hwndDlg, IDC_IMCHECK); cbd->bChatButton = IsDlgButtonChecked(hwndDlg, IDC_CHATCHECK); cbd->bCanBeHidden = IsDlgButtonChecked(hwndDlg, IDC_CANBEHIDDEN); } } } SaveTree(hToolBarTree); CB_ReInitCustomButtons(); PluginConfig.g_iButtonsBarGap = (BYTE)SendDlgItemMessage(hwndDlg, IDC_SPIN1, UDM_GETPOS, 0, 0); if (PluginConfig.g_iButtonsBarGap != M->GetByte("ButtonsBarGap", 1)) M->BroadcastMessageAsync(WM_SIZE, 0, 0); M->WriteByte(SRMSGMOD_T, "ButtonsBarGap", PluginConfig.g_iButtonsBarGap); BuildMenuObjectsTree((HWND)hToolBarTree); Utils::enableDlgControl(hwndDlg, IDC_IMCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CHATCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CANBEHIDDEN, FALSE); return 1; } break; case IDC_TOOLBARTREE: switch (((LPNMHDR)lParam)->code) { case TVN_BEGINDRAGA: case TVN_BEGINDRAGW: SetCapture(hwndDlg); drag = 1; hDragItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem; TreeView_SelectItem(hToolBarTree, hDragItem); break; case TVN_SELCHANGINGA: case TVN_SELCHANGINGW: hti = TreeView_GetSelection(hToolBarTree); if (hti != NULL) { TCHAR strbuf[128]; TVITEM tvi; tvi.hItem = hti; tvi.pszText = strbuf; tvi.cchTextMax = sizeof(strbuf); tvi.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(hToolBarTree, &tvi); if (tvi.lParam == 0 || !TreeView_GetCheckState(hToolBarTree, tvi.hItem) || !_tcscmp(tvi.pszText, MIDDLE_SEPARATOR)) break; CustomButtonData *cbd = (CustomButtonData*)tvi.lParam; if (cbd) { cbd->opFlags = (IsDlgButtonChecked(hwndDlg, IDC_IMCHECK)) ? BBSF_IMBUTTON : 0; cbd->opFlags |= (IsDlgButtonChecked(hwndDlg, IDC_CHATCHECK)) ? BBSF_CHATBUTTON : 0; cbd->opFlags |= (IsDlgButtonChecked(hwndDlg, IDC_CANBEHIDDEN)) ? BBSF_CANBEHIDDEN : 0; cbd->bIMButton = (IsDlgButtonChecked(hwndDlg, IDC_IMCHECK) ? TRUE : FALSE); cbd->bChatButton = (IsDlgButtonChecked(hwndDlg, IDC_CHATCHECK) ? TRUE : FALSE); cbd->bCanBeHidden = (IsDlgButtonChecked(hwndDlg, IDC_CANBEHIDDEN) ? TRUE : FALSE); } } break; case TVN_SELCHANGEDW: case TVN_SELCHANGEDA: hti = TreeView_GetSelection(hToolBarTree); if (hti != NULL) { TCHAR strbuf[128]; TVITEM tvi; tvi.pszText = strbuf; tvi.cchTextMax = sizeof(strbuf); tvi.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_PARAM; tvi.hItem = hti; TreeView_GetItem(hToolBarTree, &tvi); if (!TreeView_GetCheckState(hToolBarTree, tvi.hItem) || !_tcscmp(tvi.pszText, MIDDLE_SEPARATOR)) { Utils::enableDlgControl(hwndDlg, IDC_IMCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CHATCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CANBEHIDDEN, FALSE); break; } if (tvi.lParam == 0) break; CustomButtonData *cbd = (CustomButtonData*)tvi.lParam; if (cbd) { Utils::enableDlgControl(hwndDlg, IDC_IMCHECK, TRUE); Utils::enableDlgControl(hwndDlg, IDC_CHATCHECK, TRUE); Utils::enableDlgControl(hwndDlg, IDC_CANBEHIDDEN, TRUE); CheckDlgButton(hwndDlg, IDC_IMCHECK, (cbd->bIMButton) ? 1 : 0); CheckDlgButton(hwndDlg, IDC_CHATCHECK, (cbd->bChatButton) ? 1 : 0); CheckDlgButton(hwndDlg, IDC_CANBEHIDDEN, (cbd->bCanBeHidden) ? 1 : 0); } } break; case NM_CLICK: TVHITTESTINFO hti = {0}; GetCursorPos(&hti.pt); ScreenToClient(hToolBarTree, &hti.pt); if (TreeView_HitTest(hToolBarTree, &hti)) { if (hti.flags&TVHT_ONITEMSTATEICON) { SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); if (TreeView_GetCheckState(hToolBarTree, hti.hItem)) { Utils::enableDlgControl(hwndDlg, IDC_IMCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CHATCHECK, FALSE); Utils::enableDlgControl(hwndDlg, IDC_CANBEHIDDEN, FALSE); CheckDlgButton(hwndDlg, IDC_IMCHECK, 1); } else { Utils::enableDlgControl(hwndDlg, IDC_IMCHECK, TRUE); Utils::enableDlgControl(hwndDlg, IDC_CHATCHECK, TRUE); Utils::enableDlgControl(hwndDlg, IDC_CANBEHIDDEN, TRUE); } TreeView_SelectItem(hToolBarTree, hti.hItem); } } } } break; case WM_DESTROY: HIMAGELIST hIml = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TOOLBARTREE), TVSIL_NORMAL); ImageList_Destroy(hIml); hIml = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TOOLBARTREE), TVSIL_STATE); ImageList_Destroy(hIml); break; } return FALSE; }