这是我解决它的方法。基本上,有两个部分。或三个。
首先,应用程序需要在注册表中注册自己,就像这样。使用谷歌搜索来了解如何使用 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];
};
}