2

エディターでレベルを保存すると、そこに含まれるエラーのログファイルが作成されます。これらは基本的に、エラーメッセージと、ユーザーがツリービューで誤ったアイテムを見つけることができるパスで構成されます。

私が欲しいのは、そのパスをリンクにすることです。たとえば、<a href="editor://path/to/gameobject">クリックして、エディターでオブジェクトを表示します</ a>

これに関して私が見たSOの質問は、このmsdnページを指しているようです:http: //msdn.microsoft.com/en-us/library/aa767914.aspx

しかし、私が言えることから、それはアプリケーションの新しいインスタンスを生成します。私がやりたいのは、どういうわけか私たちのエディターを単に「呼び出す」ことです。それを行う1つの方法は、それを生成することだと思います。最初に、インスタンスがすでに実行されているかどうかを確認し、実行されている場合は、コマンドラインを送信します。

それが最善の方法ですか?もしそうなら、それを最もよくする方法についてのアイデアはありますか?そうでなければ、これを行うことができるいくつかの方法は何ですか?

また、msdnソリューションはブラウザ間で機能しますか?私たちのエディターはWindowsでのみ動作しますが、人々はIE、Fx、GC、Operaを使用しています。

4

3 に答える 3

3

任意のビューアーでリンクを機能させる必要がある場合は、はい、プロトコル ハンドラーを登録するのが最善の方法です。

エディターの起動に関しては、アウト プロセス COM サーバーとして実装できますが、既にコマンド ライン解析がソートされている場合は、ウィンドウ メッセージまたは名前付きパイプを使用してそれをエディターに渡すこともできます。ウィンドウ メッセージを送信している場合は、FindWindow (一意のクラス名) を使用して、実行中のインスタンスを確認できます。

于 2009-04-24T12:25:26.730 に答える
1

以前のインスタンスを確認することで、すでに解決したようです。

OS が何らかの方法でデータとの関連付けを "スタンプ" して、複数回実行する必要があるプログラムとそうでないプログラムを分離するように指示した場合、私は驚かれることでしょう。

于 2009-04-24T12:17:15.377 に答える
0

これが私がそれを解決した方法です。基本的に、2 つの部分があります。または3つ。

最初に、このようにアプリ自体をレジストリに登録する必要があります。Windows レジスタ関数の使用方法を見つけるのに多少のグーグル検索が必要でしたが、それらは非常に簡単でした。これをレジストリに追加すると、カスタム URL プロトコルのリンクがクリックされたときにアプリケーションが起動します。

次に、アプリはブラウザーから起動されたことを検出する必要があります。コマンドラインで「/uri」を確認するか、カスタマイズすることを選択しただけです。

第 3 に、アプリケーションを実際に起動する必要はありません。アプリケーションは既に実行されているはずです。代わりに、ハイパーリンクから開始したことを検出したら、アプリケーションの別のインスタンスが既に実行されているかどうかを検出する必要があります。その後、コマンドラインを渡す必要があります。これが私がそれをした方法です:

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];
 };

}
于 2015-10-26T10:07:53.073 に答える