|
|
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.