第16章 调色板管理器_16.2 调色板动画

16.2.1 弹球

(1)AnimatePallette(hPalette,uStart,uNum,&pe);

  ①必须运行在支持调色板的视频模式下(即256色,兼容256色不行)

  ②每个调色板条目PALETTEENTRY的peFlags要设为pC_RESERVED,才能出现动画

  ③uStart是原始逻辑调色板表的索引,不是PALETTEENTRY数组的索引

  ④该函数即改变了逻辑调色板的条目,又改变了系统调色板和映射表。所有窗口无需重绘,更改结果直接从视频显示器上反映出来。(可与SetPaletteEntries函数对比,后者只改变逻辑调色板)

(2)本例的改进——因实际上只改变两个条目(球先前位置和当前位置的颜色)

  iBallMin = min(iBall,iBallOld);

AnimatePalette(hPalette,iBallMin,2,plp->palPalEntry+ iBallMin);
 【Bounce程序】
效果图

/*------------------------------------------------------------
PALANIM.C -- Palette Animation Shell Program
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
extern HPALETTE  CreateRoutine(HWND);
extern void      PaintRoutine(HDC, int, int);
extern void      TimerRoutine(HDC, HPALETTE);
extern void      DestroyRoutine(HWND, HPALETTE);
extern  TCHAR   szAppName[];
extern  TCHAR   szTitle[];
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hIconSm = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,                  // window class name
                        szTitle, // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters
    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)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    static HPALETTE hPalette;
    static int cxClient, cyClient;
    switch (message)
    {
    case WM_CREATE:
        //if (!CheckDisplay(hwnd))
        //return -1;

        hPalette = CreateRoutine(hwnd);
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;
    case WM_DISPLAYCHANGE:
        if (!CheckDisplay(hwnd))
            DestroyWindow(hwnd);
        return 0;
    case WM_TIMER:
        hdc = GetDC(hwnd);
        SelectPalette(hdc, hPalette, FALSE);
        TimerRoutine(hdc, hPalette);
        ReleaseDC(hwnd, hdc);
        return 0;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        SelectPalette(hdc, hPalette, FALSE);
        RealizePalette(hdc);
        PaintRoutine(hdc, cxClient, cyClient);
        EndPaint(hwnd, &ps);
        return 0;
    case WM_QUERYNEWPALETTE:
        if (!hPalette)
            return FALSE;
        hdc = GetDC(hwnd);
        SelectPalette(hdc, hPalette, FALSE);
        RealizePalette(hdc);
        InvalidateRect(hwnd, NULL, TRUE);
        ReleaseDC(hwnd, hdc);
        return TRUE;  //返回TRUE,表示己经实现了调色板
    case WM_PALETTECHANGED:
        if (!hPalette || (HWND)wParam == hwnd)
            break;
        hdc = GetDC(hwnd);
        SelectPalette(hdc, hPalette, FALSE);
        RealizePalette(hdc);
        UpdateColors(hdc);
        ReleaseDC(hwnd, hdc);
        break;
    case WM_DESTROY:
        DestroyRoutine(hwnd, hPalette);
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

//Bounce.c

/*----------------------------------------------------------
Bounce.C -- Palette Animation Demo
(c) Charles Petzold,1998
----------------------------------------------------------*/
#include <windows.h>
#define ID_TIMER 1
TCHAR szAppName[] = TEXT("Bounce");
TCHAR szTitle[] = TEXT("Bounce:Palette Animation Demo");
static LOGPALETTE* plp;
HPALETTE  CreateRoutine(HWND hwnd)
{
    HPALETTE hPalette;
    int i;

    //逻辑调色板,共34种颜色,其中33种给33个小球,最后一种留作背景颜色
    plp = malloc(sizeof(LOGPALETTE) + 33 * sizeof(PALETTEENTRY));
    plp->palVersion = 0x0300;
    plp->palNumEntries = 34;
    for (i = 0; i < 34; i++)
    {
        plp->palPalEntry[i].peRed = 255;
        plp->palPalEntry[i].peGreen = (i == 0 ? 0 : 255); //第1个小球为红色,其余为白色
        plp->palPalEntry[i].peBlue = (i == 0 ? 0 : 255);
        plp->palPalEntry[i].peFlags = (i == 33 ? 0 : PC_RESERVED);//除背景色外,所有小球的颜色都
        //不共享(私有的),会改变,作动画用!
    }
    hPalette = CreatePalette(plp);
    SetTimer(hwnd, ID_TIMER, 50, NULL);
    return hPalette;
}
void PaintRoutine(HDC hdc, int cxClient, int cyClient)
{
    HBRUSH  hBrush;
    int i, x1, x2, y1, y2;
    RECT rect;
    //用调色板索引号为33的颜色画背景颜色
    SetRect(&rect, 0, 0, cxClient, cyClient);
    hBrush = CreateSolidBrush(PALETTEINDEX(33));
    FillRect(hdc, &rect, hBrush);
    DeleteObject(hBrush);
    //画33个球
    SelectObject(hdc, GetStockObject(NULL_PEN));
    for (i = 0; i < 33; i++)
    {
        x1 = i*cxClient / 33;
        x2 = (i + 1)*cxClient / 33;
        //33个小球,按“W”形状排列
        if (i < 9) //画W的第1笔,共9个
        {
            y1 = i*cyClient / 9;
            y2 = (i + 1)*cyClient / 9;
        } else if (i < 17)
        {
            y1 = (16 - i)*cyClient / 9;
            y2 = (17 - i)*cyClient / 9;
        } else if (i < 25)
        {
            y1 = (i - 16)*cyClient / 9;
            y2 = (i - 15)*cyClient / 9;
        } else
        {
            y1 = (32 - i)*cyClient / 9;
            y2 = (33 - i)*cyClient / 9;
        }
        hBrush = CreateSolidBrush(PALETTEINDEX(i));
        SelectObject(hdc, hBrush);
        Ellipse(hdc, x1, y1, x2, y2);
        DeleteObject(hBrush);
    }
    return;
}
void TimerRoutine(HDC hdc, HPALETTE hPalette)
{
    static BOOL bLeftToRight = TRUE;
    static int iBall;
    TCHAR szBuff[20];
    //将旧的球设为白色
    plp->palPalEntry[iBall].peGreen = 255;
    plp->palPalEntry[iBall].peBlue = 255;
    iBall += (bLeftToRight ? 1 : -1); //从左向右时,iBall++,相反iBall--;
    if (iBall == (bLeftToRight ? 33 : -1)) //最左边或最右边
    {
        iBall = (bLeftToRight ? 31 : 1); //最左边时,iBall =31,最右边时iBall =1;
        bLeftToRight ^= TRUE;  //bLeftToRight取反,相当于bLeftToRight =!bLeftToRight;
    }
    //设置新球为红色
    plp->palPalEntry[iBall].peGreen = 0;
    plp->palPalEntry[iBall].peBlue = 0;
    //改变系统调色板
    AnimatePalette(hPalette, 0, 33, plp->palPalEntry);
    wsprintf(szBuff, TEXT("%d"), iBall);
    TextOut(hdc, 100, 100, szBuff, wsprintf(szBuff, TEXT("%d"), iBall));
    return;
}
void DestroyRoutine(HWND hwnd, HPALETTE hPalette)
{
    KillTimer(hwnd, ID_TIMER);
    DeleteObject(hPalette);
    free(plp);
    return;
}

