Solved

MDI - Help Needed

Posted on 1997-04-24
11
834 Views
Last Modified: 2008-03-06
Thanks for the quick response.. not sure if this is where I'm suppose to send you my Email address for the 32 bit version. I'll try both here and the Evaluate form.

Anyway.. if you have the sample of the MDI 32 bit you were talking about please zip it and send it to jvitale@idsonline.com  Thank you very much!!! You guys are great.
----------------------------------------------------------
I'm having tons of trouble developing a Multiple Document
Interface (MDI) with C. So far what I have done is created 2
windows, one I used as a normal style of WS_OVERLAPPED with no parent window, when I created it.. The second one I tried to use a style of WS_CHILD and declared the first window as it's parent. I even tried CreateWindowEx() and WS_EX_MDICHILD style, Needless to say this did not work. The child window was in a sense invisible. I would really like a very basic sample of an MDI Client or info on where to get such material. This problem is driving me crazy, I have asked quite a few people and so far, noone knows anything about MDI's and C. I use Visual C++ 32 bit for Windows 95. Here's and example of answers I have gotten from other programmers: "Use VC++'s appwizard and examine the code." but what they don't understand is I want a "C" MDI sample, not a "C++" sample. Any help would be greatly appreciated. Sorry for the poor grammer, it's late and my brain is fried from programming.
0
Comment
Question by:jvitale
  • 8
  • 2
11 Comments
 
LVL 1

Expert Comment

by:prc
Comment Utility
Yes, it's a shame everyone's forgotten how to program, isn't it ;-)

What you need is the example code from the original MSVC or even C-7 disks.  If I remember rightly there was something called 'multipad.c' which implemented a simple MDI world.

I used to have bits of code to do this, but like everyone else I now use C++.  Hence this is a comment, not an answer.  I think you're going to have trouble writing to Windows in C - these days a lot of the user-interface functionality is in the MFC library, not the Win API.

Cheers

Paul
0
 
LVL 4

Accepted Solution

by:
emmons earned 50 total points
Comment Utility
Paul is right, the multipad example is a good one. It is a little bit too big to include in one answer, so I have broken up the 10 files into this answer and several comments. The files should be saved in the name indicated in their header.
BTW, this is a 16 bit app built under 1.5 of the compiler. There is a 32 bit version, but it is 2 or three times as long. If you need that, then leave me an email address and I will zip it up and send it to you.

/***************************************************************************
 *                                                         *
 *  PROGRAM      : MultiPad.c                                       *
 *                                                         *
 *  PURPOSE      : To give a multi-Notepad demonstration of the new MDI         *
 *              API in Windows 3.0                                 *
 *                                                         *
 *  FUNCTIONS      : WinMain()            - Calls the initialization function  *
 *                              and processes message loop         *
 *                                                         *
 *              MPFrameWndProc()    - Window function for the "frame"    *
 *                              window, which controls the menu    *
 *                              and contains the MDI document         *
 *                              windows as child windows.         *
 *                                                         *
 *              MPMDIChildWndProc() - Window function for the individual *
 *                              document windows               *
 *                                                         *
 *              InitializeMenu()    - Handles enabling/greying of menu   *
 *                              items according to the app's state.*
 *                                                         *
 *              CloseAllChildren    - Destroys all MDI child windows.    *
 *                                                         *
 *              CommandHandler()    - Processes the "frame" window's     *
 *                              WM_COMMAND messages.               *
 *                                                         *
 *              AboutDlgProc()      - Dialog function for the ubiquitous *
 *                              About.. dialog.                *
 *                                                         *
 *              SetWrap()            - Alters word wrapping in the edit   *
 *                              control.                     *
 *                                                         *
 *              MPError()            - Flashes an error messagebox.         *
 *                                                         *
 *              QueryCloseChild     - Prompts for saving current MDI         *
 *                              child window.                     *
 *                                                         *
 *              QueryCloseAllChildren() - Asks whether it is OK to close *
 *                                  down app.                     *
 *                                                         *
 ***************************************************************************/

#include "multipad.h"
#include "commdlg.h"

/* global variables used in this module or among more than one module */
PRINTDLG pd;      /* Common print dialog structure */
HANDLE hInst;                      /* Program instance handle                 */
HANDLE hAccel;                      /* Main accelerator resource           */
HWND hwndFrame             = NULL;    /* Handle to main window                 */
HWND hwndMDIClient       = NULL;    /* Handle to MDI client                 */
HWND hwndActive        = NULL;    /* Handle to currently activated child   */
HWND hwndActiveEdit       = NULL;    /* Handle to edit control                 */
LONG styleDefault    = WS_MAXIMIZE; /* Default style bits for child windows  */
                            /* The first window is created maximized */
                            /* to resemble Notepad.  Later children  */
                            /* are normal windows.                 */
LPSTR lpMenu           = (LPSTR)IDMULTIPAD;  /* Contains the resource id of the          */
                            /* current frame menu                 */


/* Forward declarations of helper functions in this module */
VOID NEAR PASCAL InitializeMenu (HANDLE);
VOID NEAR PASCAL CommandHandler (HWND,WORD);
VOID NEAR PASCAL SetWrap (HWND,BOOL);
BOOL NEAR PASCAL QueryCloseAllChildren ( VOID );
int  NEAR PASCAL QueryCloseChild (HWND);

/****************************************************************************
 *                                                          *
 *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                      *
 *                                                          *
 *  PURPOSE    : Creates the "frame" window, does some initialization and   *
 *             enters the message loop.                            *
 *                                                          *
 ****************************************************************************/
int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
    MSG msg;

    hInst = hInstance;

    /* If this is the first instance of the app. register window classes */
    if (!hPrevInstance){
      if (!InitializeApplication ())
          return 0;
    }

    /* Create the frame and do other initialization */
    if (!InitializeInstance (lpszCmdLine, nCmdShow))
      return 0;

    /* Enter main message loop */
    while (GetMessage (&msg, NULL, 0, 0)){
      /* If a keyboard message is for the MDI , let the MDI client
       * take care of it.  Otherwise, check to see if it's a normal
       * accelerator key (like F3 = find next).  Otherwise, just handle
       * the message as usual.
       */
      if ( !TranslateMDISysAccel (hwndMDIClient, &msg) &&
           !TranslateAccelerator (hwndFrame, hAccel, &msg)){
          TranslateMessage (&msg);
          DispatchMessage (&msg);
      }
    }
    return 0;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : MPFrameWndProc (hwnd, msg, wParam, lParam )                *
 *                                                          *
 *  PURPOSE    : The window function for the "frame" window, which controls *
 *             the menu and encompasses all the MDI child windows. Does   *
 *             the major part of the message processing. Specifically, in *
 *             response to:                                        *
 *                                                          *
 *                 WM_CREATE            : Creates and displays the "frame". *
 *                                                          *
 *                 WM_INITMENU      : Sets up the state of the menu.    *
 *                                                          *
 *                 WM_WININICHANGE &  : If default printer characteristics*
 *                 WM_DEVMODECHANGE        have been changed, reinitialises  *
 *                                printer DC.                      *
 *                                                          *
 *                 WM_COMMAND       : Passes control to a command-          *
 *                                handling function.                *
 *                                                          *
 *                 WM_CLOSE            : Quits the app. if all the child   *
 *                                windows agree.                *
 *                                                          *
 *                 WM_QUERYENDSESSION : Checks that all child windows     *
 *                                agree to quit.                *
 *                                                          *
 *                 WM_DESTROY       : Destroys frame window and quits   *
 *                                app.                            *
 *                                                          *
 ****************************************************************************/
LONG FAR PASCAL __export MPFrameWndProc ( hwnd, msg, wParam, lParam )

register HWND       hwnd;
UINT             msg;
register WPARAM    wParam;
LPARAM               lParam;

