--- mstools/samples/filer/filer.c 2018/08/09 18:20:59 1.1.1.1 +++ mstools/samples/filer/filer.c 2018/08/09 18:24:28 1.1.1.3 @@ -1,15 +1,23 @@ + +/******************************************************************************\ +* This is a part of the Microsoft Source Code Samples. +* Copyright (C) 1993 Microsoft Corporation. +* All rights reserved. +* This source code is only intended as a supplement to +* Microsoft Development Tools and/or WinHelp documentation. +* See these sources for detailed information regarding the +* Microsoft samples programs. +\******************************************************************************/ + /******************************Module*Header*******************************\ +* * Module Name: Filer.c * +* * Filer: SDK sample * + Simple File Management program with GUI front end. * Demonstrates Win32 File I/O API and various User algorithms. * -* Created: 5/05/92 -* Author: Colin Stuart -* -* Copyright (c) 1990 Microsoft Corporation -* * Dependencies: * * (#defines) @@ -20,13 +28,12 @@ * -Filer.h * \**************************************************************************/ +#define STRICT #include -#include #include #include #include "globals.h" #include "enumdrv.h" -#include "walk.h" #include "drvproc.h" #include "filer.h" @@ -42,7 +49,7 @@ HWND ghwndCommand; HWND ghwndDrv1, ghwndDrv2; HWND ghActiveChild = NULL; // Handle to active drive child window -HWND ghFocusLB; // Handle to last listbox with focus +HWND ghFocusWnd; // Handle to last listbox with focus HANDLE ghHeap; // Application heap handle @@ -54,7 +61,8 @@ HMENU ghMenu; // // Global Data Items // -BOOL gfDrvWndOrient = SIDE_BY_SIDE; // relative Drv child pos. +BOOL gfDrvWndOrient = SIDE_BY_SIDE, // relative Drv child pos. + gfKeepCommandWin = FALSE; DRVCHILDINFO gDrvChild1Info, gDrvChild2Info; @@ -63,11 +71,12 @@ LPDINFO glpDrives = NULL; CRITICAL_SECTION gDrvCS; // Drive list critical section var. CRITICAL_SECTION gHeapCS; // Global heap critical section. -CRITICAL_SECTION gSetDirCS; // SetCurrentDirectory critical sect. -char gszCommandLine[DIRECTORY_STRING_SIZE * 2]; -char gszExtensions[NUM_EXTENSION_STRINGS][EXTENSION_LENGTH]; +TCHAR gszCommandLine[DIRECTORY_STRING_SIZE * 2]; +TCHAR gszExtensions[NUM_EXTENSION_STRINGS][EXTENSION_LENGTH]; +VKINFO gVKArray[NUM_VERSION_INFO_KEYS]; // .EXE version info array. + // See GetVersion() in DRVPROC.C /***************************************************************************\ * WinMain @@ -77,7 +86,7 @@ char gszExtensions[NUM_EXTENSION_STRI * 04-17-91 * Created. \***************************************************************************/ -int WinMain( +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, @@ -86,15 +95,24 @@ int WinMain( MSG msg; HANDLE hAccel; + //-- check to make sure we are running on Windows NT + if( GetVersion() & 0x80000000 ) { // 0x80000000 == Windows 3.1 + MessageBox( NULL, + TEXT("Sorry, Filer must run under Windows NT. Filer will now terminate."), + TEXT("Error: Windows NT Required"), MB_OK ); + return( 0 ); + } + ghModule = hInstance; + if (!InitializeApp()) { - ErrorMsg("Filer: InitializeApp failure!"); + ErrorMsg(TEXT("Filer: InitializeApp failure!")); return 0; } ShowWindow(ghwndMain, nCmdShow); if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID)))) - ErrorMsg("Filer: Load Accel failure!"); + ErrorMsg(TEXT("Filer: Load Accel failure!")); while (GetMessage(&msg, NULL, 0, 0)) { @@ -123,60 +141,60 @@ BOOL InitializeApp(void) { WNDCLASS wc; - wc.style = NULL; + wc.style = 0; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; - wc.cbWndExtra = 0; + wc.cbWndExtra = 0; wc.hInstance = ghModule; wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(UI_FILERICON)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); - wc.lpszMenuName = "FilerMenu"; - wc.lpszClassName = "FilerClass"; + wc.hCursor = LoadCursor(ghModule, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); + wc.lpszMenuName = TEXT("FilerMenu"); + wc.lpszClassName = TEXT("FilerClass"); if (!RegisterClass(&wc)) - return(FALSE); + return(FALSE); - wc.lpfnWndProc = DrvWndProc; - wc.hIcon = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = "DrvClass"; + wc.lpfnWndProc = DrvWndProc; + wc.hIcon = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = TEXT("DrvClass"); if (!RegisterClass(&wc)) return(FALSE); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = DriveBarProc; - wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW); - wc.lpszClassName = "DriveBarClass"; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = DriveBarProc; + wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW); + wc.lpszClassName = TEXT("DriveBarClass"); if (!RegisterClass(&wc)) return(FALSE); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = TextWndProc; - wc.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION); - wc.lpszClassName = "TextClass"; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = TextWndProc; + wc.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION); + wc.lpszClassName = TEXT("TextClass"); if (!RegisterClass(&wc)) return(FALSE); - ghMenu = LoadMenu(ghModule, "FilerMenu"); + ghMenu = LoadMenu(ghModule, TEXT("FilerMenu")); - ghwndMain = CreateWindow("FilerClass", - "Filer", + ghwndMain = CreateWindow(TEXT("FilerClass"), + TEXT("Filer"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, MAIN_WIDTH, MAIN_HEIGHT, - HWND_DESKTOP, + HWND_DESKTOP, ghMenu, ghModule, NULL); if (ghwndMain == NULL) - return(FALSE); + return(FALSE); return(TRUE); } @@ -186,10 +204,10 @@ BOOL InitializeApp(void) * MainWndProc * * History: -* 05-01-92 Created. +* 05-01-92 Created. \***************************************************************************/ -LRESULT MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT WINAPI MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -206,7 +224,6 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // InitializeCriticalSection(&gDrvCS); InitializeCriticalSection(&gHeapCS); - InitializeCriticalSection(&gSetDirCS); ghDrvThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)EnumDrives, @@ -218,7 +235,7 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // ghHeap = HeapCreate( 0, (DWORD)sizeof(DRVCHILDINFO), 0); if( ghHeap == NULL ) - ErrorMsg("Main Create: Failed in Creating Heap"); + ErrorMsg(TEXT("Main Create: Failed in Creating Heap")); // // Compute default application font by creating a bold version @@ -233,14 +250,16 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // this is the height for 8 point size font in pixels. // (1 point = 1/72 in.) // - lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72; - lf.lfWeight = BOLD_FONT; + lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72; + lf.lfWeight = BOLD_FONT; + + ghFont = CreateFontIndirect(&lf); + hOldFont = SelectObject(hDC, ghFont); + GetTextMetrics(hDC, &tm); - ghFont = CreateFontIndirect(&lf); - hOldFont = SelectObject(hDC, ghFont); - GetTextMetrics(hDC, &tm); if(hOldFont) SelectObject(hDC, hOldFont); + ReleaseDC(hwnd, hDC); // @@ -249,42 +268,47 @@ LRESULT MainWndProc(HWND hwnd, UINT mess gDrvChild1Info.hParent = hwnd; gDrvChild2Info.hParent = hwnd; - ghwndDrv1 = CreateWindow("DrvClass", NULL, - WS_CHILD | - WS_CLIPSIBLINGS | WS_VISIBLE, - 0, 0, 0, 0, - hwnd, (HMENU) 1, ghModule, - (LPVOID)&gDrvChild1Info); + ghwndDrv1 = CreateWindow(TEXT("DrvClass"), NULL, + WS_CHILD | + WS_CLIPSIBLINGS | WS_VISIBLE, + 0, 0, 0, 0, + hwnd, (HMENU) 1, ghModule, + (LPVOID)&gDrvChild1Info); ghActiveChild = ghwndDrv1; - ghwndDrv2 = CreateWindow("DrvClass", NULL, - WS_CHILD | - WS_CLIPSIBLINGS | WS_VISIBLE, - 0, 0, 0, 0, - hwnd, (HMENU) 2, ghModule, - (LPVOID)&gDrvChild2Info); + // + // Set initial focus to Drive Child 1's Directory listbox. + // + ghFocusWnd = ((LPCINFO)GetWindowLong(ghwndDrv1, GWL_USERDATA))->hDirLB; + + ghwndDrv2 = CreateWindow(TEXT("DrvClass"), NULL, + WS_CHILD | + WS_CLIPSIBLINGS | WS_VISIBLE, + 0, 0, 0, 0, + hwnd, (HMENU) 2, ghModule, + (LPVOID)&gDrvChild2Info); // // Create DriveBar, FunctionBar and Command windows // - ghwndDrives = CreateWindow("DriveBarClass", NULL, + ghwndDrives = CreateWindow(TEXT("DriveBarClass"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 0, 0, hwnd, (HMENU) 3, ghModule, (LPVOID)NULL); ghwndFunction = CreateDialog(ghModule, - "FunctionBar", + TEXT("FunctionBar"), hwnd, - (DLGPROC)FunctionBarProc); + (DLGPROC)FunctionBarProc); - ghwndCommand = CreateWindow("EDIT", NULL, + ghwndCommand = CreateWindow(TEXT("EDIT"), NULL, ES_AUTOHSCROLL | ES_LEFT | WS_BORDER | ES_NOHIDESEL | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, - (HMENU) 3, + (HMENU) COMMAND_ID, ghModule, NULL); @@ -306,7 +330,7 @@ LRESULT MainWndProc(HWND hwnd, UINT mess UpdateDrivesMenu(ghMenu, ghDrvThread); - return(1); + return(1); } case WM_COMMAND:{ @@ -323,7 +347,7 @@ LRESULT MainWndProc(HWND hwnd, UINT mess wParam = MM_DRIVE_NUM; } - switch (LOWORD(wParam)) { + switch (LOWORD(wParam)) { // // If a drive is selected from the Drives menu, or clicked // on the drives toolbar, the currently active child will @@ -343,32 +367,42 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // case MM_TAB: case MM_ESCAPE: - case MM_OPEN: - case MM_COPY: - case MM_DELETE: + case MM_OPEN: + case MM_COPY: + case MM_DELETE: case MM_MOVE: - case MM_RENAME: - case MM_MKDIR:{ + case MM_RENAME: + case MM_MKDIR: + case MM_EXPAND: + case MM_VERSION:{ SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam); - return(1); - } + return(1); + } + + case MM_EXIT:{ + SendMessage(ghwndMain, WM_CLOSE, wParam, lParam); + return(1); + } // // Creates the drive enumeration thread to re-enumerate the // available drives in the main menu. Also sends a refresh // to the active drive child, and repaints the window. // - case MM_REFRESH: { + case MM_REFRESH: { DWORD dwThreadID; - DWORD dwExitCode = 0; // // Initialize/Refresh Drives linked list // - GetExitCodeThread( ghDrvThread, &dwExitCode); - if( dwExitCode != STILL_ACTIVE ){ + if( WaitForSingleObject(ghDrvThread, 0) != WAIT_TIMEOUT ){ + + // + // Close previous Drive Thread handle before creating new handle. + // + CloseHandle( ghDrvThread ); ghDrvThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)EnumDrives, @@ -378,8 +412,8 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // // Refresh active child, drive toolbar, and drives menu // - SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam); - SendMessage(ghwndDrives, WM_COMMAND, wParam, lParam); + SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam); + SendMessage(ghwndDrives, WM_COMMAND, wParam, lParam); UpdateDrivesMenu(ghMenu, ghDrvThread); // @@ -390,6 +424,7 @@ LRESULT MainWndProc(HWND hwnd, UINT mess } else MessageBeep(MB_ICONASTERISK); + return(1); } @@ -397,14 +432,16 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // Swaps the directory and file list boxes of the active drv child. // case MM_SWAP:{ - HWND hHold; LPCINFO lpCInfo; RECT rect; lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA); - hHold = lpCInfo->hwndLL; - lpCInfo->hwndLL = lpCInfo->hwndLR; - lpCInfo->hwndLR = hHold; + + // + // Switch the flag which indicates which side the Directory + // LB is on. This is used by the WM_SIZE case of DrvWndProc. + // + lpCInfo->fDirLeft = !lpCInfo->fDirLeft; // // Send size message with current size to active child, @@ -419,6 +456,19 @@ LRESULT MainWndProc(HWND hwnd, UINT mess return(1); } + case MM_KEEPCMD:{ + + gfKeepCommandWin = !gfKeepCommandWin; + + if( gfKeepCommandWin ) + CheckMenuItem( ghMenu, MM_KEEPCMD, + MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem( ghMenu, MM_KEEPCMD, + MF_BYCOMMAND | MF_UNCHECKED); + } + break; + // // Toggles the relative Drive Child orientaion between // Over/under and side/side. gfDrvWndOrient is a flag checked @@ -473,16 +523,26 @@ LRESULT MainWndProc(HWND hwnd, UINT mess } // + // Sent by the Command line Edit control. + // + case COMMAND_ID:{ + + if( HIWORD(wParam) == EN_SETFOCUS ) + ghFocusWnd = ghwndCommand; + } + break; + + // // Launches the About DialogBox. // - case MM_ABOUT:{ - if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)AboutProc) == -1) - ErrorMsg("Main: About Dialog Creation Error!"); - return(1); + case MM_ABOUT:{ + if (DialogBox(ghModule, TEXT("AboutBox"), ghwndMain, (DLGPROC)AboutProc) == -1) + ErrorMsg(TEXT("Main: About Dialog Creation Error!")); + return(1); } - default: - return( DefWindowProc(hwnd, message, wParam, lParam) ); + default: + return( DefWindowProc(hwnd, message, wParam, lParam) ); } return(1); } @@ -499,19 +559,19 @@ LRESULT MainWndProc(HWND hwnd, UINT mess // Always put the command window at the bottom of the frame window // MoveWindow(ghwndCommand, - 0, - HIWORD(lParam) - GetWindowLong(ghwndCommand, GWL_USERDATA), - LOWORD(lParam), - GetWindowLong(ghwndCommand, GWL_USERDATA), + 0, + HIWORD(lParam) - GetWindowLong(ghwndCommand, GWL_USERDATA), + LOWORD(lParam), + GetWindowLong(ghwndCommand, GWL_USERDATA), TRUE); // // Always put the drives toolbar at the top of the frame window // MoveWindow(ghwndDrives, - 0, - 0, - LOWORD(lParam), - GetWindowLong(ghwndDrives, GWL_USERDATA), + 0, + 0, + LOWORD(lParam), + GetWindowLong(ghwndDrives, GWL_USERDATA), TRUE); // @@ -537,20 +597,21 @@ LRESULT MainWndProc(HWND hwnd, UINT mess GetWindowLong(ghwndCommand, GWL_USERDATA) ) / 2; MoveWindow(ghwndDrv1, - -1, - GetWindowLong(ghwndDrives, GWL_USERDATA)+ - GetWindowLong(ghwndFunction, GWL_USERDATA), - LOWORD(lParam) + 2, - DrvWndHeight, - TRUE); + -1, + GetWindowLong(ghwndDrives, GWL_USERDATA)+ + GetWindowLong(ghwndFunction, GWL_USERDATA), + LOWORD(lParam) + 2, + DrvWndHeight, + TRUE); MoveWindow(ghwndDrv2, - -1, - GetWindowLong(ghwndDrives, GWL_USERDATA)+ - GetWindowLong(ghwndFunction, GWL_USERDATA) + DrvWndHeight, - LOWORD(lParam) + 2, - DrvWndHeight, - TRUE); + -1, + GetWindowLong(ghwndDrives, GWL_USERDATA)+ + GetWindowLong(ghwndFunction, GWL_USERDATA) + + DrvWndHeight, + LOWORD(lParam) + 2, + DrvWndHeight, + TRUE); } else{ @@ -560,26 +621,32 @@ LRESULT MainWndProc(HWND hwnd, UINT mess GetWindowLong(ghwndCommand, GWL_USERDATA); MoveWindow(ghwndDrv1, - -1, - GetWindowLong(ghwndDrives, GWL_USERDATA)+ - GetWindowLong(ghwndFunction, GWL_USERDATA), - LOWORD(lParam)/2 + 1, - DrvWndHeight, - TRUE); + -1, + GetWindowLong(ghwndDrives, GWL_USERDATA)+ + GetWindowLong(ghwndFunction, GWL_USERDATA), + LOWORD(lParam)/2 + 1, + DrvWndHeight, + TRUE); MoveWindow(ghwndDrv2, - LOWORD(lParam)/2, - GetWindowLong(ghwndDrives, GWL_USERDATA)+ - GetWindowLong(ghwndFunction, GWL_USERDATA), - LOWORD(lParam)/2 + 1, - DrvWndHeight, - TRUE); + LOWORD(lParam)/2, + GetWindowLong(ghwndDrives, GWL_USERDATA)+ + GetWindowLong(ghwndFunction, GWL_USERDATA), + LOWORD(lParam)/2 + 1, + DrvWndHeight, + TRUE); } - return(1); + return(1); } case WM_DESTROY: { + // + // Close last drive thread handle, the global heap and it's corresponding critical section, + // the created font, and the Drive list critical section. + // + CloseHandle( ghDrvThread ); + EnterCriticalSection(&gHeapCS); HeapDestroy(ghHeap); LeaveCriticalSection(&gHeapCS); @@ -587,10 +654,10 @@ LRESULT MainWndProc(HWND hwnd, UINT mess DeleteObject(ghFont); DeleteCriticalSection(&gDrvCS); - DeleteCriticalSection(&gSetDirCS); + DeleteCriticalSection(&gHeapCS); - PostQuitMessage(0); - return(1); + PostQuitMessage(0); + return(1); } default: @@ -598,6 +665,7 @@ LRESULT MainWndProc(HWND hwnd, UINT mess } } + /***************************************************************************\ * AboutProc * @@ -607,7 +675,7 @@ LRESULT MainWndProc(HWND hwnd, UINT mess * 05-13-92 Created. \***************************************************************************/ -LRESULT AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT WINAPI AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG:{ @@ -644,7 +712,7 @@ LRESULT AboutProc(HWND hDlg, UINT messag * \***************************************************************************/ -LRESULT DriveBarProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT WINAPI DriveBarProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HBITMAP hDrvBmp[NUM_BITMAPS]; static HBRUSH hBrush; // background brush @@ -659,7 +727,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me HDC hDC; HGDIOBJ hOldFont; TEXTMETRIC tm; - LONG lHeight; + LONG lHeight; lpDrvButtonRoot = NULL; @@ -678,19 +746,19 @@ LRESULT DriveBarProc (HWND hwnd, UINT me hDC = GetDC(hwnd); - hOldFont = SelectObject(hDC, ghFont); - GetTextMetrics(hDC, &tm); + hOldFont = SelectObject(hDC, ghFont); + GetTextMetrics(hDC, &tm); // - // base the height of the window on size of text + // base the height of the window on size of text // - lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6; + lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6; // - // saved the window height, drive button entry width + // saved the window height, drive button entry width // and button y starting value for later reference // - SetWindowLong(hwnd, GWL_USERDATA, lHeight); + SetWindowLong(hwnd, GWL_USERDATA, lHeight); // // Width of one button entry = spacing, button, sm. space, @@ -710,7 +778,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me SendMessage(hwnd, WM_COMMAND, (WPARAM)MM_REFRESH, (LPARAM)NULL); - break; + break; } case WM_COMMAND:{ @@ -738,29 +806,59 @@ LRESULT DriveBarProc (HWND hwnd, UINT me lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA); // + // Wait for Drive Thread to complete, if necessary. + // + WaitForSingleObject(ghDrvThread, INFINITE); + EnterCriticalSection(&gDrvCS); + + // // Traverse DRVINFO linked list, creating drive buttons and // allocating corresp. structures as necessary. // - EnterCriticalSection(&gDrvCS); lpWalk = glpDrives; lpBWalk = lpDrvButtonRoot; while( lpWalk != NULL ){ - if( lpBWalk == NULL ){ + if( lpBWalk == NULL ){ //If at the end of the button list + // Allocate a LPBINFO (button) structure EnterCriticalSection(&gHeapCS); - lpBWalk = (LPBINFO)HeapAlloc(ghHeap, sizeof(BINFO)); + lpBWalk = (LPBINFO)HeapAlloc(ghHeap, 0, (DWORD)sizeof(BINFO) ); LeaveCriticalSection(&gHeapCS); - lpBWalk->lpDrive = lpWalk; - lpBWalk->fButtonDown = FALSE; + // Create a button window + lpBWalk->hButton = (HANDLE)CreateWindow(TEXT("BUTTON"), + lpWalk->DriveName, + WS_CHILD | WS_VISIBLE | + BS_OWNERDRAW, + xVal + DRIVE_BITMAP_SPACING, + yVal, + DRIVE_BITMAP_WIDTH, + DRIVE_BITMAP_HEIGHT, + hwnd, + (HMENU)nCount, + ghModule, + NULL); + + // Insert structure into list if( lpDrvButtonRoot == NULL) lpDrvButtonRoot = lpBHold = lpBWalk; else{ lpBHold->next = lpBWalk; lpBWalk->next = NULL; } + } + + // An LPBINFO (button) structure exists: now initialize + + // Set Title of Button (Drive Letter) + SetWindowText(lpBWalk->hButton, lpWalk->DriveName); + + // Set Child Window ID for Button + SetMenu( lpBWalk->hButton, (HMENU)nCount); + + // Determine button up/down status if( lpCInfo->lpDriveInfo == lpWalk ){ nActiveDrvIndex = nCount; lpBWalk->fButtonDown = TRUE; @@ -768,21 +866,9 @@ LRESULT DriveBarProc (HWND hwnd, UINT me else lpBWalk->fButtonDown = FALSE; + // Set a pointer to the corresponding drive in Drive list lpBWalk->lpDrive = lpWalk; - lpBWalk->hButton = (HANDLE)CreateWindow("BUTTON", - lpWalk->DriveName, - WS_CHILD | WS_VISIBLE | - BS_OWNERDRAW, - xVal + DRIVE_BITMAP_SPACING, - yVal, - DRIVE_BITMAP_WIDTH, - DRIVE_BITMAP_HEIGHT, - hwnd, - (HMENU)nCount, - ghModule, - NULL); - nCount++; xVal += nDrvEntryWidth; lpBHold = lpBWalk; @@ -797,13 +883,19 @@ LRESULT DriveBarProc (HWND hwnd, UINT me // Free any remaining button windows. // while( lpBWalk != NULL ){ + // NULL out new end of list + lpBHold->next = NULL; + + // Assign pointer to doomed node lpBHold = lpBWalk; lpBWalk = lpBWalk->next; + + // Free doomed node resources if( !DestroyWindow(lpBHold->hButton) ) - ErrorMsg("DriveBarProc: Drive Button Destroy Error"); + ErrorMsg(TEXT("DriveBarProc: Drive Button Destroy Error")); EnterCriticalSection(&gHeapCS); - HeapFree(ghHeap, (LPSTR)lpBHold); + HeapFree(ghHeap, 0, (LPVOID)lpBHold); LeaveCriticalSection(&gHeapCS); } @@ -834,7 +926,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me // // change active drive to new before redrawing old. - // 'push' new active button + // 'push' new active button // lpBWalk = lpDrvButtonRoot; nCount = MM_DRIVE_NUM; @@ -859,7 +951,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me LPBINFO lpBWalk = lpDrvButtonRoot; int nCount = 0; - CHAR szDrvBuff[DIRECTORY_STRING_SIZE]; + TCHAR szDrvBuff[DIRECTORY_STRING_SIZE]; // // if drive chosen is already current drive, leave. @@ -868,7 +960,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me break; // - // 'unpush' old active button + // unpush' old active button // for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++) lpBWalk = lpBWalk->next; @@ -896,7 +988,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me DIRECTORY_STRING_SIZE); if( !ChangeDrive(szDrvBuff, (DWORD)nActiveDrvIndex) ){ - ErrorMsg("Error changing Drives."); + ErrorMsg(TEXT("Error changing Drives.")); return(0); } @@ -932,7 +1024,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me HDC hDC; HDC hCompatDC; HGDIOBJ hOldBitmap; - CHAR szDrvBuff[DIRECTORY_STRING_SIZE]; + TCHAR szDrvBuff[DIRECTORY_STRING_SIZE]; LPDRAWITEMSTRUCT lpDIS; lpDIS = (LPDRAWITEMSTRUCT)lParam; @@ -967,7 +1059,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me GetWindowText(lpDIS->hwndItem, szDrvBuff, DIRECTORY_STRING_SIZE); - szDrvBuff[1] = '\0'; + szDrvBuff[1] = TEXT('\0'); hCompatDC = CreateCompatibleDC(lpDIS->hDC); hOldBitmap = CreateCompatibleBitmap(hCompatDC, @@ -979,13 +1071,13 @@ LRESULT DriveBarProc (HWND hwnd, UINT me SelectObject( hCompatDC, hDrvBmp[nBmpIndex] ); if( !hOldBitmap ) - OutputDebugString("WM_DRAWITEM: SelectObject error\n"); + ErrorMsg(TEXT("WM_DRAWITEM: SelectObject failure.")); if( !BitBlt(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, DRIVE_BITMAP_WIDTH, DRIVE_BITMAP_HEIGHT, hCompatDC, 0, 0, SRCCOPY) ) - OutputDebugString("WM_DRAWITEM: BitBlt error\n"); + ErrorMsg(TEXT("WM_DRAWITEM: BitBlt failure.")); SelectObject( hCompatDC, hOldBitmap); @@ -1003,7 +1095,7 @@ LRESULT DriveBarProc (HWND hwnd, UINT me (GetSystemMetrics(SM_CYBORDER) + 6)/2, szDrvBuff, 1); - SetBkMode(hDC, OPAQUE); + SetBkMode(hDC, OPAQUE); ReleaseDC(hwnd, hDC); @@ -1116,18 +1208,19 @@ int GetDriveBitmap(LPBINFO lpBWalk) * Created. * \***************************************************************************/ -BOOL ChangeDrive(LPSTR lpszDriveName, DWORD DriveIndex) +BOOL ChangeDrive(LPTSTR lpszDriveName, DWORD DriveIndex) { LPCINFO lpCInfo; LPDINFO lpWalk; DWORD dwLoop; + UINT nDriveType; // // Retrieve active child handle. // if( (ghActiveChild != ghwndDrv1) && (ghActiveChild != ghwndDrv2) ){ - ErrorMsg("A Drive Window Must be Active."); + ErrorMsg(TEXT("A Drive Window Must be Active.")); return(0); } @@ -1144,30 +1237,27 @@ BOOL ChangeDrive(LPSTR lpszDriveName, DW // // if removable drive, check for existing media. // - if( GetDriveType(lpszDriveName) == DRIVE_REMOVABLE ){ + nDriveType = GetDriveType(lpszDriveName); + if( nDriveType == DRIVE_REMOVABLE || + nDriveType == DRIVE_CDROM ){ dwLoop = (DWORD)IDOK; while( !CheckRM(lpszDriveName) && (dwLoop == (DWORD)IDOK) ){ dwLoop = (DWORD)MessageBox(ghwndMain, - "Filer: Insert some media in drive", + TEXT("Filer: Insert some media in drive"), lpszDriveName, MB_OKCANCEL); } if( dwLoop == (DWORD)IDCANCEL ){ SendMessage(ghwndDrives, WM_COMMAND, MM_ACTIVEDRV, (LPARAM)lpCInfo->lpDriveInfo); + LeaveCriticalSection(&gDrvCS); return(0); } } // - // Kill any current dir refresh thread. - // - if( WaitForSingleObject(lpCInfo->hDirThread, 0) == WAIT_TIMEOUT ) - lpCInfo->fAlive = FALSE; - - // // set lpDriveInfo member to associated drive struct. // lpWalk = glpDrives; @@ -1177,11 +1267,20 @@ BOOL ChangeDrive(LPSTR lpszDriveName, DW lpCInfo->lpDriveInfo = lpWalk; - strcpy(lpCInfo->CaptionBarText, lpWalk->DriveName); + lstrcpy(lpCInfo->CaptionBarText, lpWalk->DriveName); LeaveCriticalSection(&gDrvCS); - SendMessage(ghActiveChild, WM_COMMAND, MM_REFRESH, (LPARAM)NULL); + // + // This will terminate any currently running drive thread. + // + SendMessage(ghActiveChild, WM_COMMAND, MM_ESCAPE, (LPARAM)0); + lpCInfo->fEscape = FALSE; + + // + // enact the drive change. + // + PostMessage(ghActiveChild, WM_COMMAND, MM_REFRESH, (LPARAM)0); return(1); } @@ -1199,8 +1298,7 @@ BOOL ChangeDrive(LPSTR lpszDriveName, DW * Created. * \***************************************************************************/ - -LRESULT FunctionBarProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT WINAPI FunctionBarProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HBRUSH hBrush; @@ -1271,11 +1369,78 @@ LRESULT FunctionBarProc(HWND hDlg, UINT /***************************************************************************\ * +* RunCommandItem() +* +* +* History: +* 5/26/93 +* Created. +* +\***************************************************************************/ +BOOL RunCommandItem(LPCINFO lpCInfo) +{ + TCHAR szCmdLine[DIRECTORY_STRING_SIZE * 2] = TEXT("cmd "); + LPTSTR lpszHold; + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + // + // Add the CMD.EXE parameter to keep or kill cmd sessions when done. + // + if( gfKeepCommandWin ) + lstrcat( szCmdLine, TEXT("/k ") ); + else + lstrcat( szCmdLine, TEXT("/c ") ); + + // + // Add command line edit control text. + // + lpszHold = TStrChr(szCmdLine, TEXT('\0')); + + if( SendMessage( ghwndCommand, WM_GETTEXT, + DIRECTORY_STRING_SIZE, + (LPARAM)lpszHold) == LB_ERR ){ + ErrorMsg(TEXT("RunCommandItem: Get Source String failure.")); + return(0); + } + + // + // Attempt to spawn command shell with entry as parameter. + // + si.cb = sizeof(STARTUPINFO); + si.lpReserved = NULL; + si.lpDesktop = NULL; + si.lpTitle = NULL; + si.dwFlags = 0; + si.cbReserved2 = 0; + si.lpReserved2 = NULL; + + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + + if( !CreateProcess(NULL, (LPCTSTR)szCmdLine, NULL, NULL, FALSE, + CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, + NULL, lpCInfo->CaptionBarText, &si, &pi) ){ + ErrorMsg(TEXT("RunListBoxItem: Unable to spawn file.")); + return(0); + } + + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL); + + return(1); +} + + +/***************************************************************************\ +* * UpdateDrivesMenu() * -* Adds current drives from the glpDrives linked list to the 'Drives' menu +* Adds current drives from the glpDrives linked list to the TEXT('Drives') menu * -* Input: hDrivesMenu - handle to 'Drives' Menu +* Input: hDrivesMenu - handle to TEXT('Drives') Menu * hThread - used to wait for drives thread to terminate * * History: @@ -1283,7 +1448,6 @@ LRESULT FunctionBarProc(HWND hDlg, UINT * Created. * \***************************************************************************/ - BOOL UpdateDrivesMenu(HMENU hMenu, HANDLE hThread) { HMENU hDrivesMenu; @@ -1296,12 +1460,12 @@ BOOL UpdateDrivesMenu(HMENU hMenu, HANDL // hDrivesMenu = GetSubMenu( hMenu, DRIVE_MENU_NUM); if( !hDrivesMenu ){ - ErrorMsg("UpdateDrivesMenu: GetSubMenu error."); + ErrorMsg(TEXT("UpdateDrivesMenu: GetSubMenu error.")); return(FALSE); } if( (NumMenuItems = GetMenuItemCount(hDrivesMenu)) == -1) - ErrorMsg("Main Refresh: Menu Item Count Error."); + ErrorMsg(TEXT("Main Refresh: Menu Item Count Error.")); // // Delete previous menu items. @@ -1309,7 +1473,7 @@ BOOL UpdateDrivesMenu(HMENU hMenu, HANDL for( dwLoop = 0; dwLoop < (DWORD)NumMenuItems; dwLoop++) if( !DeleteMenu( hDrivesMenu, 0, MF_BYPOSITION) ){ - ErrorMsg("Main Refresh: Menu Item Delete Error."); + ErrorMsg(TEXT("Main Refresh: Menu Item Delete Error.")); return(FALSE); } @@ -1317,7 +1481,7 @@ BOOL UpdateDrivesMenu(HMENU hMenu, HANDL // Wait for Enumdrv Thread to terminate, and // enter drive list critical section // - WaitForSingleObject(hThread, (DWORD)0xFFFFFFFF); + WaitForSingleObject(hThread, INFINITE); EnterCriticalSection(&gDrvCS); // @@ -1330,7 +1494,7 @@ BOOL UpdateDrivesMenu(HMENU hMenu, HANDL if( !InsertMenu( hDrivesMenu, NumMenuItems, MF_STRING | MF_BYPOSITION | MF_ENABLED, MM_DRIVE_NUM + NumMenuItems, lpWalk->DriveName) ) - ErrorMsg("Main Refresh: Menu Item Insert Error."); + ErrorMsg(TEXT("Main Refresh: Menu Item Insert Error.")); NumMenuItems++; lpWalk = lpWalk->next; @@ -1353,7 +1517,12 @@ BOOL UpdateDrivesMenu(HMENU hMenu, HANDL * Created. * \***************************************************************************/ -void ErrorMsg(LPSTR szMsg) +void ErrorMsg(LPTSTR szMsg) { - MessageBox(ghwndMain, szMsg, "FILER Error.", MB_OK); + TCHAR szHold[DIRECTORY_STRING_SIZE + 1]; + + lstrcpy( szHold, szMsg ); + lstrcat( szHold, TEXT("\n") ); + + OutputDebugString(szHold); }