home *** CD-ROM | disk | FTP | other *** search
- // Borland C++ - (C) Copyright 1991 by Borland International
-
- //*******************************************************************
- //
- // program - Hdump.c
- // purpose - a windows program to dump a file in hex.
- //
- //*******************************************************************
-
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <bios.h>
- #include <ctype.h>
- #include <io.h>
- #include <dos.h>
- #include <dir.h>
-
- #include "hdump.h"
-
- typedef struct scrollkeys
- {
- WORD wVirtkey;
- int iMessage;
- WORD wRequest;
- } SCROLLKEYS;
-
- SCROLLKEYS key2scroll [] =
- {
- VK_HOME, WM_COMMAND, IDM_HOME,
- VK_END, WM_VSCROLL, SB_BOTTOM,
- VK_PRIOR, WM_VSCROLL, SB_PAGEUP,
- VK_NEXT, WM_VSCROLL, SB_PAGEDOWN,
- VK_UP, WM_VSCROLL, SB_LINEUP,
- VK_DOWN, WM_VSCROLL, SB_LINEDOWN,
- VK_LEFT, WM_HSCROLL, SB_PAGEUP,
- VK_RIGHT, WM_HSCROLL, SB_PAGEDOWN
- };
-
- # define NUMKEYS (sizeof key2scroll / sizeof key2scroll[0])
-
- // data initialized by first instance
- typedef struct tagSETUPDATA
- {
- char szAppName[10]; // name of application
- } SETUPDATA;
-
- SETUPDATA SetUpData;
-
- // Data that can be referenced throughout the
- // program but not passed to other instances
-
- HANDLE hInst; // hInstance of application
- HWND hWndMain; // hWnd of main window
- //char szAppName[10]; // name of application
-
- int xChar, yChar, yCharnl; // character size
- int xClient, yClient; // client window size
-
- LOGFONT cursfont; // font structure
- HANDLE holdsfont; // handle of original font
- HANDLE hnewsfont; // handle of new fixed font
-
- // window scroll/paint stuff
- int nVscrollMax, nHscrollMax; // scroll ranges
- int nVscrollPos, nHscrollPos; // current scroll positions
- int numlines; // number of lines in file
- int maxwidth; // width of display format
- int nVscrollInc, nHscrollInc; // scroll increments
- int nPageMaxLines; // max lines on screen
-
- // file open dialog stuff
- char szFileSpec[80]; // file spec for initial search
- char szDefExt[5]; // default extension
- char szFileName[80]; // file name
- char szFilePath[80]; // file path
- WORD wFileAttr; // attribute for search
- WORD wStatus; // status of search
-
- // dump file stuff
- char szFName[64]; // file to display
- FILE *fh; // handle of open file
- LONG fsize; // size of file
-
- // function prototypes
-
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow);
-
- void InitHdump(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow);
- void InitHdumpFirst(HANDLE hInstance);
- void InitHdumpAdded(HANDLE hPrevInstance);
- void InitHdumpEvery(HANDLE hInstance, int cmdShow);
- void CloseHdump(void);
- BOOL FAR PASCAL About(HWND hDlg, WORD message, WORD wParam, LONG lParam);
-
- long FAR PASCAL HdumpWndProc(HWND hWnd, WORD message,
- WORD wParam, LONG lParam);
-
- void SetupScroll(HWND hWnd);
- void HdumpPaint(HWND hWnd);
- char *SnapLine(char *szBuf, LPSTR mem, int len,
- int dwid, char *olbl);
-
- int DoFileOpenDlg(HANDLE hInst, HWND hWnd,
- char *szFileSpecIn, char *szDefExtIn,
- WORD wFileAttrIn,
- char *szFilePathOut, char *szFileNameOut);
- extern BOOL FAR PASCAL FileOpenDlgProc(HWND hDlg, unsigned iMessage,
- WORD wParam, LONG lParam);
-
- //*******************************************************************
- // WinMain - Hdump main
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- // hPrevInstance - The instance of the previous instance
- // of this application. This will be 0
- // if this is the first instance.
- // lpszCmdLine - A long pointer to the command line that
- // started this application.
- // cmdShow - Indicates how the window is to be shown
- // initially. ie. SW_SHOWNORMAL, SW_HIDE,
- // SW_MIMIMIZE.
- //
- // returns:
- // wParam from last message.
- //
- //*******************************************************************
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow)
- {
- MSG msg;
-
- // Go init this application.
- InitHdump(hInstance, hPrevInstance, lpszCmdLine, cmdShow);
-
- // Get and dispatch messages for this applicaton.
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return(msg.wParam);
- }
-
- //*******************************************************************
-
- //*******************************************************************
- // InitHdump - init the Hdump application
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- // hPrevInstance - The instance of the previous instance
- // of this application. This will be 0
- // if this is the first instance.
- // lpszCmdLine - A long pointer to the command line that
- // started this application.
- // cmdShow - Indicates how the window is to be shown
- // initially. ie. SW_SHOWNORMAL, SW_HIDE,
- // SW_MIMIMIZE.
- //
- //*******************************************************************
- #pragma argsused
- void InitHdump(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow)
- {
- if (! hPrevInstance) // if no previous instance, this is first
- InitHdumpFirst(hInstance);
- else
- InitHdumpAdded(hPrevInstance); // this is not first instance
-
- InitHdumpEvery(hInstance, cmdShow); // initialization for all instances
- }
-
- //*******************************************************************
- // InitHdumpFirst - done only for first instance of Hdump
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- //
- //*******************************************************************
- void InitHdumpFirst(HANDLE hInstance)
- {
- WNDCLASS wcHdumpClass;
-
- // Get string from resource with application name.
- LoadString(hInstance, IDS_NAME, (LPSTR) SetUpData.szAppName, 10);
-
- // Define the window class for this application.
- wcHdumpClass.lpszClassName = SetUpData.szAppName;
- wcHdumpClass.hInstance = hInstance;
- wcHdumpClass.lpfnWndProc = HdumpWndProc;
- wcHdumpClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcHdumpClass.hIcon = LoadIcon(hInstance, SetUpData.szAppName);
- wcHdumpClass.lpszMenuName = (LPSTR) SetUpData.szAppName;
- wcHdumpClass.hbrBackground = GetStockObject(WHITE_BRUSH);
- wcHdumpClass.style = CS_HREDRAW | CS_VREDRAW;
- wcHdumpClass.cbClsExtra = 0;
- wcHdumpClass.cbWndExtra = 0;
-
- // Register the class
- RegisterClass(&wcHdumpClass);
- }
-
- //*******************************************************************
- // InitHdumpAdded - done only for added instances of Hdump
- //
- // paramaters:
- // hPrevInstance - The instance of the previous instance
- // of this application.
- //
- //*******************************************************************
- void InitHdumpAdded(HANDLE hPrevInstance)
- {
- // get the results of the initialization of first instance
- GetInstanceData(hPrevInstance, (PSTR) &SetUpData, sizeof(SETUPDATA));
- }
-
- //*******************************************************************
- // InitHdumpEvery - done for every instance of Hdump
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- // cmdShow - Indicates how the window is to be shown
- // initially. ie. SW_SHOWNORMAL, SW_HIDE,
- // SW_MIMIMIZE.
- //
- //*******************************************************************
- void InitHdumpEvery(HANDLE hInstance, int cmdShow)
- {
- TEXTMETRIC tm;
- HDC hDC;
-
- hInst = hInstance; // save for use by window procs
-
- // Create applications main window.
- hWndMain = CreateWindow(
- SetUpData.szAppName, // window class name
- SetUpData.szAppName, // window title
- WS_OVERLAPPEDWINDOW | // type of window
- WS_HSCROLL |
- WS_VSCROLL,
- CW_USEDEFAULT, // x window location
- 0, // y
- CW_USEDEFAULT, // cx and size
- 0, // cy
- NULL, // no parent for this window
- NULL, // use the class menu
- hInstance, // who created this window
- NULL // no parms to pass on
- );
-
- // Get the display context.
- hDC = GetDC(hWndMain);
-
- // Build fixed screen font. Needed to display hex formated dump.
- cursfont.lfHeight = 6;
- cursfont.lfWidth = 6;
- cursfont.lfEscapement = 0;
- cursfont.lfOrientation = 0;
- cursfont.lfWeight = FW_NORMAL;
- cursfont.lfItalic = FALSE;
- cursfont.lfUnderline = FALSE;
- cursfont.lfStrikeOut = FALSE;
- cursfont.lfCharSet = ANSI_CHARSET;
- cursfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
- cursfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- cursfont.lfQuality = DEFAULT_QUALITY;
- cursfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
- strcpy(cursfont.lfFaceName, "System");
-
- hnewsfont = CreateFontIndirect((LPLOGFONT) &cursfont);
-
- // Install the font in the current display context.
- holdsfont = SelectObject(hDC, hnewsfont);
-
- // get text metrics for paint
- GetTextMetrics(hDC, &tm);
- xChar = tm.tmAveCharWidth;
- yChar = tm.tmHeight + tm.tmExternalLeading;
- yCharnl = tm.tmHeight;
-
- // Release the display context.
- ReleaseDC(hWndMain, hDC);
-
- // Update display of main window.
- ShowWindow(hWndMain, cmdShow);
- UpdateWindow(hWndMain);
- }
-
- //*******************************************************************
- // CloseHdump - done at termination of every instance of Hdump
- //
- //*******************************************************************
- void CloseHdump()
- {
- }
-
- //*******************************************************************
- // About - handle about dialog messages
- //
- // paramaters:
- // hDlg - The window handle for this message
- // message - The message number
- // wParam - The WORD parmater for this message
- // lParam - The LONG parmater for this message
- //
- //*******************************************************************
- #pragma argsused
- BOOL FAR PASCAL About(HWND hDlg, WORD message, WORD wParam, LONG lParam)
- {
- if (message == WM_INITDIALOG)
- return(TRUE);
-
- else if (message == WM_COMMAND)
- {
- switch (wParam)
- {
- case IDOK:
- EndDialog(hDlg, TRUE);
- return(TRUE);
-
- default:
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- //*******************************************************************
-
- //*******************************************************************
- // HdumpWndProc - handles messages for this application
- //
- // paramaters:
- // hWnd - The window handle for this message
- // message - The message number
- // wParam - The WORD parmater for this message
- // lParam - The LONG parmater for this message
- //
- // returns:
- // depends on message.
- //
- //*******************************************************************
- long FAR PASCAL HdumpWndProc(HWND hWnd, WORD message,
- WORD wParam, LONG lParam)
- {
- static char sztFilePath[64]; // we remember last directory searched
- static char sztFileExt[5];
- static char sztFileSpec[64];
- static char sztFileName[64];
-
- FARPROC lpproc; // pointer to thunk for dialog box
- char buf[128]; // temp buffer
- int i;
- FILE *fh;
-
- switch (message)
- {
- case WM_CREATE:
- // Start file search at current directory
- getcwd(sztFilePath, sizeof(sztFilePath));
- strcat(sztFilePath, "\\");
- strcpy(sztFileExt, ".*");
- strcpy(sztFileName, "");
-
- return(DefWindowProc(hWnd, message, wParam, lParam));
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDM_QUIT:
- // User selected Quit on menu
- PostMessage(hWnd, WM_CLOSE, 0, 0L);
- break;
-
- case IDM_HOME:
- // Used to implement home to topleft from keyboard.
- SendMessage(hWnd, WM_HSCROLL, SB_TOP, 0L); /* not set up */
- SendMessage(hWnd, WM_VSCROLL, SB_TOP, 0L);
- break;
-
- case IDM_ABOUT:
- // Display about box.
- lpproc = MakeProcInstance(About, hInst);
- DialogBox(hInst,
- MAKEINTRESOURCE(ABOUT),
- hWnd,
- lpproc);
- FreeProcInstance(lpproc);
- break;
-
- case IDM_OPEN:
- // Setup initial search path for open dialog box.
- strcpy(sztFileSpec, sztFilePath);
- strcat(sztFileSpec, "*");
- strcat(sztFileSpec, sztFileExt);
-
- // Go ask user to select file to display.
- if (DoFileOpenDlg(hInst,
- hWnd,
- sztFileSpec,
- sztFileExt,
- 0x4010, // drives & subdirectories
- sztFilePath,
- sztFileName))
- {
- // If user said OK construct file path/file name
- // to open.
- strcpy(szFName, sztFilePath);
- strcat(szFName, sztFileName);
-
- // Show file name in window caption.
- sprintf(buf, "hdump - %s", szFName);
- SetWindowText(hWnd, buf);
-
- // Determine file size and some display paramaters.
- fh = fopen(szFName, "r+b");
- if (fh)
- {
- fsize = filelength(fileno(fh));
- numlines = (int) ((fsize + 16L - 1L) / 16L);
- SnapLine(buf, szFName, 16, 16,NULL); // display width
- maxwidth = strlen(buf);
- nVscrollPos = 0;
- nHscrollPos = 0;
-
- fclose(fh);
- }
-
- else // if file open failed.
- {
- SetWindowText(hWnd, "hdump");
- numlines = 0;
- maxwidth = 0;
- }
-
- // Go setup scroll ranges for this file.
- SetupScroll(hWnd);
-
- // Show first part of file.
- InvalidateRect(hWnd, NULL, TRUE);
- UpdateWindow(hWnd);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case WM_SIZE:
- // Save size of window client area.
- if (lParam)
- {
- yClient = HIWORD(lParam);
- xClient = LOWORD(lParam);
-
- yClient = (yClient / yCharnl + 1) * yCharnl;
-
- lParam = MAKELONG(xClient, yClient);
-
- // Go setup scroll ranges and file display area based upon
- // client area size.
- SetupScroll(hWnd);
-
- return(DefWindowProc(hWnd, message, wParam, lParam));
- }
- break;
-
- case WM_VSCROLL:
- // React to the various vertical scroll related actions.
- switch (wParam)
- {
- case SB_TOP:
- nVscrollInc = -nVscrollPos;
- break;
-
- case SB_BOTTOM:
- nVscrollInc = nVscrollMax - nVscrollPos;
- break;
-
- case SB_LINEUP:
- nVscrollInc = -1;
- break;
-
- case SB_LINEDOWN:
- nVscrollInc = 1;
- break;
-
- case SB_PAGEUP:
- nVscrollInc = -max(1, yClient / yChar);
- break;
-
- case SB_PAGEDOWN:
- nVscrollInc = max(1, yClient / yChar);
- break;
-
- case SB_THUMBPOSITION:
- nVscrollInc = LOWORD(lParam) - nVscrollPos;
- break;
-
- case SB_THUMBTRACK:
- nVscrollInc = LOWORD(lParam) - nVscrollPos;
- break;
-
- default:
- nVscrollInc = 0;
- }
-
- nVscrollInc = max(-nVscrollPos,
- min(nVscrollInc, nVscrollMax - nVscrollPos));
- if (nVscrollInc)
- {
- nVscrollPos += nVscrollInc;
- ScrollWindow(hWnd, 0, -yChar * nVscrollInc, NULL, NULL);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
- UpdateWindow(hWnd);
- }
- break;
-
- case WM_HSCROLL:
- // React to the various horizontal scroll related actions.
- switch (wParam)
- {
- case SB_LINEUP:
- nHscrollInc = -1;
- break;
-
- case SB_LINEDOWN:
- nHscrollInc = 1;
- break;
-
- case SB_PAGEUP:
- nHscrollInc = -8;
- break;
-
- case SB_PAGEDOWN:
- nHscrollInc = 8;
- break;
-
- case SB_THUMBPOSITION:
- nHscrollInc = LOWORD(lParam) - nHscrollPos;
- break;
-
- case SB_THUMBTRACK:
- nHscrollInc = LOWORD(lParam) - nHscrollPos;
- break;
-
- default:
- nHscrollInc = 0;
- }
-
- nHscrollInc = max(-nHscrollPos,
- min(nHscrollInc, nHscrollMax - nHscrollPos));
- if (nHscrollInc)
- {
- nHscrollPos += nHscrollInc;
- ScrollWindow(hWnd, -xChar * nHscrollInc, 0, NULL, NULL);
- SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
- UpdateWindow(hWnd);
- }
- break;
-
- case WM_KEYDOWN:
- // Translate various keydown messages to appropriate horizontal
- // and vertical scroll actions.
- for (i = 0; i < NUMKEYS; i++)
- {
- if (wParam == key2scroll[i].wVirtkey)
- {
- SendMessage(hWnd, key2scroll[i].iMessage,
- key2scroll[i].wRequest, 0L);
- break;
- }
- }
- break;
-
- case WM_PAINT:
- // Go paint the client area of the window with the appropriate
- // part of the selected file.
- HdumpPaint(hWnd);
- break;
-
- case WM_DESTROY:
- // This is the end if we were closed by a DestroyWindow call.
- CloseHdump(); // take any necessary wrapup action.
- PostQuitMessage(0); // this is the end...
- break;
-
- case WM_QUERYENDSESSION:
- // If we return TRUE we are saying it's ok with us to end the
- // windows session.
- CloseHdump(); // take any necessary wrapup action.
- return((long) TRUE); // we agree to end session.
-
- case WM_CLOSE:
- // Tell windows to destroy our window.
- DestroyWindow(hWnd);
- break;
-
- default:
- // Let windows handle all messages we choose to ignore.
- return(DefWindowProc(hWnd, message, wParam, lParam));
- }
-
- return(0L);
- }
-
- //*******************************************************************
- // SetupScroll - setup scroll ranges
- //
- // Setup the vertical and horizontal scroll ranges and positions
- // of the applicatons main window based on:
- //
- // numlines - The maximum number of lines to display in a hexdump
- // of the selected file.
- // maxwidth - The width of each line to display as formated for
- // the hexdump.
- //
- // The resulting variables, nVscrollPos and nPageMaxLines, are used
- // by the function HdumpPaint to determine what part of the selected
- // file to display in the window.
- //
- // paramaters:
- // hWnd - The callers window handle
- //
- //*******************************************************************
- void SetupScroll(HWND hWnd)
- {
- // numlines established during open
- nVscrollMax = max(0, numlines - yClient / yChar);
- nVscrollPos = min(nVscrollPos, nVscrollMax);
-
- nHscrollMax = max(0, maxwidth - xClient / xChar);
- nHscrollPos = min(nHscrollPos, nHscrollMax);
-
- SetScrollRange (hWnd, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos (hWnd, SB_VERT, nVscrollPos, TRUE);
-
- SetScrollRange (hWnd, SB_HORZ, 0, nHscrollMax, FALSE);
- SetScrollPos (hWnd, SB_HORZ, nHscrollPos, TRUE);
-
- nPageMaxLines = min(numlines, yClient / yChar);
- }
-
- //*******************************************************************
- // HdumpPaint - paint the main window
- //
- // If a file has been selected, as indicated by numlines being
- // greater than 0, this module will read and display a portion
- // of the file as determined by the current size and scroll
- // position of the window.
- //
- // paramaters:
- // hWnd - The callers window handle
- //
- //*******************************************************************
- void HdumpPaint(HWND hWnd)
- {
- PAINTSTRUCT ps;
- HDC hDC;
- LONG offset;
- int tlen;
- int lpos;
- char buf[128];
- int i;
- int len;
- int hfile;
- HANDLE hbuff;
- LPSTR lpbuff;
- LPSTR lcp;
-
- BeginPaint(hWnd, (LPPAINTSTRUCT) &ps);
- hDC = ps.hdc;
-
- // Establish fixed font in display context.
- SelectObject(hDC, hnewsfont);
-
- if (numlines)
- {
- // Open the file to display
- // (files should not stay open over multiple windows messages)
- if ((hfile = _lopen(szFName, OF_READ)) != -1)
- {
- // Get a buffer to hold data to fill screen.
- len = nPageMaxLines * 16;
- hbuff = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
- if (hbuff)
- {
- // Lock the buffer to get a pointer to it.
- lpbuff = GlobalLock(hbuff);
- if (lpbuff)
- {
- // Get offset into file to start display.
- offset = (LONG) nVscrollPos * 16L;
-
- if (_llseek(hfile, offset, 0) != -1L)
- {
- tlen = _lread(hfile, lpbuff, len);
- if (tlen != -1)
- {
- lpos = 0;
- lcp = lpbuff;
-
- for (i = nVscrollPos; i < (nVscrollPos + nPageMaxLines); i++)
- {
- if (tlen > 16)
- len = 16;
- else
- len = tlen;
- tlen -= len;
-
- SnapLine(buf, lcp, len, 16, (char *) (i * 16));
-
- TextOut(hDC,
- xChar * (-nHscrollPos + 0),
- yChar * lpos++,
- buf,
- strlen(buf));
-
- lcp += 16;
- }
- }
- }
-
- GlobalUnlock(hbuff);
- }
-
- GlobalFree(hbuff);
- }
-
- _lclose(hfile);
- }
- }
-
- EndPaint(hWnd, (LPPAINTSTRUCT) &ps);
- }
-
- //*******************************************************************
- // SnapLine - dump a line of memory
- //
- // paramaters:
- // szBuf - buffer to hold result
- // mem - pointer to memory to format
- // len - length to format
- // dwid - max display width (8 or 16 recomended)
- // olbl - label to put at start of line
- //
- // returns:
- // A pointer to szBbuf.
- //
- //*******************************************************************
- char *SnapLine(char *szBuf, LPSTR mem, int len, int dwid, char *olbl)
- {
- int i;
- int j;
- unsigned char c;
- unsigned char buff[80];
- unsigned char tbuf[80];
-
- if (len > dwid)
- len = dwid;
-
- *szBuf = 0;
- i = 0;
- j = 0;
-
- // Show offset for this line.
- sprintf(tbuf, "%04X ", olbl);
- strcpy(szBuf, tbuf);
-
- // Format hex portion of line and save chars for ascii portion
- for (i = 0; i < len; i++)
- {
- c = *mem++;
-
- sprintf(tbuf, "%02X ", c);
- strcat(szBuf, tbuf);
-
- if (c >= 32 && c < 127)
- buff[i] = c;
- else
- buff[i] = 46;
- }
-
- j = dwid - i;
-
- buff[i] = 0;
-
- // Fill out hex portion of short lines.
- for (i = j; i > 0; i--)
- strcat(szBuf, " ");
-
- // Add ascii portion to line.
- sprintf(tbuf, " |%s|", buff);
- strcat(szBuf, tbuf);
-
- // Fill out end of short lines.
- for (i = j; i > 0; i--)
- strcat(szBuf, " ");
-
- return(szBuf);
- }
-
- //*******************************************************************
- // DoFileOpenDlg - invoke FileOpenDlgProc to get name of file to open
- //
- // Setup call to FileOpenDlgProc to let user select path/filename
- //
- // paramaters:
- // hInst - instance of caller
- // hWnd - window of caller
- // szFileSpecIn - file path to search initially
- // szDefExtIn - file extension search initially
- // wFileAttrIn - attribute for 'DlgDirList' to use in search
- // szFilePathOut - path of selected file
- // szFileNameOut - name of selected file
- //
- // returns:
- // 1 - if a file selected
- // 0 - if file not selected
- //
- //*******************************************************************
- DoFileOpenDlg(HANDLE hInst, HWND hWnd,
- char *szFileSpecIn, char *szDefExtIn,
- WORD wFileAttrIn,
- char *szFilePathOut, char *szFileNameOut)
- {
- FARPROC lpfnFileOpenDlgProc;
- int iReturn;
-
- // Save starting file spec.
- strcpy(szFileSpec, szFileSpecIn);
- strcpy(szDefExt, szDefExtIn);
- wFileAttr = wFileAttrIn;
-
- lpfnFileOpenDlgProc = MakeProcInstance(FileOpenDlgProc, hInst);
-
- iReturn = DialogBox(hInst,
- MAKEINTRESOURCE(OPENFILE),
- hWnd,
- lpfnFileOpenDlgProc);
-
- FreeProcInstance(lpfnFileOpenDlgProc);
-
- // Return selected file spec.
- strcpy(szFilePathOut, szFilePath);
- strcpy(szFileNameOut, szFileName);
-
- return(iReturn);
- }
-
- //*******************************************************************
- // FileOpenDlgProc - get the name of a file to open
- //
- // paramaters:
- // hDlg - The window handle of this dialog box
- // message - The message number
- // wParam - The WORD parmater for this message
- // lParam - The LONG parmater for this message
- //
- // returns:
- // depends on message.
- //
- //*******************************************************************
- BOOL FAR PASCAL FileOpenDlgProc(HWND hDlg, WORD iMessage,
- WORD wParam, LONG lParam)
- {
- static char curpath[64];
-
- char cLastChar;
- int nLen;
- struct ffblk fileinfo;
-
- switch (iMessage)
- {
- case WM_INITDIALOG:
- // Save current working directory (will be restored on exit)
- getcwd(curpath, sizeof(curpath));
-
- SendDlgItemMessage(hDlg, IDD_FNAME, EM_LIMITTEXT, 80, 0L);
-
- // Fill list box with files from starting file spec.
- DlgDirList(hDlg,
- szFileSpec,
- IDD_FLIST,
- IDD_FPATH,
- wFileAttr);
-
- // Save starting file spec.
- SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
- return(TRUE);
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDD_FLIST:
- switch (HIWORD(lParam))
- {
- case LBN_SELCHANGE:
- if (DlgDirSelect(hDlg, szFileName, IDD_FLIST))
- strcat(szFileName, szFileSpec);
- SetDlgItemText(hDlg, IDD_FNAME, szFileName);
- break;
-
- case LBN_DBLCLK:
- if (DlgDirSelect(hDlg, szFileName, IDD_FLIST))
- {
- strcat(szFileName, szFileSpec);
- DlgDirList(hDlg, szFileName, IDD_FLIST, IDD_FPATH, wFileAttr);
- SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
- }
- else
- {
- SetDlgItemText(hDlg, IDD_FNAME, szFileName);
- SendMessage(hDlg, WM_COMMAND, IDOK, 0L);
- }
- break;
- }
- break;
-
- case IDD_FNAME:
- if (HIWORD(lParam) == EN_CHANGE)
- {
- EnableWindow(GetDlgItem(hDlg, IDOK),
- (BOOL) SendMessage(LOWORD(lParam),
- WM_GETTEXTLENGTH, 0, 0L));
- }
- break;
-
- case IDOK:
- GetDlgItemText(hDlg, IDD_FNAME, szFileName, 80);
-
- nLen = strlen(szFileName);
- cLastChar = *AnsiPrev(szFileName, szFileName + nLen);
-
- if (cLastChar == '\\' || cLastChar == ':')
- strcat(szFileName, szFileSpec);
-
- if (strchr(szFileName, '*') || strchr(szFileName, '?'))
- {
- if (DlgDirList(hDlg, szFileName, IDD_FLIST, IDD_FPATH, wFileAttr))
- {
- strcpy(szFileSpec, szFileName);
- SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
- }
- else
- MessageBeep(0);
- break;
- }
-
- // Fill list with new spec.
- if (DlgDirList(hDlg, szFileName, IDD_FLIST, IDD_FPATH, wFileAttr))
- {
- // Save new spec.
- strcpy(szFileSpec, szFileName);
- SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
- break;
- }
-
- // Since we fell through, szFileName was not a search path.
- szFileName[nLen] = '\0';
-
- // Make sure file exists.
- if (findfirst(szFileName, &fileinfo, 0))
- {
- strcat(szFileName, szDefExt);
-
- // Make sure file exists.
- if (findfirst(szFileName, &fileinfo, 0))
- {
- // No, beep and break.
- MessageBeep(0);
- break;
- }
- }
-
- // Get current path to return.
- GetDlgItemText(hDlg, IDD_FPATH, szFilePath, 80);
- strupr(szFilePath);
- if (szFilePath[strlen(szFilePath) - 1] != '\\')
- strcat(szFilePath, "\\");
-
- // Return selected file name.
- strcpy(szFileName, fileinfo.ff_name);
-
- // Restore current working directory.
- chdir(curpath);
-
- // Terminate this dialog box.
- EndDialog(hDlg, TRUE);
- break;
-
- case IDCANCEL:
- // Restore current working directory
- chdir(curpath);
-
- // Terminate this dialog box.
- EndDialog(hDlg, FALSE);
- break;
-
- default:
- return(FALSE);
- }
- break;
-
- default:
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- //*******************************************************************
-