C语言&嵌入式编程和单片机原来可以这样玩

“漂亮”实用的C语言计算器(1)-外形构造

2021-04-11  本文已影响0人  想啥做啥

我之前写过一篇文章是介绍easyx图形界面库的,这里我再介绍一位大神写的一个功能强大的计算器,我只把基本计算的功能浓缩过来给大家看看,感兴趣的小伙伴可以去分析下全部的源码
原始地址在这里:
https://codebus.cn/contributor/a/erlingeryi-calc
我们先来看下精简后的效果:

我们接下来通过分解来看下整个计算器的实现过程

第一步:先显示个400*600像素的窗口


显示窗口实现代码:

#include <graphics.h>

typedef TCHAR T;

int main()
{
    // 创建绘图窗口
    initgraph(400, 600);
    SetWindowText(GetHWnd(), _T("计算器"));
    while (true)
    {
        Sleep(20);
    }
    return 0;
}

第二步:在400*600的窗口画出计算器的按钮方格


显示计算器的背景和主题按钮代码:

// 编译环境:Visual C++ 6.0,EasyX 20190314(beta)
// http://www.easyx.cn
//
#include <graphics.h>


#define MyChar TCHAR

typedef TCHAR T;

void showscreen();
IMAGE  setimage(int wigth, int height, COLORREF rgb);
void copy_img(IMAGE* img1, IMAGE* img2);
void my_putimage(int dstX, int dstY, IMAGE *pimg, int avoid_color, int deviation, double light, int tp, int effect);

bool button[20][20] = { false };                                   // 屏幕按键标志


int main()
{
    // 创建绘图窗口
    initgraph(400, 600);
    SetWindowText(GetHWnd(), _T("计算器"));
    while (true)
    {
        showscreen();
        Sleep(20);
    }
    return 0;
}

void showscreen()
{
    BeginBatchDraw();


    IMAGE black = setimage(400, 600, RGB(255, 125, 0));             // 设置绘图,计算器的主背景色R=255,G=125,B=0
    my_putimage(0, 0, &black, RGB(255, 255, 255), 0, 1, 30, 0);

    black = setimage(100, 50, RGB(0, 0, 0));    // 设置绘图,按钮的颜色为黑色

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            if (j >= 1 && j < 4 && i <= 2 || j == 0 && i == 1)
            {
                if (!button[i][j])
                    my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 90, 0);
                else
                    my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 50, 0);
            }
            else
            {
                if (!button[i][j])
                    my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 80, 0);
                else
                {
                    if (i == 3 && j == 4 || j == 0 && i == 2 || j == 0 && i == 0)
                    {
                        IMAGE black = setimage(100, 50, RGB(240, 0, 0));    // 设置绘图
                        my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 50, 0);
                    }
                    else if (j == 4 && i == 0 || j == 4 && i == 2 || j <= 4 && j >= 0 && i == 3)
                    {
                        IMAGE green = setimage(100, 50, GREEN); // 设置绘图
                        my_putimage(i * 102, 340 + j * 52, &green, RGB(255, 255, 255), 0, 1, 60, 0);
                    }
                    else
                    {
                        IMAGE black = setimage(100, 50, RGB(225, 100, 26)); // 设置绘图
                        my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 50, 0);
                    }
                }
            }
        }
    }

    EndBatchDraw();
}


IMAGE  setimage(int wigth, int height, COLORREF rgb)
{
    IMAGE blacks(wigth, height);    // 创建 img 对象

    SetWorkingImage(&blacks);       // 设置绘图目标为 img 对象
    setfillcolor(rgb);
    solidrectangle(0, 0, wigth, height);

    SetWorkingImage();              // 设置绘图目标为绘图窗口

    return blacks;
}

// copy img2 to img1
void copy_img(IMAGE* img1, IMAGE* img2)
{
    IMAGE* now_working = GetWorkingImage();
    Resize(img1, img2->getwidth(), img2->getheight());
    SetWorkingImage(img2);
    getimage(img1, 0, 0, img1->getwidth(), img1->getheight());
    SetWorkingImage(now_working);
}

