美文网首页C语言&嵌入式编程和单片机原来可以这样玩
“漂亮”实用的C语言计算器(1)-外形构造

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

作者: 想啥做啥 | 来源:发表于2021-04-11 23:49 被阅读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提供了方便的画图用的库,我们采用画图的方式将整个计算器的雏形绘制出来,后面我们再继续介绍计算器的计算核心的实现。

相关文章

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

    我之前写过一篇文章是介绍easyx图形界面库的,这里我再介绍一位大神写的一个功能强大的计算器,我只把基本计算的功能...

  • 盘点:有哪些适合新手练手的C/C++项目?

    1、C/C++ - C语言制作简单计算器 2、C/C++ - C语言实现通讯录 项目使用 C 语言完成一个简单的通...

  • 20181222课程记录

    1. C语言 1.1 C语言入门 代码云盘链接 提取码: vcrg 项目:2019年个税计算器 1.2 C语言初阶...

  • 有哪些适合新手练手的C/C++项目?

    喜欢的可以收藏转发加关注 1、(免费项目) C/C++ - C语言制作简单计算器 2、(会员项目) C/C++ -...

  • C 语言制作简单计算器

    前言 C语言开发计算器可是每个开始学习C语言的人的必开发项目啊,实验楼就分享一个C语言开发计算器的教程,希望对你有...

  • iOS简单项目 — 计算器

    计算器所需求功能 计算器所用模式:MVC计算器所用语言:Swift计算器所参考课程:斯坦福 第一步:构造计算器界面...

  • Runtime

    1.什么是runtime? 1> runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型、C语言...

  • runtime

    什么是runtime 1> runtime是一套底层的c语言API(包括很多强大实用的c语言类型,c语言函数);2...

  • runtime

    什么是runtime? 1> runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型、C语言函数...

  • C语言中缀表达式计算器

    本文将介绍中缀表达式计算器的详细写法,是 C语言把中缀表达式转换为后缀表达式 和 C语言逆波兰计算器 的结合 ...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/axnzkltx.html