home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / os2 / queues / svrqmain.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  15KB  |  498 lines

  1. /*==============================================================*\
  2.  *  Svrqmain.c - Queue Server sample app
  3.  *      Copyright 1996 IBM Corp.
  4.  *--------------------------------------------------------------
  5.  *
  6.  *  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  7.  *  sample code created by IBM Corporation. This sample code is not
  8.  *  part of any standard or IBM product and is provided to you solely
  9.  *  for  the purpose of assisting you in the development of your
  10.  *  applications.  The code is provided "AS IS", without
  11.  *  warranty of any kind.  IBM shall not be liable for any damages
  12.  *  arising out of your use of the sample code, even if they have been
  13.  *  advised of the possibility of such damages.
  14.  *
  15.  *--------------------------------------------------------------
  16.  *
  17.  *  This C file contains the window creation routines and
  18.  *  manages the PM message queue.
  19.  *
  20. \*==============================================================*/
  21.  
  22.  
  23.  
  24. /*--------------------------------------------------------------*\
  25.  *  Include files, macros, defined constants, and externs
  26. \*--------------------------------------------------------------*/
  27. #define INCL_WINHELP
  28. #define INCL_WININPUT
  29. #define INCL_DOSPROCESS
  30. #define INCL_DOSQUEUES
  31. #define INCL_WINMESSAGEMGR
  32. #define INCL_WINWINDOWMGR
  33. #define INCL_WINMENUS
  34. #define INCL_WINFRAMEMGR
  35.  
  36. #include <os2.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include "svrqmain.h"
  41. #include "svrqhelp.h"
  42. #include "svrqxtrn.h"
  43.  
  44. #define  THRD_EXIT_TIMEOUT  10
  45.  
  46. /*--------------------------------------------------------------*\
  47.  *  Global variables
  48. \*--------------------------------------------------------------*/
  49.  
  50. HWND   hwndMainFrame = NULLHANDLE;    /* handle to the main frame window */
  51. HWND   hwndMain;                      /* handle to the main client window */
  52. HAB    hab;                           /* anchor block for the process */
  53. HMQ    hmq;                           /* handle to the process' message queue */
  54. CHAR   szAppName[MAXNAMEL];           /* buffer for application name string */
  55. BOOL   fHelpEnabled;                  /* flag to determine if help is enabled */
  56. HQUEUE hqQ;
  57. SHORT  sTotalMsgs;
  58. CHAR   SvrQMsgs[MAX_MESSAGES][MESSAGE_LEN + 38];
  59. BOOL   fThrdsDead = FALSE;            /* notification of thread exitting */
  60.  
  61. unsigned int  iIndex = 0;             /* beginning of circular buffer */
  62.  
  63.  
  64. /****************************************************************\
  65.  *  Main routine
  66.  *--------------------------------------------------------------
  67.  *
  68.  *  Name:   main()
  69.  *
  70.  *  Purpose: Initializes the PM environment, calls the
  71.  *              initialization routine, creates the main
  72.  *              window,  and polls the message queue
  73.  *
  74.  *  Usage:
  75.  *
  76.  *  Method:
  77.  *          - obtains anchor block handle and creates message
  78.  *              queue
  79.  *          - calls the initialization routine
  80.  *          - creates the main frame window which creates the
  81.  *              main client window
  82.  *          - polls the message queue via Get/Dispatch Msg loop
  83.  *          - upon exiting the loop, exits
  84.  *
  85.  *  Returns:
  86.  *          0 - if successful execution completed
  87.  *          1 - if error
  88. \****************************************************************/
  89. INT main(int argc, char *argv[])
  90. {
  91.    QMSG        qmsg;          /* message structure */
  92.    static int  iTimeOut = THRD_EXIT_TIMEOUT;
  93.  
  94.    hab = WinInitialize(0UL);
  95.  
  96.    if(!hab)
  97.    {
  98.       DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
  99.       return RETURN_ERROR;
  100.    }
  101.  
  102.    hmq = WinCreateMsgQueue(hab, 0L);
  103.  
  104.    if(!hmq)
  105.    {
  106.       DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
  107.       WinTerminate(hab);
  108.       return RETURN_ERROR;
  109.    }
  110.  
  111.    if(!Init(argc, argv))
  112.    {
  113.       if(hwndMainFrame == NULLHANDLE)
  114.       {
  115.           MessageBox(HWND_DESKTOP,
  116.                      IDMSG_MAINWINCREATEFAILED,
  117.                      MB_OK | MB_ERROR,
  118.                      TRUE);
  119.       }
  120.  
  121.       else
  122.       {
  123.          MessageBox(HWND_DESKTOP,
  124.                     IDMSG_INITFAILED,
  125.                     MB_OK | MB_ERROR,
  126.                     TRUE);
  127.  
  128.       }
  129.  
  130.       DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
  131.       if (WinIsWindow(hab, hwndMainFrame))
  132.       {
  133.          WinDestroyWindow(hwndMainFrame);
  134.       }
  135.       WinDestroyMsgQueue(hmq);
  136.       WinTerminate(hab);
  137.       return RETURN_ERROR;
  138.    }
  139.  
  140.    /* Get-Dispatch Message loop */
  141.    while(WinGetMsg(hab, &qmsg, NULLHANDLE, 0UL, 0UL))
  142.       WinDispatchMsg(hab, &qmsg);
  143.  
  144.  
  145.    /* destroy the help instance */
  146.    DestroyHelpInstance();
  147.  
  148.    if (WinIsWindow(hab, hwndMainFrame))
  149.       WinDestroyWindow(hwndMainFrame);
  150.    WinDestroyMsgQueue(hmq);
  151.  
  152.    /* give other thread a chance to exit */
  153.    while (!fThrdsDead && iTimeOut--)
  154.    {
  155.       DosSleep(0UL);
  156.    }
  157.  
  158.    WinTerminate(hab);
  159.    return RETURN_SUCCESS;
  160.  
  161. }   /* main() */
  162.  
  163.  
  164. /****************************************************************\
  165.  *  Main client window procedure
  166.  *--------------------------------------------------------------
  167.  *
  168.  *  Name:   MainWndProc(hwnd, msg, mp1, mp2)
  169.  *
  170.  *  Purpose: Processes the messages sent to the main client
  171.  *              window.  This routine processes the basic
  172.  *              messages all client windows should process
  173.  *              and passes all others onto WinDefWindowProc.
  174.  *
  175.  *  Usage:  Called for each message placed in the main
  176.  *          window's message queue
  177.  *
  178.  *  Method: a switch statement branches to the routines to be
  179.  *          performed for each message processed.
  180.  *
  181.  *  Returns:  Return values are determined by each message
  182.  *
  183. \****************************************************************/
  184. MRESULT EXPENTRY MainWndProc(HWND   hwnd,    /* handle of window */
  185.                              ULONG  msg,     /* id of message */
  186.                              MPARAM mp1,     /* first message parameter */
  187.                              MPARAM mp2)     /* second message parameter */
  188. {
  189.    QDATA   *pqdataQ;
  190.  
  191.    switch(msg)
  192.    {
  193.       case WM_CREATE:
  194.          return InitMainWindow(hwnd, mp1, mp2);
  195.          break;
  196.  
  197.       case WM_PAINT:
  198.          MainPaint(hwnd, SvrQMsgs, iIndex, sTotalMsgs);
  199.          break;
  200.  
  201.       case WM_SIZE:
  202.          MainSize(hwnd, sTotalMsgs, mp1, mp2);
  203.          break;
  204.  
  205.       case WM_HSCROLL:
  206.          MainHorizScroll(hwnd, mp2);
  207.          break;
  208.  
  209.       case WM_VSCROLL:
  210.          MainVertScroll(hwnd, mp2);
  211.          break;
  212.  
  213.       case WM_CHAR:
  214.          switch (SHORT2FROMMP(mp2))
  215.          {
  216.             case VK_LEFT:
  217.             case VK_RIGHT:
  218.                return MainCharHScroll (hwnd, msg, mp1, mp2) ;
  219.             case VK_UP:
  220.             case VK_DOWN:
  221.             case VK_PAGEUP:
  222.             case VK_PAGEDOWN:
  223.                return MainCharVScroll (hwnd, msg, mp1, mp2) ;
  224.          }
  225.          break ;
  226.  
  227.       case WM_COMMAND:
  228.          MainCommand(mp1, mp2);
  229.          break;
  230.  
  231.       case HM_QUERY_KEYS_HELP:
  232.          return (MRESULT)PANEL_HELPKEYS;   /* return id of key help panel */
  233.          break ;
  234.  
  235.       case WM_NEWQMSG:
  236.          /* copy message into circular array, with index being next free spot in array */
  237.          pqdataQ = (QDATA *)PVOIDFROMMP(mp1);
  238.          sprintf(SvrQMsgs[iIndex],
  239.                  "Process ID: %03lu, Priority: %02hu,  Message: %s",
  240.                  pqdataQ->pidProcess,
  241.                  pqdataQ->usPriority,
  242.                  pqdataQ->pszMsg);
  243.  
  244.          /* increment index, or reset to 0 as appropriate */
  245.          iIndex = (iIndex < MAX_MESSAGES - 1) ? iIndex + 1 : 0;
  246.  
  247.          /* increment total message count until buffer is filled */
  248.          sTotalMsgs = min(MAX_MESSAGES, sTotalMsgs + 1);
  249.  
  250.          MainUpdateMsg(hwnd, SvrQMsgs, iIndex, sTotalMsgs);
  251.          break;
  252.  
  253.       case WM_MSG:
  254.          MessageBox(hwndMain, (ULONG)SHORT1FROMMP(mp1), MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL, TRUE);
  255.          break;
  256.  
  257.       case WM_CLOSE:
  258.          DosWriteQueue(hqQ, WM_CLOSE, 0UL, NULL, 15UL);
  259.  
  260.          /* process the WM_CLOSE */
  261.  
  262.    /*--------------------------------------------------*\
  263.     *      Any messages not processed are passed on
  264.     *      to WinDefWindowProc.
  265.    \*--------------------------------------------------*/
  266.  
  267.       default:
  268.          return WinDefWindowProc(hwnd, msg, mp1, mp2);
  269.          break;
  270.    }
  271.  
  272.    return MRFROMLONG(0L);     /* all window procedures should return 0 as a default */
  273.  
  274. }   /* MainWndProc() */
  275.  
  276.  
  277. /****************************************************************\
  278.  *  Message Box procedure
  279.  *--------------------------------------------------------------
  280.  *
  281.  *  Name:   MessageBox(hwndOwner, nIdMsg, fsStyle, fBeep)
  282.  *
  283.  *  Purpose: Displays the message box with the message
  284.  *              given in idMsg retrieved from the message table
  285.  *              and using the style flags in fsStyle
  286.  *
  287.  *  Usage:  Called whenever a MessageBox is to be displayed
  288.  *
  289.  *  Method: - Message string is loaded from the process'
  290.  *              message table
  291.  *          - Alarm beep is sounded if desired
  292.  *          - Message box with the message is displayed
  293.  *          - WinMessageBox return value is returned
  294.  *
  295.  *  Returns: return value from WinMessageBox()
  296.  *
  297. \****************************************************************/
  298. ULONG MessageBox(HWND hwndOwner,  /* handle of the message box's owner */
  299.                  ULONG idMsg,     /* id if the message in the message table */
  300.                  ULONG fsStyle,   /* style of the message box */
  301.                  BOOL fBeep)      /* if TRUE, beep before message box is displayed */
  302. {
  303.    CHAR szText[TITLE_LEN];
  304.  
  305.    if(!WinLoadMessage(hab,
  306.                      NULLHANDLE,
  307.                      idMsg,
  308.                      TITLE_LEN,
  309.                      (PSZ)szText))
  310.    {
  311.       WinAlarm(HWND_DESKTOP, WA_ERROR);
  312.       return MBID_ERROR;
  313.    }
  314.  
  315.    if(fBeep)  
  316.    {
  317.       WinAlarm(HWND_DESKTOP, WA_ERROR);
  318.    }
  319.  
  320.    return WinMessageBox(HWND_DESKTOP,
  321.                         hwndOwner,
  322.                         (PSZ)szText,
  323.                         (PSZ)NULL,
  324.                         MSGBOXID,
  325.                         fsStyle);
  326.  
  327. }   /* MessageBox() */
  328.  
  329.  
  330. /****************************************************************\
  331.  *  Main window WM_COMMAND processing procedure
  332.  *--------------------------------------------------------------
  333.  *
  334.  *  Name:   MainCommand(mp1, mp2)
  335.  *
  336.  *  Purpose: Calls the appropriate procedures that deal with
  337.  *              the selected menu item.
  338.  *
  339.  *  Usage:  Routine is called whenever a WM_COMMAND message
  340.  *          is posted to the main window.
  341.  *
  342.  *  Method: a switch statement branches on the id of the
  343.  *          menu item that posted the message and the
  344.  *          appropriate action for that item is taken.
  345.  *
  346.  *  Returns:
  347.  *
  348. \****************************************************************/
  349. VOID MainCommand(MPARAM mp1, MPARAM mp2)
  350. {
  351.  
  352.    switch(SHORT1FROMMP(mp1))
  353.    {
  354.       case IDM_FILEEXIT:
  355.          FileExit();
  356.          break;
  357.  
  358.       case IDM_OPTIONPURGE:
  359.          iIndex = sTotalMsgs = 0;
  360.  
  361.          /* get memory thread, write priority 15 message to tell thread to purge Q */
  362.          DosWriteQueue(hqQ, IDM_OPTIONPURGE, 0UL, NULL, 15UL);
  363.          MainPurgeWindow();
  364.          break;
  365.  
  366.       case IDM_HELPHELPFORHELP:
  367.          HelpHelpForHelp(mp2);
  368.          break;
  369.  
  370.       case IDM_HELPEXTENDED:
  371.          HelpExtended(mp2);
  372.          break;
  373.  
  374.       case IDM_HELPKEYS:
  375.          HelpKeys(mp2);
  376.          break;
  377.  
  378.       case IDM_HELPINDEX:
  379.          HelpIndex(mp2);
  380.          break;
  381.  
  382.       case IDM_HELPTUTORIAL:
  383.          HelpTutorial(mp2);
  384.          break;
  385.  
  386.       case IDM_HELPABOUT:
  387.          HelpAbout(mp2);
  388.          break;
  389.  
  390.       default:
  391.          break;
  392.     }
  393.  
  394. }   /* MainCommand() */
  395.  
  396.  
  397. /****************************************************************\
  398.  *  Initialization routine
  399.  *--------------------------------------------------------------
  400.  *
  401.  *  Name:   Init()
  402.  *
  403.  *  Purpose: Performs initialization functions.
  404.  *
  405.  *  Usage:  Called once before the message queue is queried.
  406.  *
  407.  *  Method:
  408.  *          - starts processing thread
  409.  *          - registers all window classes
  410.  *
  411.  *  Returns:
  412.  *          TRUE  - initialization is successful
  413.  *          FALSE - initialization failed
  414. \****************************************************************/
  415. BOOL Init(int argc, char *argv[])
  416. {
  417.    PTIB   ptibDummy;
  418.    PIB    *ppibProcess;
  419.    ULONG  flCtlData;    /* frame control data */
  420.  
  421.  
  422.    /* load application name from resource file */
  423.    if(!WinLoadString(hab, NULLHANDLE, IDS_APPNAME, MAXNAMEL, (PSZ)szAppName))
  424.       return FALSE;
  425.  
  426.    /* register the main client window class */
  427.    if(!WinRegisterClass(hab,
  428.                         (PSZ)szAppName,
  429.                         MainWndProc,
  430.                         CS_SIZEREDRAW | CS_CLIPCHILDREN,
  431.                         0UL))
  432.    {
  433.       return FALSE;
  434.    }
  435.  
  436.    flCtlData = FCF_STANDARD | FCF_VERTSCROLL | FCF_HORZSCROLL;
  437.  
  438.    hwndMainFrame = WinCreateStdWindow(HWND_DESKTOP,
  439.                                       WS_VISIBLE,
  440.                                       &flCtlData,
  441.                                       (PSZ)szAppName,
  442.                                       (PSZ)NULL,
  443.                                       WS_VISIBLE,
  444.                                       NULLHANDLE,
  445.                                       IDR_MAIN,
  446.                                       &hwndMain);
  447.    if (NULLHANDLE == hwndMainFrame)
  448.       return FALSE;
  449.  
  450.    WinSetWindowText(hwndMainFrame, (PSZ)szAppName);
  451.  
  452.    if (DosGetInfoBlocks(&ptibDummy, &ppibProcess) ||
  453.        !(hqQ = InitQ((*ppibProcess).pib_ulpid,  /* process that will send WM_CLOSE command */
  454.                      hwndMainFrame)))           /* window to post to */
  455.       return FALSE;
  456.  
  457.    if (argc > 1)
  458.    {
  459.       RESULTCODES  resc;
  460.       CHAR  pszBuff[CCHMAXPATH];
  461.  
  462.       if ((BOOL)DosExecPgm((PSZ)pszBuff, CCHMAXPATH, EXEC_ASYNC, NULL, NULL, &resc, argv[1]))
  463.       {
  464.          MessageBox(hwndMain, IDMSG_CANNOT_EXEC_CLIENT, MB_CUAWARNING | MB_OK, TRUE);
  465.       }
  466.    }
  467.  
  468.    InitHelp();
  469.  
  470.    return TRUE;
  471. }  /* Init() */
  472.  
  473.  
  474. /****************************************************************\
  475.  *  Exit routine
  476.  *--------------------------------------------------------------
  477.  *
  478.  *  Name:   FileExit(mp2)
  479.  *
  480.  *  Purpose: Processes the File menu's Exit item.
  481.  *
  482.  *  Usage:  called whenever Exit from the file menu is
  483.  *          selected
  484.  *
  485.  *  Method:  Routine posts a WM_CLOSE message to the main
  486.  *           application window.
  487.  *
  488.  *  Returns:
  489.  *
  490. \****************************************************************/
  491. VOID FileExit()
  492. {
  493.  
  494.    WinPostMsg(hwndMain, WM_CLOSE, MPVOID, MPVOID);
  495.  
  496. }   /* FileExit() */
  497.  
  498.