Code Monkey home page Code Monkey logo

qtcms's Introduction

文件夹结构
-|-include                             公共文件夹
 |-libs                                Activity和plugin的生成目录
 |-output                              工程的发布目录
 |-src
  |-activities                         放置各个Activity
  |-common                             公共文件
  |-libpcom                            pcom源文件
  |-plugins                            放置各个plugin
  |-QTTest                             可执行主程序
 |-vs project                          vs2010工程文件
 |-web                                 web ui 文件
 
1.output目录的配置
	1.1将web目录下的内容,拷贝到output/Debug和output/Release下
	1.2将src/libpcom下的pcom_config.xml文件,拷贝到output/Debug和output/Release下

2.创建Activity
	2.1在解决方案内添加一个新项目,项目类型为Qt Library,选择在src/activities下存放项目
	2.2项目配置
		2.2.1配置属性->常规:
			2.2.1.1输出目录:$(SolutionDir)..\libs\
			2.2.1.2中间目录:$(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\
		2.2.2配置属性->C/C++->常规:
			附加包含目录中添加:$(SolutionDir)..\include\
		2.2.3配置属性->链接器->输入
			附加依赖项中添加:$(SolutionDir)..\libs\libpcom.lib
		2.2.4配置属性->生成事件->后期生成事件
			命令行:copy  "$(outdir)$(TargetFileName)" "$(SolutionDir)..\output\$(Configuration)\"
	2.3修改项目向导生成的文件
		2.3.1删除xxxxxx_global.h内的导出符号定义代码
		2.3.2修改xxxxxx.h文件
			2.3.2.1删除xxxxxx_EXPORT导出符号
			2.3.2.2包含头文件IActivities.h和qwfw.h
			2.3.2.3类增加继承父类和接口,依次为 QWebUiFWBase、IActivities,并在类声明内添加Q_OBJECT宏
			2.3.2.4添加以下几个从父类继承来的虚函数
				virtual long __stdcall QueryInterface(const IID & iid,void **ppv);
    		virtual unsigned long __stdcall AddRef();
    		virtual unsigned long __stdcall Release();
				virtual void Active( QWebFrame * frame);
		2.3.3修改xxxxxx.cpp文件
			2.3.3.1实现QueryInterface函数,根据传进来的iid,返回对应的接口指针,具体可以参照previewactivity.cpp中代码
			2.3.3.2实现Add和Release函数,实现实例的自释放,具体参照previewactivity.cpp中代码
			2.3.3.3实现Active函数,在函数中添加以下代码
				QWFW_MSGMAP_BEGIN(frame);
				// Todo: Add your message map here
				QWFW_MSGMAP_END;
			2.3.3.4消息响应,参照第4章的“如何实现消息响应”
	2.4CreateInstance的实现和导出
		项目中需要实现 IPcomBase * CreateInstance(); 函数,并将该函数导出,导出时需要注意添加extern "C"
		具体方式可以参照previewactivity中的dllmain.h,dllmain.cpp和previewactivity.def三个文件
		添加.def文件时需要修改项目属性:
		配置属性->链接器->输入:
			模块定义文件:添加到项目中的.def文件名
	2.5将src/common下的guid.cpp文件添加到项目中
		2.5.1在guid.cpp中添加一个CLSID,可以使用vs2010工具中的"创建 GUID"生成,具体格式可以参照其他CLSID
		2.5.2在guid.h中添加新生成的CLSID的声明,具体格式可以参照其他CLSID
	2.6修改src/libpcom下的pcom_config.xml文件,在文件的CLSID节点下新增一个item节点,节点中添加clsid,name,file及title属性
		2.6.1 clsid的值为2.5中新添加的CLSID的值
		2.6.2 name的值为开头必须以"activity.",分隔符"."后可以使用自己命名的名称
		2.6.3 file的值为生成的动态库dll相对QtTest.exe的路径,最前端不需要加"./"
		2.6.4 title的值为该activity所对应的html文件的标题

3.创建Plugin
	3.1在解决方案内添加一个新项目,项目类型为Qt Library,选择在src/plugins下存放项目
	3.2项目配置
		3.2.1配置属性->常规:
			3.2.1.1输出目录:$(SolutionDir)..\libs\
			3.2.1.2中间目录:$(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)
		3.2.2配置属性->C/C++->常规:
			附加包含目录中添加:$(SolutionDir)..\include\
		3.2.3配置属性->链接器->输入
			附加依赖项中添加:$(SolutionDir)..\libs\libpcom.lib
		3.2.4配置属性->生成事件->后期生成事件
			命令行:copy  "$(outdir)$(TargetFileName)" "$(SolutionDir)..\output\$(Configuration)\plugins"
	3.3修改项目向导生成的文件
		3.3.1删除xxxxxx_global.h内的导出符号定义代码
		3.3.2修改xxxxxx.h文件
			3.3.2.1删除xxxxxx_EXPORT导出符号
			3.3.2.2包含头文件IWebPluginBase.h
			3.3.2.3类增加继承父类和接口,依次为 QObject、IWebPluginBase
			3.3.2.4添加以下几个从父类继承来的虚函数
				virtual long __stdcall QueryInterface( const IID & iid,void **ppv );
				virtual unsigned long __stdcall AddRef();
				virtual unsigned long __stdcall Release();
				virtual QList<QWebPluginFactory::Plugin> plugins() const;
				virtual QObject * create( const QString& mimeType, const QUrl&, const QStringList& argumentNames, const QStringList& argumentValues ) const;
		3.3.3修改xxxxxx.cpp文件
			3.3.3.1添加头文件QtPlugin.h
			3.3.3.2实现QueryInterface函数,根据传进来的iid,返回对应的接口指针,具体可以参照previewactivity.cpp中代码
			3.3.3.3实现Add和Release函数,实现实例的自释放,具体参照previewactivity.cpp中代码
			3.3.3.4实现plugins和create函数,在函数中添加以下代码
				plugins函数返回一个列表,该列表描述了该库内所支持的插件的信息,具体实现可以参考viewwndplugin.cpp
				create函数根据mimeType,创建相应的插件对象并返回,具体实现可以参考viewwndplugin.cpp
			3.3.3.5添加宏Q_EXPORT_PLUGIN2(PLUGIN,PLUGINCLS),该宏用于导出插件的相关函数,PLUGIN为一个字符串,即生成的插件的文件名,PLUGINCLS为插件的类名
	3.4CreateInstance的实现和导出
		项目中需要实现 IPcomBase * CreateInstance(); 函数,并将该函数导出,导出时需要注意添加extern "C"
		具体方式可以参照previewactivity中的dllmain.h,dllmain.cpp和previewactivity.def三个文件
		添加.def文件时需要修改项目属性:
		配置属性->链接器->输入:
			模块定义文件:添加到项目中的.def文件名
	3.5将src/common下的guid.cpp文件添加到项目中
		2.5.1在guid.cpp中添加一个CLSID,可以使用vs2010工具中的"创建 GUID"生成,具体格式可以参照其他CLSID
		2.5.2在guid.h中添加新生成的CLSID的声明,具体格式可以参照其他CLSID
	3.6修改src/libpcom下的pcom_config.xml文件,在文件的CLSID节点下新增一个item节点,节点中添加clsid,name,file及mimetype属性
		3.6.1 clsid的值为3.5中新添加的CLSID的值
		3.6.2 name的值为开头必须以"plugin.",分隔符"."后可以使用自己命名的名称
		3.6.3 file的值为生成的动态库dll相对QtTest.exe的路径,最前端不需要加"./"
		3.6.4 mimetype的值为该plugin所对应的mimetype
		
4.如何实现消息响应
    项目中采用一个html页面对应一个Activity的方式来实现UI的模块化和动态插入,实现
  html上相关元素的一些UI交互操作除了采用Javascript之外,还可以由Activity来实现。
  以下步骤实现html上的消息,映射到Activity中的代码。
  4.1将src/QTTest下的qframework.js文件拷贝到输出目录
  4.2在需要做消息映射的html内,包含文件qframework.js
  4.3为html内需要映射消息的元素添加一个id,该id必须在页面内唯一
  4.4在Activity的Active函数中插入宏QWFW_MSGMAP(id,msg,proc),id,msg和proc都是
     用引号"包裹起来的字符串:
     4.4.1 id为在4.3中定义的id
     4.4.2 msg为id所对应的元素的消息类型,如mousedown,dblclick等,具体的消息类
           型可以查阅html的相关文档
     4.4.3 proc为Activity内的函数名,该函数必须声明为slots
  4.5声明并实现4.4中引用的proc函数,proc函数即为响应html元素id的msg消息的消息函数
  4.6同一id的同一个消息可以映射到多个消息函数,消息函数的调用顺序为QWFW_MSGMAP声明
     时的顺序,例如:
			void previewactivity::Active( QWebFrame * frame)
			{
				QWFW_MSGMAP_BEGIN(frame);
				QWFW_MSGMAP("top_act","dblclick","OnTopActDbClick2(event.clientX,event.clientY)");
				QWFW_MSGMAP("top_act","dblclick","OnTopActDbClick()");
				QWFW_MSGMAP_END;
			}
			
			void previewactivity::OnTopActDbClick()
			{
				qDebug("OnTopActDbClick");
			}

			void previewactivity::OnTopActDbClick2( int x,int y )
			{
				qDebug("OnTopActDbClick2:%d,%d",x,y);
			}
			以上代码,OnTopActDbClick和OnTopActDbClick2都将被执行,并且将先执行OnTopActDbClick2,
			然后再执行OnTopActDbClick,当双击top_act时,执行结果如下:
			OnTopActDbClick2:526,18
			OnTopActDbClick
			 
  4.7消息函数没有固定的参数,但是消息函数的名称、类型必须和QWFW_MSGMAP中声明的一直,
     比如html中一个id为btn的按钮元素
     QWFW_MSGMAP("btn","mousedown","OnBtnMouseDown()");
     QWFW_MSGMAP("btn","mousedown","OnBtnMouseDown(event.clientX,event.clientY)");
     两种QWFW_MSGMAP声明都是被允许的,第一种声明必须对应实现函数
     void OnBtnMouseDown();
     而第二种声明必须对应实现函数
     void OnBtnMouseDown(int x,int y);
     
5.Plugin与页面的交互
	5.1提供函数给页面调用
	  插件的实际工作实例是由Create返回的实例,该实例的类必须直接或者间接继承至QObject类,
	  并且加上Q_OBJECT宏。只需要将函数定义为public slots,外部的页面就可以直接调用该插件
	  函数,具体实例请参考ViewWndPlugin及plugintest.html。
	5.2反馈给页面事件
		事件是插件主动通知页面的一种方式。本项目中的事件,都不带参数。
		5.2.1如何在插件中加入事件(可参考ViewWndPlugin的qfviewedit类)
			5.2.1.1在插件的实例类中,包含头文件qwfw.h,为实例类添加public父类QWebPluginFWBase,
			  实例需要直接或者间接继承于QWidget
			5.2.1.2在插件的实例类中,声明以下的slots函数:
				void AddEventProc( const QString sEvent,QString sProc );
			5.2.1.3AddEventProc函数的实现
				void xxxPluginInstance::void AddEventProc( const QString sEvent,QString sProc )
				{
					m_mapEventProc.insertMulti(sEvent,sProc);
				}
			5.2.1.4事件的调用
				在需要抛出事件的地方,调用函数void EventProcCall(QString sEvent),其中参数sEvent为
				事件名称。
		5.2.2页面中如何定义事件响应(可参考web/plugintest.html)
			5.2.2.1在页面中插入插件
				页面中通过插入<object>标签来插入插件。需要注意的是<object>标签必须以标签对的方式出
				现,即<object></object>的方式;而以<object />方式插入的标签,则不支持。
				标签中必须加入属性type,该属性的值即插件的mimetype。另外如果需要在javascripte脚本中
				调用的话,需要加入id属性。
			5.2.2.2在页面中定义事件响应
				插件提供了以下函数,用于定义事件响应
				AddEventProc(event,proc);
				event:事件类型,参数类型为字符串
				proc:响应事件,可以是一段JavaScripte脚本,需要用单引号或双引号包裹
				同一个事件可以添加多个事件响应处理,事件响应处理的调用顺序和AddEventProc的调用顺序有关
				
6.页面接受Activity的事件通知
	  有些情况下,页面需要接收Activity的通知,以便知道Activity一些功能处理的状况。以下步骤描述了
	页面如何绑定事件,及Activity如何抛出事件。
	6.1页面绑定事件
	  页面通过调用函数AddActivityEvent来将事件处理函数和Activity的事件进行绑定,AddActivityEvent
	在qframework.js中定义,函数的原型如下:
		function AddActivityEvent(e,proc);
		其中e为Activity中定义的事件名称,通过字符串的方式传入;proc为页面中定义的事件处理函数。
		proc声	明为如下类似的函数:
	  function EventPorc(ev);
	  其中ev为JSON对象,由Activity抛出事件时传出,ev具体的内容由各个Activity自行定义。
	6.2Activity抛出事件
	  Activity事件抛出函数为EventProcCall,该函数在qwfw.h中定义,其函数原型定义如下:
	  void EventProcCall(QString sEvent,QVariantMap eventParam);
	  其中sEvent为事件名称,页面绑定事件时即使用该名称进行绑定。eventParam为事件参数。eventParam由
	一系列宏初始化。
	  宏DEF_EVENT_PARAM(v)对参数进行声明,EP_ADD_PARAM(v,name,value)对参数进行设置。
	  Activity在需要抛出事件的地方,首先声明并初始化事件参数,然后调用EventProcCall来将对应的事件抛
	出。
	6.3代码示例
		示例中定义了一个事件"useraddresult",事件参数包含以下内容
		name:用户名
		level:用户权限等级
		result:执行结果
	  
	  6.3.1 html上的JS代码
	  <script src="js/qframework.js" type="text/javascript"></script><!--引用相关的框架js-->
	  
	  <script type="text/javascript">
	  // 事件处理函数,此处示例仅仅弹出一个对话框提示执行结果
	  function evProc(ev){
	  	alert('Add user ' + ev.name + ' result:' + ev.result);
	  }
	  
	  // 将事件useraddresult绑定到处理函数evPorc上
	  AddActivityEvent('useraddresult','evProc(ev)');
	  </script>
	  
	  6.3.2 Activity抛出事件
	  
	  void AddUser()
	  {
	  	// 处理用户添加功能,最后执行结果保存在nResult中
	  	// 用户名保存在sName中,用户权限等级保存在nLevel中
	  	... //若干行代码
	  	
	  	// 声明事件参数
	  	DEF_EVENT_PARAM(paramTemp);
	  	// 初始化各项参数
	  	EP_ADD_PARAM(paramTemp,"name",sName);
	  	EP_ADD_PARAM(paramTemp,"level",nLevel);
	  	EP_ADD_PARAM(paramTemp,"result",sResult);
	  	// 抛出事件
	  	EventProcCall("useraddresult",paramTemp);
	  } 
	
			

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.