Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/setupdirdlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10696 - (show annotations) (download) (as text)
Tue May 2 14:00:28 2023 UTC (10 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 18340 byte(s)
初期化子を省略しないようにした

- 省略すると0で埋められるが、コンパイラ(gcc)によっては警告が出るのでNULLで埋めた
- setupdirdlg.cpp:520:17: 警告: missing initializer for member ‘SetupList::data_ptr’ [-Wmissing-field-initializers]
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2004- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "teraterm.h"
31 #include "tttypes.h"
32 #include "tttypes_key.h"
33
34 #include "ttcommon.h"
35 #include "ttdialog.h"
36 #include "commlib.h"
37 #include "ttlib.h"
38 #include "dlglib.h"
39
40 #include <stdio.h>
41 #define _CRTDBG_MAP_ALLOC
42 #include <stdlib.h>
43 #include <crtdbg.h>
44 #include <string.h>
45 #include <assert.h>
46
47 #include <shlobj.h>
48 #include <windows.h>
49 #include <wchar.h>
50 #include <htmlhelp.h>
51
52 #include "tt_res.h"
53 #include "vtwin.h"
54 #include "compat_win.h"
55 #include "codeconv.h"
56 #include "asprintf.h"
57 #include "helpid.h"
58 #include "win32helper.h"
59 #include "tipwin2.h"
60 #include "scp.h"
61
62 #include "setupdirdlg.h"
63
64 // Virtual Store���L���������������������������B
65 //
66 // [Windows 95-XP]
67 // return FALSE (always)
68 //
69 // [Windows Vista-10]
70 // return TRUE: Virtual Store Enabled
71 // FALSE: Virtual Store Disabled or Unknown
72 //
73 static BOOL GetVirtualStoreEnvironment(void)
74 {
75 #if _MSC_VER == 1400 // VSC2005(VC8.0)
76 typedef struct _TOKEN_ELEVATION {
77 DWORD TokenIsElevated;
78 } TOKEN_ELEVATION, *PTOKEN_ELEVATION;
79 int TokenElevation = 20;
80 #endif
81 BOOL ret = FALSE;
82 int flag = 0;
83 HANDLE hToken;
84 DWORD dwLength;
85 TOKEN_ELEVATION tokenElevation;
86 LONG lRet;
87 HKEY hKey;
88 char lpData[256];
89 DWORD dwDataSize;
90 DWORD dwType;
91 BYTE bValue;
92
93 // Windows Vista���O�����������B
94 if (!IsWindowsVistaOrLater())
95 goto error;
96
97 // UAC���L�����������B
98 // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System��EnableLUA(DWORD�l)��0�������������f��������(0��UAC�����A1��UAC�L��)�B
99 flag = 0;
100 lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
101 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
102 0, KEY_QUERY_VALUE, &hKey);
103 if (lRet == ERROR_SUCCESS) {
104 dwDataSize = sizeof(lpData) / sizeof(lpData[0]);
105 lRet = RegQueryValueExA(
106 hKey,
107 "EnableLUA",
108 0,
109 &dwType,
110 (LPBYTE)lpData,
111 &dwDataSize);
112 if (lRet == ERROR_SUCCESS) {
113 bValue = ((LPBYTE)lpData)[0];
114 if (bValue == 1)
115 // UAC���L���������AVirtual Store�������B
116 flag = 1;
117 }
118 RegCloseKey(hKey);
119 }
120 if (flag == 0)
121 goto error;
122
123 // UAC���L�����A�v���Z�X�����������������i�����������B
124 flag = 0;
125 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &hToken)) {
126 if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)TokenElevation, &tokenElevation, sizeof(TOKEN_ELEVATION), &dwLength)) {
127 // (0�����i�����������A��0�����i��������)�B
128 if (tokenElevation.TokenIsElevated == 0) {
129 // �����������������������������AVirtual Store�������B
130 flag = 1;
131 }
132 }
133 CloseHandle(hToken);
134 }
135 if (flag == 0)
136 goto error;
137
138 ret = TRUE;
139 return (ret);
140
141 error:
142 return (ret);
143 }
144
145 //
146 // �w�������A�v���P�[�V�������t�@�C�����J���B
147 //
148 // return TRUE: success
149 // FALSE: failure
150 //
151 static BOOL openFileWithApplication(const wchar_t *filename, const char *editor, const wchar_t *UILanguageFile)
152 {
153 wchar_t *commandW = NULL;
154 BOOL ret = FALSE;
155
156 if (GetFileAttributesW(filename) == INVALID_FILE_ATTRIBUTES) {
157 // �t�@�C��������������
158 DWORD no = GetLastError();
159 static const TTMessageBoxInfoW info = {
160 "Tera Term",
161 "MSG_ERROR", L"ERROR",
162 "DLG_SETUPDIR_NOFILE_ERROR", L"File does not exist.(%d)",
163 MB_OK | MB_ICONWARNING
164 };
165 TTMessageBoxW(NULL, &info, UILanguageFile, no);
166
167 goto error;
168 }
169
170 aswprintf(&commandW, L"%hs \"%s\"", editor, filename);
171
172 STARTUPINFOW si;
173 PROCESS_INFORMATION pi;
174 memset(&si, 0, sizeof(si));
175 GetStartupInfoW(&si);
176 memset(&pi, 0, sizeof(pi));
177
178 if (CreateProcessW(NULL, commandW, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0) {
179 // �N�����s
180 DWORD no = GetLastError();
181 static const TTMessageBoxInfoW info = {
182 "Tera Term",
183 "MSG_ERROR", L"ERROR",
184 "DLG_SETUPDIR_OPENFILE_ERROR", L"Cannot open file.(%d)",
185 MB_OK | MB_ICONWARNING
186 };
187 TTMessageBoxW(NULL, &info, UILanguageFile, no);
188
189 goto error;
190 }
191 else {
192 CloseHandle(pi.hThread);
193 CloseHandle(pi.hProcess);
194 }
195
196 ret = TRUE;
197
198 error:;
199 free(commandW);
200
201 return (ret);
202 }
203
204 /**
205 * �G�N�X�v���[�����w���t�@�C�����t�H���_���J��
206 * �t�@�C�������������������t�@�C�����I�������������J��
207 * �t�@�C���������������������t�H���_���J��
208 *
209 * @param file �t�@�C��
210 * @retval TRUE: success
211 * @retval FALSE: failure
212 */
213 static BOOL openDirectoryWithExplorer(const wchar_t *file, const wchar_t *UILanguageFile)
214 {
215 BOOL ret;
216
217 DWORD attr = GetFileAttributesW(file);
218 if (attr == INVALID_FILE_ATTRIBUTES) {
219 // �t�@�C��������������, �f�B���N�g�����I�[�v������
220 wchar_t *dir = ExtractDirNameW(file);
221 attr = GetFileAttributesW(dir);
222 if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
223 // �t�H���_���J��
224 INT_PTR h = (INT_PTR)ShellExecuteW(NULL, L"open", L"explorer.exe", dir, NULL, SW_NORMAL);
225 ret = h > 32 ? TRUE : FALSE;
226 }
227 else {
228 // �t�@�C�����t�H���_������������
229 DWORD no = GetLastError();
230 static const TTMessageBoxInfoW info = {
231 "Tera Term",
232 "MSG_ERROR", L"ERROR",
233 "DLG_SETUPDIR_NOFILE_ERROR", L"File does not exist.(%d)",
234 MB_OK | MB_ICONWARNING
235 };
236 TTMessageBoxW(NULL, &info, UILanguageFile, no);
237 ret = FALSE;
238 }
239 free(dir);
240 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
241 // �w�������������t�H���_�������A�t�H���_���J��
242 INT_PTR h = (INT_PTR)ShellExecuteW(NULL, L"open", L"explorer.exe", file, NULL, SW_NORMAL);
243 ret = h > 32 ? TRUE : FALSE;
244 } else {
245 // �t�H���_���J�� + �t�@�C���I��
246 wchar_t *param;
247 aswprintf(&param, L"/select,%s", file);
248 INT_PTR h = (INT_PTR)ShellExecuteW(NULL, L"open", L"explorer.exe", param, NULL, SW_NORMAL);
249 free(param);
250 ret = h > 32 ? TRUE : FALSE;
251 }
252 return ret;
253 }
254
255 /**
256 * �t���p�X�t�@�C������ Virtual Store�p�X�����������B
257 * @param[in] filename �����O���t�@�C����
258 * @param[out] vstore_filename Virtual Store���t�@�C����
259 * @retval TRUE ��������
260 * FALSE ��������������(Virtual Store������������������)
261 */
262 static BOOL convertVirtualStoreW(const wchar_t *filename, wchar_t **vstore_filename)
263 {
264 wchar_t *path = ExtractDirNameW(filename);
265 wchar_t *file = ExtractFileNameW(filename);
266
267 // �s�v���h���C�u���^�[�����������B
268 // �h���C�u���^�[���������������������_�������B(1��������?)
269 wchar_t *path_nodrive = wcsstr(path, L":\\");
270 if (path_nodrive == NULL) {
271 // �t���p�X��������, VS���l������������ok
272 free(path);
273 free(file);
274 return FALSE;
275 }
276 path_nodrive++;
277
278 BOOL ret = FALSE;
279 static const wchar_t* virstore_env[] = {
280 L"ProgramFiles",
281 L"ProgramData",
282 L"SystemRoot",
283 NULL
284 };
285 const wchar_t** p = virstore_env;
286
287 if (GetVirtualStoreEnvironment() == FALSE)
288 goto error;
289
290 // Virtual Store�����������t�H���_���B
291 while (*p) {
292 const wchar_t *s = _wgetenv(*p);
293 if (s != NULL && wcsstr(path, s) != NULL) {
294 break;
295 }
296 p++;
297 }
298 if (*p == NULL)
299 goto error;
300
301
302 // Virtual Store�p�X�������B
303 wchar_t *local_appdata;
304 _SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &local_appdata);
305 wchar_t *vs_file;
306 aswprintf(&vs_file, L"%s\\VirtualStore%s\\%s", local_appdata, path_nodrive, file);
307 free(local_appdata);
308
309 // �������AVirtual Store���t�@�C�������������������������B
310 if (GetFileAttributesW(vs_file) == INVALID_FILE_ATTRIBUTES) {
311 free(vs_file);
312 goto error;
313 }
314
315 *vstore_filename = vs_file;
316
317 ret = TRUE;
318 goto epilogue;
319
320 error:
321 *vstore_filename = NULL;
322 ret = FALSE;
323 epilogue:
324 free(path);
325 free(file);
326 return ret;
327 }
328
329 /**
330 * ���X�g���`�p�\����
331 */
332 typedef enum {
333 LIST_PARAM_STR = 1, // ������
334 LIST_PARAM_FUNC = 2, // ����
335 } SetupListParam;
336 typedef struct {
337 const char *key; // �e�L�X�g���L�[
338 const wchar_t *def_text; // �f�t�H���g�e�L�X�g
339 SetupListParam param; // param_ptr �����e������
340 void *param_ptr; // param�������l
341 void *data_ptr; // ���������g�p�����f�[�^
342 } SetupList;
343
344 /**
345 * ���j���[���o�����I�����������������s����
346 */
347 static void PopupAndExec(HWND hWnd, const POINT *pointer_pos, const wchar_t *path, const TTTSet *pts)
348 {
349 const wchar_t *UILanguageFile = pts->UILanguageFileW;
350 const DWORD file_stat = GetFileAttributesW(path);
351 const BOOL dir = (file_stat & FILE_ATTRIBUTE_DIRECTORY) != 0 ? TRUE : FALSE;
352
353 HMENU hMenu= CreatePopupMenu();
354 AppendMenuW(hMenu, (dir ? MF_DISABLED : MF_ENABLED) | MF_STRING | 0, 1, L"&Open file");
355 AppendMenuW(hMenu, MF_ENABLED | MF_STRING | 0, 2, L"Open folder(with explorer)");
356 AppendMenuW(hMenu, MF_ENABLED | MF_STRING | 0, 3, L"Send path to clipboard");
357 int result = TrackPopupMenu(hMenu, TPM_RETURNCMD, pointer_pos->x, pointer_pos->y, 0 , hWnd, NULL);
358 DestroyMenu(hMenu);
359 switch (result) {
360 case 1: {
361 // �A�v�����J��
362 const char *editor = pts->ViewlogEditor;
363 openFileWithApplication(path, editor, UILanguageFile);
364 break;
365 }
366 case 2: {
367 // �t�H���_���J�����A�t�@�C�����I������
368 openDirectoryWithExplorer(path, UILanguageFile);
369 break;
370 }
371 case 3: {
372 // �N���b�v�{�[�h�����������M
373 CBSetTextW(hWnd, path, 0);
374 break;
375 }
376 default:
377 break;
378 }
379 }
380
381 static wchar_t *GetCygtermIni(const SetupList *list, const TTTSet *pts)
382 {
383 wchar_t *cygterm_ini;
384 aswprintf(&cygterm_ini, L"%s\\cygterm.cfg", pts->HomeDirW);
385 if (list->data_ptr != 0) {
386 wchar_t *virtual_store_path;
387 BOOL ret = convertVirtualStoreW(cygterm_ini, &virtual_store_path);
388 free(cygterm_ini);
389 if (ret) {
390 return virtual_store_path;
391 } else {
392 return NULL;
393 }
394 }
395 return cygterm_ini;
396 }
397
398 static wchar_t *GetTTXSSHKwnownHostFile(const SetupList *list, const TTTSet *)
399 {
400 wchar_t *filename;
401 BOOL r = TTXSSHGetKnownHostsFileName(&filename);
402 if (!r) {
403 return NULL;
404 }
405 assert(!IsRelativePathW(filename));
406
407 if (list->data_ptr != 0) {
408 wchar_t *virtual_store_path;
409 BOOL ret = convertVirtualStoreW(filename, &virtual_store_path);
410 free(filename);
411 if (ret) {
412 return virtual_store_path;
413 } else {
414 return NULL;
415 }
416 }
417
418 return filename;
419 }
420
421 /**
422 * Virtaul Store�����p�X������
423 */
424 static wchar_t *GetVirtualStorePath(const SetupList *list, const TTTSet *)
425 {
426 const wchar_t *path = (wchar_t *)list->data_ptr;
427 wchar_t *virtual_store_path;
428 BOOL ret = convertVirtualStoreW(path, &virtual_store_path);
429 if (ret) {
430 return virtual_store_path;
431 } else {
432 // virtual store���g�p������������
433 return NULL;
434 }
435 }
436
437 /**
438 * current
439 */
440 static wchar_t *GetCurrentPath(const SetupList *, const TTTSet *)
441 {
442 wchar_t *path;
443 hGetCurrentDirectoryW(&path);
444 return path;
445 }
446
447 typedef struct {
448 TComVar *pcv;
449 TipWin2 *tipwin;
450 } dlg_data_t;
451
452 static INT_PTR CALLBACK OnSetupDirectoryDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
453 {
454 static const DlgTextInfo TextInfos[] = {
455 { 0, "DLG_SETUPDIR_TITLE" },
456 };
457 dlg_data_t *dlg_data = (dlg_data_t *)GetWindowLongPtr(hDlgWnd, DWLP_USER);
458 TComVar *pcv = (dlg_data == NULL) ? NULL : dlg_data->pcv;
459 TTTSet *pts = (pcv == NULL) ? NULL : pcv->ts;
460
461 switch (msg) {
462 case WM_INITDIALOG: {
463 dlg_data = (dlg_data_t *)lp;
464 pcv = dlg_data->pcv;
465 pts = pcv->ts;
466 SetWindowLongPtr(hDlgWnd, DWLP_USER, (LONG_PTR)dlg_data);
467
468 // I18N
469 SetDlgTextsW(hDlgWnd, TextInfos, _countof(TextInfos), pts->UILanguageFileW);
470
471 HWND hWndList = GetDlgItem(hDlgWnd, IDC_SETUP_DIR_LIST);
472 ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
473
474 LV_COLUMNA lvcol;
475 lvcol.mask = LVCF_TEXT | LVCF_SUBITEM;
476 lvcol.pszText = (LPSTR)"name";
477 lvcol.iSubItem = 0;
478 //ListView_InsertColumn(hWndList, 0, &lvcol);
479 SendMessage(hWndList, LVM_INSERTCOLUMNA, 0, (LPARAM)&lvcol);
480
481 lvcol.pszText = (LPSTR)"path/file";
482 lvcol.iSubItem = 1;
483 //ListView_InsertColumn(hWndList, 1, &lvcol);
484 SendMessage(hWndList, LVM_INSERTCOLUMNA, 1, (LPARAM)&lvcol);
485
486 // ��������
487 const SetupList setup_list[] = {
488 { "DLG_SETUPDIR_INIFILE", L"Tera Term Configuration File",
489 LIST_PARAM_STR, pts->SetupFNameW, NULL },
490 { NULL, L" Virtual Store",
491 LIST_PARAM_FUNC, (void *)GetVirtualStorePath, pts->SetupFNameW },
492 { "DLG_SETUPDIR_KEYBOARDFILE", L"Keyboard Configuration File",
493 LIST_PARAM_STR, pts->KeyCnfFNW, NULL },
494 { NULL, L" Virtual Store",
495 LIST_PARAM_FUNC, (void*)GetVirtualStorePath, pts->KeyCnfFNW },
496 { "DLG_SETUPDIR_CYGTERMFILE", L"CygTerm Configuration File",
497 LIST_PARAM_FUNC, (void*)GetCygtermIni, (void *)0 },
498 { NULL, L" Virtual Store",
499 LIST_PARAM_FUNC, (void*)GetCygtermIni, (void *)1 },
500 { "DLG_SETUPDIR_KNOWNHOSTSFILE", L"SSH known_hosts File",
501 LIST_PARAM_FUNC, (void*)GetTTXSSHKwnownHostFile, (void *)0 },
502 { NULL, L" Virtual Store",
503 LIST_PARAM_FUNC, (void*)GetTTXSSHKwnownHostFile, (void *)1 },
504 { NULL, L"CurrentDirectry",
505 LIST_PARAM_FUNC, (void*)GetCurrentPath, NULL },
506 { NULL, L"HomeDir",
507 LIST_PARAM_STR, pts->HomeDirW, NULL },
508 { NULL, L"ExeDir",
509 LIST_PARAM_STR, pts->ExeDirW, NULL },
510 { NULL, L"LogDir",
511 LIST_PARAM_STR, pts->LogDirW, NULL },
512 { NULL, L"LogDefaultPathW",
513 LIST_PARAM_STR, pts->LogDefaultPathW, NULL },
514 { NULL, L"Download",
515 LIST_PARAM_STR, pts->FileDirW, NULL },
516 { NULL, L"Susie Plugin Path",
517 LIST_PARAM_STR, pts->EtermLookfeel.BGSPIPathW, NULL },
518 { NULL, L"UI language file",
519 LIST_PARAM_STR, pts->UILanguageFileW, NULL },
520 };
521
522 int y = 0;
523 for (const SetupList *list = &setup_list[0]; list != &setup_list[_countof(setup_list)]; list++) {
524
525 const SetupListParam param = list->param;
526 wchar_t *s;
527 if (param & LIST_PARAM_STR) {
528 // �����������|�C���^
529 s = (wchar_t *)list->param_ptr;
530 } else if (param & LIST_PARAM_FUNC) {
531 // ����������������������
532 typedef wchar_t *(*func_t)(const SetupList *list, TTTSet *pts);
533 func_t func = (func_t)list->param_ptr;
534 s = func(list, pts);
535 } else {
536 assert("bad list?");
537 s = NULL;
538 }
539 if (s == NULL) {
540 // �\���s�v
541 continue;
542 }
543
544 const char *key = list->key;
545 const wchar_t *def_text = list->def_text;
546 wchar_t *text;
547 GetI18nStrWW("Tera Term", key, def_text, pts->UILanguageFileW, &text);
548
549 LVITEMW item;
550 item.mask = LVIF_TEXT;
551 item.iItem = y;
552 item.iSubItem = 0;
553 item.pszText = text;
554 SendMessage(hWndList, LVM_INSERTITEMW, 0, (LPARAM)&item);
555 free(text);
556
557 item.mask = LVIF_TEXT;
558 item.iItem = y;
559 item.iSubItem = 1;
560 item.pszText = s;
561 SendMessage(hWndList, LVM_SETITEMW, 0, (LPARAM)&item);
562
563 y++;
564
565 if (param & LIST_PARAM_FUNC) {
566 // �\���p�������������������J��
567 free(s);
568 }
569 }
570
571 // ��������
572 for (int i = 0; i < 2; i++) {
573 ListView_SetColumnWidth(hWndList, i, LVSCW_AUTOSIZE);
574 }
575
576 CenterWindow(hDlgWnd, GetParent(hDlgWnd));
577
578 static const wchar_t *str = L"Right click to open submenu";
579 dlg_data->tipwin = TipWin2Create(NULL, hDlgWnd);
580 TipWin2SetTextW(dlg_data->tipwin, IDC_SETUP_DIR_LIST, str);
581 return TRUE;
582 }
583
584 case WM_COMMAND: {
585 switch (LOWORD(wp)) {
586 case IDHELP:
587 OpenHelpCV(pcv, HH_HELP_CONTEXT, HlpMenuSetupDir);
588 break;
589
590 case IDOK:
591 TTEndDialog(hDlgWnd, IDOK);
592 return TRUE;
593 break;
594
595 case IDCANCEL:
596 TTEndDialog(hDlgWnd, IDCANCEL);
597 return TRUE;
598 break;
599
600 default:
601 return FALSE;
602 }
603 return FALSE;
604 }
605
606 case WM_DESTROY:
607 TipWin2Destroy(dlg_data->tipwin);
608 dlg_data->tipwin = NULL;
609 return TRUE;
610
611 case WM_NOTIFY: {
612 NMHDR *nmhdr = (NMHDR *)lp;
613 if (nmhdr->code == TTN_POP) {
614 // 1�������\�����������A����������������
615 TipWin2SetTextW(dlg_data->tipwin, IDC_SETUP_DIR_LIST, NULL);
616 }
617 else if (nmhdr->idFrom == IDC_SETUP_DIR_LIST) {
618 NMLISTVIEW *nmlist = (NMLISTVIEW *)lp;
619 switch (nmlist->hdr.code) {
620 // case NM_CLICK:
621 case NM_RCLICK: {
622 POINT pointer_pos;
623 GetCursorPos(&pointer_pos);
624 LVHITTESTINFO ht = {};
625 ht.pt = pointer_pos;
626 ScreenToClient(nmlist->hdr.hwndFrom, &ht.pt);
627 ListView_HitTest(nmlist->hdr.hwndFrom, &ht);
628 if (ht.flags & LVHT_ONITEM) {
629 int hit_item = ht.iItem;
630
631 wchar_t path[MAX_PATH];
632 LV_ITEMW item;
633 item.mask = TVIF_TEXT;
634 item.iItem = hit_item;
635 item.iSubItem = 1;
636 item.pszText = path;
637 item.cchTextMax = _countof(path);
638 SendMessageW(nmlist->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&item);
639
640 PopupAndExec(nmlist->hdr.hwndFrom, &pointer_pos, path, pts);
641 }
642 break;
643 }
644 }
645 }
646 break;
647 }
648 default:
649 return FALSE;
650 }
651 return TRUE;
652 }
653
654 void SetupDirectoryDialog(HINSTANCE hInst, HWND hWnd, TComVar *pcv)
655 {
656 dlg_data_t* dlg_data = (dlg_data_t*)calloc(sizeof(dlg_data_t), 1);
657 dlg_data->pcv = pcv;
658 TTDialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SETUP_DIR_DIALOG),
659 hWnd, OnSetupDirectoryDlgProc, (LPARAM)dlg_data);
660 free(dlg_data);
661 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26