/* This file is part of BKBTL. BKBTL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. BKBTL 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with BKBTL. If not, see . */ // ToolWindow.cpp #include "stdafx.h" #include "Main.h" #include "ToolWindow.h" #include ////////////////////////////////////////////////////////////////////// void ToolWindow_RegisterClass() { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = ToolWindow_WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInst; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = CLASSNAME_TOOLWINDOW; wcex.hIconSm = NULL; RegisterClassEx(&wcex); } LRESULT CALLBACK ToolWindow_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_NCCALCSIZE: { LPRECT pRect = (LPRECT) lParam; pRect->top += TOOLWINDOW_CAPTION_HEIGHT; } break; case WM_NCPAINT: { RECT rcClient; ::GetClientRect(hWnd, &rcClient); RECT rcWindow; ::GetWindowRect(hWnd, &rcWindow); MapWindowPoints(NULL, hWnd, (LPPOINT)&rcWindow, 2); rcClient.left -= rcWindow.left; rcClient.top -= rcWindow.top; rcClient.right -= rcWindow.left; rcClient.bottom -= rcWindow.top; rcWindow.left -= rcWindow.left; rcWindow.top -= rcWindow.top; rcWindow.right -= rcWindow.left; rcWindow.bottom -= rcWindow.top; HDC hdc = ::GetWindowDC(hWnd); ::ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); // Draw caption background BOOL okActive = (::GetActiveWindow() == hWnd); HBRUSH brushCaption = ::GetSysColorBrush(okActive ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION); RECT rc; rc.left = rc.top = 0; rc.right = rcWindow.right; rc.bottom = TOOLWINDOW_CAPTION_HEIGHT; ::FillRect(hdc, &rc, brushCaption); // Draw caption text TCHAR buffer[64]; ::GetWindowText(hWnd, buffer, 64); rc.left += 8; rc.right -= 8; HFONT hfont = CreateDialogFont(); HGDIOBJ hOldFont = ::SelectObject(hdc, hfont); ::SetTextColor(hdc, ::GetSysColor(COLOR_CAPTIONTEXT)); ::SetBkMode(hdc, TRANSPARENT); ::DrawText(hdc, buffer, (int)wcslen(buffer), &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE); ::SelectObject(hdc, hOldFont); VERIFY(::DeleteObject(hfont)); VERIFY(::ReleaseDC(hWnd, hdc)); } break; case WM_SETTEXT: { LRESULT lResult = DefWindowProc(hWnd, message, wParam, lParam); // Invalidate non-client area RECT rcWindow; ::GetWindowRect(hWnd, &rcWindow); MapWindowPoints(NULL, hWnd, (LPPOINT)&rcWindow, 2); ::RedrawWindow(hWnd, &rcWindow, NULL, RDW_FRAME | RDW_INVALIDATE); return lResult; } default: return DefWindowProc(hWnd, message, wParam, lParam); } return (LRESULT)FALSE; } ////////////////////////////////////////////////////////////////////// void OverlappedWindow_RegisterClass() { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = DefWindowProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInst; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = CLASSNAME_OVERLAPPEDWINDOW; wcex.hIconSm = NULL; RegisterClassEx(&wcex); } ////////////////////////////////////////////////////////////////////// bool m_SplitterWindow_IsMoving = false; int m_SplitterWindow_MovingStartY = 0; const int SPLITTERWINDOW_MINWINDOWHEIGHT = 64; void SplitterWindow_RegisterClass() { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = SplitterWindow_WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 8 * 2; wcex.hInstance = g_hInst; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_SIZENS); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = CLASSNAME_SPLITTERWINDOW; wcex.hIconSm = NULL; RegisterClassEx(&wcex); } HWND SplitterWindow_Create(HWND hwndParent, HWND hwndTop, HWND hwndBottom) { ASSERT(hwndParent != NULL); ASSERT(hwndTop != NULL); ASSERT(hwndBottom != NULL); HWND hwnd = CreateWindow( CLASSNAME_SPLITTERWINDOW, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 100, 4, hwndParent, NULL, g_hInst, NULL); SetWindowLongPtr(hwnd, 0, (LONG_PTR)hwndTop); SetWindowLongPtr(hwnd, 8, (LONG_PTR)hwndBottom); m_SplitterWindow_IsMoving = false; return hwnd; } void SplitterWindow_MoveWindows(HWND hwndSplitter, int deltaY) { if (deltaY == 0) return; HWND hwndTop = (HWND)GetWindowLongPtr(hwndSplitter, 0); HWND hwndBottom = (HWND)GetWindowLongPtr(hwndSplitter, 8); RECT rcTop; ::GetWindowRect(hwndTop, &rcTop); ::ScreenToClient(g_hwnd, (POINT*)&rcTop); ::ScreenToClient(g_hwnd, ((POINT*)&rcTop) + 1); RECT rcBottom; ::GetWindowRect(hwndBottom, &rcBottom); ::ScreenToClient(g_hwnd, (POINT*)&rcBottom); ::ScreenToClient(g_hwnd, ((POINT*)&rcBottom) + 1); if (deltaY < 0 && rcTop.bottom - rcTop.top + deltaY < SPLITTERWINDOW_MINWINDOWHEIGHT) deltaY = SPLITTERWINDOW_MINWINDOWHEIGHT - (rcTop.bottom - rcTop.top); if (deltaY > 0 && rcBottom.bottom - rcBottom.top - deltaY < SPLITTERWINDOW_MINWINDOWHEIGHT) deltaY = (rcBottom.bottom - rcBottom.top) - SPLITTERWINDOW_MINWINDOWHEIGHT; SetWindowPos(hwndTop, NULL, rcTop.left, rcTop.top, rcTop.right - rcTop.left, rcTop.bottom - rcTop.top + deltaY, SWP_NOZORDER); SetWindowPos(hwndBottom, NULL, rcBottom.left, rcBottom.top + deltaY, rcBottom.right - rcBottom.left, rcBottom.bottom - rcBottom.top - deltaY, SWP_NOZORDER); SetWindowPos(hwndSplitter, NULL, rcBottom.left, rcBottom.top + deltaY - 4, rcBottom.right - rcBottom.left, 4, SWP_NOZORDER); } LRESULT CALLBACK SplitterWindow_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_LBUTTONDOWN: m_SplitterWindow_IsMoving = true; m_SplitterWindow_MovingStartY = GET_Y_LPARAM(lParam); ::SetCapture(hWnd); //TODO: Draw frame return 0; case WM_LBUTTONUP: if (m_SplitterWindow_IsMoving) { m_SplitterWindow_IsMoving = false; ::ReleaseCapture(); int deltaY = GET_Y_LPARAM(lParam) - m_SplitterWindow_MovingStartY; SplitterWindow_MoveWindows(hWnd, deltaY); } return 0; case WM_MOUSEMOVE: if ((wParam == MK_LBUTTON) && m_SplitterWindow_IsMoving) { //TODO: Redraw frame } return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } //return (LRESULT)FALSE; } //////////////////////////////////////////////////////////////////////