{
    switch (msg){
      case WM_CREATE:{

          CLIENTCREATESTRUCT ccs;

          /* Find window menu where children will be listed */
          ccs.hWindowMenu = GetSubMenu (GetMenu(hwnd),WINDOWMENU);
          ccs.idFirstChild = IDM_WINDOWCHILD;

          /* Create the MDI client filling the client area */
          hwndMDIClient = CreateWindow ("mdiclient",
                                NULL,
                                WS_CHILD | WS_CLIPCHILDREN |
                                WS_VSCROLL | WS_HSCROLL,
                                0,
                                0,
                                0,
                                0,
                                hwnd,
                                0xCAC,
                                hInst,
                                (LPSTR)&ccs);


          ShowWindow (hwndMDIClient,SW_SHOW);
          break;
    }

      case WM_INITMENU:
          /* Set up the menu state */
          InitializeMenu ((HMENU)wParam);
          break;

      case WM_COMMAND:
          /* Direct all menu selection or accelerator commands to another
           * function
           */
          CommandHandler (hwnd,wParam);
          break;

      case WM_CLOSE:
          /* don't close if any children cancel the operation */
          if (!QueryCloseAllChildren ())
            break;
          DestroyWindow (hwnd);
          break;

      case WM_QUERYENDSESSION:
          /*      Before session ends, check that all files are saved */
          return QueryCloseAllChildren ();

      case WM_DESTROY:
          PostQuitMessage (0);
          break;

      default:
          /*      use DefFrameProc() instead of DefWindowProc() since there
           *      are things that have to be handled differently because of MDI
           */
          return DefFrameProc (hwnd,hwndMDIClient,msg,wParam,lParam);
    }
    return 0;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : MPMDIWndProc ( hwnd, msg, wParam, lParam )                *
 *                                                          *
 *  PURPOSE    : The window function for the individual document windows,   *
 *             each of which has a "note". Each of these windows contain  *
 *             one multi-line edit control filling their client area.     *
 *             In response to the following:                            *
 *                                                          *
 *                 WM_CREATE            : Creates & diplays an edit control *
 *                                and does some initialization.     *
 *                                                          *
 *                 WM_MDIACTIVATE      : Activates/deactivates the child.  *
 *                                                          *
 *                 WM_SETFOCUS      : Sets focus on the edit control.   *
 *                                                          *
 *                 WM_SIZE            : Resizes the edit control.          *
 *                                                          *
 *                 WM_COMMAND       : Processes some of the edit          *
 *                                commands, saves files and alters  *
 *                                the edit wrap state.                *
 *                                                          *
 *                 WM_CLOSE            : Closes child if it is ok to do so.*
 *                                                          *
 *                 WM_QUERYENDSESSION : Same as above.                *
 *                                                          *
 ****************************************************************************/

LONG FAR PASCAL __export MPMDIChildWndProc ( hwnd, msg, wParam, lParam )

register HWND      hwnd;
UINT            msg;
register WPARAM   wParam;
LPARAM              lParam;

{
    HWND hwndEdit;

    switch (msg){
      case WM_CREATE:
          /* Create an edit control */
          hwndEdit = CreateWindow ("edit",
                             NULL,
                             WS_CHILD|WS_HSCROLL|WS_MAXIMIZE|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_MULTILINE,
                             0,
                             0,
                             0,
                             0,
                             hwnd,
                             ID_EDIT,
                             hInst,
                             NULL);

          /* Remember the window handle and initialize some window attributes */
          SetWindowWord (hwnd, GWW_HWNDEDIT, (WORD)hwndEdit);
          SetWindowWord (hwnd, GWW_CHANGED, FALSE);
          SetWindowWord (hwnd, GWW_WORDWRAP, FALSE);
          SetWindowWord (hwnd, GWW_UNTITLED, TRUE);
          SetFocus (hwndEdit);
          break;

      case WM_MDIACTIVATE:
          /* If we're activating this child, remember it */
          if (wParam){
            hwndActive     = hwnd;
            hwndActiveEdit = (HWND)GetWindowWord (hwnd, GWW_HWNDEDIT);
          }
          else{
            hwndActive     = NULL;
            hwndActiveEdit = NULL;
          }
          break;

      case WM_QUERYENDSESSION:
          /* Prompt to save the child */
          return !QueryCloseChild (hwnd);

      case WM_CLOSE:
          /* If its OK to close the child, do so, else ignore */
          if (QueryCloseChild (hwnd))
            goto CallDCP;
          else
            break;

      case WM_SIZE:{
          RECT rc;

          /* On creation or resize, size the edit control. */
          hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);
          GetClientRect (hwnd, &rc);
          MoveWindow (hwndEdit,
                  rc.left,
                  rc.top,
                  rc.right-rc.left,
                  rc.bottom-rc.top,
                  TRUE);
          goto CallDCP;
      }

      case WM_SETFOCUS:
          SetFocus (GetWindowWord (hwnd, GWW_HWNDEDIT));
          break;

      case WM_COMMAND:
          switch (wParam){
            case ID_EDIT:
                switch (HIWORD(lParam)){
                  case EN_CHANGE:

                      /* If the contents of the edit control have changed,
                         set the changed flag
                       */
                      SetWindowWord (hwnd, GWW_CHANGED, TRUE);
                      break;

                  case EN_ERRSPACE:
                      /* If the control is out of space, honk */
                      MessageBeep (0);
                      break;

                  default:
                      goto CallDCP;
                }
                break;

            case IDM_FILESAVE:
                /* If empty file, ignore save */
                if ((GetWindowWord(hwnd, GWW_UNTITLED)) && (!ChangeFile(hwnd)))
                  break;

                /* Save the contents of the edit control and reset the
                 * changed flag
                 */
                SaveFile (hwnd);
                SetWindowWord (hwnd, GWW_CHANGED, FALSE);
                break;

            case IDM_EDITWRAP: {
                int fWrap = GetWindowWord (hwnd, GWW_WORDWRAP);

                /* Set the wrap state, or report it */
                if (LOWORD (lParam)){
                  fWrap = !fWrap;
                  SetWrap (hwnd, fWrap);
                }

                /* return wrap state */
                return fWrap;
            }

            default:
                goto CallDCP;
          }
          break;

      default:
CallDCP:
          /* Again, since the MDI default behaviour is a little different,
           * call DefMDIChildProc instead of DefWindowProc()
           */
          return DefMDIChildProc (hwnd, msg, wParam, lParam);
    }
    return FALSE;
}


/****************************************************************************
 *                                                          *
 *  FUNCTION   : AboutDlgProc ( hwnd, msg, wParam, lParam )                *
 *                                                          *
 *  PURPOSE    : Dialog function for the About MultiPad... dialog.          *
 *                                                          *
 ****************************************************************************/
