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

# User Rev Content
1 douglas 260 // Vance Thrift and Biller File Utility 2
2     //
3     // Douglas Thrift
4     //
5 douglas 292 // $Id: ScanUtility.cxx,v 1.17 2003/09/09 01:43:28 douglas Exp $
6 douglas 260
7     #include "ScanUtility.h"
8 douglas 265
9 douglas 282 ScanUtility::ScanUtility() : DiscBrowse()
10 douglas 268 {
11     number = count++;
12 douglas 282
13 douglas 268 utilities.insert(pair<unsigned, ScanUtility*>(number, this));
14    
15 douglas 282 title = programName + " - Scan Utility";
16 douglas 274
17 douglas 268 // start
18 douglas 271 wizard[0].dwSize = sizeof(wizard[0]);
19 douglas 282 wizard[0].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
20     PSP_USEHEADERSUBTITLE;
21 douglas 271 wizard[0].hInstance = gui.instance;
22     wizard[0].pszTemplate = MAKEINTRESOURCE(IDD_START);
23 douglas 282 wizard[0].pszTitle = title.c_str();
24 douglas 271 wizard[0].pfnDlgProc = start;
25     wizard[0].lParam = number;
26     wizard[0].pszHeaderTitle = "Start";
27     wizard[0].pszHeaderSubTitle = "Change any settings before scanning.";
28 douglas 273
29     // select
30     wizard[1].dwSize = sizeof(wizard[1]);
31 douglas 282 wizard[1].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
32     PSP_USEHEADERSUBTITLE;
33 douglas 273 wizard[1].hInstance = gui.instance;
34     wizard[1].pszTemplate = MAKEINTRESOURCE(IDD_SELECT);
35 douglas 282 wizard[1].pszTitle = title.c_str();
36 douglas 273 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 douglas 274
41     // enter
42     wizard[2].dwSize = sizeof(wizard[2]);
43 douglas 282 wizard[2].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
44     PSP_USEHEADERSUBTITLE;
45 douglas 274 wizard[2].hInstance = gui.instance;
46     wizard[2].pszTemplate = MAKEINTRESOURCE(IDD_ENTER);
47 douglas 282 wizard[2].pszTitle = title.c_str();
48 douglas 274 wizard[2].pfnDlgProc = enter;
49 douglas 277 wizard[2].lParam = number;
50 douglas 274 wizard[2].pszHeaderTitle = "Enter";
51     wizard[2].pszHeaderSubTitle = "Input the client information.";
52 douglas 278
53     // confirm
54     wizard[3].dwSize = sizeof(wizard[3]);
55 douglas 282 wizard[3].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
56     PSP_USEHEADERSUBTITLE;
57 douglas 278 wizard[3].hInstance = gui.instance;
58     wizard[3].pszTemplate = MAKEINTRESOURCE(IDD_CONFIRM);
59 douglas 282 wizard[3].pszTitle = title.c_str();
60 douglas 278 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 douglas 282 wizard[4].dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE |
68     PSP_USEHEADERSUBTITLE;
69 douglas 278 wizard[4].hInstance = gui.instance;
70     wizard[4].pszTemplate = MAKEINTRESOURCE(IDD_DONE);
71 douglas 282 wizard[4].pszTitle = title.c_str();
72 douglas 278 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 douglas 268 }
77    
78     ScanUtility::~ScanUtility()
79     {
80     utilities.erase(number);
81     }
82    
83 douglas 265 void ScanUtility::run(void)
84     {
85 douglas 282 loadDirs();
86    
87 douglas 268 PROPSHEETHEADER header;
88 douglas 265
89 douglas 268 // header
90     header.dwSize = sizeof(header);
91 douglas 271 header.dwFlags = PSH_DEFAULT | PSH_HEADER | PSH_PROPSHEETPAGE |
92 douglas 278 PSH_USEICONID | PSH_WIZARD97 | PSH_WIZARDHASFINISH;
93 douglas 268 header.hwndParent = NULL;
94     header.hInstance = gui.instance;
95     header.pszIcon = MAKEINTRESOURCE(IDI_VTB_ICON);
96 douglas 278 header.nPages = 5;
97 douglas 268 header.nStartPage = 0;
98 douglas 271 header.ppsp = wizard;
99 douglas 269 header.pszbmHeader = MAKEINTRESOURCE(IDB_VTB_BMP);
100 douglas 265
101 douglas 268 PropertySheet(&header);
102 douglas 282 saveDirs();
103 douglas 268 }
104    
105     map<unsigned, ScanUtility*> ScanUtility::utilities;
106     map<HWND, ScanUtility*> ScanUtility::windows;
107    
108 douglas 269 void ScanUtility::loadDirs(void)
109     {
110     HKEY key;
111    
112     if (RegOpenKeyEx(HKEY_CURRENT_USER,
113 douglas 271 "Software\\DouglasThrift\\VTBFileUtil2", 0, KEY_QUERY_VALUE, &key) ==
114 douglas 269 ERROR_SUCCESS)
115     {
116     DWORD type;
117 douglas 271 char data[MAX_PATH];
118 douglas 269 DWORD size = MAX_PATH;
119    
120 douglas 271 if (RegQueryValueEx(key, "ScanDir", NULL, &type, LPBYTE(data), &size)
121     == ERROR_SUCCESS)
122 douglas 269 {
123     data[size - 1] = '\0';
124    
125     switch (type)
126     {
127     case REG_EXPAND_SZ:
128 douglas 273 {
129     char folder[MAX_PATH];
130    
131     ExpandEnvironmentStrings(data, folder, MAX_PATH);
132    
133 douglas 288 scanDir = tail(folder);
134 douglas 273 }
135 douglas 269 break;
136     case REG_SZ:
137 douglas 288 scanDir = tail(data);
138 douglas 269 break;
139     default:
140     setScanDir();
141     break;
142     }
143     }
144     else
145     {
146     setScanDir();
147     }
148    
149     size = MAX_PATH;
150    
151 douglas 271 if (RegQueryValueEx(key, "SaveDir", NULL, &type, LPBYTE(data), &size)
152     == ERROR_SUCCESS)
153 douglas 269 {
154     data[size - 1] = '\0';
155    
156     switch (type)
157     {
158     case REG_EXPAND_SZ:
159 douglas 273 {
160     char folder[MAX_PATH];
161    
162     ExpandEnvironmentStrings(data, folder, MAX_PATH);
163    
164 douglas 288 saveDir = tail(folder);
165 douglas 273 }
166 douglas 269 break;
167     case REG_SZ:
168 douglas 288 saveDir = tail(data);
169 douglas 269 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 douglas 271
188     if (debug) cerr << "scanDir = " << scanDir << "\n"
189 douglas 273 << "saveDir = " << saveDir << "\n";
190 douglas 269 }
191    
192     void ScanUtility::saveDirs(void)
193     {
194     HKEY key;
195    
196 douglas 291 if (LONG code = RegCreateKeyEx(HKEY_CURRENT_USER,
197 douglas 269 "Software\\DouglasThrift\\VTBFileUtil2", 0, NULL,
198 douglas 271 REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &key,
199     NULL) == ERROR_SUCCESS)
200 douglas 269 {
201 douglas 271 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 douglas 269 {
208 douglas 271 data[size - 1] = '\0';
209 douglas 269 }
210 douglas 271 else
211     {
212     data[0] = '\0';
213     }
214 douglas 269
215 douglas 273 if (scanDir != data || type != REG_SZ)
216 douglas 269 {
217 douglas 273 if (RegSetValueEx(key, "ScanDir", 0, REG_SZ,
218     LPBYTE(scanDir.c_str()), scanDir.length() + 1) !=
219 douglas 271 ERROR_SUCCESS)
220     {
221 douglas 291 error(NULL, code);
222 douglas 271 }
223 douglas 269 }
224    
225 douglas 271 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 douglas 273 if (saveDir != data || type != REG_SZ)
238 douglas 271 {
239 douglas 273 if (RegSetValueEx(key, "SaveDir", 0, REG_SZ,
240     LPBYTE(saveDir.c_str()), saveDir.length() + 1) !=
241 douglas 271 ERROR_SUCCESS)
242     {
243 douglas 291 error(NULL, code);
244 douglas 271 }
245     }
246    
247 douglas 269 RegCloseKey(key);
248     }
249     else
250     {
251 douglas 291 error(NULL, code);
252 douglas 269 }
253     }
254    
255     void ScanUtility::setScanDir(HWND parent)
256     {
257 douglas 292 char buffer[MAX_PATH];
258    
259     SHGetFolderPath(parent, CSIDL_FLAG_CREATE | CSIDL_DESKTOPDIRECTORY, NULL,
260     0, buffer);
261    
262 douglas 271 BROWSEINFO info;
263 douglas 269
264 douglas 271 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 douglas 288 if (SHGetPathFromIDList(id, folder)) scanDir = tail(folder);
282 douglas 271 }
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 douglas 282 title.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
294 douglas 271 {
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 douglas 273
311     if (debug) cerr << "scanDir = " << scanDir << "\n";
312 douglas 269 }
313    
314     void ScanUtility::setSaveDir(HWND parent)
315     {
316 douglas 292 char buffer[MAX_PATH];
317    
318     SHGetFolderPath(parent, CSIDL_FLAG_CREATE | CSIDL_DESKTOPDIRECTORY, NULL,
319     0, buffer);
320    
321 douglas 271 BROWSEINFO info;
322 douglas 269
323 douglas 271 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 douglas 288 if (SHGetPathFromIDList(id, folder)) saveDir = tail(folder);
341 douglas 271 }
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 douglas 282 title.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
353 douglas 271 {
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 douglas 273
370     if (debug) cerr << "saveDir = " << saveDir << "\n";
371 douglas 269 }
372    
373 douglas 273 void ScanUtility::populate(HWND parent)
374     {
375     set<string> scans;
376    
377     do
378     {
379 douglas 288 string scan = scanDir + "SCAN????_000." +
380 douglas 273 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 douglas 282 title.c_str(), MB_RETRYCANCEL | MB_ICONQUESTION) == IDCANCEL)
399     break;
400 douglas 273 }
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 douglas 274 item.iItem = 0;
432 douglas 273 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 douglas 274
441     ListView_SetItemState(GetDlgItem(parent, IDC_SELECT_SCANS), 0,
442     LVIS_SELECTED, LVIS_SELECTED);
443 douglas 273 }
444     }
445    
446 douglas 277 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 douglas 271 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 douglas 290
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 douglas 271 break;
505     case BFFM_SELCHANGED:
506     {
507 douglas 284 SHFILEINFO info;
508 douglas 271
509 douglas 284 SHGetFileInfo(LPCSTR(l), 0, &info, sizeof(info), SHGFI_DISPLAYNAME
510     | SHGFI_PIDL);
511     SendMessage(dialog, BFFM_SETSTATUSTEXT, 0,
512     LPARAM(info.szDisplayName));
513 douglas 271
514 douglas 284 char folder[MAX_PATH];
515 douglas 271
516 douglas 284 if (!SHGetPathFromIDList(LPCITEMIDLIST(l), folder))
517 douglas 271 {
518     SendMessage(dialog, BFFM_ENABLEOK, 0, 0);
519     }
520 douglas 284 else
521     {
522     SendMessage(dialog, BFFM_SETSTATUSTEXT, 0, LPARAM(folder));
523     }
524 douglas 271 }
525     break;
526     }
527    
528     return 0;
529     }
530    
531 douglas 268 INT_PTR ScanUtility::start(HWND dialog, UINT msg, WPARAM w, LPARAM l)
532     {
533 douglas 277 ScanUtility* data = which(dialog);
534 douglas 268
535     switch (msg)
536 douglas 265 {
537 douglas 268 case WM_INITDIALOG:
538 douglas 269 center(GetParent(dialog));
539 douglas 274 SendMessage(GetParent(dialog), WM_SETICON, ICON_BIG, LPARAM(gui.icon));
540 douglas 277
541     data = which(dialog, l);
542 douglas 265
543 douglas 273 {
544     ostringstream instructions;
545    
546 douglas 274 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 douglas 273
551     SetDlgItemText(dialog, IDC_START_INSTRUCTIONS,
552     instructions.str().c_str());
553     }
554 douglas 268 break;
555 douglas 269 case WM_NOTIFY:
556     {
557 douglas 273 LPNMHDR nm = LPNMHDR(l);
558 douglas 269
559     switch (nm->code)
560     {
561     case PSN_SETACTIVE:
562 douglas 278 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_FINISH |
563     PSWIZB_NEXT);
564    
565 douglas 271 {
566 douglas 283 SHFILEINFO info;
567 douglas 271
568 douglas 283 SHGetFileInfo(data->scanDir.c_str(), 0, &info,
569     sizeof(info), SHGFI_ICONLOCATION);
570    
571 douglas 284 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
572     info.iIcon);
573 douglas 283
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 douglas 284 icon = ExtractIcon(gui.instance, info.szDisplayName,
580     info.iIcon);
581 douglas 283
582     SendDlgItemMessage(dialog, IDC_START_SAVE_ICON,
583     STM_SETIMAGE, IMAGE_ICON, LPARAM(icon));
584     }
585    
586     {
587     char folder[38];
588    
589 douglas 288 PathCompactPathEx(folder, data->scanDir.substr(0,
590     data->scanDir.length() - 1).c_str(), 38, 0);
591 douglas 271 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
592 douglas 288 PathCompactPathEx(folder, data->saveDir.substr(0,
593     data->saveDir.length() - 1).c_str(), 38, 0);
594 douglas 271 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
595     }
596 douglas 269 break;
597 douglas 273 case PSN_WIZNEXT:
598     SetCurrentDirectory(data->scanDir.c_str());
599     break;
600 douglas 269 }
601     }
602     break;
603 douglas 271 case WM_COMMAND:
604     switch (LOWORD(w))
605     {
606     case IDC_START_SCAN_BROWSE:
607     data->setScanDir(dialog);
608 douglas 283
609 douglas 271 {
610 douglas 283 SHFILEINFO info;
611 douglas 271
612 douglas 283 SHGetFileInfo(data->scanDir.c_str(), 0, &info, sizeof(info),
613     SHGFI_ICONLOCATION);
614    
615 douglas 284 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
616     info.iIcon);
617 douglas 283
618     SendDlgItemMessage(dialog, IDC_START_SCAN_ICON, STM_SETIMAGE,
619     IMAGE_ICON, LPARAM(icon));
620     }
621    
622     {
623     char folder[38];
624    
625 douglas 288 PathCompactPathEx(folder, data->scanDir.substr(0,
626     data->scanDir.length() - 1).c_str(), 38, 0);
627 douglas 271 SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
628     }
629     break;
630     case IDC_START_SAVE_BROWSE:
631     data->setSaveDir(dialog);
632 douglas 283
633 douglas 271 {
634 douglas 283 SHFILEINFO info;
635 douglas 271
636 douglas 283 SHGetFileInfo(data->saveDir.c_str(), 0, &info, sizeof(info),
637     SHGFI_ICONLOCATION);
638    
639 douglas 284 HICON icon = ExtractIcon(gui.instance, info.szDisplayName,
640     info.iIcon);
641 douglas 283
642     SendDlgItemMessage(dialog, IDC_START_SAVE_ICON, STM_SETIMAGE,
643     IMAGE_ICON, LPARAM(icon));
644     }
645    
646     {
647     char folder[38];
648    
649 douglas 288 PathCompactPathEx(folder, data->saveDir.substr(0,
650     data->saveDir.length() - 1).c_str(), 38, 0);
651 douglas 271 SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
652     }
653     break;
654     }
655     break;
656 douglas 268 }
657 douglas 265
658 douglas 268 return FALSE;
659 douglas 265 }
660 douglas 273
661     INT_PTR ScanUtility::select(HWND dialog, UINT msg, WPARAM w, LPARAM l)
662     {
663 douglas 277 ScanUtility* data = which(dialog);
664 douglas 273
665     switch (msg)
666     {
667     case WM_INITDIALOG:
668 douglas 277 data = which(dialog, l);
669 douglas 273
670     {
671 douglas 274 ostringstream select;
672    
673 douglas 282 select << "Select the scanned document that you need to save.";
674 douglas 274
675     SetDlgItemText(dialog, IDC_SELECT_TEXT, select.str().c_str());
676     }
677 douglas 277
678 douglas 274 {
679 douglas 273 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 douglas 274 LPNMITEMACTIVATE ni = LPNMITEMACTIVATE(l);
694    
695     switch (ni->hdr.code)
696 douglas 273 {
697 douglas 274 case NM_DBLCLK:
698 douglas 284 if (ni->iItem != -1)
699 douglas 274 {
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 douglas 273 break;
708     }
709     }
710     else
711     {
712     LPNMHDR nm = LPNMHDR(l);
713    
714     switch (nm->code)
715     {
716     case PSN_SETACTIVE:
717 douglas 274 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
718 douglas 278 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
719 douglas 273 data->populate(dialog);
720     break;
721     case PSN_WIZBACK:
722     ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
723 douglas 277 data->client.setFile("");
724 douglas 273 break;
725     case PSN_WIZNEXT:
726 douglas 274 {
727     int index = ListView_GetNextItem(GetDlgItem(dialog,
728     IDC_SELECT_SCANS), -1, LVNI_SELECTED);
729     char scan[MAX_PATH];
730    
731 douglas 284 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 douglas 274
742     data->scan = scan;
743     }
744 douglas 277
745 douglas 284 if (debug) cerr << "scan = " << data->scan << "\n";
746    
747 douglas 273 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
748     break;
749     }
750     }
751     break;
752 douglas 277 case WM_CONTEXTMENU:
753 douglas 284 if (ListView_GetNextItem(GetDlgItem(dialog, IDC_SELECT_SCANS), -1,
754     LVNI_SELECTED) != -1)
755 douglas 277 {
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 douglas 273 break;
822     }
823    
824     return FALSE;
825     }
826 douglas 274
827     INT_PTR ScanUtility::enter(HWND dialog, UINT msg, WPARAM w, LPARAM l)
828     {
829 douglas 277 ScanUtility* data = which(dialog);
830    
831     switch (msg)
832     {
833     case WM_INITDIALOG:
834     data = which(dialog, l);
835 douglas 278
836 douglas 277 {
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 douglas 278 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
856 douglas 277 }
857     else
858     {
859 douglas 278 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
860     PSWIZB_DISABLEDFINISH);
861 douglas 277 }
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 douglas 278 << " file = " << data->client.getFile() << "\n"
885 douglas 277 << "}\n";
886     }
887 douglas 278
888 douglas 292 data->save = data->saveDir + data->client.getFile();
889 douglas 278
890     if (debug) cerr << "save = " << data->save << "\n";
891    
892 douglas 277 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 douglas 278 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
915 douglas 277 }
916     else
917     {
918 douglas 278 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
919     PSWIZB_DISABLEDFINISH);
920 douglas 277 }
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 douglas 278 PSWIZB_DISABLEDFINISH | PSWIZB_NEXT);
937 douglas 277 }
938     else
939     {
940 douglas 278 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
941     PSWIZB_DISABLEDFINISH);
942 douglas 277 }
943     break;
944     }
945     break;
946     }
947    
948 douglas 274 return FALSE;
949     }
950 douglas 278
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 douglas 282 FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
1015     0, LPTSTR(&message), 0, NULL);
1016 douglas 278
1017     int code = MessageBox(dialog, LPCTSTR(message),
1018 douglas 282 data->title.c_str(), MB_RETRYCANCEL |
1019 douglas 278 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 douglas 281
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 douglas 278 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     }