/************************************************************************ MeOS - Orienteering Software Copyright (C) 2009-2019 Melin Software HB 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 3 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, see . Melin Software HB - software@melin.nu - www.melin.nu Eksoppsvägen 16, SE-75646 UPPSALA, Sweden ************************************************************************/ #include "stdafx.h" #include "resource.h" #include #include "oEvent.h" #include "xmlparser.h" #include "gdioutput.h" #include "commctrl.h" #include "SportIdent.h" #include "TabBase.h" #include "TabCompetition.h" #include "TabAuto.h" #include "TabClass.h" #include "TabCourse.h" #include "TabControl.h" #include "TabSI.h" #include "TabList.h" #include "TabTeam.h" #include "TabSpeaker.h" #include "TabMulti.h" #include "TabRunner.h" #include "TabClub.h" #include "progress.h" #include "inthashmap.h" #include #include "localizer.h" #include "intkeymap.hpp" #include "intkeymapimpl.hpp" #include "download.h" #include "meos_util.h" #include "toolbar.h" const wchar_t *szToolClass = L"MeOSToolClass"; LRESULT CALLBACK ToolProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #define BASE_ID 1013 const DWORD buttonStyles = BTNS_AUTOSIZE; const int bitmapSize = 24; Toolbar::Toolbar(gdioutput &gdi_par) : gdi(gdi_par), data(0) { hwndFloater = 0; hwndToolbar = 0; isactivating = false; // Create the imagelist. hImageListDef = ImageList_Create(bitmapSize, bitmapSize, ILC_COLOR24 | ILC_MASK, 1, 15); //hImageListMeOS = ImageList_Create(bitmapSize, bitmapSize, ILC_COLOR16 | ILC_MASK, 1, 10); hImageListMeOS = ImageList_LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(BMP_TEST), bitmapSize, 17, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION); } Toolbar::~Toolbar() { ImageList_Destroy(hImageListDef); ImageList_Destroy(hImageListMeOS); } void Toolbar::reset() { btn.clear(); tooltips.clear(); btn_id.clear(); toolbar_id.clear(); DestroyWindow(hwndToolbar); hwndToolbar = 0; } void Toolbar::show() { if (hwndFloater) ShowWindow(hwndFloater, SW_NORMAL); } void Toolbar::hide() { if (hwndFloater) ShowWindow(hwndFloater, SW_HIDE); } void Toolbar::activate(bool active) { if (!isactivating && isVisible()) { isactivating = true; //SendMessage(hwndFloater, WM_NCACTIVATE, active ? 1:0, 0); DefWindowProc(hwndFloater, WM_NCACTIVATE, active ? 1:0, 0); isactivating = false; } } void Toolbar::addButton(const string &id, int imgList, int icon, const string &tooltip) { tooltips.push_back(lang.tl(tooltip)); TBBUTTON tbButton = { MAKELONG(icon, imgList), int(btn_id.size()) + BASE_ID, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)tooltips.back().c_str() }; btn.push_back(tbButton); btn_id.push_back(id); } void Toolbar::processCommand(int id, int code) { size_t ix = id - BASE_ID; if (ix < btn_id.size()) { gdi.processToolbarMessage(btn_id[ix], data); } } void registerToolbar(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)ToolProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = 0; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); wcex.lpszMenuName = 0; wcex.lpszClassName = szToolClass; wcex.hIconSm = 0; RegisterClassEx(&wcex); } void Toolbar::createToolbar(const string &id, const wstring &title) { if (id == toolbar_id) { show(); return; } wstring t = lang.tl(title); HWND hParent = gdi.getHWNDTarget(); RECT rc; GetWindowRect(hParent, &rc); if (hwndFloater == 0) { hwndFloater = CreateWindowEx(WS_EX_TOOLWINDOW, szToolClass, t.c_str(), WS_POPUP | WS_THICKFRAME | WS_CAPTION, rc.right-300, rc.top+10, 600, 64, hParent, NULL, GetModuleHandle(0), NULL); SetWindowLongPtr(hwndFloater, GWL_USERDATA, LONG_PTR(this)); } else { SetWindowText(hwndFloater, t.c_str()); } if (hwndToolbar != 0) DestroyWindow(hwndToolbar); // Create the toolbar. hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_TOOLTIPS, 0, 0, 0, 0, hwndFloater, NULL, GetModuleHandle(0), NULL); if (hwndToolbar == NULL) return; toolbar_id = id; int ImageListID = 0; SendMessage(hwndToolbar, CCM_SETVERSION, 5, 0); // Set the image list. SendMessage(hwndToolbar, TB_SETIMAGELIST, (WPARAM)ImageListID, (LPARAM)hImageListDef); // Load the button images. SendMessage(hwndToolbar, TB_LOADIMAGES, (WPARAM)IDB_STD_LARGE_COLOR, (LPARAM)HINST_COMMCTRL); ImageListID = 1; // Set the image list. SendMessage(hwndToolbar, TB_SETIMAGELIST, (WPARAM)ImageListID, (LPARAM)hImageListMeOS); // Add buttons. SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); TBBUTTON *bt_ptr = &btn.at(0); SendMessage(hwndToolbar, TB_ADDBUTTONS, (WPARAM)btn.size(), (LPARAM)bt_ptr); SendMessage(hwndToolbar, TB_SETMAXTEXTROWS, 0, 0); // Tell the toolbar to resize itself, and show it. SendMessage(hwndToolbar, TB_AUTOSIZE, 0, 0); DWORD bsize = SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0,0); int bw = LOWORD(bsize); int bh = HIWORD(bsize); int tw = bw * btn.size(); // Resize floater GetClientRect(hwndFloater, &rc); int dx = rc.right - rc.left - tw; int dy = rc.bottom - rc.top - bh - 5; WINDOWPLACEMENT wpl; wpl.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(hwndFloater, &wpl); wpl.rcNormalPosition.right -= dx; wpl.rcNormalPosition.bottom -= dy; HWND desktop = GetDesktopWindow(); GetClientRect(desktop, &rc); dx = 0; dy = 0; if (wpl.rcNormalPosition.right > rc.right) dx = wpl.rcNormalPosition.right - rc.right + 10; else if (wpl.rcNormalPosition.left < 0) dx = wpl.rcNormalPosition.left - 10; if (wpl.rcNormalPosition.bottom > rc.bottom) dy = wpl.rcNormalPosition.bottom - rc.bottom + 10; else if (wpl.rcNormalPosition.top < 0) dy = wpl.rcNormalPosition.top - 30; if (dx != 0 || dy != 0) { OffsetRect(&wpl.rcNormalPosition, -dx, -dy); } SetWindowPlacement(hwndFloater, &wpl); SendMessage(hwndToolbar, TB_AUTOSIZE, 0, 0); ShowWindow(hwndFloater, SW_SHOW); ShowWindow(hwndToolbar, TRUE); } LRESULT CALLBACK ToolProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: break; case WM_SIZE: break; case WM_WINDOWPOSCHANGED: return DefWindowProc(hWnd, message, wParam, lParam); case WM_ACTIVATE: return DefWindowProc(hWnd, message, wParam, lParam); case WM_NCACTIVATE: { Toolbar *tb = (Toolbar *)GetWindowLongPtr(hWnd, GWL_USERDATA); if (tb) { //DefWindowProc(tb->gdi.getHWND(), message, wParam, lParam); SendMessage(tb->gdi.getHWNDMain(), message, wParam, lParam); } return DefWindowProc(hWnd, message, wParam, lParam); } case WM_PAINT: hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_DESTROY: break; case WM_COMMAND: { Toolbar *tb = (Toolbar *)GetWindowLongPtr(hWnd, GWL_USERDATA); int id = LOWORD(wParam); int code = HIWORD(wParam); if (tb) { tb->processCommand(id, code); } } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } HWND Toolbar::getFloater() const { return hwndFloater; } bool Toolbar::isVisible() const { if (!hwndFloater) return false; return IsWindowVisible(hwndFloater) != 0; }