/*+ * * Module: * Toolbar * * Description: * General toolbar functions * * Original author: * Stephen Chung * * Copyright (C) Stephen Chung, 1991. All rights reserved. -*/ #include #include "toolbar.h" #define MAXSTATES 3 static BOOL ClassRegistered = FALSE; static BOOL Capturing = FALSE; long FAR PASCAL ToolbarProc (HWND, WORD, WORD, LONG); long FAR PASCAL ToolbarButtonProc (HWND, WORD, WORD, LONG); void Create3DEffect (HDC hdc, RECT *rect, int thickness, int style) { int i; int x1 = rect->left; int y1 = rect->top; int x2 = rect->right; int y2 = rect->bottom; HBRUSH hbrush, oldbrush; HPEN hpen, oldpen; oldpen = SelectObject(hdc, GetStockObject(BLACK_PEN)); switch (style) { default: case 0: case 1: hbrush = GetStockObject(LTGRAY_BRUSH); break; case 2: hbrush = GetStockObject(WHITE_BRUSH); break; } oldbrush = SelectObject(hdc, hbrush); Rectangle(hdc, x1, y1, x2, y2); switch(style) { default: case 0: SelectObject(hdc, GetStockObject(WHITE_PEN)); break; case 1: hpen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128)); SelectObject(hdc, hpen); break; case 2: SelectObject(hdc, GetStockObject(BLACK_PEN)); break; } for (i = 1; i <= thickness; i++) { MoveTo(hdc, x1 + i, y1 + i); LineTo(hdc, x1 + i, y2 - 1); MoveTo(hdc, x1 + i, y1 + i); LineTo(hdc, x2 - 1, y1 + i); } switch (style) { default: case 0: case 2: hpen = CreatePen(PS_SOLID, 1, RGB(128,128,128)); SelectObject(hdc, hpen); break; case 1: SelectObject(hdc, GetStockObject(WHITE_PEN)); break; } for (i = 1; i <= thickness; i++) { MoveTo(hdc, x1 + i, y2 - 1 - i); LineTo(hdc, x2 - 1, y2 - 1 - i); MoveTo(hdc, x2 - 1 - i, y2 - 2); LineTo(hdc, x2 - 1 - i, y1 + i); } SelectObject(hdc, oldbrush); SelectObject(hdc, oldpen); DeleteObject(hpen); } static void CursorShape(HWND hwnd, int state) { HCURSOR hcursor; static HCURSOR arrow = NULL; if (state < 0) hcursor = (HCURSOR) GetWindowWord(GetParent(hwnd), 3 * sizeof(WORD)); else if (arrow == NULL) hcursor = arrow = LoadCursor(NULL, IDC_ARROW); else hcursor = arrow; SetCursor(hcursor); } void EnableToolbarButton (HWND hwnd, int id, BOOL enabled) { int i, n; TOOLBARICON *icons; icons = (TOOLBARICON *) GetWindowWord(hwnd, 0); n = (int) GetWindowWord(hwnd, sizeof(WORD)); for (i = 0; i < n && icons[i].id != id; i++); if (i >= n) return; if (enabled) { if (icons[i].state >= 0) return; icons[i].state = icons[i].oldstate; } else { if (icons[i].state < 0) return; icons[i].oldstate = icons[i].state; icons[i].state = -1; } InvalidateRect(icons[i].hwnd, NULL, FALSE); UpdateWindow(icons[i].hwnd); } HWND GetToolbarButton (HWND hwnd, int id, TOOLBARICON *ip) { int i, n; TOOLBARICON *icons; icons = (TOOLBARICON *) GetWindowWord(hwnd, 0); n = (int) GetWindowWord(hwnd, sizeof(WORD)); for (i = 0; i < n && icons[i].id != id; i++); if (i >= n) return (NULL); if (ip != NULL) *ip = icons[i]; return (icons[i].hwnd); } void ModifyToolbarButton (HWND hwnd, TOOLBARICON *icon) { TOOLBARICON *old; old = (TOOLBARICON *) GetWindowWord(hwnd, 0); old->id = icon->id; old->x = icon->x; old->y = icon->y; old->width = icon->width; old->height = icon->height; old->state = icon->state; old->cycle = icon->cycle; old->disabled = icon->disabled; old->undepressed = icon->undepressed; old->depressed = icon->depressed; old->grayed = icon->grayed; old->pressing = icon->pressing; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } HWND CreateToolbar (HWND parent, int x, int y, int width, int height, int thickness, int id, int n, HANDLE hInstance, TOOLBARICON *icons, char *xcursor) { int i; HWND hwnd; WNDCLASS wndclass; if (!ClassRegistered) { wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = ToolbarProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 4 * sizeof(WORD); wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = COLOR_BTNFACE + 1; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TOOLBARCLASS; RegisterClass(&wndclass); wndclass.cbWndExtra = sizeof(WORD); wndclass.lpfnWndProc = ToolbarButtonProc; wndclass.lpszClassName = TOOLBARBUTTONCLASS; RegisterClass(&wndclass); } hwnd = CreateWindow(TOOLBARCLASS, "", WS_CHILD /* | WS_VISIBLE */ , x, y, width, height, parent, id, hInstance, NULL); SetWindowWord(hwnd, 0, (WORD) icons); SetWindowWord(hwnd, sizeof(WORD), (WORD) n); SetWindowWord(hwnd, 2 * sizeof(WORD), (WORD) thickness); if (xcursor != NULL) { SetWindowWord(hwnd, 3 * sizeof(WORD), LoadCursor(hInstance, xcursor)); } else { SetWindowWord(hwnd, 3 * sizeof(WORD), NULL); } //ShowWindow(hwnd, SW_SHOW); //UpdateWindow(hwnd); /* Create the children */ for (i = 0; i < n; i++) { icons[i].hwnd = CreateWindow(TOOLBARBUTTONCLASS, "", WS_CHILD | WS_VISIBLE, icons[i].x, icons[i].y, icons[i].width, icons[i].height, hwnd, icons[i].id, hInstance, NULL); SetWindowWord(icons[i].hwnd, 0, (WORD) &(icons[i])); ShowWindow(icons[i].hwnd, SW_SHOW); UpdateWindow(hwnd); } return (hwnd); } long FAR PASCAL _export ToolbarProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) { int i; HDC hdc; PAINTSTRUCT ps; HWND child; RECT rect; TOOLBARICON *icons; switch (message) { case WM_PAINT: GetClientRect(hwnd, &rect); hdc = BeginPaint(hwnd, &ps); Create3DEffect(hdc, &rect, GetWindowWord(hwnd, 2 * sizeof(WORD)), 0); EndPaint(hwnd, &ps); return (0); case WM_COMMAND: SendMessage(GetParent(hwnd), WM_COMMAND, (wParam << 8) | GetWindowWord(hwnd, GWW_ID), lParam); return (0); case BM_SETSTATE: case BM_GETSTATE: icons = (TOOLBARICON *) GetWindowWord(hwnd, 0); for (i = 0; icons[i].id != LOWORD(lParam); i++); return (SendMessage(icons[i].hwnd, message, wParam, 0L)); } return (DefWindowProc(hwnd, message, wParam, lParam)); } long FAR PASCAL _export ToolbarButtonProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) { int i, j; BOOL crossed; HDC hdc, hdcmem; PAINTSTRUCT ps; HPEN hpen; HWND child; TOOLBARICON *icon; HBITMAP hbitmap; HANDLE hInstance; HCURSOR hcursor; icon = (TOOLBARICON *) GetWindowWord(hwnd, 0); switch (message) { case BM_SETSTATE: if (icon->state == wParam) return (0); icon->oldstate = icon->state = wParam; InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); return (0); case BM_GETSTATE: return (icon->state); case WM_LBUTTONDOWN: if (icon->state < 0) return (0); icon->oldstate = icon->state; icon->state = MAXSTATES; InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); SetCapture(hwnd); Capturing = TRUE; return (0); case WM_LBUTTONUP: if (!Capturing || icon->state < 0) return (0); ReleaseCapture(); Capturing = FALSE; i = LOWORD(lParam); j = HIWORD(lParam); if (i < 0 || i >= icon->width || j < 0 || j >= icon->height) { return (0); } else if (icon->cycle <= 0) { icon->state = icon->oldstate; } else { icon->oldstate++; if (icon->oldstate >= icon->cycle) icon->oldstate = 0; icon->state = icon->oldstate; } InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); CursorShape(hwnd, icon->state); SendMessage(GetParent(hwnd), WM_COMMAND, icon->id, MAKELONG(hwnd, BN_CLICKED)); return (0); case WM_MOUSEMOVE: CursorShape(hwnd, icon->state); if (!Capturing || icon->state < 0) return (0); i = LOWORD(lParam); j = HIWORD(lParam); if (i < 0 || i >= icon->width || j < 0 || j >= icon->height) { crossed = (icon->state == MAXSTATES); icon->state = icon->oldstate; } else { crossed = (icon->state != MAXSTATES); icon->state = MAXSTATES; } if (crossed) { InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); } return (0); case WM_PAINT: hInstance = GetWindowWord(hwnd, GWW_HINSTANCE); hdc = BeginPaint(hwnd, &ps); switch (icon->state) { default: if (icon->disabled != NULL) { hbitmap = LoadBitmap(hInstance, icon->disabled); } break; case 0: hbitmap = LoadBitmap(hInstance, icon->undepressed); break; case 1: hbitmap = LoadBitmap(hInstance, icon->depressed); break; case 2: hbitmap = LoadBitmap(hInstance, icon->grayed); break; case MAXSTATES: hbitmap = LoadBitmap(hInstance, icon->pressing); break; } hdcmem = CreateCompatibleDC(hdc); SelectObject(hdcmem, hbitmap); BitBlt(hdc, 0, 0, icon->width, icon->height, hdcmem, 0, 0, SRCCOPY); if (!DeleteDC(hdcmem)) MessageBox(NULL, "TOOLBAR: Could not delete DC", "DeleteDC error", MB_ICONEXCLAMATION | MB_OK); if (!DeleteObject(hbitmap)) MessageBox(NULL, "TOOLBAR: Could not delete bitmapC", "DeleteObject error", MB_ICONEXCLAMATION | MB_OK); EndPaint(hwnd, &ps); return (0); } return (DefWindowProc(hwnd, message, wParam, lParam)); }