backprev.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 11k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*  BACKPREV.C
  2. **
  3. **  Copyright (C) Microsoft, 1993, All Rights Reserved.
  4. **
  5. **  window class to display a preview of the screen background,
  6. **  complete with rudimentary palette handling and stretching
  7. **  of bitmaps to fit the preview screen.
  8. **
  9. **  this can be replaced with a static bitmap control only
  10. **  if palettes can also be handled by the control.
  11. **
  12. */
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #define GWW_INFO        0
  16. #define CXYDESKPATTERN 8
  17. BOOL g_bInfoSet = FALSE;
  18. HBITMAP g_hbmPreview = NULL;    // the bitmap used for previewing
  19. HBITMAP  g_hbmWall = NULL;      // bitmap image of wallpaper
  20. HDC      g_hdcWall = NULL;      // memory DC with g_hbmWall selected
  21. HPALETTE g_hpalWall = NULL;     // palette that goes with hbmWall bitmap
  22. HBRUSH   g_hbrBack = NULL;      // brush for the desktop background
  23. //extern HPALETTE WINAPI CreateHalftonePalette(HDC hdc);
  24. /*-------------------------------------------------------------
  25. ** given a pattern string from an ini file, return the pattern
  26. ** in a binary (ie useful) form.
  27. **-------------------------------------------------------------*/
  28. void FAR PASCAL ReadPattern(LPTSTR lpStr, WORD FAR *patbits)
  29. {
  30.   short i, val;
  31.   /* Get eight groups of numbers seprated by non-numeric characters. */
  32.   for (i = 0; i < CXYDESKPATTERN; i++)
  33.     {
  34.       val = 0;
  35.       if (*lpStr != TEXT(''))
  36.         {
  37.           /* Skip over any non-numeric characters. */
  38.           while (!(*lpStr >= TEXT('0') && *lpStr <= TEXT('9')))
  39.               lpStr++;
  40.           /* Get the next series of digits. */
  41.           while (*lpStr >= TEXT('0') && *lpStr <= TEXT('9'))
  42.               val = val*10 + *lpStr++ - TEXT('0');
  43.          }
  44.       patbits[i] = val;
  45.     }
  46.   return;
  47. }
  48. /*----------------------------------------------------------------------------*
  49. *----------------------------------------------------------------------------*/
  50. HPALETTE PaletteFromDS(HDC hdc)
  51. {
  52.     DWORD adw[257];
  53.     int i,n;
  54.     n = GetDIBColorTable(hdc, 0, 256, (LPRGBQUAD)&adw[1]);
  55.     adw[0] = MAKELONG(0x300, n);
  56.     for (i=1; i<=n; i++)
  57.         adw[i] = RGB(GetBValue(adw[i]),GetGValue(adw[i]),GetRValue(adw[i]));
  58.     if (n == 0)
  59.         return NULL;
  60.     else
  61.         return CreatePalette((LPLOGPALETTE)&adw[0]);
  62. }
  63. /*--------------------------------------------------------------------
  64. ** Build the preview bitmap.
  65. **
  66. ** both the pattern and the bitmap are drawn each time, but
  67. ** if the flags dictate the need, new pattern and bitmap
  68. ** globals are built as needed.
  69. **--------------------------------------------------------------------*/
  70. void NEAR PASCAL BuildPreviewBitmap(HWND hwnd, WPARAM flags)
  71. {
  72.     HBRUSH hbr = NULL;
  73.     HBITMAP hbmTemp;
  74.     HBITMAP hbmOld;
  75.     BITMAP bm;
  76.     TCHAR szBuf[MAX_PATH];
  77.     COLORREF clrOldBk, clrOldText;
  78.     WORD patbits[CXYDESKPATTERN] = {0, 0, 0, 0, 0, 0, 0, 0};
  79.     int     i;
  80.     HCURSOR hcurOld = NULL;
  81.     int     dxWall;          // size of wallpaper
  82.     int     dyWall;
  83.     if( flags & BP_REINIT )
  84.     {
  85.         if( g_hbmPreview )
  86.             DeleteObject( g_hbmPreview );
  87.         g_hbmPreview = LoadMonitorBitmap( TRUE );
  88.     }
  89.     hbmOld = SelectObject(g_hdcMem, g_hbmPreview);
  90.     /*
  91.     ** first, fill in the pattern all over the bitmap
  92.     */
  93.     if (flags & BP_NEWPAT)
  94.     {
  95.         // get rid of old brush if there was one
  96.         if (g_hbrBack)
  97.             DeleteObject(g_hbrBack);
  98.         if (*g_szCurPattern && lstrcmpi(g_szCurPattern, g_szNone))
  99.         {
  100.             if (GetPrivateProfileString(g_szPatterns, g_szCurPattern, g_szNULL,
  101.                                         szBuf, ARRAYSIZE(szBuf), g_szControlIni))
  102.             {
  103.                 ReadPattern(szBuf, patbits);    
  104.             }
  105.             hbmTemp = CreateBitmap(8, 8, 1, 1, patbits);
  106.             if (hbmTemp)
  107.             {
  108.                 g_hbrBack = CreatePatternBrush(hbmTemp);
  109.                 DeleteObject(hbmTemp);
  110.             }
  111.         }
  112.         else
  113.         {
  114.             g_hbrBack = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));
  115.         }
  116.         if (!g_hbrBack)
  117.             g_hbrBack = GetStockObject(BLACK_BRUSH);
  118.     }
  119.     clrOldText = SetTextColor(g_hdcMem, GetSysColor(COLOR_BACKGROUND));
  120.     clrOldBk = SetBkColor(g_hdcMem, GetSysColor(COLOR_WINDOWTEXT));
  121.     hbr = SelectObject(g_hdcMem, g_hbrBack);
  122.     PatBlt(g_hdcMem, MON_X, MON_Y, MON_DX, MON_DY, PATCOPY);
  123.     SelectObject(g_hdcMem, hbr);
  124.     SetTextColor(g_hdcMem, clrOldText);
  125.     SetBkColor(g_hdcMem, clrOldBk);
  126.     /*
  127.     ** now, position the wallpaper appropriately
  128.     */
  129.     if (flags & BP_NEWWALL)
  130.     {
  131.         g_bValidBitmap = TRUE;  // assume the new one is valid
  132.         if (g_hbmWall)
  133.         {
  134.             SelectObject(g_hdcWall, g_hbmDefault);
  135.             DeleteObject(g_hbmWall);
  136.             g_hbmWall = NULL;
  137.             if (g_hpalWall)
  138.             {
  139.                 DeleteObject(g_hpalWall);
  140.                 g_hpalWall = NULL;
  141.             }
  142.         }
  143.         if (!*g_szCurWallpaper || !lstrcmpi(g_szCurWallpaper, g_szNone))
  144.             goto DonePreview;
  145.         g_hbmWall = LoadImage(NULL, g_szCurWallpaper, IMAGE_BITMAP, 0, 0,
  146.             LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  147.         if (!g_hbmWall)
  148.         {
  149.             g_bValidBitmap = FALSE;  // until we know it's not
  150.             goto DonePreview;
  151.         }
  152.         SelectObject(g_hdcWall, g_hbmWall); // bitmap stays in this DC
  153.         GetObject(g_hbmWall, sizeof(bm), &bm);
  154.         if (GetDeviceCaps(g_hdcMem, RASTERCAPS) & RC_PALETTE)
  155.         {
  156.             if (bm.bmBitsPixel * bm.bmPlanes > 8)
  157.                 g_hpalWall = CreateHalftonePalette(g_hdcMem);
  158.             else if (bm.bmBitsPixel * bm.bmPlanes == 8)
  159.                 g_hpalWall = PaletteFromDS(g_hdcWall);
  160.             else
  161.                 g_hpalWall = NULL;  //!!! assume 1 or 4bpp images dont have palettes
  162.         }
  163.     }
  164.     if (g_hbmWall)
  165.     {
  166.         GetObject(g_hbmWall, sizeof(bm), &bm);
  167.         dxWall = MulDiv(bm.bmWidth, MON_DX, GetDeviceCaps(g_hdcMem, HORZRES));
  168.         dyWall = MulDiv(bm.bmHeight, MON_DY, GetDeviceCaps(g_hdcMem, VERTRES));
  169.         if (dxWall < 1) dxWall = 1;
  170.         if (dyWall < 1) dyWall = 1;
  171.         if (g_hpalWall)
  172.         {
  173.             SelectPalette(g_hdcMem, g_hpalWall, TRUE);
  174.             RealizePalette(g_hdcMem);
  175.         }
  176.         IntersectClipRect(g_hdcMem, MON_X, MON_Y, MON_X + MON_DX, MON_Y + MON_DY);
  177.         SetStretchBltMode(g_hdcMem, COLORONCOLOR);
  178.         if (flags & BP_TILE)
  179.         {
  180.             StretchBlt(g_hdcMem, MON_X, MON_Y, dxWall, dyWall,
  181.                 g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  182.             for (i = MON_X+dxWall; i < (MON_X + MON_DX); i+= dxWall)
  183.                 BitBlt(g_hdcMem, i, MON_Y, dxWall, dyWall, g_hdcMem, MON_X, MON_Y, SRCCOPY);
  184.             for (i = MON_Y; i < (MON_Y + MON_DY); i += dyWall)
  185.                 BitBlt(g_hdcMem, MON_X, i, MON_DX, dyWall, g_hdcMem, MON_X, MON_Y, SRCCOPY);
  186.         }
  187.         else
  188.         {
  189.             StretchBlt(g_hdcMem, MON_X + (MON_DX - dxWall)/2, MON_Y + (MON_DY - dyWall)/2,
  190.                     dxWall, dyWall, g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  191.         }
  192.         // restore dc
  193.         SelectPalette(g_hdcMem, GetStockObject(DEFAULT_PALETTE), TRUE);
  194.         SelectClipRgn(g_hdcMem, NULL);
  195.     }
  196. DonePreview:
  197.     SelectObject(g_hdcMem, hbmOld);
  198.     if (hcurOld)
  199.         SetCursor(hcurOld);
  200. }
  201. BOOL NEAR PASCAL BP_CreateGlobals(void)
  202. {
  203.     HDC hdc;
  204.     hdc = GetDC(NULL);
  205.     g_hdcWall = CreateCompatibleDC(hdc);
  206.     ReleaseDC(NULL, hdc);
  207.     g_hbmPreview = LoadMonitorBitmap( TRUE );
  208.     if (!g_hdcWall || !g_hbmPreview)
  209.         return FALSE;
  210.     else
  211.         return TRUE;
  212. }
  213. void NEAR PASCAL BP_DestroyGlobals(void)
  214. {
  215.     if (g_hbmPreview)
  216.     {
  217.         DeleteObject(g_hbmPreview);
  218.         g_hbmPreview = NULL;
  219.     }
  220.     if (g_hbmWall)
  221.     {
  222.         SelectObject(g_hdcWall, g_hbmDefault);
  223.         DeleteObject(g_hbmWall);
  224.         g_hbmWall = NULL;
  225.     }
  226.     if (g_hpalWall)
  227.     {
  228.         SelectPalette(g_hdcWall, GetStockObject(DEFAULT_PALETTE), TRUE);
  229.         DeleteObject(g_hpalWall);
  230.         g_hpalWall = NULL;
  231.     }
  232.     if (g_hdcWall)
  233.     {
  234.         DeleteDC(g_hdcWall);
  235.         g_hdcWall = NULL;
  236.     }
  237.     if (g_hbrBack)
  238.     {
  239.         DeleteObject(g_hbrBack);
  240.         g_hbrBack = NULL;
  241.     }
  242. }
  243. LONG CALLBACK  BackPreviewWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  244. {
  245. PAINTSTRUCT     ps;
  246. BITMAP          bm;
  247. HBITMAP         hbmOld;
  248. HPALETTE        hpalOld;
  249. RECT            rc;
  250.     switch(message)
  251.     {
  252.         case WM_CREATE:
  253.             if (!BP_CreateGlobals())
  254.                 return -1L;
  255.             break;
  256.         case WM_DESTROY:
  257.             BP_DestroyGlobals();
  258.             break;
  259.         case WM_SETBACKINFO:
  260.             if (g_hbmPreview)
  261.             {
  262.                 BuildPreviewBitmap(hWnd, wParam);
  263.                 g_bInfoSet = TRUE;
  264.                 // only invalidate the "screen" part of the monitor bitmap
  265.                 GetObject(g_hbmPreview, sizeof(bm), &bm);
  266.                 GetClientRect(hWnd, &rc);
  267.                 rc.left = ( rc.right - bm.bmWidth ) / 2 + MON_X;
  268.                 rc.top = ( rc.bottom - bm.bmHeight ) / 2 + MON_Y;
  269.                 rc.right = rc.left + MON_DX;
  270.                 rc.bottom = rc.top + MON_DY;
  271.                 InvalidateRect(hWnd, &rc, FALSE);
  272.             }
  273.             break;
  274.         case WM_PALETTECHANGED:
  275.             if ((HWND)wParam == hWnd)
  276.                 break;
  277.             //fallthru
  278.         case WM_QUERYNEWPALETTE:
  279.             if (g_hpalWall)
  280.                 InvalidateRect(hWnd, NULL, FALSE);
  281.             break;
  282.         case WM_PAINT:
  283.             BeginPaint(hWnd,&ps);
  284.             if (g_hbmPreview && g_bInfoSet)
  285.             {
  286.                 hbmOld = SelectObject(g_hdcMem, g_hbmPreview);
  287.                 if (g_hpalWall)
  288.                 {
  289.                     hpalOld = SelectPalette(ps.hdc, g_hpalWall, FALSE);
  290.                     RealizePalette(ps.hdc);
  291.                 }
  292.                 GetObject(g_hbmPreview, sizeof(bm), &bm);
  293.                 GetClientRect(hWnd, &rc);
  294.                 rc.left = ( rc.right - bm.bmWidth ) / 2;
  295.                 rc.top = ( rc.bottom - bm.bmHeight ) / 2;
  296.                 BitBlt(ps.hdc, rc.left, rc.top, bm.bmWidth, bm.bmHeight, g_hdcMem,
  297.                     0, 0, SRCCOPY);
  298.                 if (g_hpalWall)
  299.                 {
  300.                     SelectPalette(ps.hdc, hpalOld, TRUE);
  301.                     RealizePalette(ps.hdc);
  302.                 }
  303.                 SelectObject(g_hdcMem, hbmOld);
  304.             }
  305.             EndPaint(hWnd,&ps);
  306.             return 0;
  307.     }
  308.     return DefWindowProc(hWnd,message,wParam,lParam);
  309. }
  310. BOOL FAR PASCAL RegisterBackPreviewClass(HINSTANCE hInst)
  311. {
  312.     WNDCLASS wc;
  313.     if (!GetClassInfo(hInst, BACKPREV_CLASS, &wc)) {
  314.         wc.style = 0;
  315.         wc.lpfnWndProc = BackPreviewWndProc;
  316.         wc.cbClsExtra = 0;
  317.         wc.cbWndExtra = 0;
  318.         wc.hInstance = hInst;
  319.         wc.hIcon = NULL;
  320.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  321.         wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  322.         wc.lpszMenuName = NULL;
  323.         wc.lpszClassName = BACKPREV_CLASS;
  324.         if (!RegisterClass(&wc))
  325.             return FALSE;
  326.     }
  327.     return TRUE;
  328. }