Fix C4302 warnings: 'conversion': truncation from 'type 1' to 'type 2'
[TortoiseGit.git] / src / TortoiseIDiff / MainWindow.cpp
blobc5310396dab5b5b13107f59b3ab8aa6d8011c5d9
1 // TortoiseIDiff - an image diff viewer in TortoiseSVN
3 // Copyright (C) 2006-2013, 2015 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include <CommCtrl.h>
21 #include <Commdlg.h>
22 #include "TortoiseIDiff.h"
23 #include "MainWindow.h"
24 #include "AboutDlg.h"
25 #include "TaskbarUUID.h"
27 #pragma comment(lib, "comctl32.lib")
29 tstring CMainWindow::leftpicpath;
30 tstring CMainWindow::leftpictitle;
32 tstring CMainWindow::rightpicpath;
33 tstring CMainWindow::rightpictitle;
35 const UINT TaskBarButtonCreated = RegisterWindowMessage(L"TaskbarButtonCreated");
37 bool CMainWindow::RegisterAndCreateWindow()
39 WNDCLASSEX wcx;
41 // Fill in the window class structure with default parameters
42 wcx.cbSize = sizeof(WNDCLASSEX);
43 wcx.style = CS_HREDRAW | CS_VREDRAW;
44 wcx.lpfnWndProc = CWindow::stWinMsgHandler;
45 wcx.cbClsExtra = 0;
46 wcx.cbWndExtra = 0;
47 wcx.hInstance = hResource;
48 wcx.hCursor = LoadCursor(NULL, IDC_SIZEWE);
49 ResString clsname(hResource, IDS_APP_TITLE);
50 wcx.lpszClassName = clsname;
51 wcx.hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_TORTOISEIDIFF));
52 wcx.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
53 if (selectionPaths.empty())
54 wcx.lpszMenuName = MAKEINTRESOURCE(IDC_TORTOISEIDIFF);
55 else
56 wcx.lpszMenuName = MAKEINTRESOURCE(IDC_TORTOISEIDIFF2);
57 wcx.hIconSm = LoadIcon(wcx.hInstance, MAKEINTRESOURCE(IDI_TORTOISEIDIFF));
58 if (RegisterWindow(&wcx))
60 if (Create(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE, NULL))
62 UpdateWindow(m_hwnd);
63 return true;
66 return false;
69 void CMainWindow::PositionChildren(RECT * clientrect /* = NULL */)
71 RECT tbRect;
72 if (clientrect == NULL)
73 return;
74 SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);
75 GetWindowRect(hwndTB, &tbRect);
76 LONG tbHeight = tbRect.bottom-tbRect.top-1;
77 HDWP hdwp = BeginDeferWindowPos(3);
78 if (bOverlap && selectionPaths.empty())
80 SetWindowPos(picWindow1, NULL, clientrect->left, clientrect->top+tbHeight, clientrect->right-clientrect->left, clientrect->bottom-clientrect->top-tbHeight, SWP_SHOWWINDOW);
82 else
84 if (bVertical)
86 if (selectionPaths.size() != 3)
88 // two image windows
89 RECT child;
90 child.left = clientrect->left;
91 child.top = clientrect->top+tbHeight;
92 child.right = clientrect->right;
93 child.bottom = nSplitterPos-(SPLITTER_BORDER/2);
94 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow1, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
95 child.top = nSplitterPos+(SPLITTER_BORDER/2);
96 child.bottom = clientrect->bottom;
97 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow2, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
99 else
101 // three image windows
102 RECT child;
103 child.left = clientrect->left;
104 child.top = clientrect->top+tbHeight;
105 child.right = clientrect->right;
106 child.bottom = nSplitterPos-(SPLITTER_BORDER/2);
107 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow1, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
108 child.top = nSplitterPos+(SPLITTER_BORDER/2);
109 child.bottom = nSplitterPos2-(SPLITTER_BORDER/2);
110 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow2, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
111 child.top = nSplitterPos2+(SPLITTER_BORDER/2);
112 child.bottom = clientrect->bottom;
113 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow3, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
116 else
118 if (selectionPaths.size() != 3)
120 // two image windows
121 RECT child;
122 child.left = clientrect->left;
123 child.top = clientrect->top+tbHeight;
124 child.right = nSplitterPos-(SPLITTER_BORDER/2);
125 child.bottom = clientrect->bottom;
126 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow1, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
127 child.left = nSplitterPos+(SPLITTER_BORDER/2);
128 child.right = clientrect->right;
129 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow2, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
131 else
133 // three image windows
134 RECT child;
135 child.left = clientrect->left;
136 child.top = clientrect->top+tbHeight;
137 child.right = nSplitterPos-(SPLITTER_BORDER/2);
138 child.bottom = clientrect->bottom;
139 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow1, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
140 child.left = nSplitterPos+(SPLITTER_BORDER/2);
141 child.right = nSplitterPos2-(SPLITTER_BORDER/2);
142 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow2, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
143 child.left = nSplitterPos2+(SPLITTER_BORDER/2);
144 child.right = clientrect->right;
145 if (hdwp) hdwp = DeferWindowPos(hdwp, picWindow3, NULL, child.left, child.top, child.right-child.left, child.bottom-child.top, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
149 if (hdwp) EndDeferWindowPos(hdwp);
150 picWindow1.SetTransparentColor(transparentColor);
151 picWindow2.SetTransparentColor(transparentColor);
152 picWindow3.SetTransparentColor(transparentColor);
153 InvalidateRect(*this, NULL, FALSE);
156 LRESULT CALLBACK CMainWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
158 if (uMsg == TaskBarButtonCreated)
160 SetUUIDOverlayIcon(hwnd);
162 switch (uMsg)
164 case WM_CREATE:
166 m_hwnd = hwnd;
167 picWindow1.RegisterAndCreateWindow(hwnd);
168 picWindow2.RegisterAndCreateWindow(hwnd);
169 if (selectionPaths.empty())
171 picWindow1.SetPic(leftpicpath, leftpictitle, true);
172 picWindow2.SetPic(rightpicpath, rightpictitle, false);
174 picWindow1.SetOtherPicWindow(&picWindow2);
175 picWindow2.SetOtherPicWindow(&picWindow1);
177 else
179 picWindow3.RegisterAndCreateWindow(hwnd);
181 picWindow1.SetPic(selectionPaths[FileTypeMine], selectionTitles[FileTypeMine], false);
182 picWindow2.SetPic(selectionPaths[FileTypeBase], selectionTitles[FileTypeBase], false);
183 picWindow3.SetPic(selectionPaths[FileTypeTheirs], selectionTitles[FileTypeTheirs], false);
186 picWindow1.SetSelectionMode(!selectionPaths.empty());
187 picWindow2.SetSelectionMode(!selectionPaths.empty());
188 picWindow3.SetSelectionMode(!selectionPaths.empty());
190 CreateToolbar();
191 // center the splitter
192 RECT rect;
193 GetClientRect(hwnd, &rect);
194 if (selectionPaths.size() != 3)
196 nSplitterPos = (rect.right-rect.left)/2;
197 nSplitterPos2 = 0;
199 else
201 nSplitterPos = (rect.right-rect.left)/3;
202 nSplitterPos2 = (rect.right-rect.left)*2/3;
205 PositionChildren(&rect);
206 picWindow1.FitImageInWindow();
207 picWindow2.FitImageInWindow();
208 picWindow3.FitImageInWindow();
210 break;
211 case WM_COMMAND:
213 return DoCommand(LOWORD(wParam), lParam);
215 break;
216 case WM_PAINT:
218 PAINTSTRUCT ps;
219 HDC hdc;
220 RECT rect;
222 ::GetClientRect(*this, &rect);
223 hdc = BeginPaint(hwnd, &ps);
224 SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
225 ::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
226 EndPaint(hwnd, &ps);
228 break;
229 case WM_GETMINMAXINFO:
231 MINMAXINFO * mmi = (MINMAXINFO*)lParam;
232 mmi->ptMinTrackSize.x = WINDOW_MINWIDTH;
233 mmi->ptMinTrackSize.y = WINDOW_MINHEIGHT;
234 return 0;
236 break;
237 case WM_SIZE:
239 RECT rect;
240 GetClientRect(hwnd, &rect);
241 if (bVertical)
243 RECT tbRect;
244 GetWindowRect(hwndTB, &tbRect);
245 LONG tbHeight = tbRect.bottom-tbRect.top-1;
246 if (selectionPaths.size() != 3)
248 nSplitterPos = (rect.bottom-rect.top)/2+tbHeight;
249 nSplitterPos2 = 0;
251 else
253 nSplitterPos = (rect.bottom-rect.top)/3+tbHeight;
254 nSplitterPos2 = (rect.bottom-rect.top)*2/3+tbHeight;
257 else
259 if (selectionPaths.size() != 3)
261 nSplitterPos = (rect.right-rect.left)/2;
262 nSplitterPos2 = 0;
264 else
266 nSplitterPos = (rect.right-rect.left)/3;
267 nSplitterPos2 = (rect.right-rect.left)*2/3;
270 PositionChildren(&rect);
272 break;
273 case WM_SETCURSOR:
275 if ((HWND)wParam == *this)
277 RECT rect;
278 POINT pt;
279 GetClientRect(*this, &rect);
280 GetCursorPos(&pt);
281 ScreenToClient(*this, &pt);
282 if (PtInRect(&rect, pt))
284 if (bVertical)
286 HCURSOR hCur = LoadCursor(NULL, IDC_SIZENS);
287 SetCursor(hCur);
289 else
291 HCURSOR hCur = LoadCursor(NULL, IDC_SIZEWE);
292 SetCursor(hCur);
294 return TRUE;
297 return DefWindowProc(hwnd, uMsg, wParam, lParam);
299 break;
300 case WM_LBUTTONDOWN:
301 Splitter_OnLButtonDown(hwnd, uMsg, wParam, lParam);
302 break;
303 case WM_LBUTTONUP:
304 Splitter_OnLButtonUp(hwnd, uMsg, wParam, lParam);
305 break;
306 case WM_CAPTURECHANGED:
307 Splitter_CaptureChanged();
308 break;
309 case WM_MOUSEMOVE:
310 Splitter_OnMouseMove(hwnd, uMsg, wParam, lParam);
311 break;
312 case WM_MOUSEWHEEL:
314 // find out if the mouse cursor is over one of the views, and if
315 // it is, pass the mouse wheel message to that view
316 POINT pt;
317 DWORD ptW = GetMessagePos();
318 pt.x = GET_X_LPARAM(ptW);
319 pt.y = GET_Y_LPARAM(ptW);
320 RECT rect;
321 GetWindowRect(picWindow1, &rect);
322 if (PtInRect(&rect, pt))
324 picWindow1.OnMouseWheel(GET_KEYSTATE_WPARAM(wParam), GET_WHEEL_DELTA_WPARAM(wParam));
326 else
328 GetWindowRect(picWindow2, &rect);
329 if (PtInRect(&rect, pt))
331 picWindow2.OnMouseWheel(GET_KEYSTATE_WPARAM(wParam), GET_WHEEL_DELTA_WPARAM(wParam));
333 else
335 GetWindowRect(picWindow3, &rect);
336 if (PtInRect(&rect, pt))
338 picWindow3.OnMouseWheel(GET_KEYSTATE_WPARAM(wParam), GET_WHEEL_DELTA_WPARAM(wParam));
343 break;
344 case WM_MOUSEHWHEEL:
346 // find out if the mouse cursor is over one of the views, and if
347 // it is, pass the mouse wheel message to that view
348 POINT pt;
349 DWORD ptW = GetMessagePos();
350 pt.x = GET_X_LPARAM(ptW);
351 pt.y = GET_Y_LPARAM(ptW);
352 RECT rect;
353 GetWindowRect(picWindow1, &rect);
354 if (PtInRect(&rect, pt))
356 picWindow1.OnMouseWheel(GET_KEYSTATE_WPARAM(wParam)|MK_SHIFT, GET_WHEEL_DELTA_WPARAM(wParam));
358 else
360 GetWindowRect(picWindow2, &rect);
361 if (PtInRect(&rect, pt))
363 picWindow2.OnMouseWheel(GET_KEYSTATE_WPARAM(wParam)|MK_SHIFT, GET_WHEEL_DELTA_WPARAM(wParam));
365 else
367 GetWindowRect(picWindow3, &rect);
368 if (PtInRect(&rect, pt))
370 picWindow3.OnMouseWheel(GET_KEYSTATE_WPARAM(wParam)|MK_SHIFT, GET_WHEEL_DELTA_WPARAM(wParam));
375 break;
376 case WM_NOTIFY:
378 LPNMHDR pNMHDR = (LPNMHDR)lParam;
379 if (pNMHDR->code == TTN_GETDISPINFO)
381 LPTOOLTIPTEXT lpttt;
383 lpttt = (LPTOOLTIPTEXT) lParam;
384 lpttt->hinst = hResource;
386 // Specify the resource identifier of the descriptive
387 // text for the given button.
388 TCHAR stringbuf[MAX_PATH] = {0};
389 MENUITEMINFO mii;
390 mii.cbSize = sizeof(MENUITEMINFO);
391 mii.fMask = MIIM_TYPE;
392 mii.dwTypeData = stringbuf;
393 mii.cch = _countof(stringbuf);
394 GetMenuItemInfo(GetMenu(*this), (UINT)lpttt->hdr.idFrom, FALSE, &mii);
395 _tcscpy_s(lpttt->lpszText, 80, stringbuf);
398 break;
399 case WM_DESTROY:
400 bWindowClosed = TRUE;
401 PostQuitMessage(0);
402 break;
403 case WM_CLOSE:
404 ImageList_Destroy(hToolbarImgList);
405 ::DestroyWindow(m_hwnd);
406 break;
407 default:
408 return DefWindowProc(hwnd, uMsg, wParam, lParam);
411 return 0;
414 LRESULT CMainWindow::DoCommand(int id, LPARAM lParam)
416 switch (id)
418 case ID_FILE_OPEN:
420 if (OpenDialog())
422 picWindow1.SetPic(leftpicpath, _T(""), true);
423 picWindow2.SetPic(rightpicpath, _T(""), false);
424 if (bOverlap)
426 picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath);
428 else
430 picWindow1.SetSecondPic();
432 RECT rect;
433 GetClientRect(*this, &rect);
434 PositionChildren(&rect);
435 picWindow1.FitImageInWindow();
436 picWindow2.FitImageInWindow();
439 break;
440 case ID_VIEW_IMAGEINFO:
442 bShowInfo = !bShowInfo;
443 HMENU hMenu = GetMenu(*this);
444 UINT uCheck = MF_BYCOMMAND;
445 uCheck |= bShowInfo ? MF_CHECKED : MF_UNCHECKED;
446 CheckMenuItem(hMenu, ID_VIEW_IMAGEINFO, uCheck);
448 picWindow1.ShowInfo(bShowInfo);
449 picWindow2.ShowInfo(bShowInfo);
450 picWindow3.ShowInfo(bShowInfo);
452 // change the state of the toolbar button
453 TBBUTTONINFO tbi;
454 tbi.cbSize = sizeof(TBBUTTONINFO);
455 tbi.dwMask = TBIF_STATE;
456 tbi.fsState = bShowInfo ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
457 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_IMAGEINFO, (LPARAM)&tbi);
459 break;
460 case ID_VIEW_OVERLAPIMAGES:
462 bOverlap = !bOverlap;
463 HMENU hMenu = GetMenu(*this);
464 UINT uCheck = MF_BYCOMMAND;
465 uCheck |= bOverlap ? MF_CHECKED : MF_UNCHECKED;
466 CheckMenuItem(hMenu, ID_VIEW_OVERLAPIMAGES, uCheck);
467 uCheck |= ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? MF_CHECKED : MF_UNCHECKED;
468 CheckMenuItem(hMenu, ID_VIEW_BLENDALPHA, uCheck);
469 UINT uEnabled = MF_BYCOMMAND;
470 uEnabled |= bOverlap ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
471 EnableMenuItem(hMenu, ID_VIEW_BLENDALPHA, uEnabled);
473 // change the state of the toolbar button
474 TBBUTTONINFO tbi;
475 tbi.cbSize = sizeof(TBBUTTONINFO);
476 tbi.dwMask = TBIF_STATE;
477 tbi.fsState = ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? TBSTATE_CHECKED : 0;
478 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_OVERLAPIMAGES, (LPARAM)&tbi);
480 tbi.fsState = (m_BlendType == CPicWindow::BLEND_ALPHA) ? TBSTATE_CHECKED : 0;
481 if (bOverlap)
482 tbi.fsState |= TBSTATE_ENABLED;
483 else
484 tbi.fsState = 0;
485 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_BLENDALPHA, (LPARAM)&tbi);
487 if (bOverlap)
488 tbi.fsState = 0;
489 else
490 tbi.fsState = bVertical ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED;
491 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_ARRANGEVERTICAL, (LPARAM)&tbi);
493 if (bOverlap)
495 bLinkedPositions = true;
496 picWindow1.LinkPositions(bLinkedPositions);
497 picWindow2.LinkPositions(bLinkedPositions);
498 tbi.fsState = TBSTATE_CHECKED;
500 else
501 tbi.fsState = bLinkedPositions ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED;
502 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_LINKIMAGESTOGETHER, (LPARAM)&tbi);
504 ShowWindow(picWindow2, bOverlap ? SW_HIDE : SW_SHOW);
506 if (bOverlap)
508 picWindow1.StopTimer();
509 picWindow2.StopTimer();
510 picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath,
511 picWindow2.GetHPos(), picWindow2.GetVPos());
512 picWindow1.SetBlendAlpha(m_BlendType, 0.5f);
514 else
516 picWindow1.SetSecondPic();
518 picWindow1.SetOverlapMode(bOverlap);
519 picWindow2.SetOverlapMode(bOverlap);
522 RECT rect;
523 GetClientRect(*this, &rect);
524 PositionChildren(&rect);
526 return 0;
528 break;
529 case ID_VIEW_BLENDALPHA:
531 if (m_BlendType == CPicWindow::BLEND_ALPHA)
532 m_BlendType = CPicWindow::BLEND_XOR;
533 else
534 m_BlendType = CPicWindow::BLEND_ALPHA;
536 HMENU hMenu = GetMenu(*this);
537 UINT uCheck = MF_BYCOMMAND;
538 uCheck |= ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? MF_CHECKED : MF_UNCHECKED;
539 CheckMenuItem(hMenu, ID_VIEW_BLENDALPHA, uCheck);
540 UINT uEnabled = MF_BYCOMMAND;
541 uEnabled |= bOverlap ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
542 EnableMenuItem(hMenu, ID_VIEW_BLENDALPHA, uEnabled);
544 // change the state of the toolbar button
545 TBBUTTONINFO tbi;
546 tbi.cbSize = sizeof(TBBUTTONINFO);
547 tbi.dwMask = TBIF_STATE;
548 tbi.fsState = ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
549 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_BLENDALPHA, (LPARAM)&tbi);
550 picWindow1.SetBlendAlpha(m_BlendType, picWindow1.GetBlendAlpha());
551 PositionChildren();
553 break;
554 case ID_VIEW_TRANSPARENTCOLOR:
556 static COLORREF customColors[16] = {0};
557 CHOOSECOLOR ccDlg;
558 memset(&ccDlg, 0, sizeof(ccDlg));
559 ccDlg.lStructSize = sizeof(ccDlg);
560 ccDlg.hwndOwner = m_hwnd;
561 ccDlg.rgbResult = transparentColor;
562 ccDlg.lpCustColors = customColors;
563 ccDlg.Flags = CC_RGBINIT | CC_FULLOPEN;
564 if(ChooseColor(&ccDlg))
566 transparentColor = ccDlg.rgbResult;
567 picWindow1.SetTransparentColor(transparentColor);
568 picWindow2.SetTransparentColor(transparentColor);
569 picWindow3.SetTransparentColor(transparentColor);
570 // The color picker takes the focus and we don't get it back.
571 ::SetFocus(picWindow1);
574 break;
575 case ID_VIEW_FITIMAGEWIDTHS:
577 bFitWidths = !bFitWidths;
578 picWindow1.FitWidths(bFitWidths);
579 picWindow2.FitWidths(bFitWidths);
580 picWindow3.FitWidths(bFitWidths);
582 HMENU hMenu = GetMenu(*this);
583 UINT uCheck = MF_BYCOMMAND;
584 uCheck |= bFitWidths ? MF_CHECKED : MF_UNCHECKED;
585 CheckMenuItem(hMenu, ID_VIEW_FITIMAGEWIDTHS, uCheck);
587 // change the state of the toolbar button
588 TBBUTTONINFO tbi;
589 tbi.cbSize = sizeof(TBBUTTONINFO);
590 tbi.dwMask = TBIF_STATE;
591 tbi.fsState = bFitWidths ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
592 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_FITIMAGEWIDTHS, (LPARAM)&tbi);
594 break;
595 case ID_VIEW_FITIMAGEHEIGHTS:
597 bFitHeights = !bFitHeights;
598 picWindow1.FitHeights(bFitHeights);
599 picWindow2.FitHeights(bFitHeights);
600 picWindow3.FitHeights(bFitHeights);
602 HMENU hMenu = GetMenu(*this);
603 UINT uCheck = MF_BYCOMMAND;
604 uCheck |= bFitHeights ? MF_CHECKED : MF_UNCHECKED;
605 CheckMenuItem(hMenu, ID_VIEW_FITIMAGEHEIGHTS, uCheck);
607 // change the state of the toolbar button
608 TBBUTTONINFO tbi;
609 tbi.cbSize = sizeof(TBBUTTONINFO);
610 tbi.dwMask = TBIF_STATE;
611 tbi.fsState = bFitHeights ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
612 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_FITIMAGEHEIGHTS, (LPARAM)&tbi);
614 break;
615 case ID_VIEW_LINKIMAGESTOGETHER:
617 bLinkedPositions = !bLinkedPositions;
618 picWindow1.LinkPositions(bLinkedPositions);
619 picWindow2.LinkPositions(bLinkedPositions);
620 picWindow3.LinkPositions(bLinkedPositions);
622 HMENU hMenu = GetMenu(*this);
623 UINT uCheck = MF_BYCOMMAND;
624 uCheck |= bLinkedPositions ? MF_CHECKED : MF_UNCHECKED;
625 CheckMenuItem(hMenu, ID_VIEW_LINKIMAGESTOGETHER, uCheck);
627 // change the state of the toolbar button
628 TBBUTTONINFO tbi;
629 tbi.cbSize = sizeof(TBBUTTONINFO);
630 tbi.dwMask = TBIF_STATE;
631 tbi.fsState = bLinkedPositions ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
632 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_LINKIMAGESTOGETHER, (LPARAM)&tbi);
634 break;
635 case ID_VIEW_ALPHA0:
636 picWindow1.SetBlendAlpha(m_BlendType, 0.0f);
637 break;
638 case ID_VIEW_ALPHA255:
639 picWindow1.SetBlendAlpha(m_BlendType, 1.0f);
640 break;
641 case ID_VIEW_ALPHA127:
642 picWindow1.SetBlendAlpha(m_BlendType, 0.5f);
643 break;
644 case ID_VIEW_ALPHATOGGLE:
645 picWindow1.ToggleAlpha();
646 break;
647 case ID_VIEW_FITIMAGESINWINDOW:
649 picWindow1.FitImageInWindow();
650 picWindow2.FitImageInWindow();
651 picWindow3.FitImageInWindow();
653 break;
654 case ID_VIEW_ORININALSIZE:
656 picWindow1.SetZoom(100, false);
657 picWindow2.SetZoom(100, false);
658 picWindow3.SetZoom(100, false);
659 picWindow1.CenterImage();
660 picWindow2.CenterImage();
661 picWindow3.CenterImage();
663 break;
664 case ID_VIEW_ZOOMIN:
666 picWindow1.Zoom(true, false);
667 if ((!(bFitWidths || bFitHeights))&&(!bOverlap))
669 picWindow2.Zoom(true, false);
670 picWindow3.Zoom(true, false);
673 break;
674 case ID_VIEW_ZOOMOUT:
676 picWindow1.Zoom(false, false);
677 if ((!(bFitWidths || bFitHeights))&&(!bOverlap))
679 picWindow2.Zoom(false, false);
680 picWindow3.Zoom(false, false);
683 break;
684 case ID_VIEW_ARRANGEVERTICAL:
686 bVertical = !bVertical;
687 RECT rect;
688 GetClientRect(*this, &rect);
689 if (bVertical)
691 RECT tbRect;
692 GetWindowRect(hwndTB, &tbRect);
693 LONG tbHeight = tbRect.bottom-tbRect.top-1;
694 if (selectionPaths.size() != 3)
696 nSplitterPos = (rect.bottom-rect.top)/2+tbHeight;
697 nSplitterPos2 = 0;
699 else
701 nSplitterPos = (rect.bottom-rect.top)/3+tbHeight;
702 nSplitterPos2 = (rect.bottom-rect.top)*2/3+tbHeight;
705 else
707 if (selectionPaths.size() != 3)
709 nSplitterPos = (rect.right-rect.left)/2;
710 nSplitterPos2 = 0;
712 else
714 nSplitterPos = (rect.right-rect.left)/3;
715 nSplitterPos2 = (rect.right-rect.left)*2/3;
718 HMENU hMenu = GetMenu(*this);
719 UINT uCheck = MF_BYCOMMAND;
720 uCheck |= bVertical ? MF_CHECKED : MF_UNCHECKED;
721 CheckMenuItem(hMenu, ID_VIEW_ARRANGEVERTICAL, uCheck);
722 // change the state of the toolbar button
723 TBBUTTONINFO tbi;
724 tbi.cbSize = sizeof(TBBUTTONINFO);
725 tbi.dwMask = TBIF_STATE;
726 tbi.fsState = bVertical ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
727 SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_ARRANGEVERTICAL, (LPARAM)&tbi);
729 PositionChildren(&rect);
731 break;
732 case ID_ABOUT:
734 CAboutDlg dlg(*this);
735 dlg.DoModal(hInst, IDD_ABOUT, *this);
737 break;
738 case SELECTBUTTON_ID:
740 HWND hSource = (HWND)lParam;
741 if (picWindow1 == hSource)
743 if (!selectionResult.empty())
744 CopyFile(selectionPaths[FileTypeMine].c_str(), selectionResult.c_str(), FALSE);
745 PostQuitMessage(FileTypeMine);
747 if (picWindow2 == hSource)
749 if (!selectionResult.empty())
750 CopyFile(selectionPaths[FileTypeBase].c_str(), selectionResult.c_str(), FALSE);
751 PostQuitMessage(FileTypeBase);
753 if (picWindow3 == hSource)
755 if (!selectionResult.empty())
756 CopyFile(selectionPaths[FileTypeTheirs].c_str(), selectionResult.c_str(), FALSE);
757 PostQuitMessage(FileTypeTheirs);
760 break;
761 case IDM_EXIT:
762 ::PostQuitMessage(0);
763 return 0;
764 break;
765 default:
766 break;
768 return 1;
771 // splitter stuff
772 void CMainWindow::DrawXorBar(HDC hdc, int x1, int y1, int width, int height)
774 static WORD _dotPatternBmp[8] =
776 0x0055, 0x00aa, 0x0055, 0x00aa,
777 0x0055, 0x00aa, 0x0055, 0x00aa
780 HBITMAP hbm;
781 HBRUSH hbr, hbrushOld;
783 hbm = CreateBitmap(8, 8, 1, 1, _dotPatternBmp);
784 hbr = CreatePatternBrush(hbm);
786 SetBrushOrgEx(hdc, x1, y1, 0);
787 hbrushOld = (HBRUSH)SelectObject(hdc, hbr);
789 PatBlt(hdc, x1, y1, width, height, PATINVERT);
791 SelectObject(hdc, hbrushOld);
793 DeleteObject(hbr);
794 DeleteObject(hbm);
797 LRESULT CMainWindow::Splitter_OnLButtonDown(HWND hwnd, UINT /*iMsg*/, WPARAM /*wParam*/, LPARAM lParam)
799 POINT pt;
800 HDC hdc;
801 RECT rect;
802 RECT clientrect;
804 pt.x = (short)LOWORD(lParam); // horizontal position of cursor
805 pt.y = (short)HIWORD(lParam);
807 GetClientRect(hwnd, &clientrect);
808 GetWindowRect(hwnd, &rect);
809 POINT zero = {0,0};
810 ClientToScreen(hwnd, &zero);
811 OffsetRect(&clientrect, zero.x-rect.left, zero.y-rect.top);
813 ClientToScreen(hwnd, &pt);
814 // find out which drag bar is used
815 bDrag2 = false;
816 if (!selectionPaths.empty())
818 RECT pic2Rect;
819 GetWindowRect(picWindow2, &pic2Rect);
820 if (bVertical)
822 if (pic2Rect.bottom <= pt.y)
823 bDrag2 = true;
825 else
827 if (pic2Rect.right <= pt.x)
828 bDrag2 = true;
832 //convert the mouse coordinates relative to the top-left of
833 //the window
834 pt.x -= rect.left;
835 pt.y -= rect.top;
837 //same for the window coordinates - make them relative to 0,0
838 OffsetRect(&rect, -rect.left, -rect.top);
840 if (pt.x < 0)
841 pt.x = 0;
842 if (pt.x > rect.right-4)
843 pt.x = rect.right-4;
844 if (pt.y < 0)
845 pt.y = 0;
846 if (pt.y > rect.bottom-4)
847 pt.y = rect.bottom-4;
849 bDragMode = true;
851 SetCapture(hwnd);
853 hdc = GetWindowDC(hwnd);
854 if (bVertical)
855 DrawXorBar(hdc, clientrect.left, pt.y+2, clientrect.right-clientrect.left-2, 4);
856 else
857 DrawXorBar(hdc, pt.x+2, clientrect.top, 4, clientrect.bottom-clientrect.top-2);
858 ReleaseDC(hwnd, hdc);
860 oldx = pt.x;
861 oldy = pt.y;
863 return 0;
866 void CMainWindow::Splitter_CaptureChanged()
868 bDragMode = false;
871 LRESULT CMainWindow::Splitter_OnLButtonUp(HWND hwnd, UINT /*iMsg*/, WPARAM /*wParam*/, LPARAM lParam)
873 HDC hdc;
874 RECT rect;
875 RECT clientrect;
877 POINT pt;
878 pt.x = (short)LOWORD(lParam); // horizontal position of cursor
879 pt.y = (short)HIWORD(lParam);
881 if (bDragMode == FALSE)
882 return 0;
884 GetClientRect(hwnd, &clientrect);
885 GetWindowRect(hwnd, &rect);
886 POINT zero = {0,0};
887 ClientToScreen(hwnd, &zero);
888 OffsetRect(&clientrect, zero.x-rect.left, zero.y-rect.top);
890 ClientToScreen(hwnd, &pt);
891 pt.x -= rect.left;
892 pt.y -= rect.top;
894 OffsetRect(&rect, -rect.left, -rect.top);
896 if (pt.x < 0)
897 pt.x = 0;
898 if (pt.x > rect.right-4)
899 pt.x = rect.right-4;
900 if (pt.y < 0)
901 pt.y = 0;
902 if (pt.y > rect.bottom-4)
903 pt.y = rect.bottom-4;
905 hdc = GetWindowDC(hwnd);
906 if (bVertical)
907 DrawXorBar(hdc, clientrect.left, oldy+2, clientrect.right-clientrect.left-2, 4);
908 else
909 DrawXorBar(hdc, oldx+2, clientrect.top, 4, clientrect.bottom-clientrect.top-2);
910 ReleaseDC(hwnd, hdc);
912 oldx = pt.x;
913 oldy = pt.y;
915 bDragMode = false;
917 //convert the splitter position back to screen coords.
918 GetWindowRect(hwnd, &rect);
919 pt.x += rect.left;
920 pt.y += rect.top;
922 //now convert into CLIENT coordinates
923 ScreenToClient(hwnd, &pt);
924 GetClientRect(hwnd, &rect);
925 #define MINWINSIZE 10
926 if (bVertical)
928 if (bDrag2)
930 if (pt.y < (nSplitterPos+MINWINSIZE))
931 pt.y = nSplitterPos+MINWINSIZE;
932 nSplitterPos2 = pt.y;
934 else
936 if (pt.y > (nSplitterPos2-MINWINSIZE))
937 pt.y = nSplitterPos2-MINWINSIZE;
938 nSplitterPos = pt.y;
941 else
943 if (bDrag2)
945 if (pt.x < (nSplitterPos+MINWINSIZE))
946 pt.x = nSplitterPos+MINWINSIZE;
947 nSplitterPos2 = pt.x;
949 else
951 if (pt.x > (nSplitterPos2-MINWINSIZE))
952 pt.x = nSplitterPos2-MINWINSIZE;
953 nSplitterPos = pt.x;
957 ReleaseCapture();
959 //position the child controls
960 PositionChildren(&rect);
961 return 0;
964 LRESULT CMainWindow::Splitter_OnMouseMove(HWND hwnd, UINT /*iMsg*/, WPARAM wParam, LPARAM lParam)
966 HDC hdc;
967 RECT rect;
968 RECT clientrect;
970 POINT pt;
972 if (bDragMode == FALSE)
973 return 0;
975 pt.x = (short)LOWORD(lParam); // horizontal position of cursor
976 pt.y = (short)HIWORD(lParam);
978 GetClientRect(hwnd, &clientrect);
979 GetWindowRect(hwnd, &rect);
980 POINT zero = {0,0};
981 ClientToScreen(hwnd, &zero);
982 OffsetRect(&clientrect, zero.x-rect.left, zero.y-rect.top);
984 //convert the mouse coordinates relative to the top-left of
985 //the window
986 ClientToScreen(hwnd, &pt);
987 pt.x -= rect.left;
988 pt.y -= rect.top;
990 //same for the window coordinates - make them relative to 0,0
991 OffsetRect(&rect, -rect.left, -rect.top);
993 if (pt.x < 0)
994 pt.x = 0;
995 if (pt.x > rect.right-4)
996 pt.x = rect.right-4;
997 if (pt.y < 0)
998 pt.y = 0;
999 if (pt.y > rect.bottom-4)
1000 pt.y = rect.bottom-4;
1002 if ((wParam & MK_LBUTTON) && ((bVertical && (pt.y != oldy)) || (!bVertical && (pt.x != oldx))))
1004 hdc = GetWindowDC(hwnd);
1006 if (bVertical)
1008 DrawXorBar(hdc, clientrect.left, oldy+2, clientrect.right-clientrect.left-2, 4);
1009 DrawXorBar(hdc, clientrect.left, pt.y+2, clientrect.right-clientrect.left-2, 4);
1011 else
1013 DrawXorBar(hdc, oldx+2, clientrect.top, 4, clientrect.bottom-clientrect.top-2);
1014 DrawXorBar(hdc, pt.x+2, clientrect.top, 4, clientrect.bottom-clientrect.top-2);
1017 ReleaseDC(hwnd, hdc);
1019 oldx = pt.x;
1020 oldy = pt.y;
1023 return 0;
1026 bool CMainWindow::OpenDialog()
1028 return (DialogBox(hResource, MAKEINTRESOURCE(IDD_OPEN), *this, (DLGPROC)OpenDlgProc)==IDOK);
1031 BOOL CALLBACK CMainWindow::OpenDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/)
1033 switch (message)
1035 case WM_INITDIALOG:
1037 // center on the parent window
1038 HWND hParentWnd = ::GetParent(hwndDlg);
1039 RECT parentrect, childrect, centeredrect;
1040 GetWindowRect(hParentWnd, &parentrect);
1041 GetWindowRect(hwndDlg, &childrect);
1042 centeredrect.left = parentrect.left + ((parentrect.right-parentrect.left-childrect.right+childrect.left)/2);
1043 centeredrect.right = centeredrect.left + (childrect.right-childrect.left);
1044 centeredrect.top = parentrect.top + ((parentrect.bottom-parentrect.top-childrect.bottom+childrect.top)/2);
1045 centeredrect.bottom = centeredrect.top + (childrect.bottom-childrect.top);
1046 SetWindowPos(hwndDlg, NULL, centeredrect.left, centeredrect.top, centeredrect.right-centeredrect.left, centeredrect.bottom-centeredrect.top, SWP_SHOWWINDOW);
1048 if (!leftpicpath.empty())
1049 SetDlgItemText(hwndDlg, IDC_LEFTIMAGE, leftpicpath.c_str());
1050 SetFocus(hwndDlg);
1052 break;
1053 case WM_COMMAND:
1054 switch (LOWORD(wParam))
1056 case IDC_LEFTBROWSE:
1058 TCHAR path[MAX_PATH] = {0};
1059 if (AskForFile(hwndDlg, path))
1061 SetDlgItemText(hwndDlg, IDC_LEFTIMAGE, path);
1064 break;
1065 case IDC_RIGHTBROWSE:
1067 TCHAR path[MAX_PATH] = {0};
1068 if (AskForFile(hwndDlg, path))
1070 SetDlgItemText(hwndDlg, IDC_RIGHTIMAGE, path);
1073 break;
1074 case IDOK:
1076 TCHAR path[MAX_PATH] = {0};
1077 if (!GetDlgItemText(hwndDlg, IDC_LEFTIMAGE, path, _countof(path)))
1078 *path = 0;
1079 leftpicpath = path;
1080 if (!GetDlgItemText(hwndDlg, IDC_RIGHTIMAGE, path, _countof(path)))
1081 *path = 0;
1082 rightpicpath = path;
1084 // Fall through.
1085 case IDCANCEL:
1086 EndDialog(hwndDlg, wParam);
1087 return TRUE;
1090 return FALSE;
1093 bool CMainWindow::AskForFile(HWND owner, TCHAR * path)
1095 OPENFILENAME ofn = {0}; // common dialog box structure
1096 // Initialize OPENFILENAME
1097 ofn.lStructSize = sizeof(OPENFILENAME);
1098 ofn.hwndOwner = owner;
1099 ofn.lpstrFile = path;
1100 ofn.nMaxFile = MAX_PATH;
1101 ResString sTitle(::hResource, IDS_OPENIMAGEFILE);
1102 ofn.lpstrTitle = sTitle;
1103 ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_EXPLORER;
1104 ofn.hInstance = ::hResource;
1105 TCHAR filters[] = _T("Images\0*.wmf;*.jpg;*jpeg;*.bmp;*.gif;*.png;*.ico;*.dib;*.emf\0All (*.*)\0*.*\0\0");
1106 ofn.lpstrFilter = filters;
1107 ofn.nFilterIndex = 1;
1108 // Display the Open dialog box.
1109 if (GetOpenFileName(&ofn)==FALSE)
1111 return false;
1113 return true;
1116 bool CMainWindow::CreateToolbar()
1118 // Ensure that the common control DLL is loaded.
1119 INITCOMMONCONTROLSEX icex;
1120 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
1121 icex.dwICC = ICC_BAR_CLASSES | ICC_WIN95_CLASSES;
1122 InitCommonControlsEx(&icex);
1124 hwndTB = CreateWindowEx(0,
1125 TOOLBARCLASSNAME,
1126 (LPCTSTR)NULL,
1127 WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
1128 0, 0, 0, 0,
1129 *this,
1130 (HMENU)IDC_TORTOISEIDIFF,
1131 hResource,
1132 NULL);
1133 if (hwndTB == INVALID_HANDLE_VALUE)
1134 return false;
1136 SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
1138 TBBUTTON tbb[13];
1139 // create an imagelist containing the icons for the toolbar
1140 hToolbarImgList = ImageList_Create(24, 24, ILC_COLOR32 | ILC_MASK, 12, 4);
1141 if (hToolbarImgList == NULL)
1142 return false;
1143 int index = 0;
1144 HICON hIcon = NULL;
1145 if (selectionPaths.empty())
1147 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_OVERLAP));
1148 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1149 tbb[index].idCommand = ID_VIEW_OVERLAPIMAGES;
1150 tbb[index].fsState = TBSTATE_ENABLED;
1151 tbb[index].fsStyle = BTNS_BUTTON;
1152 tbb[index].dwData = 0;
1153 tbb[index++].iString = 0;
1155 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_BLEND));
1156 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1157 tbb[index].idCommand = ID_VIEW_BLENDALPHA;
1158 tbb[index].fsState = 0;
1159 tbb[index].fsStyle = BTNS_BUTTON;
1160 tbb[index].dwData = 0;
1161 tbb[index++].iString = 0;
1163 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_LINK));
1164 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1165 tbb[index].idCommand = ID_VIEW_LINKIMAGESTOGETHER;
1166 tbb[index].fsState = TBSTATE_ENABLED | TBSTATE_CHECKED;
1167 tbb[index].fsStyle = BTNS_BUTTON;
1168 tbb[index].dwData = 0;
1169 tbb[index++].iString = 0;
1171 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_FITWIDTHS));
1172 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1173 tbb[index].idCommand = ID_VIEW_FITIMAGEWIDTHS;
1174 tbb[index].fsState = TBSTATE_ENABLED;
1175 tbb[index].fsStyle = BTNS_BUTTON;
1176 tbb[index].dwData = 0;
1177 tbb[index++].iString = 0;
1179 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_FITHEIGHTS));
1180 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1181 tbb[index].idCommand = ID_VIEW_FITIMAGEHEIGHTS;
1182 tbb[index].fsState = TBSTATE_ENABLED;
1183 tbb[index].fsStyle = BTNS_BUTTON;
1184 tbb[index].dwData = 0;
1185 tbb[index++].iString = 0;
1187 tbb[index].iBitmap = 0;
1188 tbb[index].idCommand = 0;
1189 tbb[index].fsState = TBSTATE_ENABLED;
1190 tbb[index].fsStyle = BTNS_SEP;
1191 tbb[index].dwData = 0;
1192 tbb[index++].iString = 0;
1194 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_VERTICAL));
1195 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1196 tbb[index].idCommand = ID_VIEW_ARRANGEVERTICAL;
1197 tbb[index].fsState = TBSTATE_ENABLED;
1198 tbb[index].fsStyle = BTNS_BUTTON;
1199 tbb[index].dwData = 0;
1200 tbb[index++].iString = 0;
1202 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_FITINWINDOW));
1203 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1204 tbb[index].idCommand = ID_VIEW_FITIMAGESINWINDOW;
1205 tbb[index].fsState = TBSTATE_ENABLED;
1206 tbb[index].fsStyle = BTNS_BUTTON;
1207 tbb[index].dwData = 0;
1208 tbb[index++].iString = 0;
1210 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_ORIGSIZE));
1211 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1212 tbb[index].idCommand = ID_VIEW_ORININALSIZE;
1213 tbb[index].fsState = TBSTATE_ENABLED;
1214 tbb[index].fsStyle = BTNS_BUTTON;
1215 tbb[index].dwData = 0;
1216 tbb[index++].iString = 0;
1218 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_ZOOMIN));
1219 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1220 tbb[index].idCommand = ID_VIEW_ZOOMIN;
1221 tbb[index].fsState = TBSTATE_ENABLED;
1222 tbb[index].fsStyle = BTNS_BUTTON;
1223 tbb[index].dwData = 0;
1224 tbb[index++].iString = 0;
1226 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_ZOOMOUT));
1227 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1228 tbb[index].idCommand = ID_VIEW_ZOOMOUT;
1229 tbb[index].fsState = TBSTATE_ENABLED;
1230 tbb[index].fsStyle = BTNS_BUTTON;
1231 tbb[index].dwData = 0;
1232 tbb[index++].iString = 0;
1234 tbb[index].iBitmap = 0;
1235 tbb[index].idCommand = 0;
1236 tbb[index].fsState = TBSTATE_ENABLED;
1237 tbb[index].fsStyle = BTNS_SEP;
1238 tbb[index].dwData = 0;
1239 tbb[index++].iString = 0;
1241 hIcon = LoadIcon(hResource, MAKEINTRESOURCE(IDI_IMGINFO));
1242 tbb[index].iBitmap = ImageList_AddIcon(hToolbarImgList, hIcon);
1243 tbb[index].idCommand = ID_VIEW_IMAGEINFO;
1244 tbb[index].fsState = TBSTATE_ENABLED;
1245 tbb[index].fsStyle = BTNS_BUTTON;
1246 tbb[index].dwData = 0;
1247 tbb[index++].iString = 0;
1249 SendMessage(hwndTB, TB_SETIMAGELIST, 0, (LPARAM)hToolbarImgList);
1250 SendMessage(hwndTB, TB_ADDBUTTONS, (WPARAM)index, (LPARAM) (LPTBBUTTON) &tbb);
1251 SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);
1252 ShowWindow(hwndTB, SW_SHOW);
1253 return true;
1256 void CMainWindow::SetSelectionImage( FileType ft, const std::wstring& path, const std::wstring& title )
1258 selectionPaths[ft] = path;
1259 selectionTitles[ft] = title;