FILER.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:49k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 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.
- *
- * Dependencies:
- *
- * (#defines)
- * (#includes)
- * -Enumdrv.h
- * -Walk.h
- * -Drvproc.h
- * -Filer.h
- *
- **************************************************************************/
- #define STRICT
- #include <windows.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include "globals.h"
- #include "enumdrv.h"
- #include "drvproc.h"
- #include "filer.h"
- //
- // Global Handles
- //
- HANDLE ghModule; // Process Instance handle
- HWND ghwndMain; // Main window handle
- HWND ghwndDrives; // Drives Toolbar window handle
- HWND ghwndFunction; // Function Toolbar window handle
- HWND ghwndCommand; // Command Line window handle
- HWND ghwndDrv1,
- ghwndDrv2;
- HWND ghActiveChild = NULL; // Handle to active drive child window
- HWND ghFocusWnd; // Handle to last listbox with focus
- HANDLE ghHeap; // Application heap handle
- HFONT ghFont;
- HANDLE ghDrvThread = NULL;
- HMENU ghMenu; // App Menu variables
- //
- // Global Data Items
- //
- BOOL gfDrvWndOrient = SIDE_BY_SIDE, // relative Drv child pos.
- gfKeepCommandWin = FALSE;
- DRVCHILDINFO gDrvChild1Info,
- gDrvChild2Info;
- LPDINFO glpDrives = NULL; // Root of Available Drives linked list
- CRITICAL_SECTION gDrvCS; // Drive list critical section var.
- CRITICAL_SECTION gHeapCS; // Global heap critical section.
- 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
- *
- *
- * History:
- * 04-17-91
- * Created.
- ***************************************************************************/
- int WINAPI WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- 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(TEXT("Filer: InitializeApp failure!"));
- return 0;
- }
- ShowWindow(ghwndMain, nCmdShow);
- if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
- ErrorMsg(TEXT("Filer: Load Accel failure!"));
- while (GetMessage(&msg, NULL, 0, 0)) {
- if( !TranslateAccelerator(ghwndMain, hAccel, &msg) ) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return 1;
- UNREFERENCED_PARAMETER(lpCmdLine);
- UNREFERENCED_PARAMETER(hPrevInstance);
- }
- /***************************************************************************
- * InitializeApp
- *
- * History:
- * 5/5/92
- * Created
- ***************************************************************************/
- BOOL InitializeApp(void)
- {
- WNDCLASS wc;
- wc.style = 0;
- wc.lpfnWndProc = (WNDPROC)MainWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = ghModule;
- wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(UI_FILERICON));
- wc.hCursor = LoadCursor(ghModule, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);
- wc.lpszMenuName = TEXT("FilerMenu");
- wc.lpszClassName = TEXT("FilerClass");
- if (!RegisterClass(&wc))
- return(FALSE);
- 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 = TEXT("DriveBarClass");
- if (!RegisterClass(&wc))
- return(FALSE);
- 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, TEXT("FilerMenu"));
- ghwndMain = CreateWindow(TEXT("FilerClass"),
- TEXT("Filer"),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- MAIN_WIDTH,
- MAIN_HEIGHT,
- HWND_DESKTOP,
- ghMenu,
- ghModule,
- NULL);
- if (ghwndMain == NULL)
- return(FALSE);
- return(TRUE);
- }
- /***************************************************************************
- * MainWndProc
- *
- * History:
- * 05-01-92 Created.
- ***************************************************************************/
- LRESULT WINAPI MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message) {
- case WM_CREATE:{
- LOGFONT lf;
- HDC hDC;
- HGDIOBJ hOldFont;
- TEXTMETRIC tm;
- DWORD dwThreadID;
- //
- // Initialize drive list and Set Directory critical sections.
- //
- InitializeCriticalSection(&gDrvCS);
- InitializeCriticalSection(&gHeapCS);
- ghDrvThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE)EnumDrives,
- (LPVOID)&glpDrives,
- 0, &dwThreadID);
- //
- // Create the application's heap
- //
- ghHeap = HeapCreate( 0, (DWORD)sizeof(DRVCHILDINFO), 0);
- if( ghHeap == NULL )
- ErrorMsg(TEXT("Main Create: Failed in Creating Heap"));
- //
- // Compute default application font by creating a bold version
- // of the system default icon font.
- //
- SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf),
- (PVOID) &lf, FALSE);
- hDC = GetDC(hwnd);
- // this is the height for 8 point size font in pixels.
- // (1 point = 1/72 in.)
- // Japanese fonts have different characteristics and don't look good in bold
- if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_JAPANESE)
- lf.lfHeight = 10 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
- else {
- lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
- lf.lfWeight = BOLD_FONT;
- }
- ghFont = CreateFontIndirect(&lf);
- hOldFont = SelectObject(hDC, ghFont);
- GetTextMetrics(hDC, &tm);
- if(hOldFont)
- SelectObject(hDC, hOldFont);
- ReleaseDC(hwnd, hDC);
- //
- // Create Drive windows
- //
- gDrvChild1Info.hParent = hwnd;
- gDrvChild2Info.hParent = hwnd;
- ghwndDrv1 = CreateWindow(TEXT("DrvClass"), NULL,
- WS_CHILD |
- WS_CLIPSIBLINGS | WS_VISIBLE,
- 0, 0, 0, 0,
- hwnd, (HMENU) 1, ghModule,
- (LPVOID)&gDrvChild1Info);
- ghActiveChild = ghwndDrv1;
- //
- // 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(TEXT("DriveBarClass"), NULL,
- WS_CHILD | WS_VISIBLE | WS_BORDER,
- 0, 0, 0, 0,
- hwnd, (HMENU) 3, ghModule,
- (LPVOID)NULL);
- ghwndFunction = CreateDialog(ghModule,
- TEXT("FunctionBar"),
- hwnd,
- (DLGPROC)FunctionBarProc);
- ghwndCommand = CreateWindow(TEXT("EDIT"), NULL,
- ES_AUTOHSCROLL | ES_LEFT | WS_BORDER |
- ES_NOHIDESEL | WS_CHILD | WS_VISIBLE,
- 0, 0, 0, 0,
- hwnd,
- (HMENU) COMMAND_ID,
- ghModule,
- NULL);
- //
- // Compute height of command window from font; store in window info.
- // Set command window to default font.
- //
- SetWindowLong( ghwndCommand, GWL_USERDATA,
- tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6);
- SendMessage(ghwndCommand, WM_SETFONT, (WPARAM)ghFont, (LPARAM)FALSE);
- //
- // Load String table entries
- //
- LoadString( ghModule, STR_EXE, &gszExtensions[0][0], EXTENSION_LENGTH);
- LoadString( ghModule, STR_COM, &gszExtensions[1][0], EXTENSION_LENGTH);
- LoadString( ghModule, STR_CMD, &gszExtensions[2][0], EXTENSION_LENGTH);
- LoadString( ghModule, STR_BAT, &gszExtensions[3][0], EXTENSION_LENGTH);
- UpdateDrivesMenu(ghMenu, ghDrvThread);
- return(1);
- }
- case WM_COMMAND:{
- //
- // The menu Identifiers for the drives are (potentially)
- // MM_DRIVE_NUM + 0 thru MM_DRIVE_NUM + 25. They all go to the
- // same case, so we will put the Menu ID in lParam, and
- // MM_DRIVE_NUM in LOWORD(wParam).
- //
- if( (LOWORD(wParam) - MM_DRIVE_NUM) <= 25 &&
- (LOWORD(wParam) - MM_DRIVE_NUM) >= 0 ){
- lParam = LOWORD(wParam);
- wParam = MM_DRIVE_NUM;
- }
- switch (LOWORD(wParam)) {
- //
- // If a drive is selected from the Drives menu, or clicked
- // on the drives toolbar, the currently active child will
- // switch to this drive. Message 'unconverted' (see top of
- // WM_COMMAND case), and sent to DriveBarProc
- //
- case MM_DRIVE_NUM:{
- SendMessage(ghwndDrives, WM_COMMAND,
- (WPARAM)lParam, (LPARAM)NULL);
- return(1);
- }
- //
- // Passes these WM_COMMAND messages to the appropriate active child
- // window proc for processing
- //
- case MM_TAB:
- case MM_ESCAPE:
- case MM_OPEN:
- case MM_COPY:
- case MM_DELETE:
- case MM_MOVE:
- case MM_RENAME:
- case MM_MKDIR:
- case MM_EXPAND:
- case MM_VERSION:{
- SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam);
- 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: {
- DWORD dwThreadID;
- //
- // Initialize/Refresh Drives linked list
- //
- 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,
- (LPVOID)&glpDrives,
- 0, &dwThreadID);
- //
- // Refresh active child, drive toolbar, and drives menu
- //
- SendMessage(ghActiveChild, WM_COMMAND, wParam, lParam);
- SendMessage(ghwndDrives, WM_COMMAND, wParam, lParam);
- UpdateDrivesMenu(ghMenu, ghDrvThread);
- //
- // Mark all for repaint
- //
- InvalidateRect(hwnd,NULL,TRUE);
- }
- else
- MessageBeep(MB_ICONASTERISK);
- return(1);
- }
- //
- // Swaps the directory and file list boxes of the active drv child.
- //
- case MM_SWAP:{
- LPCINFO lpCInfo;
- RECT rect;
- lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA);
- //
- // 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,
- // in order to redraw the listboxes.
- //
- if( !GetClientRect( ghActiveChild, &rect ) )
- return(0);
- SendMessage( ghActiveChild, WM_SIZE, SIZENORMAL,
- MAKELONG( rect.right - rect.left,
- rect.bottom - rect.top) );
- 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
- // by WM_SIZE to size Drv children
- //
- case MM_ORIENT:{
- RECT rect;
- if( gfDrvWndOrient == OVER_UNDER )
- gfDrvWndOrient = SIDE_BY_SIDE;
- else
- gfDrvWndOrient = OVER_UNDER;
- //
- // Send size message with current size to self (main window),
- // in order to redraw the Drv children.
- //
- if( !GetClientRect( hwnd, &rect ) )
- return(0);
- SendMessage( hwnd, WM_SIZE, SIZENORMAL,
- MAKELONG( rect.right - rect.left,
- rect.bottom - rect.top) );
- InvalidateRect(ghwndDrv1,NULL,TRUE);
- InvalidateRect(ghwndDrv2,NULL,TRUE);
- return(1);
- }
- //
- // Toggles the active drive child. Sent from menu.
- // This behaves the same as a WM_MOUSEACTIVATE in one of the
- // Drive children. The PostMessage is so the current Active
- // child will not process the MM_TOGGLE message until after it
- // is no longer active.
- //
- case MM_ACTIVEDRV:{
- LPCINFO lpCInfo;
- PostMessage(ghActiveChild, WM_COMMAND, (WPARAM)MM_TOGGLE,
- (LPARAM)NULL);
- if( ghActiveChild == ghwndDrv1 )
- ghActiveChild = ghwndDrv2;
- else
- ghActiveChild = ghwndDrv1;
- SendMessage(ghActiveChild, WM_COMMAND, (WPARAM)MM_TOGGLE,
- (LPARAM)NULL);
- // change drive button
- lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA);
- SendMessage(ghwndDrives, WM_COMMAND, MM_ACTIVEDRV,
- (LPARAM)lpCInfo->lpDriveInfo);
- return(1);
- }
- //
- // 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:{
- TCHAR lpBuffer[128];
- if (DialogBox(ghModule, TEXT("AboutBox"), ghwndMain, (DLGPROC)AboutProc) == -1) {
- LoadString(ghModule, IDS_ABOUTDLGERR, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- }
- return(1);
- }
- default:
- return( DefWindowProc(hwnd, message, wParam, lParam) );
- }
- return(1);
- }
- //
- // Whenever the window is resized, its children have to be
- // resized accordingly. The GetWindowLong values are the height
- // of the windows queried by this function, and are set in the
- // WM_CREATE cases of their respective WNDPROCs.
- //
- case WM_SIZE:{
- int DrvWndHeight;
- //
- // 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),
- TRUE);
- //
- // Always put the drives toolbar at the top of the frame window
- //
- MoveWindow(ghwndDrives,
- 0,
- 0,
- LOWORD(lParam),
- GetWindowLong(ghwndDrives, GWL_USERDATA),
- TRUE);
- //
- // Always put the Function window just below the drives toolbar.
- //
- MoveWindow(ghwndFunction,
- 0,
- GetWindowLong(ghwndDrives, GWL_USERDATA),
- LOWORD(lParam),
- GetWindowLong(ghwndFunction, GWL_USERDATA),
- TRUE);
- //
- // Always size the Drive Children between the Drives and Command
- // windows. The width is set so that borders overlap.
- //
- if( gfDrvWndOrient == OVER_UNDER ){
- DrvWndHeight = ( HIWORD(lParam) -
- GetWindowLong(ghwndDrives, GWL_USERDATA) -
- GetWindowLong(ghwndFunction, GWL_USERDATA) -
- GetWindowLong(ghwndCommand, GWL_USERDATA) ) / 2;
- MoveWindow(ghwndDrv1,
- -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);
- }
- else{
- DrvWndHeight = HIWORD(lParam) -
- GetWindowLong(ghwndDrives, GWL_USERDATA) -
- GetWindowLong(ghwndFunction, GWL_USERDATA) -
- GetWindowLong(ghwndCommand, GWL_USERDATA);
- MoveWindow(ghwndDrv1,
- -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);
- }
- 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);
- DeleteObject(ghFont);
- DeleteCriticalSection(&gDrvCS);
- DeleteCriticalSection(&gHeapCS);
- PostQuitMessage(0);
- return(1);
- }
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- }
- /***************************************************************************
- * AboutProc
- *
- * About dialog proc.
- *
- * History:
- * 05-13-92 Created.
- ***************************************************************************/
- LRESULT WINAPI AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message) {
- case WM_INITDIALOG:{
- return TRUE;
- }
- case WM_COMMAND:{
- if (wParam == IDOK)
- EndDialog(hDlg, wParam);
- break;
- }
- }
- return FALSE;
- UNREFERENCED_PARAMETER(lParam);
- UNREFERENCED_PARAMETER(hDlg);
- }
- /***************************************************************************
- *
- * DriveBarProc()
- *
- * Drive Toolbar procedure for displaying available drive Icons.
- * A bitmap button is displayed corresponding to the drive type of the
- * given drive, with the drive letter alongside.
- * ghwndDrives is the global handle assoc. w/ this window procedure.
- *
- *
- * History:
- * 6/9/92
- * Created.
- *
- ***************************************************************************/
- LRESULT WINAPI DriveBarProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HBITMAP hDrvBmp[NUM_BITMAPS];
- static HBRUSH hBrush; // background brush
- static int nDrvEntryWidth; // width of button/letter entry
- static int yVal; // y value in toolbar for top left of bmp
- static LPBINFO lpDrvButtonRoot;
- static int nActiveDrvIndex;
- TCHAR lpBuffer[128];
- switch (message)
- {
- case WM_CREATE:{
- HDC hDC;
- HGDIOBJ hOldFont;
- TEXTMETRIC tm;
- LONG lHeight;
- lpDrvButtonRoot = NULL;
- //
- // Load drive button bitmaps.
- //
- for(yVal = 0; yVal < NUM_BITMAPS; yVal++)
- hDrvBmp[yVal] = LoadBitmap( ghModule,
- MAKEINTRESOURCE(UB_BMP_MARKER + yVal) );
- //
- // Sets background color of Toolbar non-modal dialog children.
- //
- hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
- hDC = GetDC(hwnd);
- hOldFont = SelectObject(hDC, ghFont);
- GetTextMetrics(hDC, &tm);
- // base the height of the window on size of text
- // Different display height is optimal if on a Japanese language system
- //
- if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_JAPANESE)
- lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 8;
- else
- lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6;
- //
- // saved the window height, drive button entry width
- // and button y starting value for later reference
- //
- SetWindowLong(hwnd, GWL_USERDATA, lHeight);
- //
- // Width of one button entry = spacing, button, sm. space,
- // drive letter, spacing.
- //
- nDrvEntryWidth = DRIVE_BITMAP_SPACING + DRIVE_BITMAP_WIDTH +
- DRIVE_LETTER_SPACING + tm.tmAveCharWidth +
- DRIVE_BITMAP_SPACING;
- //
- // Center bitmaps (by height) in drive toolbar.
- //
- yVal = (lHeight - DRIVE_BITMAP_HEIGHT)/2;
- SelectObject(hDC, hOldFont);
- ReleaseDC(hwnd, hDC);
- SendMessage(hwnd, WM_COMMAND, (WPARAM)MM_REFRESH, (LPARAM)NULL);
- break;
- }
- case WM_COMMAND:{
- //
- // The button Identifiers for the drives are (potentially)
- // MM_DRIVE_NUM + 0 thru MM_DRIVE_NUM + 25. They all go to the
- // same case, so we will put the Menu ID in lParam, and
- // MM_DRIVE_NUM in LOWORD(wParam).
- //
- if( (LOWORD(wParam) - MM_DRIVE_NUM) <= 25 &&
- (LOWORD(wParam) - MM_DRIVE_NUM) >= 0 ){
- lParam = LOWORD(wParam);
- wParam = MM_DRIVE_NUM;
- }
- switch( LOWORD(wParam) ){
- case MM_REFRESH:{
- LPDINFO lpWalk;
- LPBINFO lpBWalk, lpBHold;
- LPCINFO lpCInfo;
- int xVal = 0;
- int nCount = MM_DRIVE_NUM;
- TCHAR lpBuffer[128];
- 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.
- //
- lpWalk = glpDrives;
- lpBWalk = lpDrvButtonRoot;
- while( lpWalk != NULL ){
- if( lpBWalk == NULL ){ //If at the end of the button list
- // Allocate a LPBINFO (button) structure
- EnterCriticalSection(&gHeapCS);
- lpBWalk = (LPBINFO)HeapAlloc(ghHeap, 0, (DWORD)sizeof(BINFO) );
- LeaveCriticalSection(&gHeapCS);
- // 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;
- }
- else
- lpBWalk->fButtonDown = FALSE;
- // Set a pointer to the corresponding drive in Drive list
- lpBWalk->lpDrive = lpWalk;
- nCount++;
- xVal += nDrvEntryWidth;
- lpBHold = lpBWalk;
- lpBWalk = lpBWalk->next;
- lpWalk = lpWalk->next;
- }
- LeaveCriticalSection(&gDrvCS);
- //
- // 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) ) {
- LoadString(ghModule, IDS_DRVBUTTNERR, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- }
- EnterCriticalSection(&gHeapCS);
- HeapFree(ghHeap, 0, (LPVOID)lpBHold);
- LeaveCriticalSection(&gHeapCS);
- }
- SendMessage(hwnd, WM_PAINT, (WPARAM)NULL, (LPARAM)NULL);
- break;
- }
- //
- // switches the drive button to the newly active drv child's
- // current drive. Called by WM_MOUSEACTIVATE in DrvWndProc,
- // as well as ChangeDrive.
- // lParam contains the drive linked list pointer of the active
- // drv child's LPCINFO struct.
- //
- case MM_ACTIVEDRV:{
- LPBINFO lpBWalk = lpDrvButtonRoot;
- int nCount = 0;
- //
- // 'unpush' old active button
- //
- for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++)
- lpBWalk = lpBWalk->next;
- lpBWalk->fButtonDown = FALSE;
- InvalidateRect(lpBWalk->hButton, NULL, FALSE);
- //
- // change active drive to new before redrawing old.
- // 'push' new active button
- //
- lpBWalk = lpDrvButtonRoot;
- nCount = MM_DRIVE_NUM;
- while( lpBWalk->lpDrive != (LPDINFO)lParam){
- lpBWalk = lpBWalk->next;
- nCount++;
- }
- nActiveDrvIndex = nCount;
- lpBWalk->fButtonDown = TRUE;
- InvalidateRect(lpBWalk->hButton, NULL, FALSE);
- break;
- }
- //
- // Changes drive of active child. ButtonID in lParam.
- //
- case MM_DRIVE_NUM:{
- LPBINFO lpBWalk = lpDrvButtonRoot;
- int nCount = 0;
- TCHAR szDrvBuff[DIRECTORY_STRING_SIZE];
- //
- // if drive chosen is already current drive, leave.
- //
- if( nActiveDrvIndex == (int)lParam )
- break;
- //
- // unpush' old active button
- //
- for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++)
- lpBWalk = lpBWalk->next;
- lpBWalk->fButtonDown = FALSE;
- //
- // change active drive to new before redrawing old.
- //
- nActiveDrvIndex = (int)lParam;
- InvalidateRect(lpBWalk->hButton, NULL, FALSE);
- //
- // 'push' new active button
- //
- lpBWalk = lpDrvButtonRoot;
- for( nCount = MM_DRIVE_NUM; nCount < nActiveDrvIndex; nCount++)
- lpBWalk = lpBWalk->next;
- lpBWalk->fButtonDown = TRUE;
- InvalidateRect(lpBWalk->hButton, NULL, FALSE);
- GetWindowText(lpBWalk->hButton, szDrvBuff,
- DIRECTORY_STRING_SIZE);
- if( !ChangeDrive(szDrvBuff, (DWORD)nActiveDrvIndex) ){
- LoadString(ghModule, IDS_CHNGDRVERR, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- return(0);
- }
- break;
- }
- }
- return(1);
- }
- //
- // Sent by all created buttons for initialization purposes.
- //
- case WM_MEASUREITEM:{
- LPMEASUREITEMSTRUCT lpMIS;
- lpMIS = (LPMEASUREITEMSTRUCT)lParam;
- lpMIS->CtlType = ODT_BUTTON;
- lpMIS->CtlID = (UINT)wParam;
- lpMIS->itemWidth = DRIVE_BITMAP_WIDTH;
- lpMIS->itemHeight = DRIVE_BITMAP_HEIGHT;
- return(1);
- }
- //
- // Sent by owner draw drive buttons when needing redrawing.
- //
- case WM_DRAWITEM:{
- LPBINFO lpBWalk = lpDrvButtonRoot;
- int nCount;
- int nBmpIndex;
- HDC hDC;
- HDC hCompatDC;
- HGDIOBJ hOldBitmap;
- TCHAR szDrvBuff[DIRECTORY_STRING_SIZE];
- LPDRAWITEMSTRUCT lpDIS;
- lpDIS = (LPDRAWITEMSTRUCT)lParam;
- for( nCount = MM_DRIVE_NUM; nCount < (int)wParam; nCount++)
- lpBWalk = lpBWalk->next;
- //
- // If not the current selected button, handle button stuff.
- //
- if( (int)wParam != nActiveDrvIndex ){
- //
- // mousebutton is down...
- //
- if( lpDIS->itemAction & ODA_SELECT ){
- //
- // left button region, 'unpush' button
- //
- if( lpDIS->itemState == (UINT)ODS_FOCUS )
- lpBWalk->fButtonDown = FALSE;
- //
- // clicked on a button, draw 'pushed' button
- //
- if( lpDIS->itemState == (UINT)(ODS_SELECTED | ODS_FOCUS))
- lpBWalk->fButtonDown = TRUE;
- }
- }
- //
- // draw current state of button.
- //
- GetWindowText(lpDIS->hwndItem, szDrvBuff,
- DIRECTORY_STRING_SIZE);
- szDrvBuff[1] = TEXT(' ');
- hCompatDC = CreateCompatibleDC(lpDIS->hDC);
- hOldBitmap = CreateCompatibleBitmap(hCompatDC,
- DRIVE_BITMAP_WIDTH,
- DRIVE_BITMAP_HEIGHT);
- nBmpIndex = GetDriveBitmap(lpBWalk);
- SelectObject( hCompatDC, hDrvBmp[nBmpIndex] );
- if( !hOldBitmap ) {
- LoadString(ghModule, IDS_SELOBJERR, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- }
- if( !BitBlt(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
- DRIVE_BITMAP_WIDTH,
- DRIVE_BITMAP_HEIGHT,
- hCompatDC, 0, 0, SRCCOPY) ) {
- LoadString(ghModule, IDS_BITBLTERR, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- }
- SelectObject( hCompatDC, hOldBitmap);
- DeleteDC(hCompatDC);
- hDC = GetDC(hwnd);
- SetBkMode(hDC, TRANSPARENT);
- SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT) );
- SetBkColor(hDC, GetSysColor(COLOR_BTNSHADOW) );
- // Allow for a different aesthetic for Japanese systems
- if (GetUserDefaultLangID() == LANG_JAPANESE)
- TextOut(hDC,
- ((int)(wParam - MM_DRIVE_NUM) * nDrvEntryWidth) +
- DRIVE_BITMAP_SPACING + DRIVE_BITMAP_WIDTH +
- DRIVE_LETTER_SPACING,
- GetSystemMetrics(SM_CYBORDER)/2,
- szDrvBuff, 1);
- else
- TextOut(hDC,
- ((int)(wParam - MM_DRIVE_NUM) * nDrvEntryWidth) +
- DRIVE_BITMAP_SPACING + DRIVE_BITMAP_WIDTH +
- DRIVE_LETTER_SPACING,
- (GetSystemMetrics(SM_CYBORDER) + 6)/2,
- szDrvBuff, 1);
- SetBkMode(hDC, OPAQUE);
- ReleaseDC(hwnd, hDC);
- break;
- }
- case WM_PAINT:{
- HDC hCompatDC;
- RECT rc;
- PAINTSTRUCT ps;
- //
- // Paint btnshadow background.
- //
- GetClientRect(hwnd, &rc);
- BeginPaint(hwnd, &ps);
- hCompatDC = CreateCompatibleDC(ps.hdc);
- FillRect(ps.hdc, &rc, hBrush);
- EndPaint(hwnd, &ps);
- return(TRUE);
- }
- case WM_DESTROY:{
- DeleteObject(hBrush);
- for(yVal = 0; yVal < NUM_BITMAPS; yVal++)
- DeleteObject(hDrvBmp[yVal]);
- break;
- }
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- /***************************************************************************
- *
- * GetDriveBitmap()
- *
- * Determines the appropriate index into the drive button bitmap array
- * (hDrvBmp[]), given a pointer to a drive info structure (LPDINFO)
- *
- * lpWalk - pointer to LPDINFO structure.
- * lpCurrentDrv - pointer to current drive of active child.
- *
- *
- * History:
- * 6/16/92
- * Created.
- *
- ***************************************************************************/
- int GetDriveBitmap(LPBINFO lpBWalk)
- {
- int nBmpIndex;
- EnterCriticalSection(&gDrvCS);
- switch( lpBWalk->lpDrive->DriveType ){
- case DRIVE_REMOVABLE:{
- nBmpIndex = UB_FLOPPY1 - UB_BMP_MARKER;
- break;
- }
- case DRIVE_REMOTE:{
- nBmpIndex = UB_REMOTE1 - UB_BMP_MARKER;
- break;
- }
- case DRIVE_CDROM:{
- nBmpIndex = UB_CD1 - UB_BMP_MARKER;
- break;
- }
- case DRIVE_FIXED:
- default:{
- nBmpIndex = UB_FIXED1 - UB_BMP_MARKER;
- break;
- }
- }
- LeaveCriticalSection(&gDrvCS);
- if( lpBWalk->fButtonDown == TRUE )
- nBmpIndex++;
- return(nBmpIndex);
- }
- /***************************************************************************
- *
- * ChangeDrive()
- *
- * Changes the current drive of the active child. Called by the MM_DRIVE_NUM
- * cases in MainWndProc and DriveBarProc. This is caused by choosing a
- * Drive menu item or selecting a drive button from the drive toolbar.
- *
- * lpszDriveName - points to a buffer containing the name of the drive
- * DriveID - points to the ID of the Menu item or button, which
- * corresponds to the index into the drives linked list
- * of the new drive.
- *
- * History:
- * 6/20/92
- * Created.
- *
- ***************************************************************************/
- BOOL ChangeDrive(LPTSTR lpszDriveName, DWORD DriveIndex)
- {
- LPCINFO lpCInfo;
- LPDINFO lpWalk;
- DWORD dwLoop;
- UINT nDriveType;
- TCHAR lpBuffer[128];
- //
- // Retrieve active child handle.
- //
- if( (ghActiveChild != ghwndDrv1) &&
- (ghActiveChild != ghwndDrv2) ){
- LoadString(ghModule, IDS_DRVNOTACTVE, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- return(0);
- }
- //
- // Retrieving the child window's DRVCHILDINFO data
- //
- lpCInfo = (LPCINFO)GetWindowLong(ghActiveChild, GWL_USERDATA);
- //
- // Enter Drive list critical section
- //
- EnterCriticalSection(&gDrvCS);
- //
- // if removable drive, check for existing media.
- //
- nDriveType = GetDriveType(lpszDriveName);
- if( nDriveType == DRIVE_REMOVABLE ||
- nDriveType == DRIVE_CDROM ){
- dwLoop = (DWORD)IDOK;
- LoadString(ghModule, IDS_INSRTMEDIA, lpBuffer, sizeof(lpBuffer));
- while( !CheckRM(lpszDriveName) && (dwLoop == (DWORD)IDOK) ){
- dwLoop = (DWORD)MessageBox(ghwndMain, lpBuffer, lpszDriveName, MB_OKCANCEL);
- }
- if( dwLoop == (DWORD)IDCANCEL ){
- SendMessage(ghwndDrives, WM_COMMAND, MM_ACTIVEDRV,
- (LPARAM)lpCInfo->lpDriveInfo);
- LeaveCriticalSection(&gDrvCS);
- return(0);
- }
- }
- //
- // set lpDriveInfo member to associated drive struct.
- //
- lpWalk = glpDrives;
- for( dwLoop = 0; dwLoop < DriveIndex - MM_DRIVE_NUM;
- dwLoop++)
- lpWalk = lpWalk->next;
- lpCInfo->lpDriveInfo = lpWalk;
- lstrcpy(lpCInfo->CaptionBarText, lpWalk->DriveName);
- LeaveCriticalSection(&gDrvCS);
- //
- // 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);
- }
- /***************************************************************************
- *
- * FunctionBarProc
- *
- * ToolBar Window procedure for displaying File I/O functions.
- * ghwndFunction is the global handle assoc. w/ this Dlg procedure.
- *
- * History:
- * 6/8/92
- * Created.
- *
- ***************************************************************************/
- LRESULT WINAPI FunctionBarProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HBRUSH hBrush;
- switch (message){
- case WM_INITDIALOG:{
- HWND hButton;
- RECT rc;
- hButton = GetDlgItem(hDlg, MM_COPY);
- GetWindowRect(hButton, &rc);
- SetWindowLong(hDlg, GWL_USERDATA, rc.bottom - rc.top);
- //
- // Sets background color of Toolbar non-modal dialog children.
- //
- hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
- return(FALSE);
- }
- case WM_PAINT:{
- RECT rc;
- PAINTSTRUCT ps;
- //
- // Paint btnshadow background.
- //
- GetClientRect(hDlg, &rc);
- InvalidateRect(hDlg, &rc, FALSE);
- BeginPaint(hDlg, &ps);
- FillRect(ps.hdc, &rc, hBrush);
- EndPaint(hDlg, &ps);
- return(TRUE);
- }
- //
- // Passes button messages ( = file I/O function messages )
- // to active Drv child.
- //
- case WM_COMMAND:{
- switch(wParam){
- case MM_COPY:
- case MM_MOVE:
- case MM_DELETE:
- case MM_RENAME:
- case MM_MKDIR:{
- SendMessage(ghActiveChild, message, wParam, lParam);
- return(TRUE);
- }
- }
- }
- case WM_DESTROY:{
- DeleteObject(hBrush);
- break;
- }
- }
- return(FALSE);
- }
- /***************************************************************************
- *
- * RunCommandItem()
- *
- *
- * History:
- * 5/26/93
- * Created.
- *
- ***************************************************************************/
- BOOL RunCommandItem(LPCINFO lpCInfo)
- {
- TCHAR szCmdLine[DIRECTORY_STRING_SIZE * 2] = TEXT("cmd ");
- LPTSTR lpszHold;
- TCHAR lpBuffer[128];
- 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(' '));
- if( SendMessage( ghwndCommand, WM_GETTEXT,
- DIRECTORY_STRING_SIZE,
- (LPARAM)lpszHold) == LB_ERR ){
- LoadString(ghModule, IDS_SRCSTRNGERR, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- 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, (LPTSTR)szCmdLine, NULL, NULL, FALSE,
- CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
- NULL, lpCInfo->CaptionBarText, &si, &pi) ){
- LoadString(ghModule, IDS_CANTSPAWN, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- 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 TEXT('Drives') menu
- *
- * Input: hDrivesMenu - handle to TEXT('Drives') Menu
- * hThread - used to wait for drives thread to terminate
- *
- * History:
- * 5/14/92
- * Created.
- *
- ***************************************************************************/
- BOOL UpdateDrivesMenu(HMENU hMenu, HANDLE hThread)
- {
- HMENU hDrivesMenu;
- int NumMenuItems;
- DWORD dwLoop;
- LPDINFO lpWalk;
- TCHAR lpBuffer[128];
- //
- // Remove list of drive menu items from Drive menu, if any.
- //
- hDrivesMenu = GetSubMenu( hMenu, DRIVE_MENU_NUM);
- if( !hDrivesMenu ){
- LoadString(ghModule, IDS_MENUERR1, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- return(FALSE);
- }
- if( (NumMenuItems = GetMenuItemCount(hDrivesMenu)) == -1) {
- LoadString(ghModule, IDS_MENUERR2, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- }
- //
- // Delete previous menu items.
- //
- for( dwLoop = 0; dwLoop < (DWORD)NumMenuItems; dwLoop++)
- if( !DeleteMenu( hDrivesMenu, 0,
- MF_BYPOSITION) ){
- LoadString(ghModule, IDS_MENUERR3, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- return(FALSE);
- }
- //
- // Wait for Enumdrv Thread to terminate, and
- // enter drive list critical section
- //
- WaitForSingleObject(hThread, INFINITE);
- EnterCriticalSection(&gDrvCS);
- //
- // Fill drive menu from glpDrives linked list
- //
- NumMenuItems = 0;
- lpWalk = glpDrives;
- while(lpWalk != NULL){
- if( !InsertMenu( hDrivesMenu, NumMenuItems, MF_STRING |
- MF_BYPOSITION | MF_ENABLED, MM_DRIVE_NUM + NumMenuItems,
- lpWalk->DriveName)) {
- LoadString(ghModule, IDS_MENUERR4, lpBuffer, sizeof(lpBuffer));
- ErrorMsg(lpBuffer);
- }
- NumMenuItems++;
- lpWalk = lpWalk->next;
- }
- LeaveCriticalSection(&gDrvCS);
- return(TRUE);
- }
- /***************************************************************************
- *
- * ErrorMsg()
- *
- * Displays a Message Box with a given error message.
- *
- * History:
- * 5/28/92
- * Created.
- *
- ***************************************************************************/
- void ErrorMsg(LPTSTR szMsg)
- {
- TCHAR szHold[DIRECTORY_STRING_SIZE + 1];
- lstrcpy( szHold, szMsg );
- lstrcat( szHold, TEXT("n") );
- OutputDebugString(szHold);
- }