蛙蛙推荐:蛙蛙牌firefox插件

落花浮王杯 提交于 2020-02-08 06:23:02

上次给大家演示了抓取IE内核浏览器的网页,这次和大家一起写一个抓取firefox页面文本的例子。Firefox有自身的一套结构良好的插件机制,但要深入开发Firefox插件的话要了解javascript,XUL,XPCOM以及一些c++的基本常识,本贴算是给想开发Firefox插件的朋友入门。

我们先来了解什么是XPCOM,并开发一个

以下为引用(https://developer.mozilla.org/cn/XPCOM
XPCOM(Cross Platform Component Object Model)是一种跨平台组件模型,是Mozilla技术的核心。其原理与微软的COM技术类似,但与COM不同的是,XPCOM是一种跨平台技术,并支持多种语言绑定(Language Bindings)。也就是说,我们可以使用C++、JAVA、JavaScript、Python、Ruby、Perl等语言来编写组件。而XPCOM的接口(Interface)是用一种叫做XPIDL的IDL(Interface Description Language)来定义的。

XPCOM 自身提供了一套核心的组件和类,用于诸如内存管理,线程,基本数据结构(strings, arrays, variants)等 。但是大部分的XPCOM组件并不是这个核心库提供的,而是由很多第三方的平台(例如Gecko或者Necko)提供,或者由一个应用,甚至一个扩展提供。

要想了解如何搭建MOZILLA开发环境,可以参考如下链接
Windows Build Prerequisites
我们下载MozillaBuildGecko SDK 1.8
先安装MozillaBuild到D:\mozilla-build,后安装Gecko SDK 1.8到D:\dev\gecko-sdk,虽然整个过程没有用到MozillaBuild,但它是必须要安装的,否则后面运行regxpcom会出好多莫名其妙的错,(光解决这个问题就我就折腾了好几个晚上,希望大家少走弯路,只下载wintools.zip和gecko sdk就是不行,就得装MozillaBuild,这是先决条件。

创建XPCOM组件要先定义一个接口文件,新建IWawaComp.idl,用记事本打开,输入如下内容

#include "nsISupports.idl"
[scriptable, uuid(b7b04070
-45fc-4635-b219-7a172f806bee)]
interface IWawaComp : nsISupports
{
  
void SendSysMessage(in string  str);
};

这是一个很简单的接口,只有一个方法SendSysMessage,接受一个string类型的参数,string是gecko的类型,不支持中文,要想用中文,可以用xpcom idl中的nsAString(在idl文件里要用AString表示,用nsAString会出错), wstring等支持unicode的字符串类型。因为我最终也没办法在js下把中文传给XPCOM,所以这里最终还是决定用string类型。b7b04070-45fc-4635-b219-7a172f806bee是一个GUID类型,可以用ultraedit或者vs.net自带的功能生成一个。所有的接口必须继承自nsISupports,因为要使用string类型,所以要包含以下nsISupports.idl文件,好多基本类型都在这里面定义。如果要用wstring或AString类型,要包含以下nsrootidl.idl文件。其它的地方都是固定的,你可以自己加一些接口方法或者修改什么的,这就是一个模板。

中文问题:


光解决中文的问题,我花了周末两天和两个晚上,最后才得到一个不太完美的方案,把过程分享一下。
第一种思路是用scriptableunicodeconverter的ConvertFromUnicode方法把中文转换成unicode bytes,然后用window.btoa把unicode bytes转换成base64字符串,然后传给XPCOM,这样XPCOM的接口只用string类型就行,在XPCOM里再进行base64解码,再用MultiByteToWideChar来转换成wchar_t等宽字符类型。可惜scriptableunicodeconverter转换的bytes用window.btoa编码后的base64根本就无法再原样转回去,弄了好久,死活不行,可能gecko的这个方法对中文支持就是不行。所以这种思路最后没戏。
第一种思路的代码如下

function unicodeToBytes(content, charset) 
{
    
try
    {
        
const cc = Components.classes;
        
const ci = Components.interfaces;
        
const unicodeConverter = cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(ci.nsIScriptableUnicodeConverter);
        unicodeConverter.charset 
= charset;
        content 
= unicodeConverter.ConvertFromUnicode(content);
        
return content;
    }
    
catch (err)
    {
        alert(err);
    }
}
var data 
= unicodeToBytes("中文","utf-8"); 
alert(window.atob(window.btoa(data))); 

弹出来的是乱码,不知道咋解决,直接window.btoa("中文")也会出错
第二种思路是把接口方法的参数定义成AString,然后在XPCOM的实现方法里用NS_StringGetData和WideCharToMultiByte来转换,结果NS_StringGetData在gecko 1.8下编译链接时老提示无法解析的外部符号,在gecko1.7下倒是能编译,可是无法注册在firefox 2.0下,最后也实在没办法,不了了只。关于这种思路来源于以下链接http://rogerfd.cn/?p=165
相关讨论如下
关于XPCOM开发的问题

然后就要根据接口定义文件生成头文件和类型库文件(.xpt),先把D:\mozilla-build\moztools-180compat\bin目录下的libIDL-0.6.dll,glib-1.2.dll拷贝到D:\dev\gecko-sdk\bin目录下,然后执行如下命令
D:\dev\gecko-sdk\bin\xpidl -m header -I ..\idl  IWawaComp.idl
D:\dev\gecko-sdk\bin\xpidl -m typelib -I ..\idl  IWawaComp.idl
第一行生成头文件,第二行生成类型库文件。如果执行的时候出错了,有可能是没安装mozillabuild,还不行的话就把geckosdk的那几个bin,lib,include等目录加入到系统环境变量PATH下。

打开头文件,大概如下

 

/*
 * DO NOT EDIT.  THIS FILE IS GENERATED FROM IWawaComp.idl
 
*/

#ifndef __gen_IWawaComp_h__
#define __gen_IWawaComp_h__


#ifndef __gen_nsISupports_h__
#include 
"nsISupports.h"
#endif

/* For IDL files that don't want to include root IDL files. */
#ifndef NS_NO_VTABLE
#define NS_NO_VTABLE
#endif

/* starting interface:    IWawaComp */
#define IWAWACOMP_IID_STR "b7b04070-45fc-4635-b219-7a172f806bee"

#define IWAWACOMP_IID \
  {
0xb7b040700x45fc0x4635, \
    { 
0xb20x190x7a0x170x2f0x800x6b0xee }}

class NS_NO_VTABLE IWawaComp : public nsISupports {
 
public

  NS_DEFINE_STATIC_IID_ACCESSOR(IWAWACOMP_IID)

  
/* void SendSysMessage (in string str); */
  NS_IMETHOD SendSysMessage(
const char *str) = 0;

};

/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_IWAWACOMP \
  NS_IMETHOD SendSysMessage(
const char *str); 

/* Use this macro to declare functions that forward the behavior of this interface to another object. */
#define NS_FORWARD_IWAWACOMP(_to) \
  NS_IMETHOD SendSysMessage(
const char *str) { return _to SendSysMessage(str); } 

/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
#define NS_FORWARD_SAFE_IWAWACOMP(_to) \
  NS_IMETHOD SendSysMessage(
const char *str) { return !_to ? NS_ERROR_NULL_POINTER : _to->SendSysMessage(str); } 

#if 0
/* Use the code below as a template for the implementation class for this interface. */

/* Header file */
class _MYCLASS_ : public IWawaComp
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_IWAWACOMP

  _MYCLASS_();

private:
  
~_MYCLASS_();

protected:
  
/* additional members */
};

/* Implementation file */
NS_IMPL_ISUPPORTS1(_MYCLASS_, IWawaComp)

_MYCLASS_::_MYCLASS_()
{
  
/* member initializers and constructor code */
}

_MYCLASS_::
~_MYCLASS_()
{
  
/* destructor code */
}

/* void SendSysMessage (in string str); */
NS_IMETHODIMP _MYCLASS_::SendSysMessage(
const char *str)
{
    
return NS_ERROR_NOT_IMPLEMENTED;
}

/* End of implementation class template. */
#endif


#endif /* __gen_IWawaComp_h__ */

下面被注释掉的部分是告诉你如何写接口的实现部分。
然后用vc2005新建一个c++类库,不要MFC,ATL啥的,预编译头在打开项目后也把勾去掉,再把没用的std啥.h也都删了。把刚生成的IWawaComp.h放在头文件目录下。然后要设置一下项目的配置,先打开项目属性,做如下配置
1、c++\常规\附加包含目录,输入如"D:\dev\gecko-sdk\include"
2、c++\预处理器\预处理器定义里加入WAWAXPCOM_EXPORTS和XPCOM_GLUE
3、c++\代码生成\运行时库 改成”多线程DLL
4、链接器\附加库目录输入”"D:\dev\gecko-sdk\lib"“
5、链接器\输入\附加依赖项 输入nspr4.lib、plc4.lib、plds4.lib、xpcomglue.lib

再新建一个WawaComp.h头文件,内容如下

#pragma once

#ifndef _WAWA_COMPT_H_
#define _WAWA_COMPT_H_

#include 
"IWawaComp.h"

#define WAWA_COMP_CONTRACTID "@fetionmm.com/XPCOM/WawaComp;1"
#define WAWA_COMP_CLASSNAME "WawaComp"
#define WAWA_COMP_CID  {0xb7b04070, 0x45fc, 0x4635,{ 0xb2, 0x19, 0x7a, 0x17, 0x2f, 0x80, 0x6b, 0xee } }


class WawaComp:public IWawaComp
{
  
public:
    NS_DECL_ISUPPORTS
    NS_DECL_IWAWACOMP
};
#endif

前面是定义了一下组件的常量,WAWA_COMP_CONTRACTID是javascript创建XPCOM的时候用的字符串,后面会看到,WAWA_COMP_CLASSNAME是组件的类名,WAWA_COMP_CID是组件的唯一ID,如果你不会从GUID变成这种格式,其实就是把刚才生成的头文件里的IWAWACOMP_IID宏的值拷贝过来就行。剩下的部分基本都是固定格式,从生成的头文件里的注释部分直接拷过来就行。
再新建一个WawaCompModule.cpp文件,这个是一个XPCOM的模块文件,是必须的。

 

#include "nsIGenericFactory.h"
#include 
"WawaComp.h"

NS_GENERIC_FACTORY_CONSTRUCTOR(WawaComp)

static nsModuleComponentInfo components[] =
{
    {
        WAWA_COMP_CLASSNAME, 
        WAWA_COMP_CID,
        WAWA_COMP_CONTRACTID,
        WawaCompConstructor,
    }
};

NS_IMPL_NSGETMODULE(
"WawaCompModule", components)

前两个include是必须的,下面一句是生成本组件,参数WawaComp就是组件的实现类,再往下是生命一个nsModuleComponentInfo数组,里面前三个都是在WawaComp.h里生命的几个常量,最后一个WawaCompConstructor是固定格式,就是类名加上Constructor。再最后一句是注册这个组件,第一个字符串是这个模块的名字,第二个参数是前面声明的数组。都是固定格式,如果要自己开发XPCOM的话,按格式改改就行了。

再新建最后一个文件WawaComp.cpp
代码如下

/* MyComponent.cpp*/
#include 
"WawaComp.h"
#include 
<windows.h>
#include 
<tchar.h>

NS_IMPL_ISUPPORTS1(WawaComp, IWawaComp)
NS_IMETHODIMP WawaComp::SendSysMessage(
const char *sText)
{   
 DWORD dwSize 
= MultiByteToWideChar (CP_ACP, 0, sText, -1, NULL, 0);
 wchar_t 
*pwText;
 pwText 
= new wchar_t[dwSize];
 MultiByteToWideChar(CP_ACP, 
0, sText, -1, pwText, dwSize);

 HWND   hWnd   
=   FindWindow(NULL,_T("WawaApp"));
 COPYDATASTRUCT cpd 
= {SW_NORMAL, lstrlen(pwText)*2+2, pwText};
 SendMessage( hWnd, WM_COPYDATA, 
0, (LPARAM) & cpd );
 delete []pwText;
  
return NS_OK;
}

该文件是接口的实现文件,NS_IMPL_ISUPPORTS1一句是固定的,第一个参数是类名,第二个参数是接口名。下面就是SendSysMessage方法的实现了,该方法的签名也在前面生成的头文件的注释里复制过来,该方法返回类型是NS_IMETHODIMP类型,NS_OK表示成功。
实现的代码很简单,主要是路是把多字节字符串用MultiByteToWideChar转换成宽字符字符串,然后找到标题为WawaApp的窗口,声明一个COPYDATASTRUCT的结构,把宽字符字符串放进去,最后用SendMessage方法向目标窗口发送WM_COPYDATA消息,完了再用delete把前面声明的宽字符字符串释放内存。
MultiByteToWideChar的用法是固定的,第一次调用先得出目标字符串的长度,第二次调用是填充字符串,可以参考《windows核心编程》查看详细。COPYDATASTRUCT的第二个参数是lstrlen(pwText)*2+2,是因为一个宽字符站两个字节,所以要乘以2,完了字符串是以两个\0结尾,所以要加2。SendMessage是同步发送消息,这里没用SendMessageTimeout是怕超时后,目标进程还想读取本进程的COPYDATASTRUCT,有可能引起本进程崩溃,没有使用PostMessage是因为发了消息后对方没机会读取COPYDATASTRUCT的数据了。

进程间通信:


进程间通信有好多种方式,如果只传少量的字符串的话,可以用GlobalFindAtom,GlobalGetAtomName,GlobalDeleteAtom,GlobalAddAtom几个API来做到,不过我试验了下,这几个API传递的字符串好像有长度限制,最后放弃了。还有就是可以用内存映射文件,就是代码写的有些多,也没用;用命名管道或者socket也可以,但总感觉有些火箭穿蚊子,也没用。WriteProcessMemory也可以,感觉不优雅,太暴力,最后才选定了用WM_COPYDATA。
编译后生成WawaXPCOM.dll,到这一步XPCOM就算开发完了。关于XPCOM的部署,很麻烦,firefox3.0以下,可以用install.js来在.xpi包里自动安装,参考如下链接
http://blog.csdn.net/Xscarlet/archive/2007/07/23/1704450.aspx,但firefox3.0我测试了不行,貌似firefox3.0取消了对install.js的支持,那只能把.DLL和.XPT复制到firefox安装目录的components子目录下,然后删除C:\Documents and Settings\Administrator\Application Data\Mozilla\Firefox\Profiles\brm8mamm.dev目录下的xpti.dat和compreg.dat文件,然后重启firefox来重新自动注册XPCOM了。关于firefox下自动注册xpcom的正规方法,我费了半天劲也没找到。

下面开始开发firefox插件

先做准备工作,我用的是firefox2.0,firefox可以创建多个用户配置文件,用firefox -p运行,在对话框里新建配置文件dev,打开后再地址栏里输入about:config,修改如下选项
javascript.options.showInConsole = true //把 JavaScript 的出错信息显示在错误控制台
nglayout.debug.disable_xul_cache = true //禁用 XUL 缓存,使得对窗口和对话框的修改不需要重新加载 XUL 文件
browser.dom.window.dump.enabled  = true //允许使用 dump() 语句向标准控制台输出信息
javascript.options.strict        = true //在错误控制台中启用严格的 JavaScript 警告信息

然后给firefox安装Extension Developer's Extension 插件,这样你修改了xpcom后运行菜单 工具\Extension Developer\ Reload all Chrome不用重启ff就可以测试插件了。我们在C:\Documents and Settings\Administrator\Application Data\Mozilla\Firefox\Profiles\brm8mamm.dev\extensions(Administrator是当前用户名,brm8mamm.dev可能和你的不一样,但结尾是你刚新建的firefox配置文件名dev)目录下新建一个wawaxpcom@fetionmm.com的文件,用记事本打开,输入我们插件的开发路径,比如E:\huhao\project\WawaFF\xpcom,这样firefox就会自动加载这个插件了,每次改动了文件只需Reload all Chrome就能测试。
关于firefox插件开发环境搭建,参考如下链接
http://www.ibm.com/developerworks/cn/web/wa-lo-firefox-ext/
环境搭好了,先建立工作文件,在E:\huhao\project\WawaFF\xpcom里建立如下文件
install.rdf
chrome.manifest
components
components\IWawaComp.xpt
components\WawaXPCOM.dll
chrome
chrome\skin
chrome\content
chrome\content\overlay.xul
chrome\content\style.css
chrome\content\wawa.js
关于firefox插件的接口,参看如下链接
http://www.lewislv.org/mozilla-ext/mozilla-ext.html#ch3_1_1
其中skin文件,本例没有用到,我们先从overlay.xul开始吧,它是一个xul定义文件,XUL是一个界面描述语言,是XML格式的,用javascript和xul也能开发一些跨平台RIA应用。以下为引用
XUL 是一个Mozilla使用XML来描述用户界面的一种技术,使用XUL你可以快速的创建出跨平台,基于因特网的应用程序。基于XUL技术的应用程序可以很方便的使用好看的字体、图形以及方便的界面布局,而且也更容易部署和定制。如果程序员已经熟悉了Dynamic HTML (DHTML),那学习XUL将是更容易的事,也可以更快的开发基于XUL的应用程序.
来自https://developer.mozilla.org/cn/XUL
我们的overlay.xul,如下

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<overlay id="wawaxpcom" 
         xmlns
="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:html
="http://www.w3.org/1999/xhtml" > 
<script type="application/x-javascript"
        src
="chrome://wawaxpcom/content/wawa.js" />    
  
<statusbar id="status-bar">
   
<statusbarpanel id="statusbar_fs_sz" class="statusbarpanel-iconic"  onclick="collection(true);" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAnElEQVQ4jcWTyw0DMQhEx24gJc2NItJBqtljOkgbiMZgD/Emq/VHjnzISMiSEWN4wgBww6pEZCMZAKaCZIjI9jEgGaoa7j4VqhrlQaTiEe5et/a8v8/Hq0rlnAEg5dXx/29QMzjm7qnw6DNoABvl2iO0TDrGfQbngkFXqYQ392CgM4P4qfJqBCCRhJlNF5kZSH4vlj/TRQeXqSXbATJtb4tQeT1wAAAAAElFTkSuQmCC" insertafter="statusbar-display" style="color:green" label="wawasoft" warning="true"/>
</statusbar>
</overlay>

就是引入了一个wawa.js文件,然后再状态栏上家了一个图片panel,src属性指定图片的路径,不过我指了半天不会指,最后用base64来描述了一个小图片,反正也不大,就似乎把图片的bytes用base64字符串写在那里,微软的.mht格式也是把图片转成那样的base64字符串,还有邮件协议也是。要想让statusbarpanel显示图片的话,必须设置class="statusbarpanel-iconic",最后onclick="collection(true);" 表示点击这个图片出发collection函数,该函数在wawa.js里定义,一会儿看。关于XUL节点定义,可以查些资料看。
再看下xul的样式,就是普通的CSS,大家应该 很熟悉,

/*** XUL demonstration ***/
/* the status bar */
statusbar 
{
    width
: 100%;
    border
: 1px inset -moz-dialog;
    margin
: 4px;
    padding
: 0px 4px;
}
#status 
{
    
}
#status[warning] 
{
    color
: red;
}

就定义了基本的一些边框,外空白,内空白,警告颜色等信息。然后主要的东西在wawa.js里,如下

function collection(isSelection)
{
 
try{
  
var win = window.getBrowser().selectedBrowser.contentWindow;
  
var doc = window.getBrowser().selectedBrowser.contentDocument;
  
var sel = win.getSelection().QueryInterface(Components.interfaces.nsISelectionPrivate);
    
var contentHTMLSel = sel.toStringWithFormat("text/html"00);
    
var contentHTMLAll = doc.body.innerHTML;
    
  
var wawaxpcom = Components.classes["@fetionmm.com/XPCOM/WawaComp;1"].getService();
  wawaxpcom 
= wawaxpcom.QueryInterface(Components.interfaces.IWawaComp);
  
  
var s = encodeURIComponent(contentHTMLSel);
  
if(Selection)
   wawaxpcom.SendSysMessage(s);
  
else
    wawaxpcom.SendSysMessage(
"<h1>KK</h1>");
 }
catch(err){alert(err)}
}

前面一些是获取网页上的html代码或者用户选定的部分HTML代码,中间一节是创建我们上面创建的XPCOM,可以看到那里用到了组件的类名,接口等信息,都是固定格式。完了再下面就是把html编码用encodeURIComponent进行编码后调用组件的SendSysMessage方法发出去,进行SendSysMessage编码的原因是考虑中文,中文直接传到XPCOM里有问题,上面说过了。
值得注意的firefox本身就有好多xpcom可以使用,有访问网络的,unicode转换的,读写文件的,使用w32shell的等,很强大,在你动手写你自己的xpcom之前,最好先了解一下,免得做无用功。
chrome.manifest定义了firefox插件的文件清单,内容如下
content wawaxpcom chrome/content/
overlay chrome://browser/content/browser.xul chrome://wawaxpcom/content/overlay.xul

第一行表示的是主要内容,第二行表示要用到的界面XUL,一般就这样就行了,.css和.js不用列出来(不是太确认,有的也列出来了,不知道为啥,反正我的能用)。
install.rdf是一个部署声明文件,不是ie的频道文件,但是XML格式的,如下

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
     xmlns:em
="http://www.mozilla.org/2004/em-rdf#">

  
<Description about="urn:mozilla:install-manifest">
  
    
<em:id>wawaxpcom@fetionmm.com</em:id>
    
<em:name>wawaxpcom</em:name>
    
<em:version>0.1.0</em:version>
    
<em:description>WawaXPCOM</em:description>
    
<em:creator>wawa</em:creator>
 
    
<!-- Firefox -->
    
<em:targetApplication>
      
<Description>
        
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        
<em:minVersion>1.5</em:minVersion>
        
<em:maxVersion>3.1.0.*</em:maxVersion>
      
</Description>
    
</em:targetApplication>

  
</Description>

</RDF>

其中ec8030f7-c20a-464f-9b0e-13a3a9e97384是固定的,不是你的XPCOM的ID,这个表示firefox,其它的很明显,看节点名就行了,都是插件ingcheng,版本,适应的firefox版本等信息。
最后把整个E:\huhao\project\WawaFF\xpcom目录压缩成一个zip文件,把后缀名改成.xpi格式,拖到firefox上就会提示安装了,安装后重启ff,右下角就会有一个向下的小箭头图标了,说明插件安装成功了。

最后我们开发一个c#窗体程序来接受windows消息。


新建一个c# windows程序,把默认窗体的Text属性改成WawaApp,因为在XPCOM里给WawaApp窗口发消息,所以要用改成这样,否则就得在XPCOM里用broadcastsystemmessage进行消息广播。在窗体上放一个TextBox准备显示收过来的数据。主要的代码如下

using System;
using System.Runtime.InteropServices;
using System.Web;
using System.Windows.Forms;

namespace ShowWeb
{
    
public partial class Form1 : Form
    {
        
private const int WM_COPYDATA = 0x004A;

        
public Form1()
        {
            InitializeComponent();
        }

        
private void handlerMessage(string message)
        {
            
if (InvokeRequired)
            {
                BeginInvoke(
new handlerMessageDelegate(handlerMessage));
            }
            textBox1.Text 
= message;
        }

        
protected override void WndProc(ref Message m)
        {
            
if (m.Msg == WM_COPYDATA)
            {
                COPYDATASTRUCT dat 
= (COPYDATASTRUCT) Marshal.PtrToStructure(
                                                          m.LParam, 
typeof (COPYDATASTRUCT));
                handlerMessage(HttpUtility.UrlDecode(dat.lpData));
                
return;
            }
            
base.WndProc(ref m);
        }

        
#region Nested type: COPYDATASTRUCT

        [StructLayout(LayoutKind.Sequential)]
        
public struct COPYDATASTRUCT
        {
            
public IntPtr dwData;
            
public int cbData;
            [MarshalAs(UnmanagedType.LPWStr)] 
public string lpData;
        }

        
#endregion

        
#region Nested type: handlerMessageDelegate

        
private delegate void handlerMessageDelegate(string message);

        
#endregion
    }
}

大概解释一下,COPYDATASTRUCT用来接受WM_COPYDATA传递过来的数据,因为要传递宽字符,所以用UnmanagedType.LPWStr修饰,重写WndProc方法可以有机会在第一事件捕获本窗体收到的windows消息并加以处理,我们在这里截获WM_COPYDATA消息,用Marshal.PtrToStructure把收到的消息转换成c#的结构体,并把收到的数据进行url解码,然后调用handlerMessage方法来处理,handlerMessage方法是一个简化的winform多线程方案,如果InvokeRequired为true就调用BeginInvoke调用本身,否则执行给文本框直接赋值,这样做是为了不让界面线程把接受消息的线程给hang住。


主要参考链接


基于Mozilla平台的扩展开发(续)----XPCOM组件篇
实战 Firefox 扩展开发
FireFox Extension 开发 Helloworld
How to Build an XPCOM Component in Javascript
Firefox 3 for developers
【Firefox扩展】XPInstall的安装脚本浅析

其它参考链接


86件Firefox浏览器能而IE不能做的事
http://blog.donews.com/demson/archive/2004/11/28/185689.aspx

101件Firefox能而IE不能做的事
http://www.qqread.com/surfing/x241103051_3.html

Creating XPCOM Components
http://www.mozilla.org/projects/xpcom/book/cxc/

VC中自定义消息实现
http://citycowboy.blog.sohu.com/82319571.html

进程通信问题——RegisterWindowMessage和PostMessage
http://topic.csdn.net/t/20030522/23/1821663.html

在.NET中基于Windows消息的IPC实现
http://www.cnblogs.com/wzd24/archive/2007/05/22/755013.html

LPCTSTR、LPTSTR、_T和CString几种类型的区别
http://topic.csdn.net/t/20020928/11/1060535.html

如何获得字符串的长度?
http://topic.csdn.net/t/20030105/20/1329194.html

BSTR、char*和CString转换
http://www.cnblogs.com/justin/archive/2005/03/24/125057.aspx

用C#获得Autosuggest中数据
http://www.winbile.net/bbs/forums/threads/1024219.aspx

VC传给 C#的char*指针,C#中怎么使用
http://www.itzhe.cn/article/20080229/97292.html

利用XPCOM技术实现Firefox跨平台文件操作JavaScript类
http://www.cnblogs.com/jessezhao/archive/2008/06/10/1216146.html

用C++ 编写 Mozilla XPCom
http://rogerfd.cn/?p=165

创建C++ XPCOM组件
http://zhouchengly.blogspot.com/2007/06/creating-c-xpcom-component-xpcom-step.html

利用VC创建XPCOM组件
http://hi.baidu.com/xzq2000/blog/item/30260ff4f75cbd6fddc474ac.html

一步一步创建VC2005解决方案(转)
http://www.cnblogs.com/rainbowzc/archive/2008/09/09/1287880.html

用Visual Studio创建XPCOM组件
http://blog.csdn.net/chinesejimmy/archive/2007/06/01/1634075.aspx

How to build a binary XPCOM component using Visual Studio
https://developer.mozilla.org/en/How_to_build_a_binary_XPCOM_component_using_Visual_Studio

Firefox插件开发-技术和开发网站
http://www.yuanma.org/data/2007/0730/article_2776.htm

XPCOM
https://developer.mozilla.org/cn/XPCOM

A C++ Firefox component intercepting/operating HTML DOM
http://www.codeproject.com/KB/library/firefox_component.aspx

创建C++ XPCOM组件
http://zhouchengly.blogspot.com/2007/06/creating-c-xpcom-component-xpcom-step.html

怎样将char *转换为LPCWSTR ?
http://topic.csdn.net/t/20030701/00/1975664.html

VS2005中const char *转换为LPCWSTR的方法Unicode
http://chenet.blogbus.com/logs/28070247.html

在eclipse中动态开发Firefox扩展
http://xinsync.xju.edu.cn/index.php/archives/2135

技巧: 使用 Firefox 3.0 Extensions 中新的微格式 API
http://www.ibm.com/developerworks/cn/xml/x-tipffoxmicroapi/index.html?ca=drs-cn-0630

用C++ 编写 Mozilla XPCom
http://rogerfd.cn/?p=165

XPCOM LINUX下的组件开发技术
http://blog.csdn.net/wangweixing2000/archive/2007/09/03/1770576.aspx

关于XPCOM开发的问题
http://topic.csdn.net/u/20081110/10/e3d1b8d2-2c30-4ff7-b712-0c4951b18e37.html

 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!