ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/VTBFileUtil2/ScanUtility.cxx
Revision: 283
Committed: 2003-08-28T21:16:30-07:00 (21 years, 10 months ago) by douglas
File size: 22848 byte(s)
Log Message:
Icons, I like icons!

File Contents

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