自定义风格的时钟
- 编译环境:vs2019;
- 注意事项:点个关注吧
- 注意事项:项目属性中高级的字符集选项要设置为多字节;
- 关于图形库EasyX:需要用到该图形化库的库函数,没有下载安装的需要先下载安装改库,关于这个库的函数可自己找相关文档了解;
- 由于代码较多,为了方便管理,我添加了3个头文件来结构化模块化,所以不贴出完整代码,会挑出主要部分来叙述,我会将源文件上传CSDN,并在文末附上百度网盘链接,有需要可自行下载,若链接失效可评论获取;
- 注:文章作为自己成长的记录,不足之处还请多指教,师承大帅。
项目分析
- 一个简单的时钟有年月日时分秒,为了丰富时钟功能,我定义了两个播放和暂停音乐的按钮,一个退出按钮(虽然可以点右上角关闭…);
- 为了功能的丰富多彩,各位小伙伴可自行为其添加功能;
运行与项目截图
获取时间
- 获取时间需要定义SYSTEMTIME类型的变量,然后利用GetLocalTime()函数获取,SYSTEMTIME是一个系统定义的结构体变量,想了解更多的小伙伴可查看底层代码;我只展示一个获取时间并输入到图形化界面的代码,因为其它获取时分秒的代码大同小异;
void outtext_Hour(SYSTEMTIME sysTime)
{
settextstyle(100,0,"楷体");
char str[3] = "";
sprintf_s(str, 3, "%d", sysTime.wHour);
outtextxy(50, 40, str);
outtextxy(180, 40, ":");
}
- 首先,将SYSTEMTIME定义为形参是因为时间需要不断的获取,由于outtextxy()函数只能输出字符串类型的变量,所以需要重写该函数,重写主要是利用sprintf_s()函数格式化输出数据;
封装按钮
- 关于按钮的封装和按钮的字体对齐我上一篇文章已经提到,有疑问的小伙伴可查看上一篇文章或者评论区留言讨论,现在只贴出代码:
//封装按钮的结构体变量
typedef struct BUTTON
{
int x;
int y;
int height;
int width;
char* str;
COLORREF curColor;
}Button, * p_Button;
//初始化结构体变量
p_Button setButton(int x, int y, int width, int height,
const char* str, COLORREF curColor)
{
p_Button pb = (p_Button)malloc(sizeof(Button));
if (!pb)exit(OVERFLOW);
pb->x = x;
pb->y = y;
pb->height = height;
pb->width = width;
pb->curColor = curColor;
//字符串不能直接赋值
int strLength = strlen(str) + 1;
pb->str = (char*)malloc(sizeof(char) * strLength);
if (!pb->str)exit(OVERFLOW);
strcpy_s(pb->str, strLength, str);
return pb;
}
//画按钮
void drawButton(p_Button pb)
{
setlinecolor(BLUE);
setfillcolor(pb->curColor);
fillrectangle(pb->x, pb->y, pb->x + pb->width, pb->y + pb->height);
settextcolor(WHITE);
setbkmode(TRANSPARENT);
//设置文字居中对齐
settextstyle(25, 0, "楷体");
int textw = textwidth(pb->str);
int texth = textheight(pb->str);
int x = pb->x + (pb->width - textw) / 2;
int y = pb->y + (pb->height - texth) / 2;
outtextxy(x, y, pb->str);
}
//判断按钮点击事件
bool isClick(p_Button pb, ExMessage m)
{
if (m.x >= pb->x && m.x <= (pb->width + pb->x) &&
m.y >= pb->y && m.y <= (pb->y + pb->height)
&& m.message == WM_LBUTTONDOWN)
{
return true;
}
return false;
}
- 关于鼠标消息,需要定义一个ExMessage类型的变量,然后利用peekmessage()函数(全部小写)获取,按钮的点击就是判断鼠标点击事件发生时点击的坐标是否发生在按钮以内即可;
操作多媒体
void playMusic()
{
mciSendString("play ./music/东方之珠.mp3 repeat", NULL, 0, NULL);
}
void stopMusic()
{
mciSendString("pause ./music/东方之珠.mp3", NULL, 0, NULL);
}
void continueMusic()
{
mciSendString("resume ./music/东方之珠.mp3", NULL, 0, NULL);
}
- 关于音乐的操作,主要利用mciSendString()函数,大家只需了解双引号内的命令怎么写,无需关注后面三个参数,如想了解,可自行查阅资料;
- 双引号内写入命令+文件路径即可,命令play, pause, resume…
下面贴入主函数
#include <iostream>
#include <time.h>
#include <easyx.h>
#include <stdlib.h>
#include <windows.h>
#include "clock.h"
#include "Button.h"
#include "Music.h"
using namespace std;
int main()
{
//initgraph(800, 600);
draw_Page();
IMAGE img1;
loadimage(&img1, "./photo/胡桃.jpg", 600, 600, true);
ExMessage m;
SYSTEMTIME sysTime;
p_Button pb1 = setButton(50, 350, 120, 30, "播放音乐", RGB(255,128,192));
p_Button pb2 = setButton(250, 350, 120, 30, "暂停音乐", RGB(255, 128, 192));
p_Button pb3 = setButton(450, 350, 120, 30, "退出", RGB(255, 128, 192));
setbkmode(TRANSPARENT);
settextcolor(RGB(255, 128, 255));
BeginBatchDraw();
while (1)
{
GetLocalTime(&sysTime);
peekmessage(&m, EM_MOUSE);
putimage(0, 0, &img1);
if (isClick(pb1, m))
{
playMusic();
}
if (isClick(pb2, m))
{
stopMusic();
}
if (isClick(pb3, m))
{
exit(OVERFLOW);
}
drawButton(pb1);
drawButton(pb2);
drawButton(pb3);
outtext_year(sysTime);
outtext_month(sysTime);
outtext_day(sysTime);
outtext_Hour(sysTime);
outtext_Minute(sysTime);
outtext_Second(sysTime);
FlushBatchDraw();
}
EndBatchDraw();
char ch = getchar();
return 0;
}
- 关于该项目的主要几点和内容分析我就分析到这儿,如有疑问可私信或评论讨论,不足之处还请各位大佬指教,最后附上项目的网盘链接(嫌弃下载慢的可在我上传的资源中下载):
https://pan.baidu.com/s/1A_2jgWXsnaaeHR83zSfbGA 提取码:j31o