ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/VTBFileUtil2/ScanUtility.cxx
Revision: 291
Committed: 2003-09-05T01:57:00-07:00 (21 years, 9 months ago) by douglas
File size: 23783 byte(s)
Log Message:
Editing is rich.

File Contents

# Content
1 // Vance Thrift and Biller File Utility 2
2 //
3 // Douglas Thrift
4 //
5 // $Id: ScanUtility.cxx,v 1.16 2003/09/05 08:57:00 douglas Exp $
6
7 #include "ScanUtility.h"
8
9 ScanUtility::ScanUtility() : DiscBrowse()
10 {
11 number = count++;
12
13 utilities.insert(pair<unsigned, ScanUtility*>(number, this));
14
15 title = programName + " - Scan Utility";
16
17 // start
18 wizard[0].dwSize = sizeof(wizard[0]);
19 wizard[0].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
20 PSP_USEHEADERSUBTITLE;
21 wizard[0].hInstance = gui.instance;
22 wizard[0].pszTemplate = MAKEINTRESOURCE(IDD_START);
23 wizard[0].pszTitle = title.c_str();
24 wizard[0].pfnDlgProc = start;
25 wizard[0].lParam = number;
26 wizard[0].pszHeaderTitle = "Start";
27 wizard[0].pszHeaderSubTitle = "Change any settings before scanning.";
28
29 // select
30 wizard[1].dwSize = sizeof(wizard[1]);
31 wizard[1].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
32 PSP_USEHEADERSUBTITLE;
33 wizard[1].hInstance = gui.instance;
34 wizard[1].pszTemplate = MAKEINTRESOURCE(IDD_SELECT);
35 wizard[1].pszTitle = title.c_str();
36 wizard[1].pfnDlgProc = select;
37 wizard[1].lParam = number;
38 wizard[1].pszHeaderTitle = "Select";
39 wizard[1].pszHeaderSubTitle = "Choose the scanned document to save.";
40
41 // enter
42 wizard[2].dwSize = sizeof(wizard[2]);
43 wizard[2].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
44 PSP_USEHEADERSUBTITLE;
45 wizard[2].hInstance = gui.instance;
46 wizard[2].pszTemplate = MAKEINTRESOURCE(IDD_ENTER);
47 wizard[2].pszTitle = title.c_str();
48 wizard[2].pfnDlgProc = enter;
49 wizard[2].lParam = number;
50 wizard[2].pszHeaderTitle = "Enter";
51 wizard[2].pszHeaderSubTitle = "Input the client information.";
52
53 // confirm
54 wizard[3].dwSize = sizeof(wizard[3]);
55 wizard[3].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
56 PSP_USEHEADERSUBTITLE;
57 wizard[3].hInstance = gui.instance;
58 wizard[3].pszTemplate = MAKEINTRESOURCE(IDD_CONFIRM);
59 wizard[3].pszTitle = title.c_str();
60 wizard[3].pfnDlgProc = confirm;
61 wizard[3].lParam = number;
62 wizard[3].pszHeaderTitle = "Confirm";
63 wizard[3].pszHeaderSubTitle = "Make sure the file information is correct.";
64
65 // complete
66 wizard[4].dwSize = sizeof(wizard[3]);
67 wizard[4].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
68 PSP_USEHEADERSUBTITLE;
69 wizard[4].hInstance = gui.instance;
70 wizard[4].pszTemplate = MAKEINTRESOURCE(IDD_DONE);
71 wizard[4].pszTitle = title.c_str();
72 wizard[4].pfnDlgProc = done;
73 wizard[4].lParam = number;
74 wizard[4].pszHeaderTitle = "Done";
75 wizard[4].pszHeaderSubTitle = "Exit or start over for another scan.";
76 }
77
78 ScanUtility::~ScanUtility()
79 {
80 utilities.erase(number);
81 }
82
83 void ScanUtility::run(void)
84 {
85 loadDirs();
86
87 PROPSHEETHEADER header;
88
89 // header
90 header.dwSize = sizeof(header);
91 header.dwFlags = PSH_DEFAULT | PSH_HEADER | PSH_PROPSHEETPAGE |
92 PSH_USEICONID | PSH_WIZARD97 | PSH_WIZARDHASFINISH;
93 header.hwndParent = NULL;
94 header.hInstance = gui.instance;
95 header.pszIcon = MAKEINTRESOURCE(IDI_VTB_ICON);
96 header.nPages = 5;
97 header.nStartPage = 0;
98 header.ppsp = wizard;
99 header.pszbmHeader = MAKEINTRESOURCE(IDB_VTB_BMP);
100
101 PropertySheet(&header);
102 saveDirs();
103 }
104
105 map<unsigned, ScanUtility*> ScanUtility::utilities;
106 map<HWND, ScanUtility*> ScanUtility::windows;
107
108 void ScanUtility::loadDirs(void)
109 {
110 HKEY key;
111
112 if (RegOpenKeyEx(HKEY_CURRENT_USER,
113 "Software\\DouglasThrift\\VTBFileUtil2", 0, KEY_QUERY_VALUE, &key) ==
114 ERROR_SUCCESS)
115 {
116 DWORD type;
117 char data[MAX_PATH];
118 DWORD size = MAX_PATH;
119
120 if (RegQueryValueEx(key, "ScanDir", NULL, &type, LPBYTE(data), &size)
121 == ERROR_SUCCESS)
122 {
123 data[size - 1] = '\0';
124
125 switch (type)
126 {
127 case REG_EXPAND_SZ:
128 {
129 char folder[MAX_PATH];
130
131 ExpandEnvironmentStrings(data, folder, MAX_PATH);
132
133 scanDir = tail(folder);
134 }
135 break;
136 case REG_SZ:
137 scanDir = tail(data);
138 break;
139 default:
140 setScanDir();
141 break;
142 }
143 }
144 else
145 {
146 setScanDir();
147 }
148
149 size = MAX_PATH;
150
151 if (RegQueryValueEx(key, "SaveDir", NULL, &type, LPBYTE(data), &size)
152 == ERROR_SUCCESS)
153 {
154 data[size - 1] = '\0';
155
156 switch (type)
157 {
158 case REG_EXPAND_SZ:
159 {
160 char folder[MAX_PATH];
161
162 ExpandEnvironmentStrings(data, folder, MAX_PATH);
163
164 saveDir = tail(folder);
165 }
166 break;
167 case REG_SZ:
168 saveDir = tail(data);
169 break;
170 default:
171 setSaveDir();
172 break;
173 }
174 }
175 else
176 {
177 setSaveDir();
178 }
179
180 RegCloseKey(key);
181 }
182 else
183 {
184 setScanDir();
185 setSaveDir();
186 }
187
188 if (debug) cerr << "scanDir = " << scanDir << "\n"
189 << "saveDir = " << saveDir << "\n";
190 }
191
192 void ScanUtility::saveDirs(void)
193 {
194 HKEY key;
195
196 if (LONG code = RegCreateKeyEx(HKEY_CURRENT_USER,
197 "Software\\DouglasThrift\\VTBFileUtil2", 0, NULL,
198 REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &key,
199 NULL) == ERROR_SUCCESS)
200 {
201 DWORD type;
202 char data[MAX_PATH];
203 DWORD size = MAX_PATH;
204
205 if (RegQueryValueEx(key, "ScanDir", NULL, &type, LPBYTE(data), &size)
206 == ERROR_SUCCESS)
207 {
208 data[size - 1] = '\0';
209 }
210 else
211 {
212 data[0] = '\0';
213 }
214
215 if (scanDir != data || type != REG_SZ)
216 {
217 if (RegSetValueEx(key, "ScanDir", 0, REG_SZ,
218 LPBYTE(scanDir.c_str()), scanDir.length() + 1) !=
219 ERROR_SUCCESS)
220 {
221 error(NULL, code);
222 }
223 }
224
225 size = MAX_PATH;
226
227 if (RegQueryValueEx(key, "SaveDir", NULL, &type, LPBYTE(data), &size)
228 == ERROR_SUCCESS)
229 {
230 data[size - 1] = '\0';
231 }
232 else
233 {
234 data[0] = '\0';
235 }
236
237 if (saveDir != data || type != REG_SZ)
238 {
239 if (RegSetValueEx(key, "SaveDir", 0, REG_SZ,
240 LPBYTE(saveDir.c_str()), saveDir.length() + 1) !=
241 ERROR_SUCCESS)
242 {
243 error(NULL, code);
244 }
245 }
246
247 RegCloseKey(key);
248 }
249 else
250 {
251 error(NULL, code);
252 }
253 }
254
255 void ScanUtility::setScanDir(HWND parent)
256 {
257 BROWSEINFO info;
258
259 info.hwndOwner = parent;
260 info.pidlRoot = NULL;
261 info.pszDisplayName = NULL;
262 info.lpszTitle = "Select the Scan Directory";
263 info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
264 info.lpfn = browse;
265 info.lParam = MAKELPARAM(number, true);
266 info.iImage = 0;
267
268 do
269 {
270 LPITEMIDLIST id = SHBrowseForFolder(&info);
271
272 if (id != NULL)
273 {
274 char folder[MAX_PATH];
275
276 if (SHGetPathFromIDList(id, folder)) scanDir = tail(folder);
277 }
278
279 LPMALLOC destruct;
280
281 SHGetMalloc(&destruct);
282 destruct->Free(id);
283 destruct->Release();
284
285 if (scanDir == "")
286 {
287 switch (MessageBox(parent, "Scan Directory needs to be selected.",
288 title.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
289 {
290 case IDABORT:
291 exit(1);
292 break;
293 case IDRETRY:
294 break;
295 case IDIGNORE:
296 Beep(2200, 250);
297 Beep(1100, 500);
298 Beep(3300, 250);
299 exit(2);
300 break;
301 }
302 }
303 }
304 while (scanDir == "");
305
306 if (debug) cerr << "scanDir = " << scanDir << "\n";
307 }
308
309 void ScanUtility::setSaveDir(HWND parent)
310 {
311 BROWSEINFO info;
312
313 info.hwndOwner = parent;
314 info.pidlRoot = NULL;
315 info.pszDisplayName = NULL;
316 info.lpszTitle = "Select the Save Directory";
317 info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
318 info.lpfn = browse;
319 info.lParam = MAKELPARAM(number, false);
320 info.iImage = 0;
321
322 do
323 {
324 LPITEMIDLIST id = SHBrowseForFolder(&info);
325
326 if (id != NULL)
327 {
328 char folder[MAX_PATH];
329
330 if (SHGetPathFromIDList(id, folder)) saveDir = tail(folder);
331 }
332
333 LPMALLOC destruct;
334
335 SHGetMalloc(&destruct);
336 destruct->Free(id);
337 destruct->Release();
338
339 if (saveDir == "")
340 {
341 switch (MessageBox(parent, "Scan Directory needs to be selected.",
342 title.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
343 {
344 case IDABORT:
345 exit(1);
346 break;
347 case IDRETRY:
348 break;
349 case IDIGNORE:
350 Beep(2200, 250);
351 Beep(1100, 500);
352 Beep(3300, 250);
353 exit(2);
354 break;
355 }
356 }
357 }
358 while (saveDir == "");
359
360 if (debug) cerr << "saveDir = " << saveDir << "\n";
361 }
362
363 void ScanUtility::populate(HWND parent)
364 {
365 set<string> scans;
366
367 do
368 {
369 string scan = scanDir + "SCAN????_000." +
370 IndividualClient::getExtension();
371 WIN32_FIND_DATA found;
372 HANDLE finder = FindFirstFile(scan.c_str(), &found);
373
374 if (finder != INVALID_HANDLE_VALUE)
375 {
376 do
377 {
378 scans.insert(found.cFileName);
379 }
380 while (FindNextFile(finder, &found));
381
382 FindClose(finder);
383 }
384
385 if (scans.empty())
386 {
387 if (MessageBox(parent, "No scanned documents found.",
388 title.c_str(), MB_RETRYCANCEL | MB_ICONQUESTION) == IDCANCEL)
389 break;
390 }
391 }
392 while (scans.empty());
393
394 if (scans.empty())
395 {
396 PropSheet_PressButton(GetParent(parent), PSBTN_BACK);
397 }
398 else
399 {
400 SHFILEINFO info;
401 HIMAGELIST icons = HIMAGELIST(SHGetFileInfo((*scans.begin()).c_str(),
402 0, &info, sizeof(info), SHGFI_SMALLICON | SHGFI_SYSICONINDEX));
403
404 ListView_SetImageList(GetDlgItem(parent, IDC_SELECT_SCANS), icons,
405 LVSIL_SMALL);
406
407 if (debug) cerr << "scans = {\n";
408
409 for (set<string>::iterator itor = scans.begin(); itor != scans.end();
410 itor++)
411 {
412 if (debug) cerr << " " << *itor << "\n";
413
414 char scan[MAX_PATH];
415
416 sprintf(scan, "%s", (*itor).c_str());
417
418 LVITEM item;
419
420 item.mask = LVIF_IMAGE | LVIF_TEXT;
421 item.iItem = 0;
422 item.iSubItem = 0;
423 item.pszText = scan;
424 item.iImage = info.iIcon;
425
426 ListView_InsertItem(GetDlgItem(parent, IDC_SELECT_SCANS), &item);
427 }
428
429 if (debug) cerr << "}\n";
430
431 ListView_SetItemState(GetDlgItem(parent, IDC_SELECT_SCANS), 0,
432 LVIS_SELECTED, LVIS_SELECTED);
433 }
434 }
435
436 ScanUtility* ScanUtility::which(HWND window)
437 {
438 map<HWND, ScanUtility*>::iterator itor = windows.find(window);
439
440 return itor->second;
441 }
442
443 ScanUtility* ScanUtility::which(HWND window, LPARAM l)
444 {
445 LPPROPSHEETPAGE page = LPPROPSHEETPAGE(l);
446 map<unsigned, ScanUtility*>::iterator itor = utilities.find(page->lParam);
447
448 windows.insert(pair<HWND, ScanUtility*>(window, itor->second));
449
450 return itor->second;
451 }
452
453 int ScanUtility::browse(HWND dialog, UINT msg, LPARAM l, LPARAM d)
454 {
455 map<unsigned, ScanUtility*>::iterator itor = utilities.find(LOWORD(d));
456 ScanUtility* data = itor->second;
457
458 switch (msg)
459 {
460 case BFFM_INITIALIZED:
461 center(dialog);
462 SendMessage(dialog, BFFM_SETOKTEXT, 0,
463 LPARAM(toWide("&Select").c_str()));
464 SendMessage(dialog, BFFM_SETEXPANDED, FALSE, CSIDL_DRIVES);
465
466 if ((HIWORD(d) ? data->scanDir : data->saveDir) != "")
467 {
468 IShellFolder* desktop;
469 LPWSTR path = new WCHAR[(HIWORD(d) ? data->scanDir.length() :
470 data->saveDir.length()) + 1];
471 LPITEMIDLIST id;
472
473 wsprintfW(path, toWide(HIWORD(d) ? data->scanDir :
474 data->saveDir).c_str());
475
476 if (debug) cerr << "path = " << toAnsi(path) << "\n";
477
478 SHGetDesktopFolder(&desktop);
479 desktop->ParseDisplayName(dialog, NULL, path, NULL, &id, NULL);
480
481 if (id != NULL)
482 {
483 SendMessage(dialog, BFFM_SETSELECTION, FALSE, LPARAM(id));
484
485 LPMALLOC destruct;
486
487 SHGetMalloc(&destruct);
488 destruct->Free(id);
489 destruct->Release();
490 }
491
492 desktop->Release();
493 }
494 break;
495 case BFFM_SELCHANGED:
496 {
497 SHFILEINFO info;
498
499 SHGetFileInfo(LPCSTR(l), 0, &info, sizeof(info), SHGFI_DISPLAYNAME
500 | SHGFI_PIDL);
501 SendMessage(dialog, BFFM_SETSTATUSTEXT, 0,
502 LPARAM(info.szDisplayName));
503
504 char folder[MAX_PATH];
505
506 if (!SHGetPathFromIDList(LPCITEMIDLIST(l), folder))
507 {
508 SendMessage(dialog, BFFM_ENABLEOK, 0, 0);
509 }
510 else
511 {
512 SendMessage(dialog, BFFM_SETSTATUSTEXT, 0, LPARAM(folder));
513 }
514 }
515 break;
516 }
517
518 return 0;
519 }
520
521 INT_PTR ScanUtility::start(HWND dialog, UINT msg, WPARAM w, LPARAM l)
522 {
523 ScanUtility* data = which(dialog);
524
525 switch (msg)
526 {
527 case WM_INITDIALOG:
528 center(GetParent(dialog));
529 SendMessage(GetParent(dialog), WM_SETICON, ICON_BIG, LPARAM(gui.icon));
530
531 data = which(dialog, l);
532
533 {
534 ostringstream instructions;
535
536 instructions << "1. If you need instructions, you should not be ru"
537 << "nning this program in Scan Utility mode.\n"
538 << "2. Otherwise, go forth and scan.\n"
539 << "3. Then come back and click Next.\n";
540
541 SetDlgItemText(dialog, IDC_START_INSTRUCTIONS,
542 instructions.str().c_str());
543 }
544 break;
545 case WM_NOTIFY:
546 {
547 LPNMHDR nm = LPNMHDR(l);
548
549 switch (nm->code)
550 {
551 case PSN_SETACTIVE:
552 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_FINISH |
553 PSWIZB_NEXT);
554
555 {
556 SHFILEINFO info;
557
558 SHGetFileInfo(data->scanDir.c_str(), 0, &info,
559 sizeof(info), SHGFI_ICONLOCATION);
560
561 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
562 info.iIcon);
563
564 SendDlgItemMessage(dialog, IDC_START_SCAN_ICON,
565 STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
566 SHGetFileInfo(data->saveDir.c_str(), 0, &info,
567 sizeof(info), SHGFI_ICONLOCATION);
568
569 icon = ExtractIcon(gui.instance, info.szDisplayName,
570 info.iIcon);
571
572 SendDlgItemMessage(dialog, IDC_START_SAVE_ICON,
573 STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
574 }
575
576 {
577 char folder[38];
578
579 PathCompactPathEx(folder, data->scanDir.substr(0,
580 data->scanDir.length() - 1).c_str(), 38, 0);
581 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
582 PathCompactPathEx(folder, data->saveDir.substr(0,
583 data->saveDir.length() - 1).c_str(), 38, 0);
584 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
585 }
586 break;
587 case PSN_WIZNEXT:
588 SetCurrentDirectory(data->scanDir.c_str());
589 break;
590 }
591 }
592 break;
593 case WM_COMMAND:
594 switch (LOWORD(w))
595 {
596 case IDC_START_SCAN_BROWSE:
597 data->setScanDir(dialog);
598
599 {
600 SHFILEINFO info;
601
602 SHGetFileInfo(data->scanDir.c_str(), 0, &info, sizeof(info),
603 SHGFI_ICONLOCATION);
604
605 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
606 info.iIcon);
607
608 SendDlgItemMessage(dialog, IDC_START_SCAN_ICON, STM_SETIMAGE,
609 IMAGE_ICON, LPARAM(icon));
610 }
611
612 {
613 char folder[38];
614
615 PathCompactPathEx(folder, data->scanDir.substr(0,
616 data->scanDir.length() - 1).c_str(), 38, 0);
617 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
618 }
619 break;
620 case IDC_START_SAVE_BROWSE:
621 data->setSaveDir(dialog);
622
623 {
624 SHFILEINFO info;
625
626 SHGetFileInfo(data->saveDir.c_str(), 0, &info, sizeof(info),
627 SHGFI_ICONLOCATION);
628
629 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
630 info.iIcon);
631
632 SendDlgItemMessage(dialog, IDC_START_SAVE_ICON, STM_SETIMAGE,
633 IMAGE_ICON, LPARAM(icon));
634 }
635
636 {
637 char folder[38];
638
639 PathCompactPathEx(folder, data->saveDir.substr(0,
640 data->saveDir.length() - 1).c_str(), 38, 0);
641 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
642 }
643 break;
644 }
645 break;
646 }
647
648 return FALSE;
649 }
650
651 INT_PTR ScanUtility::select(HWND dialog, UINT msg, WPARAM w, LPARAM l)
652 {
653 ScanUtility* data = which(dialog);
654
655 switch (msg)
656 {
657 case WM_INITDIALOG:
658 data = which(dialog, l);
659
660 {
661 ostringstream select;
662
663 select << "Select the scanned document that you need to save.";
664
665 SetDlgItemText(dialog, IDC_SELECT_TEXT, select.str().c_str());
666 }
667
668 {
669 LVCOLUMN column;
670
671 column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
672 column.fmt = LVCFMT_IMAGE;
673 column.cx = 120;
674 column.pszText = "Scanned Documents";
675
676 ListView_InsertColumn(GetDlgItem(dialog, IDC_SELECT_SCANS), 0,
677 &column);
678 }
679 break;
680 case WM_NOTIFY:
681 if (w == IDC_SELECT_SCANS)
682 {
683 LPNMITEMACTIVATE ni = LPNMITEMACTIVATE(l);
684
685 switch (ni->hdr.code)
686 {
687 case NM_DBLCLK:
688 if (ni->iItem != -1)
689 {
690 char scan[MAX_PATH];
691
692 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
693 ni->iItem, 0, scan, MAX_PATH);
694 ShellExecute(dialog, NULL, scan, NULL, NULL,
695 SW_SHOWDEFAULT);
696 }
697 break;
698 }
699 }
700 else
701 {
702 LPNMHDR nm = LPNMHDR(l);
703
704 switch (nm->code)
705 {
706 case PSN_SETACTIVE:
707 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
708 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
709 data->populate(dialog);
710 break;
711 case PSN_WIZBACK:
712 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
713 data->client.setFile("");
714 break;
715 case PSN_WIZNEXT:
716 {
717 int index = ListView_GetNextItem(GetDlgItem(dialog,
718 IDC_SELECT_SCANS), -1, LVNI_SELECTED);
719 char scan[MAX_PATH];
720
721 if (index != -1)
722 {
723 ListView_GetItemText(GetDlgItem(dialog,
724 IDC_SELECT_SCANS), index, 0, scan, MAX_PATH);
725 }
726 else
727 {
728 ListView_GetItemText(GetDlgItem(dialog,
729 IDC_SELECT_SCANS), 0, 0, scan, MAX_PATH);
730 }
731
732 data->scan = scan;
733 }
734
735 if (debug) cerr << "scan = " << data->scan << "\n";
736
737 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
738 break;
739 }
740 }
741 break;
742 case WM_CONTEXTMENU:
743 if (ListView_GetNextItem(GetDlgItem(dialog, IDC_SELECT_SCANS), -1,
744 LVNI_SELECTED) != -1)
745 {
746 char scan[MAX_PATH];
747 POINT spot;
748 LVHITTESTINFO test;
749
750 test.pt.x = GET_X_LPARAM(l);
751 test.pt.y = GET_Y_LPARAM(l);
752
753 ScreenToClient(GetDlgItem(dialog, IDC_SELECT_SCANS), &test.pt);
754 ListView_HitTest(GetDlgItem(dialog, IDC_SELECT_SCANS), &test);
755
756 if (test.iItem != -1)
757 {
758 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
759 test.iItem, 0, scan, MAX_PATH);
760
761 spot.x = test.pt.x;
762 spot.y = test.pt.y;
763 }
764 else if (GET_X_LPARAM(l) == -1 && GET_Y_LPARAM(l) == -1)
765 {
766 int index = ListView_GetNextItem(GetDlgItem(dialog,
767 IDC_SELECT_SCANS), -1, LVNI_SELECTED);
768 RECT rect;
769
770 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
771 index, 0, scan, MAX_PATH);
772 ListView_EnsureVisible(GetDlgItem(dialog, IDC_SELECT_SCANS),
773 index, FALSE);
774 ListView_GetItemRect(GetDlgItem(dialog, IDC_SELECT_SCANS),
775 index, &rect, LVIR_SELECTBOUNDS);
776
777 spot.x = rect.left;
778 spot.y = rect.top;
779 }
780
781 ClientToScreen(GetDlgItem(dialog, IDC_SELECT_SCANS), &spot);
782
783 int code = TrackPopupMenuEx(data->popup, TPM_LEFTALIGN |
784 TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_RIGHTBUTTON,
785 spot.x, spot.y, GetDlgItem(dialog, IDC_SELECT_SCANS), NULL);
786
787 switch (code)
788 {
789 case 1:
790 ShellExecute(dialog, NULL, scan, NULL, NULL, SW_SHOWDEFAULT);
791 break;
792 case 2:
793 {
794 SHELLEXECUTEINFO info;
795
796 info.cbSize = sizeof(info);
797 info.fMask = SEE_MASK_INVOKEIDLIST;
798 info.hwnd = dialog;
799 info.lpVerb = "properties";
800 info.lpFile = scan;
801 info.lpParameters = NULL;
802 info.lpDirectory = NULL;
803 info.nShow = SW_SHOWDEFAULT;
804 info.lpIDList = NULL;
805
806 ShellExecuteEx(&info);
807 }
808 break;
809 }
810 }
811 break;
812 }
813
814 return FALSE;
815 }
816
817 INT_PTR ScanUtility::enter(HWND dialog, UINT msg, WPARAM w, LPARAM l)
818 {
819 ScanUtility* data = which(dialog);
820
821 switch (msg)
822 {
823 case WM_INITDIALOG:
824 data = which(dialog, l);
825
826 {
827 ostringstream enter;
828
829 enter << "Enter the client name and number.";
830
831 SetDlgItemText(dialog, IDC_ENTER_TEXT, enter.str().c_str());
832 }
833 break;
834 case WM_NOTIFY:
835 {
836 LPNMHDR nm = LPNMHDR(l);
837
838 switch (nm->code)
839 {
840 case PSN_SETACTIVE:
841 if (data->client.getName() != "" && data->client.getNumber() !=
842 0)
843 {
844 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
845 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
846 }
847 else
848 {
849 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
850 PSWIZB_DISABLEDFINISH);
851 }
852
853 SetDlgItemText(dialog, IDC_ENTER_NAME,
854 data->client.getName().c_str());
855
856 if (data->client.getNumber() != 0)
857 {
858 SetDlgItemInt(dialog, IDC_ENTER_NUM,
859 data->client.getNumber(), FALSE);
860 }
861 else
862 {
863 SetDlgItemText(dialog, IDC_ENTER_NUM, "");
864 }
865 break;
866 case PSN_WIZBACK:
867 break;
868 case PSN_WIZNEXT:
869 if (debug)
870 {
871 cerr << "client = {\n"
872 << " name = " << data->client.getName() << "\n"
873 << " number = " << data->client.getNumber() << "\n"
874 << " file = " << data->client.getFile() << "\n"
875 << "}\n";
876 }
877
878 data->save = data->saveDir + '\\' + data->client.getFile();
879
880 if (debug) cerr << "save = " << data->save << "\n";
881
882 break;
883 }
884 }
885 break;
886 case WM_COMMAND:
887 switch (LOWORD(w))
888 {
889 case IDC_ENTER_NAME:
890 {
891 char name[BUFSIZ];
892
893 GetDlgItemText(dialog, IDC_ENTER_NAME, name, BUFSIZ);
894
895 if (name != data->client.getName())
896 {
897 data->client.setName(name);
898 }
899 }
900
901 if (data->client.getName() != "" && data->client.getNumber() != 0)
902 {
903 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
904 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
905 }
906 else
907 {
908 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
909 PSWIZB_DISABLEDFINISH);
910 }
911 break;
912 case IDC_ENTER_NUM:
913 {
914 unsigned number = GetDlgItemInt(dialog, IDC_ENTER_NUM, NULL,
915 FALSE);
916
917 if (number != data->client.getNumber())
918 {
919 data->client.setNumber(number);
920 }
921 }
922
923 if (data->client.getName() != "" && data->client.getNumber() != 0)
924 {
925 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
926 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
927 }
928 else
929 {
930 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
931 PSWIZB_DISABLEDFINISH);
932 }
933 break;
934 }
935 break;
936 }
937
938 return FALSE;
939 }
940
941 INT_PTR ScanUtility::confirm(HWND dialog, UINT msg, WPARAM w, LPARAM l)
942 {
943 ScanUtility* data = which(dialog);
944
945 switch (msg)
946 {
947 case WM_INITDIALOG:
948 data = which(dialog, l);
949
950 {
951 ostringstream confirm;
952
953 confirm << "Confirm the client file\'s name and size.";
954
955 SetDlgItemText(dialog, IDC_CONFIRM_TEXT, confirm.str().c_str());
956 }
957 break;
958 case WM_NOTIFY:
959 {
960 LPNMHDR nm = LPNMHDR(l);
961
962 switch (nm->code)
963 {
964 case PSN_SETACTIVE:
965 CheckDlgButton(dialog, IDC_CONFIRM_GOOD, BST_UNCHECKED);
966 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
967 PSWIZB_DISABLEDFINISH);
968 SetDlgItemText(dialog, IDC_CONFIRM_FILE,
969 data->client.getFile().c_str());
970
971 {
972 HANDLE scan = CreateFile(data->scan.c_str(), GENERIC_READ,
973 FILE_SHARE_READ, NULL, OPEN_EXISTING,
974 FILE_ATTRIBUTE_NORMAL, NULL);
975 DWORD bytes = GetFileSize(scan, NULL);
976
977 CloseHandle(scan);
978
979 ostringstream size;
980
981 size << format(bytes);
982
983 size.setf(ios_base::fixed, ios_base::floatfield);
984 size.precision(2);
985
986 FLOAT megabytes = FLOAT(bytes) / FLOAT(1024 * 1024);
987
988 size << " bytes (" << megabytes << " MB)";
989
990 SetDlgItemText(dialog, IDC_CONFIRM_SIZE,
991 size.str().c_str());
992 }
993 break;
994 case PSN_WIZBACK:
995 break;
996 case PSN_WIZNEXT:
997 if (MoveFile(data->scan.c_str(), data->save.c_str()) == 0)
998 {
999 do
1000 {
1001 LPVOID message;
1002
1003 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1004 FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
1005 0, LPTSTR(&message), 0, NULL);
1006
1007 int code = MessageBox(dialog, LPCTSTR(message),
1008 data->title.c_str(), MB_RETRYCANCEL |
1009 MB_ICONEXCLAMATION);
1010
1011 LocalFree(message);
1012
1013 if (code == IDCANCEL)
1014 {
1015 PropSheet_PressButton(GetParent(dialog),
1016 PSBTN_BACK);
1017 break;
1018 }
1019 }
1020 while (MoveFileEx(data->scan.c_str(), data->save.c_str(),
1021 MOVEFILE_REPLACE_EXISTING) == 0);
1022 }
1023 break;
1024 }
1025 }
1026 break;
1027 case WM_COMMAND:
1028 switch (LOWORD(w))
1029 {
1030 case IDC_CONFIRM_GOOD:
1031 if (IsDlgButtonChecked(dialog, IDC_CONFIRM_GOOD) == BST_CHECKED)
1032 {
1033 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1034 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
1035 }
1036 else
1037 {
1038 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1039 PSWIZB_DISABLEDFINISH);
1040 }
1041 break;
1042 }
1043 break;
1044 }
1045
1046 return FALSE;
1047 }
1048
1049 INT_PTR ScanUtility::done(HWND dialog, UINT msg, WPARAM w, LPARAM l)
1050 {
1051 ScanUtility* data = which(dialog);
1052
1053 switch (msg)
1054 {
1055 case WM_INITDIALOG:
1056 data = which(dialog, l);
1057
1058 {
1059 ostringstream done;
1060
1061 done << "You are done saving the scanned document. Click Finish to"
1062 << " exit or click Back to return to the beginning.";
1063
1064 SetDlgItemText(dialog, IDC_DONE_TEXT, done.str().c_str());
1065 }
1066 break;
1067 case WM_NOTIFY:
1068 {
1069 LPNMHDR nm = LPNMHDR(l);
1070
1071 switch (nm->code)
1072 {
1073 case PSN_SETACTIVE:
1074 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1075 PSWIZB_FINISH);
1076 break;
1077 case PSN_WIZBACK:
1078 data->client.setFile("");
1079 PropSheet_SetCurSelByID(GetParent(dialog), IDD_START);
1080 break;
1081 case PSN_WIZFINISH:
1082 break;
1083 }
1084 }
1085 break;
1086 }
1087
1088 return FALSE;
1089 }