举报

调用GetOpenFileName函数选择好文件之后无法调用saveimage保存图片

0

使用VS 2022(V143)环境。

第一次调用saveimage可以正常看到保存的内容,但是打开了对话框选中文件之后再调用saveimage就不能看到保存的图片了。

注释掉打开文件的部分就可以看到保存的两张图片。

#include <easyx.h>

int main()
{
	IMAGE img_buf1, img_buf2;
	loadimage(&img_buf1, _T("./imgtest/img1.png"));
	saveimage(_T("./imgoutput/output1.png"), &img_buf1);

	//打开文件
	TCHAR strbuf[1024] = { 0 };
	OPENFILENAME opera = { 0 };
	opera.lStructSize = sizeof(opera);
	opera.lpstrFile = strbuf;
	opera.nMaxFile = sizeof(strbuf)/sizeof(*strbuf);
	opera.lpstrFilter = _T("PNG(*.png)\0*.png\0\0");
	opera.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT;
	GetOpenFileName(&opera);

	saveimage(_T("./imgoutput/output2.png"), &img_buf1);

	while (1);
}

举报
0

调用 Win API 提供的文件选择器后,程序当前工作目录会被修改到最后一次所选文件的目录,因此此时再使用相对路径,可能就会导致不预期的结果。

解决方案:

#include <windows.h>    // 提供 GetOpenFileName 等 API
#include <stdio.h>        // 提供 printf
#include <tchar.h>        // 提供 _wgetcwd
 
int main(int argc, char* argv[])
{
    printf("argv[0]:\t%s\n", argv[0]);
    // 输出:argv[0]: E:\TempProject\x64\Debug\CodeTest_Project.exe
    // 说明 argv[0] 存储的是包含程序名的完全路径
 
    wchar_t pwszOldPath[MAX_PATH] = { 0 };
    _wgetcwd(pwszOldPath, MAX_PATH);
    wprintf(L"_wgetcwd:\t%ls\n", pwszOldPath);
    // 输出:_wgetcwd: E:\TempProject
    // 此处调用 _wgetcwd 以获取程序当前工作目录的完整路径
    // 由于使用 VS 进行调试,所以程序的工作目录在项目目录下,而非程序目录下
 
    // 此处调用 GetOpenFileName 选择一张其他目录的图片文件
    TCHAR pszPath[MAX_PATH] = { 0 };
    OPENFILENAME filename = { 0 };
    filename.lStructSize = sizeof(filename);
    filename.lpstrFile = pszPath;
    filename.nMaxFile = sizeof(pszPath) / sizeof(*pszPath);
    filename.lpstrFilter = L"PNG(*.png)\0*.png\0\0";
    filename.Flags = OFN_EXPLORER;
    GetOpenFileName(&filename);
    wprintf(L"pszPath:\t%ls\n", pszPath);
    // 输出:pszPath: C:\Users\myname\Pictures\test.png
 
    wchar_t pwszNewPath[MAX_PATH] = { 0 };
    _wgetcwd(pwszNewPath, MAX_PATH);
    wprintf(L"_wgetcwd:\t%ls\n", pwszNewPath);
    // 输出:_wgetcwd: C:\Users\myname\Pictures
    // 证明读取图片文件后,程序工作目录发生了变化,移动到了刚刚选取的文件所在目录
 
    // 现在将目录设置回先前保存的目录
    SetCurrentDirectory(pwszOldPath);
 
    wchar_t pwszFinalPath[MAX_PATH] = { 0 };
    _wgetcwd(pwszFinalPath, MAX_PATH);
    wprintf(L"_wgetcwd:\t%ls\n", pwszFinalPath);
    // 输出:_wgetcwd: E:\TempProject
    // 证明程序目录恢复成功
 
    // 备注:
    //    在 VS 中调试时,这样是将工作目录设置回了项目目录
    //    如果想要设置工作目录为程序目录,则需要使用 argv[0] 提供的完整程序路径,代码略
 
    return 0;
}

如需更多信息,参见 http://huidong.xyz/article.php?blog_id=170 

ava
huidong

2024-7-29

技术讨论社区