OSDN Git Service

Modify documents.
[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 // IPv6対応\r
34 #include <winsock2.h>\r
35 #include <windows.h>\r
36 #include <stdio.h>\r
37 #include <stdlib.h>\r
38 #include <string.h>\r
39 #include <windowsx.h>\r
40 #include <commctrl.h>\r
41 \r
42 #include "common.h"\r
43 #include "resource.h"\r
44 \r
45 \r
46 /*===== プロトタイプ =====*/\r
47 \r
48 static void TipsShow(HWND hWnd, RECT rectTitle, LPCTSTR lpszTitleText, int xoffset, int xoffset2, int InRect);\r
49 static int CellRectFromPoint(HWND hWnd, POINT  point, RECT *cellrect, int *col);\r
50 static LRESULT CALLBACK TitleTipWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
51 \r
52 /*===== ローカルなワーク =====*/\r
53 \r
54 static HWND hWndTips;   /* tipsのウインドウハンドル */\r
55 \r
56 \r
57 \r
58 /*----- リストビューティップスのウインドウを作成 ------------------------------\r
59 *\r
60 *       Parameter\r
61 *               HWND hWnd : 親ウインドウのハンドル\r
62 *               HINSTANCE hInst : インスタンスハンドル\r
63 *\r
64 *       Return Value\r
65 *               int ステータス\r
66 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
67 *----------------------------------------------------------------------------*/\r
68 \r
69 int InitListViewTips(HWND hWnd, HINSTANCE hInst)\r
70 {\r
71         WNDCLASSEX wClass;\r
72         int Ret;\r
73 \r
74         Ret = FFFTP_FAIL;\r
75 \r
76         wClass.cbSize = sizeof(WNDCLASSEX);\r
77         wClass.style         = 0;\r
78         wClass.lpfnWndProc   = TitleTipWndProc;\r
79         wClass.cbClsExtra    = 0;\r
80         wClass.cbWndExtra    = 0;\r
81         wClass.hInstance     = hInst;\r
82         wClass.hIcon         = NULL;\r
83         wClass.hCursor       = NULL;\r
84         wClass.hbrBackground = (HBRUSH)CreateSolidBrush(GetSysColor(COLOR_INFOBK));\r
85         wClass.lpszMenuName  = NULL;\r
86         wClass.lpszClassName = "XTitleTip";\r
87         wClass.hIconSm       = NULL;\r
88         RegisterClassEx(&wClass);\r
89 \r
90         hWndTips = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,\r
91                                 "XTitleTip", NULL,\r
92                                 WS_BORDER | WS_POPUP,\r
93                                 0, 0, 0, 0,\r
94                                 hWnd, NULL, hInst, NULL);\r
95 \r
96         if(hWndTips != NULL)\r
97                 Ret = FFFTP_SUCCESS;\r
98 \r
99         return(Ret);\r
100 }\r
101 \r
102 \r
103 /*----- リストビューティップスのウインドウを削除 ------------------------------\r
104 *\r
105 *       Parameter\r
106 *               なし\r
107 *\r
108 *       Return Value\r
109 *               なし\r
110 *----------------------------------------------------------------------------*/\r
111 \r
112 void DeleteListViewTips(void)\r
113 {\r
114         if(hWndTips != NULL)\r
115                 DestroyWindow(hWndTips);\r
116         return;\r
117 }\r
118 \r
119 \r
120 /*----- リストビューティップスのウインドウを消去 ------------------------------\r
121 *\r
122 *       Parameter\r
123 *               なし\r
124 *\r
125 *       Return Value\r
126 *               なし\r
127 *----------------------------------------------------------------------------*/\r
128 \r
129 void EraseListViewTips(void)\r
130 {\r
131         ReleaseCapture();\r
132     ShowWindow(hWndTips, SW_HIDE);\r
133         return;\r
134 }\r
135 \r
136 \r
137 /*----- リストビューティップスのウインドウハンドルを返す ----------------------\r
138 *\r
139 *       Parameter\r
140 *               なし\r
141 *\r
142 *       Return Value\r
143 *               HWND ウインドウハンドル\r
144 *----------------------------------------------------------------------------*/\r
145 \r
146 HWND GetListViewTipsHwnd(void)\r
147 {\r
148         return(hWndTips);\r
149 }\r
150 \r
151 \r
152 /*----- リストビューティップスの表示チェック ----------------------------------\r
153 *\r
154 *       Parameter\r
155 *               HWND hWnd : ListViewのウインドウハンドル\r
156 *               LPARAM lParam : WM_MOUSEMOVEのLPARAM値\r
157 *\r
158 *       Return Value\r
159 *               なし\r
160 *----------------------------------------------------------------------------*/\r
161 \r
162 void CheckTipsDisplay(HWND hWnd, LPARAM lParam)\r
163 {\r
164         RECT cellrect;\r
165         static RECT cur_rect;\r
166         static int InRect;\r
167         POINT Point;\r
168         int row, col;\r
169         int offset;\r
170         int offset2;\r
171         RECT rcLabel;\r
172         char Buf[256];\r
173 \r
174         Point.x = LOWORD(lParam);\r
175         Point.y = HIWORD(lParam);\r
176         if(InRect == NO)\r
177         {\r
178                 row = CellRectFromPoint(hWnd, Point, &cellrect, &col);\r
179         if(row != -1)\r
180         {\r
181                         cur_rect=cellrect;\r
182                         offset = 6;\r
183                         offset2 = offset;\r
184                         if( col == 0 ) \r
185                         {\r
186                                 ListView_GetItemRect(hWnd,  row, &rcLabel, LVIR_LABEL);\r
187                                 offset = rcLabel.left - cellrect.left + offset / 2;\r
188                                 offset2 = 1;\r
189                         }\r
190                         cellrect.top--;\r
191                         strcpy(Buf, "");\r
192                         ListView_GetItemText(hWnd,  row, col, Buf, 256 );\r
193                         if(strlen(Buf) > 0)\r
194                                 TipsShow(hWnd, cellrect, Buf, offset-1, offset2-1, InRect);\r
195                         InRect = YES;\r
196                 }\r
197         }\r
198         else\r
199         {\r
200                 if(PtInRect(&cur_rect, Point) == FALSE)\r
201                 {\r
202                         EraseListViewTips();\r
203                         InRect = NO;\r
204                 }\r
205         }\r
206         return;\r
207 }\r
208 \r
209 \r
210 /*----- リストビューティップスを表示 ------------------------------------------\r
211 *\r
212 *       Parameter\r
213 *               HWND hWnd : ListViewのウインドウのハンドル\r
214 *               RECT rectTitle : ListViewコントルールのアイテムの矩形\r
215 *               LPCTSTR lpszTitleText : 文字列\r
216 *               int xoffset : オフセット\r
217 *               int xoffset2 : オフセット2\r
218 *               int InRect : 表示するかどうか\r
219 *\r
220 *       Return Value\r
221 *               なし\r
222 *----------------------------------------------------------------------------*/\r
223 \r
224 static void TipsShow(HWND hWnd, RECT rectTitle, LPCTSTR lpszTitleText, int xoffset, int xoffset2, int InRect)\r
225 {\r
226         HDC dc;\r
227         HFONT pFont;\r
228     HFONT pFontDC;\r
229         RECT rectDisplay;\r
230         SIZE size;\r
231 \r
232         if(InRect == NO)\r
233         {\r
234         if(GetFocus() != NULL)\r
235                 {\r
236                         RectClientToScreen(hWnd, &rectTitle);\r
237 \r
238                         /* ListViewウインドウのフォントを得る */\r
239                         dc = GetDC(hWnd);\r
240                         pFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);\r
241                         ReleaseDC(hWnd, dc);\r
242 \r
243                         dc = GetDC(hWndTips);\r
244                         pFontDC = SelectObject(dc, pFont);\r
245 \r
246                         SetTextColor(dc, GetSysColor(COLOR_INFOTEXT));\r
247                         SetBkMode(dc, TRANSPARENT);\r
248 \r
249                         rectDisplay = rectTitle;\r
250                         GetTextExtentPoint32(dc, lpszTitleText, strlen(lpszTitleText), &size);\r
251                         rectDisplay.left += xoffset;\r
252                         rectDisplay.right = rectDisplay.left + size.cx + 2;\r
253 \r
254                         if(rectDisplay.right > rectTitle.right-xoffset2)\r
255                         {\r
256                                 rectDisplay.right += 1;\r
257 \r
258                         SetWindowPos(hWndTips, HWND_TOPMOST, \r
259                                         rectDisplay.left, rectDisplay.top, \r
260                                         rectDisplay.right - rectDisplay.left, \r
261                                         rectDisplay.bottom - rectDisplay.top, \r
262                                         SWP_SHOWWINDOW|SWP_NOACTIVATE );\r
263 \r
264                                 TextOut(dc, 0, 0, lpszTitleText, strlen(lpszTitleText));\r
265 \r
266                         SetCapture(hWnd);\r
267                         }\r
268 \r
269                         SelectObject(dc, pFontDC);\r
270                         ReleaseDC(hWndTips, dc);\r
271                 }\r
272         }\r
273         return;\r
274 }\r
275 \r
276 \r
277 /*----- リストビューティップスを表示する位置を返す ----------------------------\r
278 *\r
279 *       Parameter\r
280 *               HWND hWnd : ListViewのウインドウハンドル\r
281 *               POINT point : カーソルの位置\r
282 *               RECT *cellrect : アイテムの矩形を返すワーク\r
283 *               int *col : 桁番号を返すワーク\r
284 *\r
285 *       Return Value\r
286 *               int 行番号\r
287 *                       -1=該当なし\r
288 *----------------------------------------------------------------------------*/\r
289 \r
290 static int CellRectFromPoint(HWND hWnd, POINT point, RECT *cellrect, int *col)\r
291 {\r
292         int colnum;\r
293         int nColumnCount;\r
294         RECT rect;\r
295         RECT rectClient;\r
296         int row;\r
297         int bottom;\r
298         int colwidth;\r
299         int Ret;\r
300 \r
301         Ret = -1;\r
302         // 64ビット対応\r
303 //      if((GetWindowLong(hWnd, GWL_STYLE) & LVS_TYPEMASK) == LVS_REPORT )\r
304         if((GetWindowLongPtr(hWnd, GWL_STYLE) & LVS_TYPEMASK) == LVS_REPORT )\r
305         {\r
306                 row = ListView_GetTopIndex(hWnd);\r
307                 bottom = row + ListView_GetCountPerPage(hWnd);\r
308                 if(bottom > ListView_GetItemCount(hWnd))\r
309                         bottom = ListView_GetItemCount(hWnd);\r
310 \r
311                 nColumnCount = Header_GetItemCount(GetDlgItem(hWnd, 0));\r
312 \r
313                 for(; row <= bottom; row++)\r
314                 {\r
315                         ListView_GetItemRect(hWnd, row, &rect, LVIR_BOUNDS);\r
316                         if(PtInRect(&rect, point))\r
317                         {\r
318                                 for(colnum = 0; colnum < nColumnCount; colnum++)\r
319                                 {\r
320                                         colwidth = ListView_GetColumnWidth(hWnd, colnum);\r
321                                         if((point.x >= rect.left) && \r
322                                            (point.x < (rect.left + colwidth)))\r
323                                         {\r
324                                                 GetClientRect(hWnd, &rectClient);\r
325                                                 if(point.x <= rectClient.right)\r
326                                                 {\r
327                                                         rect.right = rect.left + colwidth;\r
328                                                         if(rect.right > rectClient.right)\r
329                                                                 rect.right = rectClient.right;\r
330                                                         *cellrect = rect;\r
331                                                 *col = colnum;\r
332                                                         Ret = row;\r
333                                                         break;\r
334                                                 }\r
335                                         }\r
336                                         rect.left += colwidth;\r
337                                 }\r
338                                 break;\r
339                         }\r
340                 }\r
341         }\r
342         return(Ret);\r
343 }\r
344 \r
345 \r
346 /*----- リストビューティップスウインドウのコールバック ------------------------\r
347 *\r
348 *       Parameter\r
349 *               HWND hWnd : ウインドウハンドル\r
350 *               UINT message  : メッセージ番号\r
351 *               WPARAM wParam : メッセージの WPARAM 引数\r
352 *               LPARAM lParam : メッセージの LPARAM 引数\r
353 *\r
354 *       Return Value\r
355 *               メッセージに対応する戻り値\r
356 *----------------------------------------------------------------------------*/\r
357 \r
358 static LRESULT CALLBACK TitleTipWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
359 {\r
360         return(DefWindowProc(hWnd, message, wParam, lParam));\r
361 }\r
362 \r
363 \r