BOOL FAR PASCAL __export AboutDlgProc ( hwnd, msg, wParam, lParam )
HWND            hwnd;
register WORD msg;
register WORD wParam;
LONG            lParam;
{
    switch (msg){
      case WM_INITDIALOG:
          /* nothing to initialize */
          break;

      case WM_COMMAND:
          switch (wParam){
            case IDOK:
            case IDCANCEL:
                EndDialog(hwnd, 0);
                break;

            default:
                return FALSE;
          }
          break;

      default:
          return FALSE;
    }

    return TRUE;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : Initializemenu ( hMenu )                            *
 *                                                          *
 *  PURPOSE    : Sets up greying, enabling and checking of main menu items  *
 *             based on the app's state.                                  *
 *                                                          *
 ****************************************************************************/
VOID NEAR PASCAL InitializeMenu ( hmenu )
register HANDLE hmenu;
{
    register WORD status;
    int         i;
    long        l;

    /* Is there any active child to talk to? */
    if (hwndActiveEdit){
      /* If edit control can respond to an undo request, enable the
       * undo selection.
       */
      if (SendMessage (hwndActiveEdit, EM_CANUNDO, 0, 0L))
          status = MF_ENABLED;
      else
          status = MF_GRAYED;
      EnableMenuItem (hmenu, IDM_EDITUNDO, status);

      /* If edit control is non-empty, allow cut/copy/clear */
      l      = SendMessage (hwndActiveEdit, EM_GETSEL, 0, 0L);
      status = (HIWORD(l) == LOWORD(l)) ? MF_GRAYED : MF_ENABLED;
      EnableMenuItem (hmenu, IDM_EDITCUT, status);
      EnableMenuItem (hmenu, IDM_EDITCOPY, status);
      EnableMenuItem (hmenu, IDM_EDITCLEAR, status);

      status=MF_GRAYED;
      /* If the clipboard contains some CF_TEXT data, allow paste */
      if (OpenClipboard (hwndFrame)){
          int wFmt = 0;

          while (wFmt = EnumClipboardFormats (wFmt))
            if (wFmt == CF_TEXT){
                status = MF_ENABLED;
                break;
            }

          CloseClipboard ();
      }
      EnableMenuItem (hmenu, IDM_EDITPASTE, status);

      /* Set the word wrap state for the window */
      if ((WORD) SendMessage (hwndActive, WM_COMMAND, IDM_EDITWRAP, 0L))
          status = MF_CHECKED;
      else
          status = MF_UNCHECKED;
      CheckMenuItem (hmenu, IDM_EDITWRAP, status);

      /* Enable search menu items only if there is a search string */
      if (*szSearch)
          status = MF_ENABLED;
      else
          status = MF_GRAYED;
      EnableMenuItem (hmenu, IDM_SEARCHNEXT, status);
      EnableMenuItem (hmenu, IDM_SEARCHPREV, status);

      /* select all and wrap toggle always enabled */
      status = MF_ENABLED;
      EnableMenuItem(hmenu, IDM_EDITSELECT, status);
      EnableMenuItem(hmenu, IDM_EDITWRAP, status);
      EnableMenuItem(hmenu, IDM_SEARCHFIND, status);
    }
    else {
      /* There are no active child windows */
      status = MF_GRAYED;

      /* No active window, so disable everything */
      for (i = IDM_EDITFIRST; i <= IDM_EDITLAST; i++)
          EnableMenuItem (hmenu, i, status);

      CheckMenuItem (hmenu, IDM_EDITWRAP, MF_UNCHECKED);

      for (i = IDM_SEARCHFIRST; i <= IDM_SEARCHLAST; i++)
          EnableMenuItem (hmenu, i, status);

      EnableMenuItem (hmenu, IDM_FILEPRINT, status);

    }

    /* The following menu items are enabled if there is an active window */
    EnableMenuItem (hmenu, IDM_FILESAVE, status);
    EnableMenuItem (hmenu, IDM_FILESAVEAS, status);
    EnableMenuItem (hmenu, IDM_WINDOWTILE, status);
    EnableMenuItem (hmenu, IDM_WINDOWCASCADE, status);
    EnableMenuItem (hmenu, IDM_WINDOWICONS, status);
    EnableMenuItem (hmenu, IDM_WINDOWCLOSEALL, status);

}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : CloseAllChildren ()                                  *
 *                                                          *
 *  PURPOSE    : Destroys all MDI child windows.                      *
 *                                                          *
 ****************************************************************************/
VOID NEAR PASCAL CloseAllChildren ()
{
    register HWND hwndT;

    /* hide the MDI client window to avoid multiple repaints */
    ShowWindow(hwndMDIClient,SW_HIDE);

    /* As long as the MDI client has a child, destroy it */
    while ( hwndT = GetWindow (hwndMDIClient, GW_CHILD)){

      /* Skip the icon title windows */
      while (hwndT && GetWindow (hwndT, GW_OWNER))
          hwndT = GetWindow (hwndT, GW_HWNDNEXT);

      if (!hwndT)
          break;

      SendMessage (hwndMDIClient, WM_MDIDESTROY, (WORD)hwndT, 0L);
    }
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : CommandHandler ()                                  *
 *                                                          *
 *  PURPOSE    : Processes all "frame" WM_COMMAND messages.                *
 *                                                          *
 ****************************************************************************/
VOID NEAR PASCAL CommandHandler ( hwnd, wParam )
register HWND hwnd;
register WORD wParam;

{
   DWORD FlagSave;

   switch (wParam){
      case IDM_FILENEW:
          /* Add a new, empty MDI child */
          AddFile (NULL);
          break;

      case IDM_FILEOPEN:
          ReadFile (hwnd);
          break;

      case IDM_FILESAVE:
          /* Save the active child MDI */
          SendMessage (hwndActive, WM_COMMAND, IDM_FILESAVE, 0L);
          break;

      case IDM_FILESAVEAS:
          /* Save active child MDI under another name */
          if (ChangeFile (hwndActive))
            SendMessage (hwndActive, WM_COMMAND, IDM_FILESAVE, 0L);
          break;

      case IDM_FILEPRINT:
          /* Print the active child MDI */
          PrintFile (hwndActive);
          break;

      case IDM_FILESETUP:
       FlagSave = pd.Flags;
       pd.Flags |= PD_PRINTSETUP;    /* Set option */
       PrintDlg((LPPRINTDLG)&pd);
       pd.Flags = FlagSave;          /* Remove option */
       break;

#if 0
      /* Set up the printer environment for this app */
          GetInitializationData (hwnd);
          break;
#endif

      case IDM_FILEMENU:{

            /* lengthen / shorten the size of the MDI menu */
            HMENU hMenu;
            HMENU hWindowMenu;
            int i;

            if (lpMenu == (LPSTR)IDMULTIPAD){
              lpMenu = (LPSTR)IDMULTIPAD2;
              i       = SHORTMENU;
            }
            else{
              lpMenu = (LPSTR)IDMULTIPAD;
              i       = WINDOWMENU;
            }

            hMenu = LoadMenu (hInst, lpMenu);
            hWindowMenu = GetSubMenu (hMenu, i);

            /* Set the new menu */
            hMenu = (HMENU)SendMessage (hwndMDIClient,
                                WM_MDISETMENU,
                                0,
                                MAKELONG(hMenu,hWindowMenu));

            DestroyMenu (hMenu);
            DrawMenuBar (hwndFrame);
            break;
      }

      case IDM_FILEEXIT:
          /* Close Multipad */
          SendMessage (hwnd, WM_CLOSE, 0, 0L);
          break;

      case IDM_HELPABOUT:{
          /* Bring up the ubiquitous Ego box */
          FARPROC lpfn;

          lpfn = MakeProcInstance(AboutDlgProc, hInst);
          DialogBox (hInst, IDD_ABOUT, hwnd, lpfn);
          FreeProcInstance (lpfn);
          break;
      }

      /* The following are edit commands. Pass these off to the active
       * child's edit control window.
       */
      case IDM_EDITCOPY:
          SendMessage (hwndActiveEdit, WM_COPY, 0, 0L);
          break;

      case IDM_EDITPASTE:
          SendMessage (hwndActiveEdit, WM_PASTE, 0, 0L);
          break;

      case IDM_EDITCUT:
          SendMessage (hwndActiveEdit, WM_CUT, 0, 0L);
          break;

      case IDM_EDITCLEAR:
          SendMessage (hwndActiveEdit, EM_REPLACESEL, 0,( LONG)(LPSTR)"");
          break;

      case IDM_EDITSELECT:
          SendMessage (hwndActiveEdit, EM_SETSEL, 0, MAKELONG(0, 0xe000));
          break;

      case IDM_EDITUNDO:
          SendMessage (hwndActiveEdit, EM_UNDO, 0, 0L);
          break;

      case IDM_EDITWRAP:
          SendMessage (hwndActive, WM_COMMAND, IDM_EDITWRAP, 1L);
          break;

      case IDM_SEARCHFIND:
          /* Put up the find dialog box */
          Find ();
          break;

      case IDM_SEARCHNEXT:
          /* Find next occurence */
          FindNext ();
          break;

      case IDM_SEARCHPREV:
          /* Find previous occurence */
          FindPrev ();
          break;

      /* The following are window commands - these are handled by the
       * MDI Client.
       */
      case IDM_WINDOWTILE:
          /* Tile MDI windows */
          SendMessage (hwndMDIClient, WM_MDITILE, 0, 0L);
          break;

      case IDM_WINDOWCASCADE:
          /* Cascade MDI windows */
          SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L);
          break;

      case IDM_WINDOWICONS:
          /* Auto - arrange MDI icons */
          SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
          break;

      case IDM_WINDOWCLOSEALL:
          /* Abort operation if something is not saved */
          if (!QueryCloseAllChildren())
            break;

          CloseAllChildren();

          /* Show the window since CloseAllChilren() hides the window
           * for fewer repaints.
           */
          ShowWindow( hwndMDIClient, SW_SHOW);

          break;

      default:
         /*
          * This is essential, since there are frame WM_COMMANDS generated
          * by the MDI system for activating child windows via the
          * window menu.
          */
          DefFrameProc(hwnd, hwndMDIClient, WM_COMMAND, wParam, 0L);
    }
}
/****************************************************************************
 *                                                          *
 *  FUNCTION   : SetWrap ()                                        *
 *                                                          *
 *  PURPOSE    : Changes the word wrapping in an edit control. Since this   *
 *             cannot be done by direct means, the function creates a new *
 *             edit control, moves data from the old control to the new   *
 *             control and destroys the original control. Note that the   *
 *             function assumes that the child being modified is currently*
 *             active.                                        *          *
 *                                                          *
 ****************************************************************************/

VOID NEAR PASCAL SetWrap(hwnd, fWrap)
HWND hwnd;
BOOL fWrap;

{
    LONG    dws;
    HANDLE  hT;
    HANDLE  hTT;
    HWND    hwndOld;
    HWND    hwndNew;

    /* Change word wrap mode */
    SetWindowWord (hwnd, GWW_WORDWRAP, fWrap);

    /* Create the appropriate window style, adding a horizontal scroll
     * facility if wrapping is not present.
     */
    dws = WS_CHILD | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE;
    if (!fWrap)
      dws |= WS_HSCROLL | ES_AUTOHSCROLL;

    /* Create a new child window */
    hwndNew = CreateWindow ( "edit",
                       NULL,
                       dws,
                       0,
                       SW_SHOW,
                       0,
                       0,
                       hwnd,
                       ID_EDIT,
                       hInst,
                       NULL);

    /* Get handle to current edit control */
    hwndOld = GetWindowWord (hwnd, GWW_HWNDEDIT);

    /* Get the data handle of the old control */
    hT = (HANDLE)SendMessage (hwndOld, EM_GETHANDLE, 0, 0L);

    /* Create a dummy data handle and make it the handle to
     * the old edit control( hT still references the text of
     * old control).
     */
    hTT = LocalAlloc (LHND, 0);
    SendMessage (hwndOld, EM_SETHANDLE, hTT, 0L);

    /* Make the new window the window of interest and destroy the
     * old control.
     */
    SetWindowWord (hwnd, GWW_HWNDEDIT, hwndNew);
    hwndActiveEdit = hwndNew;
    DestroyWindow (hwndOld);

    /* Cause the window to be properly sized */
    SendMessage (hwnd, WM_SIZE, 0, 0L);

    /* Free the new window's old data handle and set it to
     * hT (text of old edit control)
     */
    LocalFree ((HANDLE)SendMessage (hwndNew, EM_GETHANDLE, 0, 0L));
    SendMessage (hwndNew, EM_SETHANDLE, hT, 0L);

    ShowWindow (hwndNew, SW_SHOW);

    /* Set focus to the new edit control */
    SetFocus (hwndNew);

}


/****************************************************************************
 *                                                          *
 *  FUNCTION   : MPError ( hwnd, flags, id, ...)                      *
 *                                                          *
 *  PURPOSE    : Flashes a Message Box to the user. The format string is    *
 *             taken from the STRINGTABLE.                            *
 *                                                          *
 *  RETURNS    : Returns value returned by MessageBox() to the caller.          *
 *                                                          *
 ****************************************************************************/
short FAR CDECL MPError(hwnd, bFlags, id, ...)
HWND hwnd;
WORD bFlags;
WORD id;
{
    char sz[160];
    char szFmt[128];

    LoadString (hInst, id, szFmt, sizeof (szFmt));
    wvsprintf (sz, szFmt, (LPSTR)(&id + 1));
    LoadString (hInst, IDS_APPNAME, szFmt, sizeof (szFmt));
    return MessageBox (hwndFrame, sz, szFmt, bFlags);
}


/****************************************************************************
 *                                                          *
 *  FUNCTION   : QueryCloseAllChildren()                            *
 *                                                          *
 *  PURPOSE    : Asks the child windows if it is ok to close up app. Nothing*
 *             is destroyed at this point. The z-order is not changed.    *
 *                                                          *
 *  RETURNS    : TRUE - If all children agree to the query.                *
 *             FALSE- If any one of them disagrees.                      *
 *                                                          *
 ****************************************************************************/

BOOL NEAR PASCAL QueryCloseAllChildren()
{
    register HWND hwndT;

    for ( hwndT = GetWindow (hwndMDIClient, GW_CHILD);
        hwndT;
        hwndT = GetWindow (hwndT, GW_HWNDNEXT)       ){

      /* Skip if an icon title window */
      if (GetWindow (hwndT, GW_OWNER))
          continue;

      if (SendMessage (hwndT, WM_QUERYENDSESSION, 0, 0L))
          return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : QueryCloseChild (hwnd)                             *
 *                                                          *
 *  PURPOSE    : If the child MDI is unsaved, allow the user to save, not   *
 *               save, or cancel the close operation.                       *
 *                                                          *
 *  RETURNS    : TRUE  - if user chooses save or not save, or if the file   *
 *                       has not changed.                                   *
 *             FALSE - otherwise.                                  *
 *                                                          *
 ****************************************************************************/

BOOL NEAR PASCAL QueryCloseChild(hwnd)
register HWND hwnd;
{
    char       sz [64];
    register int i;

    /* Return OK if edit control has not changed. */
    if (!GetWindowWord (hwnd, GWW_CHANGED))
      return TRUE;

    GetWindowText (hwnd, sz, sizeof(sz));

    /* Ask user whether to save / not save / cancel */
    i = MPError (hwnd,
             MB_YESNOCANCEL|MB_ICONQUESTION,IDS_CLOSESAVE,
             (LPSTR)sz);

    switch (i){
      case IDYES:
          /* User wants file saved */
          SaveFile(hwnd);
          break;

      case IDNO:
          /* User doesn't want file saved */
          break;

      default:
          /* We couldn't do the messagebox, or not ok to close */
          return FALSE;
    }
    return TRUE;
}

0
 
LVL 4

Expert Comment

by:emmons
Comment Utility
I seem to be having some problems with the size of this post. If it fails, I will add a 0 point question with the same title up top.

This is two files.

/***************************************************************************
 *                                                                         *
 *  MODULE    : MpFile.c                                                   *
 *                                                                         *
 *  PURPOSE   : Contains the code for File I/O for Multipad.               *
 *                                                                         *
 *  FUNCTIONS : AlreadyOpen   - Determines if a file is already open.      *
 *                                                                         *
 *              AddFile       - Creates a new MDI window and, if specified,*
 *                        loads a file into it.                      *
 *                                                                         *
 *              LoadFile      - Loads a file into a MDI window.            *
 *                                                                         *
 *              ReadFile      - Calls File/Open dialog and appropriately   *
 *                              responds to the user's input.              *
 *                                                                         *
 *              SaveFile      - Saves the contents of a MDI window's edit  *
 *                              control to a file.                         *
 *                                                                         *
 *              SetSaveFrom   - Formats the "Save 'file' to" string.       *
 *                                                                         *
 *              SaveAsDlgProc - Dialog function for the File/SaveAs dialog.*
 *                                                                         *
 *              ChangeFile    - Calls File/SaveAs dialog.                  *
 *                                                                         *
 ***************************************************************************/
#include "multipad.h"
#include "commdlg.h"

#include <string.h>

OFSTRUCT      of;
/****************************************************************************
 *                                                                          *
 *  FUNCTION   : AlreadyOpen(szFile)                                        *
 *                                                                          *
 *  PURPOSE    : Checks to see if the file described by the string pointed  *
 *               to by 'szFile' is already open.                            *
 *                                                                          *
 *  RETURNS    : a handle to the described file's window if that file is    *
 *               already open;  NULL otherwise.                             *
 *                                                                          *
 ****************************************************************************/

HWND AlreadyOpen(char *szFile)
{
    int     iDiff;
    HWND    hwndCheck;
    char    szChild[64];
    LPSTR   lpChild, lpFile;
    int     wFileTemp;

    /* Open the file with the OF_PARSE flag to obtain the fully qualified
     * pathname in the OFSTRUCT structure.
     */
    wFileTemp = OpenFile ((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE);
    if (! wFileTemp)
      return(NULL);
    _lclose (wFileTemp);

    /* Check each MDI child window in Multipad */
    for (   hwndCheck = GetWindow(hwndMDIClient, GW_CHILD);
          hwndCheck;
          hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT)   ) {
      /* Initialization  for comparison */
      lpChild = szChild;
      lpFile = AnsiUpper((LPSTR) of.szPathName);
      iDiff = 0;

      /* Skip icon title windows */
      if (GetWindow(hwndCheck, GW_OWNER))
          continue;

      /* Get current child window's name */
      GetWindowText(hwndCheck, lpChild, 64);

      /* Compare window name with given name */
      while ((*lpChild) && (*lpFile) && (!iDiff)){
          if (*lpChild++ != *lpFile++)
            iDiff = 1;
      }

      /* If the two names matched, the file is already   */
      /* open -- return handle to matching child window. */
      if (!iDiff)
          return(hwndCheck);
    }
    /* No match found -- file is not open -- return NULL handle */
    return 0;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : AddFile (lpName)                                  *
 *                                                          *
 *  PURPOSE    : Creates a new MDI window. If the lpName parameter is not   *
 *             NULL, it loads a file into the window.                 *
 *                                                          *
 *  RETURNS    : HWND  - A handle to the new window.                      *
 *                                                          *
 ****************************************************************************/

HWND FAR PASCAL AddFile(pName)
char * pName;
{
    HWND hwnd;

    char          sz[160];
    MDICREATESTRUCT mcs;

    if (!pName) {
      /* The pName parameter is NULL -- load the "Untitled" string from */
      /* STRINGTABLE and set the title field of the MDI CreateStruct.    */
      LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz));
      mcs.szTitle = (LPSTR)sz;
    }
    else
      /* Title the window with the fully qualified pathname obtained by
       * calling OpenFile() with the OF_PARSE flag (in function
       * AlreadyOpen(), which is called before AddFile().
       */
      mcs.szTitle = of.szPathName;

    mcs.szClass = szChild;
    mcs.hOwner      = hInst;

    /* Use the default size for the window */
    mcs.x = mcs.cx = CW_USEDEFAULT;
    mcs.y = mcs.cy = CW_USEDEFAULT;

    /* Set the style DWORD of the window to default */
    mcs.style = styleDefault;

    /* tell the MDI Client to create the child */
    hwnd = (WORD)SendMessage (hwndMDIClient,
                        WM_MDICREATE,
                        0,
                        (LONG)(LPMDICREATESTRUCT)&mcs);

    /* Did we get a file? Read it into the window */
    if (pName){
      if (!LoadFile(hwnd, pName)){
          /* File couldn't be loaded -- close window */
          SendMessage(hwndMDIClient, WM_MDIDESTROY, (WORD) hwnd, 0L);
      }
    }

    return 0;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : LoadFile (lpName)                                  *
 *                                                          *
 *  PURPOSE    : Given the handle to a MDI window and a filename, reads the *
 *             file into the window's edit control child.                 *
 *                                                          *
 *  RETURNS    : TRUE  - If file is sucessfully loaded.                 *
 *             FALSE - Otherwise.                                  *
 *                                                          *
 ****************************************************************************/

int FAR PASCAL LoadFile (hwnd, pName)
HWND hwnd;
char * pName;
{
    WORD   wLength;
    HANDLE hT;
    LPSTR  lpB;
    HWND   hwndEdit;
    int    fh;

    hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);

    /* The file has a title, so reset the UNTITLED flag. */
    SetWindowWord(hwnd, GWW_UNTITLED, FALSE);

    fh = _lopen (pName, 0);

    /* Make sure file has been opened correctly */
    if ( fh < 0 )
      goto error;

    /* Find the length of the file */
    wLength = (WORD)_llseek (fh, 0L, 2);
    _llseek (fh, 0L, 0);

    /* Attempt to reallocate the edit control's buffer to the file size */
    hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
    if (LocalReAlloc(hT, wLength+1, LHND) == 0) {
      /* Couldn't reallocate to new size -- error */
      _lclose (fh);
      goto error;
    }

    /* read the file into the buffer */
    if (wLength != _lread (fh, (lpB = (LPSTR)LocalLock (hT)), wLength))
      MPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName);

    /* Zero terminate the edit buffer */
    lpB[wLength] = 0;
    LocalUnlock (hT);

    SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
    _lclose (fh);

    return TRUE;

error:
    /* Report the error and quit */
    MPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName);
    return FALSE;
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : ReadFile(hwnd)                                             *
 *                                                                          *
 *  PURPOSE    : Called in response to a File/Open menu selection. It asks  *
 *               the user for a file name and responds appropriately.       *
 *                                                                          *
 ****************************************************************************/

VOID FAR PASCAL ReadFile(HWND hwnd)
{
    char    szFile[128];
    HWND    hwndFile;
    OPENFILENAME of;

    lstrcpy(szFile, "*.TXT");

      memset(&of, '\0', sizeof(OPENFILENAME));

    of.lStructSize  = sizeof(OPENFILENAME);
    of.hwndOwner    = hwnd;
    of.lpstrFilter  = (LPSTR)"Text Files (*.TXT)\0*.TXT\0";
    of.lpstrCustomFilter = NULL;
    of.nFilterIndex = 1;
    of.lpstrFile    = (LPSTR)szFile;
    of.nMaxFile     = 128;
    of.lpstrInitialDir = NULL;
    of.lpstrTitle   = NULL;
    of.Flags        = OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;
    of.lpstrDefExt  = NULL;

    if(!GetOpenFileName(&of))
       return;

    /* If the result is not the empty string -- take appropriate action */
    if (*szFile) {
           /* Is file already open?? */
           if (hwndFile = AlreadyOpen(szFile)) {
              /* Yes -- bring the file's window to the top */
              BringWindowToTop(hwndFile);
           }
           else {
              /* No -- make a new window and load file into it */
              AddFile(szFile);
           }
    }
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : SaveFile (hwnd)                                  *
 *                                                          *
 *  PURPOSE    : Saves contents of current edit control to disk.          *
 *                                                          *
 ****************************************************************************/

VOID FAR PASCAL SaveFile( hwnd )

HWND hwnd;
{
    HANDLE   hT;
    LPSTR    lpT;
    char     szFile[128];
    WORD     cch;
    int      fh;
    OFSTRUCT of;
    HWND     hwndEdit;

    hwndEdit = GetWindowWord ( hwnd, GWW_HWNDEDIT);
    GetWindowText (hwnd, szFile, sizeof(szFile));

    /* If there is no extension (control is 'Untitled') add .TXT as extension */
    for (cch = FALSE, lpT = szFile; *lpT; lpT++)
      switch (*lpT){
          case '.':
             cch = TRUE;
             break;

          case '\\':
          case ':' :
             cch = FALSE;
             break;
      }
    if (!cch)
      LoadString (hInst, IDS_ADDEXT, lpT, lpT - (LPSTR)szFile);

    fh = OpenFile (szFile, &of, OF_WRITE | OF_CREATE);

    /* If file could not be opened, quit */
    if (fh < 0){
      MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTCREATE, (LPSTR)szFile);
      return;
    }

    /* Find out the length of the text in the edit control */
    cch = GetWindowTextLength (hwndEdit);

    /* Obtain a handle to the text buffer */
    hT      = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
    lpT = (LPSTR)LocalLock (hT);

    /* Write out the contents of the buffer to the file. */
    if (cch != _lwrite (fh, lpT, cch))
      MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTWRITE, (LPSTR)szFile);

    /* Clean up */
    LocalUnlock (hT);
    SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);

    _lclose (fh);

    return;
}


