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; }