这里写目录标题
需求准备程序huawei.hhuawei.c运行图后续需求
有智能手表的人都知道,前段时间的“太空人表盘”非常火热。那么我们也可以自己动手来制作一款太空人表盘。
准备
Visual Studio EasyX Graphics Library :Visual C++ 的免费绘图库程序
huawei.h
#ifndef _HUAWEI_H_#define _HUAWEI_H_#include<graphics.h>void SetWindowNewStyle(int w, int h){// 去掉标题SetWindowLong(GetHWnd(), GWL_STYLE, GetWindowLong(GetHWnd(), GWL_STYLE) & ~WS_CAPTION);// 初始化界面为圆形SetWindowRgn(GetHWnd(), CreateEllipticRgn(0, 0, w, h), true);}//png透明贴图void drawImg(IMAGE* pimg, int x, int y){// 变量初始化DWORD* dst = GetImageBuffer();DWORD* src = GetImageBuffer(pimg);int dst_width = ::getwidth();//窗口宽高int dst_height = ::getheight();int _w = pimg->getwidth();int _h = pimg->getheight();// 计算贴图的实际长宽int iwidth = (x + _w > dst_width) ? dst_width - x : _w;// 处理超出右边界int iheight = (y + _h > dst_height) ? dst_height - y : _h;// 处理超出下边界if (x < 0) {src += -x;iwidth -= -x;x = 0; }// 处理超出左边界if (y < 0) {src += (_w * -y);iheight -= -y;y = 0; }// 处理超出上边界// 修正贴图起始位置dst += (dst_width * y + x);// 实现透明贴图for (int iy = 0; iy < iheight; iy++){for (int ix = 0; ix < iwidth; ix++){byte a = (byte)(src[ix] >> 24);//计算透明通道的值[0,256) 0为完全透明 255为完全不透明if (a > 100){dst[ix] = src[ix];}}//换到下一行dst += dst_width;src += _w;}}//去掉窗口标题以后,能够点击移动窗口void mouseEvent(){//求鼠标相对于当前窗口左上角的坐标(即鼠标距离窗口左上的的宽度和高度)static POINT WndPtSize;static bool isMove = false;if (MouseHit()){MOUSEMSG msg = GetMouseMsg();if (msg.uMsg == WM_LBUTTONDOWN)//左键按下{//获取窗口相对与屏幕左上角的 左上角坐标,和右下角坐标RECT wndRect;GetWindowRect(GetHWnd(), &wndRect);//获取鼠标光标相对于屏幕的坐标POINT curPos;GetCursorPos(&curPos);//求鼠标相对于当前窗口左上角的坐标WndPtSize.x = curPos.x - wndRect.left;WndPtSize.y = curPos.y - wndRect.top;isMove = true;}else if (msg.uMsg == WM_LBUTTONUP)//左键弹起{isMove = false;}else if (msg.uMsg == WM_MOUSEMOVE)//鼠标移动{if (isMove){POINT CursorPos;GetCursorPos(&CursorPos);/*把窗口移动到屏幕的x,y的位置* @hwnd:窗口句柄* @hwndInsertAfter:窗口的z顺序 HWND_TOPMOST {在前面, 位于任何顶部窗口的前面}* @X,Y: 窗口左上角的新位置(相对于屏幕)* @cx,xy: 窗口大小* @uFlags:SWP_NOSIZE {忽略 cx、cy, 保持大小}*/SetWindowPos(GetHWnd(), HWND_TOPMOST, CursorPos.x - WndPtSize.x, CursorPos.y - WndPtSize.y, 0, 0, SWP_NOSIZE);//CursorPos.x - WndPtSize.x//获取当前窗口左上角相对于屏幕的坐标//CursorPos.y - WndPtSize.y//printf("%d %d\n", CursorPos.x - WndPtSize.x, CursorPos.y - WndPtSize.y);}}else if (msg.uMsg == WM_RBUTTONDOWN)//右键按下{exit(0);}}}#endif // !_TOOLS_H_
huawei.c
#include <stdio.h>#include <time.h>#include "huawei.h"#include <mmsystem.h>#pragma comment(lib,"winmm.lib")#pragma warning(disable:4996)/*1,文本字体设置2,图片动画效果3,绘制表盘*/#define WIN_SIZE 500#define WIN_HALF (WIN_SIZE/2)//窗口的一半IMAGE spaceMan[59];IMAGE other[6];const char *week[7] = {"日","一","二","三","四","五","六" };void setTextStyle(int height, int width, const char *faceName){LOGFONT f = {0 };f.lfHeight = height;f.lfWidth = width;f.lfQuality = ANTIALIASED_QUALITY;strcpy(f.lfFaceName, faceName);settextstyle(&f);}void loadImg(){mciSendString("D:\\VS\\作品\\智能表盘\\images/风儿吹.mp3", NULL, 0, NULL);mciSendString("D:\\VS\\作品\\智能表盘\\images/风儿吹.mp3 repeat", NULL, 0, NULL);char fileName[50] = {0 };for (int i = 0; i < 30; i++){sprintf_s(fileName, "./images/guoguoxiaoshidi (%d).jpeg", i + 1);loadimage(spaceMan + i, fileName, 140, 130);}loadimage(&other[0], "./images/xinlv.jpg", 60, 60);//心率loadimage(&other[1], "./images/sun.jpg", 40, 40);//太阳loadimage(&other[2], "./images/shoes.jpg", 40, 40);//鞋子loadimage(&other[3], "./images/shang.jpg", 30, 30);//上箭头loadimage(&other[4], "./images/xia.jpg", 30, 30);//下箭头loadimage(&other[5], "./images/rocket.jpg", 40, 40);//火箭}//太空人旋转动画void animation(){static int index = 0;//[0~59)putimage(175, 210, spaceMan + index);static DWORD t1;DWORD t2 = clock();//获取程序运行到调用该函数经过的毫秒if (t2 - t1 > 20){index = (index + 1) % 30;t1 = t2;}}void gameDraw(){setbkcolor(RGB(255, 0, 0));cleardevice();//绘制表盘setlinecolor(RGB(0, 0, 0));//设置边框颜色setlinestyle(PS_SOLID, 30);setfillcolor(RGB(255, 255, 255));//设置圆的填充白色fillellipse(0, 0, WIN_SIZE, WIN_SIZE);//绘制一个圆//绘制线条setlinestyle(PS_SOLID, 4);setlinecolor(BLACK);//最上面竖线line(WIN_HALF - 30, 20, WIN_HALF - 30, 130);//横线x2line(WIN_HALF - 195, WIN_HALF - 120, WIN_HALF + 195, WIN_HALF - 120);line(WIN_HALF - 195, WIN_HALF + 120, WIN_HALF + 195, WIN_HALF + 120);//下面线条x3line(WIN_HALF + 80, WIN_HALF + 120, WIN_HALF + 80, WIN_HALF + 175);line(WIN_HALF + 80, WIN_HALF + 175, WIN_HALF - 60, WIN_HALF + 175);line(WIN_HALF - 60, WIN_HALF + 175, WIN_HALF - 60, WIN_HALF + 175 + 48);setbkmode(TRANSPARENT);//左上空气湿度90%setTextStyle(55, 23, "Arial");settextcolor(BLACK);outtextxy(WIN_HALF - 155, 75, "90%");drawImg(other + 5, WIN_HALF - 90, 35);//火箭//右上putimage(WIN_HALF - 90, 35, other + 5);setTextStyle(25, 15, "黑体");outtextxy(WIN_HALF - 25, 35, "空气良好");setTextStyle(25, 13, "宋体");outtextxy(WIN_HALF - 25, 65, "晴天");outtextxy(WIN_HALF - 25, 95, "25℃");outtextxy(WIN_HALF + 38, 65, "26°");outtextxy(WIN_HALF + 38, 95, "17°");drawImg(other + 4, WIN_HALF + 73, 60);//上面的箭头drawImg(other + 3, WIN_HALF + 73, 90);//下面的箭头drawImg(other + 1, WIN_HALF + 105, 70);//太阳putimage(WIN_HALF + 73, 60, other + 4);putimage(WIN_HALF + 73, 90, other + 3);putimage(WIN_HALF + 105, 70, other + 1);// 下部分setTextStyle(37, 17, "宋体");outtextxy(100, WIN_HALF + 130, "睡眠");outtextxy(WIN_HALF + 90, WIN_HALF + 130, "距离");outtextxy(50, WIN_HALF-40, "平顶山");setTextStyle(40, 15, "Arial");outtextxy(185, WIN_HALF + 125, "7h30m");outtextxy(215, WIN_HALF + 180, "9.88km");//中间//心率setTextStyle(25, 13, "宋体");outtextxy(60, WIN_HALF + 30, "80~128");drawImg(&other[0], 65, WIN_HALF + 50);//心率图putimage(65, WIN_HALF + 50, other + 0);setTextStyle(40, 15, "Arial");outtextxy(135, WIN_HALF + 60, "92");// 步数drawImg(&other[2], WIN_HALF + 65, WIN_HALF + 65);putimage(WIN_HALF + 65, WIN_HALF + 65, &other[2]);outtextxy(WIN_HALF + 125, WIN_HALF + 75, "9527");//时间、日期相关time_t timep = time(NULL);//获取当前时间struct tm* p = localtime(&timep);//把时间转成格式化时间setTextStyle(25, 12, "宋体");outtextxy(WIN_HALF + 110, WIN_HALF - 20, "四月六号");char fileName[40] = {0 };sprintf_s(fileName, "周%s %d-%d", week[p->tm_wday], p->tm_mon + 1, p->tm_mday);outtextxy(WIN_HALF + 110, WIN_HALF + 10, fileName);// 获取字体setTextStyle(100, 40, "Arial");char szBuf[40] = {0 };sprintf_s(szBuf, "%d:%02d", p->tm_hour, p->tm_min);outtextxy(105, 120, szBuf);// 秒setTextStyle(55, 23, "Arial");sprintf(szBuf, "%02d", p->tm_sec);outtextxy(335, 160, szBuf);}int main(){initgraph(WIN_SIZE, WIN_SIZE/*,EW_SHOWCONSOLE*/);SetWindowNewStyle(WIN_SIZE, WIN_SIZE);loadImg();BeginBatchDraw();//双缓冲 防止闪屏while (true){gameDraw();animation();mouseEvent();FlushBatchDraw();}EndBatchDraw();return 0;}
我将工程文件放在这里,可以自行下载。
运行图
后续
如果想了解更多物联网、智能家居项目知识,可以关注我的程序设计专栏。
或者关注公众号。
编写不易,感谢支持。