ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/VTBFileUtil2/ScanUtility.cxx
Revision: 278
Committed: 2003-08-25T00:29:00-07:00 (21 years, 10 months ago) by douglas
File size: 22353 byte(s)
Log Message:
Almost finished with Scan Utility.

File Contents

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