/****************************************************************************
 *                                                          *
 *  FUNCTION   : ChangeFile (hwnd)                                  *
 *                                                          *
 *  PURPOSE    : Invokes the File/SaveAs dialog.                      *
 *                                                          *
 *  RETURNS    : TRUE  - if user selected OK or NO.                      *
 *             FALSE - otherwise.                                  *
 *                                                          *
 ****************************************************************************/

BOOL FAR PASCAL ChangeFile (hwnd)
HWND hwnd;
{
    char    szFile[128];
    OPENFILENAME of;

    if (GetWindowWord(hwnd, GWW_UNTITLED))
        lstrcpy(szFile, "*.TXT");
    else
        GetWindowText(hwnd, szFile, 128);

    of.lStructSize  = sizeof(OPENFILENAME);
    of.hwndOwner    = hwnd;
    of.lpstrFilter  = (LPSTR)"Text Files (*.TXT)\0*.TXT\0";
    of.lpstrCustomFilter = NULL;
    of.nFilterIndex = 1;
    of.lpstrFile    = (LPSTR)szFile;
    of.nMaxFile     = 128;
    of.lpstrInitialDir = NULL;
    of.lpstrTitle   = NULL;
    of.Flags        = OFN_HIDEREADONLY;
    of.lpstrDefExt  = NULL;

    if(!GetSaveFileName(&of))
       return(FALSE);

    SetWindowWord(hwnd, GWW_UNTITLED, 0);
    SetWindowText(hwnd, szFile);
    return(TRUE);
}

/***************************************************************************
 *                                                         *
 *  MODULE      : MpFind.c                                           *
 *                                                         *
 *  PURPOSE      : Code to do text searches in MultiPad.                *
 *                                                         *
 *  FUNCTIONS      : RealSlowCompare () - Compares subject string with target *
 *                               string.                           *
 *                                                         *
 *              MyFindText ()           - Looks for the search string in the  *
 *                               active window.                     *
 *                                                         *
 *              FindPrev ()           - Find previous occurence of search   *
 *                               string.                           *
 *                                                         *
 *              FindNext ()           - Find next occurence of search string*
 *                                                         *
 *              FindDlgProc ()     - Dialog function for Search/Find.    *
 *                                                         *
 *              Find ()           - Invokes FindDlgProc ()               *
 *                                                         *
 ***************************************************************************/
#include "multipad.h"

#undef HIWORD
#undef LOWORD

#define HIWORD(l) (((WORD*)&(l))[1])
#define LOWORD(l) (((WORD*)&(l))[0])

BOOL fCase         = FALSE;    /* Turn case sensitivity off */
char szSearch[160] = "";       /* Initialize search string  */

/****************************************************************************
 *                                                          *
 *  FUNCTION   : RealSlowCompare ()                                  *
 *                                                          *
 *  PURPOSE    : Compares subject string with the target string. This fn/   *
 *             is called repeatedly so that all substrings are compared,  *
 *             which makes it O(n ** 2), hence it's name.                 *
 *                                                          *
 *  RETURNS    : TRUE  - If pSubject is identical to pTarget.                *
 *             FALSE - otherwise.                                  *
 *                                                          *
 ****************************************************************************/

