1 /* 2 * PROJECT: PAINT for ReactOS 3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) 4 * PURPOSE: Window procedure of the main window and all children apart from 5 * hPalWin, hToolSettings and hSelection 6 * COPYRIGHT: Copyright 2015 Benedikt Freisen <b.freisen@gmx.net> 7 */ 8 9 #include "precomp.h" 10 11 CToolBox toolBoxContainer; 12 13 /* FUNCTIONS ********************************************************/ 14 15 LRESULT CALLBACK 16 CPaintToolBar::ToolBarWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 17 { 18 WNDPROC oldWndProc = (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_USERDATA); 19 if (uMsg == WM_LBUTTONUP) 20 { 21 // We have to detect clicking on toolbar even if no change of pressed button 22 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; 23 INT id = (INT)SendMessage(hwnd, TB_HITTEST, 0, (LPARAM)&pt); 24 ::PostMessage(::GetParent(hwnd), WM_TOOLBARHIT, id, 0); 25 } 26 return ::CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam); 27 } 28 29 BOOL CPaintToolBar::DoCreate(HWND hwndParent) 30 { 31 // NOTE: The horizontal line above the toolbar is hidden by CCS_NODIVIDER style. 32 RECT toolbarPos = { 0, 0, CX_TOOLBAR, CY_TOOLBAR }; 33 DWORD style = WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_VERT | CCS_NORESIZE | 34 TBSTYLE_TOOLTIPS | TBSTYLE_FLAT; 35 if (!CWindow::Create(TOOLBARCLASSNAME, hwndParent, toolbarPos, NULL, style)) 36 return FALSE; 37 38 HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 16, 0); 39 SendMessage(TB_SETIMAGELIST, 0, (LPARAM)hImageList); 40 41 HBITMAP hbmIcons = (HBITMAP)::LoadImage(g_hinstExe, MAKEINTRESOURCE(IDB_TOOLBARICONS), 42 IMAGE_BITMAP, 256, 16, 0); 43 ImageList_AddMasked(hImageList, hbmIcons, RGB(255, 0, 255)); 44 ::DeleteObject(hbmIcons); 45 46 SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); 47 48 TCHAR szToolTip[30]; 49 TBBUTTON tbbutton; 50 ZeroMemory(&tbbutton, sizeof(tbbutton)); 51 tbbutton.fsStyle = TBSTYLE_CHECKGROUP; 52 for (INT i = 0; i < NUM_TOOLS; i++) 53 { 54 ::LoadString(g_hinstExe, IDS_TOOLTIP1 + i, szToolTip, _countof(szToolTip)); 55 tbbutton.iString = (INT_PTR)szToolTip; 56 tbbutton.fsState = TBSTATE_ENABLED | ((i % 2 == 1) ? TBSTATE_WRAP : 0); 57 tbbutton.idCommand = ID_FREESEL + i; 58 tbbutton.iBitmap = i; 59 SendMessage(TB_ADDBUTTONS, 1, (LPARAM) &tbbutton); 60 } 61 62 SendMessage(TB_CHECKBUTTON, ID_PEN, MAKELPARAM(TRUE, 0)); 63 SendMessage(TB_SETMAXTEXTROWS, 0, 0); 64 SendMessage(TB_SETBUTTONSIZE, 0, MAKELPARAM(CXY_TB_BUTTON, CXY_TB_BUTTON)); 65 66 SetWindowLongPtr(GWLP_USERDATA, SetWindowLongPtr(GWLP_WNDPROC, (LONG_PTR)ToolBarWndProc)); 67 return TRUE; 68 } 69 70 BOOL CToolBox::DoCreate(HWND hwndParent) 71 { 72 RECT rcToolBox = { 0, 0, 0, 0 }; // Rely on mainWindow's WM_SIZE 73 DWORD style = WS_CHILD | (registrySettings.ShowToolBox ? WS_VISIBLE : 0); 74 return !!Create(hwndParent, rcToolBox, NULL, style); 75 } 76 77 LRESULT CToolBox::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 78 { 79 toolbar.DoCreate(m_hWnd); 80 toolSettingsWindow.DoCreate(m_hWnd); 81 return 0; 82 } 83 84 LRESULT CToolBox::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 85 { 86 toolbar.SendMessage(WM_SYSCOLORCHANGE, 0, 0); 87 return 0; 88 } 89 90 struct COMMAND_TO_TOOL 91 { 92 UINT id; 93 TOOLTYPE tool; 94 }; 95 96 static const COMMAND_TO_TOOL CommandToToolMapping[] = 97 { 98 { ID_FREESEL, TOOL_FREESEL }, 99 { ID_RECTSEL, TOOL_RECTSEL }, 100 { ID_RUBBER, TOOL_RUBBER }, 101 { ID_FILL, TOOL_FILL }, 102 { ID_COLOR, TOOL_COLOR }, 103 { ID_ZOOM, TOOL_ZOOM }, 104 { ID_PEN, TOOL_PEN }, 105 { ID_BRUSH, TOOL_BRUSH }, 106 { ID_AIRBRUSH, TOOL_AIRBRUSH }, 107 { ID_TEXT, TOOL_TEXT }, 108 { ID_LINE, TOOL_LINE }, 109 { ID_BEZIER, TOOL_BEZIER }, 110 { ID_RECT, TOOL_RECT }, 111 { ID_SHAPE, TOOL_SHAPE }, 112 { ID_ELLIPSE, TOOL_ELLIPSE }, 113 { ID_RRECT, TOOL_RRECT }, 114 }; 115 116 LRESULT CToolBox::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 117 { 118 UINT id = LOWORD(wParam); 119 for (size_t i = 0; i < _countof(CommandToToolMapping); ++i) 120 { 121 if (CommandToToolMapping[i].id == id) 122 { 123 toolsModel.SetActiveTool(CommandToToolMapping[i].tool); 124 break; 125 } 126 } 127 return 0; 128 } 129 130 LRESULT CToolBox::OnToolsModelToolChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 131 { 132 selectionModel.HideSelection(); 133 toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions 134 135 // Check the toolbar button 136 TOOLTYPE tool = toolsModel.GetActiveTool(); 137 for (size_t i = 0; i < _countof(CommandToToolMapping); ++i) 138 { 139 if (CommandToToolMapping[i].tool == tool) 140 { 141 toolbar.SendMessage(TB_CHECKBUTTON, CommandToToolMapping[i].id, TRUE); 142 break; 143 } 144 } 145 146 return 0; 147 } 148 149 LRESULT CToolBox::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 150 { 151 SetCapture(); 152 return 0; 153 } 154 155 LRESULT CToolBox::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 156 { 157 if (::GetCapture() != m_hWnd) 158 return 0; 159 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; 160 ClientToScreen(&pt); 161 162 RECT rc; 163 mainWindow.GetWindowRect(&rc); 164 165 POINT ptCenter = { (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2 }; 166 167 DWORD dwExpectedBar2ID = ((pt.x < ptCenter.x) ? BAR2ID_LEFT : BAR2ID_RIGHT); 168 169 if (registrySettings.Bar2ID != dwExpectedBar2ID) 170 { 171 registrySettings.Bar2ID = dwExpectedBar2ID; 172 mainWindow.PostMessage(WM_SIZE, 0, 0); 173 } 174 175 return 0; 176 } 177 178 LRESULT CToolBox::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 179 { 180 if (::GetCapture() != m_hWnd) 181 return 0; 182 183 ::ReleaseCapture(); 184 return 0; 185 } 186 187 LRESULT CToolBox::OnToolBarHit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 188 { 189 // See also: CPaintToolBar::ToolBarWndProc 190 selectionModel.Landing(); 191 return 0; 192 } 193