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