ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/VTBFileUtil2/ScanUtility.cxx
Revision: 292
Committed: 2003-09-08T18:43:28-07:00 (21 years, 9 months ago) by douglas
File size: 24006 byte(s)
Log Message:
Should be almost done.

File Contents

# Content
1 // Vance Thrift and Biller File Utility 2
2 //
3 // Douglas Thrift
4 //
5 // $Id: ScanUtility.cxx,v 1.17 2003/09/09 01:43:28 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 char buffer[MAX_PATH];
258
259 SHGetFolderPath(parent, CSIDL_FLAG_CREATE | CSIDL_DESKTOPDIRECTORY, NULL,
260 0, buffer);
261
262 BROWSEINFO info;
263
264 info.hwndOwner = parent;
265 info.pidlRoot = NULL;
266 info.pszDisplayName = NULL;
267 info.lpszTitle = "Select the Scan Directory";
268 info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
269 info.lpfn = browse;
270 info.lParam = MAKELPARAM(number, true);
271 info.iImage = 0;
272
273 do
274 {
275 LPITEMIDLIST id = SHBrowseForFolder(&info);
276
277 if (id != NULL)
278 {
279 char folder[MAX_PATH];
280
281 if (SHGetPathFromIDList(id, folder)) scanDir = tail(folder);
282 }
283
284 LPMALLOC destruct;
285
286 SHGetMalloc(&destruct);
287 destruct->Free(id);
288 destruct->Release();
289
290 if (scanDir == "")
291 {
292 switch (MessageBox(parent, "Scan Directory needs to be selected.",
293 title.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
294 {
295 case IDABORT:
296 exit(1);
297 break;
298 case IDRETRY:
299 break;
300 case IDIGNORE:
301 Beep(2200, 250);
302 Beep(1100, 500);
303 Beep(3300, 250);
304 exit(2);
305 break;
306 }
307 }
308 }
309 while (scanDir == "");
310
311 if (debug) cerr << "scanDir = " << scanDir << "\n";
312 }
313
314 void ScanUtility::setSaveDir(HWND parent)
315 {
316 char buffer[MAX_PATH];
317
318 SHGetFolderPath(parent, CSIDL_FLAG_CREATE | CSIDL_DESKTOPDIRECTORY, NULL,
319 0, buffer);
320
321 BROWSEINFO info;
322
323 info.hwndOwner = parent;
324 info.pidlRoot = NULL;
325 info.pszDisplayName = NULL;
326 info.lpszTitle = "Select the Save Directory";
327 info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
328 info.lpfn = browse;
329 info.lParam = MAKELPARAM(number, false);
330 info.iImage = 0;
331
332 do
333 {
334 LPITEMIDLIST id = SHBrowseForFolder(&info);
335
336 if (id != NULL)
337 {
338 char folder[MAX_PATH];
339
340 if (SHGetPathFromIDList(id, folder)) saveDir = tail(folder);
341 }
342
343 LPMALLOC destruct;
344
345 SHGetMalloc(&destruct);
346 destruct->Free(id);
347 destruct->Release();
348
349 if (saveDir == "")
350 {
351 switch (MessageBox(parent, "Scan Directory needs to be selected.",
352 title.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
353 {
354 case IDABORT:
355 exit(1);
356 break;
357 case IDRETRY:
358 break;
359 case IDIGNORE:
360 Beep(2200, 250);
361 Beep(1100, 500);
362 Beep(3300, 250);
363 exit(2);
364 break;
365 }
366 }
367 }
368 while (saveDir == "");
369
370 if (debug) cerr << "saveDir = " << saveDir << "\n";
371 }
372
373 void ScanUtility::populate(HWND parent)
374 {
375 set<string> scans;
376
377 do
378 {
379 string scan = scanDir + "SCAN????_000." +
380 IndividualClient::getExtension();
381 WIN32_FIND_DATA found;
382 HANDLE finder = FindFirstFile(scan.c_str(), &found);
383
384 if (finder != INVALID_HANDLE_VALUE)
385 {
386 do
387 {
388 scans.insert(found.cFileName);
389 }
390 while (FindNextFile(finder, &found));
391
392 FindClose(finder);
393 }
394
395 if (scans.empty())
396 {
397 if (MessageBox(parent, "No scanned documents found.",
398 title.c_str(), MB_RETRYCANCEL | MB_ICONQUESTION) == IDCANCEL)
399 break;
400 }
401 }
402 while (scans.empty());
403
404 if (scans.empty())
405 {
406 PropSheet_PressButton(GetParent(parent), PSBTN_BACK);
407 }
408 else
409 {
410 SHFILEINFO info;
411 HIMAGELIST icons = HIMAGELIST(SHGetFileInfo((*scans.begin()).c_str(),
412 0, &info, sizeof(info), SHGFI_SMALLICON | SHGFI_SYSICONINDEX));
413
414 ListView_SetImageList(GetDlgItem(parent, IDC_SELECT_SCANS), icons,
415 LVSIL_SMALL);
416
417 if (debug) cerr << "scans = {\n";
418
419 for (set<string>::iterator itor = scans.begin(); itor != scans.end();
420 itor++)
421 {
422 if (debug) cerr << " " << *itor << "\n";
423
424 char scan[MAX_PATH];
425
426 sprintf(scan, "%s", (*itor).c_str());
427
428 LVITEM item;
429
430 item.mask = LVIF_IMAGE | LVIF_TEXT;
431 item.iItem = 0;
432 item.iSubItem = 0;
433 item.pszText = scan;
434 item.iImage = info.iIcon;
435
436 ListView_InsertItem(GetDlgItem(parent, IDC_SELECT_SCANS), &item);
437 }
438
439 if (debug) cerr << "}\n";
440
441 ListView_SetItemState(GetDlgItem(parent, IDC_SELECT_SCANS), 0,
442 LVIS_SELECTED, LVIS_SELECTED);
443 }
444 }
445
446 ScanUtility* ScanUtility::which(HWND window)
447 {
448 map<HWND, ScanUtility*>::iterator itor = windows.find(window);
449
450 return itor->second;
451 }
452
453 ScanUtility* ScanUtility::which(HWND window, LPARAM l)
454 {
455 LPPROPSHEETPAGE page = LPPROPSHEETPAGE(l);
456 map<unsigned, ScanUtility*>::iterator itor = utilities.find(page->lParam);
457
458 windows.insert(pair<HWND, ScanUtility*>(window, itor->second));
459
460 return itor->second;
461 }
462
463 int ScanUtility::browse(HWND dialog, UINT msg, LPARAM l, LPARAM d)
464 {
465 map<unsigned, ScanUtility*>::iterator itor = utilities.find(LOWORD(d));
466 ScanUtility* data = itor->second;
467
468 switch (msg)
469 {
470 case BFFM_INITIALIZED:
471 center(dialog);
472 SendMessage(dialog, BFFM_SETOKTEXT, 0,
473 LPARAM(toWide("&Select").c_str()));
474 SendMessage(dialog, BFFM_SETEXPANDED, FALSE, CSIDL_DRIVES);
475
476 if ((HIWORD(d) ? data->scanDir : data->saveDir) != "")
477 {
478 IShellFolder* desktop;
479 LPWSTR path = new WCHAR[(HIWORD(d) ? data->scanDir.length() :
480 data->saveDir.length()) + 1];
481 LPITEMIDLIST id;
482
483 wsprintfW(path, toWide(HIWORD(d) ? data->scanDir :
484 data->saveDir).c_str());
485
486 if (debug) cerr << "path = " << toAnsi(path) << "\n";
487
488 SHGetDesktopFolder(&desktop);
489 desktop->ParseDisplayName(dialog, NULL, path, NULL, &id, NULL);
490
491 if (id != NULL)
492 {
493 SendMessage(dialog, BFFM_SETSELECTION, FALSE, LPARAM(id));
494
495 LPMALLOC destruct;
496
497 SHGetMalloc(&destruct);
498 destruct->Free(id);
499 destruct->Release();
500 }
501
502 desktop->Release();
503 }
504 break;
505 case BFFM_SELCHANGED:
506 {
507 SHFILEINFO info;
508
509 SHGetFileInfo(LPCSTR(l), 0, &info, sizeof(info), SHGFI_DISPLAYNAME
510 | SHGFI_PIDL);
511 SendMessage(dialog, BFFM_SETSTATUSTEXT, 0,
512 LPARAM(info.szDisplayName));
513
514 char folder[MAX_PATH];
515
516 if (!SHGetPathFromIDList(LPCITEMIDLIST(l), folder))
517 {
518 SendMessage(dialog, BFFM_ENABLEOK, 0, 0);
519 }
520 else
521 {
522 SendMessage(dialog, BFFM_SETSTATUSTEXT, 0, LPARAM(folder));
523 }
524 }
525 break;
526 }
527
528 return 0;
529 }
530
531 INT_PTR ScanUtility::start(HWND dialog, UINT msg, WPARAM w, LPARAM l)
532 {
533 ScanUtility* data = which(dialog);
534
535 switch (msg)
536 {
537 case WM_INITDIALOG:
538 center(GetParent(dialog));
539 SendMessage(GetParent(dialog), WM_SETICON, ICON_BIG, LPARAM(gui.icon));
540
541 data = which(dialog, l);
542
543 {
544 ostringstream instructions;
545
546 instructions << "1. If you need instructions, you should not be ru"
547 << "nning this program in Scan Utility mode.\n"
548 << "2. Otherwise, go forth and scan.\n"
549 << "3. Then come back and click Next.\n";
550
551 SetDlgItemText(dialog, IDC_START_INSTRUCTIONS,
552 instructions.str().c_str());
553 }
554 break;
555 case WM_NOTIFY:
556 {
557 LPNMHDR nm = LPNMHDR(l);
558
559 switch (nm->code)
560 {
561 case PSN_SETACTIVE:
562 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_FINISH |
563 PSWIZB_NEXT);
564
565 {
566 SHFILEINFO info;
567
568 SHGetFileInfo(data->scanDir.c_str(), 0, &info,
569 sizeof(info), SHGFI_ICONLOCATION);
570
571 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
572 info.iIcon);
573
574 SendDlgItemMessage(dialog, IDC_START_SCAN_ICON,
575 STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
576 SHGetFileInfo(data->saveDir.c_str(), 0, &info,
577 sizeof(info), SHGFI_ICONLOCATION);
578
579 icon = ExtractIcon(gui.instance, info.szDisplayName,
580 info.iIcon);
581
582 SendDlgItemMessage(dialog, IDC_START_SAVE_ICON,
583 STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
584 }
585
586 {
587 char folder[38];
588
589 PathCompactPathEx(folder, data->scanDir.substr(0,
590 data->scanDir.length() - 1).c_str(), 38, 0);
591 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
592 PathCompactPathEx(folder, data->saveDir.substr(0,
593 data->saveDir.length() - 1).c_str(), 38, 0);
594 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
595 }
596 break;
597 case PSN_WIZNEXT:
598 SetCurrentDirectory(data->scanDir.c_str());
599 break;
600 }
601 }
602 break;
603 case WM_COMMAND:
604 switch (LOWORD(w))
605 {
606 case IDC_START_SCAN_BROWSE:
607 data->setScanDir(dialog);
608
609 {
610 SHFILEINFO info;
611
612 SHGetFileInfo(data->scanDir.c_str(), 0, &info, sizeof(info),
613 SHGFI_ICONLOCATION);
614
615 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
616 info.iIcon);
617
618 SendDlgItemMessage(dialog, IDC_START_SCAN_ICON, STM_SETIMAGE,
619 IMAGE_ICON, LPARAM(icon));
620 }
621
622 {
623 char folder[38];
624
625 PathCompactPathEx(folder, data->scanDir.substr(0,
626 data->scanDir.length() - 1).c_str(), 38, 0);
627 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
628 }
629 break;
630 case IDC_START_SAVE_BROWSE:
631 data->setSaveDir(dialog);
632
633 {
634 SHFILEINFO info;
635
636 SHGetFileInfo(data->saveDir.c_str(), 0, &info, sizeof(info),
637 SHGFI_ICONLOCATION);
638
639 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
640 info.iIcon);
641
642 SendDlgItemMessage(dialog, IDC_START_SAVE_ICON, STM_SETIMAGE,
643 IMAGE_ICON, LPARAM(icon));
644 }
645
646 {
647 char folder[38];
648
649 PathCompactPathEx(folder, data->saveDir.substr(0,
650 data->saveDir.length() - 1).c_str(), 38, 0);
651 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
652 }
653 break;
654 }
655 break;
656 }
657
658 return FALSE;
659 }
660
661 INT_PTR ScanUtility::select(HWND dialog, UINT msg, WPARAM w, LPARAM l)
662 {
663 ScanUtility* data = which(dialog);
664
665 switch (msg)
666 {
667 case WM_INITDIALOG:
668 data = which(dialog, l);
669
670 {
671 ostringstream select;
672
673 select << "Select the scanned document that you need to save.";
674
675 SetDlgItemText(dialog, IDC_SELECT_TEXT, select.str().c_str());
676 }
677
678 {
679 LVCOLUMN column;
680
681 column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
682 column.fmt = LVCFMT_IMAGE;
683 column.cx = 120;
684 column.pszText = "Scanned Documents";
685
686 ListView_InsertColumn(GetDlgItem(dialog, IDC_SELECT_SCANS), 0,
687 &column);
688 }
689 break;
690 case WM_NOTIFY:
691 if (w == IDC_SELECT_SCANS)
692 {
693 LPNMITEMACTIVATE ni = LPNMITEMACTIVATE(l);
694
695 switch (ni->hdr.code)
696 {
697 case NM_DBLCLK:
698 if (ni->iItem != -1)
699 {
700 char scan[MAX_PATH];
701
702 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
703 ni->iItem, 0, scan, MAX_PATH);
704 ShellExecute(dialog, NULL, scan, NULL, NULL,
705 SW_SHOWDEFAULT);
706 }
707 break;
708 }
709 }
710 else
711 {
712 LPNMHDR nm = LPNMHDR(l);
713
714 switch (nm->code)
715 {
716 case PSN_SETACTIVE:
717 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
718 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
719 data->populate(dialog);
720 break;
721 case PSN_WIZBACK:
722 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
723 data->client.setFile("");
724 break;
725 case PSN_WIZNEXT:
726 {
727 int index = ListView_GetNextItem(GetDlgItem(dialog,
728 IDC_SELECT_SCANS), -1, LVNI_SELECTED);
729 char scan[MAX_PATH];
730
731 if (index != -1)
732 {
733 ListView_GetItemText(GetDlgItem(dialog,
734 IDC_SELECT_SCANS), index, 0, scan, MAX_PATH);
735 }
736 else
737 {
738 ListView_GetItemText(GetDlgItem(dialog,
739 IDC_SELECT_SCANS), 0, 0, scan, MAX_PATH);
740 }
741
742 data->scan = scan;
743 }
744
745 if (debug) cerr << "scan = " << data->scan << "\n";
746
747 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
748 break;
749 }
750 }
751 break;
752 case WM_CONTEXTMENU:
753 if (ListView_GetNextItem(GetDlgItem(dialog, IDC_SELECT_SCANS), -1,
754 LVNI_SELECTED) != -1)
755 {
756 char scan[MAX_PATH];
757 POINT spot;
758 LVHITTESTINFO test;
759
760 test.pt.x = GET_X_LPARAM(l);
761 test.pt.y = GET_Y_LPARAM(l);
762
763 ScreenToClient(GetDlgItem(dialog, IDC_SELECT_SCANS), &test.pt);
764 ListView_HitTest(GetDlgItem(dialog, IDC_SELECT_SCANS), &test);
765
766 if (test.iItem != -1)
767 {
768 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
769 test.iItem, 0, scan, MAX_PATH);
770
771 spot.x = test.pt.x;
772 spot.y = test.pt.y;
773 }
774 else if (GET_X_LPARAM(l) == -1 && GET_Y_LPARAM(l) == -1)
775 {
776 int index = ListView_GetNextItem(GetDlgItem(dialog,
777 IDC_SELECT_SCANS), -1, LVNI_SELECTED);
778 RECT rect;
779
780 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
781 index, 0, scan, MAX_PATH);
782 ListView_EnsureVisible(GetDlgItem(dialog, IDC_SELECT_SCANS),
783 index, FALSE);
784 ListView_GetItemRect(GetDlgItem(dialog, IDC_SELECT_SCANS),
785 index, &rect, LVIR_SELECTBOUNDS);
786
787 spot.x = rect.left;
788 spot.y = rect.top;
789 }
790
791 ClientToScreen(GetDlgItem(dialog, IDC_SELECT_SCANS), &spot);
792
793 int code = TrackPopupMenuEx(data->popup, TPM_LEFTALIGN |
794 TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_RIGHTBUTTON,
795 spot.x, spot.y, GetDlgItem(dialog, IDC_SELECT_SCANS), NULL);
796
797 switch (code)
798 {
799 case 1:
800 ShellExecute(dialog, NULL, scan, NULL, NULL, SW_SHOWDEFAULT);
801 break;
802 case 2:
803 {
804 SHELLEXECUTEINFO info;
805
806 info.cbSize = sizeof(info);
807 info.fMask = SEE_MASK_INVOKEIDLIST;
808 info.hwnd = dialog;
809 info.lpVerb = "properties";
810 info.lpFile = scan;
811 info.lpParameters = NULL;
812 info.lpDirectory = NULL;
813 info.nShow = SW_SHOWDEFAULT;
814 info.lpIDList = NULL;
815
816 ShellExecuteEx(&info);
817 }
818 break;
819 }
820 }
821 break;
822 }
823
824 return FALSE;
825 }
826
827 INT_PTR ScanUtility::enter(HWND dialog, UINT msg, WPARAM w, LPARAM l)
828 {
829 ScanUtility* data = which(dialog);
830
831 switch (msg)
832 {
833 case WM_INITDIALOG:
834 data = which(dialog, l);
835
836 {
837 ostringstream enter;
838
839 enter << "Enter the client name and number.";
840
841 SetDlgItemText(dialog, IDC_ENTER_TEXT, enter.str().c_str());
842 }
843 break;
844 case WM_NOTIFY:
845 {
846 LPNMHDR nm = LPNMHDR(l);
847
848 switch (nm->code)
849 {
850 case PSN_SETACTIVE:
851 if (data->client.getName() != "" && data->client.getNumber() !=
852 0)
853 {
854 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
855 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
856 }
857 else
858 {
859 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
860 PSWIZB_DISABLEDFINISH);
861 }
862
863 SetDlgItemText(dialog, IDC_ENTER_NAME,
864 data->client.getName().c_str());
865
866 if (data->client.getNumber() != 0)
867 {
868 SetDlgItemInt(dialog, IDC_ENTER_NUM,
869 data->client.getNumber(), FALSE);
870 }
871 else
872 {
873 SetDlgItemText(dialog, IDC_ENTER_NUM, "");
874 }
875 break;
876 case PSN_WIZBACK:
877 break;
878 case PSN_WIZNEXT:
879 if (debug)
880 {
881 cerr << "client = {\n"
882 << " name = " << data->client.getName() << "\n"
883 << " number = " << data->client.getNumber() << "\n"
884 << " file = " << data->client.getFile() << "\n"
885 << "}\n";
886 }
887
888 data->save = data->saveDir + data->client.getFile();
889
890 if (debug) cerr << "save = " << data->save << "\n";
891
892 break;
893 }
894 }
895 break;
896 case WM_COMMAND:
897 switch (LOWORD(w))
898 {
899 case IDC_ENTER_NAME:
900 {
901 char name[BUFSIZ];
902
903 GetDlgItemText(dialog, IDC_ENTER_NAME, name, BUFSIZ);
904
905 if (name != data->client.getName())
906 {
907 data->client.setName(name);
908 }
909 }
910
911 if (data->client.getName() != "" && data->client.getNumber() != 0)
912 {
913 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
914 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
915 }
916 else
917 {
918 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
919 PSWIZB_DISABLEDFINISH);
920 }
921 break;
922 case IDC_ENTER_NUM:
923 {
924 unsigned number = GetDlgItemInt(dialog, IDC_ENTER_NUM, NULL,
925 FALSE);
926
927 if (number != data->client.getNumber())
928 {
929 data->client.setNumber(number);
930 }
931 }
932
933 if (data->client.getName() != "" && data->client.getNumber() != 0)
934 {
935 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
936 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
937 }
938 else
939 {
940 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
941 PSWIZB_DISABLEDFINISH);
942 }
943 break;
944 }
945 break;
946 }
947
948 return FALSE;
949 }
950
951 INT_PTR ScanUtility::confirm(HWND dialog, UINT msg, WPARAM w, LPARAM l)
952 {
953 ScanUtility* data = which(dialog);
954
955 switch (msg)
956 {
957 case WM_INITDIALOG:
958 data = which(dialog, l);
959
960 {
961 ostringstream confirm;
962
963 confirm << "Confirm the client file\'s name and size.";
964
965 SetDlgItemText(dialog, IDC_CONFIRM_TEXT, confirm.str().c_str());
966 }
967 break;
968 case WM_NOTIFY:
969 {
970 LPNMHDR nm = LPNMHDR(l);
971
972 switch (nm->code)
973 {
974 case PSN_SETACTIVE:
975 CheckDlgButton(dialog, IDC_CONFIRM_GOOD, BST_UNCHECKED);
976 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
977 PSWIZB_DISABLEDFINISH);
978 SetDlgItemText(dialog, IDC_CONFIRM_FILE,
979 data->client.getFile().c_str());
980
981 {
982 HANDLE scan = CreateFile(data->scan.c_str(), GENERIC_READ,
983 FILE_SHARE_READ, NULL, OPEN_EXISTING,
984 FILE_ATTRIBUTE_NORMAL, NULL);
985 DWORD bytes = GetFileSize(scan, NULL);
986
987 CloseHandle(scan);
988
989 ostringstream size;
990
991 size << format(bytes);
992
993 size.setf(ios_base::fixed, ios_base::floatfield);
994 size.precision(2);
995
996 FLOAT megabytes = FLOAT(bytes) / FLOAT(1024 * 1024);
997
998 size << " bytes (" << megabytes << " MB)";
999
1000 SetDlgItemText(dialog, IDC_CONFIRM_SIZE,
1001 size.str().c_str());
1002 }
1003 break;
1004 case PSN_WIZBACK:
1005 break;
1006 case PSN_WIZNEXT:
1007 if (MoveFile(data->scan.c_str(), data->save.c_str()) == 0)
1008 {
1009 do
1010 {
1011 LPVOID message;
1012
1013 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1014 FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
1015 0, LPTSTR(&message), 0, NULL);
1016
1017 int code = MessageBox(dialog, LPCTSTR(message),
1018 data->title.c_str(), MB_RETRYCANCEL |
1019 MB_ICONEXCLAMATION);
1020
1021 LocalFree(message);
1022
1023 if (code == IDCANCEL)
1024 {
1025 PropSheet_PressButton(GetParent(dialog),
1026 PSBTN_BACK);
1027 break;
1028 }
1029 }
1030 while (MoveFileEx(data->scan.c_str(), data->save.c_str(),
1031 MOVEFILE_REPLACE_EXISTING) == 0);
1032 }
1033 break;
1034 }
1035 }
1036 break;
1037 case WM_COMMAND:
1038 switch (LOWORD(w))
1039 {
1040 case IDC_CONFIRM_GOOD:
1041 if (IsDlgButtonChecked(dialog, IDC_CONFIRM_GOOD) == BST_CHECKED)
1042 {
1043 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1044 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
1045 }
1046 else
1047 {
1048 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1049 PSWIZB_DISABLEDFINISH);
1050 }
1051 break;
1052 }
1053 break;
1054 }
1055
1056 return FALSE;
1057 }
1058
1059 INT_PTR ScanUtility::done(HWND dialog, UINT msg, WPARAM w, LPARAM l)
1060 {
1061 ScanUtility* data = which(dialog);
1062
1063 switch (msg)
1064 {
1065 case WM_INITDIALOG:
1066 data = which(dialog, l);
1067
1068 {
1069 ostringstream done;
1070
1071 done << "You are done saving the scanned document. Click Finish to"
1072 << " exit or click Back to return to the beginning.";
1073
1074 SetDlgItemText(dialog, IDC_DONE_TEXT, done.str().c_str());
1075 }
1076 break;
1077 case WM_NOTIFY:
1078 {
1079 LPNMHDR nm = LPNMHDR(l);
1080
1081 switch (nm->code)
1082 {
1083 case PSN_SETACTIVE:
1084 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1085 PSWIZB_FINISH);
1086 break;
1087 case PSN_WIZBACK:
1088 data->client.setFile("");
1089 PropSheet_SetCurSelByID(GetParent(dialog), IDD_START);
1090 break;
1091 case PSN_WIZFINISH:
1092 break;
1093 }
1094 }
1095 break;
1096 }
1097
1098 return FALSE;
1099 }