2009-04-24 48 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]; 
}; 

} 
相關問題