我的存在函数说该文件存在,但winapi函数说它不存在

时间:2014-11-22 15:13:02

标签: image file winapi

我复制了code that's supposed to change desktop wallpaper。我的程序中有这个常数:

const char * image_name = "button_out.gif";

稍后,我使用Magick++

在磁盘上写入图像
image.write(image_name);

图像显示在程序的工作目录中。如果我直接从资源管理器运行程序,工作目录等于程序位置。

image and the image generator

因为代码打印了0x80070002 - File not found错误,所以我在开头添加了一个存在函数:

#include <sys/stat.h>
bool exists(const char* name) {
  struct stat buffer;   
  return (stat (name, &buffer) == 0); 
}
void  SetWallpaper(LPCWSTR file){
  if(!exists((const char* )file)) {
    wcout << "The file "<<file<<" does not exist!" << endl;  
  return;
  ... actually try to set a wallpaper ...
}

但是不打印错误,代码继续进行。

现在的问题是:

  1. 我的存在功能是否正常工作?
  2. Windows在哪里查找该图片?
  3. set a Magick++ generated image as background的完整代码,以防错过与此问题相关的内容。

1 个答案:

答案 0 :(得分:5)

问题1:字符串转换

您的主要问题是您尝试互换使用LPCWSTRconst wchar_t *)和const char *。我在您的来源中看到了许多问题,特别是:

  • 您从const char * image_name开始。
  • 然后,您将其投放到LPCWSTR以传递给SetWallpaper。这基本上保证了SetWallpaper失败,因为desktop->SetWallpaper无法处理非宽字符串。
  • 然后,您将其转回const char *以通过stat()转到exists()。这个 应该适用于您的情况(因为原始字符串确实是char *)但是 ,因为您的字符串参数为{{1} } 据说是一个合适的SetWallpaper

你需要选择一种字符串格式(宽字符与Windows术语&#34; ANSI&#34;)并坚持使用一致的API格式。

最简单的选择可能只是让您的大多数代码保持不变,但修改LPCWSTR以获取SetWallpaper并在需要时转换为宽字符字符串(为此您可以使用{{ 3}})。所以,例如:

const char *

另一种选择是在整个过程中使用宽字符串,即:

  • void SetWallpaper(const char * file){ // <- Use a const char* parameter. ... // Convert to a wide-character string to pass to COM: wchar_t wcfile[MAX_PATH + 1]; mbstowcs(wcfile, file, sizeof(wcfile) / sizeof(wchar_t)); // Pass the converted wide-character string: desktop->SetWallpaper(wcfile, 0); ... }
  • 修改LPCWSTR image_name = L"button_out.gif";以取exists()并改为使用mbstowcs
  • 使用所有其他API函数的宽字符版本。

但是,我不确定它将如何与ImageMagick API交互,后者可能没有广泛的字符支持。所以它取决于你。选择最容易实现的方法,但要确保一致。一般规则是不要在LPCWSTRLPCWSTR之间施放;如果您处于需要将其中一个更改为另一个的情况,则无法强制转换,必须转换(通过const char *mbstowcs)。

问题2:SetWallpaper默认目录不是当前工作目录

此时,您的字符串使用情况将保持一致。现在你已经解决了这个问题,如果wcstombs失败而SetWallpaper没有,那么exists()就不会看你想象的地方了。正如您在评论中发现的那样,SetWallpaper默认情况下会在桌面上查找。在这种情况下,虽然我还没有测试过,但您可以通过将绝对路径传递给SetWallpaper来解决此问题。为此,您可以使用_wstat()确定给定相对路径的绝对文件名。但请记住,与字符串类型保持一致。

此外,如果SetWallpaper仍然失败,那么 问题是您的工作目录不是您认为的那样,或者您的文件名不是您认为的那样。为此,您需要执行以下测试:

  • 在检查文件是否存在时打印当前工作目录,验证其是否正确。
  • 检查文件名是否存在时打印文件名,验证其是否正确。

一旦你解决了上述所有问题,你应该好好去。