ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/VTBFileUtil2/ScanUtility.cxx
Revision: 274
Committed: 2003-08-21T23:30:14-07:00 (21 years, 10 months ago) by douglas
File size: 14155 byte(s)
Log Message:
That's the stuff. Ah.

File Contents

# User Rev Content
1 douglas 260 // Vance Thrift and Biller File Utility 2
2     //
3     // Douglas Thrift
4     //
5 douglas 274 // $Id: ScanUtility.cxx,v 1.7 2003/08/22 06:30:14 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     menu = LoadMenu(gui.instance, MAKEINTRESOURCE(IDR_SELECT));
19     popup = GetSubMenu(menu, 0);
20 douglas 268
21     // start
22 douglas 271 wizard[0].dwSize = sizeof(wizard[0]);
23     wizard[0].dwFlags = PSP_DEFAULT | PSP_USEHICON | PSP_USETITLE |
24 douglas 268 PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
25 douglas 271 wizard[0].hInstance = gui.instance;
26     wizard[0].pszTemplate = MAKEINTRESOURCE(IDD_START);
27     wizard[0].hIcon = gui.icon;
28     wizard[0].pszTitle = title;
29     wizard[0].pfnDlgProc = start;
30     wizard[0].lParam = number;
31     wizard[0].pszHeaderTitle = "Start";
32     wizard[0].pszHeaderSubTitle = "Change any settings before scanning.";
33 douglas 273
34     // select
35     wizard[1].dwSize = sizeof(wizard[1]);
36     wizard[1].dwFlags = PSP_DEFAULT | PSP_USEHICON | PSP_USETITLE |
37     PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
38     wizard[1].hInstance = gui.instance;
39     wizard[1].pszTemplate = MAKEINTRESOURCE(IDD_SELECT);
40     wizard[1].hIcon = gui.icon;
41     wizard[1].pszTitle = title;
42     wizard[1].pfnDlgProc = select;
43     wizard[1].lParam = number;
44     wizard[1].pszHeaderTitle = "Select";
45     wizard[1].pszHeaderSubTitle = "Choose the scanned document to save.";
46 douglas 274
47     // enter
48     wizard[2].dwSize = sizeof(wizard[2]);
49     wizard[2].dwFlags = PSP_DEFAULT | PSP_USEHICON | PSP_USETITLE |
50     PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
51     wizard[2].hInstance = gui.instance;
52     wizard[2].pszTemplate = MAKEINTRESOURCE(IDD_ENTER);
53     wizard[2].hIcon = gui.icon;
54     wizard[2].pszTitle = title;
55     wizard[2].pfnDlgProc = enter;
56     wizard[2].pszHeaderTitle = "Enter";
57     wizard[2].pszHeaderSubTitle = "Input the client information.";
58 douglas 268 }
59    
60     ScanUtility::~ScanUtility()
61     {
62 douglas 274 DestroyMenu(popup);
63     DestroyMenu(menu);
64 douglas 268 utilities.erase(number);
65 douglas 269 saveDirs();
66    
67 douglas 268 delete [] title;
68     }
69    
70 douglas 265 void ScanUtility::run(void)
71     {
72 douglas 268 PROPSHEETHEADER header;
73 douglas 265
74 douglas 268 // header
75     header.dwSize = sizeof(header);
76 douglas 271 header.dwFlags = PSH_DEFAULT | PSH_HEADER | PSH_PROPSHEETPAGE |
77     PSH_USEICONID | PSH_WIZARD97;
78 douglas 268 header.hwndParent = NULL;
79     header.hInstance = gui.instance;
80     header.pszIcon = MAKEINTRESOURCE(IDI_VTB_ICON);
81 douglas 274 header.nPages = 3;
82 douglas 268 header.nStartPage = 0;
83 douglas 271 header.ppsp = wizard;
84 douglas 269 header.pszbmHeader = MAKEINTRESOURCE(IDB_VTB_BMP);
85 douglas 265
86 douglas 268 PropertySheet(&header);
87     }
88    
89     unsigned ScanUtility::count = 0;
90     map<unsigned, ScanUtility*> ScanUtility::utilities;
91     map<HWND, ScanUtility*> ScanUtility::windows;
92    
93 douglas 269 void ScanUtility::loadDirs(void)
94     {
95     HKEY key;
96    
97     if (RegOpenKeyEx(HKEY_CURRENT_USER,
98 douglas 271 "Software\\DouglasThrift\\VTBFileUtil2", 0, KEY_QUERY_VALUE, &key) ==
99 douglas 269 ERROR_SUCCESS)
100     {
101     DWORD type;
102 douglas 271 char data[MAX_PATH];
103 douglas 269 DWORD size = MAX_PATH;
104    
105 douglas 271 if (RegQueryValueEx(key, "ScanDir", NULL, &type, LPBYTE(data), &size)
106     == ERROR_SUCCESS)
107 douglas 269 {
108     data[size - 1] = '\0';
109    
110     switch (type)
111     {
112     case REG_EXPAND_SZ:
113 douglas 273 {
114     char folder[MAX_PATH];
115    
116     ExpandEnvironmentStrings(data, folder, MAX_PATH);
117    
118     scanDir = folder;
119     }
120 douglas 269 break;
121     case REG_SZ:
122 douglas 271 scanDir = data;
123 douglas 269 break;
124     default:
125     setScanDir();
126     break;
127     }
128     }
129     else
130     {
131     setScanDir();
132     }
133    
134     size = MAX_PATH;
135    
136 douglas 271 if (RegQueryValueEx(key, "SaveDir", NULL, &type, LPBYTE(data), &size)
137     == ERROR_SUCCESS)
138 douglas 269 {
139     data[size - 1] = '\0';
140    
141     switch (type)
142     {
143     case REG_EXPAND_SZ:
144 douglas 273 {
145     char folder[MAX_PATH];
146    
147     ExpandEnvironmentStrings(data, folder, MAX_PATH);
148    
149     saveDir = folder;
150     }
151 douglas 269 break;
152     case REG_SZ:
153 douglas 271 saveDir = data;
154 douglas 269 break;
155     default:
156     setSaveDir();
157     break;
158     }
159     }
160     else
161     {
162     setSaveDir();
163     }
164    
165     RegCloseKey(key);
166     }
167     else
168     {
169     setScanDir();
170     setSaveDir();
171     }
172 douglas 271
173     if (debug) cerr << "scanDir = " << scanDir << "\n"
174 douglas 273 << "saveDir = " << saveDir << "\n";
175 douglas 269 }
176    
177     void ScanUtility::saveDirs(void)
178     {
179     HKEY key;
180    
181     if (RegCreateKeyEx(HKEY_CURRENT_USER,
182     "Software\\DouglasThrift\\VTBFileUtil2", 0, NULL,
183 douglas 271 REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &key,
184     NULL) == ERROR_SUCCESS)
185 douglas 269 {
186 douglas 271 DWORD type;
187     char data[MAX_PATH];
188     DWORD size = MAX_PATH;
189    
190     if (RegQueryValueEx(key, "ScanDir", NULL, &type, LPBYTE(data), &size)
191     == ERROR_SUCCESS)
192 douglas 269 {
193 douglas 271 data[size - 1] = '\0';
194 douglas 269 }
195 douglas 271 else
196     {
197     data[0] = '\0';
198     }
199 douglas 269
200 douglas 273 if (scanDir != data || type != REG_SZ)
201 douglas 269 {
202 douglas 273 if (RegSetValueEx(key, "ScanDir", 0, REG_SZ,
203     LPBYTE(scanDir.c_str()), scanDir.length() + 1) !=
204 douglas 271 ERROR_SUCCESS)
205     {
206     error();
207     }
208 douglas 269 }
209    
210 douglas 271 size = MAX_PATH;
211    
212     if (RegQueryValueEx(key, "SaveDir", NULL, &type, LPBYTE(data), &size)
213     == ERROR_SUCCESS)
214     {
215     data[size - 1] = '\0';
216     }
217     else
218     {
219     data[0] = '\0';
220     }
221    
222 douglas 273 if (saveDir != data || type != REG_SZ)
223 douglas 271 {
224 douglas 273 if (RegSetValueEx(key, "SaveDir", 0, REG_SZ,
225     LPBYTE(saveDir.c_str()), saveDir.length() + 1) !=
226 douglas 271 ERROR_SUCCESS)
227     {
228     error();
229     }
230     }
231    
232 douglas 269 RegCloseKey(key);
233     }
234     else
235     {
236     error();
237     }
238     }
239    
240     void ScanUtility::setScanDir(HWND parent)
241     {
242 douglas 271 BROWSEINFO info;
243 douglas 269
244 douglas 271 info.hwndOwner = parent;
245     info.pidlRoot = NULL;
246     info.pszDisplayName = NULL;
247     info.lpszTitle = "Select the Scan Directory";
248     info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
249     info.lpfn = browse;
250     info.lParam = MAKELPARAM(number, true);
251     info.iImage = 0;
252    
253     do
254     {
255     LPITEMIDLIST id = SHBrowseForFolder(&info);
256    
257     if (id != NULL)
258     {
259     char folder[MAX_PATH];
260    
261     if (SHGetPathFromIDList(id, folder))
262     {
263     scanDir = folder;
264     }
265     }
266    
267     LPMALLOC destruct;
268    
269     SHGetMalloc(&destruct);
270     destruct->Free(id);
271     destruct->Release();
272    
273     if (scanDir == "")
274     {
275     switch (MessageBox(parent, "Scan Directory needs to be selected.",
276     programName.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
277     {
278     case IDABORT:
279     exit(1);
280     break;
281     case IDRETRY:
282     break;
283     case IDIGNORE:
284     Beep(2200, 250);
285     Beep(1100, 500);
286     Beep(3300, 250);
287     exit(2);
288     break;
289     }
290     }
291     }
292     while (scanDir == "");
293 douglas 273
294     if (debug) cerr << "scanDir = " << scanDir << "\n";
295 douglas 269 }
296    
297     void ScanUtility::setSaveDir(HWND parent)
298     {
299 douglas 271 BROWSEINFO info;
300 douglas 269
301 douglas 271 info.hwndOwner = parent;
302     info.pidlRoot = NULL;
303     info.pszDisplayName = NULL;
304     info.lpszTitle = "Select the Save Directory";
305     info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
306     info.lpfn = browse;
307     info.lParam = MAKELPARAM(number, false);
308     info.iImage = 0;
309    
310     do
311     {
312     LPITEMIDLIST id = SHBrowseForFolder(&info);
313    
314     if (id != NULL)
315     {
316     char folder[MAX_PATH];
317    
318     if (SHGetPathFromIDList(id, folder))
319     {
320     saveDir = folder;
321     }
322     }
323    
324     LPMALLOC destruct;
325    
326     SHGetMalloc(&destruct);
327     destruct->Free(id);
328     destruct->Release();
329    
330     if (saveDir == "")
331     {
332     switch (MessageBox(parent, "Scan Directory needs to be selected.",
333     programName.c_str(), MB_ABORTRETRYIGNORE | MB_ICONERROR))
334     {
335     case IDABORT:
336     exit(1);
337     break;
338     case IDRETRY:
339     break;
340     case IDIGNORE:
341     Beep(2200, 250);
342     Beep(1100, 500);
343     Beep(3300, 250);
344     exit(2);
345     break;
346     }
347     }
348     }
349     while (saveDir == "");
350 douglas 273
351     if (debug) cerr << "saveDir = " << saveDir << "\n";
352 douglas 269 }
353    
354 douglas 273 void ScanUtility::populate(HWND parent)
355     {
356     set<string> scans;
357    
358     do
359     {
360     string scan = scanDir + "\\SCAN????_000." +
361     IndividualClient::getExtension();
362     WIN32_FIND_DATA found;
363     HANDLE finder = FindFirstFile(scan.c_str(), &found);
364    
365     if (finder != INVALID_HANDLE_VALUE)
366     {
367     do
368     {
369     scans.insert(found.cFileName);
370     }
371     while (FindNextFile(finder, &found));
372    
373     FindClose(finder);
374     }
375    
376     if (scans.empty())
377     {
378     if (MessageBox(parent, "No scanned documents found.",
379     programName.c_str(), MB_RETRYCANCEL | MB_ICONQUESTION) ==
380     IDCANCEL) break;
381     }
382     }
383     while (scans.empty());
384    
385     if (scans.empty())
386     {
387     PropSheet_PressButton(GetParent(parent), PSBTN_BACK);
388     }
389     else
390     {
391     SHFILEINFO info;
392     HIMAGELIST icons = HIMAGELIST(SHGetFileInfo((*scans.begin()).c_str(),
393     0, &info, sizeof(info), SHGFI_SMALLICON | SHGFI_SYSICONINDEX));
394    
395     ListView_SetImageList(GetDlgItem(parent, IDC_SELECT_SCANS), icons,
396     LVSIL_SMALL);
397    
398     if (debug) cerr << "scans = {\n";
399    
400     for (set<string>::iterator itor = scans.begin(); itor != scans.end();
401     itor++)
402     {
403     if (debug) cerr << " " << *itor << "\n";
404    
405     char scan[MAX_PATH];
406    
407     sprintf(scan, "%s", (*itor).c_str());
408    
409     LVITEM item;
410    
411     item.mask = LVIF_IMAGE | LVIF_TEXT;
412 douglas 274 item.iItem = 0;
413 douglas 273 item.iSubItem = 0;
414     item.pszText = scan;
415     item.iImage = info.iIcon;
416    
417     ListView_InsertItem(GetDlgItem(parent, IDC_SELECT_SCANS), &item);
418     }
419    
420     if (debug) cerr << "}\n";
421 douglas 274
422     ListView_SetItemState(GetDlgItem(parent, IDC_SELECT_SCANS), 0,
423     LVIS_SELECTED, LVIS_SELECTED);
424 douglas 273 }
425     }
426    
427 douglas 271 int ScanUtility::browse(HWND dialog, UINT msg, LPARAM l, LPARAM d)
428     {
429     map<unsigned, ScanUtility*>::iterator itor = utilities.find(LOWORD(d));
430     ScanUtility* data = itor->second;
431    
432     switch (msg)
433     {
434     case BFFM_INITIALIZED:
435     center(dialog);
436     SendMessage(dialog, BFFM_SETOKTEXT, 0,
437     LPARAM(toWide("&Select").c_str()));
438     SendMessage(dialog, BFFM_SETEXPANDED, FALSE, CSIDL_DRIVES);
439 douglas 273 SendMessage(dialog, BFFM_SETSELECTION, TRUE, LPARAM(HIWORD(d) ?
440     data->scanDir.c_str() : data->saveDir.c_str()));
441 douglas 271 break;
442     case BFFM_SELCHANGED:
443     {
444     IShellFolder* object;
445    
446     SHGetDesktopFolder(&object);
447    
448     STRRET thing;
449     char* folder;
450    
451     object->GetDisplayNameOf(LPCITEMIDLIST(l), SHGDN_FORPARSING,
452     &thing);
453     StrRetToStr(&thing, LPCITEMIDLIST(l), &folder);
454     SendMessage(dialog, BFFM_SETSTATUSTEXT, 0, LPARAM(folder));
455    
456     if (PathIsUNCServer(folder))
457     {
458     SendMessage(dialog, BFFM_ENABLEOK, 0, 0);
459     }
460    
461     CoTaskMemFree(folder);
462     object->Release();
463     }
464     break;
465     }
466    
467     return 0;
468     }
469    
470 douglas 268 INT_PTR ScanUtility::start(HWND dialog, UINT msg, WPARAM w, LPARAM l)
471     {
472     map<HWND, ScanUtility*>::iterator itor = windows.find(dialog);
473     ScanUtility* data = itor->second;
474    
475     switch (msg)
476 douglas 265 {
477 douglas 268 case WM_INITDIALOG:
478 douglas 269 center(GetParent(dialog));
479 douglas 274 SendMessage(GetParent(dialog), WM_SETICON, ICON_BIG, LPARAM(gui.icon));
480 douglas 268 {
481 douglas 271 LPPROPSHEETPAGE page = LPPROPSHEETPAGE(l);
482     map<unsigned, ScanUtility*>::iterator itor =
483     utilities.find(page->lParam);
484 douglas 265
485 douglas 268 windows.insert(pair<HWND, ScanUtility*>(dialog, itor->second));
486     }
487 douglas 273 {
488     ostringstream instructions;
489    
490 douglas 274 instructions << "1. If you need instructions, you should not be ru"
491     << "nning this program in Scan Utility mode.\n"
492     << "2. Otherwise, go forth and scan.\n"
493     << "3. Then come back and click Next.\n";
494 douglas 273
495     SetDlgItemText(dialog, IDC_START_INSTRUCTIONS,
496     instructions.str().c_str());
497     }
498 douglas 268 break;
499 douglas 269 case WM_NOTIFY:
500     {
501 douglas 273 LPNMHDR nm = LPNMHDR(l);
502 douglas 269
503     switch (nm->code)
504     {
505     case PSN_SETACTIVE:
506     PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_NEXT);
507 douglas 271 {
508     char folder[44];
509    
510     PathCompactPathEx(folder, data->scanDir.c_str(), 44, 0);
511     SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
512     PathCompactPathEx(folder, data->saveDir.c_str(), 44, 0);
513     SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
514     }
515 douglas 269 break;
516 douglas 273 case PSN_WIZNEXT:
517     SetCurrentDirectory(data->scanDir.c_str());
518     break;
519 douglas 269 }
520     }
521     break;
522 douglas 271 case WM_COMMAND:
523     switch (LOWORD(w))
524     {
525     case IDC_START_SCAN_BROWSE:
526     data->setScanDir(dialog);
527     {
528     char folder[44];
529    
530     PathCompactPathEx(folder, data->scanDir.c_str(), 44, 0);
531     SetDlgItemText(dialog, IDC_START_SCAN_TEXT, folder);
532     }
533     break;
534     case IDC_START_SAVE_BROWSE:
535     data->setSaveDir(dialog);
536     {
537     char folder[44];
538    
539     PathCompactPathEx(folder, data->saveDir.c_str(), 44, 0);
540     SetDlgItemText(dialog, IDC_START_SAVE_TEXT, folder);
541     }
542     break;
543     }
544     break;
545 douglas 268 }
546 douglas 265
547 douglas 268 return FALSE;
548 douglas 265 }
549 douglas 273
550     INT_PTR ScanUtility::select(HWND dialog, UINT msg, WPARAM w, LPARAM l)
551     {
552     map<HWND, ScanUtility*>::iterator itor = windows.find(dialog);
553     ScanUtility* data = itor->second;
554    
555     switch (msg)
556     {
557     case WM_INITDIALOG:
558     {
559     LPPROPSHEETPAGE page = LPPROPSHEETPAGE(l);
560     map<unsigned, ScanUtility*>::iterator itor =
561     utilities.find(page->lParam);
562    
563     windows.insert(pair<HWND, ScanUtility*>(dialog, itor->second));
564     }
565     {
566 douglas 274 ostringstream select;
567    
568     select << "Select the scanned document that you need to be save.";
569    
570     SetDlgItemText(dialog, IDC_SELECT_TEXT, select.str().c_str());
571     }
572     {
573 douglas 273 LVCOLUMN column;
574    
575     column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
576     column.fmt = LVCFMT_IMAGE;
577     column.cx = 120;
578     column.pszText = "Scanned Documents";
579    
580     ListView_InsertColumn(GetDlgItem(dialog, IDC_SELECT_SCANS), 0,
581     &column);
582     }
583     break;
584     case WM_NOTIFY:
585     if (w == IDC_SELECT_SCANS)
586     {
587 douglas 274 LPNMITEMACTIVATE ni = LPNMITEMACTIVATE(l);
588    
589     switch (ni->hdr.code)
590 douglas 273 {
591 douglas 274 case NM_RCLICK:
592     {
593     char scan[MAX_PATH];
594    
595     ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
596     ni->iItem, 0, scan, MAX_PATH);
597    
598     SHELLEXECUTEINFO info;
599    
600     info.cbSize = sizeof(info);
601     info.fMask = SEE_MASK_INVOKEIDLIST;
602     info.hwnd = dialog;
603     info.lpVerb = "properties";
604     info.lpFile = scan;
605     info.lpParameters = NULL;
606     info.lpDirectory = NULL;
607     info.nShow = SW_SHOWDEFAULT;
608     info.lpIDList = NULL;
609    
610     ShellExecuteEx(&info);
611     }
612 douglas 273 break;
613 douglas 274 case NM_DBLCLK:
614     {
615     char scan[MAX_PATH];
616    
617     ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
618     ni->iItem, 0, scan, MAX_PATH);
619     ShellExecute(dialog, NULL, scan, NULL, NULL,
620     SW_SHOWDEFAULT);
621     }
622 douglas 273 break;
623     }
624     }
625     else
626     {
627     LPNMHDR nm = LPNMHDR(l);
628    
629     switch (nm->code)
630     {
631     case PSN_SETACTIVE:
632 douglas 274 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
633     PSWIZB_NEXT);
634 douglas 273 data->populate(dialog);
635     break;
636     case PSN_WIZBACK:
637     ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
638     break;
639     case PSN_WIZNEXT:
640 douglas 274 {
641     int index = ListView_GetNextItem(GetDlgItem(dialog,
642     IDC_SELECT_SCANS), -1, LVNI_SELECTED);
643     char scan[MAX_PATH];
644    
645     ListView_GetItemText(GetDlgItem(dialog, IDC_SELECT_SCANS),
646     index, 0, scan, MAX_PATH);
647    
648     data->scan = scan;
649     }
650 douglas 273 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
651 douglas 274 if (debug) cerr << "scan = " << data->scan << "\n";
652     ShellExecute(dialog, NULL, data->scan.c_str(), NULL, NULL,
653     SW_SHOWDEFAULT);
654 douglas 273 break;
655     }
656     }
657     break;
658     case WM_COMMAND:
659     break;
660     }
661    
662     return FALSE;
663     }
664 douglas 274
665     INT_PTR ScanUtility::enter(HWND dialog, UINT msg, WPARAM w, LPARAM l)
666     {
667     return FALSE;
668     }