由Tencent://Message協議想到的一個解決方案
源代碼下載:http://files.cnblogs.com/phinecos/HelloWorldProtocal.rar
前天在BruceZhang 的一篇博文《求助:如何在ASP頁面中調用Winform程序呢?》中回答了他提出的問題,但細想下覺得我的思路有誤。
今天在試用WebQQ的時候,無聊中想起很多人的博客上都有這樣的小玩意, , 點擊下就可以和博主進行對話,而且無需加博主爲好友。
哎,這樣的方式不就正好是BruceZhang那個問題的解決方案嗎?那麼騰訊是怎麼做到在Web頁面中調用QQ程序的呢?
先來看騰訊提供給我們的代碼:<a href="tencent://message/?uin=88888888&Site=JooIT.com&Menu=yes">
<img border="0" SRC='http://is.qq.com/webpresence/images/status/01_online.gif' alt="點擊這裏給我發消息">
</a>
很顯然,奧妙就在“tencent://message/?uin=215555521&Site=JooIT.com&Menu=yes”這裏,那這又到底是什麼原理呢?
先扯開話題按自己的思路來想,要打開本地的QQ,肯定要分兩步走,首先是定位到QQ,然後是傳遞給它一些參數,也就是“uin=215555521&Site=JooIT.com&Menu=yes”這樣的東西。定位的話,藉助註冊表是最明顯的方式了。可怎麼把QQ跑起來呢?要我們自己去啓動一個進程麼?答案是否定的,Windows操作系統考慮了這一點,允許我們爲自己的應用程序註冊爲一個協議處理者,具體參見MSDN上的文章《Registering an Application to a URL Protocol》
騰訊的Tencent://Message協議註冊表如下:
<a href="tencent://message/?uin=88888888&Site=JooIT.com&Menu=yes"><img border="0" SRC='http://is.qq.com/webpresence/images/status/01_online.gif' alt="點擊這裏給我發消息">
</a>
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Tencent]
@="TencentProtocol"
"URL Protocol"="D:\\Program Files\\Tencent\\QQ\\Timwp.exe"
[HKEY_CLASSES_ROOT\Tencent\DefaultIcon]
@="D:\\Program Files\\Tencent\\QQ\\Timwp.exe,1"
[HKEY_CLASSES_ROOT\Tencent\shell]
[HKEY_CLASSES_ROOT\Tencent\shell\open]
[HKEY_CLASSES_ROOT\Tencent\shell\open\command]
@="\"D:\\Program Files\\Tencent\\QQ\\Timwp.exe\" \"%1\""
此註冊表所實現的就是當瀏覽器(或其它)碰到 tencent://… 時,自動調用 Timwp.exe,並把 tencent://… 地址作爲第一個參數傳遞給 Timwp.exe。
廢話不多說,下面就動手實驗一個demo來說明一切,源代碼請在文章首部自行下載。 很簡單的功能,就是顯示傳遞給MFC Dialog程序的參數值。就只分析下我添加的代碼:
首先需要獲取傳入的參數,在控制檯程序中我們都知道main()函數的參數argv裏帶入了傳入的參數,而在MFC程序中則需要在InitInstance()中進行命令行參數解析。
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
爲了給對話框傳入待顯示的參數,加入了一個SetDisplayInfo方法。
CHelloWorldDlg dlg;
dlg.SetDisplayInfo(cmdInfo.m_strFileName);//設置待顯示的信息
void CHelloWorldDlg::SetDisplayInfo(CString& strInfo)
{
this->m_strInfo = strInfo;
}
最後在OnInitDialog函數中進行參數解析
//解析傳入的完整地址,e.g "helloworld://hello world/"
int pos = m_strInfo.Find("//");//找到分隔符
m_strInfo = m_strInfo.Mid(pos+2);//取到傳入的參數
m_strInfo.Delete(m_strInfo.GetLength()-1);//去掉最後的'/'
m_edit_info.SetWindowText(m_strInfo);
好了,來到最關鍵的步驟了,在註冊表中爲我們自定義的helloworld協議建立起註冊表項,從而讓HelloWorld應用程序支持此協議。將如下的註冊表項加入即可,這裏爲了簡單起見我直接用一個.reg文件來實現,也可以用其他方式進行:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\HelloWorld]
@="HelloWorld Protocol"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\HelloWorld\DefaultIcon]
@="D:\\My Documents\\Visual Studio 2005\\Projects\\HelloWorld\\release\\HelloWorld.exe,1"
[HKEY_CLASSES_ROOT\HelloWorld\shell]
@=""
[HKEY_CLASSES_ROOT\HelloWorld\shell\open]
@=""
[HKEY_CLASSES_ROOT\HelloWorld\shell\open\command]
@="\"D:\\My Documents\\Visual Studio 2005\\Projects\\HelloWorld\\release\\HelloWorld.exe\" \"%1\""
結果如圖所示
好了,這下可以來測試helloworld協議了,在地址欄中輸入:helloworld://hello world/,怎麼樣,下面的畫面出來了吧,
再來到web頁面進行測試,修改上面的html代碼如下:<html>
<head></head>
<body>
<div>
<a href="helloworld://hello world">
<img border="0" SRC='http://is.qq.com/webpresence/images/status/01_online.gif' alt="點擊這裏給我發消息">
</a>
</div>
</body>
</html>
若是要在web頁面調用本地的winform程序,同理也是可行,不過我不大懂.net,有心的朋友請試試看。
參考資料:
1, Registering an Application to a URL Protocol,
轉自點擊打開鏈接