页面切换后鼠标滑过特定按钮区域按钮轮廓线的颜色改变问题

0

请教页面切换问题,用easyx写了几个界面,当涉及到从磁盘文件中获取到内容再输出页面时,就会有问题。

现在我只留下了一个按钮,运行点击按钮进入的页面的返回按钮的效果就已经没有了,返回到页面后按钮的效果也不见了。比如从PrintGraph到ShowCity,页面可以切换内容也可以正常显示,但是鼠标滑过特定按钮区域按钮轮廓线不会改变,点击后可以正常切换回printgraph,但是返回后printgraph鼠标滑过特定按钮区域按钮轮廓线的颜色也不会改变了,而且上一页面应该会改变的轮廓线留在了这一页面。是不是因为页面输出比较复杂的问题?请问怎么可以优化?

运行以下代码需要新建一个city.txt文件随便添加几个城市名就可以(eg:北京 济南 南京)

运行环境:VS2017,EasyX_20200109(beta)

``` #define _CRT_SECURE_NO_WARNINGS #include using namespace std; #include // 引用图形库头文件 #include #include #include"stdio.h" #include"stdlib.h" #include #define High 480 //给定界面的高度和宽度 #define Width 740

void PrintGraph();//显示城市交通系统
void showCity();
int main()
{
PrintGraph();
}

//下面是主菜单的实现 实现的细节和子菜单的类似

/*
显示城市交通系统
*/
void PrintGraph()
{
MOUSEMSG m;
initgraph(Width, High);
cleardevice();//刷新一次 略等于那个system(cls)
setlinestyle(PS_DASHDOT, 3);
setlinecolor(BLUE);
// 左边1 高1 左边2 高2
roundrect(250, 170, 390, 220, 30, 55);
settextstyle(15, 0, "楷体");//设置文字格式
setbkmode(TRANSPARENT);// 去掉文字背景
outtextxy(270, 180, "显示城市");
settextcolor(WHITE);
while (1)
{
m = GetMouseMsg();
if (m.x >= 250 && m.x <= 390 && m.y >= 170 && m.y <= 220)
{
setlinecolor(WHITE);
roundrect(250, 170, 390, 220, 30, 55);
if (m.uMsg == WM_LBUTTONDOWN) //左键按下消息
showCity();//显示城市
}
else
{
setlinecolor(BLUE);
roundrect(250, 170, 390, 220, 30, 55);
}
}
getchar();
closegraph();
}

void showCity()
{
FILE *fp = NULL;
int num = 0;
char temp[30][10]; // unicode 编码存储字符用的
initgraph(Width, High); // 创建一个窗口
cleardevice();//刷新一次 略等于那个system(cls)
MOUSEMSG m;
if ((fp = fopen("city.txt", "rb")) == NULL) //打开城市文件,文件指针返回值为空
{
MessageBox(NULL, _T("无法打开文件!"), _T("提示"), MB_OK);
return;
}
for (int i = 0; !feof(fp); i++)
{
fscanf(fp, "%s\n", temp[i]);
num++;
}
fclose(fp); //关闭文件
BeginBatchDraw();
setbkmode(TRANSPARENT); // 1.设置文字背景模式为 TRANSPARENT 实现输出文字无背景色
settextcolor(WHITE); // 2.设置文字颜色为黑色
settextstyle(20, 0, _T("楷体")); // 3.设置文字大小和字体,参数依次为:高、宽、字体。若宽度为 0 表示自适应。
for (int i = 0; i < num; i++)
{
outtextxy(60 + 100 * (i % 5), 80 + 25 * (i / 5), temp[i]); // 4.输出不带背景的文字
}
// MessageBox(NULL, temp[0], _T("提示"), MB_OK);
setlinestyle(PS_DASHDOT, 3);
setlinecolor(BLUE);
settextstyle(15, 0, "楷体");//设置文字格式
roundrect(570, 420, 620, 450, 20, 40);
outtextxy(580, 420, "返回");
FlushBatchDraw();
while (1)
{
m = GetMouseMsg();
if (m.x >= 570 && m.x <= 620 && m.y >= 410 && m.y <= 440)
{
setlinecolor(WHITE);
roundrect(570, 410, 620, 440, 20, 40);
if (m.uMsg == WM_LBUTTONDOWN)
PrintGraph();//返回
}
else
{
setlinecolor(BLUE);
roundrect(570, 420, 620, 450, 20, 40);
}
}
getchar(); // 暂停程序运行,查看输出结果
closegraph(); // 关闭图形界面
}

</blockquote>
ava
题啼

2020-2-18

0

你这段代码的问题非常多。

核心错误是:
showCity 函数里面启用了批量绘图,导致之后再次调用 PrintGraph 函数时,还是批量绘图模式,但是 PrintGraph 函数里面没有 FlushBatchDraw 函数,导致绘图内容无法显示。一个简单的测试办法是:先去掉批量绘图看看。

其它错误包括:

  1. 不要使用 #define _CRT_SECURE_NO_WARNINGS,人家 VS 好心给你提示代码有问题,就不要忽视人家的好意。
  2. 不要使用 MBCS 编码。MBCS 编码方式早就是淘汰的东西了,写程序要养成使用 Unicode 编码的习惯。
  3. 你的代码逻辑是严重混乱的。你从 PrintGraph 内部调用 showCity,再从 showCity 内部调用 PrintGraph。第二次调用 PrintGraph 函数时,前两个函数并没有执行完毕,仍然在函数调用栈里面。这是一种非常严重又不易发现的错误,累积后会导致栈溢出。
  4. 不要反复调用 initgraph。创建绘图窗口只需要在 main 里面调用一次就行了,其它函数如果需要绘制新内容,只需要调用 cleardevice 清空屏幕内容就行了。
ava
慢羊羊

2020-2-18

技术讨论社区