home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / open32 / browser2 / browser.c next >
C/C++ Source or Header  |  1999-05-11  |  37KB  |  761 lines

  1. /* Copyright (C) International Business Machines Corp., 1995.               */
  2. /* Browser Program                                                          */
  3. /*   Browser will browse selected files in a Multiple Document              */
  4. /*   Interface (MDI) environment.                                           */
  5.  
  6. /* Include files */
  7. #include <os2win.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "browser.h"
  12.  
  13. /* Function prototypes */
  14. LRESULT CALLBACK FrameWndProc(HWND, UINT, WPARAM, LPARAM);
  15. LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
  16. BOOL CALLBACK CloseChildren(HWND, LPARAM);
  17. BOOL CALLBACK DeleteProperties(HWND, LPCTSTR, HANDLE);
  18.  
  19. BOOL DlgAskFile(HWND, LPSTR, LPSTR);
  20.  
  21.  
  22. /* Identifying strings */
  23. char szFrameName[] = "Browser";                /* Frame Class name          */
  24. char szChildName[] = "BrowseFile";             /* Child Class name          */
  25.  
  26. HANDLE hInstance;                              /* Global application inst.  */
  27. HMENU hClientMenu, hChildMenu;                 /* Menu handles for windows  */
  28.  
  29. /* Structures */
  30. struct scrolldata                              /* Structure used by each    */
  31. {                                              /* child wndw for scrolling  */
  32.   int numlines;                                /* Number lines inside file  */
  33.   int yPos;                                    /* Vertical scroll box pos   */
  34.   int xPos;                                    /* Horizontal scroll box pos */
  35.   int xChildw;                                 /* Width of child window.    */
  36.   int yChildw;                                 /* Height of child window.   */
  37.   int yunit;                                   /* Vertical size of charac.  */
  38.   int xunit;                                   /* Horizontal size of charac */
  39.   CHOOSEFONT cf;
  40.   LOGFONT lf;
  41. };
  42.  
  43. /* Main Program */
  44. int WINAPI WinMain(HINSTANCE hInst,             /* Current instance of app  */
  45.                    HINSTANCE hPreInst,
  46.                    LPSTR lpszCmdLine,
  47.                    int nCmdShow)
  48. {
  49.   HWND hFrameWnd, hClientWnd;                   /* Window handle            */
  50.   MSG lpMsg;                                    /* Message structure        */
  51.   WNDCLASS wcApp;                               /* Window Class Structure   */
  52.   LPSTR CmdLine;                                /* Cmd Line gave file name  */
  53.   hInstance = hInst;                            /* Save a global for later. */
  54.  
  55.   if (!hPreInst)                                /* If window class not yet  */
  56.   {                                             /* registered, do so.       */
  57.                                                 /* Register Frame wndw class*/
  58.     wcApp.lpszClassName = szFrameName;
  59.     wcApp.hInstance = hInst;
  60.     wcApp.lpfnWndProc = FrameWndProc;
  61.     wcApp.hCursor = LoadCursor(NULL,IDC_ARROW);
  62.     wcApp.hIcon = LoadIcon(NULL,IDI_APPLICATION);
  63.     wcApp.lpszMenuName = MAKEINTRESOURCE(BROWSERM);
  64.     wcApp.hbrBackground = GetStockObject(WHITE_BRUSH);
  65.     wcApp.cbClsExtra = 0;
  66.     wcApp.cbWndExtra = 0;
  67.     wcApp.style = CS_HREDRAW | CS_VREDRAW;
  68.  
  69.     if (!RegisterClass(&wcApp))
  70.       return FALSE;
  71.  
  72.                                                 /* Register Child wndw class*/
  73.     wcApp.lpszClassName = szChildName;
  74.     wcApp.lpfnWndProc = ChildWndProc;
  75.     wcApp.hIcon = LoadIcon(NULL,IDI_APPLICATION);
  76.     wcApp.lpszMenuName = NULL;                  /* Child wndws should have  */
  77.                                                 /* NULL as menu name.       */
  78.     wcApp.cbWndExtra = _MAX_PATH;               /* Reserving extra space in */
  79.                                                 /* wndw struc to associate  */
  80.                                                 /* path name of browsed file*/
  81.                                                 /* w/ particular child wndw.*/
  82.  
  83.     if (!RegisterClass(&wcApp))
  84.       return FALSE;
  85.   }
  86.                                                                                                  /* Get main menu handle for */
  87.   hClientMenu = LoadMenu(hInst, MAKEINTRESOURCE(BROWSERM));  /* ... Client  */
  88.   hChildMenu = LoadMenu(hInst, MAKEINTRESOURCE(BROWSFILEM)); /*   ... Child */
  89.  
  90.                                                 /* Create the Frame window. */
  91.   if (!lstrcmp(lpszCmdLine, ""))                /* Determine if Cmd line    */
  92.     CmdLine = NULL;                                                              /* gave filename to browse. */
  93.   else                                          /* Arguement was give...    */
  94.     CmdLine = lpszCmdLine;
  95.  
  96.   hFrameWnd = CreateWindow(szFrameName,         /* Create wndw of this class*/
  97.                            szFrameName,
  98.                            WS_CLIPCHILDREN |    /* Exclude area occupied by */
  99.                                                 /* child window when drawing*/
  100.                            WS_OVERLAPPEDWINDOW,
  101.                            CW_USEDEFAULT,
  102.                            CW_USEDEFAULT,
  103.                            CW_USEDEFAULT,       /* Width                    */
  104.                            CW_USEDEFAULT,       /* Height                   */
  105.                           (HWND) NULL,
  106.                           (HMENU) NULL,         /* Handle of menu           */
  107.                           (HANDLE) hInst,       /* Handle of app. instance  */
  108.                            CmdLine);            /* Window creation data     */
  109.  
  110.  
  111.   hClientWnd = GetWindow (hFrameWnd, GW_CHILD); /* Get Client window handle.*/
  112.  
  113.   ShowWindow(hFrameWnd,nCmdShow);        /* Specifies how window to be shown*/
  114.   UpdateWindow(hFrameWnd);               /* WM_PAINT msg sent to window proc*/
  115.  
  116.   while (GetMessage(&lpMsg,NULL,0,0))
  117.   {
  118.     if (!TranslateMDISysAccel(hClientWnd, &lpMsg)) /* If not MDI accelerator*/
  119.     {                                           /* msg for child window...  */
  120.       TranslateMessage(&lpMsg);                 /* Translates virtual key to*/
  121.                                                 /* character messages.      */
  122.       DispatchMessage(&lpMsg);                  /* Dispatch msg to wndw proc*/
  123.     }
  124.   }
  125.  
  126.   DestroyMenu(hChildMenu);               /* Release child menu resource     */
  127.                                          /* since not attached to a window. */
  128.  
  129.   return lpMsg.wParam;
  130. }
  131.  
  132. /****************************************************************************/
  133. /* Frame window procedure.  This creates the client window and processes    */
  134. /* all menu selections, from either the initial frame menu, BROWSERM, or the*/
  135. /* BROWSFILEM menu which exists when there is a child window.               */
  136. /****************************************************************************/
  137. LRESULT CALLBACK FrameWndProc(HWND hWnd,
  138.                  UINT message,
  139.                  WPARAM wParam,                 /* Unsigned int             */
  140.                  LPARAM lParam)                 /* Long int                 */
  141. {
  142.   static HWND hClientWnd;                       /* Handle of client window. */
  143.   CLIENTCREATESTRUCT clientstruc;
  144.   HWND hChildWnd;                               /* Handle of child window.  */
  145.   char FileName[_MAX_PATH] = {""};
  146.   char TitleName[_MAX_FNAME + _MAX_EXT] = {""};
  147.   char ChildTitle[6 + _MAX_FNAME + _MAX_EXT] = {"Browse "};
  148.  
  149.   switch (message)
  150.   {
  151.     case WM_CREATE:
  152.                                          /* Create the client window        */
  153.                                          /* Assign handle of Window submenu */
  154.       clientstruc.hWindowMenu = GetSubMenu(hClientMenu, BROWSE_WINPOS);
  155.                                          /* Assign 1st child window id.     */
  156.       clientstruc.idFirstChild = ID_FIRSTCHILD;
  157.                                          /* Create window.                  */
  158.       hClientWnd = CreateWindow("MDICLIENT",    /* Predefined window class  */
  159.                                 NULL,           /* Window name              */
  160.                                 WS_CHILD | WS_VISIBLE |
  161.                                 WS_HSCROLL |    /* Allow for scrolling.     */
  162.                                 WS_VSCROLL |
  163.                                 WS_CLIPCHILDREN,/* Don't allow client wndw  */
  164.                                                 /* to paint over child wndws*/
  165.                                 0,0,0,0,
  166.                                 hWnd,           /* Handle of parent - frame */
  167.                                (HMENU) 1,       /* Unique child wndw identi.*/
  168.                                (HANDLE) hInstance, /* Hndle of app. instance*/
  169.                                (LPSTR)&clientstruc);/* Window creation data */
  170.       ShowWindow(hClientWnd, SW_SHOW);
  171.  
  172.       if (((CREATESTRUCT*)lParam)->lpCreateParams != NULL) /* If Cmd line arg*/
  173.       {                                          /* create child wndw immed. */
  174.         lstrcat(ChildTitle,((CREATESTRUCT*)lParam)->lpCreateParams);/* Set up*/
  175.         CharUpper(ChildTitle);                                    /* title.  */
  176.                                                  /* Create child window.     */
  177.         hChildWnd = CreateMDIWindow(szChildName, /* Window class name.       */
  178.                                   ChildTitle,                /* Window title.*/
  179.                                   WS_HSCROLL | WS_VSCROLL,   /* Window style */
  180.                                   CW_USEDEFAULT, CW_USEDEFAULT,
  181.                                   CW_USEDEFAULT, CW_USEDEFAULT,
  182.                                   hClientWnd,    /* Handle of client window. */
  183.                                   hInstance,     /* Handle of app. instance. */
  184.                 (LPARAM)((CREATESTRUCT*)lParam)->lpCreateParams);/* Path of  */
  185.                                                              /* file selected*/
  186.                                                  /* to store in window data. */
  187.         SetClassLong(hChildWnd, GCL_HICON,
  188.              (LONG) LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIZZARD)));
  189.       }
  190.       return 0;
  191.       break;
  192.  
  193.     case WM_COMMAND:
  194.       switch (wParam)
  195.       {
  196.         case IDM_BROWSE:                        /* Browse file selected.    */
  197.                                                 /* Ask for file to browse.  */
  198.           if (DlgAskFile(hClientWnd, FileName, TitleName))/* If fle specified*/
  199.           {
  200.                                                 /* Create title by concat.  */
  201.             lstrcat(ChildTitle, TitleName);     /* "Browse" with file name. */
  202.             CharUpper(ChildTitle);
  203.                                                 /* Create Browse child wndw.*/
  204.             hChildWnd = CreateMDIWindow(szChildName, /* Window class name.  */
  205.                                       ChildTitle,    /* Window title.       */
  206.                                       WS_HSCROLL |   /* Window style        */
  207.                                       WS_VSCROLL,
  208.                                       CW_USEDEFAULT, CW_USEDEFAULT,
  209.                                       CW_USEDEFAULT, CW_USEDEFAULT,
  210.                                       hClientWnd,    /* Handle of client wnd*/
  211.                                       hInstance,     /* Handle of app. inst */
  212.                                      (LPARAM)FileName);  /* Path file select*/
  213.                                                 /* to store in window data. */
  214.             SetClassLong(hChildWnd, GCL_HICON,
  215.                  (LONG) LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIZZARD)));
  216.           }
  217.           else                                  /* No file name was selected*/
  218.           {
  219.             MessageBox(hClientWnd,
  220.                        "No File was specified for browsing.",
  221.                        "No File Specified", MB_OK);
  222.           }
  223.           return 0;
  224.           break;
  225.  
  226.         case IDM_CLOSEF:                        /* Close the active child.  */
  227.                                                 /* Get handleof active child*/
  228.           hChildWnd = (HWND)SendMessage(hClientWnd, WM_MDIGETACTIVE, 0, 0L);
  229.                     /* NOTE: the WM_MDIGETACTIVE interface changed for WNT. */
  230.                                                 /* If application in child  */
  231.                                                 /* is at a pt of termination*/
  232.           if (SendMessage(hChildWnd, WM_QUERYENDSESSION, 0, 0L))
  233.                                                 /* then close MDI child.    */
  234.             SendMessage(hClientWnd, WM_MDIDESTROY, (WPARAM)hChildWnd, 0L);
  235.           return 0;
  236.           break;
  237.  
  238.         case IDM_EXIT:
  239.           SendMessage(hWnd, WM_CLOSE, 0, 0L);
  240.           return 0;
  241.           break;
  242.  
  243.         case IDM_CASCADE:
  244.           SendMessage(hClientWnd, WM_MDICASCADE, 0, 0L);
  245.           return 0;
  246.           break;
  247.  
  248.         case IDM_TILEV:
  249.           SendMessage(hClientWnd, WM_MDITILE, (WPARAM)MDITILE_VERTICAL, 0L);
  250.           return 0;
  251.           break;
  252.  
  253.         case IDM_TILEH:
  254.           SendMessage(hClientWnd, WM_MDITILE, (WPARAM)MDITILE_HORIZONTAL, 0L);
  255.           return 0;
  256.           break;
  257.  
  258.         case IDM_ARRANGE:
  259.           SendMessage(hClientWnd, WM_MDIICONARRANGE, 0, 0L);
  260.           return 0;
  261.           break;
  262.  
  263.         case IDM_CLOSEALL:
  264.           EnumChildWindows(hClientWnd, (WNDENUMPROC) CloseChildren, 0L);
  265.           return 0;
  266.           break;
  267.  
  268.         case IDM_HELP1:                  /* Help for main client window     */
  269.           MessageBox(hClientWnd, "This is an MDI application.  You can select "
  270.                                  "multiple files to browse by selecting File>>"
  271.                                  "Browse File....  Each file selected should "
  272.                                  "be displayed in its own child window. "
  273.                                  "Select File>>Exit to leave the application.",
  274.                                  "Browser Help", MB_OK);
  275.           break;
  276.  
  277.         case IDM_HELP2:                  /* Help for when child window exits*/
  278.           MessageBox(hClientWnd, "Select File>>Browse File... to open another "
  279.                                  "file in a separate MDI child window to "
  280.                                  "browse.  Select File>>Select Font... to "
  281.                                  "select a new font for the currently active "
  282.                                  "child window.  Select File>>Close to close "
  283.                                  "the currently active child window.  Select "
  284.                                  "File>>Exit to leave the Browser application. "
  285.                                  "Use the Window menu item to arrange or "
  286.                                  "select the existing child windows.",
  287.                                  "Browser Help", MB_OK);
  288.  
  289.           break;
  290.  
  291.         default:                         /* Other menu msgs to be processed */
  292.                                          /* by the active child window.     */
  293.                                          /* Get handle of active child wndw.*/
  294.           hChildWnd = (HWND)SendMessage(hClientWnd, WM_MDIGETACTIVE, 0, 0L);
  295.                     /* NOTE: the WM_MDIGETACTIVE interface changed for WNT. */
  296.           if (IsWindow(hChildWnd))
  297.             SendMessage(hChildWnd, WM_COMMAND, wParam, lParam);
  298.           break;
  299.                                          /* Allow to fall through to        */
  300.                                          /* DefFrameProc.                   */
  301.       }
  302.       break;
  303.  
  304.       case WM_QUERYENDSESSION:
  305.       case WM_CLOSE:
  306.         SendMessage(hWnd, WM_COMMAND, IDM_CLOSEALL, 0L);
  307.         if (NULL != GetWindow(hClientWnd, GW_CHILD))
  308.           return  FALSE;
  309.         break;
  310.  
  311.       case WM_DESTROY:
  312.         PostQuitMessage(0);             /* Sends WM_QUIT message.           */
  313.         return 0;
  314.         break;
  315.  
  316.       default:
  317.         break;
  318.   }
  319.  
  320.   return DefFrameProc(hWnd, hClientWnd, message, wParam, lParam);
  321. }
  322.  
  323.  
  324. BOOL CALLBACK CloseChildren(HWND hWnd, LONG lParam)
  325. {
  326.   HWND hParent;                                 /* Handle of parent window  */
  327.  
  328.   if (GetWindow(hWnd, GW_OWNER))         /* Check for icon title window.    */
  329.                                          /* Non-title windows return NULL.  */
  330.     return TRUE;                         /* Don't do anything if icon title.*/
  331.  
  332.   hParent = GetParent(hWnd);
  333.                                          /* Restore child from Max/Min size.*/
  334.   SendMessage(hParent, WM_MDIRESTORE, (WPARAM)hWnd, 0L);
  335.  
  336.                                          /* Is child window in state to end?*/
  337.   if (SendMessage(hWnd, WM_QUERYENDSESSION, 0, 0L))
  338.                                          /* Tell client to destroy this chld*/
  339.     SendMessage(hParent, WM_MDIDESTROY, (WPARAM)hWnd, 0L);
  340.  
  341.   return TRUE;
  342. }
  343.  
  344.  
  345. LRESULT CALLBACK ChildWndProc(HWND hWnd,
  346.                               UINT message,
  347.                               WPARAM wParam,    /* Unsigned int             */
  348.                               LPARAM lParam)    /* Long int                 */
  349. {
  350.   #define LINESIZE 256
  351.  
  352.   int i,y, x;
  353.  
  354.   HWND hClientWnd;                              /* Handle of parent-client  */
  355.   HWND hFrameWnd;                               /* Handle of frame window.  */
  356.   HMENU hWindowMenu;                            /* Window hndl of Windowmenu*/
  357.                                                 /* within Child Menu bar.   */
  358.   char * pFilePath;                             /* Ptr File Pathname or data*/
  359.   MDICREATESTRUCT * mcs;                        /* For use in WM_CREATE msg */
  360.   LOCALHANDLE hFileName;                        /* Hanle to allocated space */
  361.   HANDLE hFile;                                 /* File handle.             */
  362.   DWORD FileSize, FileRead;                     /* File size, No.bytes read */
  363.   HDC hdc;                                      /* Devic Context Handle.    */
  364.  
  365.   PAINTSTRUCT ps;                               /* Paint Structurefor disply*/
  366.   static RECT rect;
  367.   TEXTMETRIC tm;
  368.   HFONT hFont;                                  /* Handle to font.          */
  369.  
  370.   struct scrolldata * psd;                      /* Internal struc. that has */
  371.                                                 /* scrolling info. of child */
  372.   int charpos;                                  /* Character positin in file*/
  373.   int clientlines;                              /* # lines to be displayed  */
  374.   char line[LINESIZE];                          /* Line to be displayed     */
  375.  
  376.  
  377.   switch (message)
  378.   {
  379.     case WM_CREATE:
  380.     /************************************************************************/
  381.     /* Client processed WM_MDICREATE msg which in turn issued WM_CREATE msg */
  382.     /* to child window.  LParam is a ptr to CREATESTRUCT.                   */
  383.     /* CREATESTRUCT->lpCreateParams is a ptr to an MDICREATESTRUCT.         */
  384.     /************************************************************************/
  385.       mcs = ((CREATESTRUCT *)lParam)->lpCreateParams;
  386.                                          /* Allocate memory for file name.  */
  387.       hFileName = LocalAlloc(LHND, _MAX_PATH);
  388.       pFilePath = LocalLock(hFileName);
  389.                                          /* Copy path name from MDICREATESTR*/
  390.       lstrcpy(pFilePath, (char *)mcs->lParam);
  391.                                          /* Save hndl to pathname in window */
  392.       SetWindowLong(hWnd, GWL_USERDATA, (LONG)hFileName);  /* data.         */
  393.                                                 /* Get ptr to path name     */
  394.       /**********************************************************************/
  395.       /* Open the file (via CreateFile) for Read-only and read the data into*/
  396.       /* globally allocated area. If unsuccessful, destroy child window.    */
  397.       /**********************************************************************/
  398.       hFile = CreateFile(pFilePath,             /* Full path to file        */
  399.                          GENERIC_READ,          /* File access specification*/
  400.                          FILE_SHARE_READ,       /* File sharing specificatn */
  401.                          NULL,                  /* Security attributes.     */
  402.                          OPEN_EXISTING,         /* Open file onlyif it exits*/
  403.                          FILE_ATTRIBUTE_READONLY,  /* File attributes       */
  404.                          NULL);
  405.       LocalUnlock(hFileName);
  406.       if (hFile != INVALID_HANDLE_VALUE)        /* No error on file open... */
  407.       {
  408.         FileSize = GetFileSize(hFile, NULL) + 1; /* Get file size.          */
  409.         pFilePath = (unsigned char *)GlobalAlloc(GPTR, FileSize); /* Allocate memory for file*/
  410.         if (pFilePath)                           /* Memory was allocated... */
  411.         {                                        /* Read the file...        */
  412.           if (ReadFile(hFile, pFilePath, FileSize , &FileRead, NULL))
  413.           {
  414.             pFilePath[FileRead + 1] = '\0';      /* Ensure file is null-term*/
  415.             CloseHandle(hFile);                  /* Close the file.         */
  416.             SetProp(hWnd, "FILE_DATA",
  417.                     (HANDLE)pFilePath);          /* Save @ to data as a child*/
  418.                                                 /* window property.         */
  419.           }
  420.           else                                  /* Read error...            */
  421.           {
  422.             MessageBox(hWnd, "File Read Error", "File Error",
  423.                                           MB_OK | MB_ICONEXCLAMATION);
  424.                                                 /* Kill child window        */
  425.             hClientWnd = GetParent(hWnd);       /* by sending the parent    */
  426.             SendMessage(hClientWnd,             /* client window a message. */
  427.                         WM_MDIDESTROY,          /* This will remove child   */
  428.                         (WPARAM)hWnd, 0L);      /* from window list.        */
  429.             return 0;
  430.           }                                     /* End read error.          */
  431.         }
  432.         else                                    /* Memory was not allocated.*/
  433.         {
  434.           MessageBox(hWnd, "Memory Allocation Problem", "File Error",
  435.                                           MB_OK | MB_ICONEXCLAMATION);
  436.                                                 /* Kill child window        */
  437.           hClientWnd = GetParent(hWnd);         /* by sending the parent    */
  438.           SendMessage(hClientWnd,               /* client window a message. */
  439.                       WM_MDIDESTROY,            /* This will remove child   */
  440.                       (WPARAM)hWnd, 0L);        /* from window list.        */
  441.           return 0;
  442.         }                                       /* End memory not allocated.*/
  443.       }
  444.       else                                      /* Error opening file.      */
  445.       {                                         /* Notify user              */
  446.         MessageBox(hWnd, "Cannot Open File!", pFilePath,
  447.                                           MB_OK | MB_ICONEXCLAMATION);
  448.                                                 /* Kill child window        */
  449.         hClientWnd = GetParent(hWnd);           /* by sending the parent    */
  450.         SendMessage(hClientWnd,                 /* client window a message. */
  451.                     WM_MDIDESTROY,              /* This will remove child   */
  452.                     (WPARAM)hWnd, 0L);          /* from window list.        */
  453.         return 0;
  454.       }
  455.       /**********************************************************************/
  456.       /* OK...we are able to get the data to display. Get info. on how.     */
  457.       /**********************************************************************/
  458.                                                 /* Allocate scrolldata struc*/
  459.       psd = (struct scrolldata *)LocalAlloc(LPTR, sizeof(struct scrolldata));
  460.       SetProp(hWnd, "SCROLL_DATA", (HANDLE)psd);        /* Save address as wndw prop*/
  461.                                                 /* Get number of lines      */
  462.       for(psd->numlines = 0, i=0; i < (int)FileRead; i++)/* in file to dsply*/
  463.         if (pFilePath[i] == '\n')
  464.            psd->numlines++;
  465.                                                 /* Set scroll range & box.  */
  466.       SetScrollRange(hWnd, SB_VERT, 0, psd->numlines, TRUE);
  467.       SetScrollPos(hWnd, SB_VERT, 0, TRUE);
  468.       SetScrollRange(hWnd, SB_HORZ, 0, LINESIZE, TRUE);
  469.       SetScrollPos(hWnd, SB_HORZ, 0, TRUE);
  470.       psd->yPos = psd->xPos = 0;                /* Init x and y position    */
  471.  
  472.                                                 /* Get current font info.   */
  473.                                                 /* and init font strucs.    */
  474.       GetObject(GetStockObject(SYSTEM_FONT), sizeof(psd->lf), &psd->lf);
  475.       psd->cf.lStructSize = sizeof(psd->cf);
  476.       psd->cf.hwndOwner = hWnd;
  477.       psd->cf.lpLogFont = &psd->lf;
  478.       psd->cf.Flags = CF_EFFECTS | CF_FORCEFONTEXIST |
  479.                               CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
  480.  
  481.       InvalidateRect(hWnd, NULL, TRUE); /* Set so WM_PAINT will draw text.  */
  482.  
  483.       return 0;                         /* Return 0.See online documentation*/
  484.       break;
  485.  
  486.     case WM_SIZE:
  487.       psd = (struct scrolldata *)GetProp(hWnd, "SCROLL_DATA");       /* Get scroll info for wndw */
  488.       psd->xChildw = LOWORD(lParam);            /* Save new width.          */
  489.       psd->yChildw = HIWORD(lParam);            /* Save new height.         */
  490.                                   /* Let msg fall through to DefMDIChildProc*/
  491.       break;
  492.  
  493.     case WM_VSCROLL:
  494.       psd = (struct scrolldata *)GetProp(hWnd, "SCROLL_DATA");       /* Get scroll info for wndw */
  495.       pFilePath = (unsigned char *)GetProp(hWnd, "FILE_DATA");   /* Get ptr to file data.    */
  496.       switch (LOWORD(wParam))
  497.       {                                         /* Determine change in y.   */
  498.         case SB_LINEDOWN:
  499.           y = 1;
  500.           break;
  501.  
  502.         case SB_LINEUP:
  503.           y = -1;
  504.           break;
  505.  
  506.         case SB_PAGEDOWN:                       /* Scroll one page size     */
  507.           y = psd->yChildw/psd->yunit;
  508.           break;
  509.  
  510.         case SB_PAGEUP:                         /* Scroll one page size     */
  511.           y = -psd->yChildw/psd->yunit;
  512.           break;
  513.  
  514.         case SB_THUMBPOSITION:
  515.           y = HIWORD(wParam) - psd->yPos;
  516.           break;
  517.  
  518.         case SB_ENDSCROLL:
  519.           return 0;
  520.           break;
  521.  
  522.         default:                                /* Default: no change       */
  523.           y = 0;
  524.         break;
  525.       }
  526.  
  527.       psd->yPos += y;                    /* Calculate new vert scrollbox pos*/
  528.       if (psd->yPos > psd->numlines)
  529.       {
  530.         psd->yPos = psd->numlines;
  531.         InvalidateRect(hWnd, NULL, TRUE);
  532.       }
  533.       else
  534.         if (psd->yPos < 0)
  535.         {
  536.           psd->yPos = 0;
  537.           InvalidateRect(hWnd, NULL, TRUE);
  538.         }
  539.         else
  540.         {                                 /* ScrollWindow makes it smooth   */
  541.           ScrollWindow(hWnd, 0,
  542.                        -psd->yunit * y,   /* Amount of vertical srolling    */
  543.                       (CONST RECT *) NULL, (CONST RECT *) NULL);
  544.           UpdateWindow(hWnd);             /* Sends WM_PAINT msg; not posted!*/
  545.         }
  546.       SetScrollPos(hWnd, SB_VERT, psd->yPos, TRUE); /* Set box on window    */
  547.       return 0;                       /* Return 0. See online documentation*/
  548.       break;
  549.  
  550.     case WM_HSCROLL:
  551.       psd = (struct scrolldata *)GetProp(hWnd, "SCROLL_DATA");       /* Get scroll info for wndw */
  552.       pFilePath = (unsigned char *)GetProp(hWnd, "FILE_DATA");   /* Get ptr to file data.    */
  553.       switch (LOWORD(wParam))
  554.       {                                  /* Determine change in x           */
  555.         case SB_LINELEFT:
  556.           x = -1;
  557.           break;
  558.  
  559.         case SB_LINERIGHT:
  560.           x = 1;
  561.           break;
  562.  
  563.         case SB_PAGELEFT:                       /* I set paging to be 10    */
  564.           x = -10;
  565.           break;                                /* characters for horizontal*/
  566.  
  567.         case SB_PAGERIGHT:
  568.           x = 10;
  569.           break;
  570.  
  571.         case SB_THUMBPOSITION:
  572.           x = HIWORD(wParam) - psd->xPos;
  573.           break;
  574.  
  575.         case SB_ENDSCROLL:
  576.           return 0;
  577.           break;
  578.  
  579.         default:
  580.           x = 0;                               /* Default: no change        */
  581.           break;
  582.       }
  583.  
  584.       psd->xPos += x;                    /* Calculate new horz scrollbox pos*/
  585.       if (psd->xPos > LINESIZE)
  586.       {
  587.         x = 0;                           /* No change from current display. */
  588.         psd->xPos = LINESIZE;
  589.       }
  590.       else
  591.         if (psd->xPos < 0)
  592.         {
  593.           x = 0;                         /* No change from current display. */
  594.           psd->xPos = 0;
  595.         }
  596.  
  597.       SetScrollPos(hWnd, SB_HORZ, psd->xPos, TRUE); /* Set box on window    */
  598.       InvalidateRect(hWnd, NULL, TRUE);
  599.       return 0;                       /* Return 0. See online documentation*/
  600.       break;
  601.  
  602.     case WM_COMMAND:
  603.       switch (wParam)
  604.       {
  605.         case (IDM_FONT):                 /* User chose "Select Font..."     */
  606.           psd = (struct scrolldata *)GetProp(hWnd, "SCROLL_DATA");
  607.  
  608.           if (ChooseFont(&psd->cf))      /* If user selects a new font      */
  609.             InvalidateRect(hWnd, NULL, TRUE);  /* re-paint window with it.  */
  610.           break;
  611.  
  612.         default:
  613.           break;
  614.       }
  615.       return 0;                       /* Return 0. See online documentation*/
  616.       break;
  617.  
  618.     case WM_PAINT:
  619.       psd = (struct scrolldata *)GetProp(hWnd, "SCROLL_DATA");       /* Get scroll info for wndw */
  620.       pFilePath = (unsigned char *)GetProp(hWnd, "FILE_DATA");   /* Get ptr to data to paint */
  621.  
  622.       hdc = BeginPaint(hWnd, &ps);              /* Gets device context.     */
  623.                                                 /* Set up the font.         */
  624.       hFont = CreateFontIndirect(&psd->lf);     /* Creates font w/ character*/
  625.                                                 /* -istics specified in lf  */
  626.       SelectObject(hdc, hFont);                 /* Sets up DC with new info */
  627.       SetTextColor(hdc, psd->cf.rgbColors);     /* Sets up DC with new color*/
  628.  
  629.       GetTextMetrics(hdc, &tm);                 /* Get Font dimensions.     */
  630.                                                /* Get horiz/vert scroll unit*/
  631.       psd->xunit = tm.tmAveCharWidth;
  632.       psd->yunit = tm.tmHeight + tm.tmExternalLeading;
  633.  
  634.                                          /* Determine offset in file.       */
  635.                                          /* Psd->YPOS pts to line we want   */
  636.                                          /* to start display at.            */
  637.       for (i=0, charpos = 0; i < psd->yPos; charpos++)
  638.         if (pFilePath[charpos] == '\n')
  639.            i++;
  640.                                          /* Determine # of lines to be      */
  641.                                          /* displayed, smaller of lines left*/
  642.                                          /* in file and amt that will fit   */
  643.                                          /* on the currently sized area.    */
  644.       clientlines = min((psd->numlines-psd->yPos),(psd->yChildw/psd->yunit)+1);
  645.  
  646.       memset(line, ' ', sizeof(line));   /* Init output line to blanks.     */
  647.                                          /* Display the lines of text.      */
  648.       for (i = 0, y = 0; y < clientlines; i++, charpos++)
  649.       {                                  /* i is line index;y is lines done */
  650.         if (pFilePath[charpos] == '\n')  /* Line is filled.                 */
  651.         {
  652.           TextOut(hdc, 0, psd->yunit * y, &line[psd->xPos],
  653.                                            sizeof(line) - psd->xPos);
  654.           y++;                           /* did 1 line                      */
  655.           i = -1;               /* reset line index to 0 (post increment ++)*/
  656.           memset(line, ' ', sizeof(line));
  657.         }
  658.         else                            /* Fill line with character.        */
  659.         {
  660.           if (i < LINESIZE)
  661.           line[i] = pFilePath[charpos];
  662.         }
  663.       }
  664.  
  665.       SelectObject(hdc, GetStockObject(SYSTEM_FONT));/* Replace w/ original */
  666.                                        /* default font object.              */
  667.       DeleteObject(hFont);             /* Delete the font object created.   */
  668.       EndPaint(hWnd, &ps);             /* Delete the device context.        */
  669.       return 0;                        /* Return 0. See online documentation*/
  670.       break;
  671.  
  672.     case WM_MDIACTIVATE:               /* MDI msg sent by client window when*/
  673.                                        /* inactive child is clicked or      */
  674.                                        /* brought to foreground.            */
  675.       hClientWnd = GetParent(hWnd);    /* Get handle of client window.      */
  676.       if ((HWND)lParam == hWnd)        /* WM_MDIACTIVATE msg sent to        */
  677.       {                                /*  activate this child window.      */
  678.                                        /* Get handle of Window submenu w/in */
  679.                                        /*  the child menu.                  */
  680.         hWindowMenu = GetSubMenu(hChildMenu,BROWSEF_WINPOS);
  681.         SendMessage(hClientWnd, WM_MDISETMENU, (WPARAM)hChildMenu,
  682.                    (LPARAM)hWindowMenu);
  683.       }
  684.       else                             /* Else the message was sent to      */
  685.       {                                /*  deactivate this child window.    */
  686.                                        /* Get handle of Window submenu w/in */
  687.                                        /*  the client menu.                 */
  688.         hWindowMenu = GetSubMenu(hClientMenu, BROWSE_WINPOS);
  689.         SendMessage(hClientWnd, WM_MDISETMENU, (WPARAM)hClientMenu,
  690.                    (LPARAM)NULL);
  691.       }
  692.       hFrameWnd = GetParent(hClientWnd);
  693.       DrawMenuBar(hFrameWnd);          /* Draw change in menu bar.          */
  694.       return 0;                        /* Return 0. See online documentation*/
  695.       break;
  696.  
  697.     case WM_DESTROY:                   /* Free the memory belonging to child*/
  698.                                        /* Free the path name stored as wndw */
  699.       hFileName = (LOCALHANDLE)GetWindowLong(hWnd, GWL_USERDATA); /* instance data*/
  700.       LocalFree(hFileName);
  701.  
  702.       EnumProps(hWnd, DeleteProperties); /* Delete any child properties     */
  703.       return 0;                        /* Return 0. See online documentation*/
  704.       break;
  705.  
  706.     default:
  707.       break;
  708.   }
  709.  
  710.   return DefMDIChildProc(hWnd, message, wParam, lParam);
  711. }
  712.  
  713.  
  714. BOOL DlgAskFile(HWND hWnd, LPSTR FileName, LPSTR TitleName)
  715. {
  716.   DWORD x;
  717.   OPENFILENAME fn;                       /* Structure for file selection    */
  718.   char filetypes[] = {"Code file\0*.C\0Header file\0*.h\0Text file\0*.TXT\0"
  719.                       "Script file\0*.SCR\0All files\0*.*\0\0"};
  720.  
  721.                                                                                   /* Initialize the Open structure.  */
  722.   fn.lStructSize = sizeof(OPENFILENAME);
  723.   fn.hwndOwner = hWnd;                   /* Handle that owns dialog box     */
  724.   fn.hInstance = NULL;
  725.   fn.lpstrFilter ="Code file\0*.C\0\0";
  726.   fn.lpstrCustomFilter = NULL;
  727.   fn.nMaxCustFilter = 0;
  728.   fn.nFilterIndex = 1;                   /* Initialize to C files.          */
  729.   fn.lpstrFile = FileName;               /* FN to init File Name edit ctl.  */
  730.   fn.nMaxFile = _MAX_PATH;               /* Buffer size of lpstrFile        */
  731.   fn.lpstrFileTitle = TitleName;         /* Pts to buffer to receive title  */
  732.   fn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
  733.   fn.lpstrInitialDir = NULL;             /* Use current directory initially */
  734.   fn.lpstrTitle = "Browse File";         /* Title of dialog box.            */
  735.   fn.Flags = OFN_FILEMUSTEXIST |
  736.              OFN_HIDEREADONLY |
  737.              OFN_NONETWORKBUTTON;
  738.   fn.nFileOffset = 0;
  739.   fn.nFileExtension = 0;
  740.   fn.lpstrDefExt = "c";
  741.   fn.lCustData = 0;
  742.   fn.lpfnHook = NULL;
  743.   fn.lpTemplateName = NULL;
  744.  
  745.   x = GetOpenFileName(&fn);
  746.   if (!x)
  747.     x = CommDlgExtendedError();
  748.   return x;
  749. }
  750.  
  751.  
  752. BOOL CALLBACK DeleteProperties(HWND hWnd, LPCTSTR PropName, HANDLE hData)
  753. {
  754.  
  755.   GlobalFree(hData);
  756.   RemoveProp(hWnd, PropName);
  757.  
  758.   return TRUE;
  759. }
  760. /*************************   end of browser.c *****************************/
  761.