⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 16. 调色盘管理器.txt

📁 本书介绍了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0下程序写作的方法
💻 TXT
📖 第 1 页 / 共 5 页
字号:
           PAINTSTRUCT                   ps ;
        
           RECT                          rect ;
        

           switch (message)
        
    {
        
           case   WM_CREATE:
        
                          if (!CheckDisplay (hwnd))
        
                                                 return -1 ;
        

                   plp = malloc (sizeof (LOGPALETTE) + 255 * sizeof (PALETTEENTRY)) ;
        

                   plp->palVersion                      = 0x0300 ;
        
                   plp->palNumEntries            = 256 ;
        

                  for (i = 0 ; i < 256 ; i++)
        
                   {
        
                                   plp->palPalEntry[i].peRed            = i ;
        
                                  plp->palPalEntry[i].peGreen          = 0 ;
        
                                                 plp->palPalEntry[i].peBlue    = 0 ;
        
                                                 plp->palPalEntry[i].peFlags   = PC_EXPLICIT ;
        
                        }
        
        
        
                   hPalette = CreatePalette (plp) ;
        
                   free (plp) ;        
        
                   return 0 ;
        
   
        
    case   WM_DISPLAYCHANGE:
        
                          if (!CheckDisplay (hwnd))
        
                                                 DestroyWindow (hwnd) ;
        

                          return 0 ;
        

           case   WM_SIZE:
        
                          cxClient = LOWORD (lParam) ;
        
                          cyClient = HIWORD (lParam) ;
        
                          return 0 ;
        

           case   WM_PAINT:
        
                          hdc = BeginPaint (hwnd, &ps) ;
        

                          SelectPalette (hdc, hPalette, FALSE) ;
        
                          RealizePalette (hdc) ;
        

                          for (y = 0 ; y < 16 ; y++)
        
                          for (x = 0 ; x < 16 ; x++)
        
                          {
        
                                         hBrush = CreateSolidBrush (PALETTEINDEX (16 * y + x)) ;
        
                                         SetRect (&rect, x     * cxClient /16, y     * cyClient / 16,
        
                            (x + 1)`     *      cxClient      /      16,(y+1)      * cyClient / 16);
        
                                         FillRect (hdc, &rect, hBrush) ;
        
                                         DeleteObject (hBrush) ;
        
                          }
        
                          EndPaint (hwnd, &ps) ;
        
                          return 0 ;
        

           case   WM_PALETTECHANGED:
        
                          if ((HWND) wParam != hwnd)
        
                                                 InvalidateRect (hwnd, NULL, FALSE) ;
        

                         return 0 ;
        

           case   WM_DESTROY:
        
                          DeleteObject (hPalette) ;
        
                          PostQuitMessage (0) ;
        
                          return 0 ;
        
    }
        
           return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        
SYSPAL2在WM_CREATE消息处理期间建立了逻辑调色盘。但是请注意:逻辑调色盘中所有的256个值都是从0到255的调色盘索引,并且peFlags字段是PC_EXPLICIT。该旗标是这样定义的:「逻辑调色盘项目的较低字组指定了一个硬件调色盘索引。此旗标允许应用程序显示硬件调色盘的内容。」该旗标就是专为我们要做的这件事情而设计的。

在WM_PAINT消息处理期间,SYSPAL2将该调色盘选进设备内容并显现它。这不会引起系统调色盘的任何重组,而是允许程序使用PALETTEINDEX宏来指定系统调色盘中的颜色。按此方法,SYSPAL2显示了256个矩形。另外,当您执行该程序时,注意顶行和底行的前10种和后10种颜色是20种保留颜色,如表16-1所示。当您执行使用自己逻辑调色盘的程序时,显示就改变了。

如果您既喜欢看SYSPAL2中的颜色,又喜欢RGB的值,那么请与第八章的WHATCLR程序同时执行。

SYSPAL系列中的第三版使用的技术对我来说是最近才出现的-从我开始研究Windows调色盘管理器七年多后,才出现了那些技术。

事实上,所有的GDI函数都直接或间接地指定颜色作为RGB值。在GDI内部,这将转换成与那个颜色相关的图素位。在某些显示模式中(例如,16位或24位颜色模式),这些转换是相当直接的。在其它显示模式中(4位或8位颜色),这可能涉及最接近颜色的搜索。

然而,有两个GDI函数让您直接指定图素位中的颜色。当然在这种方式中使用的这两个函数都与设备高度相关。它们太依赖设备了,以至于它们可以直接显示视讯显示卡上实际的调色盘对照表。这两个函数是BitBlt和StretchBlt。

程序16-6所示的SYSPAL3程序显示了使用StretchBlt显示系统调色盘中颜色的方法。

程序16-6 SYSPAL3 
        
SYSPAL3.C
        
/*---------------------------------------------------------------------------
        
  SYSPAL3.C -- Displays system palette
        
                                                         (c) Charles Petzold, 1998
        
----------------------------------------------------------------------------*/
        
#include <windows.h>
        
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
        
TCHAR szAppName [] = TEXT ("SysPal3") ;
        
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
        
                                                                PSTR szCmdLine, int iCmdShow)
        
{
        
           HWND                          hwnd ;
        
          MSG                           msg ;
        
           WNDCLASS              wndclass ;
        

           wndclass.style                               = CS_HREDRAW | CS_VREDRAW ;
        
           wndclass.lpfnWndProc                         = WndProc ;
        
           wndclass.cbClsExtra                          = 0 ;
        
           wndclass.cbWndExtra                          = 0 ;
        
           wndclass.hInstance                          = hInstance ;
        
           wndclass.hIcon                               = LoadIcon (NULL, IDI_APPLICATION) ;
        
           wndclass.hCursor                             = LoadCursor (NULL, IDC_ARROW) ;
        
           wndclass.hbrBackground              = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        
           wndclass.lpszMenuName                = NULL ;
        
           wndclass.lpszClassName               = szAppName ;
        
           if (!RegisterClass (&wndclass))
        
           {
        
                          MessageBox (  NULL, TEXT ("This program requires Windows NT!"),
        
                                                                               szAppName, MB_ICONERROR) ;
        
                  return 0 ;
        
           }
        

    hwnd = CreateWindow ( szAppName, TEXT ("System Palette #3"),
        
                         WS_OVERLAPPEDWINDOW,
        
                         CW_USEDEFAULT, CW_USEDEFAULT,
        
                         CW_USEDEFAULT, CW_USEDEFAULT,
        
                        NULL, NULL, hInstance, NULL) ;
        

    if (!hwnd)
        
                          return 0 ;
        
    ShowWindow (hwnd, iCmdShow) ;
        
          UpdateWindow (hwnd) ;
        

           while (GetMessage (&msg, NULL, 0, 0))
        
           {
        
                          TranslateMessage (&msg) ;
        
                          DispatchMessage (&msg) ;
        
           }
        
           return msg.wParam ;
        
}
        

BOOL CheckDisplay (HWND hwnd)
        
{
        
           HDC hdc ;
        
           int iPalSize ;
        

           hdc = GetDC (hwnd) ;
        
           iPalSize = GetDeviceCaps (hdc, SIZEPALETTE) ;
        
           ReleaseDC (hwnd, hdc) ;
        

           if (iPalSize != 256)
        
          {
        
      MessageBox (hwnd,TEXT("This program requires that the video ")
        
                       TEXT("display mode have a 256-color palette."),
        
                                  szAppName, MB_ICONERROR) ;
        
                          return FALSE ;
        
           }
        
    return TRUE ;
        
}
        

LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
        
{
        
           static HBITMAP hBitmap ;
        
           static int                    cxClient, cyClient ;
        
           BYTE                          bits [256] ;
        
           HDC                           hdc, hdcMem ;
        
           int                           i ;
        
           PAINTSTRUCT                   ps ;
        

           switch (message)
        
           {
        
           case   WM_CREATE:
        
                          if (!  CheckDisplay (hwnd))
        
                                                         return -1 ;
        

                          for (  i = 0 ; i < 256 ; i++)
        
                                                      bits [i] = i ;
        
        
        
                         hBitmap = CreateBitmap (16, 16, 1, 8, &bits) ;
        
                          return 0 ;
        
                                                      
        
           case   WM_DISPLAYCHANGE:
        
                          if (!CheckDisplay (hwnd))
        
                                                 DestroyWindow (hwnd) ;
        

                         return 0 ;
        

           case   WM_SIZE:
        
                          cxClient = LOWORD (lParam) ;
        
                          cyClient = HIWORD (lParam) ;
        
                          return 0 ;
        

           case   WM_PAINT:
        
                          hdc = BeginPaint (hwnd, &ps) ;
        

                          hdcMem = CreateCompatibleDC (hdc) ;
        
                          SelectObject (hdcMem, hBitmap) ;
        

                          StretchBlt (hdc,    0, 0, cxClient, cyClient,
        
                                            hdcMem, 0, 0, 16, 16, SRCCOPY) ;
        

                          DeleteDC (hdcMem) ;
        
                          EndPaint (hwnd, &ps) ;
        
                          return 0 ;
        
           case   WM_DESTROY:
        
                          DeleteObject (hBitmap) ;
        
                          PostQuitMessage (0) ;
        
                          return 0 ;
        
           }
        
           return DefWindowProc (hwnd, message, wParam, lParam) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -