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

# Content
1 // Vance Thrift and Biller File Utility 2
2 //
3 // Douglas Thrift
4 //
5 // $Id: ScanUtility.cxx,v 1.7 2003/08/22 06:30:14 douglas Exp $
6
7 #include "ScanUtility.h"
8
9 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 loadDirs();
17
18 menu = LoadMenu(gui.instance, MAKEINTRESOURCE(IDR_SELECT));
19 popup = GetSubMenu(menu, 0);
20
21 // start
22 wizard[0].dwSize = sizeof(wizard[0]);
23 wizard[0].dwFlags = PSP_DEFAULT | PSP_USEHICON | PSP_USETITLE |
24 PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
25 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
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
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 }
59
60 ScanUtility::~ScanUtility()
61 {
62 DestroyMenu(popup);
63 DestroyMenu(menu);
64 utilities.erase(number);
65 saveDirs();
66
67 delete [] title;
68 }
69
70 void ScanUtility::run(void)
71 {
72 PROPSHEETHEADER header;
73
74 // header
75 header.dwSize = sizeof(header);
76 header.dwFlags = PSH_DEFAULT | PSH_HEADER | PSH_PROPSHEETPAGE |
77 PSH_USEICONID | PSH_WIZARD97;
78 header.hwndParent = NULL;
79 header.hInstance = gui.instance;
80 header.pszIcon = MAKEINTRESOURCE(IDI_VTB_ICON);
81 header.nPages = 3;
82 header.nStartPage = 0;
83 header.ppsp = wizard;
84 header.pszbmHeader = MAKEINTRESOURCE(IDB_VTB_BMP);
85
86 PropertySheet(&header);
87 }
88
89 unsigned ScanUtility::count = 0;
90 map<unsigned, ScanUtility*> ScanUtility::utilities;
91 map<HWND, ScanUtility*> ScanUtility::windows;
92
93 void ScanUtility::loadDirs(void)
94 {
95 HKEY key;
96
97 if (RegOpenKeyEx(HKEY_CURRENT_USER,
98 "Software\\DouglasThrift\\VTBFileUtil2", 0, KEY_QUERY_VALUE, &key) ==
99 ERROR_SUCCESS)
100 {
101 DWORD type;
102 char data[MAX_PATH];
103 DWORD size = MAX_PATH;
104
105 if (RegQueryValueEx(key, "ScanDir", NULL, &type, LPBYTE(data), &size)
106 == ERROR_SUCCESS)
107 {
108 data[size - 1] = '\0';
109
110 switch (type)
111 {
112 case REG_EXPAND_SZ:
113 {
114 char folder[MAX_PATH];
115
116 ExpandEnvironmentStrings(data, folder, MAX_PATH);
117
118 scanDir = folder;
119 }
120 break;
121 case REG_SZ:
122 scanDir = data;
123 break;
124 default:
125 setScanDir();
126 break;
127 }
128 }
129 else
130 {
131 setScanDir();
132 }
133
134 size = MAX_PATH;
135
136 if (RegQueryValueEx(key, "SaveDir", NULL, &type, LPBYTE(data), &size)
137 == ERROR_SUCCESS)
138 {
139 data[size - 1] = '\0';
140
141 switch (type)
142 {
143 case REG_EXPAND_SZ:
144 {
145 char folder[MAX_PATH];
146
147 ExpandEnvironmentStrings(data, folder, MAX_PATH);
148
149 saveDir = folder;
150 }
151 break;
152 case REG_SZ:
153 saveDir = data;
154 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
173 if (debug) cerr << "scanDir = " << scanDir << "\n"
174 << "saveDir = " << saveDir << "\n";
175 }
176
177 void ScanUtility::saveDirs(void)
178 {
179 HKEY key;
180
181 if (RegCreateKeyEx(HKEY_CURRENT_USER,
182 "Software\\DouglasThrift\\VTBFileUtil2", 0, NULL,
183 REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &key,
184 NULL) == ERROR_SUCCESS)
185 {
186 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 {
193 data[size - 1] = '\0';
194 }
195 else
196 {
197 data[0] = '\0';
198 }
199
200 if (scanDir != data || type != REG_SZ)
201 {
202 if (RegSetValueEx(key, "ScanDir", 0, REG_SZ,
203 LPBYTE(scanDir.c_str()), scanDir.length() + 1) !=
204 ERROR_SUCCESS)
205 {
206 error();
207 }
208 }
209
210 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 if (saveDir != data || type != REG_SZ)
223 {
224 if (RegSetValueEx(key, "SaveDir", 0, REG_SZ,
225 LPBYTE(saveDir.c_str()), saveDir.length() + 1) !=
226 ERROR_SUCCESS)
227 {
228 error();
229 }
230 }
231
232 RegCloseKey(key);
233 }
234 else
235 {
236 error();
237 }
238 }
239
240 void ScanUtility::setScanDir(HWND parent)
241 {
242 BROWSEINFO info;
243
244 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
294 if (debug) cerr << "scanDir = " << scanDir << "\n";
295 }
296
297 void ScanUtility::setSaveDir(HWND parent)
298 {
299 BROWSEINFO info;
300
301 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
351 if (debug) cerr << "saveDir = " << saveDir << "\n";
352 }
353
354 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 item.iItem = 0;
413 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
422 ListView_SetItemState(GetDlgItem(parent, IDC_SELECT_SCANS), 0,
423 LVIS_SELECTED, LVIS_SELECTED);
424 }
425 }
426
427 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 SendMessage(dialog, BFFM_SETSELECTION, TRUE, LPARAM(HIWORD(d) ?
440 data->scanDir.c_str() : data->saveDir.c_str()));
441 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 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 {
477 case WM_INITDIALOG:
478 center(GetParent(dialog));
479 SendMessage(GetParent(dialog), WM_SETICON, ICON_BIG, LPARAM(gui.icon));
480 {
481 LPPROPSHEETPAGE page = LPPROPSHEETPAGE(l);
482 map<unsigned, ScanUtility*>::iterator itor =
483 utilities.find(page->lParam);
484
485 windows.insert(pair<HWND, ScanUtility*>(dialog, itor->second));
486 }
487 {
488 ostringstream instructions;
489
490 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
495 SetDlgItemText(dialog, IDC_START_INSTRUCTIONS,
496 instructions.str().c_str());
497 }
498 break;
499 case WM_NOTIFY:
500 {
501 LPNMHDR nm = LPNMHDR(l);
502
503 switch (nm->code)
504 {
505 case PSN_SETACTIVE:
506 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_NEXT);
507 {
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 break;
516 case PSN_WIZNEXT:
517 SetCurrentDirectory(data->scanDir.c_str());
518 break;
519 }
520 }
521 break;
522 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 }
546
547 return FALSE;
548 }
549
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 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 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 LPNMITEMACTIVATE ni = LPNMITEMACTIVATE(l);
588
589 switch (ni->hdr.code)
590 {
591 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 break;
613 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 break;
623 }
624 }
625 else
626 {
627 LPNMHDR nm = LPNMHDR(l);
628
629 switch (nm->code)
630 {
631 case PSN_SETACTIVE:
632 PropSheet_SetWizButtons(GetParent(dialog), PSWIZB_BACK |
633 PSWIZB_NEXT);
634 data->populate(dialog);
635 break;
636 case PSN_WIZBACK:
637 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
638 break;
639 case PSN_WIZNEXT:
640 {
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 ListView_DeleteAllItems(GetDlgItem(dialog, IDC_SELECT_SCANS));
651 if (debug) cerr << "scan = " << data->scan << "\n";
652 ShellExecute(dialog, NULL, data->scan.c_str(), NULL, NULL,
653 SW_SHOWDEFAULT);
654 break;
655 }
656 }
657 break;
658 case WM_COMMAND:
659 break;
660 }
661
662 return FALSE;
663 }
664
665 INT_PTR ScanUtility::enter(HWND dialog, UINT msg, WPARAM w, LPARAM l)
666 {
667 return FALSE;
668 }