【Fader程序】——只需调色板的一个条目,实现文字的淡入淡出

//PalAnim.c文件:参考Bounce程序 
//Fader.c文件

//PalAnim.c文件:参考Bounce程序
//Fader.c文件
/*------------------------------------------------------------
FADER.C -- Palette Animation Demo
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#define ID_TIMER 1
TCHAR szAppName[] = TEXT("Fader");
TCHAR szTitle[] = TEXT("Fader:Palette Animation Demo");
static LOGPALETTE  lp;
HPALETTE  CreateRoutine(HWND hwnd)
{
    HPALETTE hPalette;

    //逻辑调色板,只有一种颜色
    lp.palVersion = 0x0300;
    lp.palNumEntries = 1;
    lp.palPalEntry[0].peRed = 255;
    lp.palPalEntry[0].peGreen = 255;
    lp.palPalEntry[0].peBlue = 255;
    lp.palPalEntry[0].peFlags = PC_RESERVED;
    hPalette = CreatePalette(&lp);
    SetTimer(hwnd, ID_TIMER, 50, NULL);
    return hPalette;
}
void PaintRoutine(HDC hdc, int cxClient, int cyClient)
{
    static TCHAR szText[] = TEXT("Fade In and Out");
    SIZE sizeText;
    int x, y;
    SetTextColor(hdc, PALETTEINDEX(0));
    GetTextExtentPoint32(hdc, szText, lstrlen(szText), &sizeText);
    for (x = 0; x < cxClient; x += sizeText.cx)
        for (y = 0; y < cyClient; y += sizeText.cy)
        {
            TextOut(hdc, x, y, szText, lstrlen(szText));
        }
    return;
}
void TimerRoutine(HDC hdc, HPALETTE hPalette)
{
    static BOOL bFadeIn = TRUE;
    if (bFadeIn)
    {
        lp.palPalEntry[0].peRed -= 4;
        lp.palPalEntry[0].peGreen -= 4;
        if (lp.palPalEntry[0].peRed == 3)
        {
            bFadeIn = FALSE;
        }
    } else
    {
        lp.palPalEntry[0].peRed += 4;
        lp.palPalEntry[0].peGreen += -4;
        if (lp.palPalEntry[0].peRed == 255)
        {
            bFadeIn = TRUE;
        }
    }

    AnimatePalette(hPalette, 0, 1, lp.palPalEntry);
    return;
}
void DestroyRoutine(HWND hwnd, HPALETTE hPalette)
{
    KillTimer(hwnd, ID_TIMER);
    DeleteObject(hPalette);
    return;
}

【AllColor程序】——列出所有颜色

//PalAnim.c文件:参考Bounce程序

//AllColor.c

/*------------------------------------------------------------
AllCOLOR.C -- Palette Animation Demo
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#define ID_TIMER 1
TCHAR szAppName[] = TEXT("AllColor");
TCHAR szTitle[] = TEXT("AllColor:Palette Animation Demo");
static int  iIncr;
static PALETTEENTRY  pe;
HPALETTE  CreateRoutine(HWND hwnd)
{
    HPALETTE hPalette;
    HDC hdc;
    LOGPALETTE  lp;

    hdc = GetDC(hwnd);
    //根据颜色分辨率,设置步长。如24位,时iIncr=1;16位时,iIncr=4;
    iIncr = 1 << (8 - GetDeviceCaps(hdc, COLORRES) / 3);
    ReleaseDC(hwnd, hdc);
    //创建逻辑调色板
    lp.palVersion = 0x0300;
    lp.palNumEntries = 1;
    lp.palPalEntry[0].peRed = 0;
    lp.palPalEntry[0].peGreen = 0;
    lp.palPalEntry[0].peBlue = 0;
    lp.palPalEntry[0].peFlags = PC_RESERVED;

    hPalette = CreatePalette(&lp);
    //为方便书写,保存第一个颜色条目
    pe = lp.palPalEntry[0];
    SetTimer(hwnd, ID_TIMER, 10, NULL);
    return hPalette;
}
void DisplayRGB(HDC hdc, PALETTEENTRY* ppe)
{
    TCHAR szBuffer[16];
    wsprintf(szBuffer, TEXT(" %02X-%02X-%02X "),
             ppe->peRed, ppe->peGreen, ppe->peBlue);
    TextOut(hdc, 0, 0, szBuffer, lstrlen(szBuffer));
}
void PaintRoutine(HDC hdc, int cxClient, int cyClient)
{
    HBRUSH hBrush;
    RECT  rect;
    //将调色板第1个条目的颜色画在整个客户区
    hBrush = CreateSolidBrush(PALETTEINDEX(0));
    SetRect(&rect, 0, 0, cxClient, cyClient);
    FillRect(hdc, &rect, hBrush);
    DeleteObject(SelectObject(hdc, GetStockObject(WHITE_BRUSH)));
    DisplayRGB(hdc, &pe);
    return;
}
void TimerRoutine(HDC hdc, HPALETTE hPalette)
{
    static BOOL bRedUp = TRUE, bGreenUp = TRUE, bBlueUp = TRUE;
    //计算新颜色
    pe.peBlue += (bBlueUp ? iIncr : -iIncr);
    //B先从0->255->0,再G从0->255->0,最后R
    if (pe.peBlue == (BYTE)(bBlueUp ? 0 : 256 - iIncr)) //peBlue是否到边界
    {
        //向上到边界时,将peBlue设为255,向下到边界时,设为0
        pe.peBlue = (bBlueUp ? 256 - iIncr : 0);
        bBlueUp ^= TRUE;   //取反
        pe.peGreen += (bGreenUp ? iIncr : -iIncr);
        if (pe.peGreen == (BYTE)(bGreenUp ? 0 : 256 - iIncr))//peGreen是否到边界
        {
            //向上到边界时,将peGreen设为255,向下到边界时,设为0
            pe.peGreen = (bGreenUp ? 256 - iIncr : 0);
            bGreenUp ^= TRUE;   //取反
            pe.peRed += (bRedUp ? iIncr : -iIncr);
            if (pe.peRed == (BYTE)(bRedUp ? 0 : 256 - iIncr)) //peRed是否到边界
            {
                //向上到边界时,将peRed设为255,向下到边界时,设为0
                pe.peRed = (bRedUp ? 256 - iIncr : 0);
                bRedUp ^= TRUE;
            }
        }
    }
    AnimatePalette(hPalette, 0, 1, &pe);
    DisplayRGB(hdc, &pe);
    return;
}
void DestroyRoutine(HWND hwnd, HPALETTE hPalette)
{
    KillTimer(hwnd, ID_TIMER);
    DeleteObject(hPalette);
    return;
}

16.2.3 工程应用

【Pipes程序】——模拟管道内流体的流动现象

//PalAnim.c文件:参考Bounce程序

//Pipes.c

/*------------------------------------------------------------
PIPES.C -- Palette Animation Demo
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#define ID_TIMER 1
TCHAR szAppName[] = TEXT("Pipes");
TCHAR szTitle[] = TEXT("Pipes:Palette Animation Demo");
static LOGPALETTE* plp;
HPALETTE  CreateRoutine(HWND hwnd)
{
    HPALETTE hPalette;
    PALETTEENTRY* ppe;
    int i;
    //创建33种颜色的调色板
    plp = malloc(sizeof(LOGPALETTE) + 32 * sizeof(PALETTEENTRY));
    //初始化逻辑调色板的颜色
    plp->palVersion = 0x0300;
    plp->palNumEntries = 16; //这里给33也没错
    ppe = plp->palPalEntry;
    //i   :    0  1  2  3  4  5  6  7  8
    //16-i: 16 15 14 13 12 11 10 9  8
    //16+i:16 17 18 19 20 21 22 23 24
    //32-i: 32 31 30 29 28 27 26 25 24
    for (i = 0; i <= 8; i++)
    {
        ppe[i].peRed = (BYTE)min(255, 0x20 * i); //0-256
        ppe[i].peGreen = 0;
        ppe[i].peBlue = (BYTE)min(255, 0x20 * i);
        ppe[i].peFlags = PC_RESERVED;
        ppe[16 - i] = ppe[i];
        ppe[16 + i] = ppe[i];  //这以后的颜色是为了重复颜色,以达到动画的连续性
        ppe[32 - i] = ppe[i];
    }
    hPalette = CreatePalette(plp);
    SetTimer(hwnd, ID_TIMER, 100, NULL);
    return hPalette;
}
void PaintRoutine(HDC hdc, int cxClient, int cyClient)
{
    HBRUSH hBrush;
    int i;
    RECT rect;
    //画窗口背景
    SetRect(&rect, 0, 0, cxClient, cyClient);
    hBrush = SelectObject(hdc, GetStockObject(WHITE_BRUSH));
    FillRect(hdc, &rect, hBrush);
    //画内部的管道
    for (i = 0; i < 128; i++)
    {
        hBrush = CreateSolidBrush(PALETTEINDEX(i % 16));
        SelectObject(hdc, hBrush);
        //从右向左画
        rect.left = (127 - i)*cxClient / 128;
        rect.right = (128 - i)*cxClient / 128;
        rect.top = 4 * cyClient / 14;
        rect.bottom = 5 * cyClient / 14;
        FillRect(hdc, &rect, hBrush);
        //从左向右画
        rect.left = i   * cxClient / 128;
        rect.right = (i + 1)*cxClient / 128;
        rect.top = 9 * cyClient / 14;
        rect.bottom = 10 * cyClient / 14;
        FillRect(hdc, &rect, hBrush);
        DeleteObject(SelectObject(hdc, GetStockObject(WHITE_BRUSH)));
    }
    //画管道的边缘
    MoveToEx(hdc, 0, 4 * cyClient / 14, NULL);
    LineTo(hdc, cxClient, 4 * cyClient / 14);
    MoveToEx(hdc, 0, 5 * cyClient / 14, NULL);
    LineTo(hdc, cxClient, 5 * cyClient / 14);
    MoveToEx(hdc, 0, 9 * cyClient / 14, NULL);
    LineTo(hdc, cxClient, 9 * cyClient / 14);
    MoveToEx(hdc, 0, 10 * cyClient / 14, NULL);
    LineTo(hdc, cxClient, 10 * cyClient / 14);
    return;
}
void TimerRoutine(HDC hdc, HPALETTE hPalette)
{
    static int iIndex;
    //共33种颜色,逻辑调色板的第1种颜色的入口点每次往后一位,相当于颜色在移动
    //比如当iIndex=7时,则逻辑调色板的入口点从数组palPalEntry[7]-palPalEntry[23]
    AnimatePalette(hPalette, 0, 16, plp->palPalEntry + iIndex);
    iIndex = (iIndex + 1) % 16;
    return;
}
void DestroyRoutine(HWND hwnd, HPALETTE hPalette)
{
    free(plp);
    KillTimer(hwnd, ID_TIMER);
    DeleteObject(hPalette);
    return;
}

【Tunnel程序】——模拟隧道效果

//PalAnim.c文件:参考Bounce程序

//Tunnel.c

/*------------------------------------------------------------
TUNNEL.C -- Palette Animation Demo
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#define ID_TIMER 1
TCHAR szAppName[] = TEXT("Tunnel");
TCHAR szTitle[] = TEXT("Tunnel:Palette Animation Demo");
static LOGPALETTE* plp;
HPALETTE  CreateRoutine(HWND hwnd)
{
    BYTE   byGrayLevel;
    HPALETTE hPalette;
    PALETTEENTRY* ppe;
    int i;
    //创建256种颜色的调色板
    plp = malloc(sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY));
    //初始化逻辑调色板的颜色
    plp->palVersion = 0x0300;
    plp->palNumEntries = 128;
    ppe = plp->palPalEntry;

    for (i = 0; i < 128; i++)
    {
        //byGrayLevel =0,4,8,16,24,...,252,255,252,...,4
        if (i < 64)
            byGrayLevel = (BYTE)(i * 4);
        else
            byGrayLevel = (BYTE)min(255, 4 * (128 - i));
        ppe[i].peRed = byGrayLevel;
        ppe[i].peGreen = byGrayLevel;
        ppe[i].peBlue = byGrayLevel;
        ppe[i].peFlags = PC_RESERVED;
        //这以后的颜色是为了重复颜色,以达到动画的连续性
        ppe[i + 128].peRed = byGrayLevel;
        ppe[i + 128].peGreen = byGrayLevel;
        ppe[i + 128].peBlue = byGrayLevel;
        ppe[i + 128].peFlags = PC_RESERVED;
    }
    hPalette = CreatePalette(plp);
    SetTimer(hwnd, ID_TIMER, 50, NULL);
    return hPalette;
}
void PaintRoutine(HDC hdc, int cxClient, int cyClient)
{
    HBRUSH hBrush;
    int i;
    RECT rect;
    //画128个矩形
    for (i = 0; i < 127; i++)
    {
        hBrush = CreateSolidBrush(PALETTEINDEX(i));
        //从外向里画各个矩形
        rect.left = i *cxClient / 255;
        rect.top = i* cyClient / 255;
        rect.right = cxClient - i* cxClient / 255;
        rect.bottom = cyClient - i* cyClient / 255;
        FillRect(hdc, &rect, hBrush);
        DeleteObject(hBrush);
    }
    return;
}
void TimerRoutine(HDC hdc, HPALETTE hPalette)
{
    static int iLevel;
    //共256种颜色,逻辑调色板的第1种颜色的入口点每次往后一位,相当于颜色在移动
    //比如当iLevel=60时,则逻辑调色板的入口点从数组palPalEntry[60]-palPalEntry[208]
    iLevel = (iLevel + 1) % 128;
    AnimatePalette(hPalette, 0, 128, plp->palPalEntry + iLevel);

    return;
}
void DestroyRoutine(HWND hwnd, HPALETTE hPalette)
{
    free(plp);
    KillTimer(hwnd, ID_TIMER);
    DeleteObject(hPalette);
    return;
}
时间: 2024-10-12 23:53:55

第16章 调色板管理器_16.2 调色板动画的相关文章

第16章 调色板管理器_16.1 调色板原理和使用

16.1 调色板的使用 16.1.1 调色板原理 注意: ①使用调色板前要创建逻辑调色板,选入并实现调色板.在映射过程中,逻辑调色板中的颜色会被相等匹配.或近似匹配.或新增加进系统调色板中(见后面分析) ②Windows规定,活动窗口(标题栏高亮显示的程序)的逻辑调色板(如果有的话)具有最高的实现优先权,这是因为活动窗口是当前与用户交互的窗口,应该保证其有最佳的颜色显示.非活动窗口的优先权是按Z顺序自上到下确定的(Z顺序就是重叠窗口的重叠顺序).活动窗口有权将其逻辑调色板作为前景调色板实现,非活

第16章 调色板管理器_16.3 调色板和现实世界中的图像

16.3.1 调色板和紧凑DIB (1)对于16.24.32位的DIB,没有颜色表,就不必创建调色板.但在8位视频模式下,只会用标准的20种保留色来显示.由DIB颜色表创建的调色板被称为“原生调色板” (2)dwPixel =PackedDibGetPixel(pPackedDib,x,y),当这类函数多次调用时会使程序变慢. (3)很多函数,需要对OS/2兼容DIB作不同处理. [ShowDib3程序]——原生(Native)调色板 效果图 //PackedDIB.h文件 /*--------

第16章 调色板管理器_16.4 一个DIB位图库的实现(1)

16.4.1自定义的 DIBSTRUCT结构体 字段 含义 PBYTE *ppRow ①指向位图视觉上最上面的一行像素.(不管是自下而上,还是自上而下) ②放在第一个字段,为的是后面定义宏时可方便访问到 int iSignature =“Dib ”,是这个结构体的标志 HBITMAP hBitmap 存储了由CreateDIBSection返回的位图句柄(注意,实质是DIB,但兼有DDB的特点,可直接BitBlt) BYTE *pBits 指向像素阵列的指针,其指针值在CreateDIBSect

第16章 调色板管理器_16.4 一个DIB位图库的实现(2)

//接上一篇 //DibPal.h /*----------------------------------------------------------------- DIBPAL.H header file for DIBPAL.C -----------------------------------------------------------------*/ #pragma once; #include <windows.h> #include "DibHelp.h&q

