• 第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;
    }
  • 相关阅读:
    PLC 输入输出接线示意图
    光耦的使用
    windows server 2008R2 搭建FTP服务器的步骤:
    C# semaphore的使用
    Multisim模拟 达灵顿管,防反接电路,恒流源电路
    一些芯片资料
    220V交流转5V直流电路详细
    STM32中的模拟IIC使用
    基于C8T6的DA14580蓝牙方案
    基本元件实验:继电器
  • 原文地址:https://www.cnblogs.com/5iedu/p/4700997.html
Copyright © 2020-2023  润新知