diff options
Diffstat (limited to 'plugins/TopToolBar/src/toolbarwnd.cpp')
-rw-r--r-- | plugins/TopToolBar/src/toolbarwnd.cpp | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/plugins/TopToolBar/src/toolbarwnd.cpp b/plugins/TopToolBar/src/toolbarwnd.cpp new file mode 100644 index 0000000000..e3f19f693b --- /dev/null +++ b/plugins/TopToolBar/src/toolbarwnd.cpp @@ -0,0 +1,330 @@ +
+#include "common.h"
+
+COLORREF bkColour;
+HBITMAP hBmpBackground, hBmpSeparator;
+int backgroundBmpUse;
+
+static TCHAR pluginname[] = _T("TopToolBar");
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Toolbar window procedure
+
+static void PaintToolbar(HWND hwnd)
+{
+ InvalidateRect(hwnd, 0, FALSE);
+
+ PAINTSTRUCT paintst;
+ HDC hdc = BeginPaint(hwnd, &paintst);
+ RECT *rcPaint = &paintst.rcPaint;
+
+ RECT clRect;
+ GetClientRect(hwnd, &clRect);
+ if (rcPaint == NULL) rcPaint = &clRect;
+
+ int yScroll = 0;
+ int y = -yScroll;
+
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ HBITMAP hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
+ HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcMem, hBmpOsb);
+ SetBkMode(hdcMem, TRANSPARENT);
+
+ HBRUSH hBrush = CreateSolidBrush(bkColour);
+ HBRUSH hoBrush = (HBRUSH)SelectObject(hdcMem, hBrush);
+ FillRect(hdcMem, rcPaint, hBrush);
+ SelectObject(hdcMem, hoBrush);
+ DeleteObject(hBrush);
+ if (hBmpBackground) {
+ BITMAP bmp;
+ GetObject(hBmpBackground, sizeof(bmp), &bmp);
+
+ HDC hdcBmp = CreateCompatibleDC(hdcMem);
+ SelectObject(hdcBmp, hBmpBackground);
+ int y = backgroundBmpUse & CLBF_SCROLL ? -yScroll : 0;
+ int maxx = backgroundBmpUse & CLBF_TILEH ? clRect.right : 1;
+ int maxy = backgroundBmpUse & CLBF_TILEV ? maxy = rcPaint->bottom : y+1;
+
+ int destw, desth;
+ switch(backgroundBmpUse & CLBM_TYPE) {
+ case CLB_STRETCH:
+ if (backgroundBmpUse&CLBF_PROPORTIONAL) {
+ if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) {
+ desth = clRect.bottom;
+ destw = desth * bmp.bmWidth/bmp.bmHeight;
+ }
+ else {
+ destw = clRect.right;
+ desth = destw * bmp.bmHeight/bmp.bmWidth;
+ }
+ }
+ else {
+ destw = clRect.right;
+ desth = clRect.bottom;
+ }
+ break;
+ case CLB_STRETCHH:
+ if (backgroundBmpUse & CLBF_PROPORTIONAL) {
+ destw = clRect.right;
+ desth = destw * bmp.bmHeight/bmp.bmWidth;
+ if (backgroundBmpUse & CLBF_TILEVTOROWHEIGHT)
+ desth = g_ctrl->nButtonHeight+2;
+ }
+ else {
+ destw = clRect.right;
+ desth = bmp.bmHeight;
+ }
+ break;
+ case CLB_STRETCHV:
+ if (backgroundBmpUse & CLBF_PROPORTIONAL) {
+ desth = clRect.bottom;
+ destw = desth*bmp.bmWidth/bmp.bmHeight;
+ }
+ else {
+ destw = bmp.bmWidth;
+ desth = clRect.bottom;
+ }
+ break;
+ default: //clb_topleft
+ destw = bmp.bmWidth;
+ desth = bmp.bmHeight;
+ if (backgroundBmpUse & CLBF_TILEVTOROWHEIGHT)
+ desth = g_ctrl->nButtonHeight+2;
+ break;
+ }
+
+ for (; y < maxy; y += desth) {
+ if (y < rcPaint->top - desth)
+ continue;
+
+ for (int x = 0; x < maxx; x += destw)
+ StretchBlt(hdcMem, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
+ }
+ DeleteDC(hdcBmp);
+ }
+ BitBlt(hdc, rcPaint->left, rcPaint->top, rcPaint->right-rcPaint->left, rcPaint->bottom-rcPaint->top, hdcMem, rcPaint->left, rcPaint->top, SRCCOPY);
+ SelectObject(hdcMem, hOldBmp);
+ DeleteDC(hdcMem);
+ DeleteObject(hBmpOsb);
+
+ paintst.fErase = FALSE;
+ EndPaint(hwnd, &paintst);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+LRESULT CALLBACK TopToolBarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static bool supressRepos = false;
+
+ if (g_ctrl->fnWindowProc != NULL)
+ if ( g_ctrl->fnWindowProc(hwnd, msg, wParam, lParam))
+ return g_ctrl->lResult;
+
+ switch(msg) {
+ case WM_CREATE:
+ g_ctrl->hWnd = hwnd;
+ PostMessage(hwnd, TTB_UPDATEFRAMEVISIBILITY, 1, 0);
+ return FALSE;
+
+ 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);
+ if (rcClient.bottom - rcClient.top != iHeight && iHeight) {
+ supressRepos = true;
+ PostMessage(hwnd, TTB_UPDATEFRAMEVISIBILITY, -1, 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 vis=(BOOL)wParam;
+ BOOL curvis = IsWindowVisible(hwnd);
+ bool bResize = false;
+ int Height = ArrangeButtons();
+
+ if (g_ctrl->bAutoSize) {
+ 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 ((curvis != vis || bResize) && vis != -1) {
+ INT_PTR frameopt = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, g_ctrl->hFrame), 0);
+ frameopt &= ~F_VISIBLE;
+ frameopt |= vis ? F_VISIBLE : 0;
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, g_ctrl->hFrame), frameopt);
+ }
+ }
+ break;
+
+ case TTB_SETCUSTOM:
+ {
+ TTBCtrlCustomize *pCustom = (TTBCtrlCustomize*)lParam;
+ if (pCustom == NULL || g_ctrl->fnWindowProc)
+ break;
+
+ g_ctrl = (TTBCtrl*)mir_realloc(g_ctrl, pCustom->cbLen);
+ if (pCustom->cbLen > sizeof(TTBCtrl))
+ memset(g_ctrl+1, 0, pCustom->cbLen - sizeof(TTBCtrl));
+
+ g_ctrl->fnWindowProc = pCustom->fnWindowProc;
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR)g_ctrl);
+ }
+ break;
+
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return(TRUE);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR OnEventFire(WPARAM wParam, LPARAM lParam)
+{
+ CallService(MS_SYSTEM_REMOVEWAIT, wParam, 0);
+ CloseHandle((HANDLE)wParam);
+
+ HWND parent = (HWND)CallService(MS_CLUI_GETHWND, 0, 0);
+ if (parent == NULL) // no clist, no buttons
+ return -1;
+
+ WNDCLASS wndclass = { 0 };
+ wndclass.lpfnWndProc = TopToolBarProc;
+ wndclass.cbWndExtra = sizeof(void*);
+ wndclass.hInstance = hInst;
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ wndclass.lpszClassName = pluginname;
+ RegisterClass(&wndclass);
+
+ g_ctrl->pButtonList = (SortedList*)&Buttons;
+ g_ctrl->hWnd = CreateWindow(pluginname, _T("Toolbar"),
+ WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ 0, 0, 0, g_ctrl->nLastHeight, parent, NULL, hInst, NULL);
+ SetWindowLongPtr(g_ctrl->hWnd, 0, (LPARAM)g_ctrl);
+
+ LoadBackgroundOptions();
+
+ // if we're working in skinned clist, receive the standard buttons & customizations
+ if (g_CustomProc && g_ctrl->hWnd)
+ g_CustomProc(TTB_WINDOW_HANDLE, g_ctrl->hWnd, g_CustomProcParam);
+
+ // if there's no customized frames, create our own
+ if (g_ctrl->hFrame == NULL) {
+ CLISTFrame Frame = { 0 };
+ Frame.cbSize = sizeof(Frame);
+ Frame.tname = _T("Toolbar");
+ Frame.hWnd = g_ctrl->hWnd;
+ Frame.align = alTop;
+ Frame.Flags = F_VISIBLE | F_NOBORDER | F_LOCKED | F_TCHAR;
+ Frame.height = g_ctrl->nLastHeight;
+ g_ctrl->hFrame = (HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0);
+ }
+
+ // receive all buttons
+ NotifyEventHooks(hTTBInitButtons, 0, 0);
+ NotifyEventHooks(hTTBModuleLoaded, 0, 0);
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int LoadBackgroundOptions()
+{
+ //load options
+ bkColour = DBGetContactSettingDword(NULL, TTB_OPTDIR, "BkColour", TTBDEFAULT_BKCOLOUR);
+ if (hBmpBackground) {
+ DeleteObject(hBmpBackground);
+ hBmpBackground = NULL;
+ }
+
+ if (db_get_b(NULL, TTB_OPTDIR, "UseBitmap", TTBDEFAULT_USEBITMAP)) {
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(NULL, TTB_OPTDIR, "BkBitmap", &dbv)) {
+ hBmpBackground = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ }
+ backgroundBmpUse = DBGetContactSettingWord(NULL, TTB_OPTDIR, "BkBmpUse", TTBDEFAULT_BKBMPUSE);
+
+ RECT rc;
+ GetClientRect(g_ctrl->hWnd, &rc);
+ InvalidateRect(g_ctrl->hWnd, &rc, TRUE);
+ UpdateWindow(g_ctrl->hWnd);
+
+ return 0;
+}
|