流畅的python第十五章上下文管理器和else块学习记录

with 语句和上下文管理器for.while 和 try 语句的 else 子句 with 语句会设置一个临时的上下文,交给上下文管理器对象控制,并且负责清理上下文.这么做能避免错误并减少样板代码,因此 API 更安全,而且更易于使用.除了自动关闭文件之外,with 块还有很多用途 else 子句不仅能在 if 语句中使用,还能在 for.while 和 try 语句中使用 for 仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 块.while 仅

AWT布局管理器

布局管理器 容器内可以存放各种组件,而组件的位置和大小是由容器内的布局管理器来决定的.在AWT中为我们提供了以下5种布局管理器: ①   FlowLayout 流式布局管理器 ②   BorderLayout 边界布局管理器 ③   GridLayout 网格布局管理器 ④   CradLayout 卡片布局管理器 ⑤   GridBagLayout 网格包布局管理器 容器中组件的布局通常由布局管理器控制.每个Container(比如一个Panel或一个Frame)都有一个与他相关的缺省布局管理

node.js入门经典 第2章 npm(Node包管理器)

2.1 npm是什么 npm(Node Package Manager)是Node.js的包管理器.它允许开发人员在Node.js应用程序中创建.共享并重用模块. 2.3 安装模块 npm install [module_name] 2.4 使用模块 var module = require{'module'}; 2.8  使用package.json指定依赖关系 使用package.json文件来指定在应用程序中要用的模块,并且通过单个命令来安装它们: npm install

【Swing 2】布局管理器上

很苦逼的是,每次想记录一个小程序,发现,要给别人讲清楚,总是得分很多模块讲解. 所以今天来讲下Swing组件的三大布局管理器. 参考:<Head First Java>第十三章 1. BorderLayout--边界布局 2. FlowLayout--顺序布局 3. BoxLayout--不知道叫啥 1. BorderLayout(边界布局) 该管理器把背景分成东南西北中五大块,这是框架默认的布局管理器 1 package demo; 2 3 import javax.swing.*; 4 i

Lua_第16 章 Weak 表

Lua_第16 章 Weak 表 Lua自动进行内存的管理.程序只能创建对象(表,函数等),而没有执行删除对象 的函数.通过使用垃圾收集技术,Lua 会自动删除那些失效的对象.这可以使你从内存 管理的负担中解脱出来.更重要的,可以让你从那些由此引发的大部分 BUG中解脱出 来,比如指针挂起(dangling   pointers)和内存溢出. 和其他的不同,Lua 的垃圾收集器不存在循环的问题.在使用循环性的数据结构的 时候,你无须加入特殊的操作;他们会像其他数据一样被收集.当然,有些时候即使更