// wparam = (TTBButton*)lpTTBButton // lparam = hLangpack INT_PTR TTBAddButton(WPARAM wParam, LPARAM lParam) { if (wParam == 0) return -1; TTBButton *but = (TTBButton *)wParam; if (!(but->dwFlags & TTBBF_ISLBUTTON) && nameexists(but->name)) return -1; TopButtonInt *b = CreateButton(but); b->hLangpack = (int)lParam; b->LoadSettings(); b->CreateWnd(); if (b->hwnd == NULL) { delete b; return -1; } mir_cslock lck(csButtonsHook); Buttons.insert(b); g_ctrl->bOrderChanged = TRUE; ArrangeButtons(); AddToOptions(b); return b->id; }
int OnIconChange(WPARAM, LPARAM) { mir_cslock lck(csButtonsHook); for (int i = 0; i < Buttons.getCount(); i++) { TopButtonInt *b = Buttons[i]; if (!b->hIconHandleUp && !b->hIconHandleDn) continue; if (b->hIconHandleUp) { IcoLib_ReleaseIcon(b->hIconUp); b->hIconUp = IcoLib_GetIconByHandle(b->hIconHandleUp); } if (b->hIconHandleDn) { IcoLib_ReleaseIcon(b->hIconDn); b->hIconDn = IcoLib_GetIconByHandle(b->hIconHandleDn); } DestroyWindow(b->hwnd); b->CreateWnd(); } if (g_ctrl->hWnd) { g_ctrl->bOrderChanged = true; PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, 0, 0); } return 0; }
// wparam = hTTBButton // lparam = state INT_PTR TTBSetState(WPARAM wParam, LPARAM lParam) { mir_cslock lck(csButtonsHook); TopButtonInt *b = idtopos(wParam); if (b == NULL) return -1; b->bPushed = (lParam & TTBST_PUSHED) != 0; b->SetBitmap(); return 0; }
static void RecreateWindows() { { mir_cslock lck(csButtonsHook); for (int i = 0; i < Buttons.getCount(); i++) { TopButtonInt *b = Buttons[i]; if (b->hwnd) { if (g_ctrl->bHardUpdate) { DestroyWindow(b->hwnd); b->CreateWnd(); } else b->SetBitmap(); } } } if (g_ctrl->hWnd) PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, 0, 0); }
INT_PTR TTBSetOptions(WPARAM wParam, LPARAM lParam) { mir_cslock lck(csButtonsHook); TopButtonInt *b = idtopos(HIWORD(wParam)); if (b == NULL) return -1; switch (LOWORD(wParam)) { case TTBO_FLAGS: { if (b->dwFlags == lParam) return 0; DWORD retval = b->CheckFlags(lParam); if (retval & TTBBF_PUSHED) b->SetBitmap(); if (retval & TTBBF_VISIBLE) { ArrangeButtons(); b->SaveSettings(0, 0); } return 1; } case TTBO_TIPNAME: if (lParam == 0) return -1; replaceStrT(b->ptszTooltip, TranslateTS(_A2T((LPCSTR)lParam))); SendMessage(b->hwnd, BUTTONADDTOOLTIP, (WPARAM)b->ptszTooltip, BATF_UNICODE); return 1; case TTBO_ALLDATA: if (lParam) { TTBButton *lpTTB = (TTBButton*)lParam; DWORD retval = b->CheckFlags(lpTTB->dwFlags); bool changed = false; if (b->hIconUp != lpTTB->hIconUp) { b->hIconUp = lpTTB->hIconUp; changed = true; } if (b->hIconDn != lpTTB->hIconDn) { b->hIconDn = lpTTB->hIconDn; changed = true; } if (changed) b->SetBitmap(); if (retval & TTBBF_VISIBLE) { ArrangeButtons(); b->SaveSettings(0, 0); } if (b->dwFlags & TTBBF_ISLBUTTON) replaceStrT(b->ptszProgram, lpTTB->program); else replaceStr(b->pszService, lpTTB->pszService); b->lParamUp = lpTTB->lParamUp; b->wParamUp = lpTTB->wParamUp; b->lParamDown = lpTTB->lParamDown; b->wParamDown = lpTTB->wParamDown; return 1; } else return 0; default: return -1; } }
int ArrangeButtons() { mir_cslock lck(csButtonsHook); RECT rcClient; GetClientRect(g_ctrl->hWnd, &rcClient); int nBarSize = rcClient.right - rcClient.left; if (nBarSize == 0) return 0; int nLineCount = 0; int i, nextX = 0, y = 0; int nButtonCount = 0; for (i = 0; i < Buttons.getCount(); i++) if (Buttons[i]->hwnd) nButtonCount++; if (nButtonCount == 0) return 0; HDWP hdwp = BeginDeferWindowPos(nButtonCount); bool bWasButttonBefore; int nUsedWidth, iFirstButtonId = 0, iLastButtonId = 0; do { nLineCount++; bWasButttonBefore = false; nUsedWidth = 0; for (i = iFirstButtonId; i < Buttons.getCount(); i++) { TopButtonInt *b = Buttons[i]; if (b->hwnd == NULL) continue; int width = 0; if (b->isVisible()) width = b->isSep() ? SEPWIDTH + 2 : g_ctrl->nButtonWidth + (bWasButttonBefore ? g_ctrl->nButtonSpace : 0); if (nUsedWidth + width > nBarSize) break; nUsedWidth += width; iLastButtonId = i + 1; bWasButttonBefore = !b->isSep(); } for (i = iFirstButtonId; i < iLastButtonId; i++) { TopButtonInt *b = Buttons[i]; if (b->hwnd == NULL) continue; bool bOldVisible = IsWindowVisible(b->hwnd) != 0; if (bOldVisible != b->isVisible()) g_ctrl->bOrderChanged = TRUE; if (b->isVisible()) { if (NULL != b->hwnd) /* Wine fix. */ hdwp = DeferWindowPos(hdwp, b->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); if (b->isSep()) nextX += SEPWIDTH + 2; else nextX += g_ctrl->nButtonWidth + g_ctrl->nButtonSpace; } else { if (NULL != Buttons[i]->hwnd) /* Wine fix. */ hdwp = DeferWindowPos(hdwp, Buttons[i]->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW); } } if (iFirstButtonId == iLastButtonId) break; iFirstButtonId = iLastButtonId; y += g_ctrl->nButtonHeight + g_ctrl->nButtonSpace; nextX = 0; if (g_ctrl->bSingleLine) break; } while (iFirstButtonId < Buttons.getCount() && y >= 0 && (g_ctrl->bAutoSize || (y + g_ctrl->nButtonHeight <= rcClient.bottom - rcClient.top))); for (i = iLastButtonId; i < Buttons.getCount(); i++) { if (NULL != Buttons[i]->hwnd) /* Wine fix. */ hdwp = DeferWindowPos(hdwp, Buttons[i]->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW); } if (hdwp) EndDeferWindowPos(hdwp); return (g_ctrl->nButtonHeight + g_ctrl->nButtonSpace) * nLineCount - g_ctrl->nButtonSpace; }
LRESULT CALLBACK TopToolBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static bool supressRepos = false; switch(msg) { case WM_CREATE: g_ctrl->hWnd = hwnd; PostMessage(hwnd, TTB_UPDATEFRAMEVISIBILITY, 0, 0); return FALSE; case WM_DESTROY: g_ctrl->hWnd = NULL; break; case WM_MOVE: return 0; case WM_WINDOWPOSCHANGING: case WM_SIZE: if (g_ctrl->nLastHeight != HIWORD(lParam)) { db_set_dw(0, TTB_OPTDIR, "LastHeight", g_ctrl->nLastHeight = HIWORD(lParam)); ArrangeButtons(); } if (supressRepos) { supressRepos = false; break; } // fall through case TTB_REPOSBUTTONS: if (g_ctrl->hWnd == hwnd) { int iHeight = ArrangeButtons(); if ( g_ctrl->bAutoSize) { RECT rcClient; GetClientRect(g_ctrl->hWnd, &rcClient); rcClient.bottom -= rcClient.top; if (rcClient.bottom != iHeight && iHeight && rcClient.bottom) { supressRepos = true; PostMessage(hwnd, TTB_UPDATEFRAMEVISIBILITY, 0, 0); } } return 0; } break; case WM_NCPAINT: case WM_PAINT: PaintToolbar(hwnd); return 0; case WM_LBUTTONDOWN: if (db_get_b(NULL, "CLUI", "ClientAreaDrag", 0)) { POINT pt; GetCursorPos(&pt); return SendMessage(GetParent(hwnd), WM_SYSCOMMAND, SC_MOVE|HTCAPTION, MAKELPARAM(pt.x, pt.y)); } return 0; case WM_COMMAND: switch (HIWORD(wParam)) { case BN_CLICKED: case BN_DOUBLECLICKED: { int id = GetWindowLongPtr((HWND)lParam, GWLP_USERDATA); if (id != 0) { mir_cslock lck(csButtonsHook); TopButtonInt* b = idtopos(id); if (b == NULL || b->isSep()) return 0; if (b->dwFlags & TTBBF_ASPUSHBUTTON) b->bPushed = !b->bPushed; if (b->bPushed) { //Dn -> Up if (!(b->dwFlags & TTBBF_ISLBUTTON)) // must be always true if (b->pszService != NULL) CallService(b->pszService, b->wParamUp, b->lParamUp); } else { //Up -> Dn if (b->pszService != NULL) CallService(b->pszService, b->wParamDown, b->lParamDown); } b->SetBitmap(); } } break; } break; case TTB_UPDATEFRAMEVISIBILITY: { bool bResize = false; if (g_ctrl->bAutoSize) { int Height = ArrangeButtons(); INT_PTR frameopt = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, g_ctrl->hFrame), 0); if (Height != frameopt) { CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, g_ctrl->hFrame), Height); bResize = TRUE; } } if (g_ctrl->bOrderChanged) bResize = TRUE, g_ctrl->bOrderChanged = FALSE; if (bResize) CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)g_ctrl->hFrame, FU_FMPOS); } break; case TTB_SETCUSTOMDATASIZE: g_ctrl = (TTBCtrl*)mir_realloc(g_ctrl, lParam); if (lParam > sizeof(TTBCtrl)) memset(g_ctrl+1, 0, lParam - sizeof(TTBCtrl)); SetWindowLongPtr(hwnd, 0, (LONG_PTR)g_ctrl); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return TRUE; }