home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / src / mingw-runtime-19991107 / w32api / lib / scrnsave.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-02  |  9.9 KB  |  407 lines

  1. /*
  2.   Screen saver library by Anders Norlander <anorland@hem2.passagen.se>
  3.  
  4.   This library is (hopefully) compatible with Microsoft's
  5.   screen saver library.
  6.  
  7.   This is public domain software.
  8.  
  9.  */
  10. #include <windows.h>
  11. #include <scrnsave.h>
  12. #include <regstr.h>
  13.  
  14. /* screen saver window class */
  15. #define CLASS_SCRNSAVE TEXT("WindowsScreenSaverClass")
  16.  
  17. /* globals */
  18. HWND        hMainWindow = NULL;
  19. BOOL        fChildPreview = FALSE;
  20. HINSTANCE    hMainInstance;
  21. TCHAR        szName[TITLEBARNAMELEN];
  22. TCHAR        szAppName[APPNAMEBUFFERLEN];
  23. TCHAR        szIniFile[MAXFILELEN];
  24. TCHAR        szScreenSaver[22];
  25. TCHAR        szHelpFile[MAXFILELEN];
  26. TCHAR        szNoHelpMemory[BUFFLEN];
  27. UINT        MyHelpMessage;
  28.  
  29. /* local house keeping */
  30. static HINSTANCE hPwdLib = NULL;
  31. static POINT pt_orig;
  32. static BOOL checking_pwd = FALSE;
  33. static BOOL closing = FALSE;
  34. static BOOL w95 = FALSE;
  35.  
  36. typedef BOOL (WINAPI *VERIFYPWDPROC)(HWND);
  37. typedef DWORD (WINAPI *CHPWDPROC)(LPCTSTR, HWND, DWORD, PVOID);
  38. static VERIFYPWDPROC VerifyScreenSavePwd = NULL;
  39.  
  40. /* function names */
  41. #define szVerifyPassword "VerifyScreenSavePwd"
  42.  
  43. #ifdef UNICODE
  44. #define szPwdChangePassword "PwdChangePasswordW"
  45. #else
  46. #define szPwdChangePassword "PwdChangePasswordA"
  47. #endif
  48.  
  49. static void TerminateScreenSaver(HWND hWnd);
  50. static BOOL RegisterClasses(void);
  51. static LRESULT WINAPI SysScreenSaverProc(HWND,UINT,WPARAM,LPARAM);
  52. static int LaunchScreenSaver(HWND hParent);
  53. static void LaunchConfig(void);
  54.  
  55. static int ISSPACE(char c)
  56. {
  57.   return (c == ' ' || c == '\t');
  58. }
  59.  
  60. #define ISNUM(c) ((c) >= '0' && c <= '9')
  61. static unsigned long
  62. _toul(const char *s)
  63. {
  64.   unsigned long res;
  65.   unsigned long n;
  66.   const char *p;
  67.   for (p = s; *p; p++)
  68.     if (!ISNUM(*p)) break;
  69.   p--;
  70.   res = 0;
  71.   for (n = 1; p >= s; p--, n *= 10)
  72.     res += (*p - '0') * n;
  73.   return res;
  74. }
  75.  
  76. /* screen saver entry point */
  77. int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
  78.                      LPSTR CmdLine, int nCmdShow)
  79. {
  80.   LPSTR p;
  81.   OSVERSIONINFO vi;
  82.  
  83.   /* initialize */
  84.   hMainInstance = hInst;
  85.  
  86.   vi.dwOSVersionInfoSize = sizeof(vi);
  87.   GetVersionEx(&vi);
  88.   /* check if we are going to check for passwords */
  89.   if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  90.     {
  91.       HKEY hKey;
  92.       /* we are using windows 95 */
  93.       w95 = TRUE;
  94.       if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE ,&hKey) ==
  95.           ERROR_SUCCESS)
  96.         {
  97.           DWORD check_pwd;
  98.           DWORD size = sizeof(DWORD);
  99.           DWORD type;
  100.           LONG res;
  101.           res = RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD,
  102.                                 NULL, &type, (PBYTE) &check_pwd, &size);
  103.           if (check_pwd && res == ERROR_SUCCESS)
  104.             {
  105.               hPwdLib = LoadLibrary(TEXT("PASSWORD.CPL"));
  106.               if (hPwdLib)
  107.                 VerifyScreenSavePwd = GetProcAddress(hPwdLib, szVerifyPassword);
  108.             }
  109.           RegCloseKey(hKey);
  110.         }
  111.     }
  112.  
  113.   /* parse arguments */
  114.   for (p = CmdLine; *p; p++)
  115.     {
  116.       switch (*p)
  117.         {
  118.         case 'S':
  119.         case 's':
  120.           /* start screen saver */
  121.           return LaunchScreenSaver(NULL);
  122.           
  123.         case 'P':
  124.         case 'p':
  125.           {
  126.             /* start screen saver in preview window */
  127.             HWND hParent;
  128.             fChildPreview = TRUE;
  129.             while (ISSPACE(*++p));
  130.             hParent = (HWND) _toul(p);
  131.             if (hParent && IsWindow(hParent))
  132.               return LaunchScreenSaver(hParent);
  133.           }
  134.           return 0;
  135.  
  136.         case 'C':
  137.         case 'c':
  138.           /* display configure dialog */
  139.           LaunchConfig();
  140.           return 0;
  141.  
  142.         case 'A':
  143.         case 'a':
  144.           {
  145.             /* change screen saver password */
  146.             HWND hParent;
  147.             while (ISSPACE(*++p));
  148.             hParent = (HWND) _toul(p);
  149.             if (!hParent || !IsWindow(hParent))
  150.               hParent = GetForegroundWindow();
  151.             ScreenSaverChangePassword(hParent);
  152.           }
  153.           return 0;
  154.  
  155.         case '-':
  156.         case '/':
  157.         case ' ':
  158.         default:
  159.         }
  160.     }
  161.   LaunchConfig();
  162.   return 0;
  163. }
  164.  
  165. static void LaunchConfig(void)
  166. {
  167.   /* FIXME: should this be called */
  168.   RegisterDialogClasses(hMainInstance);
  169.   /* display configure dialog */
  170.   DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE),
  171.             GetForegroundWindow(), (DLGPROC) ScreenSaverConfigureDialog);
  172. }
  173.  
  174.  
  175. static int LaunchScreenSaver(HWND hParent)
  176. {
  177.   BOOL foo;
  178.   UINT style;
  179.   RECT rc;
  180.   MSG msg;
  181.  
  182.   /* don't allow other tasks to get into the foreground */
  183.   if (w95 && !fChildPreview)
  184.     SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &foo, 0);
  185.  
  186.   msg.wParam = 0;
  187.  
  188.   /* register classes, both user defined and classes used by screen saver
  189.      library */
  190.   if (!RegisterClasses())
  191.     {
  192.       MessageBox(NULL, TEXT("RegisterClasses() failed"), NULL, MB_ICONHAND);
  193.       goto restore;
  194.     }
  195.  
  196.   /* a slightly different approach needs to be used when displaying
  197.      in a preview window */
  198.   if (hParent)
  199.     {
  200.       style = WS_CHILD;
  201.       GetClientRect(hParent, &rc);
  202.     }
  203.   else
  204.     {
  205.       style = WS_POPUP;
  206.       rc.right = GetSystemMetrics(SM_CXSCREEN);
  207.       rc.bottom = GetSystemMetrics(SM_CYSCREEN);
  208.       style |= WS_VISIBLE;
  209.     }
  210.  
  211.   /* create main screen saver window */
  212.   hMainWindow = CreateWindowEx(hParent ? 0 : WS_EX_TOPMOST, CLASS_SCRNSAVE,
  213.                                TEXT("SCREENSAVER"), style,
  214.                                0, 0, rc.right, rc.bottom, hParent, NULL,
  215.                                hMainInstance, NULL);
  216.  
  217.   /* display window and start pumping messages */
  218.   if (hMainWindow)
  219.     {
  220.       UpdateWindow(hMainWindow);
  221.       ShowWindow(hMainWindow, SW_SHOW);
  222.  
  223.       while (GetMessage(&msg, NULL, 0, 0) == TRUE)
  224.         {
  225.           TranslateMessage(&msg);
  226.           DispatchMessage(&msg);
  227.         }
  228.     }
  229.  
  230. restore:
  231.   /* restore system */
  232.   if (w95 && !fChildPreview)
  233.     SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &foo, 0);
  234.   FreeLibrary(hPwdLib);
  235.   return msg.wParam;
  236. }
  237.  
  238. /* this function takes care of *must* do tasks, like terminating
  239.    screen saver */
  240. static LRESULT WINAPI SysScreenSaverProc(HWND hWnd, UINT msg,
  241.                                   WPARAM wParam, LPARAM lParam)
  242. {
  243.   switch (msg)
  244.     {
  245.     case WM_CREATE:
  246.       if (!fChildPreview)
  247.         SetCursor(NULL);
  248.       /* mouse is not supposed to move from this position */
  249.       GetCursorPos(&pt_orig);
  250.       break;
  251.     case WM_DESTROY:
  252.       PostQuitMessage(0);
  253.       break;
  254.     case WM_TIMER:
  255.       if (closing)
  256.         return 0;
  257.       break;
  258.     case WM_PAINT:
  259.       if (closing)
  260.         return DefWindowProc(hWnd, msg, wParam, lParam);
  261.       break;
  262.     case WM_SYSCOMMAND:
  263.       if (!fChildPreview)
  264.         switch (wParam)
  265.           {
  266.           case SC_CLOSE:
  267.           case SC_SCREENSAVE:
  268.           case SC_NEXTWINDOW:
  269.           case SC_PREVWINDOW:
  270.             return FALSE;
  271.           }
  272.       break;
  273.     case WM_MOUSEMOVE:
  274.     case WM_LBUTTONDOWN:
  275.     case WM_RBUTTONDOWN:
  276.     case WM_MBUTTONDOWN:
  277.     case WM_KEYDOWN:
  278.     case WM_SYSKEYDOWN:
  279.     case WM_NCACTIVATE:
  280.     case WM_ACTIVATE:
  281.     case WM_ACTIVATEAPP:
  282.       if (closing)
  283.         return DefWindowProc(hWnd, msg, wParam, lParam);
  284.       break;
  285.     }
  286.   return ScreenSaverProc(hWnd, msg, wParam, lParam);
  287. }
  288.  
  289. LONG WINAPI DefScreenSaverProc(HWND hWnd, UINT msg,
  290.                                WPARAM wParam, LPARAM lParam)
  291. {
  292.   /* don't do any special processing when in preview mode */
  293.   if (fChildPreview || closing)
  294.     return DefWindowProc(hWnd, msg, wParam, lParam);
  295.  
  296.   switch (msg)
  297.     {
  298.     case WM_CLOSE:
  299.       TerminateScreenSaver(hWnd);
  300.       /* do NOT pass this to DefWindowProc; it will terminate even if
  301.          an invalid password was given.
  302.        */
  303.       return 0;
  304.     case SCRM_VERIFYPW: 
  305.       /* verify password or return TRUE if password checking is turned off */
  306.       if (VerifyScreenSavePwd) 
  307.         return VerifyScreenSavePwd(hWnd);
  308.       else
  309.         return TRUE;
  310.     case WM_SETCURSOR:
  311.       if (checking_pwd)
  312.         break;
  313.       SetCursor(NULL);
  314.       return TRUE;
  315.     case WM_NCACTIVATE:
  316.     case WM_ACTIVATE:
  317.     case WM_ACTIVATEAPP:
  318.       if (wParam != FALSE)
  319.         break;
  320.     case WM_MOUSEMOVE:
  321.       {
  322.         POINT pt;
  323.         GetCursorPos(&pt);
  324.         if (pt.x == pt_orig.x && pt.y == pt_orig.y)
  325.           break;
  326.       }
  327.     case WM_LBUTTONDOWN:
  328.     case WM_RBUTTONDOWN:
  329.     case WM_MBUTTONDOWN:
  330.     case WM_KEYDOWN:
  331.     case WM_SYSKEYDOWN:
  332.       /* try to terminate screen saver */
  333.       if (!checking_pwd)
  334.         PostMessage(hWnd, WM_CLOSE, 0, 0);
  335.       break;
  336.     }
  337.   return DefWindowProc(hWnd, msg, wParam, lParam);
  338. }
  339.  
  340. static void TerminateScreenSaver(HWND hWnd)
  341. {
  342.   /* don't allow recursion */
  343.   if (checking_pwd || closing)
  344.     return;
  345.  
  346.   /* verify password */
  347.   if (VerifyScreenSavePwd)
  348.     {
  349.       checking_pwd = TRUE;
  350.       closing = SendMessage(hWnd, SCRM_VERIFYPW, 0, 0);
  351.       checking_pwd = FALSE;
  352.     }
  353.   else
  354.     closing = TRUE;
  355.  
  356.   /* are we closing? */
  357.   if (closing)
  358.     {
  359.       DestroyWindow(hWnd);
  360.     }
  361.   else
  362.     GetCursorPos(&pt_orig); /* if not: get new mouse position */
  363. }
  364.  
  365. /*
  366.   Register screen saver window class and call user
  367.   supplied hook.
  368.  */
  369. static BOOL RegisterClasses(void)
  370. {
  371.   WNDCLASS cls;
  372.   
  373.   cls.hCursor = NULL; 
  374.   cls.hIcon = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP)); 
  375.   cls.lpszMenuName = NULL;
  376.   cls.lpszClassName = CLASS_SCRNSAVE;
  377.   cls.hbrBackground = GetStockObject(BLACK_BRUSH);
  378.   cls.hInstance = hMainInstance;
  379.   cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_PARENTDC;
  380.   cls.lpfnWndProc = (WNDPROC) SysScreenSaverProc;
  381.   cls.cbWndExtra = 0;
  382.   cls.cbClsExtra = 0;
  383.   
  384.   if (!RegisterClass(&cls))
  385.     return FALSE;
  386.  
  387.   return RegisterDialogClasses(hMainInstance);
  388. }
  389.  
  390. void WINAPI ScreenSaverChangePassword(HWND hParent)
  391. {
  392.   /* load Master Password Router (MPR) */
  393.   HINSTANCE hMpr = LoadLibrary(TEXT("MPR.DLL"));
  394.   
  395.   if (hMpr)
  396.     {
  397.       CHPWDPROC ChangePassword;
  398.       ChangePassword = (CHPWDPROC) GetProcAddress(hMpr, szPwdChangePassword);
  399.  
  400.       /* change password for screen saver provider */
  401.       if (ChangePassword)
  402.         ChangePassword(TEXT("SCRSAVE"), hParent, 0, NULL);
  403.  
  404.       FreeLibrary(hMpr);
  405.     }
  406. }
  407.