|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: Filer.c
3: *
4: * Filer: SDK sample
5: * + Simple File Management program with GUI front end.
6: * Demonstrates Win32 File I/O API and various User algorithms.
7: *
8: * Created: 5/05/92
9: * Author: Colin Stuart
10: *
11: * Copyright (c) 1990 Microsoft Corporation
12: *
13: * Dependencies:
14: *
15: * (#defines)
16: * (#includes)
17: * -Enumdrv.h
18: * -Walk.h
19: * -Drvproc.h
20: * -Filer.h
21: *
22: \**************************************************************************/
23: #include <windows.h>
24: #include <string.h>
25: #include <stdlib.h>
26: #include <stdarg.h>
27: #include "globals.h"
28: #include "enumdrv.h"
29: #include "walk.h"
30: #include "drvproc.h"
31: #include "filer.h"
32:
33: //
34: // Global Handles
35: //
36: HANDLE ghModule; // Process ID handle
37:
38: HWND ghwndMain; // Main window handle
39: HWND ghwndDrives; // Drives Toolbar window handle
40: HWND ghwndFunction; // Function Toolbar window handle
41: HWND ghwndCommand; // Command Line window handle
42: HWND ghwndDrv1,
43: ghwndDrv2;
44: HWND ghActiveChild = NULL; // Handle to active drive child window
45: HWND ghFocusLB; // Handle to last listbox with focus
46:
47:
48: HANDLE ghHeap; // Application heap handle
49: HFONT ghFont;
50: HANDLE ghDrvThread = NULL;
51:
52: HMENU ghMenu; // App Menu variables
53:
54: //
55: // Global Data Items
56: //
57: BOOL gfDrvWndOrient = SIDE_BY_SIDE; // relative Drv child pos.
58:
59: DRVCHILDINFO gDrvChild1Info,
60: gDrvChild2Info;
61:
62: LPDINFO glpDrives = NULL; // Root of Available Drives linked list
63:
64: CRITICAL_SECTION gDrvCS; // Drive list critical section var.
65: CRITICAL_SECTION gHeapCS; // Global heap critical section.
66: CRITICAL_SECTION gSetDirCS; // SetCurrentDirectory critical sect.
67:
68: char gszCommandLine[DIRECTORY_STRING_SIZE * 2];
69: char gszExtensions[NUM_EXTENSION_STRINGS][EXTENSION_LENGTH];
70:
71:
72: /***************************************************************************\
73: * WinMain
74: *
75: *
76: * History:
77: * 04-17-91
78: * Created.
79: \***************************************************************************/
80: int WinMain(
81: HINSTANCE hInstance,
82: HINSTANCE hPrevInstance,
83: LPSTR lpCmdLine,
84: int nCmdShow)
85: {
86: MSG msg;
87: HANDLE hAccel;
88:
89: ghModule = hInstance;
90: if (!InitializeApp()) {
91: ErrorMsg("Filer: InitializeApp failure!");
92: return 0;
93: }
94: ShowWindow(ghwndMain, nCmdShow);
95:
96: if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
97: ErrorMsg("Filer: Load Accel failure!");
98:
99:
100: while (GetMessage(&msg, NULL, 0, 0)) {
101: if( !TranslateAccelerator(ghwndMain, hAccel, &msg) ) {
102: TranslateMessage(&msg);
103: DispatchMessage(&msg);
104: }
105: }
106:
107: return 1;
108:
109: UNREFERENCED_PARAMETER(lpCmdLine);
110: UNREFERENCED_PARAMETER(hPrevInstance);
111: }
112:
113:
114: /***************************************************************************\
115: * InitializeApp
116: *
117: * History:
118: * 5/5/92
119: * Created
120: \***************************************************************************/
121:
122: BOOL InitializeApp(void)
123: {
124: WNDCLASS wc;
125:
126: wc.style = NULL;
127: wc.lpfnWndProc = (WNDPROC)MainWndProc;
128: wc.cbClsExtra = 0;
129: wc.cbWndExtra = 0;
130: wc.hInstance = ghModule;
131: wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(UI_FILERICON));
132: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
133: wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);
134: wc.lpszMenuName = "FilerMenu";
135: wc.lpszClassName = "FilerClass";
136:
137: if (!RegisterClass(&wc))
138: return(FALSE);
139:
140: wc.lpfnWndProc = DrvWndProc;
141: wc.hIcon = NULL;
142: wc.lpszMenuName = NULL;
143: wc.lpszClassName = "DrvClass";
144:
145: if (!RegisterClass(&wc))
146: return(FALSE);
147:
148: wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
149: wc.lpfnWndProc = DriveBarProc;
150: wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW);
151: wc.lpszClassName = "DriveBarClass";
152:
153: if (!RegisterClass(&wc))
154: return(FALSE);
155:
156: wc.style = CS_HREDRAW | CS_VREDRAW;
157: wc.lpfnWndProc = TextWndProc;
158: wc.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION);
159: wc.lpszClassName = "TextClass";
160:
161: if (!RegisterClass(&wc))
162: return(FALSE);
163:
164: ghMenu = LoadMenu(ghModule, "FilerMenu");
165:
166: ghwndMain = CreateWindow("FilerClass",
167: "Filer",
168: WS_OVERLAPPEDWINDOW,
169: CW_USEDEFAULT,
170: CW_USEDEFAULT,
171: MAIN_WIDTH,
172: MAIN_HEIGHT,
173: HWND_DESKTOP,
174: ghMenu,
175: ghModule,
176: NULL);
177:
178: if (ghwndMain == NULL)
179: return(FALSE);
180:
181: return(TRUE);
182: }
183:
184:
185: /***************************************************************************\
186: * MainWndProc
187: *
188: * History:
189: * 05-01-92 Created.
190: \***************************************************************************/
191:
192: LRESULT MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
193: {
194: switch (message) {
195:
196: case WM_CREATE:{
197: LOGFONT lf;
198: HDC hDC;
199: HGDIOBJ hOldFont;
200: TEXTMETRIC tm;
201:
202: DWORD dwThreadID;
203:
204: //
205: // Initialize drive list and Set Directory critical sections.
206: //
207: InitializeCriticalSection(&gDrvCS);
208: InitializeCriticalSection(&gHeapCS);
209: InitializeCriticalSection(&gSetDirCS);
210:
211: ghDrvThread = CreateThread(NULL, 0,
212: (LPTHREAD_START_ROUTINE)EnumDrives,
213: (LPVOID)&glpDrives,
214: 0, &dwThreadID);
215:
216: //
217: // Create the application's heap
218: //
219: ghHeap = HeapCreate( 0, (DWORD)sizeof(DRVCHILDINFO), 0);
220: if( ghHeap == NULL )
221: ErrorMsg("Main Create: Failed in Creating Heap");
222:
223: //
224: // Compute default application font by creating a bold version
225: // of the system default icon font.
226: //
227: SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf),
228: (PVOID) &lf, FALSE);
229:
230: hDC = GetDC(hwnd);
231:
232: //
233: // this is the height for 8 point size font in pixels.
234: // (1 point = 1/72 in.)
235: //
236: lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
237: lf.lfWeight = BOLD_FONT;
238:
239: ghFont = CreateFontIndirect(&lf);
240: hOldFont = SelectObject(hDC, ghFont);
241: GetTextMetrics(hDC, &tm);
242: if(hOldFont)
243: SelectObject(hDC, hOldFont);
244: ReleaseDC(hwnd, hDC);
245:
246: //
247: // Create Drive windows
248: //
249: gDrvChild1Info.hParent = hwnd;
250: gDrvChild2Info.hParent = hwnd;
251:
252: ghwndDrv1 = CreateWindow("DrvClass", NULL,
253: WS_CHILD |
254: WS_CLIPSIBLINGS | WS_VISIBLE,
255: 0, 0, 0, 0,
256: hwnd, (HMENU) 1, ghModule,
257: (LPVOID)&gDrvChild1Info);
258:
259: ghActiveChild = ghwndDrv1;
260:
261: ghwndDrv2 = CreateWindow("DrvClass", NULL,
262: WS_CHILD |
263: WS_CLIPSIBLINGS | WS_VISIBLE,
264: 0, 0, 0, 0,
265: hwnd, (HMENU) 2, ghModule,
266: (LPVOID)&gDrvChild2Info);
267:
268: //
269: // Create DriveBar, FunctionBar and Command windows
270: //
271: ghwndDrives = CreateWindow("DriveBarClass", NULL,
272: WS_CHILD | WS_VISIBLE | WS_BORDER,
273: 0, 0, 0, 0,
274: hwnd, (HMENU) 3, ghModule,
275: (LPVOID)NULL);
276:
277: ghwndFunction = CreateDialog(ghModule,
278: "FunctionBar",
279: hwnd,
280: (DLGPROC)FunctionBarProc);
281:
282: ghwndCommand = CreateWindow("EDIT", NULL,
283: ES_AUTOHSCROLL | ES_LEFT | WS_BORDER |
284: ES_NOHIDESEL | WS_CHILD | WS_VISIBLE,
285: 0, 0, 0, 0,
286: hwnd,
287: (HMENU) 3,
288: ghModule,
289: NULL);
290:
291: //
292: // Compute height of command window from font; store in window info.
293: // Set command window to default font.
294: //
295: SetWindowLong( ghwndCommand, GWL_USERDATA,
296: tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6);
297: SendMessage(ghwndCommand, WM_SETFONT, (WPARAM)ghFont, (LPARAM)FALSE);
298:
299: //
300: // Load String table entries
301: //
302: LoadString( ghModule, STR_EXE, &gszExtensions[0][0], EXTENSION_LENGTH);
303: LoadString( ghModule, STR_COM, &gszExtensions[1][0], EXTENSION_LENGTH);
304: LoadString( ghModule, STR_CMD, &gszExtensions[2][0], EXTENSION_LENGTH);
305: LoadString( ghModule, STR_BAT, &gszExtensions[3][0], EXTENSION_LENGTH);
306:
307: UpdateDrivesMenu(ghMenu, ghDrvThread);
308:
309: return(1);
310: }
311:
312: case WM_COMMAND:{
313:
314: //
315: // The menu Identifiers for the drives are (potentially)
316: // MM_DRIVE_NUM + 0 thru MM_DRIVE_NUM + 25. They all go to the
317: // same case, so we will put the Menu ID in lParam, and
318: // MM_DRIVE_NUM in LOWORD(wParam).
319: //
320: if( (LOWORD(wParam) - MM_DRIVE_NUM) <= 25 &&
321: (LOWORD(wParam) - MM_DRIVE_NUM) >= 0 ){
322: lParam = LOWORD(wParam);
323: wParam = MM_DRIVE_NUM;
324: }
325:
326: switch (LOWORD(wParam)) {
327: //
328: // If a drive is selected from the Drives menu, or clicked
329: // on the drives toolbar, the currently active child will
330: // switch to this drive. Message 'unconverted' (see top of
331: // WM_COMMAND case), and sent to DriveBarProc
332: //
333: case MM_DRIVE_NUM:{
334:
335: SendMessage(ghwndDrives, WM_COMMAND,
336: (WPARAM)lParam, (LPARAM)NULL);
337: return(1);
338: }
339:
340: //
341: // Passes these WM_COMMAND messages to the appropriate active child
342: // window proc for processing
343: //
344: case MM_TAB:
345: case MM_ESCAPE:
346: case MM_OPEN:
347: case MM_COPY:
348: case MM_DELETE:
349: case MM_MOVE:
350: case MM_RENAME:
351: case MM_MKDIR:{
352:
353: SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam);
354: return(1);
355: }
356:
357: //
358: // Creates the drive enumeration thread to re-enumerate the
359: // available drives in the main menu. Also sends a refresh
360: // to the active drive child, and repaints the window.
361: //
362: case MM_REFRESH: {
363: DWORD dwThreadID;
364: DWORD dwExitCode = 0;
365:
366: //
367: // Initialize/Refresh Drives linked list
368: //
369: GetExitCodeThread( ghDrvThread, &dwExitCode);
370:
371: if( dwExitCode != STILL_ACTIVE ){
372:
373: ghDrvThread = CreateThread(NULL, 0,
374: (LPTHREAD_START_ROUTINE)EnumDrives,
375: (LPVOID)&glpDrives,
376: 0, &dwThreadID);
377:
378: //
379: // Refresh active child, drive toolbar, and drives menu
380: //
381: SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam);
382: SendMessage(ghwndDrives, WM_COMMAND, wParam, lParam);
383: UpdateDrivesMenu(ghMenu, ghDrvThread);
384:
385: //
386: // Mark all for repaint
387: //
388: InvalidateRect(hwnd,NULL,TRUE);
389:
390: }
391: else
392: MessageBeep(MB_ICONASTERISK);
393: return(1);
394: }
395:
396: //
397: // Swaps the directory and file list boxes of the active drv child.
398: //
399: case MM_SWAP:{
400: HWND hHold;
401: LPCINFO lpCInfo;
402: RECT rect;
403:
404: lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA);
405: hHold = lpCInfo->hwndLL;
406: lpCInfo->hwndLL = lpCInfo->hwndLR;
407: lpCInfo->hwndLR = hHold;
408:
409: //
410: // Send size message with current size to active child,
411: // in order to redraw the listboxes.
412: //
413: if( !GetClientRect( ghActiveChild, &rect ) )
414: return(0);
415:
416: SendMessage( ghActiveChild, WM_SIZE, SIZENORMAL,
417: MAKELONG( rect.right - rect.left,
418: rect.bottom - rect.top) );
419: return(1);
420: }
421:
422: //
423: // Toggles the relative Drive Child orientaion between
424: // Over/under and side/side. gfDrvWndOrient is a flag checked
425: // by WM_SIZE to size Drv children
426: //
427: case MM_ORIENT:{
428: RECT rect;
429:
430: if( gfDrvWndOrient == OVER_UNDER )
431: gfDrvWndOrient = SIDE_BY_SIDE;
432: else
433: gfDrvWndOrient = OVER_UNDER;
434:
435: //
436: // Send size message with current size to self (main window),
437: // in order to redraw the Drv children.
438: //
439: if( !GetClientRect( hwnd, &rect ) )
440: return(0);
441:
442: SendMessage( hwnd, WM_SIZE, SIZENORMAL,
443: MAKELONG( rect.right - rect.left,
444: rect.bottom - rect.top) );
445:
446: InvalidateRect(ghwndDrv1,NULL,TRUE);
447: InvalidateRect(ghwndDrv2,NULL,TRUE);
448:
449: return(1);
450: }
451:
452: //
453: // Toggles the active drive child. Sent from menu.
454: // This behaves the same as a WM_MOUSEACTIVATE in one of the
455: // Drive children. The PostMessage is so the current Active
456: // child will not process the MM_TOGGLE message until after it
457: // is no longer active.
458: //
459: case MM_ACTIVEDRV:{
460:
461: PostMessage(ghActiveChild, WM_COMMAND, (WPARAM)MM_TOGGLE,
462: (LPARAM)NULL);
463:
464: if( ghActiveChild == ghwndDrv1 )
465: ghActiveChild = ghwndDrv2;
466: else
467: ghActiveChild = ghwndDrv1;
468:
469: SendMessage(ghActiveChild, WM_COMMAND, (WPARAM)MM_TOGGLE,
470: (LPARAM)NULL);
471:
472: return(1);
473: }
474:
475: //
476: // Launches the About DialogBox.
477: //
478: case MM_ABOUT:{
479: if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)AboutProc) == -1)
480: ErrorMsg("Main: About Dialog Creation Error!");
481: return(1);
482: }
483:
484: default:
485: return( DefWindowProc(hwnd, message, wParam, lParam) );
486: }
487: return(1);
488: }
489: //
490: // Whenever the window is resized, its children have to be
491: // resized accordingly. The GetWindowLong values are the height
492: // of the windows queried by this function, and are set in the
493: // WM_CREATE cases of their respective WNDPROCs.
494: //
495: case WM_SIZE:{
496: int DrvWndHeight;
497:
498: //
499: // Always put the command window at the bottom of the frame window
500: //
501: MoveWindow(ghwndCommand,
502: 0,
503: HIWORD(lParam) - GetWindowLong(ghwndCommand, GWL_USERDATA),
504: LOWORD(lParam),
505: GetWindowLong(ghwndCommand, GWL_USERDATA),
506: TRUE);
507: //
508: // Always put the drives toolbar at the top of the frame window
509: //
510: MoveWindow(ghwndDrives,
511: 0,
512: 0,
513: LOWORD(lParam),
514: GetWindowLong(ghwndDrives, GWL_USERDATA),
515: TRUE);
516:
517: //
518: // Always put the Function window just below the drives toolbar.
519: //
520: MoveWindow(ghwndFunction,
521: 0,
522: GetWindowLong(ghwndDrives, GWL_USERDATA),
523: LOWORD(lParam),
524: GetWindowLong(ghwndFunction, GWL_USERDATA),
525: TRUE);
526:
527: //
528: // Always size the Drive Children between the Drives and Command
529: // windows. The width is set so that borders overlap.
530: //
531:
532: if( gfDrvWndOrient == OVER_UNDER ){
533:
534: DrvWndHeight = ( HIWORD(lParam) -
535: GetWindowLong(ghwndDrives, GWL_USERDATA) -
536: GetWindowLong(ghwndFunction, GWL_USERDATA) -
537: GetWindowLong(ghwndCommand, GWL_USERDATA) ) / 2;
538:
539: MoveWindow(ghwndDrv1,
540: -1,
541: GetWindowLong(ghwndDrives, GWL_USERDATA)+
542: GetWindowLong(ghwndFunction, GWL_USERDATA),
543: LOWORD(lParam) + 2,
544: DrvWndHeight,
545: TRUE);
546:
547: MoveWindow(ghwndDrv2,
548: -1,
549: GetWindowLong(ghwndDrives, GWL_USERDATA)+
550: GetWindowLong(ghwndFunction, GWL_USERDATA) + DrvWndHeight,
551: LOWORD(lParam) + 2,
552: DrvWndHeight,
553: TRUE);
554: }
555: else{
556:
557: DrvWndHeight = HIWORD(lParam) -
558: GetWindowLong(ghwndDrives, GWL_USERDATA) -
559: GetWindowLong(ghwndFunction, GWL_USERDATA) -
560: GetWindowLong(ghwndCommand, GWL_USERDATA);
561:
562: MoveWindow(ghwndDrv1,
563: -1,
564: GetWindowLong(ghwndDrives, GWL_USERDATA)+
565: GetWindowLong(ghwndFunction, GWL_USERDATA),
566: LOWORD(lParam)/2 + 1,
567: DrvWndHeight,
568: TRUE);
569:
570: MoveWindow(ghwndDrv2,
571: LOWORD(lParam)/2,
572: GetWindowLong(ghwndDrives, GWL_USERDATA)+
573: GetWindowLong(ghwndFunction, GWL_USERDATA),
574: LOWORD(lParam)/2 + 1,
575: DrvWndHeight,
576: TRUE);
577: }
578:
579: return(1);
580: }
581:
582: case WM_DESTROY: {
583: EnterCriticalSection(&gHeapCS);
584: HeapDestroy(ghHeap);
585: LeaveCriticalSection(&gHeapCS);
586:
587: DeleteObject(ghFont);
588:
589: DeleteCriticalSection(&gDrvCS);
590: DeleteCriticalSection(&gSetDirCS);
591:
592: PostQuitMessage(0);
593: return(1);
594: }
595:
596: default:
597: return DefWindowProc(hwnd, message, wParam, lParam);
598: }
599: }
600:
601: /***************************************************************************\
602: * AboutProc
603: *
604: * About dialog proc.
605: *
606: * History:
607: * 05-13-92 Created.
608: \***************************************************************************/
609:
610: LRESULT AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
611: {
612: switch (message) {
613: case WM_INITDIALOG:{
614: return TRUE;
615: }
616:
617: case WM_COMMAND:{
618: if (wParam == IDOK)
619: EndDialog(hDlg, wParam);
620: break;
621: }
622: }
623:
624: return FALSE;
625:
626: UNREFERENCED_PARAMETER(lParam);
627: UNREFERENCED_PARAMETER(hDlg);
628: }
629:
630:
631: /***************************************************************************\
632: *
633: * DriveBarProc()
634: *
635: * Drive Toolbar procedure for displaying available drive Icons.
636: * A bitmap button is displayed corresponding to the drive type of the
637: * given drive, with the drive letter alongside.
638: * ghwndDrives is the global handle assoc. w/ this window procedure.
639: *
640: *
641: * History:
642: * 6/9/92
643: * Created.
644: *
645: \***************************************************************************/
646:
647: LRESULT DriveBarProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
648: {
649: static HBITMAP hDrvBmp[NUM_BITMAPS];
650: static HBRUSH hBrush; // background brush
651: static int nDrvEntryWidth; // width of button/letter entry
652: static int yVal; // y value in toolbar for top left of bmp
653: static LPBINFO lpDrvButtonRoot;
654: static int nActiveDrvIndex;
655:
656: switch (message)
657: {
658: case WM_CREATE:{
659: HDC hDC;
660: HGDIOBJ hOldFont;
661: TEXTMETRIC tm;
662: LONG lHeight;
663:
664:
665: lpDrvButtonRoot = NULL;
666:
667: //
668: // Load drive button bitmaps.
669: //
670: for(yVal = 0; yVal < NUM_BITMAPS; yVal++)
671: hDrvBmp[yVal] = LoadBitmap( ghModule,
672: MAKEINTRESOURCE(UB_BMP_MARKER + yVal) );
673:
674: //
675: // Sets background color of Toolbar non-modal dialog children.
676: //
677: hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
678:
679: hDC = GetDC(hwnd);
680:
681: hOldFont = SelectObject(hDC, ghFont);
682: GetTextMetrics(hDC, &tm);
683:
684: //
685: // base the height of the window on size of text
686: //
687: lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6;
688:
689: //
690: // saved the window height, drive button entry width
691: // and button y starting value for later reference
692: //
693: SetWindowLong(hwnd, GWL_USERDATA, lHeight);
694:
695: //
696: // Width of one button entry = spacing, button, sm. space,
697: // drive letter, spacing.
698: //
699: nDrvEntryWidth = DRIVE_BITMAP_SPACING + DRIVE_BITMAP_WIDTH +
700: DRIVE_LETTER_SPACING + tm.tmAveCharWidth +
701: DRIVE_BITMAP_SPACING;
702:
703: //
704: // Center bitmaps (by height) in drive toolbar.
705: //
706: yVal = (lHeight - DRIVE_BITMAP_HEIGHT)/2;
707:
708: SelectObject(hDC, hOldFont);
709: ReleaseDC(hwnd, hDC);
710:
711: SendMessage(hwnd, WM_COMMAND, (WPARAM)MM_REFRESH, (LPARAM)NULL);
712:
713: break;
714: }
715:
716: case WM_COMMAND:{
717: //
718: // The button Identifiers for the drives are (potentially)
719: // MM_DRIVE_NUM + 0 thru MM_DRIVE_NUM + 25. They all go to the
720: // same case, so we will put the Menu ID in lParam, and
721: // MM_DRIVE_NUM in LOWORD(wParam).
722: //
723: if( (LOWORD(wParam) - MM_DRIVE_NUM) <= 25 &&
724: (LOWORD(wParam) - MM_DRIVE_NUM) >= 0 ){
725: lParam = LOWORD(wParam);
726: wParam = MM_DRIVE_NUM;
727: }
728:
729: switch( LOWORD(wParam) ){
730: case MM_REFRESH:{
731:
732: LPDINFO lpWalk;
733: LPBINFO lpBWalk, lpBHold;
734: LPCINFO lpCInfo;
735: int xVal = 0;
736: int nCount = MM_DRIVE_NUM;
737:
738: lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA);
739:
740: //
741: // Traverse DRVINFO linked list, creating drive buttons and
742: // allocating corresp. structures as necessary.
743: //
744: EnterCriticalSection(&gDrvCS);
745: lpWalk = glpDrives;
746: lpBWalk = lpDrvButtonRoot;
747:
748: while( lpWalk != NULL ){
749: if( lpBWalk == NULL ){
750:
751: EnterCriticalSection(&gHeapCS);
752: lpBWalk = (LPBINFO)HeapAlloc(ghHeap, sizeof(BINFO));
753: LeaveCriticalSection(&gHeapCS);
754:
755: lpBWalk->lpDrive = lpWalk;
756: lpBWalk->fButtonDown = FALSE;
757: if( lpDrvButtonRoot == NULL)
758: lpDrvButtonRoot = lpBHold = lpBWalk;
759: else{
760: lpBHold->next = lpBWalk;
761: lpBWalk->next = NULL;
762: }
763: }
764: if( lpCInfo->lpDriveInfo == lpWalk ){
765: nActiveDrvIndex = nCount;
766: lpBWalk->fButtonDown = TRUE;
767: }
768: else
769: lpBWalk->fButtonDown = FALSE;
770:
771: lpBWalk->lpDrive = lpWalk;
772:
773: lpBWalk->hButton = (HANDLE)CreateWindow("BUTTON",
774: lpWalk->DriveName,
775: WS_CHILD | WS_VISIBLE |
776: BS_OWNERDRAW,
777: xVal + DRIVE_BITMAP_SPACING,
778: yVal,
779: DRIVE_BITMAP_WIDTH,
780: DRIVE_BITMAP_HEIGHT,
781: hwnd,
782: (HMENU)nCount,
783: ghModule,
784: NULL);
785:
786: nCount++;
787: xVal += nDrvEntryWidth;
788: lpBHold = lpBWalk;
789: lpBWalk = lpBWalk->next;
790:
791: lpWalk = lpWalk->next;
792: }
793:
794: LeaveCriticalSection(&gDrvCS);
795:
796: //
797: // Free any remaining button windows.
798: //
799: while( lpBWalk != NULL ){
800: lpBHold = lpBWalk;
801: lpBWalk = lpBWalk->next;
802: if( !DestroyWindow(lpBHold->hButton) )
803: ErrorMsg("DriveBarProc: Drive Button Destroy Error");
804:
805: EnterCriticalSection(&gHeapCS);
806: HeapFree(ghHeap, (LPSTR)lpBHold);
807: LeaveCriticalSection(&gHeapCS);
808: }
809:
810: SendMessage(hwnd, WM_PAINT, (WPARAM)NULL, (LPARAM)NULL);
811: break;
812: }
813:
814:
815: //
816: // switches the drive button to the newly active drv child's
817: // current drive. Called by WM_MOUSEACTIVATE in DrvWndProc,
818: // as well as ChangeDrive.
819: // lParam contains the drive linked list pointer of the active
820: // drv child's LPCINFO struct.
821: //
822: case MM_ACTIVEDRV:{
823: LPBINFO lpBWalk = lpDrvButtonRoot;
824: int nCount = 0;
825:
826: //
827: // 'unpush' old active button
828: //
829: for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++)
830: lpBWalk = lpBWalk->next;
831: lpBWalk->fButtonDown = FALSE;
832:
833: InvalidateRect(lpBWalk->hButton, NULL, FALSE);
834:
835: //
836: // change active drive to new before redrawing old.
837: // 'push' new active button
838: //
839: lpBWalk = lpDrvButtonRoot;
840: nCount = MM_DRIVE_NUM;
841: while( lpBWalk->lpDrive != (LPDINFO)lParam){
842: lpBWalk = lpBWalk->next;
843: nCount++;
844: }
845:
846: nActiveDrvIndex = nCount;
847:
848: lpBWalk->fButtonDown = TRUE;
849:
850: InvalidateRect(lpBWalk->hButton, NULL, FALSE);
851:
852: break;
853: }
854:
855: //
856: // Changes drive of active child. ButtonID in lParam.
857: //
858: case MM_DRIVE_NUM:{
859:
860: LPBINFO lpBWalk = lpDrvButtonRoot;
861: int nCount = 0;
862: CHAR szDrvBuff[DIRECTORY_STRING_SIZE];
863:
864: //
865: // if drive chosen is already current drive, leave.
866: //
867: if( nActiveDrvIndex == (int)lParam )
868: break;
869:
870: //
871: // 'unpush' old active button
872: //
873: for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++)
874: lpBWalk = lpBWalk->next;
875: lpBWalk->fButtonDown = FALSE;
876:
877: //
878: // change active drive to new before redrawing old.
879: //
880: nActiveDrvIndex = (int)lParam;
881:
882: InvalidateRect(lpBWalk->hButton, NULL, FALSE);
883:
884: //
885: // 'push' new active button
886: //
887: lpBWalk = lpDrvButtonRoot;
888:
889: for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++)
890: lpBWalk = lpBWalk->next;
891: lpBWalk->fButtonDown = TRUE;
892:
893: InvalidateRect(lpBWalk->hButton, NULL, FALSE);
894:
895: GetWindowText(lpBWalk->hButton, szDrvBuff,
896: DIRECTORY_STRING_SIZE);
897:
898: if( !ChangeDrive(szDrvBuff, (DWORD)nActiveDrvIndex) ){
899: ErrorMsg("Error changing Drives.");
900: return(0);
901: }
902:
903: break;
904: }
905: }
906: return(1);
907: }
908:
909: //
910: // Sent by all created buttons for initialization purposes.
911: //
912: case WM_MEASUREITEM:{
913: LPMEASUREITEMSTRUCT lpMIS;
914:
915: lpMIS = (LPMEASUREITEMSTRUCT)lParam;
916:
917: lpMIS->CtlType = ODT_BUTTON;
918: lpMIS->CtlID = (UINT)wParam;
919: lpMIS->itemWidth = DRIVE_BITMAP_WIDTH;
920: lpMIS->itemHeight = DRIVE_BITMAP_HEIGHT;
921:
922: return(1);
923: }
924:
925: //
926: // Sent by owner draw drive buttons when needing redrawing.
927: //
928: case WM_DRAWITEM:{
929: LPBINFO lpBWalk = lpDrvButtonRoot;
930: int nCount;
931: int nBmpIndex;
932: HDC hDC;
933: HDC hCompatDC;
934: HGDIOBJ hOldBitmap;
935: CHAR szDrvBuff[DIRECTORY_STRING_SIZE];
936: LPDRAWITEMSTRUCT lpDIS;
937:
938: lpDIS = (LPDRAWITEMSTRUCT)lParam;
939:
940: for( nCount = MM_DRIVE_NUM; nCount < (int)wParam; nCount++)
941: lpBWalk = lpBWalk->next;
942:
943: //
944: // If not the current selected button, handle button stuff.
945: //
946: if( (int)wParam != nActiveDrvIndex ){
947: //
948: // mousebutton is down...
949: //
950: if( lpDIS->itemAction & ODA_SELECT ){
951: //
952: // left button region, 'unpush' button
953: //
954: if( lpDIS->itemState == (UINT)ODS_FOCUS )
955: lpBWalk->fButtonDown = FALSE;
956: //
957: // clicked on a button, draw 'pushed' button
958: //
959: if( lpDIS->itemState == (UINT)(ODS_SELECTED | ODS_FOCUS))
960: lpBWalk->fButtonDown = TRUE;
961: }
962: }
963:
964: //
965: // draw current state of button.
966: //
967: GetWindowText(lpDIS->hwndItem, szDrvBuff,
968: DIRECTORY_STRING_SIZE);
969:
970: szDrvBuff[1] = '\0';
971:
972: hCompatDC = CreateCompatibleDC(lpDIS->hDC);
973: hOldBitmap = CreateCompatibleBitmap(hCompatDC,
974: DRIVE_BITMAP_WIDTH,
975: DRIVE_BITMAP_HEIGHT);
976:
977: nBmpIndex = GetDriveBitmap(lpBWalk);
978:
979: SelectObject( hCompatDC, hDrvBmp[nBmpIndex] );
980:
981: if( !hOldBitmap )
982: OutputDebugString("WM_DRAWITEM: SelectObject error\n");
983:
984: if( !BitBlt(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
985: DRIVE_BITMAP_WIDTH,
986: DRIVE_BITMAP_HEIGHT,
987: hCompatDC, 0, 0, SRCCOPY) )
988: OutputDebugString("WM_DRAWITEM: BitBlt error\n");
989:
990:
991: SelectObject( hCompatDC, hOldBitmap);
992: DeleteDC(hCompatDC);
993:
994: hDC = GetDC(hwnd);
995: SetBkMode(hDC, TRANSPARENT);
996: SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT) );
997: SetBkColor(hDC, GetSysColor(COLOR_BTNSHADOW) );
998:
999: TextOut(hDC,
1000: ((int)(wParam - MM_DRIVE_NUM) * nDrvEntryWidth) +
1001: DRIVE_BITMAP_SPACING + DRIVE_BITMAP_WIDTH +
1002: DRIVE_LETTER_SPACING,
1003: (GetSystemMetrics(SM_CYBORDER) + 6)/2,
1004: szDrvBuff, 1);
1005:
1006: SetBkMode(hDC, OPAQUE);
1007:
1008: ReleaseDC(hwnd, hDC);
1009:
1010: break;
1011: }
1012:
1013:
1014: case WM_PAINT:{
1015: HDC hCompatDC;
1016: RECT rc;
1017: PAINTSTRUCT ps;
1018:
1019: //
1020: // Paint btnshadow background.
1021: //
1022: GetClientRect(hwnd, &rc);
1023:
1024: BeginPaint(hwnd, &ps);
1025:
1026: hCompatDC = CreateCompatibleDC(ps.hdc);
1027: FillRect(ps.hdc, &rc, hBrush);
1028:
1029: EndPaint(hwnd, &ps);
1030:
1031: return(TRUE);
1032: }
1033:
1034: case WM_DESTROY:{
1035: DeleteObject(hBrush);
1036:
1037: for(yVal = 0; yVal < NUM_BITMAPS; yVal++)
1038: DeleteObject(hDrvBmp[yVal]);
1039:
1040: break;
1041: }
1042: }
1043: return DefWindowProc(hwnd, message, wParam, lParam);
1044: }
1045:
1046:
1047: /***************************************************************************\
1048: *
1049: * GetDriveBitmap()
1050: *
1051: * Determines the appropriate index into the drive button bitmap array
1052: * (hDrvBmp[]), given a pointer to a drive info structure (LPDINFO)
1053: *
1054: * lpWalk - pointer to LPDINFO structure.
1055: * lpCurrentDrv - pointer to current drive of active child.
1056: *
1057: *
1058: * History:
1059: * 6/16/92
1060: * Created.
1061: *
1062: \***************************************************************************/
1063: int GetDriveBitmap(LPBINFO lpBWalk)
1064: {
1065: int nBmpIndex;
1066:
1067: EnterCriticalSection(&gDrvCS);
1068:
1069: switch( lpBWalk->lpDrive->DriveType ){
1070: case DRIVE_REMOVABLE:{
1071: nBmpIndex = UB_FLOPPY1 - UB_BMP_MARKER;
1072: break;
1073: }
1074:
1075: case DRIVE_REMOTE:{
1076: nBmpIndex = UB_REMOTE1 - UB_BMP_MARKER;
1077: break;
1078: }
1079:
1080: case DRIVE_CDROM:{
1081: nBmpIndex = UB_CD1 - UB_BMP_MARKER;
1082: break;
1083: }
1084:
1085: case DRIVE_FIXED:
1086: default:{
1087: nBmpIndex = UB_FIXED1 - UB_BMP_MARKER;
1088: break;
1089: }
1090: }
1091:
1092: LeaveCriticalSection(&gDrvCS);
1093:
1094: if( lpBWalk->fButtonDown == TRUE )
1095: nBmpIndex++;
1096:
1097: return(nBmpIndex);
1098: }
1099:
1100:
1101: /***************************************************************************\
1102: *
1103: * ChangeDrive()
1104: *
1105: * Changes the current drive of the active child. Called by the MM_DRIVE_NUM
1106: * cases in MainWndProc and DriveBarProc. This is caused by choosing a
1107: * Drive menu item or selecting a drive button from the drive toolbar.
1108: *
1109: * lpszDriveName - points to a buffer containing the name of the drive
1110: * DriveID - points to the ID of the Menu item or button, which
1111: * corresponds to the index into the drives linked list
1112: * of the new drive.
1113: *
1114: * History:
1115: * 6/20/92
1116: * Created.
1117: *
1118: \***************************************************************************/
1119: BOOL ChangeDrive(LPSTR lpszDriveName, DWORD DriveIndex)
1120: {
1121: LPCINFO lpCInfo;
1122: LPDINFO lpWalk;
1123: DWORD dwLoop;
1124:
1125: //
1126: // Retrieve active child handle.
1127: //
1128: if( (ghActiveChild != ghwndDrv1) &&
1129: (ghActiveChild != ghwndDrv2) ){
1130: ErrorMsg("A Drive Window Must be Active.");
1131: return(0);
1132: }
1133:
1134: //
1135: // Retrieving the child window's DRVCHILDINFO data
1136: //
1137: lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA);
1138:
1139: //
1140: // Enter Drive list critical section
1141: //
1142: EnterCriticalSection(&gDrvCS);
1143:
1144: //
1145: // if removable drive, check for existing media.
1146: //
1147: if( GetDriveType(lpszDriveName) == DRIVE_REMOVABLE ){
1148: dwLoop = (DWORD)IDOK;
1149:
1150: while( !CheckRM(lpszDriveName) && (dwLoop == (DWORD)IDOK) ){
1151:
1152: dwLoop = (DWORD)MessageBox(ghwndMain,
1153: "Filer: Insert some media in drive",
1154: lpszDriveName, MB_OKCANCEL);
1155: }
1156:
1157: if( dwLoop == (DWORD)IDCANCEL ){
1158: SendMessage(ghwndDrives, WM_COMMAND, MM_ACTIVEDRV,
1159: (LPARAM)lpCInfo->lpDriveInfo);
1160: return(0);
1161: }
1162: }
1163:
1164: //
1165: // Kill any current dir refresh thread.
1166: //
1167: if( WaitForSingleObject(lpCInfo->hDirThread, 0) == WAIT_TIMEOUT )
1168: lpCInfo->fAlive = FALSE;
1169:
1170: //
1171: // set lpDriveInfo member to associated drive struct.
1172: //
1173: lpWalk = glpDrives;
1174: for( dwLoop = 0; dwLoop < DriveIndex - MM_DRIVE_NUM;
1175: dwLoop++)
1176: lpWalk = lpWalk->next;
1177:
1178: lpCInfo->lpDriveInfo = lpWalk;
1179:
1180: strcpy(lpCInfo->CaptionBarText, lpWalk->DriveName);
1181:
1182: LeaveCriticalSection(&gDrvCS);
1183:
1184: SendMessage(ghActiveChild, WM_COMMAND, MM_REFRESH, (LPARAM)NULL);
1185:
1186: return(1);
1187: }
1188:
1189:
1190: /***************************************************************************\
1191: *
1192: * FunctionBarProc
1193: *
1194: * ToolBar Window procedure for displaying File I/O functions.
1195: * ghwndFunction is the global handle assoc. w/ this Dlg procedure.
1196: *
1197: * History:
1198: * 6/8/92
1199: * Created.
1200: *
1201: \***************************************************************************/
1202:
1203: LRESULT FunctionBarProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1204: {
1205: static HBRUSH hBrush;
1206:
1207: switch (message){
1208: case WM_INITDIALOG:{
1209: HWND hButton;
1210: RECT rc;
1211:
1212: hButton = GetDlgItem(hDlg, MM_COPY);
1213:
1214: GetWindowRect(hButton, &rc);
1215:
1216: SetWindowLong(hDlg, GWL_USERDATA, rc.bottom - rc.top);
1217:
1218: //
1219: // Sets background color of Toolbar non-modal dialog children.
1220: //
1221: hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
1222:
1223: return(FALSE);
1224: }
1225:
1226: case WM_PAINT:{
1227: RECT rc;
1228: PAINTSTRUCT ps;
1229:
1230: //
1231: // Paint btnshadow background.
1232: //
1233: GetClientRect(hDlg, &rc);
1234: InvalidateRect(hDlg, &rc, FALSE);
1235:
1236: BeginPaint(hDlg, &ps);
1237:
1238: FillRect(ps.hdc, &rc, hBrush);
1239:
1240: EndPaint(hDlg, &ps);
1241:
1242: return(TRUE);
1243: }
1244:
1245: //
1246: // Passes button messages ( = file I/O function messages )
1247: // to active Drv child.
1248: //
1249: case WM_COMMAND:{
1250: switch(wParam){
1251: case MM_COPY:
1252: case MM_MOVE:
1253: case MM_DELETE:
1254: case MM_RENAME:
1255: case MM_MKDIR:{
1256: SendMessage(ghActiveChild, message, wParam, lParam);
1257: return(TRUE);
1258: }
1259: }
1260: }
1261:
1262: case WM_DESTROY:{
1263: DeleteObject(hBrush);
1264: break;
1265: }
1266: }
1267:
1268: return(FALSE);
1269: }
1270:
1271:
1272: /***************************************************************************\
1273: *
1274: * UpdateDrivesMenu()
1275: *
1276: * Adds current drives from the glpDrives linked list to the 'Drives' menu
1277: *
1278: * Input: hDrivesMenu - handle to 'Drives' Menu
1279: * hThread - used to wait for drives thread to terminate
1280: *
1281: * History:
1282: * 5/14/92
1283: * Created.
1284: *
1285: \***************************************************************************/
1286:
1287: BOOL UpdateDrivesMenu(HMENU hMenu, HANDLE hThread)
1288: {
1289: HMENU hDrivesMenu;
1290: int NumMenuItems;
1291: DWORD dwLoop;
1292: LPDINFO lpWalk;
1293:
1294: //
1295: // Remove list of drive menu items from Drive menu, if any.
1296: //
1297: hDrivesMenu = GetSubMenu( hMenu, DRIVE_MENU_NUM);
1298: if( !hDrivesMenu ){
1299: ErrorMsg("UpdateDrivesMenu: GetSubMenu error.");
1300: return(FALSE);
1301: }
1302:
1303: if( (NumMenuItems = GetMenuItemCount(hDrivesMenu)) == -1)
1304: ErrorMsg("Main Refresh: Menu Item Count Error.");
1305:
1306: //
1307: // Delete previous menu items.
1308: //
1309: for( dwLoop = 0; dwLoop < (DWORD)NumMenuItems; dwLoop++)
1310: if( !DeleteMenu( hDrivesMenu, 0,
1311: MF_BYPOSITION) ){
1312: ErrorMsg("Main Refresh: Menu Item Delete Error.");
1313: return(FALSE);
1314: }
1315:
1316: //
1317: // Wait for Enumdrv Thread to terminate, and
1318: // enter drive list critical section
1319: //
1320: WaitForSingleObject(hThread, (DWORD)0xFFFFFFFF);
1321: EnterCriticalSection(&gDrvCS);
1322:
1323: //
1324: // Fill drive menu from glpDrives linked list
1325: //
1326: NumMenuItems = 0;
1327: lpWalk = glpDrives;
1328:
1329: while(lpWalk != NULL){
1330: if( !InsertMenu( hDrivesMenu, NumMenuItems, MF_STRING |
1331: MF_BYPOSITION | MF_ENABLED, MM_DRIVE_NUM + NumMenuItems,
1332: lpWalk->DriveName) )
1333: ErrorMsg("Main Refresh: Menu Item Insert Error.");
1334:
1335: NumMenuItems++;
1336: lpWalk = lpWalk->next;
1337: }
1338:
1339: LeaveCriticalSection(&gDrvCS);
1340:
1341: return(TRUE);
1342: }
1343:
1344:
1345: /***************************************************************************\
1346: *
1347: * ErrorMsg()
1348: *
1349: * Displays a Message Box with a given error message.
1350: *
1351: * History:
1352: * 5/28/92
1353: * Created.
1354: *
1355: \***************************************************************************/
1356: void ErrorMsg(LPSTR szMsg)
1357: {
1358: MessageBox(ghwndMain, szMsg, "FILER Error.", MB_OK);
1359: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.