2009-04-24 29 views
2

当我们在编辑器中保存一个关卡时,我们会创建一个包含它的任何错误的日志文件。它们基本上由错误消息和允许用户在树视图中查找错误项目的路径组成。如何发送指向应用程序的链接,如Spotify所做的那样

我要的是使路径中的链接,像 < A HREF = “主编://路径/到/游戏对象”>点击查看对象编辑器</A>

的SO我看到的关于这个问题似乎指向这个msdn页面: http://msdn.microsoft.com/en-us/library/aa767914.aspx

但从我所知道的,它会产生一个新的应用程序实例。我想要做的就是以某种方式简单地“调用”我们的编辑器。我猜想,一种方法是产生它,并在开始时检查是否有一个实例正在运行,如果是,请将命令行发送给它。

这是最好的办法吗?如果是这样,关于如何做到最好的想法?除此之外,还有哪些方法可以做到这一点?

另外:msdn解决方案是否跨浏览器工作?我们的编辑器仅在Windows中运行,但人们使用IE,Fx,GC和Opera。

回答

3

如果您需要链接在任何查看器中工作,是的,注册协议处理程序是最好的方法。

至于启动编辑器,你可以实现它作为out-of-process COM server,但如果你已经命令行解析排序,你可以使用a window message或命名管道将它传递给编辑器。如果您发送窗口消息,则可以使用FindWindow(具有唯一的类名称)来检查正在运行的实例。

1

听起来像你已经解决了它,通过检查以前的实例。

如果操作系统以某种方式“关联”与数据的关联,告诉它分离应该从不应该运行多次的程序,我会感到惊讶。

+0

使您可以检查以前的实例(如果可用并传递命令行)。 – stevehipwell 2009-04-24 12:21:51

0

下面是我解决它的方法。基本上有两个部分。或三个。

首先,应用程序需要在注册表中注册,就像这样。它花费了一些Google搜索来了解如何使用Windows注册函数,但它们非常简单。通过将这添加到注册表中,您的应用程序将在点击与自定义url协议的链接时启动。

其次,应用程序需要检测到它已从浏览器启动。显然很琐碎,只需检查命令行中的“/ uri”,或者选择自定义它。

三,你其实不想开始你的应用程序 - 它应该已经在运行了!相反,当您检测到从超链接开始时,您需要检测应用程序的另一个实例是否已在运行。之后,您需要将命令行传递给它。以下是我做的:

bool ShouldContinueStartEditor(const std::string& command_line) 
{ 
    // Check if this instance was spawned from a web browser 
    if (command_line.find("/uri") != std::string::npos) 
    { 
     // Try to find other instance of JustEdit 
     HWND wnd = FindWindow("AV_MainFrame", NULL); 
     if (wnd) 
     { 
      COPYDATASTRUCT cds; 
      NEditorCopyData::SCommandLine data_to_copy; 

      strncpy(data_to_copy.m_CommandLine, command_line.c_str(), sizeof(data_to_copy.m_CommandLine) - 2); 
      cds.dwData = NEditorCopyData::ECommandLine; // function identifier 
      cds.cbData = sizeof(data_to_copy); // size of data 
      cds.lpData = &data_to_copy;   // data structure 

      SendMessage(wnd, WM_COPYDATA, NULL, (LPARAM) (LPVOID) &cds); 
     } 

     return false; 
    } 

    return true; 
} 

“AV_Mainframe”是hwnd的名称。如果你碰巧在使用WTL,你可以像这样声明它。现在

DECLARE_FRAME_WND_CLASS("AV_MainFrame", IDR_MAINFRAME) 

,在你的窗口类,你需要处理WM_COPYDATA消息是这样的:

MESSAGE_HANDLER(WM_COPYDATA, OnCopyData); 
LRESULT OnCopyData(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); 


LRESULT CMainFrame::OnCopyData(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) 
{ 
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT) lParam; 
if (cds->dwData == NEditorCopyData::ECommandLine) 
{ 
    NEditorCopyData::SCommandLine* command_line = static_cast(cds->lpData); 

    const char* internal_path = strstr(command_line->m_CommandLine, "/uri"); 
    if (internal_path != NULL) 
    { 
    // Do your thang 
    } 
} 

return 0; 
} 

而这几乎是所有有给它。哦,这就是复制数据名称空间的样子:

namespace NEditorCopyData 
{ 
enum ECopyDataMessages 
{ 
    ECommandLine = 0 
}; 

struct SCommandLine 
{ 
    char m_CommandLine[512]; 
}; 

} 
相关问题