OSDN Git Service

Fix bugs of automatic detection for Kanji code of filenames.
[ffftp/ffftp.git] / lvtips.c
1 /*=============================================================================\r
2 *\r
3 *                                                       リストビューティップス\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 /* このソースは MFC Programmer's SourceBook (http://www.codeguru.com/)を参考にしました */\r
31 \r
32 #define  STRICT\r
33 #include <windows.h>\r
34 #include <stdio.h>\r
35 #include <stdlib.h>\r
36 #include <string.h>\r
37 #include <windowsx.h>\r
38 #include <commctrl.h>\r
39 \r
40 #include "common.h"\r
41 #include "resource.h"\r
42 \r
43 \r
44 /*===== プロトタイプ =====*/\r
45 \r
46 static void TipsShow(HWND hWnd, RECT rectTitle, LPCTSTR lpszTitleText, int xoffset, int xoffset2, int InRect);\r
47 static int CellRectFromPoint(HWND hWnd, POINT  point, RECT *cellrect, int *col);\r
48 static LRESULT CALLBACK TitleTipWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
49 \r
50 /*===== ローカルなワーク =====*/\r
51 \r
52 static HWND hWndTips;   /* tipsのウインドウハンドル */\r
53 \r
54 \r
55 \r
56 /*----- リストビューティップスのウインドウを作成 ------------------------------\r
57 *\r
58 *       Parameter\r
59 *               HWND hWnd : 親ウインドウのハンドル\r
60 *               HINSTANCE hInst : インスタンスハンドル\r
61 *\r
62 *       Return Value\r
63 *               int ステータス\r
64 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
65 *----------------------------------------------------------------------------*/\r
66 \r
67 int InitListViewTips(HWND hWnd, HINSTANCE hInst)\r
68 {\r
69         WNDCLASSEX wClass;\r
70         int Ret;\r
71 \r
72         Ret = FFFTP_FAIL;\r
73 \r
74         wClass.cbSize = sizeof(WNDCLASSEX);\r
75         wClass.style         = 0;\r
76         wClass.lpfnWndProc   = TitleTipWndProc;\r
77         wClass.cbClsExtra    = 0;\r
78         wClass.cbWndExtra    = 0;\r
79         wClass.hInstance     = hInst;\r
80         wClass.hIcon         = NULL;\r
81         wClass.hCursor       = NULL;\r
82         wClass.hbrBackground = (HBRUSH)CreateSolidBrush(GetSysColor(COLOR_INFOBK));\r
83         wClass.lpszMenuName  = NULL;\r
84         wClass.lpszClassName = "XTitleTip";\r
85         wClass.hIconSm       = NULL;\r
86         RegisterClassEx(&wClass);\r
87 \r
88         hWndTips = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,\r
89                                 "XTitleTip", NULL,\r
90                                 WS_BORDER | WS_POPUP,\r
91                                 0, 0, 0, 0,\r
92                                 hWnd, NULL, hInst, NULL);\r
93 \r
94         if(hWndTips != NULL)\r
95                 Ret = FFFTP_SUCCESS;\r
96 \r
97         return(Ret);\r
98 }\r
99 \r
100 \r
101 /*----- リストビューティップスのウインドウを削除 ------------------------------\r
102 *\r
103 *       Parameter\r
104 *               なし\r
105 *\r
106 *       Return Value\r
107 *               なし\r
108 *----------------------------------------------------------------------------*/\r
109 \r
110 void DeleteListViewTips(void)\r
111 {\r
112         if(hWndTips != NULL)\r
113                 DestroyWindow(hWndTips);\r
114         return;\r
115 }\r
116 \r
117 \r
118 /*----- リストビューティップスのウインドウを消去 ------------------------------\r
119 *\r
120 *       Parameter\r
121 *               なし\r
122 *\r
123 *       Return Value\r
124 *               なし\r
125 *----------------------------------------------------------------------------*/\r
126 \r
127 void EraseListViewTips(void)\r
128 {\r
129         ReleaseCapture();\r
130     ShowWindow(hWndTips, SW_HIDE);\r
131         return;\r
132 }\r
133 \r
134 \r
135 /*----- リストビューティップスのウインドウハンドルを返す ----------------------\r
136 *\r
137 *       Parameter\r
138 *               なし\r
139 *\r
140 *       Return Value\r
141 *               HWND ウインドウハンドル\r
142 *----------------------------------------------------------------------------*/\r
143 \r
144 HWND GetListViewTipsHwnd(void)\r
145 {\r
146         return(hWndTips);\r
147 }\r
148 \r
149 \r
150 /*----- リストビューティップスの表示チェック ----------------------------------\r
151 *\r
152 *       Parameter\r
153 *               HWND hWnd : ListViewのウインドウハンドル\r
154 *               LPARAM lParam : WM_MOUSEMOVEのLPARAM値\r
155 *\r
156 *       Return Value\r
157 *               なし\r
158 *----------------------------------------------------------------------------*/\r
159 \r
160 void CheckTipsDisplay(HWND hWnd, LPARAM lParam)\r
161 {\r
162         RECT cellrect;\r
163         static RECT cur_rect;\r
164         static int InRect;\r
165         POINT Point;\r
166         int row, col;\r
167         int offset;\r
168         int offset2;\r
169         RECT rcLabel;\r
170         char Buf[256];\r
171 \r
172         Point.x = LOWORD(lParam);\r
173         Point.y = HIWORD(lParam);\r
174         if(InRect == NO)\r
175         {\r
176                 row = CellRectFromPoint(hWnd, Point, &cellrect, &col);\r
177         if(row != -1)\r
178         {\r
179                         cur_rect=cellrect;\r
180                         offset = 6;\r
181                         offset2 = offset;\r
182                         if( col == 0 ) \r
183                         {\r
184                                 ListView_GetItemRect(hWnd,  row, &rcLabel, LVIR_LABEL);\r
185                                 offset = rcLabel.left - cellrect.left + offset / 2;\r
186                                 offset2 = 1;\r
187                         }\r
188                         cellrect.top--;\r
189                         strcpy(Buf, "");\r
190                         ListView_GetItemText(hWnd,  row, col, Buf, 256 );\r
191                         if(strlen(Buf) > 0)\r
192                                 TipsShow(hWnd, cellrect, Buf, offset-1, offset2-1, InRect);\r
193                         InRect = YES;\r
194                 }\r
195         }\r
196         else\r
197         {\r
198                 if(PtInRect(&cur_rect, Point) == FALSE)\r
199                 {\r
200                         EraseListViewTips();\r
201                         InRect = NO;\r
202                 }\r
203         }\r
204         return;\r
205 }\r
206 \r
207 \r
208 /*----- リストビューティップスを表示 ------------------------------------------\r
209 *\r
210 *       Parameter\r
211 *               HWND hWnd : ListViewのウインドウのハンドル\r
212 *               RECT rectTitle : ListViewコントルールのアイテムの矩形\r
213 *               LPCTSTR lpszTitleText : 文字列\r
214 *               int xoffset : オフセット\r
215 *               int xoffset2 : オフセット2\r
216 *               int InRect : 表示するかどうか\r
217 *\r
218 *       Return Value\r
219 *               なし\r
220 *----------------------------------------------------------------------------*/\r
221 \r
222 static void TipsShow(HWND hWnd, RECT rectTitle, LPCTSTR lpszTitleText, int xoffset, int xoffset2, int InRect)\r
223 {\r
224         HDC dc;\r
225         HFONT pFont;\r
226     HFONT pFontDC;\r
227         RECT rectDisplay;\r
228         SIZE size;\r
229 \r
230         if(InRect == NO)\r
231         {\r
232         if(GetFocus() != NULL)\r
233                 {\r
234                         RectClientToScreen(hWnd, &rectTitle);\r
235 \r
236                         /* ListViewウインドウのフォントを得る */\r
237                         dc = GetDC(hWnd);\r
238                         pFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);\r
239                         ReleaseDC(hWnd, dc);\r
240 \r
241                         dc = GetDC(hWndTips);\r
242                         pFontDC = SelectObject(dc, pFont);\r
243 \r
244                         SetTextColor(dc, GetSysColor(COLOR_INFOTEXT));\r
245                         SetBkMode(dc, TRANSPARENT);\r
246 \r
247                         rectDisplay = rectTitle;\r
248                         GetTextExtentPoint32(dc, lpszTitleText, strlen(lpszTitleText), &size);\r
249                         rectDisplay.left += xoffset;\r
250                         rectDisplay.right = rectDisplay.left + size.cx + 2;\r
251 \r
252                         if(rectDisplay.right > rectTitle.right-xoffset2)\r
253                         {\r
254                                 rectDisplay.right += 1;\r
255 \r
256                         SetWindowPos(hWndTips, HWND_TOPMOST, \r
257                                         rectDisplay.left, rectDisplay.top, \r
258                                         rectDisplay.right - rectDisplay.left, \r
259                                         rectDisplay.bottom - rectDisplay.top, \r
260                                         SWP_SHOWWINDOW|SWP_NOACTIVATE );\r
261 \r
262                                 TextOut(dc, 0, 0, lpszTitleText, strlen(lpszTitleText));\r
263 \r
264                         SetCapture(hWnd);\r
265                         }\r
266 \r
267                         SelectObject(dc, pFontDC);\r
268                         ReleaseDC(hWndTips, dc);\r
269                 }\r
270         }\r
271         return;\r
272 }\r
273 \r
274 \r
275 /*----- リストビューティップスを表示する位置を返す ----------------------------\r
276 *\r
277 *       Parameter\r
278 *               HWND hWnd : ListViewのウインドウハンドル\r
279 *               POINT point : カーソルの位置\r
280 *               RECT *cellrect : アイテムの矩形を返すワーク\r
281 *               int *col : 桁番号を返すワーク\r
282 *\r
283 *       Return Value\r
284 *               int 行番号\r
285 *                       -1=該当なし\r
286 *----------------------------------------------------------------------------*/\r
287 \r
288 static int CellRectFromPoint(HWND hWnd, POINT point, RECT *cellrect, int *col)\r
289 {\r
290         int colnum;\r
291         int nColumnCount;\r
292         RECT rect;\r
293         RECT rectClient;\r
294         int row;\r
295         int bottom;\r
296         int colwidth;\r
297         int Ret;\r
298 \r
299         Ret = -1;\r
300         if((GetWindowLong(hWnd, GWL_STYLE) & LVS_TYPEMASK) == LVS_REPORT )\r
301         {\r
302                 row = ListView_GetTopIndex(hWnd);\r
303                 bottom = row + ListView_GetCountPerPage(hWnd);\r
304                 if(bottom > ListView_GetItemCount(hWnd))\r
305                         bottom = ListView_GetItemCount(hWnd);\r
306 \r
307                 nColumnCount = Header_GetItemCount(GetDlgItem(hWnd, 0));\r
308 \r
309                 for(; row <= bottom; row++)\r
310                 {\r
311                         ListView_GetItemRect(hWnd, row, &rect, LVIR_BOUNDS);\r
312                         if(PtInRect(&rect, point))\r
313                         {\r
314                                 for(colnum = 0; colnum < nColumnCount; colnum++)\r
315                                 {\r
316                                         colwidth = ListView_GetColumnWidth(hWnd, colnum);\r
317                                         if((point.x >= rect.left) && \r
318                                            (point.x < (rect.left + colwidth)))\r
319                                         {\r
320                                                 GetClientRect(hWnd, &rectClient);\r
321                                                 if(point.x <= rectClient.right)\r
322                                                 {\r
323                                                         rect.right = rect.left + colwidth;\r
324                                                         if(rect.right > rectClient.right)\r
325                                                                 rect.right = rectClient.right;\r
326                                                         *cellrect = rect;\r
327                                                 *col = colnum;\r
328                                                         Ret = row;\r
329                                                         break;\r
330                                                 }\r
331                                         }\r
332                                         rect.left += colwidth;\r
333                                 }\r
334                                 break;\r
335                         }\r
336                 }\r
337         }\r
338         return(Ret);\r
339 }\r
340 \r
341 \r
342 /*----- リストビューティップスウインドウのコールバック ------------------------\r
343 *\r
344 *       Parameter\r
345 *               HWND hWnd : ウインドウハンドル\r
346 *               UINT message  : メッセージ番号\r
347 *               WPARAM wParam : メッセージの WPARAM 引数\r
348 *               LPARAM lParam : メッセージの LPARAM 引数\r
349 *\r
350 *       Return Value\r
351 *               メッセージに対応する戻り値\r
352 *----------------------------------------------------------------------------*/\r
353 \r
354 static LRESULT CALLBACK TitleTipWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
355 {\r
356         return(DefWindowProc(hWnd, message, wParam, lParam));\r
357 }\r
358 \r
359 \r