home *** CD-ROM | disk | FTP | other *** search
/ Windows Shareware GOLD / NuclearComputingVol3No1.cdr / utils / f1332 / ss.c < prev    next >
C/C++ Source or Header  |  1991-01-24  |  23KB  |  639 lines

  1. /****************************************************************************
  2. *
  3. *  FILE:          SS.C
  4. *
  5. *  DESCRIPTION:   Windows 3.0 Screen Saver Utility. This version supports
  6. *                 activation time setup via the system menu.  Activation
  7. *                 time is stored in the Win.Ini initialization file so that
  8. *                 the activation time will be restored every time this app-
  9. *                 lication is run.
  10. *
  11. *                 This software is hereby placed in the public domain.
  12. *                 Use and abuse it at your own risk!
  13. *
  14. *
  15. *  AUTHOR:        Tom Wheeler
  16. *                 31294 Morlock
  17. *                 Livonia, Mich.  48152
  18. *                 [72037,1742]
  19. *
  20. *****************************************************************************
  21. *
  22. *     DATE                                DESCRIPTION
  23. *  ----------     -----------------------------------------------------------
  24. *   10/11/90      Initial Development
  25. *   11/02/90      Better activation time control, mouse detection added
  26. *   11/08/90      Mouse capture problems resolved
  27. *   11/20/90      Improved mouse capturing functionality (not perfect yet,
  28. *                 however).
  29. *   01/24/91      Eliminated mouse capturing altogether in favor of sub-
  30. *                 classing the Active window to determine mouse activity.
  31. *
  32. ****************************************************************************/
  33.  
  34. #include <windows.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <time.h>
  39. #include "ss.h"
  40.  
  41. /********************************* CONSTANTS *******************************/
  42.  
  43. #define VERSIONID "Version 1.4"
  44. #define ONE_MINUTE (WORD)60000      /* 60 Second Timer for Activation      */
  45. #define DRAW_TIME  (WORD)3000       /*  3 Second Timer for Screen Update   */
  46. #define MOUSE_TIME (WORD)1000       /*  1 Second Mouse Capture Timer       */
  47. #define MOUSE_COUNT     5           /* Deactivation Mouse Counter          */
  48. #define DRAW_TIMER      1           /* Screen Update Timer ID              */
  49. #define ACTIVATE_TIMER  2           /* Activation Timer ID                 */
  50. #define MOUSE_TIMER     3           /* Mouse Capture Timer ID              */
  51.  
  52. /* Macro to get a random integer within a specified range */
  53. #define getrandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
  54.  
  55. /********************************* VARIABLES *******************************/
  56.  
  57. char szAppName[]     = "Screen Saver";
  58. char szChildClass[]  = "Screen Save Child";
  59. BOOL bShow           = FALSE;
  60. HANDLE hInst         = NULL;
  61. HWND hWndMain        = NULL;
  62. HWND hWndChild       = NULL;
  63. HWND hFocus          = NULL;
  64. HBITMAP hBitmap      = NULL;
  65. WORD wDrawTimer      = 0;
  66. WORD wActivateTimer  = 0;
  67. WORD wMouseTimer     = 0;
  68. WORD wTimeOut        = 1;
  69. WORD wTimeCount      = 0;
  70. int iOldX=0,iOldY    = 0;
  71. BITMAP Drawbm        = {0};
  72. RECT DrawRect        = {0};
  73. FARPROC lpfnOldProc = (FARPROC)NULL;/* subclassed window proc              */
  74. FARPROC lpfnNewProc = (FARPROC)NULL;/* subclassing window proc             */
  75.  
  76. /********************************* FUNCTIONS *******************************/
  77.  
  78. /****************************************************************************
  79. *
  80. *  void CenterWindow(HWND hWnd)
  81. *
  82. *  DESCRIPTION:   Centers a window on the screen
  83. *
  84. *  INPUT:         hWnd     - Handle to window to be centered
  85. *
  86. *  OUTPUT:        N/A
  87. *
  88. ****************************************************************************/
  89. void CenterWindow(HWND hWnd)
  90. {
  91.    int iX,iY,iNewX,iNewY;
  92.    RECT rect;
  93.  
  94.    iX = GetSystemMetrics(SM_CXSCREEN);
  95.    iY = GetSystemMetrics(SM_CYSCREEN);
  96.    GetWindowRect(hWnd,(LPRECT)&rect);
  97.    iNewX = (iX/2)-((rect.right-rect.left)/2);
  98.    iNewY = (iY/2)-((rect.bottom-rect.top)/2);
  99.    SetWindowPos(hWnd,NULL,iNewX,iNewY,rect.right-rect.left,
  100.                 rect.bottom-rect.top,SWP_NOZORDER);
  101. }
  102.  
  103. /****************************************************************************
  104. *
  105. *  BOOL FAR PASCAL AboutDlgProc(HWND hDlg,int iMessage,WORD wParam,
  106. *                               LONG lParam)
  107. *
  108. *  DESCRIPTION:   About Dialog Box Proc
  109. *
  110. *  INPUT:         hDlg - Handle to Dialog Box
  111. *                 iMessage - Dialog Box message
  112. *                 wParam
  113. *                 lParam - Standard Windows message parameters
  114. *                 Called externally from WINDOWS - Exported Function
  115. *
  116. *  OUTPUT:        N/A
  117. *
  118. ****************************************************************************/
  119. BOOL FAR PASCAL AboutDlgProc(HWND hDlg,int iMessage,WORD wParam,LONG lParam)
  120. {
  121.    char szTemp[80];
  122.  
  123.    switch (iMessage) {
  124.       case WM_COMMAND:
  125.          EndDialog(hDlg,TRUE);
  126.          /* fall through */
  127.  
  128.       case WM_INITDIALOG:
  129.          strcpy(szTemp,VERSIONID);
  130.          sprintf(szTemp,"%s  %s %s",VERSIONID,__DATE__,__TIME__);
  131.          SetDlgItemText(hDlg,IDD_PGMVERSION,(LPSTR)szTemp);
  132.          CenterWindow(hDlg);
  133.          return(TRUE);
  134.  
  135.       default:
  136.          return(FALSE);
  137.    }
  138.    return(FALSE);
  139. }
  140.  
  141. /****************************************************************************
  142. *
  143. *  BOOL FAR PASCAL TimeEditDlgProc(HWND hDlg,int iMessage,WORD wParam,
  144. *                                  LONG lParam)
  145. *
  146. *  DESCRIPTION:   Screen Save Time Edit Dialog Box Proc
  147. *
  148. *  INPUT:         hDlg - Handle to Dialog Box
  149. *                 iMessage - Dialog Box message
  150. *                 wParam
  151. *                 lParam - Standard Windows message parameters
  152. *                 Called externally from WINDOWS - Exported Function
  153. *
  154. *  OUTPUT:        N/A
  155. *
  156. ****************************************************************************/
  157. BOOL FAR PASCAL TimeEditDlgProc(HWND hDlg,int iMessage,WORD wParam,
  158.                                 LONG lParam)
  159. {
  160.    BOOL bTransFlag;
  161.    WORD wVal;
  162.    char szTime[10];
  163.  
  164.    switch (iMessage) {
  165.       case WM_COMMAND:
  166.          switch(wParam) {
  167.             case IDD_SAVE:
  168.                wVal = GetDlgItemInt(hDlg,IDD_TIMEEDIT,(BOOL FAR *)&bTransFlag,
  169.                                     FALSE);
  170.                if((!bTransFlag) || (wVal < 1)) {
  171.                   MessageBeep(0);
  172.                   sprintf(szTime,"%d",wTimeOut);
  173.                   SetDlgItemText(hDlg,IDD_TIMEEDIT,(LPSTR)szTime);
  174.                }
  175.                else {
  176.                   wTimeOut = wVal;
  177.                   sprintf(szTime,"%d",wTimeOut);
  178.                   WriteProfileString((LPSTR)"screen save",(LPSTR)"activate",
  179.                                      (LPSTR)szTime);
  180.                   EndDialog(hDlg,FALSE);
  181.                }
  182.                break;
  183.  
  184.             case IDD_CANCEL:
  185.                EndDialog(hDlg,FALSE);
  186.                break;
  187.          }
  188.          break;
  189.  
  190.       case WM_INITDIALOG:
  191.          sprintf(szTime,"%d",wTimeOut);
  192.          SetDlgItemText(hDlg,IDD_TIMEEDIT,(LPSTR)szTime);
  193.          CenterWindow(hDlg);
  194.          return(TRUE);
  195.  
  196.       default:
  197.          return(FALSE);
  198.    }
  199.    return(FALSE);
  200. }
  201.  
  202. /****************************************************************************
  203.  *
  204.  *  FUNCTION   : DrawBitmap(HDC hdc,int x,int y,HBITMAP hbm,DWORD rop)
  205.  *
  206.  *  PURPOSE    : Draws bitmap <hbm> at the specifed position in DC <hdc>
  207.  *
  208.  *  RETURNS    : Return value of BitBlt()
  209.  *
  210.  ****************************************************************************/
  211. BOOL DrawBitmap(HDC hdc,int x,int y,HBITMAP hbm,DWORD rop)
  212. {
  213.     HDC       hdcBits;
  214.     BITMAP    bm;
  215.     BOOL      f;
  216.  
  217.     if (!hdc || !hbm)
  218.         return FALSE;
  219.  
  220.     hdcBits = CreateCompatibleDC(hdc);
  221.     GetObject(hbm,sizeof(BITMAP),(LPSTR)&bm);
  222.     SelectObject(hdcBits,hbm);
  223.     f = BitBlt(hdc,x,y,bm.bmWidth,bm.bmHeight,hdcBits,0,0,rop);
  224.     DeleteDC(hdcBits);
  225.     return f;
  226. }
  227.  
  228. /****************************************************************************
  229. *
  230. *  long FAR PASCAL WndProc(HWND hWnd,int iMessage,WORD wParam,LONG lParam)
  231. *                          LONG lParam)
  232. *
  233. *  DESCRIPTION:   ScreenSave Main Window Proc
  234. *
  235. *  INPUT:         hWnd     - Handle to Window
  236. *                 iMessage - Dialog Box message
  237. *                 wParam
  238. *                 lParam   - Standard Windows message parameters
  239. *                 Called externally from WINDOWS - Exported Function
  240. *
  241. *  OUTPUT:        N/A
  242. *
  243. ****************************************************************************/
  244. long FAR PASCAL WndProc(HWND hWnd,int iMessage,WORD wParam,LONG lParam)
  245. {
  246.    FARPROC  lpfn;
  247.  
  248.    switch(iMessage) {
  249.  
  250.       case WM_SYSCOMMAND:
  251.          switch(wParam) {
  252.             case IDM_ABOUT:
  253.                lpfn = MakeProcInstance((FARPROC)AboutDlgProc,hInst);
  254.                DialogBox(hInst,"ABOUTDLGBOX",hWnd,lpfn);
  255.                FreeProcInstance(lpfn);
  256.                break;
  257.  
  258.             case IDM_SETTIME:
  259.                lpfn = MakeProcInstance((FARPROC)TimeEditDlgProc,hInst);
  260.                DialogBox(hInst,"TIMEVALINPUT",hWnd,lpfn);
  261.                FreeProcInstance(lpfn);
  262.                break;
  263.  
  264.             default:
  265.                return DefWindowProc(hWnd,iMessage,wParam,lParam);
  266.                break;
  267.          }
  268.          break;
  269.  
  270.       case WM_QUERYOPEN:
  271.          break;
  272.  
  273.       case WM_DESTROY:
  274.          if(wDrawTimer) {
  275.             KillTimer(hWndChild,DRAW_TIMER);
  276.             wDrawTimer = 0;
  277.          }
  278.          if(wActivateTimer) {
  279.             KillTimer(hWndChild,ACTIVATE_TIMER);
  280.             wActivateTimer = 0;
  281.          }
  282.          if(wMouseTimer) {
  283.             KillTimer(hWndChild,MOUSE_TIMER);
  284.             wActivateTimer = 0;
  285.             if((lpfnOldProc != (FARPROC)NULL) &&
  286.                (lpfnNewProc != (FARPROC)NULL)) {
  287.                SetWindowLong(hFocus,GWL_WNDPROC,(LONG)lpfnOldProc);
  288.                FreeProcInstance(lpfnNewProc);
  289.                lpfnOldProc = (FARPROC)NULL;
  290.                lpfnNewProc = (FARPROC)NULL;
  291.             }
  292.          }
  293.          PostQuitMessage(0);
  294.          break;
  295.  
  296.       default:
  297.          return DefWindowProc(hWnd,iMessage,wParam,lParam);
  298.          break;
  299.    }
  300.    return 0L;
  301. }
  302.  
  303. /****************************************************************************
  304. *  LONG FAR ActiveFilterProc(hWnd,iMessage,wParam,lParam)
  305. *
  306. *  Description:   Subclassing proc to filter mouse activity in the currently
  307. *                 active window.
  308. *
  309. *  Input:         hWnd - Handle to Window
  310. *                 iMessage - Dialog Box message
  311. *                 wParam
  312. *                 lParam - Standard Windows message parameters
  313. *                 Called externally from WINDOWS - Exported Function
  314. *
  315. *  Output:        Chains to subclassed proc after filtering mouse activity.
  316. *                 Posts a message to "ChildWndProc" to indicate the detection
  317. *                 of any filtered messages.
  318. ****************************************************************************/
  319. LONG FAR PASCAL ActiveFilterProc(HWND hWnd,WORD iMessage,WORD wParam,
  320.                                  LONG lParam)
  321. {
  322.    switch(iMessage) {
  323.       case WM_SETCURSOR:
  324.       case WM_NCHITTEST:
  325.          PostMessage(hWndChild,WM_HOOKKEY,0,0L);
  326.          break;
  327.    }
  328.    return CallWindowProc(lpfnOldProc,hWnd,iMessage,wParam,lParam);
  329. }
  330.  
  331. /****************************************************************************
  332. *
  333. *  long FAR PASCAL ChildWndProc(HWND hWnd,int iMessage,WORD wParam,
  334. *                               LONG lParam)
  335. *
  336. *  DESCRIPTION:   ScreenSave Child Window Proc - Responsible for most of the
  337. *                 active screen save functions
  338. *
  339. *  INPUT:         hWnd     - Handle to Window
  340. *                 iMessage - Dialog Box message
  341. *                 wParam
  342. *                 lParam   - Standard Windows message parameters
  343. *                 Called externally from WINDOWS - Exported Function
  344. *
  345. *  OUTPUT:        N/A
  346. *
  347. ****************************************************************************/
  348. long FAR PASCAL ChildWndProc(HWND hWnd,int iMessage,WORD wParam,LONG lParam)
  349. {
  350.    HDC hDC;
  351.    HWND hTest;
  352.    PAINTSTRUCT ps;
  353.    static int iMcount = MOUSE_COUNT;
  354.    static HCURSOR hCursor;
  355.  
  356.    switch(iMessage) {
  357.  
  358.       case WM_HOOKKEY:
  359.          /* This message is sent by "SSHOOK.DLL" when it detects any
  360.           * keyboard activity.  It is also sent by "ActiveFilterProc"
  361.           * when any mouse activity is detected in the currently active
  362.           * window.
  363.           */
  364.          goto Bypass;
  365.  
  366.       case WM_SETCURSOR:
  367.          if(bShow) {
  368.             /* If the screen is blanked, keep a count of mouse activity and
  369.              * only deactivate after a specified number of messages.  This
  370.              * provides a littly hysteresis for mouse activity.
  371.              */
  372.             if(iMcount) {
  373.                --iMcount;
  374.                break;
  375.             }
  376.          }
  377.          goto Bypass;
  378.  
  379.       case WM_LBUTTONDOWN:
  380.       case WM_LBUTTONUP:
  381.       case WM_RBUTTONDOWN:
  382.       case WM_RBUTTONUP:
  383.          /* process all mouse button activity */
  384.  
  385.       Bypass:
  386.  
  387.          if((wActivateTimer =
  388.              SetTimer(hWnd,ACTIVATE_TIMER,ONE_MINUTE,NULL)) == 0) {
  389.             MessageBox(hWndMain,"No More System Timers!",
  390.                        szAppName,MB_OK | MB_ICONEXCLAMATION);
  391.             PostQuitMessage(0);
  392.          }
  393.          if(bShow) {
  394.             iMcount = MOUSE_COUNT;
  395.             SetCursor(hCursor);
  396.             ShowWindow(hWndChild,SW_HIDE);
  397.             iOldX = (GetSystemMetrics(SM_CXSCREEN) - Drawbm.bmWidth) / 2;
  398.             iOldY = (GetSystemMetrics(SM_CYSCREEN) - Drawbm.bmHeight) / 2;
  399.             if(wDrawTimer) {
  400.                KillTimer(hWnd,DRAW_TIMER);
  401.                wDrawTimer = 0;
  402.                wTimeCount = 0;
  403.             }
  404.          }
  405.          bShow = FALSE;
  406.          break;
  407.  
  408.       case WM_TIMER:
  409.          switch(wParam) {
  410.             case DRAW_TIMER:
  411.                /* This timer indicates that it is time to move the icon
  412.                 * on the saved screen
  413.                 */
  414.                if(bShow) {
  415.                   hDC = GetDC(hWnd);
  416.                   DrawBitmap(hDC,iOldX,iOldY,hBitmap,BLACKNESS);
  417.                   iOldX = getrandom(0,(DrawRect.right-Drawbm.bmWidth));
  418.                   iOldY = getrandom(0,(DrawRect.bottom-Drawbm.bmHeight));
  419.                   DrawBitmap(hDC,iOldX,iOldY,hBitmap,SRCCOPY);
  420.                   ReleaseDC(hWnd,hDC);
  421.                }
  422.                break;
  423.  
  424.             case ACTIVATE_TIMER:
  425.                /* This timer indicates that the specified activation time
  426.                 * has expired.  Screen save initialization is performed and
  427.                 * the screen is blanked (ie. the child window is displayed.)
  428.                 */
  429.                if(!bShow) {
  430.                   wTimeCount++;
  431.                   if(wTimeCount == wTimeOut) {
  432.                      if((wDrawTimer =
  433.                          SetTimer(hWnd,DRAW_TIMER,DRAW_TIME,NULL)) == 0) {
  434.                         MessageBox(hWndMain,"No More System Timers!",
  435.                                    szAppName,MB_OK | MB_ICONEXCLAMATION);
  436.                         PostQuitMessage(0);
  437.                      }
  438.                      hCursor = SetCursor(NULL);
  439.                      ShowWindow(hWndChild,SW_SHOWNORMAL);
  440.                      bShow = TRUE;
  441.                   }
  442.                }
  443.                break;
  444.  
  445.             case MOUSE_TIMER:
  446.                if(wMouseTimer && !bShow) {
  447.                   /* Sub-class the active window and filter for signs of
  448.                    * mouse activity.
  449.                    */
  450.                   if((hTest = GetActiveWindow()) != NULL) {
  451.                      if(hTest != hFocus) {
  452.                         /* onlu sub-class if the active window has changed */
  453.                         if((lpfnOldProc != (FARPROC)NULL) &&
  454.                            (lpfnNewProc != (FARPROC)NULL)) {
  455.                            SetWindowLong(hFocus,GWL_WNDPROC,(LONG)lpfnOldProc);
  456.                            FreeProcInstance(lpfnNewProc);
  457.                         }
  458.                         hFocus = hTest;
  459.                         lpfnOldProc = (FARPROC)GetWindowLong(hFocus,
  460.                                                              GWL_WNDPROC);
  461.                         lpfnNewProc =
  462.                               MakeProcInstance((FARPROC)ActiveFilterProc,
  463.                                                hInst);
  464.                         if((lpfnOldProc != (FARPROC)NULL) &&
  465.                            (lpfnNewProc != (FARPROC)NULL)) {
  466.                            SetWindowLong(hFocus,GWL_WNDPROC,
  467.                                          (LONG)lpfnNewProc);
  468.                         }
  469.                      }
  470.                   }
  471.                }
  472.                break;
  473.          }
  474.          break;
  475.  
  476.       case WM_PAINT:
  477.          /* displays the screen save icon */
  478.          hDC = BeginPaint(hWnd,&ps);
  479.          DrawBitmap(hDC,iOldX,iOldY,hBitmap,SRCCOPY);
  480.          EndPaint(hWnd,&ps);
  481.          break;
  482.  
  483.       case WM_CREATE:
  484.          /* initialization code for the screen saver blanking window */
  485.          srand((unsigned)time(NULL));
  486.          if((hBitmap = LoadBitmap(hInst,"SaveScreen")) == NULL) {
  487.             MessageBox(hWndMain,"Could Not Create Bitmap!",
  488.                      szAppName,MB_OK | MB_ICONEXCLAMATION);
  489.             PostQuitMessage(0);
  490.          }
  491.          if((wActivateTimer =
  492.              SetTimer(hWnd,ACTIVATE_TIMER,ONE_MINUTE,NULL)) == 0) {
  493.             MessageBox(hWndMain,"No More System Timers!",
  494.                        szAppName,MB_OK | MB_ICONEXCLAMATION);
  495.             PostQuitMessage(0);
  496.          }
  497.          if((wMouseTimer =
  498.              SetTimer(hWnd,MOUSE_TIMER,MOUSE_TIME,NULL)) == 0) {
  499.             MessageBox(hWndMain,"No More System Timers!",
  500.                        szAppName,MB_OK | MB_ICONEXCLAMATION);
  501.             PostQuitMessage(0);
  502.          }
  503.          GetClientRect(hWnd,&DrawRect);
  504.          GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&Drawbm);
  505.          iOldX = (GetSystemMetrics(SM_CXSCREEN) - Drawbm.bmWidth) / 2;
  506.          iOldY = (GetSystemMetrics(SM_CYSCREEN) - Drawbm.bmHeight) / 2;
  507.          InitHook(hWnd);
  508.          break;
  509.  
  510.       default:
  511.          return DefWindowProc(hWnd,iMessage,wParam,lParam);
  512.          break;
  513.    }
  514.    return 0L;
  515. }
  516.  
  517. /****************************************************************************
  518. *
  519. *  int far PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  520. *                         LPSTR lpszCmdLine, int nCmdShow);
  521. *
  522. *  DESCRIPTION:   ScreenSave Main Function
  523. *
  524. *  INPUT:         N/A
  525. *
  526. *  OUTPUT:        N/A
  527. *
  528. ****************************************************************************/
  529. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  530.                    LPSTR lpszCmdLine, int nCmdShow)
  531. {
  532.    MSG      msg;
  533.    WNDCLASS wc;
  534.    HANDLE   hMenu;
  535.  
  536.    hInst = hInstance;
  537.  
  538.    if( !hPrevInstance )
  539.    {
  540.       /* client window class */
  541.  
  542.       wc.style          = CS_HREDRAW | CS_VREDRAW;
  543.       wc.lpfnWndProc    = WndProc;
  544.       wc.cbClsExtra     = 0;
  545.       wc.cbWndExtra     = 0;
  546.       wc.hInstance      = hInstance;
  547.       wc.hIcon          = LoadIcon(hInstance,"SS");
  548.       wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  549.       wc.hbrBackground  = GetStockObject(BLACK_BRUSH);
  550.       wc.lpszMenuName   = szAppName;
  551.       wc.lpszClassName  = szAppName;
  552.  
  553.       if( !RegisterClass( &wc ) )
  554.          return NULL;
  555.  
  556.       wc.style         = CS_HREDRAW | CS_VREDRAW;
  557.       wc.lpfnWndProc   = ChildWndProc;
  558.       wc.cbClsExtra    = 0;
  559.       wc.cbWndExtra    = 0;
  560.       wc.hInstance     = hInstance;
  561.       wc.hIcon         = NULL;
  562.       wc.hCursor       = NULL;
  563.       wc.hbrBackground = GetStockObject (BLACK_BRUSH);
  564.       wc.lpszMenuName  = NULL;
  565.       wc.lpszClassName = szChildClass;
  566.  
  567.       if( !RegisterClass( &wc ) )
  568.          return NULL;
  569.    }
  570.    else {
  571.       MessageBox(NULL,(LPSTR)"Can't start more than one copy of Screen Saver!",
  572.                  (LPSTR)szAppName,MB_OK | MB_ICONSTOP);
  573.       return TRUE;
  574.    }
  575.  
  576.    /* create the main appplication window */
  577.    hWndMain = CreateWindow(szAppName,           /* Window class name          */
  578.                        szAppName,           /* window caption             */
  579.                        WS_OVERLAPPEDWINDOW, /* window style               */
  580.                        CW_USEDEFAULT,       /* initial x (horiz) position */
  581.                        CW_USEDEFAULT,       /* initial y (vert) position  */
  582.                        CW_USEDEFAULT,       /* initial x size             */
  583.                        CW_USEDEFAULT,       /* initial y size             */
  584.                        NULL,                /* parent window handle       */
  585.                        NULL,                /* window menu handle         */
  586.                        hInstance,           /* program instance handle    */
  587.                        NULL);               /* create parameters          */
  588.  
  589.    /* create the child screen saver window */
  590.    hWndChild = CreateWindow(szChildClass,   /* window class name          */
  591.                        NULL,                /* window caption             */
  592.                        WS_POPUP,            /* window style               */
  593.                        0,                   /* initial x position         */
  594.                        0,                   /* initial y position         */
  595.                        GetSystemMetrics(SM_CXSCREEN), /* initial x size   */
  596.                        GetSystemMetrics(SM_CYSCREEN), /* initial y size   */
  597.                        NULL,                /* parent window handle       */
  598.                        NULL,                /* window menu handle         */
  599.                        hInstance,           /* program instance handle    */
  600.                        NULL) ;              /* create parameters          */
  601.  
  602.    /* Rearrange the system menu to suit this programs functionality */
  603.    hMenu = GetSystemMenu(hWndMain,FALSE);
  604.    DeleteMenu(hMenu,0,MF_BYPOSITION);
  605.    DeleteMenu(hMenu,1,MF_BYPOSITION);
  606.    DeleteMenu(hMenu,1,MF_BYPOSITION);
  607.    DeleteMenu(hMenu,1,MF_BYPOSITION);
  608.    AppendMenu(hMenu,MF_SEPARATOR,NULL,NULL);
  609.    AppendMenu(hMenu,MF_STRING | MF_ENABLED,IDM_SETTIME,"&Time");
  610.    AppendMenu(hMenu,MF_SEPARATOR,NULL,NULL);
  611.    AppendMenu(hMenu,MF_STRING | MF_ENABLED,IDM_ABOUT,"&About ...");
  612.  
  613.    /* Recover the saved activation time from WIN.INI.  If none, create a
  614.     * default activation time of 10 minutes.
  615.     */
  616.    wTimeOut = GetProfileInt((LPSTR)"screen save",(LPSTR)"activate",0);
  617.    if(wTimeOut == 0) {
  618.       WriteProfileString((LPSTR)"screen save",(LPSTR)"activate",(LPSTR)"10");
  619.       wTimeOut = 10;
  620.    }
  621.  
  622.    /* display the main window iconic */
  623.    ShowWindow(hWndMain,SW_SHOWMINNOACTIVE);
  624.    UpdateWindow(hWndMain);                  /* sends WM_PAINT message     */
  625.  
  626.    /* Display the screen save window as hidden.  It is unhidden only
  627.     * upon activation.
  628.     */
  629.    ShowWindow(hWndChild,SW_HIDE);           /* forces WM_CREATE message   */
  630.    UpdateWindow(hWndChild);                 /* sends WM_PAINT message     */
  631.  
  632.    while(GetMessage(&msg,NULL,NULL,NULL))
  633.    {
  634.       TranslateMessage(&msg);
  635.       DispatchMessage(&msg);
  636.    }
  637.    return msg.wParam;
  638. }
  639.