发现重大bug 调用GetOpenFileName获取文件路径之后loadimage函数失效获取不到实体 最后导致putimage失效,急急急!

1

发现重大bug 调用GetOpenFileName获取文件路径之后loadimage函数失效获取不到实体 最后导致putimage失效,急急急!

#include <stdio.h>
#include <graphics.h>		// 引用图形库头文件
#include <conio.h>

// 返回值: 成功 1, 失败 0
// 通过 path 返回获取的路径
int FileDialog(char *path)
{	
	OPENFILENAME ofn;	
	ZeroMemory(&ofn, sizeof(ofn)); 
	ofn.lStructSize = sizeof(ofn); // 结构大小   
	ofn.lpstrFile = path; // 路径  
	ofn.nMaxFile = MAX_PATH; // 路径大小  
	ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0"; // 文件类型  
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	return GetOpenFileName(&ofn);
}

int main()
{
	IMAGE imgHead;
	char szFile[MAX_PATH] = {0};   //文件路径
	initgraph(640, 480);

	if(FileDialog(szFile))
	{
		loadimage(&imgHead,"image\\login.png");	//任何一张路径对的图片都无效,你把loadimage放到if外面又正常				
		putimage(0,0,&imgHead);						
	}
	_getch();
	return 0;
}
ava

2021-5-24

0

“当前路径”并不是很稳定的一个值,比如在我的系统下测试,你的代码是没问题的。

但是换一个环境就不一定了,有些操作可能会修改“当前路径”,导致使用相对路径时找不到文件。可以这样测试一下:

	char pCurDir[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, pCurDir);
	outtextxy(0, 0, pCurDir);

	FileDialog(szFile);

	GetCurrentDirectory(MAX_PATH, pCurDir);
	outtextxy(0, 20, pCurDir);

看看在调用 FileDialog 的前后,当前路径是否被修改了。

如果当前路径被修改了,那么解决方案有两种:用 SetCurrentDirectory() 将当前路径设置回去,或者,用 GetModuleFileName() 获取到当前 .exe 的完整路径,再由此拼接出资源的绝对路径。

用 SetCurrentDirectory() 将当前路径设置回去,这个比较简单,局部代码如下:

	char pCurDir[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, pCurDir);	// 保存当前路径
	FileDialog(szFile);
	SetCurrentDirectory(pCurDir);			// 设置当前路径
	// (你可以将 保存/设置 当前路径的代码,加到函数 FileDialog 里面)

用 GetModuleFileName() 拼接出资源的绝对路径的方法如下:

	// 由 .exe 的路径和资源的相对路径拼接出资源的绝对路径
	// 注意:这个资源的相对路径,是基于 .exe 的路径计算的,而不是项目文件夹
	char szPath[MAX_PATH];							// 资源路径
	GetModuleFileName(NULL, szPath, MAX_PATH);		// 获取当前 .exe 的路径
	strcpy(strrchr(szPath, '\\') + 1, "test.bmp");	// 拼接出资源的绝对路径
	loadimage(&imgHead, szPath);					// 加载图片资源

注:如果项目是 Unicode 字符集,请修改相关字符串操作函数。

ava
慢羊羊

2021-5-24

技术讨论社区