void my_putimage(int dstX, int dstY, IMAGE *pimg, int avoid_color, int deviation, double light, int tp, int effect)
{
    int x, y, num;
    int R, G, B;            // 记录贴图某点色彩
    // 记录排除颜色色彩
    int avoid_r = GetRValue(avoid_color);
    int avoid_g = GetGValue(avoid_color);
    int avoid_b = GetBValue(avoid_color);
    IMAGE pSrcImg;          // 背景图
    IMAGE tempimg;          // 临时贴图
    copy_img(&tempimg, pimg);
    SetWorkingImage(NULL);  // 对默认绘图窗口的绘图操作
    getimage(&pSrcImg, dstX, dstY, pimg->getwidth(), pimg->getheight());

    // 透明度容错
    if (tp < 0)tp = 0;
    else if (tp > 100)tp = 100;

    // 获取背景指向显存的指针
    DWORD* bk_pMem = GetImageBuffer(&pSrcImg);

    // 贴图指向显存的指针
    DWORD* pMem = GetImageBuffer(&tempimg);
    for (y = 0; y < pimg->getheight(); y++)
    {
        for (x = 0; x < pimg->getwidth(); x++)
        {
            num = y * pimg->getwidth() + x;
            R = GetRValue(pMem[num]);
            G = GetGValue(pMem[num]);
            B = GetBValue(pMem[num]);
            if ((abs(R - avoid_r) <= deviation) && (abs(G - avoid_g) <= deviation) && (abs(B - avoid_b) <= deviation))
            {
                pMem[num] = bk_pMem[num];
            }
            else
            {
                if (light > 0 && light < 1)
                {
                    R = int(R * light);
                    G = int(G * light);
                    B = int(B * light);
                }
                else if (light > 1)
                {
                    R = min(int(R * light), 255);
                    G = min(int(G * light), 255);
                    B = min(int(B * light), 255);
                }
                if (effect == 1)//反相
                {
                    pMem[num] = 0xffffff - pMem[num];
                    continue;
                }
                else if (effect == 2)//黑白
                {
                    R = G = B = int(R * 0.299 + G * 0.587 + B * 0.114);
                }
                pMem[num] = RGB((R * tp + GetRValue(bk_pMem[num]) * (100 - tp)) / 100,
                    (G * tp + GetGValue(bk_pMem[num]) * (100 - tp)) / 100,
                    (B * tp + GetBValue(bk_pMem[num]) * (100 - tp)) / 100);
            }
        }
    }
    putimage(dstX, dstY, &tempimg);
}

第三步:显示按钮上的字符,看起来是不是有点计算器的样子了😀😀

void showscreen()
{
    BeginBatchDraw();


    IMAGE black = setimage(400, 600, RGB(255, 125, 0));             // 设置绘图,计算器的主背景色R=255,G=125,B=0
    my_putimage(0, 0, &black, RGB(255, 255, 255), 0, 1, 30, 0);

    black = setimage(100, 50, RGB(0, 0, 0));    // 设置绘图,按钮的颜色为黑色

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            if (j >= 1 && j < 4 && i <= 2 || j == 0 && i == 1)
            {
                if (!button[i][j])
                    my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 90, 0);
                else
                    my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 50, 0);
            }
            else
            {
                if (!button[i][j])
                    my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 80, 0);
                else
                {
                    if (i == 3 && j == 4 || j == 0 && i == 2 || j == 0 && i == 0)
                    {
                        IMAGE black = setimage(100, 50, RGB(240, 0, 0));    // 设置绘图
                        my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 50, 0);
                    }
                    else if (j == 4 && i == 0 || j == 4 && i == 2 || j <= 4 && j >= 0 && i == 3)
                    {
                        IMAGE green = setimage(100, 50, GREEN); // 设置绘图
                        my_putimage(i * 102, 340 + j * 52, &green, RGB(255, 255, 255), 0, 1, 60, 0);
                    }
                    else
                    {
                        IMAGE black = setimage(100, 50, RGB(225, 100, 26)); // 设置绘图
                        my_putimage(i * 102, 340 + j * 52, &black, RGB(255, 255, 255), 0, 1, 50, 0);
                    }
                }
            }
        }
    }

        // 添加的按钮字符
    settextstyle(30, 0, _T("微软雅黑"), 0, 0, 900, 0, 0, 0);
    settextcolor(RGB(255, 255, 255));
    setbkmode(TRANSPARENT);
    settextstyle(23, 0, _T("Consolas"));
    outtextxy(223, 355, _T("delete"));
    settextstyle(30, 0, _T("Consolas"));
    outtextxy(40, 350, 'C');
    outtextxy(142, 560, '.');
    outtextxy(142, 350, '0');
    outtextxy(36, 560, '(');
    outtextxy(40, 508, '1');
    outtextxy(142, 508, '2');
    outtextxy(244, 508, '3');
    outtextxy(40, 456, '4');
    outtextxy(142, 456, '5');
    outtextxy(244, 456, '6');
    outtextxy(40, 404, '7');
    outtextxy(142, 404, '8');
    outtextxy(244, 404, '9');
    outtextxy(248, 560, ')');
    settextstyle(40, 0, _T("Consolas"));
    outtextxy(342, 500, '+');
    outtextxy(342, 344, _T("÷"));
    outtextxy(342, 396, _T("×"));
    outtextxy(342, 552, '=');
    settextstyle(40, 25, _T("Consolas"));
    outtextxy(339, 448, '-');

    EndBatchDraw();
}

总结:

计算器的外形构造先介绍到这里,我们看到整个外形构造实现起来还是不复杂,当然这个前提是easyx提供了方便的画图用的库,我们采用画图的方式将整个计算器的雏形绘制出来,后面我们再继续介绍计算器的计算核心的实现。

上一篇下一篇

猜你喜欢

热点阅读