BOOL NEAR PASCAL RealSlowCompare (pSubject, pTarget )
register PSTR pSubject;
register PSTR pTarget;
{
    if (fCase){
      while (*pTarget)
          if (*pTarget++ != *pSubject++)
            return FALSE;
    }
    else{
      /* If case-insensitive, convert both subject and target to lowercase
       * before comparing.
       */
      AnsiLower ((LPSTR)pTarget);
      while (*pTarget)
          if (*pTarget++ != (char)(DWORD)AnsiLower ((LPSTR)(DWORD)(BYTE)*pSubject++))
            return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : MyFindText ()                                        *
 *                                                          *
 *  PURPOSE    : Finds the search string in the active window according to  *
 *             search direction (dch) specified ( -1 for reverse and 1 for*
 *             forward searches).                                  *
 *                                                          *
 ****************************************************************************/
VOID NEAR PASCAL MyFindText( dch )
register int dch;

{
    register PSTR pText;
    HANDLE        hT;
    LONG        l;
    WORD        cch;
    int         i;

    if (!*szSearch)
      return;

    /* Find the current selection range */
    l = SendMessage(hwndActiveEdit, EM_GETSEL, 0, 0L);

    /* Get the handle to the text buffer and lock it */
    hT        = (HANDLE)SendMessage (hwndActiveEdit, EM_GETHANDLE, 0, 0L);
    pText = LocalLock(hT);

    /* Get the length of the text */
    cch = (WORD)SendMessage (hwndActiveEdit, WM_GETTEXTLENGTH, 0, 0L);

    /* Start with the next char. in selected range ... */
    pText += LOWORD (l) + dch;

    /* Compute how many characters are before/after the current selection*/
    if (dch < 0)
      i = LOWORD (l);
    else
      i = cch - LOWORD (l) + 1 - lstrlen (szSearch);

    /* While there are uncompared substrings... */
    while ( i > 0){
      LOWORD(l)+=dch;

      /* Does this substring match? */
      if (RealSlowCompare(pText,szSearch)){

          /* Yes, unlock the buffer.*/
          LocalUnlock(hT);

          /* Select the located string */
          HIWORD(l) = LOWORD(l) + lstrlen (szSearch);
          SendMessage (hwndActiveEdit, EM_SETSEL, 0, l);
          return;
      }
      i--;

      /* increment/decrement start position by 1 */
      pText += dch;
    }

    /* Not found... unlock buffer. */
    LocalUnlock (hT);

    /* Give a message */
    MPError (hwndFrame, MB_OK | MB_ICONEXCLAMATION, IDS_CANTFIND, (LPSTR)szSearch);

    return;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : FindPrev ()                                        *
 *                                                          *
 *  PURPOSE    : Finds the previous occurence of the search string. Calls   *
 *             MyFindText () with a negative search direction.                *
 *                                                          *
 ****************************************************************************/
VOID FAR PASCAL FindPrev(void)
{
    MyFindText(-1);
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : FindNext ()                                        *
 *                                                          *
 *  PURPOSE    : Finds the next occurence of search string. Calls          *
 *             MyFindText () with a positive search direction.                *
 *                                                          *
 ****************************************************************************/
VOID FAR PASCAL FindNext(void)
{
    MyFindText(1);
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : FindDlgProc(hwnd, message, wParam, lParam)                *
 *                                                          *
 *  PURPOSE    : Dialog function for the Search/Find command. Prompts user  *
 *             for target string, case flag and search direction.          *
 *                                                          *
 ****************************************************************************/
BOOL FAR PASCAL FindDlgProc(hwnd, msg, wParam, lParam)
HWND hwnd;
WORD msg;
WORD wParam;
LONG lParam;
{
    switch (msg){
      case WM_INITDIALOG:{

          /* Check/uncheck case button */
          CheckDlgButton (hwnd, IDD_CASE, fCase);

          /* Set default search string to most recently searched string */
          SetDlgItemText (hwnd, IDD_SEARCH, szSearch);

          /* Allow search only if target is nonempty */
          if (!lstrlen (szSearch)){
            EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
            EnableWindow (GetDlgItem (hwnd, IDD_PREV), FALSE);
          }
          break;
      }

      case WM_COMMAND:{

          /* Search forward by default (see IDOK below) */
          int i = 1;

          switch (wParam){
            /* if the search target becomes non-empty, enable searching */
            case IDD_SEARCH:
                if (HIWORD (lParam) == EN_CHANGE){
                  if (!(WORD) SendDlgItemMessage (hwnd,
                                          IDD_SEARCH,
                                          WM_GETTEXTLENGTH,
                                          0,
                                          0L))
                      i = FALSE;
                  else
                      i = TRUE;
                  EnableWindow (GetDlgItem (hwnd, IDOK), i);
                  EnableWindow (GetDlgItem (hwnd, IDD_PREV), i);
                }
                break;

            case IDD_CASE:
                /* Toggle state of case button */
                CheckDlgButton (hwnd,
                            IDD_CASE,
                            !IsDlgButtonChecked (hwnd, IDD_CASE));
                break;

            case IDD_PREV:
                /* Set direction to backwards */
                i=-1;
                /*** FALL THRU ***/

            case IDOK:
                /* Save case selection */
                fCase = IsDlgButtonChecked( hwnd, IDD_CASE);

                /* Get search string */
                GetDlgItemText (hwnd, IDD_SEARCH, szSearch, sizeof (szSearch));

                /* Find the text */
                MyFindText (i);
                /*** FALL THRU ***/

            /* End the dialog */
            case IDCANCEL:
                EndDialog (hwnd, 0);
                break;

            default:
                return FALSE;
          }
          break;
      }
      default:
          return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : Find()                                         *
 *                                                          *
 *  PURPOSE    : Invokes the Search/Find dialog.                      *
 *                                                          *
 ****************************************************************************/

VOID FAR PASCAL Find()
{
    FARPROC lpfn;

    lpfn = MakeProcInstance (FindDlgProc, hInst);
    DialogBox (hInst, IDD_FIND, hwndFrame, lpfn);
    FreeProcInstance (lpfn);
}

0
 
LVL 4

Expert Comment

by:emmons
Comment Utility
Two more files...
/***************************************************************************
 *                                                         *
 *  MODULE      : MpInit.c                                       *
 *                                                         *
 *  PURPOSE      : Contains initialization code for MultiPad.               *
 *                                                         *
 *  FUNCTIONS      : InitializeApplication() - Sets up Class data structure   *
 *                                  and registers window class.    *
 *                                                         *
 *              InitializeInstance ()   - Does a per-instance initial-   *
 *                                  ization of MultiPad. Creates   *
 *                                  the "frame" and MDI client.    *
 *                                                         *
 ***************************************************************************/

#include "multipad.h"
#include "commdlg.h"

PRINTDLG pd;                  /* Common print dialog structure */

char szFrame[] = "mpframe";   /* Class name for "frame" window */
char szChild[] = "mpchild";   /* Class name for MDI window     */

/****************************************************************************
 *                                                          *
 *  FUNCTION   : InitializeApplication ()                            *
 *                                                          *
 *  PURPOSE    : Sets up the class data structures and does a one-time          *
 *             initialization of the app by registering the window classes*
 *                                                          *
 *  RETURNS    : TRUE  - If RegisterClass() was successful for both classes.*
 *             FALSE - otherwise.                                  *
 *                                                          *
 ****************************************************************************/

BOOL FAR PASCAL InitializeApplication()
{
    WNDCLASS      wc;

    /* Register the frame class */
    wc.style           = 0;
    wc.lpfnWndProc   = MPFrameWndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInst;
    wc.hIcon           = LoadIcon(hInst,IDMULTIPAD);
    wc.hCursor           = LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = COLOR_APPWORKSPACE+1;
    wc.lpszMenuName  = IDMULTIPAD;
    wc.lpszClassName = szFrame;

    if (!RegisterClass (&wc) )
      return FALSE;

    /* Register the MDI child class */
    wc.lpfnWndProc   = MPMDIChildWndProc;
    wc.hIcon           = LoadIcon(hInst,IDNOTE);
    wc.lpszMenuName  = NULL;
    wc.cbWndExtra    = CBWNDEXTRA;
    wc.lpszClassName = szChild;

    /* fill in non-variant fields of PRINTDLG struct. */

    pd.lStructSize    = sizeof(PRINTDLG);
    pd.hDevMode       = NULL;
    pd.hDevNames      = NULL;
    pd.Flags          = PD_RETURNDC | PD_NOSELECTION | PD_NOPAGENUMS;
    pd.nCopies        = 1;

   
   if (!RegisterClass(&wc))
      return FALSE;

    return TRUE;

}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : InitializeInstance ()                                  *
 *                                                          *
 *  PURPOSE    : Performs a per-instance initialization of MultiPad. It     *
 *             also creates the frame and an MDI window.                *
 *                                                          *
 *  RETURNS    : TRUE  - If initialization was successful.                *
 *             FALSE - otherwise.                                  *
 *                                                          *
 ****************************************************************************/
BOOL FAR PASCAL InitializeInstance(LPSTR lpCmdLine, WORD nCmdShow)
{
    extern HWND  hwndMDIClient;
    char       sz[80], *pCmdLine;

    /* Get the base window title */
    LoadString (hInst, IDS_APPNAME, sz, sizeof(sz));

    /* Create the frame */
    hwndFrame = CreateWindow (szFrame,
                        sz,
                        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                        CW_USEDEFAULT,
                        0,
                        CW_USEDEFAULT,
                        0,
                        NULL,
                        NULL,
                        hInst,
                        NULL);

    if ((!hwndFrame) || (!hwndMDIClient))
      return FALSE;

    pd.hwndOwner = hwndFrame;

   /* Load main menu accelerators */
    if (!(hAccel = LoadAccelerators (hInst, IDMULTIPAD)))
      return FALSE;

    /* Display the frame window */
    ShowWindow (hwndFrame, nCmdShow);
    UpdateWindow (hwndFrame);

    /* If the command line string is empty, nullify the pointer to it
    ** else copy command line into our data segment
    */
    if ( lpCmdLine && !(*lpCmdLine))
           pCmdLine = NULL;
    else {
        pCmdLine = (char *) LocalAlloc(LPTR, lstrlen(lpCmdLine) + 1);
        if (pCmdLine)
           lstrcpy(pCmdLine, lpCmdLine);
    }

    /* Add the first MDI window */
    AddFile (pCmdLine);

    /* if we allocated a buffer then free it */
    if (pCmdLine)
        LocalFree((LOCALHANDLE) pCmdLine);

    /* Default to minimized windows after the first. */
    styleDefault = 0L;

    return TRUE;

}
/***************************************************************************
 *                                                         *
 *  MODULE      : MpPrint()                                       *
 *                                                         *
 *  PURPOSE      : Printing code for MultiPad.                           *
 *                                                         *
 *  FUNCTIONS      : GetPrinterDC ()         -  Creates a printer DC for the *
 *                                    default device.               *
 *                                                         *
 *              AbortProc ()               -  Export proc. for GDI to check*
 *                                    print abort.               *
 *                                                         *
 *              PrintDlgProc ()         -  Dialog function for the print*
 *                                    cancel dialog.               *
 *                                                         *
 *              PrintFile ()               -  Prints the contents of the   *
 *                                    edit control.               *
 *                                                         *
 *              GetInitializationData () -  Gets DC initialisation data  *
 *                                    from a DC supporting         *
 *                                    ExtDeviceMode().               *
 *                                                         *
 ***************************************************************************/
#include "multipad.h"
#include "commdlg.h"

PRINTDLG pd;      /* Common print dialog structure */
BOOL fAbort;            /* TRUE if the user has aborted the print job       */
HWND hwndPDlg;            /* Handle to the cancel print dialog             */
PSTR szTitle;            /* Global pointer to job title                   */
HANDLE hInitData=NULL;      /* handle to initialization data             */


/****************************************************************************
 *                                                          *
 *  FUNCTION   : GetPrinterDC ()                                  *
 *                                                          *
 *  PURPOSE    : Creates a printer display context for the printer  *
 *                                                          *
 *  RETURNS    : HDC   - A handle to printer DC.                      *
 *                                                          *
 ****************************************************************************/
HDC FAR PASCAL GetPrinterDC(void)
{

    HDC         hDC;
    LPDEVMODE   lpDevMode = NULL;
    LPDEVNAMES  lpDevNames;
    LPSTR       lpszDriverName;
    LPSTR       lpszDeviceName;
    LPSTR       lpszPortName;

    if (!PrintDlg((LPPRINTDLG)&pd))
        return(NULL);

    if (pd.hDC)
      {
        hDC = pd.hDC;
      }
    else
      {

        if (!pd.hDevNames)
            return(NULL);

        lpDevNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
        lpszDriverName = (LPSTR)lpDevNames + lpDevNames->wDriverOffset;
        lpszDeviceName = (LPSTR)lpDevNames + lpDevNames->wDeviceOffset;
        lpszPortName   = (LPSTR)lpDevNames + lpDevNames->wOutputOffset;
        GlobalUnlock(pd.hDevNames);

        if (pd.hDevMode)
            lpDevMode = (LPDEVMODE)GlobalLock(pd.hDevMode);

        hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (LPSTR)lpDevMode);

        if (pd.hDevMode && lpDevMode)
            GlobalUnlock(pd.hDevMode);
      }

    if (pd.hDevNames)
        GlobalFree(pd.hDevNames);
    if (pd.hDevMode)
        GlobalFree(pd.hDevMode);
    return(hDC);
}


/****************************************************************************
 *                                                          *
 *  FUNCTION   : AbortProc()                                        *
 *                                                          *
 *  PURPOSE    : To be called by GDI print code to check for user abort.    *
 *                                                          *
 ****************************************************************************/
int FAR PASCAL __export AbortProc ( hdc, reserved )
HDC hdc;
WORD reserved;
{
    MSG msg;

    /* Allow other apps to run, or get abort messages */
    while (!fAbort && PeekMessage (&msg, NULL, NULL, NULL, TRUE))
      if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)){
          TranslateMessage (&msg);
          DispatchMessage  (&msg);
      }
    return !fAbort;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : PrintDlgProc ()                                  *
 *                                                          *
 *  PURPOSE    : Dialog function for the print cancel dialog box.          *
 *                                                          *
 *  RETURNS    : TRUE  - OK to abort/ not OK to abort                      *
 *             FALSE - otherwise.                                  *
 *                                                          *
 ****************************************************************************/
BOOL FAR PASCAL __export PrintDlgProc(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
{
   switch (msg){
         case WM_COMMAND:
             /* abort printing if the only button gets hit */
             fAbort = TRUE;
             break;

      default:
          return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                                                          *
 *  FUNCTION   : PrintFile ()                                        *
 *                                                          *
 *  PURPOSE    : Prints the contents of the edit control.                *
 *                                                          *
 ****************************************************************************/

VOID FAR PASCAL PrintFile(HWND hwnd)
{
    HDC     hdc;
    int     yExtPage;
    char    sz[32];
    WORD    cch;
    WORD    ich;
    PSTR    pch;
    WORD    iLine;
    WORD    nLinesEc;
    HANDLE  hT;
    FARPROC lpfnAbort;
    FARPROC lpfnPDlg;
    HWND    hwndPDlg;
    WORD    dy;
    int     yExtSoFar;
    WORD    fError = TRUE;
    HWND    hwndEdit;

    hwndEdit = (HWND)GetWindowWord(hwnd,GWW_HWNDEDIT);

    /* Create the job title by loading the title string from STRINGTABLE */
    cch = LoadString (hInst, IDS_PRINTJOB, sz, sizeof(sz));
    szTitle = sz + cch;
    cch += GetWindowText (hwnd, sz + cch, 32 - cch);
    sz[31] = 0;

    /* Make instances of the Abort proc. and the Print dialog function */
    lpfnAbort = MakeProcInstance (AbortProc, hInst);
    if (!lpfnAbort)
      goto getout;
    lpfnPDlg = MakeProcInstance (PrintDlgProc, hInst);
    if (!lpfnPDlg)
      goto getout4;

    /* Initialize the printer */
    hdc = GetPrinterDC();
    if (!hdc)
      goto getout5;

    /* Disable the main application window and create the Cancel dialog */
    EnableWindow (hwndFrame, FALSE);
    hwndPDlg = CreateDialog (hInst, IDD_PRINT, hwnd, lpfnPDlg);
    if (!hwndPDlg)
      goto getout3;
    ShowWindow (hwndPDlg, SW_SHOW);
    UpdateWindow (hwndPDlg);

    /* Allow the app. to inform GDI of the escape function to call */
    if (Escape (hdc, SETABORTPROC, 0, (LPSTR)lpfnAbort, NULL) < 0)
      goto getout1;

    /* Initialize the document */
    if (Escape (hdc, STARTDOC, cch, (LPSTR)sz, NULL) < 0)
      goto getout1;

    /* Get the height of one line and the height of a page */
    dy = HIWORD (GetTextExtent (hdc, "CC", 2));
    yExtPage = GetDeviceCaps (hdc, VERTRES);

    /* Get the lines in document and and a handle to the text buffer */
    iLine     = 0;
    yExtSoFar = 0;
    nLinesEc  = (WORD)SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L);
    hT            = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);

    /* While more lines print out the text */
    while (iLine < nLinesEc){
      if (yExtSoFar + (int)dy > yExtPage){
          /* Reached the end of a page. Tell the device driver to eject a
           * page
           */
          if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0 || fAbort)
            goto getout2;
          yExtSoFar = 0;
      }

      /* Get the length and position of the line in the buffer
       * and lock from that offset into the buffer */
      ich = (WORD)SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0L);
      cch = (WORD)SendMessage (hwndEdit, EM_LINELENGTH, ich, 0L);
      pch = LocalLock(hT) + ich;

      /* Print the line and unlock the text handle */
      TextOut (hdc, 0, yExtSoFar, (LPSTR)pch, cch);
      LocalUnlock (hT);

      /* Test and see if the Abort flag has been set. If yes, exit. */
      if (fAbort)
          goto getout2;

      /* Move down the page */
      yExtSoFar += dy;
      iLine++;
    }

    /* Eject the last page. */
    if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0)
      goto getout2;

    /* Complete the document. */
    if (Escape (hdc, ENDDOC, 0, NULL, NULL) < 0){
getout2:
      /* Ran into a problem before NEWFRAME? Abort the document */
      Escape( hdc, ABORTDOC, 0, NULL, NULL);
    }
    else
      fError=FALSE;

getout3:
    /* Close the cancel dialog and re-enable main app. window */
    EnableWindow (hwndFrame, TRUE);
    DestroyWindow (hwndPDlg);

getout1:
    DeleteDC(hdc);

getout5:
    /* Get rid of dialog procedure instances */
    FreeProcInstance (lpfnPDlg);

getout4:
    FreeProcInstance (lpfnAbort);

getout:

    /* Error? make sure the user knows... */
    if (fError)
      MPError (hwnd, MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPSTR)szTitle);

    return;
}

#if 0

/****************************************************************************
 *                                                          *
 *  FUNCTION   : GetInitializationData()                            *
 *                                                          *
 *  PURPOSE    : Gets DC initialization data from a printer driver          *
 *             supporting ExtDeviceMode(). Called in response to the          *
 *             File/Printer setup menu selection.                      *
 *                                                          *
 *             This function allows the user to change the printer          *
 *             settings FOR MULTIPAD ONLY.  This allows Multipad to print *
 *             in a variety of settings without messing up any other          *
 *             applications. In a more sophisticated application, this    *
 *             setup could even be saved on a document-by-document basis. *
 *                                                          *
 ****************************************************************************/
BOOL FAR PASCAL GetInitializationData( hwnd )
HWND hwnd ;
{
    LPSTR     lpOld;
    LPSTR     lpNew;
    FARPROC   lpfn;
    HANDLE    hT,hDrv;
    char      sz[32];
    WORD      cb;
    int       flag;

    /* Pop up dialog for user and retain data in app buffer */
    flag = DM_PROMPT | DM_COPY;

    /* Load the device driver and find the ExtDeviceMode() function */
    wsprintf (sz, "%s.drv", (LPSTR)szDriver);
    if ((hDrv = LoadLibrary (sz)) < 32)
      return FALSE;
    if (!(lpfn = GetProcAddress (hDrv, szExtDeviceMode)))
      return FALSE;

    if (hInitData){
      /* We have some old data... we want to modify the previously specified
       * setup rather than starting with the default setup.
       */
      lpOld = (LPSTR)LocalLock(hInitData);
      flag |= DM_MODIFY;
    }
    else
      lpOld = NULL;

    /* Get the number of bytes needed for the init data */
    cb = (*lpfn) (hwnd,
              hDrv,
              NULL,
              (LPSTR)szDevice,
              (LPSTR)szPort,
              (LPDEVMODE)NULL,
              (LPSTR)NULL,
              0);

    /* Grab some memory for the new data and lock it. */
    hT        = LocalAlloc (LHND,cb);
    lpNew = (LPSTR)LocalLock (hT);

    /* Post the device mode dialog. 0 flag iff user hits OK button */
    if ((*lpfn) (hwnd,
             hDrv,
             (LPDEVMODE)lpNew,
             (LPSTR)szDevice,
             (LPSTR)szPort,
             (LPDEVMODE)lpOld,
             (LPSTR)NULL,
             flag)==IDOK)
      flag = 0;

    /* Unlock the input structures */
    LocalUnlock (hT);
    if (hInitData)
      LocalUnlock (hInitData);

    /* If the user hit OK and everything worked, free the original init.
     * data and retain the new one.  Otherwise, toss the new buffer.
     */
    if (flag)
      LocalFree (hT);
    else{
      if (hInitData)
          LocalFree (hInitData);
      hInitData = hT;
    }

    FreeLibrary(hDrv);
    return (!flag);
}


#endif

0
 
LVL 4

Expert Comment

by:emmons
Comment Utility
/* multipad.h */

#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#include "drivinit.h"
#include "resource.h"

#ifndef CDECL
#define CDECL cdecl
#endif

#define WINDOWMENU  3      /* position of window menu             */
#define SHORTMENU   2      /* position of short version window menu */

#define DEFFILESEARCH      (LPSTR) "*.TXT"

#ifdef RC_INVOKED
#define ID(id) id
#else
#define ID(id) MAKEINTRESOURCE(id)
#endif

/* edit control identifier */
#define ID_EDIT 0xCAC

/* resource ID's */
#define IDMULTIPAD  ID(1)
#define IDMULTIPAD2 ID(3)
#define IDNOTE          ID(2)

/* Window word values for child windows */
#define GWW_HWNDEDIT      0
#define GWW_CHANGED      2
#define GWW_WORDWRAP      4
#define GWW_UNTITLED      6
#define CBWNDEXTRA      8

/* menu ID's */
#define IDM_EDITFIRST      IDM_EDITUNDO
#define IDM_EDITLAST      IDM_EDITFONT
#define IDM_SEARCHFIRST IDM_SEARCHFIND
#define IDM_SEARCHLAST      IDM_SEARCHPREV

/* dialog ids */
#define IDD_FILEOPEN      ID(200)
#define IDD_ABOUT      ID(300)
#define IDD_FIND      ID(400)
#define IDD_SAVEAS      ID(500)
#define IDD_PRINT      ID(600)
#define IDD_FONT      ID(700)
#define IDD_NEXT      IDOK

/* attribute flags for DlgDirList */
#define ATTR_DIRS      0xC010            /* find drives and directories */
#define ATTR_FILES      0x0000            /* find ordinary files             */
#define PROP_FILENAME      szPropertyName      /* name of property for dialog */

/*
 *  External variable declarations
 */
extern HANDLE hInst;            /* application instance handle              */
extern HANDLE hAccel;            /* resource handle of accelerators        */
extern HWND hwndFrame;            /* main window handle                    */
extern HWND hwndMDIClient;      /* handle of MDI Client window              */
extern HWND hwndActive;       /* handle of current active MDI child        */
extern HWND hwndActiveEdit;      /* handle of edit control in active child */
extern LONG styleDefault;      /* default child creation state         */
extern char szChild[];            /* class of child                    */
extern char szSearch[];       /* search string                    */
extern char *szDriver;            /* name of printer driver              */
extern char szPropertyName[];      /* filename property for dialog box        */
extern int iPrinter;            /* level of printing capability         */
extern BOOL fCase;            /* searches case sensitive              */
extern WORD cFonts;            /* number of fonts enumerated              */

/*  externally declared functions
 */
extern BOOL FAR PASCAL InitializeApplication(VOID);
extern BOOL FAR PASCAL InitializeInstance(LPSTR,WORD);
extern BOOL FAR PASCAL __export AboutDlgProc(HWND,WORD,WORD,LONG);
extern HWND FAR PASCAL AddFile(char *);
extern VOID FAR PASCAL ReadFile(HWND);
extern VOID FAR PASCAL SaveFile(HWND);
extern BOOL FAR PASCAL ChangeFile(HWND);
extern int FAR PASCAL LoadFile(HWND, char *);
extern VOID FAR PASCAL PrintFile(HWND);
extern BOOL FAR PASCAL GetInitializationData(HWND);
extern short FAR CDECL MPError(HWND,WORD,WORD,...);
extern VOID FAR PASCAL Find(void);
extern VOID FAR PASCAL FindNext(void);
extern VOID FAR PASCAL FindPrev(void);
extern VOID FAR PASCAL MPSpotHelp(HWND,POINT);
extern LONG FAR PASCAL __export MPFrameWndProc(HWND,UINT,WPARAM,LPARAM);
extern LONG FAR PASCAL __export MPMDIChildWndProc(HWND,UINT,WPARAM,LPARAM);
extern HDC FAR PASCAL GetPrinterDC(void);
extern VOID NEAR PASCAL SetSaveFrom (HWND, PSTR);
extern BOOL NEAR PASCAL RealSlowCompare (PSTR, PSTR);
extern VOID FAR PASCAL FindPrev (void);
extern VOID FAR PASCAL FindNext (void);
extern BOOL NEAR PASCAL IsWild (PSTR);
extern VOID NEAR PASCAL SelectFile (HWND);
extern VOID NEAR PASCAL MyFindText ( int );

0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 4

Expert Comment

by:emmons
Comment Utility
/* Multipad.def (this comment will give you an error if you don't delete it! */

NAME           MULTIPAD

DESCRIPTION  'Microsoft Windows MDI Notepad App'

EXETYPE      WINDOWS

STUB           'WINSTUB.EXE'

CODE           PRELOAD MOVEABLE DISCARDABLE
DATA           PRELOAD MOVEABLE MULTIPLE

HEAPSIZE     2048

SEGMENTS
    _TEXT    PRELOAD      MOVABLE DISCARDABLE
    _MPINIT  PRELOAD      MOVABLE DISCARDABLE
    _MPFILE  LOADONCALL MOVABLE DISCARDABLE
    _MPFIND  LOADONCALL MOVABLE DISCARDABLE
    _MPPRINT LOADONCALL MOVABLE DISCARDABLE

EXPORTS
      MPFrameWndProc
      MPMDIChildWndProc
      AboutDlgProc
      FindDlgProc
      PrintDlgProc
      AbortProc

0
 
LVL 4

Expert Comment

by:emmons
Comment Utility
# multipad.mak
# Microsoft Visual C++ generated build script - Do not modify

PROJ = MULTIPAD
DEBUG = 1
PROGTYPE = 0
CALLER =
ARGS =
DLLS =
D_RCDEFINES =
R_RCDEFINES =
ORIGIN = MSVC
ORIGIN_VER =1.00
PROJPATH =UNKNOWN
USEMFC = 0
CC = cl
CPP = cl
CXX = cl
CCREATEPCHFLAG =
CPPCREATEPCHFLAG =
CUSEPCHFLAG =
CPPUSEPCHFLAG =
FIRSTC = MPFILE.C    
FIRSTCPP =            
RC = rc
CFLAGS_D_WEXE =/nologo /YX /G2 /W3 /AM /Od /D "_DEBUG" /FR /GA /Zi
CFLAGS_R_WEXE =/nologo /YX /G2 /W3 /AM /Ox /D "NDEBUG" /FR /GA /Gs
LFLAGS_D_WEXE =/NOLOGO /NOD /STACK:8192 /ALIGN:16 /ONERROR:NOEXE /CO
LFLAGS_R_WEXE =/NOLOGO /NOD /STACK:8192 /ALIGN:16 /ONERROR:NOEXE
LIBS_D_WEXE = oldnames libw commdlg shell olecli olesvr mlibcew LIBW commdlg.lib
LIBS_R_WEXE = oldnames libw commdlg shell olecli olesvr mlibcew LIBW
RCFLAGS =/NOLOGO  
RESFLAGS =/NOLOGO  -t
RUNFLAGS =
DEFFILE = MULTIPAD.DEF
OBJS_EXT =
LIBS_EXT =
!if "$(DEBUG)" == "1"
CFLAGS = $(CFLAGS_D_WEXE)
LFLAGS = $(LFLAGS_D_WEXE)
LIBS = $(LIBS_D_WEXE)
MAPFILE = nul
RCDEFINES = $(D_RCDEFINES)
!else
CFLAGS = $(CFLAGS_R_WEXE)
LFLAGS = $(LFLAGS_R_WEXE)
LIBS = $(LIBS_R_WEXE)
MAPFILE = nul
RCDEFINES = $(R_RCDEFINES)
!endif
!if [if exist MSVC.BND del MSVC.BND]
!endif
SBRS = MPFILE.SBR \
            MPFIND.SBR \
            MPINIT.SBR \
            MPPRINT.SBR \
            MULTIPAD.SBR


MPFILE_DEP = multipad.h


MPFIND_DEP = multipad.h


MPINIT_DEP = multipad.h


MPPRINT_DEP = multipad.h


MULTIPAD_DEP = multipad.h


MULTIPAD_RCDEP = multipad.h \
      mp300.ico \
      note300.ico


all:      $(PROJ).EXE $(PROJ).BSC

MPFILE.OBJ:      MPFILE.C $(MPFILE_DEP)
      $(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c MPFILE.C

MPFIND.OBJ:      MPFIND.C $(MPFIND_DEP)
      $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MPFIND.C

MPINIT.OBJ:      MPINIT.C $(MPINIT_DEP)
      $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MPINIT.C

MPPRINT.OBJ:      MPPRINT.C $(MPPRINT_DEP)
      $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MPPRINT.C

MULTIPAD.OBJ:      MULTIPAD.C $(MULTIPAD_DEP)
      $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MULTIPAD.C

MULTIPAD.RES:      MULTIPAD.RC $(MULTIPAD_RCDEP)
      $(RC) $(RCFLAGS) $(RCDEFINES) -r MULTIPAD.RC


$(PROJ).EXE::      MULTIPAD.RES

$(PROJ).EXE::      MPFILE.OBJ MPFIND.OBJ MPINIT.OBJ MPPRINT.OBJ MULTIPAD.OBJ $(OBJS_EXT) $(DEFFILE)
      echo >NUL @<<$(PROJ).CRF
MPFILE.OBJ +
MPFIND.OBJ +
MPINIT.OBJ +
MPPRINT.OBJ +
MULTIPAD.OBJ +
$(OBJS_EXT)
$(PROJ).EXE
$(MAPFILE)
$(LIBS)
$(DEFFILE);
<<
      link $(LFLAGS) @$(PROJ).CRF
      $(RC) $(RESFLAGS) MULTIPAD.RES $@
      @copy $(PROJ).CRF MSVC.BND

$(PROJ).EXE::      MULTIPAD.RES
      if not exist MSVC.BND       $(RC) $(RESFLAGS) MULTIPAD.RES $@

run: $(PROJ).EXE
      $(PROJ) $(RUNFLAGS)


$(PROJ).BSC: $(SBRS)
      bscmake @<<
/o$@ $(SBRS)
<<

0
 
LVL 4

Expert Comment

by:emmons
Comment Utility
// resource.h
//
//{{NO_DEPENDENCIES}}
// App Studio generated include file.
// Used by MULTIPAD.RC
//
#define IDS_CANTOPEN                    1
#define IDS_CANTREAD                    2
#define IDS_CANTCREATE                  3
#define IDS_CANTWRITE                   4
#define IDS_ILLFNM                      5
#define IDS_ADDEXT                      6
#define IDS_CLOSESAVE                   7
#define IDS_CANTFIND                    8
#define IDS_HELPNOTAVAIL                9
#define IDS_CLIENTTITLE                 16
#define IDS_UNTITLED                    17
#define IDS_APPNAME                     18
#define IDS_PRINTJOB                    24
#define IDS_PRINTERROR                  25
#define _APS_NEXT_COMMAND_VALUE         101
#define _APS_NEXT_SYMED_VALUE           101
#define _APS_NEXT_RESOURCE_VALUE        102
#define IDD_FILENAME                    201
#define IDD_FILES                       202
#define IDD_PATH                        203
#define IDD_DIRS                        204
#define IDD_SEARCH                      401
#define IDD_PREV                        402
#define IDD_CASE                        403
#define IDD_SAVEFROM                    501
#define IDD_SAVETO                      502
#define IDD_PRINTDEVICE                 601
#define IDD_PRINTPORT                   602
#define IDD_PRINTTITLE                  603
#define IDD_FACES                       701
#define IDD_SIZES                       702
#define IDD_BOLD                        703
#define IDD_ITALIC                      704
#define IDD_FONTTITLE                   705
#define _APS_NEXT_CONTROL_VALUE         1000
#define IDM_FILENEW                     1001
#define IDM_FILEOPEN                    1002
#define IDM_FILESAVE                    1003
#define IDM_FILESAVEAS                  1004
#define IDM_FILEPRINT                   1005
#define IDM_FILEEXIT                    1006
#define IDM_FILEABOUT                   1007
#define IDM_FILESETUP                   1008
#define IDM_FILEMENU                    1009
#define IDM_EDITUNDO                    2001
#define IDM_EDITCUT                     2002
#define IDM_EDITCOPY                    2003
#define IDM_EDITPASTE                   2004
#define IDM_EDITCLEAR                   2005
#define IDM_EDITSELECT                  2006
#define IDM_EDITTIME                    2007
#define IDM_EDITWRAP                    2008
#define IDM_EDITFONT                    2009
#define IDM_SEARCHFIND                  3001
#define IDM_SEARCHNEXT                  3002
#define IDM_SEARCHPREV                  3003
#define IDM_WINDOWTILE                  4001
#define IDM_WINDOWCASCADE               4002
#define IDM_WINDOWCLOSEALL              4003
#define IDM_WINDOWICONS                 4004
#define IDM_WINDOWCHILD                 4100
#define IDM_HELPHELP                    5001
#define IDM_HELPABOUT                   5002
#define IDM_HELPSPOT                    5003

0
 
LVL 4

Expert Comment

by:emmons
Comment Utility
// multipad.rc
//
//Microsoft App Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////
//
// From TEXTINCLUDE 2
//
#include "multipad.h"

/////////////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS


//////////////////////////////////////////////////////////////////////////////
//
// Icon
//

IDMULTIPAD              ICON    DISCARDABLE     "mp300.ico"
IDNOTE                  ICON    DISCARDABLE     "note300.ico"

//////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDMULTIPAD MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New",                        IDM_FILENEW
        MENUITEM "&Open...",                    IDM_FILEOPEN
        MENUITEM "&Save",                       IDM_FILESAVE
        MENUITEM "Save &As...",                 IDM_FILESAVEAS
        MENUITEM SEPARATOR
        MENUITEM "&Print",                      IDM_FILEPRINT
        MENUITEM "Printer Se&tup...",           IDM_FILESETUP
        MENUITEM SEPARATOR
        MENUITEM "S&hort Menus",                IDM_FILEMENU
        MENUITEM SEPARATOR
        MENUITEM "E&xit",                       IDM_FILEEXIT
        MENUITEM SEPARATOR
        MENUITEM "&About Multipad...",          IDM_HELPABOUT
    END
    POPUP "&Edit"
    BEGIN
        MENUITEM "&Undo\tAlt+BkSp",             IDM_EDITUNDO
        MENUITEM SEPARATOR
        MENUITEM "Cu&t\tShift+Del",             IDM_EDITCUT
        MENUITEM "&Copy\tCtrl+Ins",             IDM_EDITCOPY
        MENUITEM "&Paste\tShift+Ins",           IDM_EDITPASTE
        MENUITEM "&Delete\tDel",                IDM_EDITCLEAR
        MENUITEM SEPARATOR
        MENUITEM "&Select All",                 IDM_EDITSELECT
        MENUITEM "&Word Wrap",                  IDM_EDITWRAP
    END
    POPUP "&Search"
    BEGIN
        MENUITEM "&Find...",                    IDM_SEARCHFIND
        MENUITEM "&Next\tF3",                   IDM_SEARCHNEXT
        MENUITEM "&Previous\tF4",               IDM_SEARCHPREV
    END
    POPUP "&Window"
    BEGIN
        MENUITEM "&Tile",                       IDM_WINDOWTILE
        MENUITEM "&Cascade",                    IDM_WINDOWCASCADE
        MENUITEM "Arrange &Icons",              IDM_WINDOWICONS
        MENUITEM "Close &All",                  IDM_WINDOWCLOSEALL
    END
END

IDMULTIPAD2 MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New",                        IDM_FILENEW
        MENUITEM "&Open...",                    IDM_FILEOPEN
        MENUITEM "&Save",                       IDM_FILESAVE
        MENUITEM "Save &as...",                 IDM_FILESAVEAS
        MENUITEM SEPARATOR
        MENUITEM "&Print...",                   IDM_FILEPRINT
        MENUITEM SEPARATOR
        MENUITEM "&Full Menus",                 IDM_FILEMENU
        MENUITEM SEPARATOR
        MENUITEM "E&xit",                       IDM_FILEEXIT
        MENUITEM SEPARATOR
        MENUITEM "&About Multipad...",          IDM_HELPABOUT
    END
    POPUP "&Edit"
    BEGIN
        MENUITEM "&Undo\tAlt+BkSp",             IDM_EDITUNDO
        MENUITEM SEPARATOR
        MENUITEM "&Cut\tShift+Del",             IDM_EDITCUT
        MENUITEM "Co&py\tCtrl+Ins",             IDM_EDITCOPY
        MENUITEM "&Paste\tShift+Ins",           IDM_EDITPASTE
        MENUITEM "&Delete\tDel",                IDM_EDITCLEAR
    END
    POPUP "&Window"
    BEGIN
        MENUITEM "&Arrange",                    IDM_WINDOWTILE
    END
END


//////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDMULTIPAD ACCELERATORS MOVEABLE PURE
BEGIN
    VK_INSERT,      IDM_EDITCOPY,           VIRTKEY,CONTROL
    VK_INSERT,      IDM_EDITPASTE,          VIRTKEY,SHIFT
    VK_DELETE,      IDM_EDITCUT,            VIRTKEY,SHIFT
    VK_BACK,        IDM_EDITUNDO,           VIRTKEY,ALT
    VK_F5,          IDM_EDITTIME,           VIRTKEY
    VK_F3,          IDM_SEARCHNEXT,         VIRTKEY
    VK_F4,          IDM_SEARCHPREV,         VIRTKEY
    VK_F1,          IDM_HELPHELP,           VIRTKEY
    VK_F1,          IDM_HELPSPOT,           VIRTKEY,SHIFT
END


//////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUT DIALOG DISCARDABLE  25, 23, 184, 78
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Multipad"
FONT 8, "Helv"
BEGIN
    CTEXT           "Microsoft Windows",-1,0,5,184,8
    CTEXT           "Multipad",-1,0,15,184,8
    CTEXT           "Version 3.10",-1,0,34,184,8
    CTEXT           "Copyright \251 1990-91 Microsoft Corp.",-1,0,47,184,9
    DEFPUSHBUTTON   "OK",IDOK,76,60,32,14,WS_GROUP
    ICON            IDMULTIPAD,-1,25,14,18,20
END

IDD_FIND DIALOG DISCARDABLE  18, 13, 167, 69
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Find"
FONT 8, "Helv"
BEGIN
    RTEXT           "&Find:",100,6,12,31,10,NOT WS_GROUP
    EDITTEXT        IDD_SEARCH,43,11,114,12
    CHECKBOX        "&Case Sensitive",IDD_CASE,19,28,137,12
    DEFPUSHBUTTON   "&Next",IDOK,11,48,45,14
    PUSHBUTTON      "&Previous",IDD_PREV,63,48,45,14
    PUSHBUTTON      "C&ancel",IDCANCEL,116,48,43,14
END

IDD_PRINT DIALOG DISCARDABLE  56, 61, 128, 66
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Print"
FONT 8, "Helv"
BEGIN
    RTEXT           "Printing...",100,2,6,44,8,NOT WS_GROUP
    DEFPUSHBUTTON   "Cancel",IDOK,75,46,47,14
END

#ifdef APSTUDIO_INVOKED
//////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
    "#include ""multipad.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
    "\r\n"
    "\0"
END

/////////////////////////////////////////////////////////////////////////////////////
#endif    // APSTUDIO_INVOKED


//////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE DISCARDABLE
BEGIN
    IDS_CANTOPEN            "Can't open the file '%s'"
    IDS_CANTREAD            "Can't read the file '%s'"
    IDS_CANTCREATE          "Can't create the file '%s'"
    IDS_CANTWRITE           "Can't write the file '%s'"
    IDS_ILLFNM              "Invalid filename: '%s'"
    IDS_ADDEXT              ".TXT"
    IDS_CLOSESAVE           "%s has been changed.  Save file before closing?"
    IDS_CANTFIND            "Can't find '%s'"
    IDS_HELPNOTAVAIL        "Can't load Windows Help application"
END

STRINGTABLE DISCARDABLE
BEGIN
    IDS_CLIENTTITLE         "MultiPad MDI Demonstration App, Version 0.01"
    IDS_UNTITLED            "Untitled"
    IDS_APPNAME             "Multipad"
    IDS_PRINTJOB            "Multipad - "
    IDS_PRINTERROR          "Cannot print %s!"
END

#ifndef APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////////////
//
// From TEXTINCLUDE 3
//


/////////////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

0
 

Author Comment

by:jvitale
Comment Utility
Edited text of question
0
 

Author Comment

by:jvitale
Comment Utility
Thanks allot.. I would also really appreciate the 32 bit sample of the MDI client. Just zip it and send it to jvitale@idsonline.com   Again.. thanks.. you guys are the first group of intelligient C programmers I have met in a long while :)
Great Job!!!!
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now