OSDN Git Service

merge original branch.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseIDiff / NiceTrackbar.cpp
1 // TortoiseIDiff - an image diff viewer in TortoiseSVN\r
2 \r
3 // Copyright (C) 2006 - 2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "StdAfx.h"\r
20 #include "NiceTrackbar.h"\r
21 #include <tchar.h>\r
22 #include <CommCtrl.h>\r
23 #include <WindowsX.h>\r
24 \r
25 \r
26 LRESULT CALLBACK CNiceTrackbar::NiceTrackbarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
27 {\r
28         CNiceTrackbar* self = (CNiceTrackbar*)GetWindowLongPtr(hwnd, GWLP_USERDATA);\r
29 \r
30         switch (message) {\r
31         case WM_LBUTTONDOWN:\r
32                 self->m_Dragging = true;\r
33                 self->m_DragChanged = false;\r
34                 SetCapture(hwnd);\r
35                 //SetFocus(hwnd);\r
36                 if (self->SetThumb(lParam)) {\r
37                         self->m_DragChanged = true;\r
38                         self->PostMessageToParent(TB_THUMBTRACK);\r
39                 }\r
40                 return 0;\r
41         case WM_MOUSEMOVE:\r
42                 if (self->m_Dragging)\r
43                 {\r
44                         if (self->SetThumb(lParam))\r
45                         {\r
46                                 self->m_DragChanged = true;\r
47                                 self->PostMessageToParent(TB_THUMBTRACK);\r
48                         }\r
49                         return 0;\r
50                 }\r
51                 break;\r
52         case WM_LBUTTONUP:\r
53                 if (self->m_Dragging)\r
54                 {\r
55                         self->m_Dragging = false;\r
56                         ReleaseCapture();\r
57                         if (self->SetThumb(lParam))\r
58                         {\r
59                                 self->PostMessageToParent(TB_ENDTRACK);\r
60                                 self->m_DragChanged = true;\r
61                         }\r
62                         if (self->m_DragChanged)\r
63                         {\r
64                                 self->PostMessageToParent(TB_THUMBPOSITION);\r
65                                 self->m_DragChanged = false;\r
66                         }\r
67                         return 0;\r
68                 }\r
69                 break;\r
70         case WM_DESTROY:\r
71                 SetWindowLongPtr (hwnd, GWLP_WNDPROC, (LONG_PTR)self->m_OrigProc);\r
72                 break;\r
73         }\r
74         return CallWindowProc (self->m_OrigProc, hwnd, message, wParam, lParam);\r
75 }\r
76 \r
77 \r
78 void CNiceTrackbar::ConvertTrackbarToNice( HWND window )\r
79 {\r
80         m_Window = window;\r
81 \r
82         // setup this pointer\r
83         SetWindowLongPtr( window, GWLP_USERDATA, (LONG_PTR)this );\r
84 \r
85         // subclass it\r
86         m_OrigProc = (WNDPROC)SetWindowLongPtr( window, GWLP_WNDPROC, (LONG_PTR)NiceTrackbarProc );\r
87 }\r
88 \r
89 \r
90 bool CNiceTrackbar::SetThumb (LPARAM lparamPoint)\r
91 {\r
92         POINT point = { GET_X_LPARAM(lparamPoint), GET_Y_LPARAM(lparamPoint) };\r
93         const int nMin = (int)SendMessage(m_Window, TBM_GETRANGEMIN, 0, 0l);\r
94         const int nMax = (int)SendMessage(m_Window, TBM_GETRANGEMAX, 0, 0l);\r
95         RECT rc;\r
96         SendMessage(m_Window, TBM_GETCHANNELRECT, 0, (LPARAM)&rc);\r
97         double ratio;\r
98         if (GetWindowLong(m_Window, GWL_STYLE) & TBS_VERT)\r
99         {\r
100                 // note: for vertical trackbar, it still returns the rectangle as if it was horizontal\r
101                 ratio = (double)(point.y - rc.left)/(rc.right - rc.left);\r
102         }\r
103         else\r
104         {\r
105                 ratio = (double)(point.x - rc.left)/(rc.right - rc.left);\r
106         }\r
107 \r
108         int nNewPos = (int)(nMin + (nMax-nMin)*ratio + 0.5); // round the result to go to the nearest tick mark\r
109 \r
110         const bool changed = (nNewPos != (int)SendMessage(m_Window, TBM_GETPOS, 0, 0));\r
111         if (changed)\r
112         {\r
113                 SendMessage(m_Window, TBM_SETPOS, TRUE, nNewPos);\r
114         }\r
115         return changed;\r
116 }\r
117 \r
118 \r
119 void CNiceTrackbar::PostMessageToParent (int tbCode) const\r
120 {\r
121         HWND parent = GetParent(m_Window);\r
122         if (parent) {\r
123                 int pos = (int)SendMessage(m_Window, TBM_GETPOS, 0, 0);\r
124                 bool vert = (GetWindowLong(m_Window, GWL_STYLE) & TBS_VERT) != 0;\r
125                 PostMessage( parent, vert ? WM_VSCROLL : WM_HSCROLL, (WPARAM)((pos << 16) | tbCode), (LPARAM)m_Window );\r
126         }\r
127 }\r