ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/VTBFileUtil2/ScanUtility.cxx
Revision: 288
Committed: 2003-09-03T15:58:38-07:00 (21 years, 9 months ago) by douglas
File size: 23219 byte(s)
Log Message:
Ran into some trouble on Windows 95, hopefully its fixed.

File Contents

# Content
1 // Vance Thrift and Biller File Utility 2
2 //
3 // Douglas Thrift
4 //
5 // $Id: ScanUtility.cxx,v 1.14 2003/09/03 22:58:38 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 (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)) 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 else
385 {
386 error(parent);
387 }
388
389 if (scans.empty())
390 {
391 if (MessageBox(parent, "No scanned documents found.",
392 title.c_str(), MB_RETRYCANCEL | MB_ICONQUESTION) == IDCANCEL)
393 break;
394 }
395 }
396 while (scans.empty());
397
398 if (scans.empty())
399 {
400 PropSheet_PressButton(GetParent(parent), PSBTN_BACK);
401 }
402 else
403 {
404 SHFILEINFO info;
405 HIMAGELIST icons = HIMAGELIST(SHGetFileInfo((*scans.begin()).c_str(),
406 0, &info, sizeof(info), SHGFI_SMALLICON | SHGFI_SYSICONINDEX));
407
408 ListView_SetImageList(GetDlgItem(parent, IDC_SELECT_SCANS), icons,
409 LVSIL_SMALL);
410
411 if (debug) cerr << "scans = {\n";
412
413 for (set<string>::iterator itor = scans.begin(); itor != scans.end();
414 itor++)
415 {
416 if (debug) cerr << " " << *itor << "\n";
417
418 char scan[MAX_PATH];
419
420 sprintf(scan, "%s", (*itor).c_str());
421
422 LVITEM item;
423
424 item.mask = LVIF_IMAGE | LVIF_TEXT;
425 item.iItem = 0;
426 item.iSubItem = 0;
427 item.pszText = scan;
428 item.iImage = info.iIcon;
429
430 ListView_InsertItem(GetDlgItem(parent, IDC_SELECT_SCANS), &item);
431 }
432
433 if (debug) cerr << "}\n";
434
435 ListView_SetItemState(GetDlgItem(parent, IDC_SELECT_SCANS), 0,
436 LVIS_SELECTED, LVIS_SELECTED);
437 }
438 }
439
440 ScanUtility* ScanUtility::which(HWND window)
441 {
442 map<HWND, ScanUtility*>::iterator itor = windows.find(window);
443
444 return itor->second;
445 }
446
447 ScanUtility* ScanUtility::which(HWND window, LPARAM l)
448 {
449 LPPROPSHEETPAGE page = LPPROPSHEETPAGE(l);
450 map<unsigned, ScanUtility*>::iterator itor = utilities.find(page->lParam);
451
452 windows.insert(pair<HWND, ScanUtility*>(window, itor->second));
453
454 return itor->second;
455 }
456
457 int ScanUtility::browse(HWND dialog, UINT msg, LPARAM l, LPARAM d)
458 {
459 map<unsigned, ScanUtility*>::iterator itor = utilities.find(LOWORD(d));
460 ScanUtility* data = itor->second;
461
462 switch (msg)
463 {
464 case BFFM_INITIALIZED:
465 center(dialog);
466 SendMessage(dialog, BFFM_SETOKTEXT, 0,
467 LPARAM(toWide("&Select").c_str()));
468 SendMessage(dialog, BFFM_SETEXPANDED, FALSE, CSIDL_DRIVES);
469 SendMessage(dialog, BFFM_SETSELECTION, TRUE, LPARAM(HIWORD(d) ?
470 data->scanDir.c_str() : data->saveDir.c_str()));
471 break;
472 case BFFM_SELCHANGED:
473 {
474 SHFILEINFO info;
475
476 SHGetFileInfo(LPCSTR(l), 0, &info, sizeof(info), SHGFI_DISPLAYNAME
477 | SHGFI_PIDL);
478 SendMessage(dialog, BFFM_SETSTATUSTEXT, 0,
479 LPARAM(info.szDisplayName));
480
481 char folder[MAX_PATH];
482
483 if (!SHGetPathFromIDList(LPCITEMIDLIST(l), folder))
484 {
485 SendMessage(dialog, BFFM_ENABLEOK, 0, 0);
486 }
487 else
488 {
489 SendMessage(dialog, BFFM_SETSTATUSTEXT, 0, LPARAM(folder));
490 }
491 }
492 break;
493 }
494
495 return 0;
496 }
497
498 INT_PTR ScanUtility::start(HWND dialog, UINT msg, WPARAM w, LPARAM l)
499 {
500 ScanUtility* data = which(dialog);
501
502 switch (msg)
503 {
504 case WM_INITDIALOG:
505 center(GetParent(dialog));
506 SendMessage(GetParent(dialog), WM_SETICON, ICON_BIG, LPARAM(gui.icon));
507
508 data = which(dialog, l);
509
510 {
511 ostringstream instructions;
512
513 instructions << "1. If you need instructions, you should not be ru"
514 << "nning this program in Scan Utility mode.\n"
515 << "2. Otherwise, go forth and scan.\n"
516 << "3. Then come back and click Next.\n";
517
518 SetDlgItemText(dialog, IDC_START_INSTRUCTIONS,
519 instructions.str().c_str());
520 }
521 break;
522 case WM_NOTIFY:
523 {
524 LPNMHDR nm = LPNMHDR(l);
525
526 switch (nm->code)
527 {
528 case PSN_SETACTIVE:
529 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_FINISH |
530 PSWIZB_NEXT);
531
532 {
533 SHFILEINFO info;
534
535 SHGetFileInfo(data->scanDir.c_str(), 0, &info,
536 sizeof(info), SHGFI_ICONLOCATION);
537
538 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
539 info.iIcon);
540
541 SendDlgItemMessage(dialog, IDC_START_SCAN_ICON,
542 STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
543 SHGetFileInfo(data->saveDir.c_str(), 0, &info,
544 sizeof(info), SHGFI_ICONLOCATION);
545
546 icon = ExtractIcon(gui.instance, info.szDisplayName,
547 info.iIcon);
548
549 SendDlgItemMessage(dialog, IDC_START_SAVE_ICON,
550 STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
551 }
552
553 {
554 char folder[38];
555
556 PathCompactPathEx(folder, data->scanDir.substr(0,
557 data->scanDir.length() - 1).c_str(), 38, 0);
558 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
559 PathCompactPathEx(folder, data->saveDir.substr(0,
560 data->saveDir.length() - 1).c_str(), 38, 0);
561 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
562 }
563 break;
564 case PSN_WIZNEXT:
565 SetCurrentDirectory(data->scanDir.c_str());
566 break;
567 }
568 }
569 break;
570 case WM_COMMAND:
571 switch (LOWORD(w))
572 {
573 case IDC_START_SCAN_BROWSE:
574 data->setScanDir(dialog);
575
576 {
577 SHFILEINFO info;
578
579 SHGetFileInfo(data->scanDir.c_str(), 0, &info, sizeof(info),
580 SHGFI_ICONLOCATION);
581
582 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
583 info.iIcon);
584
585 SendDlgItemMessage(dialog, IDC_START_SCAN_ICON, STM_SETIMAGE,
586 IMAGE_ICON, LPARAM(icon));
587 }
588
589 {
590 char folder[38];
591
592 PathCompactPathEx(folder, data->scanDir.substr(0,
593 data->scanDir.length() - 1).c_str(), 38, 0);
594 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
595 }
596 break;
597 case IDC_START_SAVE_BROWSE:
598 data->setSaveDir(dialog);
599
600 {
601 SHFILEINFO info;
602
603 SHGetFileInfo(data->saveDir.c_str(), 0, &info, sizeof(info),
604 SHGFI_ICONLOCATION);
605
606 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
607 info.iIcon);
608
609 SendDlgItemMessage(dialog, IDC_START_SAVE_ICON, STM_SETIMAGE,
610 IMAGE_ICON, LPARAM(icon));
611 }
612
613 {
614 char folder[38];
615
616 PathCompactPathEx(folder, data->saveDir.substr(0,
617 data->saveDir.length() - 1).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 if (ni->iItem != -1)
666 {
667 char scan[MAX_PATH];
668
669 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
670 ni->iItem, 0, scan, MAX_PATH);
671 ShellExecute(dialog, NULL, scan, NULL, NULL,
672 SW_SHOWDEFAULT);
673 }
674 break;
675 }
676 }
677 else
678 {
679 LPNMHDR nm = LPNMHDR(l);
680
681 switch (nm->code)
682 {
683 case PSN_SETACTIVE:
684 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
685 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
686 data->populate(dialog);
687 break;
688 case PSN_WIZBACK:
689 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
690 data->client.setFile("");
691 break;
692 case PSN_WIZNEXT:
693 {
694 int index = ListView_GetNextItem(GetDlgItem(dialog,
695 IDC_SELECT_SCANS), -1, LVNI_SELECTED);
696 char scan[MAX_PATH];
697
698 if (index != -1)
699 {
700 ListView_GetItemText(GetDlgItem(dialog,
701 IDC_SELECT_SCANS), index, 0, scan, MAX_PATH);
702 }
703 else
704 {
705 ListView_GetItemText(GetDlgItem(dialog,
706 IDC_SELECT_SCANS), 0, 0, scan, MAX_PATH);
707 }
708
709 data->scan = scan;
710 }
711
712 if (debug) cerr << "scan = " << data->scan << "\n";
713
714 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
715 break;
716 }
717 }
718 break;
719 case WM_CONTEXTMENU:
720 if (ListView_GetNextItem(GetDlgItem(dialog, IDC_SELECT_SCANS), -1,
721 LVNI_SELECTED) != -1)
722 {
723 char scan[MAX_PATH];
724 POINT spot;
725 LVHITTESTINFO test;
726
727 test.pt.x = GET_X_LPARAM(l);
728 test.pt.y = GET_Y_LPARAM(l);
729
730 ScreenToClient(GetDlgItem(dialog, IDC_SELECT_SCANS), &test.pt);
731 ListView_HitTest(GetDlgItem(dialog, IDC_SELECT_SCANS), &test);
732
733 if (test.iItem != -1)
734 {
735 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
736 test.iItem, 0, scan, MAX_PATH);
737
738 spot.x = test.pt.x;
739 spot.y = test.pt.y;
740 }
741 else if (GET_X_LPARAM(l) == -1 && GET_Y_LPARAM(l) == -1)
742 {
743 int index = ListView_GetNextItem(GetDlgItem(dialog,
744 IDC_SELECT_SCANS), -1, LVNI_SELECTED);
745 RECT rect;
746
747 ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
748 index, 0, scan, MAX_PATH);
749 ListView_EnsureVisible(GetDlgItem(dialog, IDC_SELECT_SCANS),
750 index, FALSE);
751 ListView_GetItemRect(GetDlgItem(dialog, IDC_SELECT_SCANS),
752 index, &rect, LVIR_SELECTBOUNDS);
753
754 spot.x = rect.left;
755 spot.y = rect.top;
756 }
757
758 ClientToScreen(GetDlgItem(dialog, IDC_SELECT_SCANS), &spot);
759
760 int code = TrackPopupMenuEx(data->popup, TPM_LEFTALIGN |
761 TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_RIGHTBUTTON,
762 spot.x, spot.y, GetDlgItem(dialog, IDC_SELECT_SCANS), NULL);
763
764 switch (code)
765 {
766 case 1:
767 ShellExecute(dialog, NULL, scan, NULL, NULL, SW_SHOWDEFAULT);
768 break;
769 case 2:
770 {
771 SHELLEXECUTEINFO info;
772
773 info.cbSize = sizeof(info);
774 info.fMask = SEE_MASK_INVOKEIDLIST;
775 info.hwnd = dialog;
776 info.lpVerb = "properties";
777 info.lpFile = scan;
778 info.lpParameters = NULL;
779 info.lpDirectory = NULL;
780 info.nShow = SW_SHOWDEFAULT;
781 info.lpIDList = NULL;
782
783 ShellExecuteEx(&info);
784 }
785 break;
786 }
787 }
788 break;
789 }
790
791 return FALSE;
792 }
793
794 INT_PTR ScanUtility::enter(HWND dialog, UINT msg, WPARAM w, LPARAM l)
795 {
796 ScanUtility* data = which(dialog);
797
798 switch (msg)
799 {
800 case WM_INITDIALOG:
801 data = which(dialog, l);
802
803 {
804 ostringstream enter;
805
806 enter << "Enter the client name and number.";
807
808 SetDlgItemText(dialog, IDC_ENTER_TEXT, enter.str().c_str());
809 }
810 break;
811 case WM_NOTIFY:
812 {
813 LPNMHDR nm = LPNMHDR(l);
814
815 switch (nm->code)
816 {
817 case PSN_SETACTIVE:
818 if (data->client.getName() != "" && data->client.getNumber() !=
819 0)
820 {
821 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
822 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
823 }
824 else
825 {
826 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
827 PSWIZB_DISABLEDFINISH);
828 }
829
830 SetDlgItemText(dialog, IDC_ENTER_NAME,
831 data->client.getName().c_str());
832
833 if (data->client.getNumber() != 0)
834 {
835 SetDlgItemInt(dialog, IDC_ENTER_NUM,
836 data->client.getNumber(), FALSE);
837 }
838 else
839 {
840 SetDlgItemText(dialog, IDC_ENTER_NUM, "");
841 }
842 break;
843 case PSN_WIZBACK:
844 break;
845 case PSN_WIZNEXT:
846 if (debug)
847 {
848 cerr << "client = {\n"
849 << " name = " << data->client.getName() << "\n"
850 << " number = " << data->client.getNumber() << "\n"
851 << " file = " << data->client.getFile() << "\n"
852 << "}\n";
853 }
854
855 data->save = data->saveDir + '\\' + data->client.getFile();
856
857 if (debug) cerr << "save = " << data->save << "\n";
858
859 break;
860 }
861 }
862 break;
863 case WM_COMMAND:
864 switch (LOWORD(w))
865 {
866 case IDC_ENTER_NAME:
867 {
868 char name[BUFSIZ];
869
870 GetDlgItemText(dialog, IDC_ENTER_NAME, name, BUFSIZ);
871
872 if (name != data->client.getName())
873 {
874 data->client.setName(name);
875 }
876 }
877
878 if (data->client.getName() != "" && data->client.getNumber() != 0)
879 {
880 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
881 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
882 }
883 else
884 {
885 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
886 PSWIZB_DISABLEDFINISH);
887 }
888 break;
889 case IDC_ENTER_NUM:
890 {
891 unsigned number = GetDlgItemInt(dialog, IDC_ENTER_NUM, NULL,
892 FALSE);
893
894 if (number != data->client.getNumber())
895 {
896 data->client.setNumber(number);
897 }
898 }
899
900 if (data->client.getName() != "" && data->client.getNumber() != 0)
901 {
902 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
903 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
904 }
905 else
906 {
907 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
908 PSWIZB_DISABLEDFINISH);
909 }
910 break;
911 }
912 break;
913 }
914
915 return FALSE;
916 }
917
918 INT_PTR ScanUtility::confirm(HWND dialog, UINT msg, WPARAM w, LPARAM l)
919 {
920 ScanUtility* data = which(dialog);
921
922 switch (msg)
923 {
924 case WM_INITDIALOG:
925 data = which(dialog, l);
926
927 {
928 ostringstream confirm;
929
930 confirm << "Confirm the client file\'s name and size.";
931
932 SetDlgItemText(dialog, IDC_CONFIRM_TEXT, confirm.str().c_str());
933 }
934 break;
935 case WM_NOTIFY:
936 {
937 LPNMHDR nm = LPNMHDR(l);
938
939 switch (nm->code)
940 {
941 case PSN_SETACTIVE:
942 CheckDlgButton(dialog, IDC_CONFIRM_GOOD, BST_UNCHECKED);
943 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
944 PSWIZB_DISABLEDFINISH);
945 SetDlgItemText(dialog, IDC_CONFIRM_FILE,
946 data->client.getFile().c_str());
947
948 {
949 HANDLE scan = CreateFile(data->scan.c_str(), GENERIC_READ,
950 FILE_SHARE_READ, NULL, OPEN_EXISTING,
951 FILE_ATTRIBUTE_NORMAL, NULL);
952 DWORD bytes = GetFileSize(scan, NULL);
953
954 CloseHandle(scan);
955
956 ostringstream size;
957
958 size << format(bytes);
959
960 size.setf(ios_base::fixed, ios_base::floatfield);
961 size.precision(2);
962
963 FLOAT megabytes = FLOAT(bytes) / FLOAT(1024 * 1024);
964
965 size << " bytes (" << megabytes << " MB)";
966
967 SetDlgItemText(dialog, IDC_CONFIRM_SIZE,
968 size.str().c_str());
969 }
970 break;
971 case PSN_WIZBACK:
972 break;
973 case PSN_WIZNEXT:
974 if (MoveFile(data->scan.c_str(), data->save.c_str()) == 0)
975 {
976 do
977 {
978 LPVOID message;
979
980 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
981 FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
982 0, LPTSTR(&message), 0, NULL);
983
984 int code = MessageBox(dialog, LPCTSTR(message),
985 data->title.c_str(), MB_RETRYCANCEL |
986 MB_ICONEXCLAMATION);
987
988 LocalFree(message);
989
990 if (code == IDCANCEL)
991 {
992 PropSheet_PressButton(GetParent(dialog),
993 PSBTN_BACK);
994 break;
995 }
996 }
997 while (MoveFileEx(data->scan.c_str(), data->save.c_str(),
998 MOVEFILE_REPLACE_EXISTING) == 0);
999 }
1000 break;
1001 }
1002 }
1003 break;
1004 case WM_COMMAND:
1005 switch (LOWORD(w))
1006 {
1007 case IDC_CONFIRM_GOOD:
1008 if (IsDlgButtonChecked(dialog, IDC_CONFIRM_GOOD) == BST_CHECKED)
1009 {
1010 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1011 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
1012 }
1013 else
1014 {
1015 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1016 PSWIZB_DISABLEDFINISH);
1017 }
1018 break;
1019 }
1020 break;
1021 }
1022
1023 return FALSE;
1024 }
1025
1026 INT_PTR ScanUtility::done(HWND dialog, UINT msg, WPARAM w, LPARAM l)
1027 {
1028 ScanUtility* data = which(dialog);
1029
1030 switch (msg)
1031 {
1032 case WM_INITDIALOG:
1033 data = which(dialog, l);
1034
1035 {
1036 ostringstream done;
1037
1038 done << "You are done saving the scanned document. Click Finish to"
1039 << " exit or click Back to return to the beginning.";
1040
1041 SetDlgItemText(dialog, IDC_DONE_TEXT, done.str().c_str());
1042 }
1043 break;
1044 case WM_NOTIFY:
1045 {
1046 LPNMHDR nm = LPNMHDR(l);
1047
1048 switch (nm->code)
1049 {
1050 case PSN_SETACTIVE:
1051 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
1052 PSWIZB_FINISH);
1053 break;
1054 case PSN_WIZBACK:
1055 data->client.setFile("");
1056 PropSheet_SetCurSelByID(GetParent(dialog), IDD_START);
1057 break;
1058 case PSN_WIZFINISH:
1059 break;
1060 }
1061 }
1062 break;
1063 }
1064
1065 return FALSE;
1066 }