2011-02-26 54 views
3

我的C++程序创建PNG文件,我需要创建后打开(视图)这个文件 - 是有办法打开它所以被Windows资源管理器中打开 - 因此文件wiil与用户的首选方案被打开,如果有与文件的格式没有关联程序 - Windows会显示对话窗口中,用户将能够选择任何程序打开该文件。与C之内Windows的本地程序++代码打开文件

跨平台(+的Linux,MacOS的+,+ BSD)的解决方案将是完美的。

谢谢。

+2

您的整个问题都是关于Windows和Windows资源管理器,然后最后一句请求一个跨平台的解决方案。我错过了什么吗? – 2011-02-26 13:49:49

+0

程序将在Windows和* nix上运行,我用宏编写了很多依赖于平台的代码,但最好是有跨平台的解决方案。 – Slav 2011-02-26 13:52:16

+0

我想你已经尝试过'system()'命令?这是我可以想到跨平台的最快捷方式,但是如果您提出这个问题,我认为它不会完全按照您的要求进行。 – 2011-02-26 14:02:48

回答

4

如果使用Qt来开发自己的跨平台应用程序,那么QDesktopServices::openUrl() method会做这项工作。它当然是跨平台的,就像Qt中的所有东西一样。

既然你已经使用wxWidgets,使用Qt只需打开一个文件显然是矫枉过正。由于wxWidgets主要是GUI的东西,它可能没有这样的东西,虽然我不能确定,因为我从来没有用过它。

不过,如果你想要做一个跨平台的方式,这里是Qt的对Windows:

quintptr returnValue = (quintptr)ShellExecute(0, 0, 
    (wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL); 
// ShellExecute returns a value greater than 32 if successful 
return (returnValue > 32); 

这里,filePath.utf16()是Unicode空值终止的文件路径。

这里是X11/Unix的相关部分:

if (launch(url, QLatin1String("xdg-open"))) 
    return true; 
if (X11->desktopEnvironment == DE_GNOME 
    && launch(url, QLatin1String("gnome-open"))) { 
    return true; 
} else { 
    if (X11->desktopEnvironment == DE_KDE 
     && launch(url, QLatin1String("kfmclient exec"))) 
     return true; 
} 
if (launch(url, QLatin1String("firefox"))) 
    return true; 
if (launch(url, QLatin1String("mozilla"))) 
    return true; 
if (launch(url, QLatin1String("netscape"))) 
    return true; 
if (launch(url, QLatin1String("opera"))) 
    return true; 
return false; 

这里,推出()函数基本启动指定的应用程序,通过它的URL打开。不只是像Windows一样的文件路径,还有像file:///home/user/tmp/file.doc这样的完整URL。但是,不确定它很重要。在将它传递给程序之前,它还会对URL中的所有非ASCII字符进行百分比编码。不知道它是否对openDocument()尝试的所有程序都很重要。我已经用xdg-open对它进行了测试,它不关心它是否被百分比编码。

下面是相应的检测桌面环境,并设置X11->desktopEnvironment部分:

X11->desktopEnvironment = DE_UNKNOWN; 
    Atom type; 
    int format; 
    unsigned long length, after; 
    uchar *data = 0; 
    int rc; 
    do { 
     if (!qgetenv("KDE_FULL_SESSION").isEmpty()) { 
      X11->desktopEnvironment = DE_KDE; 
      break; 
     } 
     if (qgetenv("DESKTOP_SESSION") == "gnome") { 
      X11->desktopEnvironment = DE_GNOME; 
      break; 
     } 
     // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it 
     if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) { 
      X11->desktopEnvironment = DE_GNOME; 
      break; 
     } 
     rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE), 
           0, 2, False, XA_STRING, &type, &format, &length, 
           &after, &data); 
     if (rc == Success && length) { 
      if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) { 
       // Pretend that xfce4 is gnome, as it uses the same libraries. 
       // The detection above is stolen from xdg-open. 
       X11->desktopEnvironment = DE_GNOME; 
       break; 
      } 
      // We got the property but it wasn't xfce4. Free data before it gets overwritten. 
      XFree(data); 
      data = 0; 
     } 
    } while(0); 

哇,这是什么。我已经删除了检测其他环境的部分,因为它们不在openDocument()中使用。

最后,这里是使用openDocument()的光荣Mac版:

// LSOpen does not work in this case, use QProcess open instead. 
return QProcess::startDetached(QLatin1String("open"), QStringList() << file.toLocalFile()); 

真的吗?而已?哇,毕竟一定有什么东西给Mac平台的。在这里,QProcess :: startDetached()只是启动一个新进程,将文件路径作为参数传递。它基本上等同于system()调用,但不等待进程终止。不知道这是否重要,我不知道如何在Mac上不使用QProcess,因为我从未见过Mac。

+1

为什么假设提问者正在使用Qt? – 2011-02-26 13:58:44

+0

@Cody,我没有假设。然而,不使用跨平台库以跨平台的方式进行操作几乎是不可能的,因此无论如何使用它是一个好主意。我拿起了我最熟悉的那个。 – 2011-02-26 14:09:47

+0

Qt的许可证过于纠结,所以我更喜欢wxWidgets。 – Slav 2011-02-26 14:09:52

1

下面是从应用程序中打开一个位图的一个例子:

ShellExecute( GetSafeHwnd(), 
         _T("open"), 
         "Test.bmp", 
         NULL, 
         NULL, 
         SW_SHOW); 

对于如果谷歌你的要求,你会发现很多的信息,跨平台的版本。

再见

+0

请注意'GetSafeHwnd'是一个MFC函数。它不是标准Windows API的一部分。所有你必须指定的是一个窗口句柄('HWND')。 – 2011-02-26 14:10:57

+0

我设置第一个参数为NULL - 它的工作。 – Slav 2011-02-26 14:19:06