home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / TOOLKIT / PM / GRAPHICS / GRAPHIC.C < prev    next >
C/C++ Source or Header  |  1994-11-17  |  56KB  |  1,532 lines

  1. /************ GRAPHIC C Sample Program Source Code File (.C) *****************
  2.  *
  3.  * PROGRAM NAME: GRAPHIC
  4.  * -------------
  5.  *  Presentation Manager Non-Retained Graphics C Sample Program
  6.  *
  7.  * WHAT THIS PROGRAM DOES:
  8.  * -----------------------
  9.  *  This program displays a selected metafile.
  10.  *  The current contents of the client area can also be printed.
  11.  *  All drawing is performed by a lower-priority asynchronous
  12.  *  thread, thus allowing the program to monitor its message queue
  13.  *  at regular intervals. The program does not test every call for
  14.  *  an error return code.
  15.  *
  16.  * WHAT THIS PROGRAM DEMONSTRATES:
  17.  * -------------------------------
  18.  *  This program demonstrates the use of the default viewing
  19.  *  transformation, metafile loading and playing, the use of
  20.  *  dialog boxes, and file manipulation through Standard Open dialog.
  21.  *  It also demonstrates the use of an asynchronous drawing thread and
  22.  *  print thread.
  23.  *
  24.  * API CALLS FEATURED:
  25.  * -------------------
  26.  *
  27.  *  WinAddSwitchEntry                     DosReleaseMutexSem
  28.  *  WinAssociateHelpInstance              DosCloseMutexSem
  29.  *  WinBeginPaint                         DosCloseEventSem
  30.  *  WinCreateStdWindow                    DosWaitThread
  31.  *  WinCreationFlags
  32.  *  WinCreateHelpInstance                 DosResetEventSem
  33.  *  WinCreateMsgQueue
  34.  *  WinCreateWindow                       DosCreateThread
  35.  *  WinDlgBox                             DosGetInfoBlocks
  36.  *  WinDefFileDlgProc                     DosCreateMutexSem
  37.  *  WinDestroyHelpInstance                DosCreateEventSem
  38.  *  WinDestroyMsgQueue
  39.  *  WinDestroyWindow                      GpiCharStringAt
  40.  *  WinDispatchMsg                        GpiSetColor
  41.  *  WinDefDlgProc                         GpiQueryFontMetrics
  42.  *  WinDefWindowProc                      GpiCreateRegion
  43.  *  WinDismissDlg                         GpiCreatePS
  44.  *  WinEndPaint                           GpiQueryCharBox
  45.  *  WinFillRect                           GpiAssociate
  46.  *  WinGetPS                              GpiDestroyPS
  47.  *  WinGetMsg                             GpiDestroyRegion
  48.  *  WinInitialize                         GpiLoadMetaFile
  49.  *  WinInvalidateRegion                   GpiResetPS
  50.  *  WinInvalidateRect                     GpiSetStopDraw
  51.  *  WinLoadString
  52.  *  WinMessageBox
  53.  *  WinOpenWindowDC
  54.  *  WinPostMsg
  55.  *  WinPostQueueMsg
  56.  *  WinQuerySysValue
  57.  *  WinQuerySysPointer
  58.  *  WinQueryWindowDC
  59.  *  WinQueryWindowPos
  60.  *  WinQueryWindowProcess
  61.  *  WinQueryWindowPtr
  62.  *  WinQueryWindowRect
  63.  *  WinRegisterClass
  64.  *  WinReleasePS
  65.  *  WinRequestMutexSem
  66.  *  WinSendDlgItemMsg
  67.  *  WinSendMsg
  68.  *  WinSetWindowPos
  69.  *  WinSetWindowPtr
  70.  *  WinSetWindowText
  71.  *  WinTerminate
  72.  *  WinWaitEventSem
  73.  *  WinWindowFromID
  74.  *
  75.  * WHAT YOU NEED TO COMPILE THIS PROGRAM:
  76.  * --------------------------------------
  77.  *
  78.  *  REQUIRED FILES:
  79.  *  ---------------
  80.  *
  81.  *    GRAPHIC.C     - Source code
  82.  *    FILE.C        - Source code (File Handling)
  83.  *    GRAPHIC.MAK   - Make file for this program
  84.  *    GRAPHIC.DEF   - Module definition file
  85.  *    GRAPHIC.H     - Application header file
  86.  *    GRAPHIC.ICO   - Icon file
  87.  *    GRAPHIC.L     - Linker automatic response file
  88.  *    GRAPHIC.RC    - Resource file
  89.  *
  90.  *    OS2.H          - Presentation Manager include file
  91.  *    STDLIB.H       - Miscellaneous function declarations
  92.  *    STRING.H       - String function declarations
  93.  *
  94.  * EXPECTED INPUT:
  95.  * ---------------
  96.  *  User activity with the mouse or the keyboard, the standard
  97.  *  frame controls, menus, and dialog boxes.
  98.  *
  99.  * EXPECTED OUTPUT:
  100.  * ----------------
  101.  *  Display of the center part of a metafile picture in a standard
  102.  *  window. This has a frame with title bar, system and application
  103.  *  menus, and maximize and minimize icons.
  104.  *
  105.  *  Copyright (C) 1991 IBM Corporation
  106.  *
  107.  *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  108.  *      sample code created by IBM Corporation. This sample code is not
  109.  *      part of any standard or IBM product and is provided to you solely
  110.  *      for  the purpose of assisting you in the development of your
  111.  *      applications.  The code is provided "AS IS", without
  112.  *      warranty of any kind.  IBM shall not be liable for any damages
  113.  *      arising out of your use of the sample code, even if they have been
  114.  *      advised of the possibility of such damages.                                                    *
  115.  ******************************************************************************/
  116.  
  117. /* Include the required sections of the PM header file */
  118.  
  119. #include <stdlib.h>
  120. #include <string.h>
  121.  
  122. #define INCL_DOSPROCESS
  123. #define INCL_DOSSEMAPHORES
  124. #define INCL_GPICONTROL
  125. #define INCL_GPIMETAFILES
  126. #define INCL_GPIREGIONS
  127. #define INCL_GPIPRIMITIVES
  128. #define INCL_GPILCIDS
  129. #define INCL_WINSTDFILE
  130. #define INCL_WINSTDDLGS
  131. #define INCL_WINHELP
  132. #define INCL_WINPOINTERS
  133. #define INCL_WINFRAMEMGR
  134. #define INCL_WINWINDOWMGR
  135. #define INCL_WINMESSAGEMGR
  136. #define INCL_WINDIALOGS
  137. #define INCL_WINSYS
  138. #define INCL_WINMENUS
  139. #define INCL_WINMLE
  140. #define INCL_WINERRORS
  141.  
  142. #include <os2.h>
  143. #include <pmstddlg.h>
  144. #include <ctype.h>
  145. #include <process.h>
  146. #include <memory.h>
  147. #include "graphic.h"
  148.  
  149. /*
  150.  * Presentation Manager Program Main Body
  151.  *
  152.  * The following routine is the Presentation Manager program Main Body.
  153.  * The Main Body of a PM program is concerned with associating the
  154.  * application with the Presentation Manager system, creating its
  155.  * message queue, registering and displaying its main window, servicing
  156.  * its message queue during the time that the application is active,
  157.  * and disassociating the application from PM when the user is finished
  158.  * with the application. The remaining parts of this source module that
  159.  * are concerned with the Presentation Manager are the application's
  160.  * window procedures (main window procedure, child window procedures,
  161.  * and dialog window procedures) that process the messages associated
  162.  * with the application's various windows.
  163.  */
  164.  
  165. /* static function definitions */
  166. static   VOID       InvalidateTextRect(HWND hWnd);
  167. static   MAIN_PARM  Parm;
  168. static   PAPPL_DEFAULTS ApplDefaults;
  169.  
  170. /**************************************************************************
  171.  * Function: main
  172.  *
  173.  * Initializes the structures and handle the messages for the main window
  174.  *
  175.  * Parameters: none
  176.  *
  177.  * Result: none
  178.  *
  179.  ***************************************************************************/
  180. VOID main(VOID)
  181. {
  182.          QMSG       qmsg;           /* MSG structure to store the messages */
  183.          BOOL       fRc;
  184.          BOOL       FastQuit = FALSE;
  185.  
  186. /* Do the Initialization */
  187.    if (!Initialize())
  188.    {
  189.       FastQuit = TRUE;
  190.       ReportError();
  191.       EndProgram();
  192.    }
  193.  
  194.  
  195. /* The following is the message loop for the application. */
  196.  
  197.    do
  198.    {
  199.       fRc = WinGetMsg(Parm.hAB, (PQMSG)&qmsg, 0, 0, 0);
  200.       if (fRc)                   /* if not WM_QUIT, pass the message to the   */
  201.          WinDispatchMsg(Parm.hAB, (PQMSG)&qmsg);     /* window procedure     */
  202.    } while (fRc);
  203.  
  204. /* if printing is in process, cancel print job */
  205.    if (Parm.PrintStatus)
  206.    {
  207.       if (GpiSetStopDraw(Parm.hpsPrint, (LONG)TRUE) == GPI_ERROR)
  208.          DispError(Parm.hAB,Parm.hWndClient);
  209.    }
  210.  
  211.    EndProgram();
  212.    exit(0);
  213. } /* End of main */
  214.  
  215. /**************************************************************************
  216.  * Function: Initialize
  217.  *
  218.  * Initializing the structures and handle the messages for the main window
  219.  *
  220.  * Parameters: none
  221.  *
  222.  * Result:  BOOL              TRUE      Initialization ok
  223.  *                            FALSE     Error in Initialization
  224.  *
  225.  ***************************************************************************/
  226. BOOL Initialize(VOID)
  227. {
  228.          CHAR       szAppName[20];            /* class name of application */
  229. static   CHAR       InfoWindow[] = "GRAPHIC"; /* class name of info window */
  230.          INT        rc;
  231.          HELPINIT   hiGRAPHICHelp;     /* Help initialization structure    */
  232.          ULONG      WinCreationFlags;  /* window creation flags            */
  233.          PID        pid;         /* Process identifier for adding name to  */
  234.                                        /* switch list                      */
  235.          TID        tid;               /* Thread identifier                */
  236.          SWCNTRL    Swctl;
  237.          ULONG     WindowPosOption;
  238.  
  239.  
  240. /* Init Structure */
  241.    memset((PVOID)&Parm, '\0', sizeof(MAIN_PARM));
  242.    Parm.PrintEnabled = Parm.PrintPropertiesEnabled = Parm.fNotReady = TRUE;
  243.    Parm.DrawThreadID = (TID)-1;
  244.    Parm.CheckedItem = -1;
  245.    Parm.DrawParm.rclBounds.xLeft = Parm.DrawParm.rclBounds.yBottom =
  246.                                    Parm.DrawParm.rclBounds.xRight =
  247.                                    Parm.DrawParm.rclBounds.yTop = 0xFFFF;
  248.    Parm.DrawParm.fAllValid = Parm.fStoppable = Parm.DrawParm.fDrawing = TRUE;
  249.  
  250.    /* Create semaphores */
  251.    DosCreateMutexSem(NULL, &Parm.hmtxsemStoppable, DC_SEM_SHARED, FALSE);
  252.    DosCreateEventSem(NULL, &Parm.hevsemTerminate, DC_SEM_SHARED, TRUE);
  253.    DosCreateEventSem(NULL, &Parm.hevsemPrintEnds, DC_SEM_SHARED, TRUE);
  254.    DosCreateEventSem(NULL, &Parm.hevsemStop, DC_SEM_SHARED, TRUE);
  255.    /*
  256.     * The WinInitialize routine initializes the Presentation Manager
  257.     * facilities for use by this application and returns a handle to the
  258.     * anchor block assigned to the application by PM.
  259.     */
  260.    if ((Parm.hAB = WinInitialize(0)) == (HAB)0)
  261.       return(FALSE);
  262.  
  263.    Parm.ProgramTitle = GetString(Parm.hAB, APPLICATION_NAME, ALLOC_STRING);
  264.  
  265.    /* The WinCreateMsgQueue call creates a message queue for this application */
  266.    if ((Parm.hMQ = WinCreateMsgQueue(Parm.hAB, 16384)) == (HMQ)0)
  267.       return(FALSE);
  268.  
  269.    /* Query System Pointer */
  270.    Parm.hptrGlass = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  271.    Parm.hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
  272.  
  273.  
  274. /* The following function registers the classes of all application windows */
  275.    strcpy(szAppName, GetString(Parm.hAB, APPLICATION_NAME, STATIC_STRING));
  276.    rc = WinRegisterClass(Parm.hAB,         /* Anchor block handle             */
  277.                          (PCH)szAppName,   /* Name of class being registered  */
  278.                          (PFNWP)WndProc,   /* Window procedure for class      */
  279.                          CS_CLIPCHILDREN | CS_SIZEREDRAW | CS_SYNCPAINT,
  280.                          0);
  281.  
  282.    if (rc == FALSE)
  283.       return(FALSE);
  284.  
  285.    /* register a class for the information window */
  286.    rc = WinRegisterClass(Parm.hAB,         /* Anchor block handle             */
  287.                          (PCH)InfoWindow,  /* Name of class being registered  */
  288.                          (PFNWP)WndProcI,  /* Window procedure for class      */
  289.                          /* CS_SIZEREDRAW | CS_SYNCPAINT | CS_SAVEBITS, */
  290.                          0L,
  291.                          sizeof(PMAIN_PARM));
  292.  
  293.    if (rc == FALSE)
  294.       {
  295.       strcpy(Parm.ErrorMsg,
  296.              GetString(Parm.hAB, ERRMSG_REGISTER_FAILED, STATIC_STRING));
  297.       return(FALSE);
  298.       }
  299.  
  300.    /* IPF Initialization Structure */
  301.  
  302.    hiGRAPHICHelp.cb = sizeof(HELPINIT);            /* size of init structure */
  303.    hiGRAPHICHelp.ulReturnCode = 0;
  304.    hiGRAPHICHelp.pszTutorialName = 0;              /* no tutorial            */
  305.    hiGRAPHICHelp.phtHelpTable = (PVOID)(0xffff0000 | ID_GRAPHIC);
  306.    hiGRAPHICHelp.hmodAccelActionBarModule = 0;
  307.    hiGRAPHICHelp.idAccelTable = 0;
  308.    hiGRAPHICHelp.idActionBar = 0;
  309.    hiGRAPHICHelp.pszHelpWindowTitle = szAppName;
  310.    hiGRAPHICHelp.hmodHelpTableModule = 0;
  311.    hiGRAPHICHelp.fShowPanelId = 0;
  312.    hiGRAPHICHelp.pszHelpLibraryName = HELP_FILE;
  313.  
  314.    /* Create Instance of IPF */
  315.  
  316.    Parm.hWndGRAPHICHelp = WinCreateHelpInstance(Parm.hAB, &hiGRAPHICHelp);
  317.  
  318.    if (!Parm.hWndGRAPHICHelp || hiGRAPHICHelp.ulReturnCode)
  319.       {
  320.       WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  321.                     GetString(Parm.hAB, ERRMSG_NO_HELP, STATIC_STRING),
  322.                     (PSZ)Parm.ProgramTitle,
  323.                     1,
  324.                     MB_OK | MB_APPLMODAL | MB_MOVEABLE);
  325.       WinDestroyHelpInstance(Parm.hWndGRAPHICHelp);
  326.       }
  327.     /*
  328.      * The CreateWindow function creates a frame window for this application's
  329.      * top window, and sets the window's size and location as appropriate.
  330.      */
  331.    WinCreationFlags = FCF_TITLEBAR     |
  332.                       FCF_SYSMENU      |
  333.                       FCF_MINBUTTON    |
  334.                       FCF_MAXBUTTON    |
  335.                       FCF_SIZEBORDER   |
  336.                       FCF_MENU         |
  337.                       FCF_ACCELTABLE   |
  338.                       FCF_ICON;
  339.  
  340.    WinCreationFlags |= FCF_SHELLPOSITION;
  341.  
  342.    /* Create the frame window */
  343.    Parm.hWndFrame = WinCreateStdWindow(HWND_DESKTOP, /* parent of window      */
  344.                                 WS_VISIBLE,          /* frame window style    */
  345.                                 &WinCreationFlags,   /* frame flags           */
  346.                                 szAppName,           /* class name            */
  347.                                 Parm.ProgramTitle,   /* window title          */
  348.                                 WS_VISIBLE |         /* client window style   */
  349.                                 WS_CLIPCHILDREN,
  350.                                 (HMODULE)NULL,       /* module for resources  */
  351.                                 ID_GRAPHIC,          /* resource id           */
  352.                                 (HWND FAR *)&Parm.hWndClient); /* client handle*/
  353.       /*
  354.        * if hWndFrame is NULL, an error occured when opening the window,
  355.        *     notify the user and exit this function
  356.        */
  357.    if (Parm.hWndFrame == (HWND)0)
  358.       {
  359.       strcpy(Parm.ErrorMsg, GetString(Parm.hAB, ERRMSG_CREATE_WINDOW,
  360.                                        STATIC_STRING));
  361.       return(FALSE);
  362.       }
  363.  
  364.    /* Associate Instance of IPF */
  365.  
  366.    if (Parm.hWndGRAPHICHelp)
  367.       WinAssociateHelpInstance(Parm.hWndGRAPHICHelp,
  368.                                Parm.hWndFrame);
  369.    /*
  370.     * The following inline routine fills out the application's switch control
  371.     * structure with the appropriate information to add the application's
  372.     * name to the OS/2 Task Manager List, a list of the jobs currently
  373.     * running on the computer.
  374.     */
  375.    WinQueryWindowProcess(Parm.hWndFrame, &pid, &tid);
  376.    Swctl.hwnd = Parm.hWndFrame;                     /* Frame window handle    */
  377.    Swctl.idProcess = pid;                           /* Process identifier     */
  378.    Swctl.uchVisibility = SWL_VISIBLE;               /* visibility             */
  379.    Swctl.fbJump = SWL_JUMPABLE;                     /* Jump indicator         */
  380.    strcpy(Swctl.szSwtitle, Parm.ProgramTitle);      /* Frame window title     */
  381.    WinAddSwitchEntry(&Swctl);
  382.  
  383.    /* Copy Application Defaults */
  384.    if (ApplDefaults)
  385.       {
  386.       strcpy(Parm.DriverName, ApplDefaults->DriverName);
  387.       }
  388.  
  389.    /* Query Default Printer and set print items (Print & Printer Properties) */
  390.    SetPrintItems(&Parm);
  391.  
  392.    /* create information window */
  393.      Parm.InfoWnd.hWnd = WinCreateWindow(Parm.hWndClient,
  394.                                          InfoWindow,
  395.                                          (PSZ)InfoWindow,
  396.                                          WS_SAVEBITS | WS_CLIPCHILDREN,
  397.                                          0,
  398.                                          0,
  399.                                          1,
  400.                                          1,
  401.                                          Parm.hWndClient,
  402.                                          HWND_TOP,
  403.                                          ID_GRAPHIC,
  404.                                          (PVOID)&Parm,
  405.                                          NULL);
  406.  
  407.    if (Parm.InfoWnd.hWnd == (HWND)0)
  408.    {
  409.       strcpy(Parm.ErrorMsg, GetString(Parm.hAB, ERRMSG_INFO_WINDOW, STATIC_STRING));
  410.       return(FALSE);
  411.    }
  412.  
  413. /*
  414.  * Query current process ID, thread ID and the process ID of the parent
  415.  * process
  416.  */
  417.    DosGetInfoBlocks(&Parm.ptibMain, &Parm.ppibMain);
  418.  
  419. /* create draw thread */
  420.    if (DosCreateThread(&Parm.DrawThreadID,
  421.                     (PFNTHREAD)DrawThread,
  422.                     (ULONG)(PMAIN_PARM)&Parm,
  423.                     (ULONG)0,
  424.                     (ULONG)STACK_SIZE))
  425.    {
  426.       strcpy(Parm.ErrorMsg, GetString(Parm.hAB, ERRMSG_DRAW_THREAD, STATIC_STRING));
  427.       return(FALSE);
  428.    }
  429.  
  430. /* create print thread */
  431.    if (DosCreateThread(&Parm.PrintThreadID,
  432.                     (PFNTHREAD)PrintThread,
  433.                     (ULONG)(PMAIN_PARM)&Parm,
  434.                     (ULONG)0,
  435.                     (ULONG)STACK_SIZE))
  436.    {
  437.       strcpy(Parm.ErrorMsg, GetString(Parm.hAB, ERRMSG_PRINT_THREAD,
  438.              STATIC_STRING));
  439.       return(FALSE);
  440.    }
  441.  
  442. /* invalidate text rectangle */
  443.    InvalidateTextRect(Parm.hWndClient);
  444.  
  445. } /* End of Initialize */
  446.  
  447. /**************************************************************************
  448.  * Function: Report Error
  449.  *
  450.  * Display a message box with the error returned from the function
  451.  * Initialize.
  452.  *
  453.  * Parameters: none
  454.  *
  455.  * Result:  none
  456.  *
  457.  ***************************************************************************/
  458. VOID ReportError(VOID)
  459.  
  460. {
  461.    if (Parm.ErrorMsg)
  462.       WinMessageBox(HWND_DESKTOP,
  463.                  (Parm.hWndFrame) ? Parm.hWndFrame : HWND_DESKTOP,
  464.                  (PSZ)Parm.ErrorMsg,
  465.                  (PSZ)NULL,
  466.                  0,
  467.                  MB_MOVEABLE | MB_CUACRITICAL | MB_OK);
  468. } /* End of ReportError */
  469.  
  470. /*************************************************************************
  471.  * Function: EndProgram
  472.  *
  473.  * End the threads and discard all windows
  474.  *
  475.  * Parameters: none
  476.  *
  477.  * Result:  none
  478.  *
  479.  ***************************************************************************/
  480. VOID EndProgram(VOID)
  481. {
  482.    ULONG      ResetCount;
  483. /*
  484.  * Perform clean up before exiting application.
  485.  * Destroy Instance of IPF
  486.  */
  487.    if (Parm.hWndGRAPHICHelp)
  488.       WinDestroyHelpInstance(Parm.hWndGRAPHICHelp);
  489.  
  490. /* end the draw thread */
  491.    if (Parm.DrawThreadID != -1)
  492.    {
  493.       WinRequestMutexSem(Parm.hmtxsemStoppable, (ULONG)-1);
  494.       Parm.fStoppable = TRUE;
  495.       DosReleaseMutexSem(Parm.hmtxsemStoppable);
  496.       SendCommand(&Parm, (ULONG)FLUSH_COMMAND, (ULONG)NULL);
  497.       DosResetEventSem(Parm.hevsemTerminate, &ResetCount);
  498.       if (SendCommand(&Parm, (ULONG)STOP_THREAD, (ULONG)NULL))
  499.          WinWaitEventSem(Parm.hevsemTerminate, (ULONG)-1);
  500.    }
  501.  
  502. /* end the print thread */
  503.    if (Parm.PrintThreadID != -1)
  504.    {
  505.       DosResetEventSem(Parm.hevsemPrintEnds, &ResetCount);
  506.       WinPostQueueMsg(Parm.hMQPrint, STOP_THREAD, MPFROMSHORT(0), MPFROMSHORT(0));
  507.       WinWaitEventSem(Parm.hevsemPrintEnds, (ULONG)-1);
  508.    }
  509.  
  510. /* wait until Draw Thread has ended */
  511.    DosWaitThread(&Parm.DrawThreadID, DCWW_WAIT);
  512.  
  513. /* wait until print thread has ended */
  514.    DosWaitThread(&Parm.PrintThreadID, DCWW_WAIT);
  515.  
  516.    if (Parm.InfoWnd.hWnd)
  517.       WinDestroyWindow(Parm.InfoWnd.hWnd);  /* Destroy the Infowindow            */
  518.    if (Parm.hWndFrame)
  519.       WinDestroyWindow(Parm.hWndFrame);     /* Destroy the frame window          */
  520.    if (Parm.hMQ)
  521.       WinDestroyMsgQueue(Parm.hMQ);  /* Destroy the application message queue */
  522.    if (Parm.hAB)
  523.       WinTerminate(Parm.hAB);        /* Terminate the application's use of   */
  524.                                      /* Presentation Manager resources       */
  525.  
  526.    /* Close the semaphores */
  527.    DosCloseMutexSem(Parm.hmtxsemStoppable);        /* new with 2.0 */
  528.    DosCloseEventSem(Parm.hevsemTerminate);
  529.    DosCloseEventSem(Parm.hevsemPrintEnds);
  530.    DosCloseEventSem(Parm.hevsemStop);
  531. } /* End of EndProgram */
  532.  
  533. /**************************************************************************
  534.  * Function: WndProc
  535.  *
  536.  * Main Window Procedure
  537.  *
  538.  * This procedure provides service routines for the general PM events
  539.  * (messages) that PM sends to the window, as well as the user
  540.  * initiated events (messages) that are generated when the user selects
  541.  * the action bar and pulldown menu controls or the corresponding
  542.  * keyboard accelerators.
  543.  *
  544.  * The SWITCH statement shown below distributes the window messages to
  545.  * the respective message service routines, which are set apart by the
  546.  * CASE statements. The window procedures must provide an appropriate
  547.  * service routine for its end user initiated messages, as well as the
  548.  * general PM messages (like the WM_CLOSE message). If a message is
  549.  * sent to this procedure for which there is no programmed CASE clause
  550.  * (i.e., no service routine), the message is defaulted to the
  551.  * WinDefWindowProc function, where it is disposed of by PM.
  552.  *
  553.  * Parameters: HWND         window handle
  554.  *             USHORT       message
  555.  *             MPARAM       message parameter 1
  556.  *             MPARAM       message parameter 2
  557.  *
  558.  * Result:  MRESULT         message result
  559.  *
  560.  ***************************************************************************/
  561. MRESULT EXPENTRY WndProc(HWND hWnd, ULONG message, MPARAM mp1, MPARAM mp2)
  562. {
  563.          HPS        hPS;      /* Handle for the Presentation Space         */
  564.          RECTL      rClient;  /* Handle to rectangle formed by client area */
  565.          PSWP       WindowPos;
  566. static   BOOL       WindowMinimized = FALSE;
  567.          HMF        hmfPicture;
  568. static   CHAR       Filename[260];
  569. static   CHAR       Filemask[260];
  570. static   MENUITEM   mi =
  571.                     {
  572.                     1, MIS_TEXT, 0, IDM_F_TEXT_PREVIOUS, (HWND)0, (ULONG)0
  573.                     };
  574. static   BOOL       MenuUpdated = FALSE;
  575.          PSZ        FileName;
  576.          PSZ        DialogHeader;
  577.  
  578.    switch(message)
  579.    {
  580.    case SET_PRINT_STATUS:              /* set print status              */
  581.         Parm.PrintStatus = (BOOL)SHORT1FROMMP(mp1);
  582.         Parm.hpsPrint = (HPS)LONGFROMMP(mp2);
  583.         WinSendMsg(Parm.InfoWnd.hWnd,  /* hide/show information window */
  584.                    ENABLE_INFO_WND,
  585.                    mp1,
  586.                    MPFROMSHORT(0));
  587.         SetPrintItems(&Parm);              /* set item "Print" in the menu */
  588.         break;
  589.  
  590.    case WM_CREATE:
  591.         return(WndProcCreate(hWnd, &Parm));
  592.         break;
  593.  
  594.    case WM_ERASEBACKGROUND:
  595.         /*
  596.          * If the flag fNotReady is set, the default processing for this
  597.          * message occurs.
  598.          */
  599.         if (Parm.fNotReady)
  600.            return(MRESULT)(TRUE);
  601.         else
  602.            return(MRESULT)(FALSE);
  603.         break;
  604.  
  605.    case WM_USER_END_ON_ERROR:          /* Display error and end program */
  606.         WinMessageBox(HWND_DESKTOP,
  607.                       hWnd,
  608.                       (PSZ)PVOIDFROMMP(mp2),
  609.                       (PSZ)PVOIDFROMMP(mp1),
  610.                       (USHORT)0,
  611.                       MB_OK | MB_MOVEABLE | MB_CUACRITICAL | MB_APPLMODAL);
  612.         WinPostMsg(hWnd,
  613.                    WM_QUIT,
  614.                    MPFROMSHORT(0),
  615.                    MPFROMSHORT(0));
  616.         break;
  617.    case WM_USER_DEFINED_CODE:          /* own messages                  */
  618.         switch (SHORT1FROMMP(mp1))
  619.            {
  620.            case CHECK_ITEM:            /* check item in file menu       */
  621.                 break;
  622.            }
  623.  
  624.    case WM_COMMAND:
  625.         /*
  626.          * The PM messages for action bar and pulldown menu items are
  627.          * processed in this routine.
  628.          */
  629.         switch(SHORT1FROMMP(mp1))
  630.            {
  631.            case IDM_F_GPI:             /* menu item "GPI"               */
  632.                *Parm.Message = '\0';
  633.                 if (Parm.CheckedItem != 1)
  634.                 {
  635.                    StopDrawing(&Parm);
  636.                    if (GpiResetPS(Parm.hpsClient, GRES_ALL) == GPI_ERROR)
  637.                        DispError(Parm.hAB,Parm.hWndClient);
  638.                    SendCommand(&Parm, (ULONG)SET_TRANSFORM, (ULONG)NULL);
  639.                    SendCommand(&Parm, (ULONG)DRAW_ORDERS, (ULONG)NULL);
  640.                    Parm.DrawThreadActivated = TRUE;
  641.                    CheckPulldown(&Parm, 1);
  642.                    SetTitleBarText(&Parm, "GPI");
  643.                 }
  644.                 break;
  645.  
  646.            case IDM_F_METAFILE_LOAD:/* load metafile from menu item "METAFILE"*/
  647.                 *Parm.Message = '\0';
  648.                 strcpy(Filemask, Parm.MetafilePath);
  649.                 FileName = strrchr(Filemask, (int)'\\');
  650.                 if (FileName == NULL)
  651.                    FileName = Filemask;
  652.                 else
  653.                    FileName++;
  654.                 strcpy(FileName, "*.MET");
  655.  
  656.                 /* Display File Dialog */
  657.                 DialogHeader = GetString(Parm.hAB, FILEDLG_META_HEADER,
  658.                                          ALLOC_STRING);
  659.                 if (OpenFileDialog(Parm.hWndFrame, DialogHeader,
  660.                                    Filemask, Filename))
  661.                    {
  662.                       strcpy(Parm.MetafilePath, Filename);
  663.                       WinSendMsg(hWnd,
  664.                                  IDM_F_METAFILE,
  665.                                  MPFROMSHORT(0),
  666.                                  MPFROMSHORT(0));
  667.                    }
  668.                 free(DialogHeader);
  669.                 break;
  670.  
  671.            case IDM_F_PRINT:              /* menu item "Print"          */
  672.                 switch (Parm.CheckedItem)
  673.                    {
  674.                    case 1:             /* print GPI */
  675.                         PrintGpiMeta(&Parm, DRAW_GPI);
  676.                         break;
  677.                    case 2:             /* print Metafile */
  678.                         PrintGpiMeta(&Parm, DRAW_META);
  679.                         break;
  680.                    }
  681.                 break;
  682.  
  683.            case IDM_O_PRINTPROPERTIES:   /*  menu item "Job properties" */
  684.                 QueryJobProperties(Parm.hAB,
  685.                                    &Parm.DriverData,
  686.                                    &Parm.DriverDataLength,
  687.                                    Parm.DriverName,
  688.                                    Parm.QueueName,
  689.                                    NULL, TRUE);
  690.  
  691.                 break;
  692.  
  693.            case IDM_H_HELPINDEX:        /* menu item "Help for Index"  */
  694.                 if (Parm.hWndGRAPHICHelp)
  695.                    WinSendMsg(Parm.hWndGRAPHICHelp, HM_DISPLAY_HELP,
  696.                              MPFROMSHORT(HELP_INDEX), 0L);
  697.                 break;
  698.  
  699.            case IDM_H_HELPGEN:          /* menu item "Help for General"*/
  700.                 if (Parm.hWndGRAPHICHelp)
  701.                    WinSendMsg(Parm.hWndGRAPHICHelp, HM_DISPLAY_HELP,
  702.                              MPFROMSHORT(HELP_GEN), 0L);
  703.                 break;
  704.  
  705.            case IDM_H_HELPUSING:        /* menu item "Help for Using"  */
  706.                 if (Parm.hWndGRAPHICHelp)
  707.                    WinSendMsg(Parm.hWndGRAPHICHelp, HM_DISPLAY_HELP,
  708.                              MPFROMSHORT(HELP_USING), 0L);
  709.                 break;
  710.  
  711.            case IDM_H_HELPKEYS:         /* menu item "Help for Keys"   */
  712.                 if (Parm.hWndGRAPHICHelp)
  713.                    WinSendMsg(Parm.hWndGRAPHICHelp, HM_DISPLAY_HELP,
  714.                               MPFROMSHORT(HELP_KEYS), 0L);
  715.                 break;
  716.  
  717.            case IDM_H_ABOUT:            /* menu item "About"           */
  718.                 WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)AboutDlg,
  719.                           0, ID_ABOUT, (PBYTE)NULL);
  720.                 break;
  721.  
  722.            default:
  723.                 break; /* End of default case for switch(mp1) */
  724.            }
  725.          break; /* End of WM_COMMAND */
  726.  
  727.     case IDM_F_METAFILE:
  728.          StopDrawing(&Parm);
  729.          if (GpiResetPS(Parm.hpsClient, GRES_ALL) == GPI_ERROR)
  730.              DispError(Parm.hAB,Parm.hWndClient);
  731.          if (LONGFROMMP(mp1) == 0L)
  732.             hmfPicture = GpiLoadMetaFile(Parm.hAB, Parm.MetafilePath);
  733.          else
  734.             hmfPicture = (HMF)LONGFROMMP(mp1);
  735.          if (hmfPicture == (HMF)NULL)
  736.             {
  737.             StringWithVarText(Parm.hAB, ERRMSG_METAFILE_FAILED,
  738.                               Parm.MetafilePath, Parm.Message),
  739.             Parm.fNotReady = FALSE;
  740.             DisplayMessage(Parm.hWndClient, Parm.Message);
  741.             }
  742.          else
  743.             {
  744.             SendCommand(&Parm, (ULONG)SET_TRANSFORM,
  745.                         (ULONG)hmfPicture);
  746.             SendCommand(&Parm, (ULONG)DRAW_ORDERS, (ULONG)NULL);
  747.             Parm.DrawThreadActivated = TRUE;
  748.             CheckPulldown(&Parm, 2);
  749.             if (LONGFROMMP(mp1) == 0L)
  750.                SetTitleBarText(&Parm, Parm.MetafilePath);
  751.             else
  752.                SetTitleBarText(&Parm, "!Clipboard Metafile");
  753.             }
  754.          break;
  755.  
  756.     case WM_INITMENU:      /* message appears on selecting a pulldown menu */
  757.          switch(SHORT1FROMMP(mp1))
  758.             {
  759.             case IDM_FILE:             /* set items "Print" and "Print      */
  760.             case IDM_OPTIONS:          /* properties" when menu is selected */
  761.                  SetPrintItems(&Parm);
  762.                  break;
  763.             case IDM_F_METAFILE:
  764.                  /* test, if metafile data in the clipboard */
  765.                  /* test, if a metafile was selected */
  766.                    if (*Parm.MetafilePath != '\0')
  767.                     {
  768.                     FileName = strrchr(Parm.MetafilePath, (int)'\\');
  769.                     if (FileName == NULL)
  770.                        FileName = Parm.MetafilePath;
  771.                     else
  772.                        FileName++;
  773.                     WinSendMsg(HWNDFROMMP(mp2),
  774.                                MM_INSERTITEM,
  775.                                MPFROMP(&mi),
  776.                                MPFROMP(FileName));
  777.                     MenuUpdated = TRUE;
  778.                     }
  779.                  break;
  780.             }
  781.          break;
  782.  
  783.    case WM_DESTROY:
  784.       /*
  785.        * The application has asked for the window to be destroyed.
  786.        * Where appropriate, the region and the graphics presentation
  787.        * spaces are destroyed.
  788.        */
  789.       if (Parm.DrawParm.hrgnInvalid != (HRGN)NULL)
  790.          if (GpiDestroyRegion(Parm.hpsClient,
  791.                               Parm.DrawParm.hrgnInvalid) == GPI_ERROR)
  792.              DispError(Parm.hAB,Parm.hWndClient);
  793.       if (Parm.hpsClient !=(HPS)NULL)
  794.          {
  795.           if (GpiAssociate(Parm.hpsClient, (HDC)NULL) == GPI_ERROR)
  796.               DispError(Parm.hAB,Parm.hWndClient);
  797.           if (GpiDestroyPS(Parm.hpsClient) == GPI_ERROR)
  798.               DispError(Parm.hAB,Parm.hWndClient);
  799.          }
  800.       if (Parm.hpsPaint !=(HPS)NULL)
  801.          if (GpiDestroyPS(Parm.hpsPaint) == GPI_ERROR)
  802.              DispError(Parm.hAB,Parm.hWndClient);
  803.       break;
  804.  
  805.    case WM_MINMAXFRAME:           /* minimize/maximize window */
  806.         WindowPos = PVOIDFROMMP(mp1);
  807.         if (WindowPos->fl & SWP_MINIMIZE)
  808.            {
  809.            WindowMinimized = TRUE;
  810.            if (Parm.DrawThreadActivated)
  811.               SendCommand(&Parm, (ULONG)FLUSH_COMMAND, (ULONG)NULL);
  812.            }
  813.         else
  814.            {
  815.            WindowMinimized = FALSE;
  816.            }
  817.         break;
  818.  
  819.  
  820.    case HM_QUERY_KEYS_HELP:
  821.         /*
  822.          * If the user requests Keys Help from the help pulldown,
  823.          * IPF sends the HM_QUERY_KEYS_HELP message to the application,
  824.          * which should return the panel id of the Keys Help panel
  825.          */
  826.         return (MRESULT)PANEL_HELPKEYS;  /* return id of key help panel */
  827.         break;
  828.  
  829.    case HM_ERROR:
  830.         /*
  831.          * If an IPF error occurs, an HM_ERROR message will be sent to
  832.          * the application.
  833.          */
  834.         if (Parm.hWndGRAPHICHelp && ((ULONG)mp1) == HMERR_NO_MEMORY)
  835.            {
  836.            WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  837.                          GetString(Parm.hAB, ERRMSG_HELP_TERMINATED,
  838.                                    STATIC_STRING),
  839.                          Parm.ProgramTitle,
  840.                          1,
  841.                          MB_OK | MB_APPLMODAL | MB_MOVEABLE);
  842.            WinDestroyHelpInstance(Parm.hWndGRAPHICHelp);
  843.            }
  844.          else
  845.            {
  846.            strcpy(Parm.ErrorMsg,
  847.                   GetString(Parm.hAB, ERRMSG_HELP_ERROR, STATIC_STRING));
  848.            _ltoa(LONGFROMMP(mp1), &Parm.ErrorMsg[strlen(Parm.ErrorMsg)], 16);
  849.  
  850.            WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  851.                          (PSZ)Parm.ErrorMsg,
  852.                          (PSZ)Parm.ProgramTitle,
  853.                          1,
  854.                          MB_OK | MB_APPLMODAL | MB_MOVEABLE);
  855.            }
  856.         break;
  857.  
  858.    case WM_SIZE:     /* code for sizing client area */
  859.         if (WindowMinimized)
  860.            break;
  861.         if (Parm.ResizeWindow)
  862.            AdjustWindowSize(&Parm);
  863.         else
  864.            Parm.ResizeWindow = TRUE;
  865.         if (Parm.DrawThreadActivated)  /* cancel any pending draw requests */
  866.         {
  867.            SendCommand(&Parm, (ULONG)FLUSH_COMMAND, (ULONG)NULL);
  868.            SendCommand(&Parm, (ULONG)SIZING, (ULONG)NULL);
  869.         }
  870.         WinPostMsg(Parm.InfoWnd.hWnd,     /* reposition information window */
  871.                    POS_INFO_WND,
  872.                    MPFROMSHORT(0),
  873.                    MPFROMSHORT(0));
  874.         break;       /* End of WM_SIZE */
  875.  
  876.    case WM_PAINT:    /* code for the window's client area */
  877.         if (Parm.DrawThreadActivated)
  878.            return(WndProcPaint(&Parm));
  879.         /* Obtain a handle to a cache presentation space */
  880.         hPS = WinBeginPaint(hWnd, 0, 0);
  881.  
  882.         /* Determine the size of the client area */
  883.         WinQueryWindowRect(hWnd, &rClient);
  884.  
  885.         /* Fill the background with the default background color */
  886.         WinFillRect(hPS, &rClient, CLR_BACKGROUND);
  887.  
  888.         /* return presentation space to state before WinBeginPaint */
  889.         WinEndPaint(hPS);
  890.  
  891.         break; /* End of WM_PAINT */
  892.  
  893.    default:
  894.         /*
  895.          * For any message which you don't specifically provide a
  896.          * service routine, you should return the message to PM using
  897.          * the WinDefWindowProc function.
  898.          */
  899.         return(WinDefWindowProc(hWnd, message, mp1, mp2));
  900.         break;  /* End of default */
  901.    }
  902. return(0L);
  903. } /* End of WndProc */
  904.  
  905. /*************************************************************************
  906.  * Function: CheckPulldown
  907.  *
  908.  * Check one of the pulldown items "GPI", "METAFILE"
  909.  *
  910.  * Parameters: PMAIN_PARM   main parameter structure
  911.  *             ULONG       number of item to check
  912.  *
  913.  * Result:  none
  914.  *
  915.  ***************************************************************************/
  916. VOID CheckPulldown(PMAIN_PARM Parm, LONG index)
  917. {
  918. static   ULONG     Items[] =
  919.                     {
  920.                     IDM_F_GPI,
  921.                     IDM_F_METAFILE,
  922.                     };
  923.  
  924. /* if item already checked, do nothing */
  925.    if (Parm->CheckedItem != index)
  926.    {
  927.       if (index == 0)                  /* If text is selected */
  928.       {
  929.          WinSendMsg(Parm->hWndFrame,
  930.                  WM_USER_DEFINED_CODE,
  931.                  MPFROMSHORT(INIT_MLE),
  932.                  MPFROMSHORT(TRUE));
  933.       }
  934.       if (Parm->CheckedItem == 0)      /* If text is deselected */
  935.       {
  936.          WinSendMsg(Parm->hWndFrame,
  937.                  WM_USER_DEFINED_CODE,
  938.                  MPFROMSHORT(INIT_MLE),
  939.                  MPFROMSHORT(FALSE));
  940.       }
  941.       Parm->CheckedItem = index;
  942.       if (!index)
  943.          InvalidateTextRect(Parm->hWndClient);
  944.    }
  945. } /* End of CheckPullDown */
  946.  
  947. /*************************************************************************
  948.  * Function: AdjustWindowSize
  949.  *
  950.  * resize frame window
  951.  *
  952.  * Parameters: PMAIN_PARM   main parameter structure
  953.  *
  954.  * Result:  none
  955.  *
  956.  ***************************************************************************/
  957. VOID AdjustWindowSize(PMAIN_PARM Parm)
  958. {
  959.    SWP        SizeFrame;
  960.    SWP        SizeClient;
  961.    HPS        hPS;
  962.    SIZEF      CharSizeClient;
  963.  
  964.    hPS = WinGetPS(Parm->hWndClient);         /* get PS of client area      */
  965.  
  966.    /* get size of character box */
  967.    if (GpiQueryCharBox(hPS, (PSIZEF)&CharSizeClient) == GPI_ERROR)
  968.        DispError(Parm->hAB,Parm->hWndClient);
  969.  
  970.    WinReleasePS(hPS);                        /* release presentation space */
  971.  
  972.    WinReleasePS(hPS);                        /* release presentation space */
  973.    /*
  974.     * resize window, so that at least the information line and one line of
  975.     * the multiline edit field can be displayed
  976.     */
  977.    WinQueryWindowPos(Parm->hWndFrame,
  978.                      &SizeFrame);
  979.  
  980.    WinQueryWindowPos(Parm->hWndClient,
  981.                      &SizeClient);
  982. } /* End of AdjustWindowSize */
  983.  
  984. /*************************************************************************
  985.  * Function: WndProcCreate
  986.  *
  987.  * The WndProcCreate function obtains a device context for the client
  988.  * area of the window, creates a normal graphics presentation space,
  989.  * and associates the two. The presentation page is defined in pels,
  990.  * and is the same size as the maximum client area.
  991.  * A second graphics presentation space is defined for use by the main
  992.  * thread. This is the same size and format as the first presentation
  993.  * space.  WndProcCreate also defines an empty region for hpsClient.
  994.  * This is used by the asynchronous thread to accumulate invalid
  995.  * regions in the client area.
  996.  *
  997.  * Parameters: HWND         window handle of the frame window
  998.  *             PMAIN_PARM   main parameter structure
  999.  *
  1000.  * Result:  MRESULT         TRUE if an error appeared, otherwise false
  1001.  *
  1002.  ***************************************************************************/
  1003. MRESULT WndProcCreate(HWND hwnd, PMAIN_PARM Parm)
  1004. {
  1005.    SIZEL      sizlClient;
  1006.  
  1007. /* query size of Desktop */
  1008.    sizlClient.cx = WinQuerySysValue(HWND_DESKTOP, SV_CXFULLSCREEN);
  1009.    sizlClient.cy = WinQuerySysValue(HWND_DESKTOP, SV_CYFULLSCREEN);
  1010.  
  1011.    /* open device context for client area */
  1012.    Parm->hdcClient = WinOpenWindowDC(hwnd);
  1013.    /* create presentation space for client area  and associate it with DC */
  1014.    Parm->hpsClient = GpiCreatePS(Parm->hAB,
  1015.                                  Parm->hdcClient,
  1016.                                  &sizlClient,
  1017.                                  GPIA_ASSOC | PU_PELS);
  1018.    if (Parm->hpsClient == (HPS)NULL)
  1019.       return((MRESULT)TRUE);
  1020.  
  1021.    /* create presentation space for painting */
  1022.    Parm->hpsPaint = GpiCreatePS(Parm->hAB,
  1023.                                 (HDC)NULL,
  1024.                                 &sizlClient,
  1025.                                 PU_PELS);
  1026.  
  1027.    /* create region for client area */
  1028.    Parm->DrawParm.hrgnInvalid = GpiCreateRegion(Parm->hpsClient,
  1029.                                                 (ULONG)0, (PRECTL)NULL);
  1030.  
  1031.    return(FALSE);
  1032. } /* End of WndProcCreate */
  1033.  
  1034. /*************************************************************************
  1035.  * Function: SetPrintItems
  1036.  *
  1037.  * Test (default) printer queue and enable/disable menu items "Print" and
  1038.  * "Print properties".
  1039.  *
  1040.  * Parameters: PMAIN_PARM   main parameter structure
  1041.  *
  1042.  * Result:  none
  1043.  *
  1044.  ***************************************************************************/
  1045. VOID SetPrintItems(PMAIN_PARM Parm)
  1046. {
  1047. BOOL       QueuePredefined;
  1048.  
  1049.                                         /* test, if queue preselected */
  1050.    if (Parm->QueueName[0] == '\0')
  1051.       QueuePredefined = FALSE;
  1052.    else
  1053.       QueuePredefined = TRUE;
  1054. /*
  1055.  * if queue preselected, test if queue is already valid, otherwise query
  1056.  * default queue
  1057.  */
  1058.    if (QueryDefaultQueue(Parm->QueueName, Parm->DriverName))
  1059.    {
  1060.    /*
  1061.     * if item "Print" is disabled and no print request is running, enable
  1062.     * menu item "Print"
  1063.     */
  1064.       if (!Parm->PrintEnabled)
  1065.       {
  1066.          if (!Parm->PrintStatus)
  1067.          {
  1068.             WinSendMsg(WinWindowFromID(Parm->hWndFrame, (USHORT)FID_MENU),
  1069.                     MM_SETITEMATTR,
  1070.                     MPFROM2SHORT(IDM_F_PRINT, TRUE),
  1071.                     MPFROM2SHORT(MIA_DISABLED, ~MIA_DISABLED));
  1072.             Parm->PrintEnabled = TRUE;
  1073.          }
  1074.       }
  1075.       else
  1076.    /*
  1077.     * if item "Print" is enabled and a print request is running, disable
  1078.     * menu item "Print"
  1079.     */
  1080.          if (Parm->PrintStatus)
  1081.          {
  1082.             WinSendMsg(WinWindowFromID(Parm->hWndFrame, (USHORT)FID_MENU),
  1083.                     MM_SETITEMATTR,
  1084.                     MPFROM2SHORT(IDM_F_PRINT, TRUE),
  1085.                     MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  1086.             Parm->PrintEnabled = FALSE;
  1087.          }
  1088.    /* if menu item "Print properties" is disabled, enable item */
  1089.       if (!Parm->PrintPropertiesEnabled)
  1090.       {
  1091.          WinSendMsg(WinWindowFromID(Parm->hWndFrame, (USHORT)FID_MENU),
  1092.                  MM_SETITEMATTR,
  1093.                  MPFROM2SHORT(IDM_O_PRINTPROPERTIES, TRUE),
  1094.                  MPFROM2SHORT(MIA_DISABLED, ~MIA_DISABLED));
  1095.          Parm->PrintPropertiesEnabled = TRUE;
  1096.       }
  1097.    }
  1098.    else
  1099.    {
  1100.    /*
  1101.     * if printer queue is not valid, disable menu items "Print" and
  1102.     * "Print properties
  1103.     */
  1104.       if (Parm->PrintEnabled)
  1105.       {
  1106.          WinSendMsg(WinWindowFromID(Parm->hWndFrame, (USHORT)FID_MENU),
  1107.                  MM_SETITEMATTR,
  1108.                  MPFROM2SHORT(IDM_F_PRINT, TRUE),
  1109.                  MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  1110.          Parm->PrintEnabled = FALSE;
  1111.       }
  1112.       if (Parm->PrintPropertiesEnabled)
  1113.       {
  1114.          WinSendMsg(WinWindowFromID(Parm->hWndFrame, (USHORT)FID_MENU),
  1115.                  MM_SETITEMATTR,
  1116.                  MPFROM2SHORT(IDM_O_PRINTPROPERTIES, TRUE),
  1117.                  MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  1118.          Parm->PrintPropertiesEnabled = FALSE;
  1119.       }
  1120.       if (!QueuePredefined)
  1121.          *Parm->QueueName = '\0';
  1122.    }
  1123. } /* End of SetPrintItems */
  1124.  
  1125. /*************************************************************************
  1126.  * Function: StopDrawing
  1127.  *
  1128.  * Stop drawing "GPI or "METAFILE"  on request.
  1129.  *
  1130.  * Parameters: PMAIN_PARM   main parameter structure
  1131.  *
  1132.  * Result:  none
  1133.  *
  1134.  ***************************************************************************/
  1135. VOID StopDrawing(PMAIN_PARM Parm)
  1136. {
  1137. ULONG      ResetCount;
  1138.     /*
  1139.      * if not "GPI" or "METAFILE"  do nothing
  1140.      * if ((Parm->CheckedItem < 1) || (Parm->CheckedItem > 3))
  1141.      */
  1142.    if (Parm->CheckedItem < 1)
  1143.       return;
  1144.  
  1145.    if (Parm->DrawThreadID != -1)
  1146.    {
  1147.       if (Parm->hpsClient != (HPS)NULL)
  1148.          if (GpiSetStopDraw(Parm->hpsClient, (LONG)TRUE) == GPI_ERROR)
  1149.             DispError(Parm->hAB,Parm->hWndClient);
  1150.       WinRequestMutexSem(Parm->hmtxsemStoppable, (ULONG)-1);
  1151.       Parm->fStoppable = TRUE;
  1152.       DosReleaseMutexSem(Parm->hmtxsemStoppable);
  1153.       SendCommand(Parm, FLUSH_COMMAND, 0L);
  1154.       DosResetEventSem(Parm->hevsemStop, &ResetCount);
  1155.       if (SendCommand(Parm, STOP_DRAWING, 0L))
  1156.          WinWaitEventSem(Parm->hevsemStop, (ULONG)-1);
  1157.    }
  1158. } /* End of StopDrawing */
  1159.  
  1160. /*************************************************************************
  1161.  * Function: AboutDlg
  1162.  *
  1163.  * Dialog procedure for About dialog box.
  1164.  *
  1165.  * Parameters: HWND         window handle of dialog box
  1166.  *             USHORT       message
  1167.  *             MPARAM       message parameter 1
  1168.  *             MPARAM       message parameter 2
  1169.  *
  1170.  * Result:  MRESULT         message result
  1171.  *
  1172.  ***************************************************************************/
  1173. MRESULT EXPENTRY AboutDlg(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  1174. {
  1175.  
  1176.    switch (msg)
  1177.    {
  1178.    case DLG_OK:
  1179.         WinDismissDlg(hWnd, FALSE);
  1180.         break;
  1181.    default:
  1182.         return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  1183.    }
  1184.    return (MRESULT)FALSE;
  1185. } /* End of AboutDlg */
  1186.  
  1187. /**************************************************************************
  1188.  * Function: InvalidateTextRect
  1189.  *
  1190.  * Query size of information line and invalidate that rectangle.
  1191.  *
  1192.  * Parameters: HWND         window handle of client area
  1193.  *
  1194.  * Result:  none
  1195.  *
  1196.  ***************************************************************************/
  1197. static VOID InvalidateTextRect(HWND hWnd)
  1198. {
  1199.    HPS         hPS;
  1200.    FONTMETRICS ActFont;
  1201.    RECTL       Rectl;
  1202.  
  1203.    WinQueryWindowRect(hWnd, &Rectl);
  1204.    hPS = WinGetPS(hWnd);
  1205.    if (GpiQueryFontMetrics(hPS, (LONG)sizeof(FONTMETRICS), &ActFont) == GPI_ERROR)
  1206.        DispError(Parm.hAB,Parm.hWndClient);
  1207.    WinReleasePS(hPS);
  1208.  
  1209.    Rectl.yBottom = Rectl.yTop - ActFont.lMaxBaselineExt;
  1210.    WinInvalidateRect(hWnd, &Rectl, FALSE);
  1211. } /* End of InvalidateTextRect */
  1212.  
  1213. /*************************************************************************
  1214.  * Function: WndProcI
  1215.  *
  1216.  * Window procedure for information window.
  1217.  *
  1218.  * Parameters: HWND         window handle of information window
  1219.  *             USHORT       message
  1220.  *             MPARAM       message parameter 1
  1221.  *             MPARAM       message parameter 2
  1222.  *
  1223.  * Result:  MRESULT         message result
  1224.  *
  1225.  ***************************************************************************/
  1226. MRESULT EXPENTRY WndProcI(HWND hWndI, ULONG Msg, MPARAM mp1, MPARAM mp2)
  1227. {
  1228.          PMAIN_PARM Parm;
  1229.          FONTMETRICS ActFont;
  1230.          HPS        hPS;
  1231.          SWP        WinPos;
  1232.          RECTL      rInfo;
  1233.          POINTL     DrawPos;
  1234. static   PSZ        Message;
  1235.  
  1236.    if (Msg != WM_CREATE)
  1237.       Parm = WinQueryWindowPtr(hWndI, 0);
  1238.  
  1239.    switch (Msg)
  1240.    {
  1241.    case WM_CREATE:      /* Set window pointer to main parameter stucture   */
  1242.         Parm = (PMAIN_PARM)PVOIDFROMMP(mp1);
  1243.         Message = GetString(Parm->hAB, TEXT_SPOOLING_MESSAGE, ALLOC_STRING);
  1244.         WinSetWindowPtr(hWndI, 0, (PVOID)Parm);
  1245.         break;
  1246.    case ENABLE_INFO_WND:               /* show/hide information window     */
  1247.         if (Parm->InfoWnd.SizeX == 0)  /* if first call, calculate size of */
  1248.            {                           /* information window               */
  1249.            hPS = WinGetPS(hWndI);
  1250.            if (GpiQueryFontMetrics(hPS, (LONG)sizeof(FONTMETRICS), &ActFont) == GPI_ERROR)
  1251.                DispError(Parm->hAB,Parm->hWndClient);
  1252.            Parm->InfoWnd.SizeY = (LONG)ActFont.lMaxBaselineExt;
  1253.            Parm->InfoWnd.DrawLine = (LONG)ActFont.lMaxDescender;
  1254.            Parm->InfoWnd.SizeX = (LONG)12 * (LONG)ActFont.lAveCharWidth;
  1255.            WinReleasePS(hPS);
  1256.            WinSetWindowPos(hWndI,
  1257.                            (HWND)NULLHANDLE,
  1258.                            0L, 0L, Parm->InfoWnd.SizeX,
  1259.                            Parm->InfoWnd.SizeY,
  1260.                            SWP_SIZE | SWP_HIDE);
  1261.            }
  1262.         /* show/hide information window */
  1263.         Parm->InfoWnd.EnableWindow = SHORT1FROMMP(mp1);
  1264.         if (!Parm->InfoWnd.EnableWindow)
  1265.            {
  1266.            WinSetWindowPos(hWndI, (HWND)NULLHANDLE,
  1267.                            0L, 0L, 0L, 0L,
  1268.                            SWP_HIDE);
  1269.            }
  1270.         else
  1271.            {
  1272.            WinSendMsg(hWndI,
  1273.                       POS_INFO_WND,
  1274.                       MPFROMSHORT(0),
  1275.                       MPFROMSHORT(0));
  1276.            WinInvalidateRect(hWndI, (PRECTL)NULL, TRUE);
  1277.            }
  1278.         break;
  1279.    case POS_INFO_WND:                  /* reposition info window if frame */
  1280.         if (Parm->InfoWnd.EnableWindow)
  1281.         {
  1282.         WinQueryWindowPos(Parm->hWndClient, &WinPos); /* window is resized */
  1283.         WinSetWindowPos(hWndI, (HWND)HWND_TOP,
  1284.                         WinPos.cx - Parm->InfoWnd.SizeX,
  1285.                         WinPos.cy - Parm->InfoWnd.SizeY,
  1286.                         0L, 0L,
  1287.                         SWP_MOVE | SWP_SHOW);
  1288.         }
  1289.         break;
  1290.    case WM_PAINT:                            /* paint information window if*/
  1291.         if (Parm->InfoWnd.EnableWindow)      /* window is shown            */
  1292.            {
  1293.            hPS = WinBeginPaint(hWndI, 0, 0);
  1294.            WinQueryWindowRect(hWndI, &rInfo);
  1295.            WinFillRect(hPS, &rInfo, CLR_RED);
  1296.            GpiSetColor(hPS, CLR_WHITE);
  1297.            DrawPos.x = 4L;
  1298.            DrawPos.y = (LONG)Parm->InfoWnd.DrawLine;
  1299.            GpiCharStringAt(hPS, &DrawPos, strlen(Message) - 1L,
  1300.                            Message);
  1301.            WinEndPaint(hPS);
  1302.            }
  1303.         else
  1304.            return(WinDefWindowProc(hWndI, Msg, mp1, mp2));
  1305.         break;
  1306.    default:
  1307.         return(WinDefWindowProc(hWndI, Msg, mp1, mp2));
  1308.    }
  1309.    return (MRESULT)FALSE;
  1310. } /* End of WndProcI */
  1311.  
  1312. /*************************************************************************
  1313.  * Function: SetTitleBarText
  1314.  *
  1315.  * Change Text of Titlebar
  1316.  *
  1317.  * Parameters: PMAIN_PARM   Pointer to main parameter structure
  1318.  *             PSZ          filename to display
  1319.  *
  1320.  * Result:  none
  1321.  *
  1322.  ***************************************************************************/
  1323. VOID SetTitleBarText(PMAIN_PARM Parm, PSZ Filename)
  1324. {
  1325. static   CHAR       TitleBarText[80];
  1326.          PSZ        Ptr;
  1327.  
  1328.    strcpy(TitleBarText, Parm->ProgramTitle);
  1329.    if (Filename != (PSZ)NULL)
  1330.       if (*Filename == '!')
  1331.       {
  1332.          strcat(TitleBarText, " - ");
  1333.          strcat(TitleBarText, &Filename[1]);
  1334.       }
  1335.       else
  1336.          if (*Filename != '\0')
  1337.          {
  1338.             strcat(TitleBarText, " - \"");
  1339.  
  1340.          /* Set Ptr to first character after the path if possible */
  1341.             if ((Ptr = strrchr(Filename, '\\')) == NULL)
  1342.                Ptr = Filename;
  1343.             else
  1344.                Ptr++;
  1345.  
  1346.             strcat(TitleBarText, Ptr);
  1347.             strcat(TitleBarText, "\"");
  1348.          }
  1349.  
  1350. /* Set Title Bar Text */
  1351.    WinSetWindowText(WinWindowFromID(Parm->hWndFrame, FID_TITLEBAR),
  1352.                  TitleBarText);
  1353. } /* End of SetTitleBarText */
  1354.  
  1355. /**************************************************************************
  1356.  * Function: GetString
  1357.  *
  1358.  * Get String from resource file
  1359.  *
  1360.  * Parameters: HAB          Anchor block handle
  1361.  *             ULONG        ID of string
  1362.  *             BOOL         FALSE - Use static field
  1363.  *                          TRUE  - allocate space for the string
  1364.  *
  1365.  * Result:  PSZ        Pointer to the loaded string or NULL if error
  1366.  *
  1367.  ***************************************************************************/
  1368. PSZ GetString(HAB hAB, ULONG ID, BOOL Alloc)
  1369. {
  1370.    LONG       sLength;
  1371.    static PSZ Field[256];
  1372.    PSZ        Ptr;
  1373.  
  1374.    if ((sLength = WinLoadString(hAB,
  1375.                                 (HMODULE)NULLHANDLE,
  1376.                                 ID,
  1377.                                 sizeof(Field),
  1378.                                 (PSZ)Field)) == 0)
  1379.       return(NULL);
  1380.  
  1381.    if (Alloc)
  1382.    {
  1383.       Ptr = malloc(sLength + 1);
  1384.       memcpy(Ptr, Field, sLength + 1);
  1385.       return(Ptr);
  1386.    }
  1387.  
  1388.    return  (PSZ)Field ;
  1389. } /* End of GetString */
  1390.  
  1391. /**************************************************************************
  1392.  * Function: StringWithVarText
  1393.  *
  1394.  * Get String from resource file
  1395.  *
  1396.  * Parameters: HAB          Anchor block handle
  1397.  *             ULONG        ID of string
  1398.  *             PSZ          Pointer to variable text
  1399.  *             PSZ          Pointer to output buffer
  1400.  *
  1401.  * Result:  PSZ        Pointer to output buffer
  1402.  *
  1403.  ***************************************************************************/
  1404. PSZ StringWithVarText(HAB hAB, ULONG ID, PSZ VarText, PSZ Result)
  1405. {
  1406.    PSZ        Field;
  1407.    PSZ        Ptr;
  1408.  
  1409.    Field = GetString(hAB, ID, STATIC_STRING);
  1410.  
  1411.    if ((Ptr = strstr(Field, "<t>")) == NULL)
  1412.       Ptr = strstr(Field, "<T>");
  1413.  
  1414.    strcpy(Result, Field);
  1415.  
  1416.    if (Ptr != NULL)
  1417.    {
  1418.       strcpy(&Result[Ptr - Field], VarText);
  1419.       strcat(Result, &Ptr[3]);
  1420.    }
  1421.  
  1422.    return(Result);
  1423. } /* End of StringWithVarText */
  1424.  
  1425. /**************************************************************************
  1426.  * Function: TemplateOpenFilterProc
  1427.  *
  1428.  * TemplateOpenFilterProc - This is a procedure that will filter the help
  1429.  *                           messages to the open dialog.
  1430.  *
  1431.  * Parameters: HWND        window handle of information window
  1432.  *             USHORT      message
  1433.  *             MPARAM      message parameter 1
  1434.  *             MPARAM      message parameter 2
  1435.  *
  1436.  ***************************************************************************/
  1437. MRESULT EXPENTRY TemplateOpenFilterProc(HWND hwnd, ULONG message,
  1438.                                         MPARAM mp1, MPARAM mp2)
  1439. {
  1440.  
  1441.   if(message == WM_HELP)
  1442.   {
  1443.       DisplayHelpPanel(HID_FS_OPEN_DLG_HELP_PANEL);
  1444.        return FALSE ;
  1445.   }
  1446.  
  1447.    return WinDefFileDlgProc( hwnd, message, mp1, mp2 ) ;
  1448. } /* End of TemplateOpenFilterProc */
  1449.  
  1450. /**************************************************************************
  1451.  * Function: DisplayHelpPanel(idPanel)
  1452.  *
  1453.  * DisplayHelpPanel - Displays the help panel whose id is given
  1454.  *
  1455.  *  Usage:  Called whenever a help panel is desired to be
  1456.  *          displayed, usually from the WM_HELP processing
  1457.  *          of the dialog boxes
  1458.  *
  1459.  *  Method: Sends HM_DISPLAY_HELP message to the help instance
  1460.  *
  1461.  ***************************************************************************/
  1462. VOID DisplayHelpPanel(SHORT idPanel)
  1463. {
  1464.    if(WinSendMsg(Parm.hWndGRAPHICHelp,
  1465.                  HM_DISPLAY_HELP,
  1466.                  MPFROMLONG(MAKELONG(idPanel, NULL)),
  1467.                  MPFROMSHORT(HM_RESOURCEID)))
  1468.    {
  1469.       strcpy(Parm.ErrorMsg,
  1470.           GetString(Parm.hAB, ERRMSG_HELPDISPLAYERROR, STATIC_STRING));
  1471.    }
  1472.  
  1473. } /* End of DisplayHelpPanel */
  1474.  
  1475. /**************************************************************************
  1476.  * Function: DispError
  1477.  *
  1478.  *  DispError -- report an error returned from an API service.
  1479.  *
  1480.  *  Usage:  The error message is displayed using a message box
  1481.  *
  1482.  ***************************************************************************/
  1483. VOID DispErrorMsg(HAB hab, HWND hwndFrame, PCH FileName, LONG LineNum)
  1484. {
  1485.    PERRINFO  pErrInfoBlk;
  1486.    PSZ       pszOffSet, pszErrMsg;
  1487.    ERRORID   ErrorId;
  1488.    PCH       ErrorStr;
  1489.    CHAR      szbuff[125];
  1490.  
  1491.    DosBeep(800,10);
  1492.  
  1493.    if (!hab)
  1494.    {                                     /* Non-PM Error */
  1495.       WinLoadString(Parm.hAB, 0L, IDS_UNKNOWNMSG, sizeof(szbuff), (PSZ)szbuff);
  1496.       ErrorStr = malloc(strlen(szbuff)+strlen(FileName)+10);
  1497.       sprintf(ErrorStr, szbuff, FileName, LineNum);
  1498.       WinMessageBox(HWND_DESKTOP,         /* Parent window is desk top */
  1499.                    hwndFrame,            /* Owner window is our frame */
  1500.                    (PSZ)ErrorStr,        /* PMWIN Error message       */
  1501.                    "Error Message",      /* Title bar message         */
  1502.                    MSGBOXID,             /* Message identifier        */
  1503.                    MB_MOVEABLE | MB_CUACRITICAL | MB_CANCEL ); /* Flags */
  1504.       free(ErrorStr);
  1505.       return;
  1506.    }
  1507.  
  1508.    ErrorId = WinGetLastError(Parm.hAB);
  1509.  
  1510.    if ((pErrInfoBlk = WinGetErrorInfo(Parm.hAB)) != (PERRINFO)NULL)
  1511.    {
  1512.       pszOffSet = ((PSZ)pErrInfoBlk) + pErrInfoBlk->offaoffszMsg;
  1513.       pszErrMsg = ((PSZ)pErrInfoBlk) + *((PSHORT)pszOffSet);
  1514.  
  1515.       WinLoadString(Parm.hAB, 0L, IDS_ERRORMSG, sizeof(szbuff), (PSZ)szbuff);
  1516.       ErrorStr = malloc(strlen(szbuff)+strlen(pszErrMsg)+strlen(FileName)+10);
  1517.       sprintf(ErrorStr, szbuff, pszErrMsg, FileName, LineNum);
  1518.  
  1519.       WinMessageBox(HWND_DESKTOP,         /* Parent window is desktop */
  1520.                    hwndFrame,            /* Owner window is our frame */
  1521.                    (PSZ)ErrorStr,        /* PMWIN Error message       */
  1522.                    "Error Message",      /* Title bar message         */
  1523.                    MSGBOXID,             /* Message identifier        */
  1524.                    MB_MOVEABLE | MB_CUACRITICAL | MB_CANCEL ); /* Flags */
  1525.  
  1526.       free(ErrorStr);
  1527.  
  1528.       WinFreeErrorInfo(pErrInfoBlk);
  1529.    }
  1530. } /* End of DispErrorMsg */
  1531. /****************************** End of Graphic.c **************************/
  1532.