home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / MSJV5-6.ZIP / WINTRO3.ZIP / STOCK.C < prev    next >
C/C++ Source or Header  |  1990-11-01  |  15KB  |  524 lines

  1. /*
  2.   Microsoft Systems Journal Stock Application
  3.   Written by Marc Adler
  4.              Magma Systems
  5.              15 Bodwell Terrace
  6.              Millburn, New Jersey  07041
  7.  
  8.   This is for the third article. It is the basic skeleton of our
  9.   application. We add MDI capabilities to the code.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "windows.h"
  15. #include "stock.h"
  16.  
  17.  
  18. HANDLE hThisInstance;         /* Program instance handle */
  19. HWND hWndMain      = NULL;    /* Handle to main window   */
  20. HWND hwndMDIClient = NULL;    /* Handle to MDI client    */
  21. HWND hWndActive    = NULL;    /* Handle of the active MDI child */
  22. HWND hWndStatus    = NULL;    /* Window for status mesages */
  23.  
  24. HANDLE hAccelTable;           /* The accelerator table for this app */
  25.  
  26.  
  27. int NEAR PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  28.   HANDLE hInstance;
  29.   HANDLE hPrevInstance;
  30.   LPSTR  lpszCmdLine;
  31.   int    nCmdShow;
  32. {
  33.   MSG msg;
  34.  
  35.   /*
  36.     Save the handle to this inctance.
  37.   */
  38.   hThisInstance = hInstance;
  39.  
  40.   /* 
  41.     If this is the first instance of the app, register window classes...
  42.   */
  43.   if (!hPrevInstance)
  44.   {
  45.     if (!InitializeApplication())
  46.     {
  47.       MessageBeep(0);
  48.       return FALSE;
  49.     }
  50.   }
  51.  
  52.   /* 
  53.     Perform the initialization for this particular instance...
  54.   */
  55.   if (!InitializeInstance(lpszCmdLine, nCmdShow))
  56.   {
  57.     return FALSE;
  58.   }
  59.  
  60.  
  61.   /*
  62.     The main message loop...
  63.   */
  64.   while (GetMessage(&msg, (HWND) NULL, 0, 0))
  65.   {
  66.   /* If a keyboard message is for the MDI , let the MDI client
  67.    * take care of it.  Otherwise, check to see if it's a normal
  68.    * accelerator key (like F3 = find next).  Otherwise, just handle
  69.    * the message as usual.
  70.    */
  71.     if (!TranslateMDISysAccel(hwndMDIClient, &msg) && 
  72.         !TranslateAccelerator(hWndMain, hAccelTable, &msg))
  73.     {
  74.       TranslateMessage(&msg);
  75.       DispatchMessage(&msg);
  76.     }
  77.   }
  78.  
  79.   return 0;
  80. }
  81.  
  82.  
  83.  
  84. BOOL FAR PASCAL InitializeApplication(VOID)
  85. {
  86.   WNDCLASS wc;
  87.  
  88.   /*
  89.     Register the main window class
  90.   */
  91.   wc.style         = CS_VREDRAW | CS_HREDRAW;
  92.   wc.lpfnWndProc   = MainWndProc;
  93.   wc.cbClsExtra    = 0;
  94.   wc.cbWndExtra    = 0;
  95.   wc.hInstance     = hThisInstance;
  96.   wc.hIcon         = LoadIcon(hThisInstance, MAKEINTRESOURCE(ID_STOCK));
  97.   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  98.   wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  99.   wc.lpszMenuName  = "StockMenu";
  100.   wc.lpszClassName = "StockMainWindow";
  101.   if (!RegisterClass(&wc))
  102.   {
  103.     return FALSE;
  104.   }
  105.  
  106.   /* Register the MDI child class */
  107.   wc.lpfnWndProc   = GraphWndProc;
  108.   wc.hIcon         = LoadIcon(hThisInstance, MAKEINTRESOURCE(ID_GRAPH));
  109.   wc.lpszMenuName  = NULL;
  110.   wc.cbWndExtra    = CBWNDEXTRA;
  111.   wc.lpszClassName = "GraphWindow";
  112.   if (!RegisterClass(&wc))
  113.   {
  114.     return FALSE;
  115.   }
  116.  
  117.   wc.style         = CS_VREDRAW | CS_HREDRAW;
  118.   wc.lpfnWndProc   = StatusWndProc;
  119.   wc.cbClsExtra    = 0;
  120.   wc.cbWndExtra    = 0;
  121.   wc.hInstance     = hThisInstance;
  122.   wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  123.   wc.lpszMenuName  = NULL;
  124.   wc.lpszClassName = "StockStatus";
  125.   if (!RegisterClass(&wc))
  126.     return FALSE;
  127.  
  128.   return TRUE;
  129. }
  130.  
  131.  
  132.  
  133. BOOL FAR PASCAL InitializeInstance(LPSTR lpCmdLine, WORD nCmdShow)
  134. {
  135.   /* 
  136.     Create the frame
  137.   */
  138.   hWndMain = CreateWindow("StockMainWindow",
  139.                           "MSJ Stock Application",
  140.                           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  141.                           CW_USEDEFAULT, 0,
  142.                           CW_USEDEFAULT, 0,
  143.                           (HWND) NULL,
  144.                           (HMENU) NULL,
  145.                           hThisInstance,
  146.                           (LPSTR) NULL);
  147.  
  148.   if (!hWndMain)
  149.   {
  150.     return FALSE;
  151.   }
  152.  
  153.   /* MDI client should have been created in response to WM_CREATE funtion for
  154.    * frame window.
  155.    */
  156.   if (!hwndMDIClient)
  157.     return FALSE;
  158.  
  159.   /*
  160.     Load the accelerators in
  161.   */
  162.   hAccelTable = LoadAccelerators(hThisInstance, (LPSTR) "StockAccelerators");
  163.  
  164.   /* 
  165.     Display the main window
  166.   */
  167.   ShowWindow(hWndMain, nCmdShow);
  168.   UpdateWindow(hWndMain);
  169.  
  170.   return TRUE;
  171. }
  172.  
  173.  
  174. LONG FAR PASCAL MainWndProc(hWnd, msg, wParam, lParam)
  175.   HWND hWnd;
  176.   WORD msg;
  177.   WORD wParam;
  178.   LONG lParam;
  179. {
  180.   BOOL        rc;
  181.   HDC         hDC;
  182.   PAINTSTRUCT ps;
  183.   FARPROC     lpfn;
  184.   LPSTOCKINFO lpStockInfo;
  185.  
  186.   char        szMsg[80];
  187.   RECT        rClient;
  188.   int         i;
  189.  
  190.   static HWND ahwndSubMenus[16];
  191.  
  192.  
  193.   switch (msg)
  194.   {
  195.     case WM_CREATE:
  196.     {
  197.       CLIENTCREATESTRUCT ccs;
  198.  
  199.       /* Find window menu where children will be listed */
  200.       ccs.hWindowMenu  = GetSubMenu(GetMenu(hWnd), 3);
  201.       ccs.idFirstChild = ID_WINDOW_CHILDREN;
  202.  
  203.       /* Create the MDI client filling the client area */
  204.       hwndMDIClient = CreateWindow("mdiclient",
  205.                                     NULL,
  206.                                     WS_CHILD   | WS_CLIPCHILDREN | 
  207.                                     WS_VSCROLL | WS_HSCROLL,
  208.                                     0,0,0,0,
  209.                                     hWnd,
  210.                                     0xCAC,
  211.                                     hThisInstance,
  212.                                     (LPSTR) &ccs);
  213.       ShowWindow(hwndMDIClient, SW_SHOW);
  214.  
  215.       /*
  216.         Create a status window at the bottom of the main window.
  217.       */
  218.       GetClientRect(hWnd, (LPRECT) &rClient);
  219.       hWndStatus = CreateWindow("StockStatus",
  220.                                  NULL,
  221.                                  WS_CHILD | WS_BORDER,
  222.                                  rClient.left, rClient.bottom - Y_STATUSWINDOW,
  223.                                  rClient.right - rClient.left, Y_STATUSWINDOW,
  224.                                  hWnd,
  225.                                  NULL, 
  226.                                  hThisInstance,
  227.                                  (LPSTR) 0L);
  228.       if (hWndStatus)
  229.         ShowWindow(hWndStatus, SW_SHOW);
  230.  
  231.       /*
  232.         We gather up the window handles of all of the sub menus.
  233.       */
  234.       for (i = 0;  (ahwndSubMenus[i] = GetSubMenu(GetMenu(hWnd),i));  i++)
  235.         ;
  236.  
  237.  
  238.       break;
  239.     }
  240.  
  241.     case WM_COMMAND :
  242.       switch (wParam)
  243.       {
  244.         case ID_NEW   :
  245.           GraphCreateWindow(NULL);
  246.           break;
  247.         case ID_OPEN  :
  248.           break;
  249.         case ID_SAVE  :
  250.           break;
  251.         case ID_CLOSE :
  252.           break;
  253.         case ID_PRINT :
  254.           break;
  255.         case ID_EXIT  :
  256.           PostQuitMessage(0);
  257.           break;
  258.  
  259.         case ID_TICK_ADD :
  260.           break;
  261.         case ID_TICK_CHANGE:
  262.           break;
  263.  
  264.         case ID_GRAPH_OPTIONS   :
  265.           break;
  266.         case ID_GRAPH_PRICE     :
  267.           break;
  268.         case ID_GRAPH_VOLUME    :
  269.           break;
  270.         case ID_GRAPH_ZOOM      :
  271.           break;
  272.         case ID_GRAPH_COLORS    :
  273.           break;
  274.         case ID_GRAPH_GRID_HORZ :
  275.           break;
  276.         case ID_GRAPH_GRID_VERT :
  277.           break;
  278.  
  279.         case ID_WINDOW_TILE     :
  280.           SendMessage(hwndMDIClient, WM_MDITILE, 0, 0L);
  281.           break;
  282.         case ID_WINDOW_CASCADE  :
  283.           SendMessage(hwndMDIClient, WM_MDICASCADE, 0, 0L);
  284.           break;
  285.         case ID_WINDOW_ICONS    :
  286.           SendMessage(hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  287.           break;
  288.  
  289.         case ID_WINDOW_CLOSEALL :
  290.         {
  291.           HWND hwndT;
  292.           ShowWindow(hwndMDIClient, SW_HIDE);
  293.           while ((hwndT = GetWindow(hwndMDIClient, GW_CHILD)) != NULL)
  294.           {
  295.             /* Skip the icon title windows */
  296.             while (hwndT && GetWindow(hwndT, GW_OWNER))
  297.           hwndT = GetWindow(hwndT, GW_HWNDNEXT);
  298.             if (!hwndT)
  299.           break;
  300.             SendMessage(hwndMDIClient, WM_MDIDESTROY, (WORD) hwndT, 0L);
  301.           }
  302.           ShowWindow(hwndMDIClient, SW_SHOW);
  303.           ShowWindow(hWndStatus, SW_SHOW);
  304.           break;
  305.         }
  306.  
  307.         case ID_ABOUT :
  308.           break;
  309.  
  310.         default :
  311.           /*
  312.             We might have chosen to change the focus to one of the
  313.             MDI children.
  314.           */
  315.           return DefFrameProc(hWnd, hwndMDIClient, msg, wParam, lParam);
  316.       }
  317.       break;
  318.  
  319.  
  320.     case WM_MENUSELECT          :
  321.     {
  322.       WORD idMenu;
  323.       WORD iLen;
  324.  
  325.       /*
  326.         We trigger off of the WM_MENUSELECT message so that we
  327.         can print informative messages about each menu option.
  328.       */
  329.  
  330.       if (lParam & MF_POPUP)
  331.       {
  332.         /*
  333.           The handle of the popup menu is returned in wParam. Search
  334.           the array of sub-menu window handles in order to see which
  335.           submenu we are in.
  336.         */
  337.         for (idMenu = 0;
  338.              ahwndSubMenus[idMenu] && wParam != ahwndSubMenus[idMenu];
  339.              idMenu++)
  340.           ;
  341.         if (!ahwndSubMenus[idMenu])
  342.           break;
  343.         idMenu++;  /* make it a 1-offset value */
  344.       }
  345.       else
  346.         /*
  347.           An actual menu item identifier is returned in wparam...
  348.         */
  349.         idMenu = wParam;
  350.  
  351.       /*
  352.         If lParam was <-1,0>, then the user dismissed the menu, so
  353.         we just want to erase the previous help text from the
  354.         status window. If not, then idMenu contains a valid menu or
  355.         submenu identifier. Load the corresponding string from
  356.         the string table, and print it.
  357.       */
  358.       if (LOWORD(lParam) == -1 && HIWORD(lParam) == 0  ||
  359.          ((iLen = LoadString(hThisInstance, idMenu, (LPSTR) szMsg, sizeof(szMsg)))))
  360.       {
  361.         HDC hDC = GetDC(hWndStatus);
  362.         HBRUSH hBrush, hOldBrush;
  363.  
  364.         /*
  365.           Use a white brush for erasing.
  366.         */
  367.         hBrush = CreateSolidBrush(0x00FFFFFF);
  368.         hOldBrush = SelectObject(hDC, hBrush);
  369.  
  370.         /*
  371.           Erase the previous menu help text, if any. Then display the
  372.           new help text.
  373.         */
  374.         GetClientRect(hWndStatus, (LPRECT) &rClient);
  375.         FillRect(hDC, &rClient, hBrush);
  376.         if (LOWORD(lParam) == -1 && HIWORD(lParam) == 0)
  377.           ;
  378.         else
  379.           TextOut(hDC, 0, 0, szMsg, iLen);
  380.  
  381.         /*
  382.           Restore the old brush.
  383.         */
  384.         SelectObject(hDC, hOldBrush);
  385.         DeleteObject(hBrush);
  386.         ReleaseDC(hWndStatus, hDC);
  387.       }
  388.       break;
  389.     }
  390.  
  391.  
  392.     case WM_SIZE :
  393.       /*
  394.         When the main window is resized, we want to move and resize the
  395.         status window so that it is always lying on the bottom.
  396.       */
  397.       if (hWndStatus)
  398.       {
  399.         GetClientRect(hWnd, (LPRECT) &rClient);
  400.         MoveWindow(hWndStatus, 
  401.                    rClient.left, rClient.bottom - Y_STATUSWINDOW,
  402.                    rClient.right - rClient.left, Y_STATUSWINDOW,
  403.                    TRUE);
  404.       }
  405.       /*
  406.         We need to call DefFrameProc, because it processes the WM_SIZE
  407.         messages too!
  408.       */
  409.       goto call_DFP;
  410.  
  411.  
  412.     case WM_DESTROY :
  413.       PostQuitMessage(0);
  414.       break;
  415.  
  416.     default :
  417.     /*    use DefFrameProc() instead of DefWindowProc() since there
  418.      *    are things that have to be handled differently because of MDI
  419.      */
  420. call_DFP:
  421.       return DefFrameProc(hWnd, hwndMDIClient, msg, wParam, lParam);
  422.   }
  423.  
  424.   return (LONG) TRUE;
  425. }
  426.  
  427.  
  428. LONG FAR PASCAL StatusWndProc(hWnd, msg, wParam, lParam)
  429.   HWND hWnd;
  430.   WORD msg;
  431.   WORD wParam;
  432.   LONG lParam;
  433. {
  434.   return DefWindowProc(hWnd, msg, wParam, lParam);
  435. }
  436.  
  437.  
  438. /****************************************************************************/
  439. /*                                                                          */
  440. /* Function : GraphCreateWindow()                                           */
  441. /*                                                                          */
  442. /* Purpose  : Creates a new graph window (an MDI child) in response to      */
  443. /*            the File/New and File/Open commands.                          */
  444. /*                                                                          */
  445. /* Returns  : The handle of the newly created MDI child window.             */
  446. /*                                                                          */
  447. /****************************************************************************/
  448.  
  449. HWND PASCAL GraphCreateWindow(LPSTR lpName)
  450. {
  451.   HWND hWnd;
  452.   char sz[160];
  453.   MDICREATESTRUCT mcs;
  454.  
  455.   static int nChildren = 1;
  456.  
  457.  
  458.   if (!lpName)
  459.   {
  460.     /* If the lpName parameter is NULL, load the "Untitled" string
  461.     *  from STRINGTABLE and set the title field of the MDI CreateStruct.
  462.     */
  463.     sprintf(sz, "(Untitled - %d)", nChildren++);
  464.     mcs.szTitle = (LPSTR) sz;
  465.   }
  466.   else
  467.   {
  468.     /* Title the window with the supplied filename */
  469.     AnsiUpper(lpName);
  470.     mcs.szTitle = lpName;
  471.   }
  472.  
  473.   mcs.szClass = "GraphWindow";
  474.   mcs.hOwner  = hThisInstance;
  475.  
  476.   /* Use the default size for the window */
  477.   mcs.x = mcs.cx = CW_USEDEFAULT;
  478.   mcs.y = mcs.cy = CW_USEDEFAULT;
  479.  
  480.   /* Set the style DWORD of the window to default */
  481.   mcs.style = 0L;
  482.  
  483.   /* tell the MDI Client to create the child */
  484.   hWnd = (WORD) SendMessage(hwndMDIClient,
  485.                 WM_MDICREATE,
  486.                 0,
  487.                 (LONG) (LPMDICREATESTRUCT) &mcs);
  488.   return hWnd;
  489. }
  490.  
  491. /****************************************************************************/
  492. /*                                                                          */
  493. /* Function : GraphWndProc                                                  */
  494. /*                                                                          */
  495. /* Purpose  : Window procedure for the graph windows (MDI child)            */
  496. /*                                                                          */
  497. /* Returns  :                                                               */
  498. /*                                                                          */
  499. /****************************************************************************/
  500.  
  501. LONG FAR PASCAL GraphWndProc(hWnd, msg, wParam, lParam)
  502.   HWND hWnd;
  503.   WORD msg;
  504.   WORD wParam;
  505.   LONG lParam;
  506. {
  507.   switch (msg)
  508.   {
  509.     case WM_MDIACTIVATE:
  510.       /* If we're activating this child, remember it */
  511.       hWndActive = (wParam) ? hWnd : (HWND) NULL;
  512.       break;
  513.  
  514.     default:
  515.       /* Again, since the MDI default behaviour is a little different,
  516.        * call DefMDIChildProc instead of DefWindowProc()
  517.        */
  518.       return DefMDIChildProc(hWnd, msg, wParam, lParam);
  519.   }
  520.  
  521.   return (LONG) FALSE;
  522. }
  523.  
  524.