home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / S12678.ZIP / HELLO.C < prev    next >
C/C++ Source or Header  |  1990-08-22  |  7KB  |  244 lines

  1. /*
  2.     NoClose - An example to show how to write a 1.21 application that
  3.           can't ever be closed except by a system shutdown. The is useful
  4.           for controlling shells, etc.
  5.  
  6.     This sample shows how to make an unkillable 1.21 application
  7.     similar to the way the Print Manager is implemented. This is guaranteed
  8.     to work in OS/2 1.21, but it uses undocumented features which may change
  9.     in future versions.
  10.  
  11.  
  12.     Ed Mills
  13.     Microsoft
  14.     August 1990
  15.     */
  16.  
  17. #define INCL_BASE
  18. #define INCL_PM
  19. #include <os2.h>
  20. #include <string.h>
  21. #include "hello.h"
  22.  
  23. HAB     hAB;
  24. HMQ     hmqHello;
  25. HWND    hwndHello;
  26. HWND    hwndHelloFrame;
  27.  
  28. CHAR    szClassName[] = "Hello";
  29. CHAR    szMessage[]   = "Hello World";
  30.  
  31. VOID PASCAL FAR SignalHandler(USHORT, USHORT);
  32.  
  33.  
  34. /***************************** Private Function ****************************\
  35. *
  36. * Hello World Main procedure
  37. *
  38. * Effects: Set globals   - hAB        Handle to Application Anchor Block
  39. *                        - hmqHello   Handle to application window msg     queue
  40. *
  41. * Warnings: None
  42. *
  43. \***************************************************************************/
  44.  
  45. int cdecl main( )
  46. {
  47.     QMSG    qmsg;
  48.     ULONG    ctldata;
  49.     HWND    hWndSysMenu;
  50.     HWND    hWndSysSubMenu;
  51.     MENUITEM    miSysMenu;
  52.     SHORT    idSysMenu;
  53.     USHORT    iSepPos, iSepID;
  54.     HWND far *    pShellWindow;         /* Exported by OS2SM.DLL */
  55.     USHORT    pid, tid;
  56.     SWCNTRL    sw;
  57.     HMODULE    hmod;
  58.  
  59.  
  60.     /* Set a signal handler to trap SIG_KILLPROCESS so that we can't
  61.        be killed when the user hits a CTRL-C or CTRL-BREAK from a
  62.        windowed command shell, or kills our parent, etc.
  63.  
  64.        By not specifying SIGA_ACKNOWLEDGE, we prevent the signal from
  65.        occuring a second time.
  66.        */
  67.     if (DosSetSigHandler(SignalHandler, NULL, NULL,
  68.              SIGA_ACCEPT, SIG_KILLPROCESS)) {
  69.     DosBeep(1000, 200);
  70.     return(1);
  71.     }
  72.  
  73.     hAB = WinInitialize(NULL);
  74.  
  75.     hmqHello = WinCreateMsgQueue(hAB, 0);
  76.  
  77.     /* Don't allow the task manager to shut this queue down. */
  78.     WinCancelShutdown(hmqHello, TRUE );
  79.  
  80.  
  81.     if (!WinRegisterClass( hAB,
  82.                            (PCH)szClassName,
  83.                            (PFNWP)HelloWndProc,
  84.                            CS_SYNCPAINT | CS_SIZEREDRAW,
  85.                            0))
  86.         return( 0 );
  87.  
  88.     ctldata = FCF_STANDARD & ~FCF_MENU & ~FCF_ACCELTABLE & ~FCF_TASKLIST;
  89.  
  90.     hwndHelloFrame = WinCreateStdWindow( HWND_DESKTOP,
  91.                      0L,
  92.                        &ctldata,
  93.                                          (PCH)szClassName,
  94.                      "Unkillable Application",
  95.                                          0L,
  96.                                          (HMODULE)NULL,
  97.                                          HELLOICON,
  98.                                          (HWND FAR *)&hwndHello );
  99.  
  100.     /* Get handle of the [-] System Menu */
  101.     hWndSysMenu = WinWindowFromID (hwndHelloFrame, FID_SYSMENU);
  102.  
  103.     /* Get the id of the zeroth item of the system menu */
  104.     idSysMenu = (SHORT) WinSendMsg (hWndSysMenu,
  105.                     MM_ITEMIDFROMPOSITION, 0L, 0L);
  106.  
  107.     /* Get the MENUITEM structure for the system menu */
  108.     WinSendMsg (hWndSysMenu,
  109.         MM_QUERYITEM,
  110.         (MPARAM)MAKEULONG (idSysMenu, FALSE),
  111.         (MPARAM)(PMENUITEM)&miSysMenu);
  112.  
  113.     /* Get handle of the system sub menu */
  114.     hWndSysSubMenu = miSysMenu.hwndSubMenu;
  115.  
  116.     /* Remove the close seperator. */
  117.     iSepPos = (USHORT)WinSendMsg(hWndSysSubMenu,
  118.                  MM_ITEMPOSITIONFROMID,
  119.                  MPFROM2SHORT((USHORT)SC_CLOSE, (BOOL)FALSE),
  120.                  0L) - 1;
  121.     iSepID = (USHORT)WinSendMsg(hWndSysSubMenu,
  122.                 MM_ITEMIDFROMPOSITION,
  123.                 MPFROMSHORT((SHORT)iSepPos),
  124.                 0L);
  125.     WinSendMsg(hWndSysSubMenu,
  126.            MM_REMOVEITEM,
  127.            MPFROM2SHORT((USHORT)iSepID, (BOOL)FALSE),
  128.            0L);
  129.  
  130.     /* Remove the sysmenu close. */
  131.     WinSendMsg(hWndSysSubMenu,
  132.            MM_REMOVEITEM,
  133.            MPFROM2SHORT((USHORT) SC_CLOSE, (BOOL)FALSE),
  134.            0L);
  135.  
  136.  
  137.     /* Open it iconic. */
  138.     WinSetWindowPos(hwndHelloFrame, HWND_TOP, 0, 0, 0, 0,
  139.             SWP_MINIMIZE | SWP_SHOW);
  140.  
  141.  
  142.     /* Now add the unkillable switch list entry for this application.
  143.        Note that this works but uses all sorts of undocumented stuff
  144.        which may change in the future.
  145.        We probably also want to use a system semaphore or such to
  146.        prevent more than one of these from running at a time.
  147.        */
  148.  
  149.     /* Get the handle to the shell. */
  150.     DosLoadModule(NULL, 0, "OS2SM", &hmod);
  151.     DosGetProcAddr(hmod, "SHELLWINDOW", &pShellWindow);
  152.     DosFreeModule(hmod);
  153.  
  154.     WinQueryWindowProcess(hwndHelloFrame, &pid, &tid);
  155.  
  156.     strcpy(sw.szSwtitle, "Unkillable");
  157.     sw.hwnd         = hwndHelloFrame;
  158.     sw.hwndIcon      = (ULONG)NULL;
  159.     sw.hprog         = (ULONG)NULL;
  160.     sw.idProcess     = pid;
  161.     sw.idSession     = (USHORT)0;
  162.     sw.uchVisibility = SWL_VISIBLE;
  163.     sw.fbJump        = SWL_JUMPABLE;
  164.  
  165. #define SH_SWITCHLIST        0x0080
  166. #define SWL_NOTERMINATE     4
  167.  
  168.     /* Add us to the list. */
  169.     WinPostMsg(*pShellWindow, SH_SWITCHLIST, (MPARAM)SWL_NOTERMINATE,
  170.             (MPARAM)WinAddSwitchEntry(&sw));
  171.  
  172.  
  173.     /* Poll messages from event queue */
  174.     while (WinGetMsg( hAB, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
  175.     WinDispatchMsg( hAB, (PQMSG)&qmsg );
  176.  
  177.  
  178.     WinDestroyWindow( hwndHelloFrame );
  179.     WinDestroyMsgQueue( hmqHello );
  180.     WinTerminate( hAB );
  181. }
  182.  
  183.  
  184.  
  185. /***************************** Private Function ****************************\
  186. *
  187. * Procedure which processes window messages
  188. *
  189. * Effects: None
  190. *
  191. * Warnings: None
  192. *
  193. \***************************************************************************/
  194.  
  195. MRESULT EXPENTRY _loadds HelloWndProc( hWnd, msg, mp1, mp2 )
  196. HWND   hWnd;
  197. USHORT msg;
  198. MPARAM mp1;
  199. MPARAM mp2;
  200. {
  201.     HPS    hPS;
  202.     POINTL pt;
  203.     CHARBUNDLE cb;
  204.  
  205.     switch (msg)
  206.     {
  207.     case WM_CLOSE:
  208.         WinPostMsg( hWnd, WM_QUIT, 0L, 0L );
  209.         break;
  210.  
  211.     case WM_PAINT:
  212.         hPS = WinBeginPaint( hWnd, (HPS)NULL, (PWRECT)NULL );
  213.         pt.x = pt.y = 0L;
  214.         cb.lColor = CLR_BLACK;
  215.         GpiSetAttrs(hPS, PRIM_CHAR, CBB_COLOR, 0L, (PBUNDLE)&cb);
  216.  
  217.         GpiCharStringAt( hPS, (PPOINTL)&pt, (LONG)sizeof(szMessage)-1,
  218.                         (PCH)szMessage );
  219.         WinEndPaint( hPS );
  220.         break;
  221.  
  222.     case WM_ERASEBACKGROUND:
  223.         return( TRUE );
  224.         break;
  225.  
  226.     default:
  227.         return( WinDefWindowProc( hWnd, msg, mp1, mp2 ) );
  228.         break;
  229.     }
  230.     return(0L);
  231. }
  232.  
  233.  
  234. VOID PASCAL FAR SignalHandler(usSigArg, usSigNum)
  235. USHORT usSigArg;    /* furnished by DosFlagProcess if appropriate */
  236. USHORT usSigNum;    /* signal number being processed              */
  237. {
  238.     /* We just ignore the signal. */
  239.     return;
  240.  
  241. usSigArg;   /* These are just to shut up the compiler. */
  242. usSigNum;
  243. }
  244.