home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / os2 / printq / helloqmt / hello.c next >
Encoding:
C/C++ Source or Header  |  1993-08-19  |  13.9 KB  |  401 lines

  1. /* hello.c: source code file for Hello queue/2 */
  2. /* Version 1.2 MT, (C) Peter Wansch, 1993      */
  3. /* created: 93-5-7                             */
  4. /* modified: 93-8-16                           */
  5.  
  6. #define INCL_PM    
  7.  
  8. #include <printq.h>
  9. #include <stdio.h>
  10. #include <stdlib.h> 
  11. #include <string.h> 
  12.  
  13. #include "hello.h"
  14.  
  15. /* global variables */
  16. HAB hab;                                     /* anchor-block handle            */
  17. HWND hwndFrame;                              /* frame window handle            */
  18. CHAR szOut[NUM_OF_LINES][LENGTH_STRING+1];   /* message strings                */
  19. BOOL fIni = TRUE;                            /* logo display flag              */
  20. LONG lMaxAscender;                           /* screen font metric information */
  21. LONG lMaxBaselineExt;                        /* screen font metric information */
  22. BOOL fPrintThreadStarted = FALSE;            /* flag to indicate if a print    */
  23.                                              /* job has been started in a      */
  24.                                              /* secondary thread               */
  25. TID tid = 0UL;                               /* thread id of print job         */
  26.     
  27. int main(VOID)
  28. {
  29.   QMSG  qmsg;                                 /* message queue handle               */
  30.   FONTMETRICS fm;                             /* default screen font metrics        */
  31.   HPS hps;                                    /* screen ps handle for retrieving fm */
  32.   ULONG flCreate = FCF_STANDARD;              /* frame creation flag                */
  33.   HWND hwndClient;                            /* client window handle               */
  34.   HMQ hmq;                                    /* queue handle (1st thread)          */
  35.   BOOL fIniQ = FALSE;
  36.  
  37.   /* register application to Presentation Manager */
  38.   hab = WinInitialize(0);
  39.   if(!hab)
  40.   {
  41.     WinAlarm(HWND_DESKTOP, WA_ERROR); 
  42.     exit(RETURN_ERROR);
  43.   }
  44.  
  45.   /* initialize PRINTQ */
  46.   if (!SpoolInitialize(hab, NULL, &fIniQ))
  47.   {
  48.     WinAlarm(HWND_DESKTOP, WA_ERROR); 
  49.     WinTerminate(hab);
  50.     exit(RETURN_ERROR);
  51.   }
  52.  
  53.   /* create message queue */
  54.   hmq = WinCreateMsgQueue( hab, 0 );
  55.   if(!hmq)
  56.   {
  57.     WinAlarm(HWND_DESKTOP, WA_ERROR); 
  58.     SpoolTerminate();
  59.     WinTerminate(hab);
  60.     exit(RETURN_ERROR);
  61.   }
  62.  
  63.   /* display timed logo */
  64.   if (!WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, (PFNWP)dpProdInfo, NULLHANDLE, DB_PRODINFO, (PBOOL)&fIni))
  65.   {
  66.     WinDestroyMsgQueue(hmq);
  67.     SpoolTerminate();
  68.     WinTerminate(hab);
  69.     exit(RETURN_ERROR);
  70.   }
  71.   fIni = FALSE;
  72.  
  73.   /* register private window class for application window */
  74.   if (!WinRegisterClass(hab,(PSZ)"Hello", wpMain, CS_SIZEREDRAW, 0))
  75.   {
  76.     WinDestroyMsgQueue(hmq);
  77.     SpoolTerminate();
  78.     WinTerminate(hab);
  79.     exit(RETURN_ERROR);
  80.   }
  81.  
  82.   /* create application window */
  83.   hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flCreate, "Hello", "Hello queue/2", 
  84.                                  WS_VISIBLE, NULLHANDLE, WD_MAIN, &hwndClient);
  85.   if (!hwndFrame)
  86.   {
  87.     WinDestroyMsgQueue(hmq);
  88.     SpoolTerminate();
  89.     WinTerminate(hab);
  90.     exit(RETURN_ERROR);
  91.   }
  92.  
  93.   /* query default screen font metrics to position strings in the application window */
  94.   hps = WinGetPS (HWND_DESKTOP);
  95.   GpiQueryFontMetrics (hps, sizeof(FONTMETRICS), &fm);
  96.   WinReleasePS(hps); 
  97.   lMaxAscender=fm.lMaxAscender;
  98.   lMaxBaselineExt=fm.lMaxBaselineExt;
  99.  
  100.   /* main message loop */
  101.   while(WinGetMsg(hab, &qmsg, (HWND)NULL, 0, 0))
  102.     WinDispatchMsg(hab, &qmsg);
  103.  
  104.   /* terminate application */
  105.   WinDestroyWindow(hwndFrame);        
  106.   WinDestroyMsgQueue(hmq);   
  107.          
  108.   /* de-register from PRINTQ and Presentation Manager */
  109.   SpoolTerminate();
  110.   WinTerminate(hab);                  
  111.   return(0);
  112. }
  113.  
  114. MRESULT EXPENTRY wpMain (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  115. {
  116.   RECTL rclUpdate, rclClient;
  117.   SHORT i;
  118.   POINTL pt;
  119.   CHAR szJobInfo[128];
  120.  
  121.   switch( msg )
  122.   {
  123.     case WM_CREATE:
  124.       InitOut();
  125.       return (MRESULT)FALSE;
  126.  
  127.     case WM_ERASEBACKGROUND:
  128.       return (MRESULT)TRUE;
  129.  
  130.     case WM_INITMENU:
  131.       /* disable Print and Printer setup menu items while there is a print job */
  132.       WinEnableMenuItem (HWNDFROMMP(mp2), MI_SETUP, !fPrintThreadStarted);
  133.       WinEnableMenuItem (HWNDFROMMP(mp2), MI_PRINT, !fPrintThreadStarted);
  134.       /* enable Abort print job after the job has been started */
  135.       /* a job is started when SpoolBeginSpool has been called */
  136.       WinEnableMenuItem (HWNDFROMMP(mp2), MI_ABORT, SpoolIsJobStarted());
  137.       return (MRESULT)(0);
  138.  
  139.     case WMP_JOB_DONE:
  140.       /* print job has ended */
  141.       fPrintThreadStarted = FALSE;
  142.  
  143.       /* give the user information about the print job */
  144.       if (LONGFROMMP(mp2))
  145.         sprintf(szJobInfo, "Print job with id %ld has been spooled.", LONGFROMMP(mp1));
  146.       else
  147.         sprintf(szJobInfo, "Print job has been aborted.");
  148.       WinMessageBox(HWND_DESKTOP, hwnd, szJobInfo,
  149.                     (PCH) "Hello/2", ID_MESSAGEBOX, MB_OK | MB_APPLMODAL | MB_MOVEABLE | MB_INFORMATION);
  150.  
  151.       /* restore old window title */
  152.       WinSetWindowText(hwndFrame, (PSZ)"Hello queue/2");
  153.       break;
  154.  
  155.     case WM_COMMAND:
  156.       switch (SHORT1FROMMP(mp1))
  157.       {
  158.         case MI_SETUP:
  159.           /* display Printer setup dialog box */
  160.           WinDlgBox(HWND_DESKTOP, hwnd, dpQueryQInfo, (HMODULE)0, DB_QUERYPRINT, NULL);
  161.           InitOut();
  162.           WinInvalidateRegion(hwnd, NULLHANDLE, FALSE);
  163.           SpoolEndSetup();
  164.           break;
  165.  
  166.         case MI_ABORT:
  167.           /* abort current print job */
  168.           if (!SpoolAbortSpool())
  169.             WinMessageBox(HWND_DESKTOP, hwnd, "Unable to abort print job.",
  170.                               (PCH) "Hello/2", ID_MESSAGEBOX, MB_OK | MB_APPLMODAL | MB_MOVEABLE | MB_ERROR);
  171.           break;
  172.  
  173.         case MI_PRINT:
  174.           /* print text displayed in the application window */
  175.           /* create print thread */
  176.           fPrintThreadStarted = TRUE;
  177.           if (DosCreateThread(&tid, PrintInfo, 0L, 0L, STACK_SIZE) != 0)
  178.           {
  179.             WinMessageBox(HWND_DESKTOP, hwnd, "Unable to create print thread.",
  180.                               (PCH) "Hello/2", ID_MESSAGEBOX, MB_OK | MB_APPLMODAL | MB_MOVEABLE | MB_ERROR);
  181.             fPrintThreadStarted = FALSE;
  182.           }
  183.           else
  184.             /* print thread was successfully created */
  185.             WinSetWindowText(hwndFrame, (PSZ)"Printing in secondary thread is in progress...");
  186.           break;
  187.  
  188.         case MI_INFO:
  189.           /* display product information dialog box */
  190.           WinDlgBox( HWND_DESKTOP, hwndFrame, (PFNWP)dpProdInfo, (HMODULE)0, DB_PRODINFO, (PBOOL)&fIni);           /* initialization data          */
  191.           break;
  192.  
  193.         default:
  194.           return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  195.       }
  196.       break;
  197.  
  198.       case WM_PAINT:
  199.       {
  200.         HPS hps;
  201.         /* paint client window */
  202.         /* begin drawing */
  203.         hps = WinBeginPaint( hwnd, (HPS)NULL, &rclUpdate);
  204.  
  205.         /* paint invalid rectangle first */
  206.         WinFillRect (hps, &rclUpdate, SYSCLR_WINDOW);
  207.  
  208.         /* draw lines */
  209.         WinQueryWindowRect(hwnd, &rclClient);
  210.         pt.x = 0; pt.y = rclClient.yTop-lMaxAscender;
  211.         for (i=0; i < NUM_OF_LINES; i++)
  212.         {
  213.           GpiCharStringAt(hps, &pt, (LONG)strlen(szOut[i]), (PSZ)szOut[i]);
  214.           pt.y-=lMaxBaselineExt;
  215.         }
  216.  
  217.       WinEndPaint(hps);               /* drawing is complete */
  218.       }
  219.       break;
  220.       
  221.     case WM_CLOSE:
  222.       WinPostMsg( hwnd, WM_QUIT, NULL, NULL);     /* cause termination */
  223.       break;
  224.     
  225.     case WM_DESTROY:
  226.       /* if a job has been started it is aborted */
  227.       if (SpoolIsJobStarted())
  228.         SpoolAbortSpool();
  229.       /* we have to wait until the print thread terminates (if there is one) */
  230.       DosWaitThread(&tid, DCWW_WAIT);
  231.       break;
  232.  
  233.     default:
  234.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  235.   }
  236.   return (MRESULT) FALSE;
  237. }
  238.  
  239. MRESULT EXPENTRY dpQueryQInfo( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 )
  240. {
  241.   static BOOL fVisitedJobProp;
  242.   HWND hwndListBox;
  243.  
  244.   switch (msg)
  245.   {
  246.     case WM_INITDLG:
  247.       fVisitedJobProp = FALSE;
  248.       hwndListBox = WinWindowFromID(hwndDlg, LB_QUEUES);
  249.       /* fill list box and select default printer */
  250.       SpoolBeginSetup(hwndListBox);
  251.       break;
  252.  
  253.     case WM_CONTROL:
  254.       /* list box item is double-clicked */
  255.       if (SHORT2FROMMP(mp1) == LN_ENTER && SHORT1FROMMP(mp1) == LB_QUEUES)
  256.         WinPostMsg(hwndDlg, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), NULL);
  257.       break;
  258.      
  259.     case WM_COMMAND:                    /* posted by push button or key */
  260.       switch(SHORT1FROMMP(mp1))       /* extract the command value */
  261.       {
  262.         case PB_JOBPROP:
  263.           /* Job properties button has been chosen, display Jop properties dialog box */
  264.           if (!SpoolJobProp())
  265.             WinAlarm(HWND_DESKTOP, WA_ERROR);
  266.           fVisitedJobProp = TRUE;
  267.           break;
  268.         case DID_OK:            /* the OK push button or key */
  269.           /* set the currently hilited printer the default */
  270.           SpoolSetDef();
  271.           /* close dialog */
  272.           WinDismissDlg(hwndDlg, TRUE);
  273.           break;
  274.         case DID_CANCEL:        /* the Cancel pushbutton or Escape key */
  275.           WinDismissDlg(hwndDlg, fVisitedJobProp ? TRUE : FALSE);   /* removes the dialog window */
  276.           break;
  277.         default:
  278.           break;
  279.       }
  280.       break;
  281.     default:
  282.       return WinDefDlgProc( hwndDlg, msg, mp1, mp2 );
  283.   }
  284.   return (MRESULT) FALSE;
  285. }
  286.  
  287. MRESULT EXPENTRY dpProdInfo(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  288. {
  289.   LONG lLogoDisplayTime;
  290.   ULONG ulTimerId;
  291.  
  292.   switch(msg)
  293.   {
  294.     case WM_INITDLG:
  295.       if (*((PBOOL)mp2))  
  296.       {
  297.         lLogoDisplayTime = PrfQueryProfileInt(HINI_USERPROFILE, "PM_ControlPanel", "LogoDisplayTime", -1L);
  298.         switch(lLogoDisplayTime)
  299.         {  
  300.           case 0: WinDismissDlg(hwnd, TRUE); break; /* logo is not displayed */
  301.           case -1: break; /* indefinite logo display */
  302.           default: ulTimerId = WinStartTimer(hab, hwnd, TI_LOGO, lLogoDisplayTime); break;
  303.         }
  304.       }
  305.       break;
  306.  
  307.     case WM_TIMER:
  308.       if (SHORT1FROMMP(mp1) == TI_LOGO)
  309.         WinPostMsg(hwnd, WM_COMMAND, NULL, NULL);
  310.       break;
  311.  
  312.     case WM_COMMAND:
  313.       /* OK has been pressed or timer messages has arrived */
  314.       WinStopTimer(hab, hwnd, ulTimerId);
  315.       WinDismissDlg(hwnd, TRUE);
  316.       break;
  317.  
  318.     default:
  319.       return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  320.   }
  321.   return (MRESULT)0;
  322. }
  323.  
  324. void InitOut(void)
  325. {
  326.   sprintf(szOut[0], "Queue information:");
  327.   sprintf(szOut[1], "  Queue name: %s", prqInfoDef.pszName);
  328.   sprintf(szOut[2], "  Default queue processor: %s", prqInfoDef.pszPrProc);
  329.   sprintf(szOut[3], "  Queue description: %s", prqInfoDef.pszComment);
  330.   sprintf(szOut[4], "  Default device driver: %s", prqInfoDef.pszDriverName);
  331.   sprintf(szOut[5], "  Print devices connected to queue: %s", prqInfoDef.pszPrinters);
  332.   sprintf(szOut[6], "");
  333.   sprintf(szOut[7], "Default form description: ");
  334.   sprintf(szOut[8], "  Form name: %s", hcInfoDef.szFormname);
  335.   sprintf(szOut[9], "  Width (left-to-right): %ld milimeters", hcInfoDef.cx);
  336.   sprintf(szOut[10], "  Height (top-to-bottom): %ld milimeters", hcInfoDef.cy);
  337.   sprintf(szOut[11], "  Number of pels between left and right clip limits: %ld", hcInfoDef.xPels);
  338.   sprintf(szOut[12], "  Number of pels between bottom and top clip limits: %ld", hcInfoDef.yPels);
  339.   sprintf(szOut[13], "");  
  340.   sprintf(szOut[14], "Device capabilities: ");
  341.   sprintf(szOut[15], "  Media width: %ld pels", alCaps[CAPS_WIDTH]);
  342.   sprintf(szOut[16], "  Media height: %ld pels", alCaps[CAPS_HEIGHT]);
  343.   sprintf(szOut[17], "  Media width: %ld chars", alCaps[CAPS_WIDTH_IN_CHARS]);
  344.   sprintf(szOut[18], "  Media height: %ld chars", alCaps[CAPS_HEIGHT_IN_CHARS]);
  345.   sprintf(szOut[19], "  Char height: %ld pels", alCaps[CAPS_CHAR_HEIGHT]);
  346.   sprintf(szOut[20], "  Number of device specific fonts: %ld", alCaps[CAPS_DEVICE_FONTS]);
  347.   sprintf(szOut[21], "  Number of distinct colors available on the device: %ld", alCaps[CAPS_PHYS_COLORS]);
  348.   sprintf(szOut[22], "  Horizontal resolution: %ld dpi", alCaps[CAPS_HORIZONTAL_FONT_RES]);
  349.   sprintf(szOut[23], "  Vertical resolution: %ld dpi", alCaps[CAPS_VERTICAL_FONT_RES]);
  350. }
  351.  
  352. void PrintInfo(ULONG ulParam)
  353. {
  354.   HPS hpsPrn;
  355.   FONTMETRICS fm;
  356.   LONG lprnMaxAscender, lprnMaxBaselineExt;
  357.   SHORT i;
  358.   POINTL pt;
  359.   USHORT usJobId = 0;
  360.  
  361.   /* begin a print job and obtain a handle to the printer presentation space */
  362.   SpoolBeginSpool("Printer Capabilities", "Printer Caps", "COP=1", 0UL, &hpsPrn, FALSE);
  363.  
  364.   /* obtain necessary font metrics of the selected font */
  365.   GpiQueryFontMetrics (hpsPrn, sizeof(FONTMETRICS), &fm);
  366.   lprnMaxAscender=fm.lMaxAscender;
  367.   lprnMaxBaselineExt=fm.lMaxBaselineExt;
  368.  
  369.   /* print lines */
  370.   pt.x = 0; pt.y = hcInfoDef.yPels-lprnMaxAscender;
  371.   for (i=0; i < NUM_OF_LINES; i++)
  372.   {
  373.     /* has the job been aborted from the primary thread? */
  374.     if (!SpoolIsJobStarted())
  375.     {
  376.       /* job has been aborted, so we quit as well */
  377.       while (!WinPostMsg(hwndFrame, WMP_JOB_DONE, MPFROMLONG(usJobId), MPFROMLONG(FALSE)))
  378.         DosSleep(BACKOFF_TIME);
  379.       DosExit(EXIT_THREAD, 0UL);
  380.     }
  381.     /* form feed */
  382.     if (i%alCaps[CAPS_HEIGHT_IN_CHARS]==0 && i>0)
  383.     {
  384.       SpoolNewFrame();
  385.       pt.y = hcInfoDef.yPels-lprnMaxAscender;
  386.     }
  387.     GpiCharStringAt(hpsPrn, &pt, (LONG)strlen(szOut[i]), (PSZ)szOut[i]);
  388.     pt.y-=lprnMaxBaselineExt;
  389.     /* nap attack after spooling one line */
  390.     DosSleep (1000UL);
  391.   }
  392.   /* end print job */
  393.   SpoolEndSpool(&usJobId);
  394.   /* make sure that the Job done message is successfully posted */
  395.   /* mp1 contains the job id */
  396.   /* mp2 contains an indicator if the job was successful */
  397.   while (!WinPostMsg(hwndFrame, WMP_JOB_DONE, MPFROMLONG(usJobId), MPFROMLONG(TRUE)))
  398.     DosSleep(BACKOFF_TIME);
  399. }
  400.  
  401.