diff --git a/ZbaSDK/Package/ZbaEngine.dll b/ZbaSDK/Package/ZbaEngine.dll
new file mode 100644
index 0000000000000000000000000000000000000000..750e713fde23637ef3e5cafabfc6f2bf1ec96bde
Binary files /dev/null and b/ZbaSDK/Package/ZbaEngine.dll differ
diff --git a/ZbaSDK/Package/ZbaPackage.exe b/ZbaSDK/Package/ZbaPackage.exe
new file mode 100644
index 0000000000000000000000000000000000000000..0954f70d57ab190ac715962968434d82273cea94
Binary files /dev/null and b/ZbaSDK/Package/ZbaPackage.exe differ
diff --git a/ZbaSDK/Package/ZbaSafe.wdb b/ZbaSDK/Package/ZbaSafe.wdb
new file mode 100644
index 0000000000000000000000000000000000000000..2971a0830d7f8ad5cfd0adcb3623ed326e9d2048
Binary files /dev/null and b/ZbaSDK/Package/ZbaSafe.wdb differ
diff --git "a/ZbaSDK/PluginOK\344\270\255\351\227\264\344\273\266\345\256\211\345\205\250\350\247\243\345\206\263\346\226\271\346\241\210.doc" "b/ZbaSDK/PluginOK\344\270\255\351\227\264\344\273\266\345\256\211\345\205\250\350\247\243\345\206\263\346\226\271\346\241\210.doc"
new file mode 100644
index 0000000000000000000000000000000000000000..78a77352af96adef37a5a0d7e6ce838b61055df4
Binary files /dev/null and "b/ZbaSDK/PluginOK\344\270\255\351\227\264\344\273\266\345\256\211\345\205\250\350\247\243\345\206\263\346\226\271\346\241\210.doc" differ
diff --git "a/ZbaSDK/PluginOK\344\270\255\351\227\264\344\273\266\346\216\210\346\235\203\346\234\215\345\212\241\345\231\250\351\205\215\347\275\256\350\257\264\346\230\216.doc" "b/ZbaSDK/PluginOK\344\270\255\351\227\264\344\273\266\346\216\210\346\235\203\346\234\215\345\212\241\345\231\250\351\205\215\347\275\256\350\257\264\346\230\216.doc"
new file mode 100644
index 0000000000000000000000000000000000000000..9ef287bfd4c0b6df6283a1f9ae6c3616a9aa7b91
Binary files /dev/null and "b/ZbaSDK/PluginOK\344\270\255\351\227\264\344\273\266\346\216\210\346\235\203\346\234\215\345\212\241\345\231\250\351\205\215\347\275\256\350\257\264\346\230\216.doc" differ
diff --git "a/ZbaSDK/PluginOK\345\274\200\345\217\221\350\200\205\346\211\213\345\206\214.doc" "b/ZbaSDK/PluginOK\345\274\200\345\217\221\350\200\205\346\211\213\345\206\214.doc"
new file mode 100644
index 0000000000000000000000000000000000000000..df57d5060168376b06a572f50b7c20318c597171
Binary files /dev/null and "b/ZbaSDK/PluginOK\345\274\200\345\217\221\350\200\205\346\211\213\345\206\214.doc" differ
diff --git "a/ZbaSDK/PluginOK\346\240\270\345\277\203\347\273\204\344\273\266\346\216\245\345\217\243\350\257\264\346\230\216.xls" "b/ZbaSDK/PluginOK\346\240\270\345\277\203\347\273\204\344\273\266\346\216\245\345\217\243\350\257\264\346\230\216.xls"
new file mode 100644
index 0000000000000000000000000000000000000000..481b71ee549cf1008ef4095f2d83de06313158a5
Binary files /dev/null and "b/ZbaSDK/PluginOK\346\240\270\345\277\203\347\273\204\344\273\266\346\216\245\345\217\243\350\257\264\346\230\216.xls" differ
diff --git a/ZbaSDK/SampleCode/Bin/ZbaApplet.dll b/ZbaSDK/SampleCode/Bin/ZbaApplet.dll
new file mode 100644
index 0000000000000000000000000000000000000000..c886f287d811635043b669de7c6f9aa7f3266974
Binary files /dev/null and b/ZbaSDK/SampleCode/Bin/ZbaApplet.dll differ
diff --git a/ZbaSDK/SampleCode/Bin/ZbaBase.dll b/ZbaSDK/SampleCode/Bin/ZbaBase.dll
new file mode 100644
index 0000000000000000000000000000000000000000..859dda027fbb5e05d359bbfd3f7d05fd0d498a0e
Binary files /dev/null and b/ZbaSDK/SampleCode/Bin/ZbaBase.dll differ
diff --git a/ZbaSDK/SampleCode/Bin/ZbaEngine.dll b/ZbaSDK/SampleCode/Bin/ZbaEngine.dll
new file mode 100644
index 0000000000000000000000000000000000000000..750e713fde23637ef3e5cafabfc6f2bf1ec96bde
Binary files /dev/null and b/ZbaSDK/SampleCode/Bin/ZbaEngine.dll differ
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.cpp b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f0a0d3490806f005558cde8918457c960c10445
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.cpp
@@ -0,0 +1,86 @@
+// PluginComDll.cpp : DLL 导出的实现。
+
+#include "stdafx.h"
+#include "resource.h"
+#include "PluginComDll_i.h"
+#include "dllmain.h"
+#include "xdlldata.h"
+
+// 用于确定 DLL 是否可由 OLE 卸载。
+STDAPI DllCanUnloadNow(void)
+{
+#ifdef _MERGE_PROXYSTUB
+ HRESULT hr = PrxDllCanUnloadNow();
+ if (hr != S_OK)
+ return hr;
+#endif
+ return _AtlModule.DllCanUnloadNow();
+}
+
+// 返回一个类工厂以创建所请求类型的对象。
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+#ifdef _MERGE_PROXYSTUB
+ if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
+ return S_OK;
+#endif
+ return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
+}
+
+// DllRegisterServer - 在系统注册表中添加项。
+STDAPI DllRegisterServer(void)
+{
+ // 注册对象、类型库和类型库中的所有接口
+ HRESULT hr = _AtlModule.DllRegisterServer();
+#ifdef _MERGE_PROXYSTUB
+ if (FAILED(hr))
+ return hr;
+ hr = PrxDllRegisterServer();
+#endif
+ return hr;
+}
+
+// DllUnregisterServer - 在系统注册表中移除项。
+STDAPI DllUnregisterServer(void)
+{
+ HRESULT hr = _AtlModule.DllUnregisterServer();
+#ifdef _MERGE_PROXYSTUB
+ if (FAILED(hr))
+ return hr;
+ hr = PrxDllRegisterServer();
+ if (FAILED(hr))
+ return hr;
+ hr = PrxDllUnregisterServer();
+#endif
+ return hr;
+}
+
+// DllInstall - 按用户和计算机在系统注册表中逐一添加/移除项。
+STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
+{
+ HRESULT hr = E_FAIL;
+ static const wchar_t szUserSwitch[] = L"user";
+
+ if (pszCmdLine != NULL)
+ {
+ if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)
+ {
+ ATL::AtlSetPerUserRegistration(true);
+ }
+ }
+
+ if (bInstall)
+ {
+ hr = DllRegisterServer();
+ if (FAILED(hr))
+ {
+ DllUnregisterServer();
+ }
+ }
+ else
+ {
+ hr = DllUnregisterServer();
+ }
+
+ return hr;
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.def b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.def
new file mode 100644
index 0000000000000000000000000000000000000000..762038f675a9249c09fcddc1d5d07ee641eebcf5
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.def
@@ -0,0 +1,10 @@
+; PluginComDll.def : 定义模块参数。
+
+LIBRARY
+
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
+ DllInstall PRIVATE
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.idl b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.idl
new file mode 100644
index 0000000000000000000000000000000000000000..5026697238b251acbbab818e834a19afe1d7dc36
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.idl
@@ -0,0 +1,74 @@
+// PluginComDll.idl : PluginComDll 的 IDL 源
+//
+
+// 此文件将由 MIDL 工具处理以
+// 产生类型库(PluginComDll.tlb)和封送处理代码。
+
+import "oaidl.idl";
+import "ocidl.idl";
+
+[
+ object,
+ uuid(C38672FA-B5C8-4D9D-89B5-2D71F0760661),
+ dual,
+ nonextensible,
+ pointer_default(unique)
+]
+interface ITextFile : IDispatch{
+};
+
+[
+ object,
+ uuid(E46E1B5B-2891-414F-A21A-17B00231E650),
+ dual,
+ nonextensible,
+ pointer_default(unique)
+]
+interface ISysInfo : IDispatch{
+};
+
+[
+ uuid(A22E18F1-95F8-4FDB-99D2-188E5FB12B23),
+ version(1.0),
+]
+library PluginComDllLib
+{
+ importlib("stdole2.tlb");
+
+ [
+ uuid(40756D41-E6C7-4648-80C4-AB70A325F831)
+ ]
+ dispinterface _ITextFileEvents
+ {
+ properties:
+ methods:
+ };
+
+ [
+ uuid(40613676-C8A5-4879-A59B-9CE6406476F6)
+ ]
+ coclass TextFile
+ {
+ [default] interface ITextFile;
+ [default, source] dispinterface _ITextFileEvents;
+ };
+
+ [
+ uuid(FAC6FC19-9B22-4904-A656-581FCB35EC98)
+ ]
+ dispinterface _ISysInfoEvents
+ {
+ properties:
+ methods:
+ };
+
+ [
+ uuid(6D7595BD-BFB0-4D2C-906B-247028691A50)
+ ]
+ coclass SysInfo
+ {
+ [default] interface ISysInfo;
+ [default, source] dispinterface _ISysInfoEvents;
+ };
+};
+
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.rc b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.rc
new file mode 100644
index 0000000000000000000000000000000000000000..24a37d1d104fb282c3fa86dfeb7c542933ae228e
Binary files /dev/null and b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.rc differ
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.rgs b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.rgs
new file mode 100644
index 0000000000000000000000000000000000000000..e7d37400e19a24d70c54739df67e0024251a65b6
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.rgs
@@ -0,0 +1,3 @@
+HKCR
+{
+}
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.sln b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.sln
new file mode 100644
index 0000000000000000000000000000000000000000..03a33b3ff7c6f128f58c9d9ba6be6123ef6aa786
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.sln
@@ -0,0 +1,26 @@
+锘
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginComDll", "PluginComDll.vcxproj", "{880E1365-4E58-469D-809B-6BE3B1D1EC5F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Debug|Win32.Build.0 = Debug|Win32
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Debug|x64.ActiveCfg = Debug|x64
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Debug|x64.Build.0 = Debug|x64
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Release|Win32.ActiveCfg = Release|Win32
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Release|Win32.Build.0 = Release|Win32
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Release|x64.ActiveCfg = Release|x64
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.suo b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.suo
new file mode 100644
index 0000000000000000000000000000000000000000..6e74689e9c38f5d30ce8a2fe92bf27afde7a85bf
Binary files /dev/null and b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.suo differ
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.vcxproj b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..b579fb733f390bcf423f211f7e6553da5091ff21
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.vcxproj
@@ -0,0 +1,316 @@
+锘
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {880E1365-4E58-469D-809B-6BE3B1D1EC5F}
+ AtlProj
+
+
+
+
+
+
+
+
+
+ DynamicLibrary
+ true
+ Dynamic
+ Unicode
+
+
+ DynamicLibrary
+ true
+ Dynamic
+ Unicode
+
+
+ DynamicLibrary
+ false
+ Static
+ Unicode
+
+
+ DynamicLibrary
+ false
+ Static
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ \$(Configuration)\$(Platform)\Plugins\$(ProjectName)\
+ $(Configuration)\$(Platform)\$(ProjectName)\
+
+
+ true
+ true
+ \$(Configuration)\$(Platform)\Plugins\$(ProjectName)\
+ $(Configuration)\$(Platform)\$(ProjectName)\
+
+
+ true
+ false
+ \$(Configuration)\$(Platform)\Plugins\$(ProjectName)\
+ \$(Configuration)\$(Platform)\$(ProjectName)\
+
+
+ true
+ false
+ \$(Configuration)\$(Platform)\Plugins\$(ProjectName)\
+ \$(Configuration)\$(Platform)\$(ProjectName)\
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ false
+ Win32
+ _DEBUG;%(PreprocessorDefinitions)
+ PluginComDll_i.h
+ PluginComDll_i.c
+ PluginComDll_p.c
+ true
+ $(IntDir)PluginComDll.tlb
+
+
+ true
+
+
+ 0x0804
+ $(IntDir);%(AdditionalIncludeDirectories)
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\PluginComDll.def
+ true
+ false
+ \$(Configuration)\$(Platform)\$(TargetName).pdb
+
+
+
+
+ Use
+ Level3
+ Disabled
+ _WIN64;WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ false
+ _DEBUG;%(PreprocessorDefinitions)
+ PluginComDll_i.h
+ PluginComDll_i.c
+ PluginComDll_p.c
+ true
+ $(IntDir)PluginComDll.tlb
+
+
+
+
+ 0x0804
+ $(IntDir);%(AdditionalIncludeDirectories)
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\PluginComDll.def
+ true
+ false
+ \$(Configuration)\$(Platform)\$(TargetName).pdb
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+ false
+ Win32
+ NDEBUG;%(PreprocessorDefinitions)
+ PluginComDll_i.h
+ PluginComDll_i.c
+ PluginComDll_p.c
+ true
+ $(IntDir)PluginComDll.tlb
+
+
+ true
+
+
+ 0x0804
+ $(IntDir);%(AdditionalIncludeDirectories)
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\PluginComDll.def
+ true
+ true
+ true
+ false
+ \$(Configuration)\$(Platform)\$(TargetName).pdb
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ _WIN64;WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+ PluginComDll_i.h
+ PluginComDll_i.c
+ PluginComDll_p.c
+ true
+ $(IntDir)PluginComDll.tlb
+
+
+
+
+ 0x0804
+ $(IntDir);%(AdditionalIncludeDirectories)
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\PluginComDll.def
+ true
+ true
+ true
+ false
+ \$(Configuration)\$(Platform)\$(TargetName).pdb
+
+
+
+
+ false
+ false
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+ false
+ false
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+ false
+ false
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginComDll.vcxproj.filters b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..aaebbe2129c403cbfb9b3f0f34ffe211842b6673
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginComDll.vcxproj.filters
@@ -0,0 +1,110 @@
+锘
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {8153f5ab-ee41-475a-9302-f858f98c99a9}
+ False
+
+
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+ 鐢熸垚鐨勬枃浠
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 鐢熸垚鐨勬枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+ 婧愭枃浠
+
+
+ 璧勬簮鏂囦欢
+
+
+ 璧勬簮鏂囦欢
+
+
+ 璧勬簮鏂囦欢
+
+
+
+
+ 婧愭枃浠
+
+
+
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/PluginConfig.json b/ZbaSDK/SampleCode/PluginComDll/PluginConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..a154d3ea10127716d8d5f15b39f283fe91d62772
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/PluginConfig.json
@@ -0,0 +1,27 @@
+{
+ "Type": 1,
+ "OS": 1,
+ "Control": 0,
+ "OSMinVer": "5.0",
+ "Version": "2.0.2.1",
+ "Name": "鏃犵獥鍙e皬绋嬪簭鑼冧緥(C++璇█)",
+ "Corp": "ZorroSoft",
+ "Icon": "",
+ "Date": "2020.08.25",
+ "Desc": "鏃犵獥鍙e皬绋嬪簭(C++璇█)-璇诲啓TXT璁颁簨鏈強鑾峰彇褰撳墠绯荤粺淇℃伅",
+ "Home": "http://zorrosoft.com/WRL",
+ "Down": "http://zorrosoft.com/WRL",
+ "Module": "PluginComDll.dll",
+ "PID": "A22E18F1-95F8-4FDB-99D2-188E5FB12B23",
+ "Objects": [
+ {
+ "ProgID": "C38672FA-B5C8-4D9D-89B5-2D71F0760661",
+ "ClassID": "40613676-C8A5-4879-A59B-9CE6406476F6"
+ },
+ {
+ "ProgID": "E46E1B5B-2891-414F-A21A-17B00231E650",
+ "ClassID": "6D7595BD-BFB0-4D2C-906B-247028691A50"
+ }
+ ],
+ "Updates": []
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/ReadMe.txt b/ZbaSDK/SampleCode/PluginComDll/ReadMe.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2b18d781a4e0e3245483a795f99ee552095e57e2
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/ReadMe.txt
@@ -0,0 +1,60 @@
+锘========================================================================
+ 娲诲姩妯℃澘搴 : PluginComDll 椤圭洰姒傝堪
+========================================================================
+
+搴旂敤绋嬪簭鍚戝宸蹭负鎮ㄥ垱寤轰簡姝 PluginComDll 椤圭洰锛屼綔涓虹紪鍐欏姩鎬侀摼鎺ュ簱 (DLL)
+鐨勮捣鐐广
+
+鏈枃浠舵瑕佷粙缁嶇粍鎴愰」鐩殑姣忎釜鏂囦欢鐨勫唴瀹广
+
+PluginComDll.vcxproj
+ 杩欐槸浣跨敤搴旂敤绋嬪簭鍚戝鐢熸垚鐨 VC++ 椤圭洰鐨勪富椤圭洰鏂囦欢锛
+ 鍏朵腑鍖呭惈鐢熸垚璇ユ枃浠剁殑 Visual C++ 鐨勭増鏈俊鎭紝
+ 浠ュ強鏈夊叧浣跨敤搴旂敤绋嬪簭鍚戝閫夋嫨鐨勫钩鍙般侀厤缃拰椤圭洰鍔熻兘鐨勪俊鎭
+
+PluginComDll.vcxproj.filters
+ 杩欐槸浣跨敤鈥滃簲鐢ㄧ▼搴忓悜瀵尖濈敓鎴愮殑 VC++ 椤圭洰绛涢夊櫒鏂囦欢銆
+ 瀹冨寘鍚湁鍏抽」鐩枃浠朵笌绛涢夊櫒涔嬮棿鐨勫叧鑱斾俊鎭 鍦 IDE 涓紝閫氳繃杩欑鍏宠仈锛
+ 鍦ㄧ壒瀹氳妭鐐逛笅浠ュ垎缁勫舰寮忔樉绀哄叿鏈夌浉浼兼墿灞曞悕鐨勬枃浠躲
+ 渚嬪锛屸.cpp鈥濇枃浠朵笌鈥滄簮鏂囦欢鈥濈瓫閫夊櫒鍏宠仈銆
+
+PluginComDll.idl
+ 姝ゆ枃浠跺寘鍚」鐩腑瀹氫箟鐨勭被鍨嬪簱銆佹帴鍙e拰缁勪欢绫荤殑 IDL 瀹氫箟銆
+ 姝ゆ枃浠跺皢鐢 MIDL 缂栬瘧鍣ㄥ鐞嗕互鐢熸垚锛
+ C++ 鎺ュ彛瀹氫箟鍜 GUID 澹版槑 (PluginComDll.h)
+ GUID 瀹氫箟 (PluginComDll_i.c)
+ 绫诲瀷搴 (PluginComDll.tlb)
+ 灏侀佸鐞嗕唬鐮 (PluginComDll_p.c 鍜
+ dlldata.c锛
+
+PluginComDll.h
+ 姝ゆ枃浠跺寘鍚 PluginComDll.idl 涓畾涔夌殑椤圭洰鐨 C++ 鎺ュ彛瀹氫箟
+ 鍜 GUID 澹版槑銆 瀹冨皢鍦ㄧ紪璇戣繃绋嬩腑鐢 MIDL 閲嶆柊鐢熸垚銆
+
+PluginComDll.cpp
+ 姝ゆ枃浠跺寘鍚璞℃槧灏勫拰 DLL 瀵煎嚭鐨勫疄鐜般
+
+PluginComDll.rc
+ 杩欐槸绋嬪簭浣跨敤鐨勬墍鏈 Microsoft Windows 璧勬簮鐨勫垪琛ㄣ
+
+PluginComDll.def
+ 姝ゆā鍧楀畾涔夋枃浠朵负閾炬帴鍣ㄦ彁渚涙湁鍏 DLL 鎵瑕佹眰鐨勫鍑虹殑淇℃伅锛
+ 瀹冨寘鍚敤浜庝互涓嬪唴瀹圭殑瀵煎嚭锛
+ DllGetClassObject
+ DllCanUnloadNow
+ DllRegisterServer
+ DllUnregisterServer
+ DllInstall
+
+/////////////////////////////////////////////////////////////////////////////
+鍏朵粬鏍囧噯鏂囦欢锛
+
+StdAfx.h锛孲tdAfx.cpp
+ 杩欎簺鏂囦欢鐢ㄤ簬鐢熸垚鍚嶄负 PluginComDll.pch 鐨勯缂栬瘧澶 (PCH) 鏂囦欢鍜
+ 鍚嶄负 StdAfx.obj 鐨勯缂栬瘧绫诲瀷鏂囦欢銆
+
+Resource.h
+ 杩欐槸鐢ㄤ簬瀹氫箟璧勬簮 ID 鐨勬爣鍑嗗ご鏂囦欢銆
+
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/ZbaSDK/SampleCode/PluginComDll/SysInfo.cpp b/ZbaSDK/SampleCode/PluginComDll/SysInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa2eb6d7840964c2fd014fef578c0f3a0e4f703a
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/SysInfo.cpp
@@ -0,0 +1,29 @@
+// SysInfo.cpp : CSysInfo 的实现
+
+#include "stdafx.h"
+#include "SysInfo.h"
+#include
+
+// CSysInfo
+STDMETHODIMP CSysInfo::RecText(BSTR bstrContent)
+{
+ // TODO: Add your implementation code here
+ ATLASSERT(NULL != m_spiSocketConnect);
+ if(NULL == bstrContent || NULL == m_spiSocketConnect)
+ return E_POINTER;
+ m_spiSocketConnect->put_ActiveTime(COleDateTime::GetCurrentTime().m_dt);
+ /// 请处理收到的文本信息,这里演示直接回复原内容
+ ULONG nReqID = 0;
+ m_spiSocketConnect->AsynSendText(bstrContent,&nReqID);
+ return S_OK;
+}
+
+STDMETHODIMP CSysInfo::RecJson(ULONG nReqID,BSTR bstrReqName,BSTR bstrContent)
+{
+ // TODO: Add your implementation code here
+ ATLASSERT(NULL != m_spiSocketConnect);
+ if(NULL == bstrContent || NULL == m_spiSocketConnect)
+ return E_POINTER;
+ /// 请处理收到的普通JSON数据包
+ return S_OK;
+}
diff --git a/ZbaSDK/SampleCode/PluginComDll/SysInfo.h b/ZbaSDK/SampleCode/PluginComDll/SysInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..e32b90348c14c36bdbfebdf8da190faed26151e3
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/SysInfo.h
@@ -0,0 +1,116 @@
+// SysInfo.h : CSysInfo 的声明
+
+#pragma once
+#include "resource.h" // 主符号
+#ifdef _USRDLL
+#include "PluginComDll_i.h"
+#else
+#include "PluginComExe_i.h"
+#endif
+#include "_ISysInfoEvents_CP.h"
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
+#endif
+
+// CSysInfo
+
+class ATL_NO_VTABLE CSysInfo :
+ public CComObjectRootEx,
+ public CComCoClass,
+ public IConnectionPointContainerImpl,
+ public CProxy_ISysInfoEvents,
+#ifdef _USRDLL
+ public IDispatchImpl,
+#else
+ public IDispatchImpl,
+#endif
+ public IDispatchImpl
+{
+protected:
+ /// WEB SOCKET连接对象
+ IWebSocketConnectPtr m_spiSocketConnect;
+
+public:
+ CSysInfo()
+ :m_spiSocketConnect(NULL)
+ {
+ }
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_SYSINFO)
+
+ BEGIN_COM_MAP(CSysInfo)
+ COM_INTERFACE_ENTRY(ISysInfo)
+ COM_INTERFACE_ENTRY2(IDispatch, IWrlConn)
+ COM_INTERFACE_ENTRY(IConnectionPointContainer)
+ COM_INTERFACE_ENTRY(IWrlConn)
+ END_COM_MAP()
+
+ BEGIN_CONNECTION_POINT_MAP(CSysInfo)
+ CONNECTION_POINT_ENTRY(__uuidof(_ISysInfoEvents))
+ END_CONNECTION_POINT_MAP()
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ HRESULT FinalConstruct()
+ {
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ if (NULL != m_spiSocketConnect)
+ m_spiSocketConnect = NULL;
+ }
+
+public:
+
+ // IWrlConn Methods
+ STDMETHOD(Load)(LPDISPATCH piDispatch,BSTR bstrAuthInfo,BSTR bstrLang)
+ {
+ HRESULT hRet = piDispatch->QueryInterface(IID_IWebSocketConnect,(LPVOID *)&m_spiSocketConnect);
+ ATLASSERT(NULL != m_spiSocketConnect);
+ return hRet;
+ }
+
+ STDMETHOD(Unload)(EWrlCloseConnType eCloseConnType, BSTR bstrReason)
+ {
+ if(NULL != m_spiSocketConnect)
+ m_spiSocketConnect = NULL;
+ return S_OK;
+ }
+
+ STDMETHOD(UsbChanged)(BSTR bstrDisk, ULONG nStatus, BSTR bstrName)
+ {
+ /// 收到USB变化通知
+ return S_OK;
+ }
+
+ STDMETHOD(SendJson)(BSTR bstrContent)
+ {
+ HRESULT hRet(S_FALSE);
+ if (NULL != m_spiSocketConnect)
+ {
+ ULONG nRet = 0;
+ hRet = m_spiSocketConnect->AsynSendText(bstrContent, &nRet);
+ }
+ return hRet;
+ }
+
+ STDMETHOD(RecText)(BSTR bstrContent);
+
+ STDMETHOD(RecJson)(ULONG nReqID,BSTR bstrReqName,BSTR bstrContent);
+
+ STDMETHOD(RecByte)(BYTE* pContent,ULONG nLen)
+ {
+ return S_FALSE;
+ }
+
+ STDMETHOD(HttpRequst)(BSTR bstrUrl,BSTR bstrPara, BSTR* pVal)
+ {
+ /// HTTP服务请求响应
+ return E_NOTIMPL;
+ }
+};
+
+OBJECT_ENTRY_AUTO(__uuidof(SysInfo), CSysInfo)
diff --git a/ZbaSDK/SampleCode/PluginComDll/SysInfo.rgs b/ZbaSDK/SampleCode/PluginComDll/SysInfo.rgs
new file mode 100644
index 0000000000000000000000000000000000000000..bafa94b88814bfa0828b584ec5bfe067560ffe20
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/SysInfo.rgs
@@ -0,0 +1,26 @@
+HKCR
+{
+ PluginComDll.SysInfo.1 = s 'SysInfo Class'
+ {
+ CLSID = s '{6D7595BD-BFB0-4D2C-906B-247028691A50}'
+ }
+ PluginComDll.SysInfo = s 'SysInfo Class'
+ {
+ CurVer = s 'PluginComDll.SysInfo.1'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {6D7595BD-BFB0-4D2C-906B-247028691A50} = s 'SysInfo Class'
+ {
+ ProgID = s 'PluginComDll.SysInfo.1'
+ VersionIndependentProgID = s 'PluginComDll.SysInfo'
+ ForceRemove Programmable
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ TypeLib = s '{A22E18F1-95F8-4FDB-99D2-188E5FB12B23}'
+ Version = s '1.0'
+ }
+ }
+}
diff --git a/ZbaSDK/SampleCode/PluginComDll/TextFile.cpp b/ZbaSDK/SampleCode/PluginComDll/TextFile.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b300cfea07c486a2b3c6f716c4c5c344e3e5cf8f
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/TextFile.cpp
@@ -0,0 +1,122 @@
+// TextFile.cpp : CTextFile 的实现
+
+#include "stdafx.h"
+#include
+#include "TextFile.h"
+
+// CTextFile
+STDMETHODIMP CTextFile::RecText(BSTR bstrContent)
+{
+ // TODO: Add your implementation code here
+ if(NULL == bstrContent || NULL == m_spiSocketConnect)
+ {
+ return E_POINTER;
+ }
+ HRESULT hRet = m_spiSocketConnect->put_ActiveTime(COleDateTime::GetCurrentTime().m_dt);
+
+ /// 请处理收到的文本信息,这里演示直接回复原内容
+ hRet = m_spiSocketConnect->AsynSendText(bstrContent,NULL);
+ ATLASSERT(SUCCEEDED(hRet));
+ /// 也可以直接发送二进制数据流,建议把二进制流进行编码后再传输
+// BYTE szContent[] = "TestByte";
+// hRet = m_spiSocketConnect->AsynSendByte(szContent,strlen((char*)szContent),NULL);
+ return hRet;
+}
+
+ATL::CString GetSpecialFolderPath(long lFoldID)
+{
+ TCHAR szSpecialPath[MAX_PATH];
+ ::memset(szSpecialPath,0,MAX_PATH*sizeof(TCHAR));
+ BOOL bGetFlag = ::SHGetSpecialFolderPath(NULL,szSpecialPath,lFoldID,TRUE);
+ if(!bGetFlag)
+ {
+ return _T("");
+ }
+
+ ATL::CString strSpecialPath(szSpecialPath);
+ ///路径后面都有"\"
+ if(!strSpecialPath.IsEmpty() && 0 != strSpecialPath.Right(1).CompareNoCase(_T("\\")))
+ strSpecialPath+=_T("\\");
+ return strSpecialPath;
+}
+
+STDMETHODIMP CTextFile::RecJson(ULONG nReqID,BSTR bstrReqName,BSTR bstrContent)
+{
+ // TODO: Add your implementation code here
+ ATLASSERT(NULL != m_spiSocketConnect);
+ if(NULL == bstrContent || NULL == m_spiSocketConnect)
+ return E_POINTER;
+ m_spiSocketConnect->put_ActiveTime(COleDateTime::GetCurrentTime().m_dt);
+ IJsonServicePtr spiJsonService = NULL;
+ HRESULT hRet = spiJsonService.CreateInstance(__uuidof(JsonService));
+ if(NULL == spiJsonService)
+ return hRet;/// 创建JSON解析器对象失败
+ VARIANT_BOOL bLoadFlag = VARIANT_FALSE;
+ spiJsonService->put_CodingType(CODINGTYPE_US2);
+ hRet = spiJsonService->ParseString(bstrContent,&bLoadFlag);
+ if(VARIANT_FALSE == bLoadFlag)
+ {
+ spiJsonService = NULL;
+ return hRet;
+ }
+ /// 请处理收到的普通JSON数据包
+ /// 在这里解析请求并作出回应
+ CString strReqName(bstrReqName);
+ if(0 == strReqName.CompareNoCase(L"Demo_WriteFile"))
+ {
+ CString strFilePath = GetSpecialFolderPath(CSIDL_COMMON_DESKTOPDIRECTORY);
+ CComBSTR bstrVal;
+ spiJsonService->GetStringValue(CComBSTR(L"Name"),&bstrVal);;
+ strFilePath += bstrVal.m_str;
+ bstrVal.Empty();
+ spiJsonService->GetStringValue(CComBSTR(L"Content"),&bstrVal);;
+ CString strContent = bstrVal.m_str;
+ bstrVal.Empty();
+
+ CTextFileWrite WriteFile(strFilePath);
+ WriteFile.Write(strContent);
+ WriteFile.Close();
+ CString strReturn;
+ strContent.Replace(L"\"",L"\\\"");
+ strFilePath.Replace(L"\\",L"/");
+ strReturn.Format(_T("{\"rid\":%ld,\"data\":{\"Content\":\"%s\"}}"), \
+ nReqID,strFilePath + L" 文件写入完成");
+ m_spiSocketConnect->AsynSendText(CComBSTR(strReturn),NULL);
+ }
+ else if(0 == strReqName.CompareNoCase(L"Demo_ReadFile"))
+ {
+ CString strFilePath = GetSpecialFolderPath(CSIDL_COMMON_DESKTOPDIRECTORY);
+ CComBSTR bstrVal;
+ spiJsonService->GetStringValue(CComBSTR(L"Name"),&bstrVal);;
+ strFilePath += bstrVal.m_str;
+ bstrVal.Empty();
+
+ CString strReturn;
+ CTextFileRead ReadFile(strFilePath);
+ string strLine;
+ while(ReadFile.ReadLine(strLine))
+ {
+ if(!strLine.length())
+ continue;/// 空行不发送
+ strReturn.Empty();
+ strReturn.Format(_T("{\"rid\":%ld,\"data\":{\"ReadLine\":\"%s\"}}"), \
+ nReqID,CString(strLine.c_str()));
+ m_spiSocketConnect->AsynSendText(CComBSTR(strReturn),NULL);
+ strLine.clear();
+ }
+ ReadFile.Close();
+ strReturn.Empty();
+ strReturn.Format(_T("{\"rid\":%ld,\"data\":{\"End\":\"%s\"}}"), \
+ nReqID,L"读取完成");
+ m_spiSocketConnect->AsynSendText(CComBSTR(strReturn), NULL);
+ }
+ else
+ {
+ CString strReturn,strContent(bstrContent);
+ strContent.Replace(L"\"",L"\\\"");
+ strReturn.Format(L"{\"rid\":%ld,\"data\":{\"Req\":\"%s\",\"Content\":\"%s\",\"Status\":\"不识别的请求\"}}",\
+ nReqID,strReqName,strContent);
+ m_spiSocketConnect->AsynSendText(CComBSTR(strReturn), NULL);
+ }
+ return S_OK;
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/TextFile.h b/ZbaSDK/SampleCode/PluginComDll/TextFile.h
new file mode 100644
index 0000000000000000000000000000000000000000..62c0303b77b6dca8df9bbd0c78c5f313fed6ad91
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/TextFile.h
@@ -0,0 +1,122 @@
+// TextFile.h : CTextFile 的声明
+
+#pragma once
+#include "resource.h" // 主符号
+#include
+#ifdef _USRDLL
+#include "PluginComDll_i.h"
+#else
+#include "PluginComExe_i.h"
+#endif
+#include "_ITextFileEvents_CP.h"
+#include "TextFileHelper.h"
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
+#endif
+
+// CTextFile
+
+class ATL_NO_VTABLE CTextFile :
+ public CComObjectRootEx,
+ public CComCoClass,
+ public IConnectionPointContainerImpl,
+ public CProxy_ITextFileEvents,
+#ifdef _USRDLL
+ public IDispatchImpl,
+#else
+ public IDispatchImpl,
+#endif
+ public IDispatchImpl
+{
+protected:
+
+ /// WEB SOCKET连接对象
+ IWebSocketConnectPtr m_spiSocketConnect;
+
+public:
+ CTextFile()
+ :m_spiSocketConnect(NULL)
+ {
+ }
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_TEXTFILE)
+
+ BEGIN_COM_MAP(CTextFile)
+ COM_INTERFACE_ENTRY(ITextFile)
+ COM_INTERFACE_ENTRY2(IDispatch, IWrlConn)
+ COM_INTERFACE_ENTRY(IConnectionPointContainer)
+ COM_INTERFACE_ENTRY(IWrlConn)
+ END_COM_MAP()
+
+ BEGIN_CONNECTION_POINT_MAP(CTextFile)
+ CONNECTION_POINT_ENTRY(__uuidof(_ITextFileEvents))
+ END_CONNECTION_POINT_MAP()
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ HRESULT FinalConstruct()
+ {
+ return S_OK;
+ }
+
+ void FinalRelease()
+ {
+ if (NULL != m_spiSocketConnect)
+ m_spiSocketConnect = NULL;
+ }
+
+public:
+
+ // IWrlConn Methods
+ STDMETHOD(Load)(LPDISPATCH piDispatch,BSTR bstrAuthInfo,BSTR bstrLang)
+ {
+ if(NULL == piDispatch)
+ return E_POINTER;
+ HRESULT hRet = piDispatch->QueryInterface(IID_IWebSocketConnect,(LPVOID *)&m_spiSocketConnect);
+ if(NULL != m_spiSocketConnect)
+ hRet = m_spiSocketConnect->put_ActiveTime(COleDateTime::GetCurrentTime().m_dt);
+ return hRet;
+ }
+
+ STDMETHOD(Unload)(EWrlCloseConnType eCloseConnType, BSTR bstrReason)
+ {
+ if(NULL != m_spiSocketConnect)
+ m_spiSocketConnect = NULL;
+ return S_OK;
+ }
+
+ STDMETHOD(UsbChanged)(BSTR bstrDisk, ULONG nStatus, BSTR bstrName)
+ {
+ /// 收到USB变化通知
+ return S_OK;
+ }
+
+ STDMETHOD(SendJson)(BSTR bstrContent)
+ {
+ HRESULT hRet(S_FALSE);
+ if (NULL != m_spiSocketConnect)
+ {
+ ULONG nRet = 0;
+ hRet = m_spiSocketConnect->AsynSendText(bstrContent,&nRet);
+ }
+ return hRet;
+ }
+
+ STDMETHOD(RecText)(BSTR bstrContent);
+
+ STDMETHOD(RecJson)(ULONG nReqID,BSTR bstrReqName,BSTR bstrContent);
+
+ STDMETHOD(RecByte)(BYTE* pContent,ULONG nLen)
+ {
+ return S_FALSE;
+ }
+
+ STDMETHOD(HttpRequst)(BSTR bstrUrl,BSTR bstrPara, BSTR* pVal)
+ {
+ /// HTTP服务请求响应
+ return E_NOTIMPL;
+ }
+};
+
+OBJECT_ENTRY_AUTO(__uuidof(TextFile), CTextFile)
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/TextFile.rgs b/ZbaSDK/SampleCode/PluginComDll/TextFile.rgs
new file mode 100644
index 0000000000000000000000000000000000000000..0f807b8de0a70aa813e41e3f6b39873dee2e0cc0
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/TextFile.rgs
@@ -0,0 +1,26 @@
+HKCR
+{
+ PluginComDll.TextFile.1 = s 'TextFile Class'
+ {
+ CLSID = s '{40613676-C8A5-4879-A59B-9CE6406476F6}'
+ }
+ PluginComDll.TextFile = s 'TextFile Class'
+ {
+ CurVer = s 'PluginComDll.TextFile.1'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {40613676-C8A5-4879-A59B-9CE6406476F6} = s 'TextFile Class'
+ {
+ ProgID = s 'PluginComDll.TextFile.1'
+ VersionIndependentProgID = s 'PluginComDll.TextFile'
+ ForceRemove Programmable
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ TypeLib = s '{A22E18F1-95F8-4FDB-99D2-188E5FB12B23}'
+ Version = s '1.0'
+ }
+ }
+}
diff --git a/ZbaSDK/SampleCode/PluginComDll/TextFileHelper.cpp b/ZbaSDK/SampleCode/PluginComDll/TextFileHelper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..44b8589ba7da54a11499b4b813869a146d3b73d9
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/TextFileHelper.cpp
@@ -0,0 +1,1592 @@
+/* NOTE: If you running this in a none-Windows platform,
+ then you should remove the include file below.
+ */
+#include "stdafx.h"
+#include "TextFileHelper.h"
+
+#if PEK_TX_TECHLEVEL == 0
+ //Include iostream if running in ANSI mode.
+ #include
+#endif
+
+#pragma warning( disable : 4996)
+
+//在段模式下,没条记录允许的段数
+#define ENABLESECTION_SECTION_COUNT 10
+
+//Base constructor
+CTextFileBase::CTextFileBase()
+{
+ #if PEK_TX_TECHLEVEL > 0
+ m_codepage = CP_ACP;
+ m_unknownChar = 0;
+ #else
+ m_unknownChar = '?';
+ #endif
+
+ #if PEK_TX_TECHLEVEL == 1
+ m_hFile = INVALID_HANDLE_VALUE;
+ #elif PEK_TX_TECHLEVEL == 2
+ m_file = NULL;
+ m_closeAndDeleteFile = false;
+ #endif
+
+ m_datalost = false;
+
+ m_buffpos = -1;
+}
+
+//Base destructor
+CTextFileBase::~CTextFileBase()
+{
+ Close();
+}
+
+//Set which character to use when conversion can't be done
+void CTextFileBase::SetUnknownChar(const char unknown)
+{
+ m_unknownChar = unknown;
+}
+
+//True if data was lost during conversion
+bool CTextFileBase::IsDataLost() const
+{
+ return m_datalost;
+}
+
+//Reset the data lost flag
+void CTextFileBase::ResetDataLostFlag()
+{
+ m_datalost = false;
+}
+
+#if PEK_TX_TECHLEVEL > 0
+
+//Make sure we have a legal value for code page to use when
+//converting string. Used for debugging only.
+#define IsLegalCodePage(cp) (cp == CP_ACP || cp == CP_MACCP || cp == CP_OEMCP || cp == CP_SYMBOL || cp == CP_THREAD_ACP || cp == CP_UTF7 || cp == CP_UTF8 || IsValidCodePage(cp))
+
+//(Windows-specific) Set codepage to use when working with non-unicode strings.
+void CTextFileBase::SetCodePage(const UINT codepage)
+{
+ ATLASSERT(IsLegalCodePage(codepage));
+ m_codepage = codepage;
+}
+
+//(Windows-specific) Get codepage to use when working with non-unicode strings.
+UINT CTextFileBase::GetCodePage() const
+{
+ return m_codepage;
+}
+
+//(Windows-specific) Convert string to wstring with current codepage
+inline void CTextFileBase::CharToWstring(const char* from, wstring &to) const
+{
+ ConvertCharToWstring(from, to, m_codepage);
+}
+
+//(Windows-specific) Convert wstring to string with current codepage
+inline void CTextFileBase::WcharToString(const wchar_t* from, string &to)
+{
+ ConvertWcharToString(from, to, m_codepage, &m_datalost, m_unknownChar);
+}
+
+//(Windows-specific) Convert char* to wstring
+void CTextFileBase::ConvertCharToWstring(const char* from, wstring &to, UINT codepage)
+{
+ to = L"";
+
+ ATLASSERT(IsLegalCodePage(codepage));
+ //Use api convert routine
+ int wlen = MultiByteToWideChar( codepage,
+ 0,
+ from,
+ -1,
+ NULL,
+ 0);
+
+ //if wlen == 0, some unknown codepage was probably used.
+ ATLASSERT(wlen);
+ if(wlen == 0)
+ return;
+
+ wchar_t* wbuffer = new wchar_t[wlen+2];
+
+ MultiByteToWideChar( codepage,
+ 0,
+ from,
+ -1,
+ wbuffer,
+ wlen);
+ to = wbuffer;
+ delete [] wbuffer;
+
+}
+
+//(Windows-specific) Convert wchar_* to string
+void CTextFileBase::ConvertWcharToString(const wchar_t* from, string &to,
+ UINT codepage, bool* datalost, char unknownchar)
+{
+ to = "";
+
+ ATLASSERT(IsLegalCodePage(codepage));
+
+ int alen = WideCharToMultiByte( codepage,
+ 0,
+ from,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+
+ //if alen == 0, some unknown codepage was probably used.
+ ATLASSERT(alen);
+ if(alen == 0)
+ return;
+ //Use mfc convert routine
+ char* abuffer = new char[alen+2];
+ BOOL UsedDefault=FALSE;
+
+ WideCharToMultiByte( codepage,
+ 0,
+ from,
+ -1,
+ abuffer,
+ alen,
+ (unknownchar != 0 ? &unknownchar : NULL),
+ (datalost != NULL ? &UsedDefault : NULL)
+ );
+
+ if( datalost != NULL && UsedDefault != FALSE)
+ *datalost = true;
+
+ to = abuffer;
+ delete [] abuffer;
+}
+
+#else
+
+//(None-windows-specific) Convert string to wstring
+inline void CTextFileBase::CharToWstring(const char* from, wstring &to) const
+{
+ ConvertCharToWstring(from, to);
+}
+
+//(None-windows-specific) Convert wstring to string
+inline void CTextFileBase::WcharToString(const wchar_t* from, string &to)
+{
+ ConvertWcharToString(from, to, &m_datalost, m_unknownChar);
+}
+
+//(None-windows-specific) Convert char* to wstring
+void CTextFileBase::ConvertCharToWstring(const char* from, wstring &to)
+{
+ to = L"";
+
+ size_t pos=0;
+ wchar_t temp[1];
+
+ while(true)
+ {
+ size_t len = mbtowc(temp, from+pos, MB_CUR_MAX);
+ //Found end
+ if(len == 0)
+ return;
+ else if(len == (size_t)-1)
+ {
+ //Unknown character, should never happen
+ pos++;
+ }
+ else
+ {
+ to += temp[0];
+ pos += len;
+ }
+ }
+}
+
+//(None-windows-specific) Convert wchar_* to string
+void CTextFileBase::ConvertWcharToString(const wchar_t* from, string &to, bool* datalost, char unknownchar)
+{
+ to = "";
+ char* temp = new char[MB_CUR_MAX];
+ while(*from != L'\0')
+ {
+ size_t len = wctomb(temp, *from);
+
+ //Found end
+ if(len == 0)
+ break;
+ else if(len == (size_t)-1)
+ {
+ //Replace with unknown character
+ to += unknownchar;
+
+ if(datalost != NULL)
+ *datalost=true;
+ }
+ else
+ {
+ //Copy all characters
+ for(size_t i=0; im_hFile != CFile::hFileNull);
+#endif
+}
+
+//Close file
+void CTextFileBase::Close()
+{
+ if(IsOpen())
+ {
+#if PEK_TX_TECHLEVEL == 0
+ m_file.close();
+#elif PEK_TX_TECHLEVEL == 1
+ ::CloseHandle(m_hFile);
+ m_hFile = INVALID_HANDLE_VALUE;
+#else
+ if(m_closeAndDeleteFile)
+ {
+ m_file->Close();
+ }
+#endif
+ }
+
+#if PEK_TX_TECHLEVEL == 2
+ if(m_closeAndDeleteFile)
+ {
+ delete m_file;
+ m_file = NULL;
+ }
+#endif
+}
+
+BOOL IsPathExist(const ATL::CString& strPath)
+{
+ BOOL bRet = FALSE;
+ if(strPath.IsEmpty())
+ return bRet;
+ WIN32_FIND_DATA data;
+ BOOL bFindDir = FALSE;
+
+ ATL::CString strFind(strPath);
+ if (0 == strPath.Right(1).CompareNoCase( _T("\\")))
+ {
+ /// 查找目录
+ bFindDir = TRUE;
+ strFind+=_T("*.*");
+ }
+
+ HANDLE hFindFile = ::FindFirstFile(strFind,&data);
+ if(INVALID_HANDLE_VALUE != hFindFile)
+ {
+ if(bFindDir)
+ {
+ while(INVALID_HANDLE_VALUE != hFindFile)
+ {
+ if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
+ {
+
+ bRet = TRUE;
+ break;
+ }
+ if (!FindNextFile(hFindFile,&data))
+ break;
+ }
+ }
+ else
+ bRet = TRUE;
+ ::FindClose(hFindFile);
+ hFindFile = NULL;
+ }
+ else
+ bRet=FALSE;
+ return bRet;
+}
+
+BOOL CreatePath(const ATL::CString& strLocalDir)
+{
+ BOOL bCreateFlag = FALSE;
+ ATL::CString strWorkDir,strPath=strLocalDir;
+ int index = -2;
+ index = strPath.Find(_T('\\'));
+ if(index == -1)
+ return FALSE;
+ strWorkDir = strPath.Left(index);
+ strPath.Delete(0,index+1);
+ while(strPath.GetLength())
+ {
+ index=strPath.Find(_T('\\'));
+ if(index == -1)
+ {
+ bCreateFlag = ::CreateDirectory(strLocalDir,NULL);
+ strWorkDir.Empty();
+ strPath.Empty();
+ break;
+ }
+ strWorkDir+=_T("\\");
+ strWorkDir+=strPath.Left(index);
+ strPath.Delete(0,index+1);
+ if(!IsPathExist(strWorkDir+_T("\\")))
+ bCreateFlag = ::CreateDirectory(strWorkDir,NULL);
+ }
+ if(!bCreateFlag)
+ {
+ DWORD dwErrCode = ::GetLastError();
+ ::Sleep(100);
+ }
+ return bCreateFlag;
+}
+
+//Create textfile
+CTextFileWrite::CTextFileWrite(const FILENAMECHAR* filename, TEXTENCODING encoding)
+{
+ CString strFilPath(filename);
+ int iFind = strFilPath.ReverseFind(_T('\\'));
+ if(-1 != iFind)
+ {
+ /// 创建目录
+ CreatePath(strFilPath.Left(iFind));
+ }
+
+#if PEK_TX_TECHLEVEL == 0
+ m_file.open(filename, ios::binary | ios::out );
+#elif PEK_TX_TECHLEVEL == 1
+
+ m_hFile = ::CreateFile( filename,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+#else
+ m_file = new CFile;
+ m_file->Open(filename, CFile::modeCreate | CFile::modeWrite);
+
+ m_closeAndDeleteFile = true;
+#endif
+ m_buffpos = -1;
+ m_buffsize = 0;
+
+ m_encoding = encoding;
+
+ WriteBOM();
+}
+
+#if PEK_TX_TECHLEVEL==2
+//Create textfile from CFile object
+CTextFileWrite::CTextFileWrite(CFile* file, TEXTENCODING encoding)
+{
+ ATLASSERT(file);
+
+ m_file = file;
+ m_closeAndDeleteFile = false;
+
+ m_encoding = encoding;
+
+ m_buffpos = -1;
+ m_buffsize = 0;
+
+ WriteBOM();
+}
+#endif
+
+CTextFileWrite::~CTextFileWrite()
+{
+ Close();
+}
+
+void CTextFileWrite::WriteBOM()
+{
+ //Write BOM
+ if(IsOpen())
+ {
+ if(m_encoding == UNI16_BE || m_encoding == UNI16_LE)
+ {
+ //Write BOM
+ WriteWchar( 0xFEFF );
+ }
+ else if(m_encoding == UTF_8)
+ {
+ //Write UTF-8 BOM. 0xEF 0xBB 0xBF
+ WriteByte(0xEF);
+ WriteByte(0xBB);
+ WriteByte(0xBF);
+ }
+ }
+}
+
+//Write one byte
+void CTextFileWrite::WriteByte(const unsigned char byte)
+{
+ //Instead of writing, save data in buffer and write when buffer is full
+ if(m_buffpos+1 >= BUFFSIZE)
+ Flush();
+
+ m_buffpos++;
+ m_buf[m_buffpos] = byte;
+}
+
+//Write and empty buffer
+void CTextFileWrite::Flush()
+{
+#if PEK_TX_TECHLEVEL==0
+ m_file.write(m_buf, m_buffpos+1);
+#elif PEK_TX_TECHLEVEL==1
+
+ DWORD nWritten;
+ if (!::WriteFile(m_hFile, m_buf, m_buffpos+1, &nWritten, NULL))
+ {
+ //Something bad has happend! Close file
+ CTextFileBase::Close();
+
+ //Throw exception
+ throw CTextFileException(GetLastError());
+ }
+
+#else
+ m_file->Write(m_buf, m_buffpos+1);
+#endif
+
+ m_buffpos = -1;
+}
+
+void CTextFileWrite::WriteWchar(const wchar_t ch)
+{
+ //Write HO byte first?
+ if(m_encoding == UNI16_BE)
+ {
+ //Write HO byte
+ WriteByte((unsigned char) (ch >> 8) );
+ //Write LO byte
+ WriteByte((unsigned char) ch);
+ }
+ else if(m_encoding == UNI16_LE)
+ {
+ //Write LO byte
+ WriteByte((unsigned char) ch);
+ //Write HO byte
+ WriteByte((unsigned char) (ch >> 8) );
+ }
+ else
+ {
+ //http://www.cl.cam.ac.uk/~mgk25/unicode.html#examples
+ //http://www.ietf.org/rfc/rfc3629.txt
+
+ //Just a single byte?
+ if(ch <= 0x7F)
+ {
+ //U-00000000 - U-0000007F: 0xxxxxxx
+ WriteByte( (unsigned char) ch );
+ }
+
+ //Two bytes?
+ else if(ch <= 0x7FF)
+ {
+ //U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
+ WriteByte( (unsigned char) (0xC0 | (ch>>6)) );
+ WriteByte( (unsigned char) (0x80 | (ch&0x3F)) );
+ }
+
+ //Three bytes?
+ else if(ch <= 0xFFFF)
+ {
+ //U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
+ WriteByte( (unsigned char) (0xE0 | ( ch>>12) ));
+ WriteByte( (unsigned char) (0x80 | ( (ch>>6)&0x3F ) ));
+ WriteByte( (unsigned char) (0x80 | ( ch&0x3F ) ));
+ }
+
+ /* //UPS! I did some coding for UTF-32, may be useful in the future :-)
+ //Four bytes?
+ else if(ch <= 0x1FFFFF)
+ {
+ //U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ WriteByte( (unsigned char) (0xF0 | ( ch>>18) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>12)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>6)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( ch&0xA0 ) ));
+ }
+
+ //Five bytes bytes?
+ else if(ch <= 0x3FFFFFF)
+ {
+ //U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ WriteByte( (unsigned char) (0xF8 | ( ch>>24) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>18)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>12)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>6)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( ch&0xA0 ) ));
+ }
+
+ //Five bytes bytes?
+ else if(ch <= 0x7FFFFFFF)
+ {
+ //U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ WriteByte( (unsigned char) (0xFC | ( ch>>30) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>24)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>18)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>12)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( (ch>>6)&0xA0 ) ));
+ WriteByte( (unsigned char) (0xA0 | ( ch&0xA0 ) ));
+ }*/
+ }
+}
+
+//Write new line
+void CTextFileWrite::WriteEndl()
+{
+ if(m_encoding == ASCII)
+ {
+ WriteByte(0x0D);
+ WriteByte(0x0A);
+ }
+ else
+ {
+ WriteWchar(0x0D);
+ WriteWchar(0x0A);
+ }
+}
+
+//Write a c-string in ASCII.
+//In versions before 1.02 this function wrote directly to file,
+//no buffer was used. But sense WriteEndl() used buffer the file was
+//written incorretly. Now buffer is used here too, this is the
+//fastest solution.
+void CTextFileWrite::WriteAsciiString(const char* s)
+{
+ while(*s != '\0')
+ {
+ WriteByte(*s);
+ s++;
+ }
+}
+
+CTextFileWrite& CTextFileWrite::operator<< (const char* text)
+{
+ Write(text);
+ return *this;
+};
+
+CTextFileWrite& CTextFileWrite::operator << (const string& text)
+{
+ Write(text.c_str());
+ return *this;
+}
+
+CTextFileWrite& CTextFileWrite::operator<< (const wchar_t* text)
+{
+ Write(text);
+ return *this;
+};
+
+CTextFileWrite& CTextFileWrite::operator << (const wstring& text)
+{
+ Write(text.c_str());
+ return *this;
+}
+
+CTextFileWrite& CTextFileWrite::operator<< (const wchar_t wc)
+{
+ //Not the perfect code, but it's easy!
+ wstring text;
+ text=wc;
+ Write(text.c_str());
+ return *this;
+};
+
+CTextFileWrite& CTextFileWrite::operator<< (const char c)
+{
+ //Not the perfect code, but it's easy!
+ string text;
+ text=c;
+ Write(text.c_str());
+ return *this;
+};
+
+BOOL CTextFileWrite::Write(const string& text)
+{
+ try
+ {
+ Write(text.c_str());
+ }
+ catch ( ... )
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL CTextFileWrite::Write(const wstring& text)
+{
+ try
+ {
+ Write(text.c_str());
+ }
+ catch ( ... )
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//Write char*
+void CTextFileWrite::Write(const char* text)
+{
+ //ASCIItext file format?
+ if(m_encoding == ASCII)
+ WriteAsciiString(text);
+ else
+ {
+ //Convert text to unicode
+ wstring utext;
+ CharToWstring(text, utext);
+
+ //OK, lets write unicode
+ for(wstring::const_iterator i=utext.begin();
+ i < utext.end();
+ i++)
+ {
+ WriteWchar(*i);
+ }
+
+ }
+}
+
+//Write wcar_t*
+void CTextFileWrite::Write(const wchar_t* utext)
+{
+ //ASCII text file format?
+ if(m_encoding == ASCII)
+ {
+ //Convert to string and write
+ string text;
+ WcharToString(utext, text);
+ WriteAsciiString(text.c_str());
+ }
+ else
+ {
+ while(*utext != 0)
+ {
+ WriteWchar(*utext);
+ utext++;
+ }
+ }
+}
+
+//Close the file
+void CTextFileWrite::Close()
+{
+ if(IsOpen())
+ Flush();
+
+ CTextFileBase::Close();
+}
+
+CTextFileRead::CTextFileRead(const FILENAMECHAR* filename)
+{
+
+#if PEK_TX_TECHLEVEL==0
+ //If not Windows, do this
+ m_file.open(filename, ios::binary | ios::in);
+#elif PEK_TX_TECHLEVEL == 1
+
+ m_hFile = ::CreateFile( filename,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+#else
+ m_file = new CFile;
+ //In windows, do this
+ m_file->Open(filename, CFile::modeRead | CFile::shareDenyWrite );
+ m_closeAndDeleteFile = true;
+#endif
+
+ m_firstLine = true;
+ m_endoffile = (IsOpen()==0);
+
+ //Force reading to buffer next time
+ m_buffpos=-1;
+
+ m_useExtraBuffer = false;
+
+ //段落信息无效
+ m_section_enable = false;
+
+ m_buf_first_section = -1;
+ m_wbuf_first_section = -1;
+
+ m_current_pos = 0;
+ m_section_count = 0;
+
+ m_dirty = false;
+
+ ReadBOM();
+}
+
+#if PEK_TX_TECHLEVEL==2
+CTextFileRead::CTextFileRead(CFile* file)
+{
+ ATLASSERT(file);
+
+ m_file = file;
+ m_closeAndDeleteFile = false;
+
+ m_firstLine = true;
+ m_endoffile = (IsOpen()==0);
+
+ //Force reading to buffer next time
+ m_buffpos=-1;
+
+ m_useExtraBuffer=false;
+
+ ReadBOM();
+}
+#endif
+
+void CTextFileRead::ReadBOM()
+{
+ if( IsOpen() )
+ {
+ unsigned char bytes[2];
+
+ //Read the first two bytes
+ ReadByte(bytes[0]);
+ ReadByte(bytes[1]);
+
+ //Figure out what format the file is in
+ if( bytes[0] == 0xFF && bytes[1] == 0xFE)
+ m_encoding = UNI16_LE;
+ else if( bytes[0] == 0xFE && bytes[1] == 0xFF)
+ m_encoding = UNI16_BE;
+ else if( bytes[0] == 0xEF && bytes[1] == 0xBB)
+ {
+ //This is probably UTF-8, check the third byte
+ unsigned char temp;
+ ReadByte(temp);
+ if( temp == 0xBF)
+ m_encoding = UTF_8;
+ else
+ {
+ //Set text format.
+ m_encoding = ASCII;
+ ResetFilePointer();
+ }
+ }
+ else
+ {
+ m_encoding = ASCII;
+
+ //Set start pos
+ ResetFilePointer();
+ }
+ }
+}
+
+//End of file?
+bool CTextFileRead::Eof() const
+{
+ return m_endoffile;
+}
+
+//Read one byte
+void CTextFileRead::ReadByte(unsigned char& ch)
+{
+ //Use extrabuffer if needed
+ if(m_useExtraBuffer)
+ {
+ m_useExtraBuffer=false;
+ ch = m_extraBuffer_char;
+ return;
+ }
+ //In Windows, do this...
+ //If buffer used or not read
+ if(m_buffpos==-1 || m_buffpos == BUFFSIZE-1)
+ {
+#if PEK_TX_TECHLEVEL==0
+ m_buffsize = m_file.read(m_buf, BUFFSIZE).gcount();
+#elif PEK_TX_TECHLEVEL==1
+
+ DWORD dwRead;
+ if (!::ReadFile(m_hFile, m_buf, BUFFSIZE, &dwRead, NULL))
+ {
+ //Couldn't read!
+ Close();
+ m_buffsize = 0;
+
+ //Throw exception
+ throw CTextFileException(GetLastError());
+ }
+ else
+ m_buffsize = (int) dwRead;
+
+#else
+ m_buffsize=m_file->Read(m_buf, BUFFSIZE);
+#endif
+
+ if(m_buffsize == 0)
+ {
+ m_endoffile=true;
+ ch = 0;
+ return;
+ }
+
+ m_buffpos=0;
+ }
+ else
+ {
+ m_buffpos++;
+
+ if(m_buffpos >= m_buffsize)
+ {
+ m_endoffile=true;
+ ch = 0;
+ return;
+ }
+ }
+
+ //当前位置增加
+ m_current_pos++;
+
+ ch = m_buf[m_buffpos];
+}
+
+void CTextFileRead::ReadWchar(wchar_t& ch)
+{
+ if(m_useExtraBuffer)
+ {
+ m_useExtraBuffer=false;
+ ch = m_extraBuffer_wchar;
+ return;
+ }
+
+ if(m_encoding == UTF_8)
+ {
+ //This is quite tricky :-/
+ //http://www.cl.cam.ac.uk/~mgk25/unicode.html#examples
+ unsigned char byte;
+ ReadByte(byte);
+
+ int onesBeforeZero = 0;
+
+ { //Calc how many ones before the first zero...
+ unsigned char temp = byte;
+
+ while( (temp & 0x80)!=0 )
+ {
+ temp = (unsigned char) (temp << 1);
+ onesBeforeZero++;
+ }
+ }
+
+ if(onesBeforeZero==0)
+ {
+ ch = byte;
+ return;
+ }
+ else if(onesBeforeZero == 2)
+ {
+ //U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
+ unsigned char byteb;
+ ReadByte(byteb);
+
+ ch = (wchar_t) ( ((0x1F & byte) << 6)|
+ (0x3F & byteb)
+ ) ;
+
+ return;
+ }
+ else if(onesBeforeZero == 3)
+ {
+ //U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
+ unsigned char byteb, bytec;
+ ReadByte(byteb);
+ ReadByte(bytec);
+
+ ch = (wchar_t) ( ((0x0F & byte) << 12) |
+ ((0x3F & byteb) << 6) |
+ (0x3F & bytec) );
+
+ return;
+ }
+
+ //This should never happend! It it do, something is wrong with the file.
+ ch = 0xFFFD;
+
+ }
+ else
+ {
+
+ unsigned char bytes[2];
+ ReadByte(bytes[0]);
+ ReadByte(bytes[1]);
+
+ if(m_encoding == UNI16_BE)
+ ch = (wchar_t) ( ((wchar_t) bytes[0] << 8) |
+ (wchar_t) bytes[1]
+ ) ;
+ else
+ ch = (wchar_t) ( ((wchar_t) bytes[1] << 8) |
+ (wchar_t) bytes[0]
+ );
+ }
+}
+
+void CTextFileRead::ResetFilePointer()
+{
+ m_useExtraBuffer=false;
+
+#if PEK_TX_TECHLEVEL==0
+ m_file.clear();
+ m_file.seekg(0, ios::beg);
+
+#elif PEK_TX_TECHLEVEL==1
+
+ ::SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN);
+ m_section_position.clear();
+
+#else
+ m_file->SeekToBegin();
+#endif
+ //Force reread buffer
+ m_buffpos=-1;
+
+ m_current_pos = 0;
+
+ m_firstLine = true;
+ m_endoffile = false;
+
+}
+
+bool CTextFileRead::ReadLine(string& line,bool bRecordSection )
+{
+ //EOF?
+ if(Eof())
+ return false;
+
+ //使用章节序号获取的话,不允许正常的获取方法了
+ if(!m_section_enable)
+ ATLASSERT(!bRecordSection);
+
+ if(m_encoding == ASCII)
+ {
+ return ReadCharLine(line);
+ }
+
+ wstring wline;
+
+ if(!ReadWcharLine(wline))
+ return false;
+
+ //Convert
+ WcharToString(wline.c_str(), line);
+
+ return true;
+}
+
+bool CTextFileRead::ReadLine(wstring& line,bool bRecordSection)
+{
+ //EOF?
+ if(Eof())
+ return false;
+
+ if(m_encoding == ASCII)
+ {
+ string cline;
+
+ if(!ReadCharLine(cline))
+ return false;
+
+ //Convert to wstring
+ CharToWstring(cline.c_str(), line);
+
+ return true;
+ }
+ return ReadWcharLine(line);
+}
+
+bool CTextFileRead::ReadLineByID(string& line,long section_id)
+{
+ ATLASSERT(m_section_enable); //段落打开
+
+ ATLASSERT(section_id >= 0);
+ ATLASSERT(section_id < m_section_count);
+
+ ATLASSERT(m_hFile);
+
+ if(m_buf_first_section != section_id/ENABLESECTION_SECTION_COUNT * ENABLESECTION_SECTION_COUNT)
+ {
+ //当前段不在缓冲区,填充缓冲区
+ m_section_buf.clear();
+ m_buf_first_section = section_id/ENABLESECTION_SECTION_COUNT * ENABLESECTION_SECTION_COUNT;
+
+ //设置文件位置
+ ::SetFilePointer(m_hFile, m_section_position[section_id/ENABLESECTION_SECTION_COUNT], NULL, FILE_BEGIN);
+ m_section_position[section_id/ ENABLESECTION_SECTION_COUNT];
+ m_buffpos = -1;
+ m_endoffile = false;
+ m_useExtraBuffer=false;
+
+ //跳过前几个
+ for(long i = m_buf_first_section;
+ i < ENABLESECTION_SECTION_COUNT+m_buf_first_section && i< m_section_count; i++)
+ {
+ ReadLine(line);
+ m_section_buf.push_back(line);
+ }
+ }
+
+ line = m_section_buf[section_id%ENABLESECTION_SECTION_COUNT];
+ return true;
+}
+
+bool CTextFileRead::ReadLineByID(wstring& line,long section_id)
+{
+ ATLASSERT(m_section_enable); //段落打开
+
+ ATLASSERT(section_id >= 0);
+ ATLASSERT(section_id < m_section_count);
+
+ ATLASSERT(m_hFile);
+
+ if(m_wbuf_first_section != section_id/ENABLESECTION_SECTION_COUNT * ENABLESECTION_SECTION_COUNT)
+ {
+ //当前段不在缓冲区,填充缓冲区
+ m_wsection_buf.clear();
+ m_wbuf_first_section = section_id/ENABLESECTION_SECTION_COUNT * ENABLESECTION_SECTION_COUNT;
+
+ //设置文件位置
+ ::SetFilePointer(m_hFile, m_section_position[section_id/ENABLESECTION_SECTION_COUNT], NULL, FILE_BEGIN);
+ m_section_position[section_id/ ENABLESECTION_SECTION_COUNT];
+ m_buffpos = -1;
+ m_endoffile = false;
+ m_useExtraBuffer=false;
+
+ //跳过前几个
+ for(long i = m_wbuf_first_section;
+ i < ENABLESECTION_SECTION_COUNT+m_wbuf_first_section && i< m_section_count; i++)
+ {
+ ReadLine(line);
+ m_wsection_buf.push_back(line);
+ }
+ }
+
+ line = m_wsection_buf[section_id%ENABLESECTION_SECTION_COUNT];
+ return true;
+}
+
+bool CTextFileRead::Read(string& all, const string newline)
+{
+ if(!IsOpen())
+ return false;
+
+ int buffsize = GuessCharacterCount()+2;
+ int buffpos = 0;
+
+ //Create buffer
+ char* buffer = new char[buffsize];
+
+ //If not possible, don't use any buffer
+ if(buffer == NULL)
+ buffsize = 0;
+
+ string temp;
+ all = temp;
+ all.reserve(buffsize);
+ bool firstLine=true;
+
+ while(!Eof())
+ {
+ if(ReadLine(temp))
+ {
+ //Add new line, if not first line
+ if(!firstLine)
+ temp.insert(0, newline.c_str());
+ else
+ firstLine=false;
+
+ //Add to buffer if possible
+ if(buffpos + (int) temp.size() < buffsize)
+ {
+ strcpy(buffer+buffpos, temp.c_str());
+ buffpos += (int) temp.size();
+ }
+ else
+ {
+ //Copy to all string
+ if(buffpos != 0)
+ {
+ all.append(buffer, buffpos);
+ buffpos = 0;
+ }
+ all += temp;
+ }
+ }
+ };
+
+ //Copy to all string
+ if(buffpos != 0)
+ {
+ all.append(buffer, buffpos);
+ }
+
+ if(buffer != NULL)
+ delete [] buffer;
+
+ return true;
+}
+
+bool CTextFileRead::Read(wstring& all, const wstring newline)
+{
+ if(!IsOpen())
+ return false;
+
+ int buffsize = GuessCharacterCount()+2;
+ int buffpos = 0;
+
+ //Create buffer
+ wchar_t* buffer = new wchar_t[buffsize];
+
+ //If not possible, don't use any buffer
+ if(buffer == NULL)
+ buffsize = 0;
+
+ wstring temp;
+ all = temp;
+ all.reserve(buffsize);
+ bool firstLine=true;
+
+ while(!Eof())
+ {
+ if(ReadLine(temp))
+ {
+ //Add new line, if not first line
+ if(!firstLine)
+ temp.insert(0, newline.c_str());
+ else
+ firstLine=false;
+
+ //Add to buffer if possible
+ if(buffpos + (int) temp.size() < buffsize)
+ {
+ wcscpy(buffer+buffpos, temp.c_str());
+ buffpos += (int) temp.size();
+ }
+ else
+ {
+ //Copy to all string
+ if(buffpos != 0)
+ {
+ all.append(buffer, buffpos);
+ buffpos = 0;
+ }
+
+ all += temp;
+ }
+ }
+ };
+
+ //Copy to all string
+ if(buffpos != 0)
+ {
+ all.append(buffer, buffpos);
+ }
+
+ if(buffer != NULL)
+ delete [] buffer;
+
+ return true;
+}
+
+int CTextFileRead::GuessCharacterCount()
+{
+ #if PEK_TX_TECHLEVEL==2
+ int bytecount = (int) m_file->GetLength();
+ #else
+ //Code needed to get file size when not using MFC
+ int bytecount = 1024*1024; //Default: 1 MB
+ #endif
+
+ //If ASCII, the number of characters is the byte count.
+ //If UTF-8, it can't be more than bytecount, so use byte count
+ if(m_encoding == ASCII || m_encoding == UTF_8)
+ return bytecount;
+
+ //Otherwise, every two byte in one character
+ return bytecount/2;
+}
+
+#if PEK_TX_TECHLEVEL==2
+
+bool CTextFileRead::ReadLine(CString& line)
+{
+#ifndef _UNICODE
+ string temp;
+#else
+ wstring temp;
+#endif
+
+ if(!ReadLine(temp))
+ return false;
+
+ line = temp.c_str();
+ return true;
+}
+
+bool CTextFileRead::Read(CString& all, const CString newline)
+{
+#ifndef _UNICODE
+ string temp, n=newline;
+#else
+ wstring temp, n=newline;
+#endif
+
+ if(!Read(temp, n))
+ return false;
+
+ all = temp.c_str();
+ return true;
+}
+
+#endif
+
+
+//Returns false if end-of-file was reached
+//(line will not be changed). If returns true,
+//it means that last line ended with a line break.
+bool CTextFileRead::ReadWcharLine(wstring& line)
+{
+ //EOF?
+ if(Eof())
+ return false;
+
+ wchar_t ch=0;
+
+ //Ignore 0x0D and 0x0A
+ //or 0x0D 0x0D and 0x0A
+ //or just 0x0D
+ //or just 0x0A
+ //except when we read the first line
+ ReadWchar(ch);
+
+ if(!m_firstLine)
+ {
+ if(ch == 0x0D) //If next is 0x0A, ignore that too
+ {
+ ReadWchar(ch);
+
+ if(ch == 0x0A)
+ ReadWchar(ch);
+ else if(ch == 0x0D)
+ {
+ ReadWchar(ch);
+ if(ch == 0x0A)
+ ReadWchar(ch);
+ }
+
+ }
+ else if(ch == 0x0A)
+ {
+ ReadWchar(ch);
+ }
+ }
+ else
+ {
+ //Next time we reads we don't read the first line in file.
+ //(then we should ignore \r\n)
+ m_firstLine = false;
+ }
+
+ //Clear line
+ line = L"";
+
+ //It would be a lot easier if we didn't use a buffer, and added directly to
+ //line, but that is quite slow.
+ wchar_t buffer[BUFFSIZE];
+ buffer[BUFFSIZE-1] = '\0';
+ //Where to insert next character
+ int bufpos = 0;
+
+ //Read line
+ while(ch != 0x0D && ch != 0x0A && !Eof())
+ {
+ //End of buffer?
+ if(bufpos+1 >= BUFFSIZE)
+ {
+ //Add to line
+ line.append(buffer, bufpos);
+ bufpos=0;
+ }
+
+ buffer[bufpos] = ch;
+ bufpos++;
+
+ ReadWchar(ch);
+ };
+
+ buffer[bufpos] = L'\0';
+ line += buffer;
+
+ //Save currents character in extra buffer
+ m_useExtraBuffer=true;
+ m_extraBuffer_wchar=ch;
+
+ return true;
+}
+
+//Returns false if end-of-file was reached
+//(line will not be changed). If returns true,
+//it means that last line ended with a line break.
+bool CTextFileRead::ReadCharLine(string& line)
+{
+ //EOF?
+ if(Eof())
+ return false;
+
+ unsigned char ch=0;
+
+ //Ignore 0x0D and 0x0A
+ //or just 0x0D
+ //or just 0x0A
+ //except when we read the first line
+ ReadByte(ch);
+
+ if(!m_firstLine)
+ {
+ if(ch == 0x0D) //If next is 0x0A, ignore that too
+ {
+ ReadByte(ch);
+
+ if(ch == 0x0A)
+ ReadByte(ch);
+ else if(ch == 0x0D)
+ {
+ ReadByte(ch);
+ if(ch == 0x0A)
+ ReadByte(ch);
+ }
+ }
+ else if(ch == 0x0A)
+ {
+ ReadByte(ch);
+ }
+ }
+ else
+ {
+ //Next time we reads we don't read the first line in file.
+ //(then we should ignore \r\n)
+ m_firstLine = false;
+ }
+
+ //Clear line
+ line = "";
+
+ //It would be a lot easier if we didn't use a buffer, and added directly to
+ //line, but that is quite slow.
+ char buffer[BUFFSIZE];
+ buffer[BUFFSIZE-1] = '\0';
+ //Where to insert next character
+ int bufpos = 0;
+
+ //Read line
+ while(ch != 0x0D && ch != 0x0A && !Eof())
+ {
+ //End of buffer?
+ if(bufpos+1 >= BUFFSIZE)
+ {
+ //Add to line
+ line.append(buffer, bufpos);
+ bufpos=0;
+ }
+
+ buffer[bufpos] = ch;
+ bufpos++;
+
+ ReadByte(ch);
+ };
+
+ buffer[bufpos] = L'\0';
+ line += buffer;
+
+ //Save currents character in extra buffer
+ m_useExtraBuffer=true;
+ m_extraBuffer_char=ch;
+
+ return true;
+}
+
+
+long CTextFileRead::EnableSection(HANDLE hRecorder)
+{
+ ATLASSERT(m_hFile);
+ m_section_enable = true;
+ //载入成功标志
+ bool load_ok = false;
+
+ if(hRecorder)
+ load_ok = LoadSectionInfo(hRecorder);
+
+ if(!load_ok)
+ {
+ //载入失败,进行重建
+ m_section_count = 0;
+
+ for(;;)
+ {
+ long last_pos = m_current_pos;
+ for(long loop = 0 ; loop < ENABLESECTION_SECTION_COUNT ; loop++)
+ {
+ string str;
+ if(!ReadLine(str,true))
+ break;
+ m_section_count++;
+ str.empty();
+ }
+ m_section_position.push_back(last_pos);
+ if(Eof())
+ break;
+ }
+ m_dirty = true;
+ }
+ return m_section_count;
+}
+
+bool CTextFileRead::LoadSectionInfo(HANDLE hRecorder)
+{
+ ATLASSERT(hRecorder);
+ ATLASSERT(m_hFile);
+
+ //获取修改
+ FILETIME last_write_time; //修改时间
+ if(!GetFileTime(m_hFile,NULL,NULL,&last_write_time))
+ return false;
+
+ DWORD dwReadSize = 0;
+ BOOL bResult = FALSE;
+
+ FILETIME last_write_time_recorder;
+ //读取最后修改时间
+ bResult = ReadFile(hRecorder,&last_write_time_recorder,sizeof(FILETIME),&dwReadSize,NULL);
+
+ if(!bResult || dwReadSize != sizeof(FILETIME))
+ return false;
+ //比较修改时间
+ if(memcmp(&last_write_time,&last_write_time_recorder,sizeof(FILETIME)) != 0)
+ return false;
+
+ //读取每条记录的段落数
+ long recorder_section_count = 0;
+ bResult = ReadFile(hRecorder,&recorder_section_count,sizeof(long),&dwReadSize,NULL);
+ if(!bResult || dwReadSize != sizeof(long))
+ return false;
+ if(recorder_section_count != ENABLESECTION_SECTION_COUNT)
+ return false;
+
+ //读取段落数
+ bResult = ReadFile(hRecorder,&m_section_count,sizeof(long),&dwReadSize,NULL);
+ if(!bResult || dwReadSize != sizeof(long))
+ return false;
+ m_section_position.clear();
+
+ long lSectionCount = m_section_count / ENABLESECTION_SECTION_COUNT;
+ if(m_section_count%ENABLESECTION_SECTION_COUNT)
+ lSectionCount++;
+ //读取各个段落的文件位置
+ for(long section = 0; section < lSectionCount; section++)
+ {
+ long section_pos = 0;
+ bResult = ReadFile(hRecorder,§ion_pos,sizeof(long),&dwReadSize,NULL);
+
+ if(!bResult || dwReadSize != sizeof(long))
+ {
+ m_section_position.clear();
+ return false;
+ }
+ m_section_position.push_back(section_pos);
+ }
+
+ return true;
+}
+
+bool CTextFileRead::SaveSectionInfo(HANDLE hRecorder)
+{
+ ATLASSERT(hRecorder);
+
+ if(!m_dirty)
+ return true;/// 不需要保存
+
+ //获取修改
+ FILETIME last_write_time; //修改时间
+ if(!GetFileTime(m_hFile,NULL,NULL,&last_write_time))
+ return false;
+
+ DWORD dwReadSize = 0;
+ BOOL bResult = 0;
+
+ //写入最后修改时间
+ bResult = WriteFile(hRecorder,&last_write_time,sizeof(FILETIME),&dwReadSize,NULL);
+
+ if(!bResult || dwReadSize != sizeof(FILETIME))
+ return false;
+
+ //写入每条记录段落数
+ long recorder_section_count = ENABLESECTION_SECTION_COUNT;
+ bResult = WriteFile(hRecorder,&recorder_section_count,sizeof(long),&dwReadSize,NULL);
+
+ if(!bResult || dwReadSize != sizeof(long))
+ return false;
+
+ //写入段落数
+ bResult = WriteFile(hRecorder,&m_section_count,sizeof(long),&dwReadSize,NULL);
+
+ if(!bResult || dwReadSize != sizeof(long))
+ return false;
+ long lSectionCount = m_section_count / ENABLESECTION_SECTION_COUNT;
+ if(m_section_count%ENABLESECTION_SECTION_COUNT)
+ lSectionCount++;
+ for(long section = 0; section < lSectionCount ; section++)
+ {
+ long section_pos = m_section_position[section];
+ bResult = WriteFile(hRecorder,§ion_pos,sizeof(long),&dwReadSize,NULL);
+
+ if(!bResult || dwReadSize != sizeof(long))
+ return false;
+ }
+
+ return ::FlushFileBuffers(hRecorder)?true:false;
+}
+
+DWORD CTextFileRead::GetFileSize()
+{
+ ATLASSERT(m_hFile);
+ return ::GetFileSize(m_hFile,NULL);
+}
diff --git a/ZbaSDK/SampleCode/PluginComDll/TextFileHelper.h b/ZbaSDK/SampleCode/PluginComDll/TextFileHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9d25bdbecd75b1e70082d7b5918bb3544362d9b
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/TextFileHelper.h
@@ -0,0 +1,413 @@
+// TextFileHelper.h: interface for the CTextFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+/*
+ CTextFileDocument let you write and read text files with
+ different encodings (ASCII, UTF-8, Unicode 16 little/big
+ endian is supported). When you work with ASCII-files
+ CTextFileDocument will help you convert strings to/from
+ different code-pages.
+
+ Let me now if you find something strange or just gets
+ a clever idea...
+
+ Get the latest version at
+ http://www.codeproject.com/file/textfiledocument.asp
+
+ Version 1.22 - 21 May 2005
+ ! Reading a line before reading everything could add an
+ extra line break.
+ ! A member variable wasn't always initialized, could cause
+ problems when reading single lines.
+ ! A smarter/easier algorithm is used when reading single lines.
+
+ Version 1.21 - 10 Apr 2005
+ ! Fix by sammyc: If it was not possible to open a file in techlevel 1,
+ IsOpen returned a bad result.
+
+ Version 1.20 - 15 Jan 2005
+ ! Fixed some problems when converting multi-byte string to Unicode,
+ and vice versa.
+ + Improved conversion routines. It's now possible to define
+ which code-page to use.
+ + It's now possible to set which character to use when it's
+ not possible to convert an Unicode character to an multi-byte character.
+ + It's now possible to see if data was lost during conversion.
+ + Better support for other platforms, it's no longer necessary to use
+ MFC in Windows.
+ ! Reading very small files (1 byte) failed.
+
+ Version 1.13 - 26 Dec 2004
+ ! Fixes by drinktea:
+ ! If a text file begun with an empty line, the file
+ wasn't read correctly (first empty line was ignored).
+ ! Fixes in CharToWstring and WcharToString.
+
+ Version 1.12 - 17 Oct 2004
+ + Minor memory leak when open file failed, fixed.
+
+ Version 1.11 - 28 Aug 2004
+ ! Calling WriteEndl() when writing an ASCII file could make
+ the file incorrectly written. Fixed.
+ + ASCII files is written faster.
+
+ Version 1.10 - 13 Aug 2004
+ Sorry about the quick update.
+ + Improved performance (much faster now, but code is more complicated :-/).
+ + Buffer is used when writing files.
+ + Buffer is used in non-mfc compilers
+
+ Version 1.0 - 12 Aug 2004
+ Initial version.
+
+ PEK
+ */
+/*
+
+If you are creating a console project that doesn't support
+MFC in Visual Studio, you will probably need to define
+techlevel to 0:
+#define PEK_TX_TECHLEVEL 0
+
+In other cases it usually not necessary to define which "tech-level"
+to use, the code below should do this for you. However,
+if you need to this is the difference:
+
+#define PEK_TX_TECHLEVEL 0
+You should use this if you running on a none-Windows
+platform. This uses fstream internally to read and
+write files. If you want to change codepage you should
+call setlocal.
+
+#define PEK_TX_TECHLEVEL 1
+Use this on Windows if you don't use MFC. This calls
+Windows API directly to read and write files. If
+something couldn't be read/written a CTextFileException
+is thrown. Unicode in filenames are supported.
+Codepages are supported.
+
+#define PEK_TX_TECHLEVEL 2
+Use this when you are using MFC. This uses CFile
+internally to read and write files. If data can't be
+read/written, CFile will throw an exception. Codepages
+are supported. Unicode in filenames are supported.
+CString is supported.
+
+*/
+
+#define PEK_TX_TECHLEVEL 1
+
+#ifndef PEK_TX_TECHLEVEL
+
+//Autodetect which "tech level" to use
+#ifdef _MFC_VER
+ #define PEK_TX_TECHLEVEL 2
+#else
+#ifdef _WIN32
+ #define PEK_TX_TECHLEVEL 1
+#else
+ #define PEK_TX_TECHLEVEL 0
+#endif
+#endif
+#endif
+
+#if PEK_TX_TECHLEVEL > 0
+ /*
+ In windows it's possible to use Unicode in filenames,
+ in unix it's not possible (afaik). FILENAMECHAR is the
+ charactertype.
+ */
+ #ifndef _UNICODE
+ typedef char FILENAMECHAR;
+ #else
+ typedef wchar_t FILENAMECHAR;
+ #endif
+#else
+ #include
+ typedef char FILENAMECHAR;
+#endif
+
+#include
+#include
+using namespace std;
+
+class CTextFileBase
+{
+public:
+
+ enum TEXTENCODING
+ {
+ ASCII=0,
+ UNI16_BE,
+ UNI16_LE,
+ UTF_8
+ };
+
+ CTextFileBase();
+ ~CTextFileBase();
+
+ //Is the file open?
+ int IsOpen();
+
+ //Close the file
+ virtual void Close();
+
+ //Return the encoding of the file (ASCII, UNI16_BE, UNI16_LE or UTF_8);
+ TEXTENCODING GetEncoding() const;
+
+ //Set which character that should be used when converting
+ //Unicode->multi byte and an unknown character is found ('?' is default)
+ void SetUnknownChar(const char unknown);
+
+ //Returns true if data was lost
+ //(happens when converting Unicode->multi byte string and an unmappable
+ //characters is found).
+ bool IsDataLost() const;
+
+ //Reset the data lost flag
+ void ResetDataLostFlag();
+
+ #if PEK_TX_TECHLEVEL > 0
+
+ /* Note!
+ The codepage is only used when converting from multibyte
+ to Unicode or vice versa. It is not used when reading
+ ANSI-files in none-Unicode strings, or reading
+ Unicode-files in Unicode strings.
+
+ This means that if you want to read a ANSI-textfile
+ (with some code page) to an non-Unicode string you
+ must do the conversion yourself. But this is easy :-).
+ Read the file with the codepage to a wstring, then use
+ ConvertCharToWstring to convert the wstring to a
+ string.
+
+ */
+ //Set codepage to use when working with none-Unicode strings
+ void SetCodePage(const UINT codepage);
+
+ //Get codepage to use when working with none-Unicode strings
+ UINT GetCodePage() const;
+
+ //Convert char* to wstring
+ static void ConvertCharToWstring(const char* from, wstring &to, UINT codepage=CP_ACP);
+
+ //Convert wchar_t* to string
+ static void ConvertWcharToString(const wchar_t* from, string &to, UINT codepage=CP_ACP, bool* datalost=NULL, char unknownchar=0);
+
+ #else
+
+ //Convert char* to wstring
+ static void ConvertCharToWstring(const char* from, wstring &to);
+
+ //Convert wchar_t* to string
+ static void ConvertWcharToString(const wchar_t* from, string &to, bool* datalost=NULL, char unknownchar='a');
+ #endif
+protected:
+ //Convert char* to wstring
+ void CharToWstring(const char* from, wstring &to) const;
+ //Convert wchar_t* to string
+ void WcharToString(const wchar_t* from, string &to);
+ //The enocoding of the file
+ TEXTENCODING m_encoding;
+ //Buffersize
+ #define BUFFSIZE 1024
+
+#if PEK_TX_TECHLEVEL == 0
+ //Use fstream
+ fstream m_file;
+#elif PEK_TX_TECHLEVEL == 1
+ HANDLE m_hFile;
+#else
+ //In windows we are using CFile
+ CFile* m_file;
+ bool m_closeAndDeleteFile;
+#endif
+ //These controls the buffer for reading/writing
+ //True if end of file
+ bool m_endoffile;
+ //Readingbuffer
+ char m_buf[BUFFSIZE];
+ //Bufferposition
+ int m_buffpos;
+ //Size of buffer
+ int m_buffsize;
+ //Character used when converting Unicode->multi byte and an unknown character was found
+ char m_unknownChar;
+ //Is true if data was lost when converting Unicode->multi-byte
+ bool m_datalost;
+
+#if PEK_TX_TECHLEVEL > 0
+ UINT m_codepage;
+#endif
+};
+
+class CTextFileWrite : public CTextFileBase
+{
+public:
+ CTextFileWrite(const FILENAMECHAR* filename, TEXTENCODING type=ASCII);
+#if PEK_TX_TECHLEVEL == 2
+ CTextFileWrite(CFile* file, TEXTENCODING type=ASCII);
+#endif
+ ~CTextFileWrite();
+
+ //Write routines
+ void Write(const char* text);
+ void Write(const wchar_t* text);
+ BOOL Write(const string& text);
+ BOOL Write(const wstring& text);
+
+ CTextFileWrite& operator << (const char c);
+ CTextFileWrite& operator << (const char* text);
+ CTextFileWrite& operator << (const string& text);
+
+ CTextFileWrite& operator << (const wchar_t wc);
+ CTextFileWrite& operator << (const wchar_t* text);
+ CTextFileWrite& operator << (const wstring& text);
+
+ //Write new line (two characters, 13 and 10)
+ void WriteEndl();
+
+ //Close the file
+ virtual void Close();
+
+private:
+ //Write and empty buffer
+ void Flush();
+
+ //Write a single one wchar_t, convert first
+ void WriteWchar(const wchar_t ch);
+
+ //Write one byte
+ void WriteByte(const unsigned char byte);
+
+ //Write a c-string in ASCII-format
+ void WriteAsciiString(const char* s);
+
+ //Write byte order mark
+ void WriteBOM();
+};
+
+class CTextFileRead : public CTextFileBase
+{
+public:
+ /**
+ * @brief
+ *
+ *
+ * @param filename
+ * @param hRecorder 文件记录句柄
+ * @return
+ */
+ CTextFileRead(const FILENAMECHAR* filename);
+#if PEK_TX_TECHLEVEL == 2
+ CTextFileRead(CFile* file);
+#endif
+
+ //Returns false if end-of-file was reached
+ //(line will not be changed). If returns true,
+ //it means that last line ended with a line break.
+ bool ReadLine(string& line,bool bRecordSection = false);
+ bool ReadLine(wstring& line,bool bRecordSection = false);
+
+ //通过段落序号,获取段落内容
+ bool ReadLineByID(string& line,long section_id);
+ bool ReadLineByID(wstring& line,long section_id);
+
+ //Returns everything from current position.
+ bool Read(string& all, const string newline="\r\n");
+ bool Read(wstring& all, const wstring newline=L"\r\n");
+
+ //保存和载入段落信息
+ bool LoadSectionInfo(HANDLE hRecorder);
+ bool SaveSectionInfo(HANDLE hRecorder);
+
+ /**
+ * @brief 段落信息有效
+ *
+ *
+ * @param hRecorder 有效段落信息的文件句柄
+ */
+ long EnableSection(HANDLE hRecorder = NULL);
+
+ //获取文件大小
+ DWORD GetFileSize();
+
+#if PEK_TX_TECHLEVEL == 2
+ bool ReadLine(CString& line);
+ bool Read(CString& all, const CString newline=_T("\r\n"));
+#endif
+
+ //End of file?
+ bool Eof() const;
+
+private:
+ //Guess the number of characters in the file
+ int GuessCharacterCount();
+
+ //Read line to wstring
+ bool ReadWcharLine(wstring& line);
+
+ //Read line to string
+ bool ReadCharLine(string& line);
+
+ //Reset the filepointer to start
+ void ResetFilePointer();
+
+ //Read one wchar_t
+ void ReadWchar(wchar_t& ch);
+
+ //Read one byte
+ void ReadByte(unsigned char& ch);
+
+ //Detect encoding
+ void ReadBOM();
+
+ //Use extra buffer. Sometimes we read one character to much, save it.
+ bool m_useExtraBuffer;
+
+ //Used to read see if the first line in file is to read
+ //(so we know how to handle \n\r)
+ bool m_firstLine;
+
+ //Extra buffer. It's ok to share the memory
+ union
+ {
+ char m_extraBuffer_char;
+ wchar_t m_extraBuffer_wchar;
+ };
+
+ //段落位置映射表
+ std::vector m_section_position;
+ bool m_section_enable;
+ long m_current_pos; //当前读取的位置
+ bool m_dirty; //写文件标志
+ long m_section_count; //段数
+
+ std::vector m_section_buf; //段落的缓存
+ long m_buf_first_section; //段落缓存首段号
+
+ std::vector m_wsection_buf; //段落的缓存
+ long m_wbuf_first_section; //段落缓存首段号
+};
+
+#if PEK_TX_TECHLEVEL == 1
+
+//This is only used in Windows mode (no MFC)
+//An exception is thrown will data couldn't be read or written
+class CTextFileException
+{
+public:
+ CTextFileException(DWORD err)
+ {
+ m_errorCode = err;
+ }
+
+ //Value returned by GetLastError()
+ DWORD m_errorCode;
+};
+
+#endif
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginComDll/_ISysInfoEvents_CP.h b/ZbaSDK/SampleCode/PluginComDll/_ISysInfoEvents_CP.h
new file mode 100644
index 0000000000000000000000000000000000000000..d10c8440d130be77b659e8bc6806eb551ee81844
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/_ISysInfoEvents_CP.h
@@ -0,0 +1,10 @@
+#pragma once
+
+using namespace ATL;
+
+template
+class CProxy_ISysInfoEvents : public IConnectionPointImpl
+{
+ // 警告: 此类可以由向导重新生成
+public:
+};
diff --git a/ZbaSDK/SampleCode/PluginComDll/_ITextFileEvents_CP.h b/ZbaSDK/SampleCode/PluginComDll/_ITextFileEvents_CP.h
new file mode 100644
index 0000000000000000000000000000000000000000..0421fc3c12874a8dbf8167fe5c5116031744c38c
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/_ITextFileEvents_CP.h
@@ -0,0 +1,10 @@
+#pragma once
+
+using namespace ATL;
+
+template
+class CProxy_ITextFileEvents : public IConnectionPointImpl
+{
+ // 警告: 此类可以由向导重新生成
+public:
+};
diff --git a/ZbaSDK/SampleCode/PluginComDll/dlldata.c b/ZbaSDK/SampleCode/PluginComDll/dlldata.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d80751d1a92b537ad0c1dbc2cadee689a181188
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/dlldata.c
@@ -0,0 +1,38 @@
+/*********************************************************
+ DllData file -- generated by MIDL compiler
+
+ DO NOT ALTER THIS FILE
+
+ This file is regenerated by MIDL on every IDL file compile.
+
+ To completely reconstruct this file, delete it and rerun MIDL
+ on all the IDL files in this DLL, specifying this file for the
+ /dlldata command line option
+
+*********************************************************/
+
+#define PROXY_DELEGATION
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EXTERN_PROXY_FILE( PluginComDll )
+
+
+PROXYFILE_LIST_START
+/* Start of list */
+ REFERENCE_PROXY_FILE( PluginComDll ),
+/* End of list */
+PROXYFILE_LIST_END
+
+
+DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )
+
+#ifdef __cplusplus
+} /*extern "C" */
+#endif
+
+/* end of generated dlldata file */
diff --git a/ZbaSDK/SampleCode/PluginComDll/dllmain.cpp b/ZbaSDK/SampleCode/PluginComDll/dllmain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c6c0772818fe5639bf4c59abb199b7f6ff54d279
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/dllmain.cpp
@@ -0,0 +1,20 @@
+// dllmain.cpp : DllMain 的实现。
+
+#include "stdafx.h"
+#include "resource.h"
+#include "PluginComDll_i.h"
+#include "dllmain.h"
+#include "xdlldata.h"
+
+CPluginComDllModule _AtlModule;
+
+// DLL 入口点
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+{
+#ifdef _MERGE_PROXYSTUB
+ if (!PrxDllMain(hInstance, dwReason, lpReserved))
+ return FALSE;
+#endif
+ hInstance;
+ return _AtlModule.DllMain(dwReason, lpReserved);
+}
diff --git a/ZbaSDK/SampleCode/PluginComDll/dllmain.h b/ZbaSDK/SampleCode/PluginComDll/dllmain.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4fcf6743e43053211c7d3f41f853ba4f19272cd
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/dllmain.h
@@ -0,0 +1,10 @@
+// dllmain.h : 模块类的声明。
+
+class CPluginComDllModule : public ATL::CAtlDllModuleT< CPluginComDllModule >
+{
+public :
+ DECLARE_LIBID(LIBID_PluginComDllLib)
+ DECLARE_REGISTRY_APPID_RESOURCEID(IDR_PLUGINCOMDLL, "{F0FFF18E-E8C7-4778-8B38-45C9CD71912E}")
+};
+
+extern class CPluginComDllModule _AtlModule;
diff --git a/ZbaSDK/SampleCode/PluginComDll/resource.h b/ZbaSDK/SampleCode/PluginComDll/resource.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b2ca51fc2c3a8c6be9797e6ba7a27a198466967
Binary files /dev/null and b/ZbaSDK/SampleCode/PluginComDll/resource.h differ
diff --git a/ZbaSDK/SampleCode/PluginComDll/stdafx.cpp b/ZbaSDK/SampleCode/PluginComDll/stdafx.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7a93b91a3a315faf53a779c607f3440f1d4fb18
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/stdafx.cpp
@@ -0,0 +1,5 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// PluginComDll.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
diff --git a/ZbaSDK/SampleCode/PluginComDll/stdafx.h b/ZbaSDK/SampleCode/PluginComDll/stdafx.h
new file mode 100644
index 0000000000000000000000000000000000000000..16b99e89858d42e3c1eda9fbc4749e9f313fc435
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/stdafx.h
@@ -0,0 +1,35 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#include "targetver.h"
+
+#define _ATL_APARTMENT_THREADED
+
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
+
+#define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW
+
+#include "resource.h"
+#include
+#include
+#include
+#include
+
+using namespace ATL;
+
+#pragma warning( disable : 4100 )
+#pragma warning( disable : 4510 )
+#pragma warning( disable : 4610 )
+#pragma warning( disable : 4206 )
+
+#import "..\\Bin\\\ZbaEngine.dll" no_namespace, raw_interfaces_only, raw_native_types, named_guids
+#import "..\\Bin\\\ZbaBase.dll" no_namespace, raw_interfaces_only, raw_native_types, named_guids
diff --git a/ZbaSDK/SampleCode/PluginComDll/targetver.h b/ZbaSDK/SampleCode/PluginComDll/targetver.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a7d2c83b87e4a064a51e5fd8a18393201ddfaeb
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include
diff --git a/ZbaSDK/SampleCode/PluginComDll/xdlldata.c b/ZbaSDK/SampleCode/PluginComDll/xdlldata.c
new file mode 100644
index 0000000000000000000000000000000000000000..b43d3a9b99286266edd066b29212edc3f2ac5c88
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/xdlldata.c
@@ -0,0 +1,18 @@
+// dlldata.c 的包装
+
+#ifdef _MERGE_PROXYSTUB // 合并代理存根(stub) DLL
+
+#define REGISTER_PROXY_DLL //DllRegisterServer 等
+
+#define _WIN32_WINNT 0x0500 //对于 WinNT 4.0 或安装了 DCOM 的 Win95
+#define USE_STUBLESS_PROXY //仅当使用 MIDL 开关 /Oicf 时定义
+
+#pragma comment(lib, "rpcns4.lib")
+#pragma comment(lib, "rpcrt4.lib")
+
+#define ENTRY_PREFIX Prx
+
+#include "dlldata.c"
+#include "PluginComDll_p.c"
+
+#endif //_MERGE_PROXYSTUB
diff --git a/ZbaSDK/SampleCode/PluginComDll/xdlldata.h b/ZbaSDK/SampleCode/PluginComDll/xdlldata.h
new file mode 100644
index 0000000000000000000000000000000000000000..89313c5cc1b9a6784051bf0b8145068143e26f49
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginComDll/xdlldata.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#ifdef _MERGE_PROXYSTUB
+
+extern "C"
+{
+BOOL WINAPI PrxDllMain(HINSTANCE hInstance, DWORD dwReason,
+ LPVOID lpReserved);
+STDAPI PrxDllCanUnloadNow(void);
+STDAPI PrxDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv);
+STDAPI PrxDllRegisterServer(void);
+STDAPI PrxDllUnregisterServer(void);
+}
+
+#endif
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Config.json b/ZbaSDK/SampleCode/PluginExeDemo/Config.json
new file mode 100644
index 0000000000000000000000000000000000000000..df74b525d165ee7b8baad558dea3de7cfdcab49c
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Config.json
@@ -0,0 +1,3 @@
+{
+ "PORT": 12900
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Form1.Designer.cs b/ZbaSDK/SampleCode/PluginExeDemo/Form1.Designer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d5ad6b95c559f97a6973abd7a225ed78355452b5
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Form1.Designer.cs
@@ -0,0 +1,96 @@
+锘縩amespace PluginExeDemo
+{
+ partial class Form1
+ {
+ ///
+ /// 蹇呴渶鐨勮璁″櫒鍙橀噺銆
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 娓呯悊鎵鏈夋鍦ㄤ娇鐢ㄧ殑璧勬簮銆
+ ///
+ /// 濡傛灉搴旈噴鏀炬墭绠¤祫婧愶紝涓 true锛涘惁鍒欎负 false銆
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows 绐椾綋璁捐鍣ㄧ敓鎴愮殑浠g爜
+
+ ///
+ /// 璁捐鍣ㄦ敮鎸佹墍闇鐨勬柟娉 - 涓嶈
+ /// 浣跨敤浠g爜缂栬緫鍣ㄤ慨鏀规鏂规硶鐨勫唴瀹广
+ ///
+ private void InitializeComponent()
+ {
+ this.IEBrowser = new System.Windows.Forms.WebBrowser();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.textBox2 = new System.Windows.Forms.TextBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // IEBrowser
+ //
+ this.IEBrowser.Location = new System.Drawing.Point(12, 12);
+ this.IEBrowser.MinimumSize = new System.Drawing.Size(20, 20);
+ this.IEBrowser.Name = "IEBrowser";
+ this.IEBrowser.Size = new System.Drawing.Size(699, 604);
+ this.IEBrowser.TabIndex = 0;
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(732, 12);
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(459, 258);
+ this.textBox1.TabIndex = 1;
+ //
+ // textBox2
+ //
+ this.textBox2.Location = new System.Drawing.Point(732, 318);
+ this.textBox2.Multiline = true;
+ this.textBox2.Name = "textBox2";
+ this.textBox2.Size = new System.Drawing.Size(459, 298);
+ this.textBox2.TabIndex = 2;
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(732, 281);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(75, 26);
+ this.button1.TabIndex = 3;
+ this.button1.Text = "鍙戦佸唴瀹";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(1203, 628);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.textBox2);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.IEBrowser);
+ this.Name = "Form1";
+ this.Text = "C#寮圭獥灏忕▼搴忚寖渚";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.WebBrowser IEBrowser;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.TextBox textBox2;
+ private System.Windows.Forms.Button button1;
+ }
+}
+
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Form1.cs b/ZbaSDK/SampleCode/PluginExeDemo/Form1.cs
new file mode 100644
index 0000000000000000000000000000000000000000..794620df74f85b84f06b74456d779742318fd5e4
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Form1.cs
@@ -0,0 +1,232 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Windows.Forms;
+
+/// 娣诲姞鏍稿績缁勪欢寮曠敤
+using ZbaEngine;
+using ZbaBase;
+
+namespace PluginExeDemo
+{
+ public partial class Form1 : Form
+ {
+ ///
+ /// web socket鏈嶅姟瀵硅薄
+ ///
+ SocketProxyClass WebSocketServer = null;
+ ///
+ /// web socket鏈嶅姟浜嬩欢瀵硅薄
+ ///
+ WebSocketEventSink WebSocketEvent = null;
+
+ ///
+ /// 鍛戒护琛屽惎鍔ㄥ弬鏁
+ ///
+ Dictionary m_Para;
+
+ public Form1(string strPara)
+ {
+ InitializeComponent();
+
+ m_Para = new Dictionary();
+
+ /// 瑙f瀽鍛戒护琛屽弬鏁
+ string[] cmdArray = strPara.Split('&');
+ foreach (string cmd in cmdArray)
+ {
+ string[] paraArray = cmd.Split('=');
+ foreach (string para in paraArray)
+ {
+ m_Para.Add(paraArray[0], paraArray[1]);
+ break;
+ }
+ }
+ }
+
+ public void Send(string strSID,string strContent)
+ {
+ WebSocketServer.AsynSendText(strSID,strContent);
+ }
+
+ public void OpenUrl(string strUrl)
+ {
+ this.IEBrowser.Navigate(strUrl);
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ WebSocketServer = new SocketProxyClass();
+ if (null == WebSocketServer)
+ return;
+ WebSocketEvent = new WebSocketEventSink();
+ if (null == WebSocketEvent)
+ return;
+ WebSocketEvent.SetForm(this);
+ ushort nPort = ushort.Parse(m_Para["PORT"]);
+ ushort nListenPort = WebSocketServer.Listen(nPort, m_Para["SID"], m_Para["AI"]);
+
+ /// 寤虹珛浜嬩欢閫氱煡
+ WebSocketServer.NewConnEvent += WebSocketEvent.NewConnEvent;
+ WebSocketServer.RecMsgEvent += WebSocketEvent.RecMsgEvent;
+ WebSocketServer.RecTextEvent += WebSocketEvent.RecTextEvent;
+ WebSocketServer.ConnCloseEvent += WebSocketEvent.ConnCloseEvent;
+ }
+
+ private void Form1_Closed(object sender, EventArgs e)
+ {
+ /// 绉婚櫎浜嬩欢閫氱煡
+ WebSocketServer.NewConnEvent -= WebSocketEvent.NewConnEvent;
+ WebSocketServer.RecMsgEvent -= WebSocketEvent.RecMsgEvent;
+ WebSocketServer.RecTextEvent -= WebSocketEvent.RecTextEvent;
+ WebSocketServer.ConnCloseEvent -= WebSocketEvent.ConnCloseEvent;
+ /// 閲婃斁瀵硅薄
+ if (null != WebSocketServer)
+ {
+ WebSocketServer.Close();
+ WebSocketServer = null;
+ }
+
+ WebSocketServer = null;
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ string strLastSID = WebSocketEvent.GetLastSID();
+ if (null == strLastSID || 0 == strLastSID.Length)
+ {
+ MessageBox.Show("杩樻湭鏈夋潵鑷綉椤电殑杩炴帴锛");
+ return;
+ }
+ Send(strLastSID, this.textBox1.Text);
+ this.textBox1.Text = "";
+ }
+
+ ///
+ /// WebSocket鏈嶅姟浜嬩欢閫氱煡
+ ///
+ public class WebSocketEventSink : _ISocketProxyEvents
+ {
+ ///
+ /// 涓荤獥鍙
+ ///
+
+ Form1 m_Form;
+
+ string m_strLastSID;
+
+ public void SetForm(Form1 Form)
+ {
+ m_Form = Form;
+ }
+
+ public string GetLastSID()
+ {
+ return m_strLastSID;
+ }
+
+ public void WriteLog(string documentName, string msg)
+ {
+ string LogFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data");
+ if (!System.IO.Directory.Exists(LogFilePath))
+ System.IO.Directory.CreateDirectory(LogFilePath);
+ string logFile = System.IO.Path.Combine(LogFilePath, documentName + "@" + DateTime.Today.ToString("yyyy-MM-dd") + ".txt");
+ bool writeBaseInfo = System.IO.File.Exists(logFile);
+ StreamWriter swLogFile = new StreamWriter(logFile, true, Encoding.Unicode);
+ swLogFile.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "\t" + msg);
+ swLogFile.Close();
+ swLogFile.Dispose();
+ }
+
+ ///
+ /// 閫氱煡鏂拌繛鎺
+ ///
+ ///
+ public void NewConnEvent(string bstrSID)
+ {
+ m_strLastSID = bstrSID;
+ m_Form.textBox2.AppendText("鏀跺埌鏂拌繛鎺ワ細");
+ m_Form.textBox2.AppendText(bstrSID);
+ m_Form.textBox2.AppendText("\r\n");
+ }
+
+ ///
+ /// 閫氱煡杩炴帴鏀跺埌JSON鏁版嵁鍖
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RecMsgEvent(string bstrSID, uint nReqID, string bstrPushName, string bstrMsg)
+ {
+ m_Form.textBox2.AppendText("鏀跺埌鏂版暟鎹寘锛岃姹傚簭鍙凤細");
+ m_Form.textBox2.AppendText(nReqID.ToString());
+ m_Form.textBox2.AppendText("鍗忚鍚嶏細");
+ m_Form.textBox2.AppendText(bstrPushName);
+ m_Form.textBox2.AppendText("鍐呭锛");
+ m_Form.textBox2.AppendText(bstrMsg);
+ m_Form.textBox2.AppendText("\r\n");
+
+ if (bstrPushName == "Demo_OpenUrl")
+ {
+ /// 鑾峰緱鎵撳紑URL鍦板潃锛岃皟鐢ㄦ祻瑙堝櫒鎵撳紑
+ JsonServiceClass JsonService = new JsonServiceClass();
+ JsonService.ParseString(bstrMsg);
+ string strUrl = JsonService.GetStringValue("url");
+ JsonService = null;
+ m_Form.OpenUrl(strUrl);
+ return;
+ }
+ /// 鍥炰紶缁欑綉椤靛唴瀹
+ m_Form.Send(bstrSID,"鏀跺埌璇锋眰" + bstrPushName);
+ }
+
+ ///
+ /// 閫氱煡杩炴帴鏀跺埌鏂囨湰鍐呭
+ ///
+ ///
+ ///
+ public void RecTextEvent(string bstrSID, string bstrText)
+ {
+ m_Form.textBox2.AppendText("鏀跺埌鏂囨湰鍐呭锛");
+ m_Form.textBox2.AppendText(bstrText);
+ m_Form.textBox2.AppendText("\r\n");
+ /// 鍥炰紶缁欑綉椤靛唴瀹
+ m_Form.Send(bstrSID,"鏀跺埌鏂囨湰鍐呭" + bstrText);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RecByteEvent(string bstrSID, Object Content, uint nLen)
+ {
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void HttpReqEvent(uint nSessionID, string strUrl, string strPara)
+ {
+ }
+
+ ///
+ /// 閫氱煡鍏抽棴杩炴帴
+ ///
+ ///
+ public void ConnCloseEvent(string bstrSID)
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Form1.resx b/ZbaSDK/SampleCode/PluginExeDemo/Form1.resx
new file mode 100644
index 0000000000000000000000000000000000000000..1af7de150c99c12dd67a509fe57c10d63e4eeb04
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Form1.resx
@@ -0,0 +1,120 @@
+锘
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/PluginConfig.json b/ZbaSDK/SampleCode/PluginExeDemo/PluginConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..f8939f678ce21e94eb30944924aec64e82db79e6
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/PluginConfig.json
@@ -0,0 +1,17 @@
+{
+ "Type": 2,
+ "OS": 1,
+ "Control": 0,
+ "OSMinVer": "5.0",
+ "Version": "2.0.2.1",
+ "Name": "寮圭獥灏忕▼搴忚寖渚(C#璇█)",
+ "Corp": "ZorroSoft",
+ "Icon": "",
+ "Date": "2020.08.25",
+ "Desc": "寮圭獥灏忕▼搴忚寖渚(C#璇█)-婕旂ず鑴氭湰璇锋眰鎵撳紑鎸囧畾缃戠珯",
+ "Home": "http://zorrosoft.com/WRL",
+ "Down": "http://zorrosoft.com/WRL",
+ "Module": "PluginExeDemo.exe",
+ "PID": "99225C6D-B7A3-441c-AEFB-3EE23ACA2209",
+ "Updates": []
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/PluginExeDemo.csproj b/ZbaSDK/SampleCode/PluginExeDemo/PluginExeDemo.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..b7746cdf8ec1d623612edf7d69dcdc6ae80b7c31
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/PluginExeDemo.csproj
@@ -0,0 +1,147 @@
+锘
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {A293EC60-CDAD-4A3A-8BD6-953924479BBC}
+ WinExe
+ Properties
+ PluginExeDemo
+ PluginExeDemo
+ v4.0
+ Client
+ 512
+
+
+
+
+
+
+
+
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ bin\Debug\PluginExeDemo.exe.CodeAnalysisLog.xml
+ true
+ GlobalSuppressions.cs
+ prompt
+ MinimumRecommendedRules.ruleset
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
+ false
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ bin\Release\PluginExeDemo.exe.CodeAnalysisLog.xml
+ true
+ GlobalSuppressions.cs
+ prompt
+ MinimumRecommendedRules.ruleset
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
+ false
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+ {633D01A0-8A82-40CB-9CE6-8BA26B9C778C}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ False
+
+
+ {B5380DD6-64E5-462A-AB4E-2C3DFCCD2168}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ False
+
+
+
+
+
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/PluginExeDemo.sln b/ZbaSDK/SampleCode/PluginExeDemo/PluginExeDemo.sln
new file mode 100644
index 0000000000000000000000000000000000000000..a509e60c0a6b7c8c7e9c3c8db5215ce2c5c235b3
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/PluginExeDemo.sln
@@ -0,0 +1,23 @@
+锘
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginExeDemo", "PluginExeDemo.csproj", "{A293EC60-CDAD-4A3A-8BD6-953924479BBC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A293EC60-CDAD-4A3A-8BD6-953924479BBC}.Debug|x86.ActiveCfg = Debug|x86
+ {A293EC60-CDAD-4A3A-8BD6-953924479BBC}.Debug|x86.Build.0 = Debug|x86
+ {A293EC60-CDAD-4A3A-8BD6-953924479BBC}.Release|x86.ActiveCfg = Release|x86
+ {A293EC60-CDAD-4A3A-8BD6-953924479BBC}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {ED83012C-0D95-4661-8381-C87370A29FDD}
+ EndGlobalSection
+EndGlobal
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Program.cs b/ZbaSDK/SampleCode/PluginExeDemo/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7c088a04df7eb6b61e9e3542eff458ca687db140
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Program.cs
@@ -0,0 +1,28 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace PluginExeDemo
+{
+ static class Program
+ {
+ ///
+ /// 搴旂敤绋嬪簭鐨勪富鍏ュ彛鐐广
+ ///
+ [STAThread]
+ static void Main(string[] args)
+ {
+ if (args.Length <= 0)
+ {
+ MessageBox.Show("璇疯緭鍏ュ惎鍔ㄥ弬鏁");
+ Application.Exit();
+ return;
+ }
+
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1(args[0]));
+ }
+ }
+}
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Properties/AssemblyInfo.cs b/ZbaSDK/SampleCode/PluginExeDemo/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..32f2de3efd85c845d050b39872e1f369c058c0e5
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑甯歌淇℃伅閫氳繃浠ヤ笅
+// 鐗规ч泦鎺у埗銆傛洿鏀硅繖浜涚壒鎬у煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭
+[assembly: AssemblyTitle("PluginExeDemo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PluginExeDemo")]
+[assembly: AssemblyCopyright("Copyright(C) 2013-? ZorroSoft. All Rights Reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏 ComVisible 璁剧疆涓 false 浣挎绋嬪簭闆嗕腑鐨勭被鍨
+// 瀵 COM 缁勪欢涓嶅彲瑙併傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷锛
+// 鍒欏皢璇ョ被鍨嬩笂鐨 ComVisible 鐗规ц缃负 true銆
+[assembly: ComVisible(false)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("4823a65a-0ab1-4ee8-8030-24b050a00f79")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅闈㈠洓涓肩粍鎴:
+//
+// 涓荤増鏈
+// 娆$増鏈
+// 鍐呴儴鐗堟湰鍙
+// 淇鍙
+//
+// 鍙互鎸囧畾鎵鏈夎繖浜涘硷紝涔熷彲浠ヤ娇鐢ㄢ滃唴閮ㄧ増鏈彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊硷紝
+// 鏂规硶鏄寜濡備笅鎵绀轰娇鐢ㄢ*鈥:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("2.0.1.1")]
+[assembly: AssemblyFileVersion("2.0.1.1")]
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Properties/Resources.Designer.cs b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..67f4266522c1bbe823bbc50facc96cc8c15d27ef
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+锘//------------------------------------------------------------------------------
+//
+// 姝や唬鐮佺敱宸ュ叿鐢熸垚銆
+// 杩愯鏃剁増鏈: 4.0.30319.42000
+//
+// 瀵规鏂囦欢鐨勬洿鏀瑰彲鑳戒細瀵艰嚧涓嶆纭殑琛屼负锛屽苟涓斿鏋
+// 閲嶆柊鐢熸垚浠g爜锛岃繖浜涙洿鏀瑰皢涓㈠け銆
+//
+//------------------------------------------------------------------------------
+
+namespace PluginExeDemo.Properties
+{
+
+
+ ///
+ /// 涓涓己绫诲瀷鐨勮祫婧愮被锛岀敤浜庢煡鎵炬湰鍦板寲鐨勫瓧绗︿覆绛夈
+ ///
+ // 姝ょ被鏄敱 StronglyTypedResourceBuilder
+ // 绫婚氳繃绫讳技浜 ResGen 鎴 Visual Studio 鐨勫伐鍏疯嚜鍔ㄧ敓鎴愮殑銆
+ // 鑻ヨ娣诲姞鎴栫Щ闄ゆ垚鍛橈紝璇风紪杈 .ResX 鏂囦欢锛岀劧鍚庨噸鏂拌繍琛 ResGen
+ // (浠 /str 浣滀负鍛戒护閫夐」)锛屾垨閲嶆柊鐢熸垚 VS 椤圭洰銆
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// 杩斿洖姝ょ被浣跨敤鐨勩佺紦瀛樼殑 ResourceManager 瀹炰緥銆
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PluginExeDemo.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 涓烘墍鏈夎祫婧愭煡鎵鹃噸鍐欏綋鍓嶇嚎绋嬬殑 CurrentUICulture 灞炴э紝
+ /// 鏂规硶鏄娇鐢ㄦ寮虹被鍨嬭祫婧愮被銆
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Properties/Resources.resx b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Resources.resx
new file mode 100644
index 0000000000000000000000000000000000000000..af7dbebbacef595e3089c01c05671016c21a8304
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Resources.resx
@@ -0,0 +1,117 @@
+锘
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Properties/Settings.Designer.cs b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Settings.Designer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..16e852704682b682623e23611fdea49e700cdff9
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+锘//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PluginExeDemo.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/ZbaSDK/SampleCode/PluginExeDemo/Properties/Settings.settings b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Settings.settings
new file mode 100644
index 0000000000000000000000000000000000000000..39645652af62950ebf3b28ec3a5400dcec30b1c4
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginExeDemo/Properties/Settings.settings
@@ -0,0 +1,7 @@
+锘
+
+
+
+
+
+
diff --git a/ZbaSDK/SampleCode/PluginNetDll/PluginConfig.json b/ZbaSDK/SampleCode/PluginNetDll/PluginConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..dccd312ea63d3c7688abf6b8878aa1e8312f44ff
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginNetDll/PluginConfig.json
@@ -0,0 +1,24 @@
+{
+ "Type": 1,
+ "OS": 1,
+ "Control": 0,
+ "Asm": 1,
+ "OSMinVer": "5.0",
+ "Version": "2.0.2.1",
+ "Name": "鏃犵獥鍙e皬绋嬪簭鑼冧緥(C#璇█)",
+ "Corp": "ZorroSoft",
+ "Icon": "",
+ "Date": "2020.08.25",
+ "Desc": "鏃犵獥鍙e皬绋嬪簭鑼冧緥(C#璇█)",
+ "Home": "http://zorrosoft.com/WRL",
+ "Down": "http://zorrosoft.com/WRL",
+ "Module": "PluginNetDll.dll",
+ "PID": "D10495F4-DF0F-44FA-8647-91275347214A",
+ "Objects": [
+ {
+ "ProgID": "FCADA8A7-D975-42c6-B5D3-FA40F6FE1286",
+ "ClassID": "5DDA3CFF-6AD1-4836-B378-628B43748626"
+ }
+ ],
+ "Updates": []
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.csproj b/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..b36f35ef9d9c51b0724c4198e5e8ab8a1217c57a
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.csproj
@@ -0,0 +1,124 @@
+锘
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {4B48FC7A-94AC-45C1-9361-D12ADF21893A}
+ Library
+ Properties
+ PluginNetDll
+ PluginNetDll
+ v4.0
+ 512
+
+
+
+
+
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+ false
+
+
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ bin\Debug\PluginNetDll.dll.CodeAnalysisLog.xml
+ true
+ GlobalSuppressions.cs
+ prompt
+ MinimumRecommendedRules.ruleset
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
+ true
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
+ true
+ false
+
+
+ bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ bin\Release\PluginNetDll.dll.CodeAnalysisLog.xml
+ true
+ GlobalSuppressions.cs
+ prompt
+ MinimumRecommendedRules.ruleset
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
+ true
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {633D01A0-8A82-40CB-9CE6-8BA26B9C778C}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ False
+
+
+ {B5380DD6-64E5-462A-AB4E-2C3DFCCD2168}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ False
+
+
+
+
+
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.sln b/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.sln
new file mode 100644
index 0000000000000000000000000000000000000000..f7cae84eb0fd46a361a407704598710dcff68b3b
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.sln
@@ -0,0 +1,20 @@
+锘
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginNetDll", "PluginNetDll.csproj", "{4B48FC7A-94AC-45C1-9361-D12ADF21893A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4B48FC7A-94AC-45C1-9361-D12ADF21893A}.Debug|x86.ActiveCfg = Debug|x86
+ {4B48FC7A-94AC-45C1-9361-D12ADF21893A}.Debug|x86.Build.0 = Debug|x86
+ {4B48FC7A-94AC-45C1-9361-D12ADF21893A}.Release|x86.ActiveCfg = Release|x86
+ {4B48FC7A-94AC-45C1-9361-D12ADF21893A}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.suo b/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.suo
new file mode 100644
index 0000000000000000000000000000000000000000..9de3912b264c5e253d00ff7bea4ec36230b8043f
Binary files /dev/null and b/ZbaSDK/SampleCode/PluginNetDll/PluginNetDll.suo differ
diff --git a/ZbaSDK/SampleCode/PluginNetDll/Properties/AssemblyInfo.cs b/ZbaSDK/SampleCode/PluginNetDll/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a22632cbf22696c854bee3c041b2f0eab76e9be2
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginNetDll/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑甯歌淇℃伅閫氳繃浠ヤ笅
+// 鐗规ч泦鎺у埗銆傛洿鏀硅繖浜涚壒鎬у煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭
+[assembly: AssemblyTitle("PluginNetDll")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WRL")]
+[assembly: AssemblyCopyright("ZorroSoft Copyright 漏 2013-2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏 ComVisible 璁剧疆涓 false 浣挎绋嬪簭闆嗕腑鐨勭被鍨
+// 瀵 COM 缁勪欢涓嶅彲瑙併傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷锛
+// 鍒欏皢璇ョ被鍨嬩笂鐨 ComVisible 鐗规ц缃负 true銆
+[assembly: ComVisible(true)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("D10495F4-DF0F-44FA-8647-91275347214A")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅闈㈠洓涓肩粍鎴:
+//
+// 涓荤増鏈
+// 娆$増鏈
+// 鍐呴儴鐗堟湰鍙
+// 淇鍙
+//
+// 鍙互鎸囧畾鎵鏈夎繖浜涘硷紝涔熷彲浠ヤ娇鐢ㄢ滃唴閮ㄧ増鏈彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊硷紝
+// 鏂规硶鏄寜濡備笅鎵绀轰娇鐢ㄢ*鈥:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("2.0.1.1")]
+[assembly: AssemblyFileVersion("12.0.1.1")]
diff --git a/ZbaSDK/SampleCode/PluginNetDll/TestWrl.cs b/ZbaSDK/SampleCode/PluginNetDll/TestWrl.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1e180efe23d05d4431cbdac62c37ff3272116b30
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginNetDll/TestWrl.cs
@@ -0,0 +1,141 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using ZbaEngine;
+using ZbaBase;
+
+[Guid("FCADA8A7-D975-42c6-B5D3-FA40F6FE1286")]
+[TypeLibType(4160)]
+[ComVisible(true)]
+public interface ITestWrl
+{
+}
+
+namespace PluginNetDll
+{
+ [Guid("5DDA3CFF-6AD1-4836-B378-628B43748626")]
+ [TypeLibType(4160)]
+ [ClassInterface(ClassInterfaceType.None)]
+ [ComDefaultInterface(typeof(ITestWrl))]
+ [ComSourceInterfaces(typeof(ITestWrl))]
+ public class TestWrl : ITestWrl, IWrlConn
+ {
+ ///
+ /// Web Socket杩炴帴瀵硅薄
+ ///
+ IWebSocketConnect m_WebSocketConnect;
+
+ #region IWrlConn Members
+ void IWrlConn.Load(object piDispatch, string bstrAuthInfo, string bstrLang)
+ {
+ m_WebSocketConnect = piDispatch as IWebSocketConnect;
+ if (null != m_WebSocketConnect)
+ WriteLog("PluginNetDll", "鎴愬姛鑾峰緱WS鎺ュ彛");
+ else
+ WriteLog("PluginNetDll", "鑾峰彇WS鎺ュ彛澶辫触");
+ }
+
+ void IWrlConn.Unload(EWrlCloseConnType eCloseConnType, string bstrReason)
+ {
+ m_WebSocketConnect = null;
+ WriteLog("PluginNetDll", "璇锋眰鍗稿皬绋嬪簭");
+ }
+
+ string IWrlConn.HttpRequst(string bstrUrl, string bstrPara)
+ {
+ /// 鏀跺埌HTTP绫诲瀷璇锋眰锛屾殏鏈疄鐜
+ return "";
+ }
+
+ void IWrlConn.RecByte(ref byte pContent, uint nLen)
+ {
+ /// 鏀跺埌浜岃繘鍒舵暟鎹祦锛岀壒娈婄敤閫
+ WriteLog("PluginNetDll", "鎴戜笉鏄満鍣ㄤ汉锛");
+ }
+ ///
+ /// 閲嶇偣澶勭悊姝ゅ嚱鏁
+ ///
+ ///
+ ///
+ ///
+ void IWrlConn.RecJson(uint nReqID, string bstrPushName, string bstrContent)
+ {
+ /// 鍒涘缓JSON瑙f瀽鍣
+ JsonServiceClass JsonService = new JsonServiceClass();
+
+ bool bRet = JsonService.ParseString(bstrContent);
+ /// 鏍规嵁璇锋眰鍚嶇ОbstrPushName鍜岃姹傚弬鏁癰strContent鍒嗗埆瀹氫箟鑷繁鐨勫崗璁繘琛屽鐞嗐
+ string strReturn = "";
+ if(bstrPushName == "Demo_Return")
+ {
+ strReturn = "鏀跺埌璇锋眰 ";
+ strReturn += bstrPushName;
+ strReturn += " 鍐呭锛";
+ strReturn += bstrContent;
+ strReturn += " 搴忓彿锛";
+ strReturn += nReqID.ToString();
+ }
+ else if(bstrPushName == "Demo_WriteFile")
+ {
+ string strName = JsonService.GetStringValue("Name");
+ string strContent = JsonService.GetStringValue("Content");
+
+ string strAppPath = this.GetType().Assembly.Location;
+ strAppPath.Replace(".exe","");
+ strAppPath += "\\Data\\";
+ StreamWriter swFile = new StreamWriter(strAppPath + strName, true, Encoding.Unicode);
+ swFile.WriteLine(strContent);
+ swFile.Close();
+ swFile.Dispose();
+ strReturn = strAppPath + strName + "鍐欏叆鍐呭" ;
+ }
+ else
+ strReturn = "鏀跺埌鏈煡璇锋眰:" + bstrPushName;
+
+ WriteLog(bstrPushName, strReturn);
+ /// 缁欏墠绔洖澶嶈姹
+ m_WebSocketConnect.AsynSendText(strReturn);
+ }
+
+ void IWrlConn.RecText(string bstrContent)
+ {
+ /// 鏀跺埌鏂囨湰璇锋眰锛屼竴鑸兘鏄疛SON鍖
+ m_WebSocketConnect.AsynSendText("浣犵‘瀹氭病鍙戦敊锛");
+ }
+
+ ///
+ /// 妗嗘灦璋冪敤鍙戦侀氱煡
+ ///
+ ///
+ void IWrlConn.SendJson(string bstrContent)
+ {
+ if (null != m_WebSocketConnect)
+ m_WebSocketConnect.AsynSendText(bstrContent);
+ }
+
+ void IWrlConn.UsbChanged(string bstrDisk, uint nStatus, string bstrName)
+ {
+ /// USB瀛樺偍璁惧鎻掓嫈閫氱煡
+ }
+
+ #endregion
+
+ public void WriteLog(string documentName, string msg)
+ {
+ string LogFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data");
+ if (!System.IO.Directory.Exists(LogFilePath))
+ System.IO.Directory.CreateDirectory(LogFilePath);
+ string logFile = System.IO.Path.Combine(LogFilePath, documentName + "@" + DateTime.Today.ToString("yyyy-MM-dd") + ".txt");
+ bool writeBaseInfo = System.IO.File.Exists(logFile);
+ StreamWriter swLogFile = new StreamWriter(logFile, true, Encoding.Unicode);
+ swLogFile.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "\t" + msg);
+ swLogFile.Close();
+ swLogFile.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginWinExe/BrowserHost.h b/ZbaSDK/SampleCode/PluginWinExe/BrowserHost.h
new file mode 100644
index 0000000000000000000000000000000000000000..5509f648fdb576f8f0be3c829b25d1e9c55aa30e
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginWinExe/BrowserHost.h
@@ -0,0 +1,276 @@
+#pragma once
+
+#include // browser control definitions
+#include // browser event dispatch IDs
+#include
+
+enum CONTEXT_MENU_MODE // 上下文菜单
+ {
+ NoContextMenu, // 无菜单
+ DefaultMenu, // 默认菜单
+ TextSelectionOnly, // 仅文本选择菜单
+ CustomMenu // 自定义菜单
+ };
+
+class CDocHostUIHandler :
+ public IDocHostUIHandler,
+ public IOleCommandTarget
+{
+protected:
+
+ LONG m_cRef;
+
+ // Default interface pointers
+ CComQIPtr m_spDefaultDocHostUIHandler;
+
+ CComQIPtr m_spDefaultOleCommandTarget;
+
+public:
+ CDocHostUIHandler()
+ :m_cRef(0)
+ {
+ }
+
+ void ReleaseCom()
+ {
+ m_cRef = 0;
+
+ if(NULL != m_spDefaultDocHostUIHandler)
+ m_spDefaultDocHostUIHandler.Release();
+ if(NULL != m_spDefaultOleCommandTarget)
+ m_spDefaultOleCommandTarget.Release();
+ }
+
+ HRESULT STDMETHODCALLTYPE SetHandler(CComPtr spWebBrowser)
+ {
+ HRESULT result = E_NOINTERFACE;
+ if(NULL == spWebBrowser)
+ return E_POINTER;
+ CComPtr spDisp = NULL;
+ HRESULT hr = spWebBrowser->get_Document(&spDisp);
+ if (SUCCEEDED(hr) && spDisp)
+ {
+ // If this is not an HTML document (e.g., it's a Word doc or a PDF), don't sink.
+ CComQIPtr spHTML(spDisp);
+ if (spHTML)
+ {
+ // Get pointers to default interfaces
+ CComQIPtr spOleObject(spDisp);
+ if (spOleObject)
+ {
+ CComPtr spClientSite = NULL;
+ hr = spOleObject->GetClientSite(&spClientSite);
+ if (SUCCEEDED(hr) && spClientSite)
+ {
+ m_spDefaultDocHostUIHandler = spClientSite;
+ m_spDefaultOleCommandTarget = spClientSite;
+ }
+ }
+
+ // Set this class to be the IDocHostUIHandler
+ CComQIPtr spCustomDoc(spDisp);
+ if (spCustomDoc)
+ {
+ spCustomDoc->SetUIHandler(this);
+ result = S_OK;
+ }
+ }
+ }
+ spDisp = NULL;
+ return result;
+ }
+
+ /// IDocHostUIHandler
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
+ {
+ HRESULT result = S_OK;
+
+ if (IsBadWritePtr(ppvObject, sizeof(LPVOID)))
+ result = E_INVALIDARG;
+
+ if (result == S_OK)
+ {
+ *ppvObject = NULL;
+
+ if ( IsEqualIID( riid, IID_IUnknown ) )
+ *ppvObject = this;
+ else if ( IsEqualIID( riid, IID_IDispatch ) )
+ *ppvObject = (IDispatch *) this;
+ else if ( IsEqualIID( riid, IID_IDocHostUIHandler ) )
+ *ppvObject = (IDocHostUIHandler *) this;
+ else if ( IsEqualIID( riid, IID_IOleCommandTarget ) )
+ *ppvObject = (IOleCommandTarget *) this;
+ else
+ result = E_NOINTERFACE;
+ }
+
+ if (result == S_OK)
+ this->AddRef();
+
+ return result;
+ }
+
+ ULONG STDMETHODCALLTYPE AddRef()
+ {
+ InterlockedIncrement(&m_cRef);
+ return m_cRef;
+ }
+
+ ULONG STDMETHODCALLTYPE Release()
+ {
+ ULONG ulRefCount = InterlockedDecrement(&m_cRef);
+ if(m_cRef == 0)
+ {
+ delete this;
+ }
+ return ulRefCount;
+ }
+
+ STDMETHOD(ShowContextMenu)(DWORD dwID, POINT FAR* ppt, IUnknown FAR* pcmdTarget, IDispatch FAR* pdispReserved)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->ShowContextMenu(dwID, ppt, pcmdTarget, pdispReserved);
+ return S_FALSE;
+ }
+
+ STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject FAR* pActiveObject,
+ IOleCommandTarget FAR* pCommandTarget,
+ IOleInPlaceFrame FAR* pFrame,
+ IOleInPlaceUIWindow FAR* pDoc)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->ShowUI(dwID, pActiveObject, pCommandTarget, pFrame, pDoc);
+ return S_FALSE;
+ }
+
+ STDMETHOD(GetHostInfo)(DOCHOSTUIINFO FAR *pInfo)
+ {
+ pInfo->cbSize = sizeof(DOCHOSTUIINFO);
+ pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION;
+ pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
+ pInfo->pchHostCss = 0;
+ pInfo->pchHostNS = 0;
+// if(m_spDefaultDocHostUIHandler)
+ // return m_spDefaultDocHostUIHandler->GetHostInfo(pInfo);
+ return S_OK;
+ }
+
+ STDMETHOD(HideUI)(void)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->HideUI();
+ return S_OK;
+ }
+
+ STDMETHOD(UpdateUI)(void)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->UpdateUI();
+ return S_OK;
+ }
+
+ STDMETHOD(EnableModeless)(BOOL fEnable)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->EnableModeless(fEnable);
+ return S_OK;
+ }
+
+ STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->OnDocWindowActivate(fActivate);
+ return S_OK;
+ }
+
+ STDMETHOD(OnFrameWindowActivate)(BOOL fActivate)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->OnFrameWindowActivate(fActivate);
+ return S_OK;
+ }
+
+ STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow FAR* pUIWindow, BOOL fFrameWindow)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->ResizeBorder(prcBorder, pUIWindow, fFrameWindow);
+ return S_OK;
+ }
+
+ STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID FAR* pguidCmdGroup, DWORD nCmdID)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->TranslateAccelerator(lpMsg, pguidCmdGroup, nCmdID);
+ return E_NOTIMPL;
+ }
+
+ STDMETHOD(GetOptionKeyPath)(LPOLESTR FAR* pchKey, DWORD dw)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->GetOptionKeyPath(pchKey, dw);
+ return E_FAIL;
+ }
+
+ STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ m_spDefaultDocHostUIHandler->GetDropTarget(pDropTarget, ppDropTarget);
+ return S_OK;
+ }
+
+ STDMETHOD(GetExternal)(IDispatch** ppDispatch)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->GetExternal(ppDispatch);
+ return S_FALSE;
+ }
+
+ STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->TranslateUrl(dwTranslate, pchURLIn, ppchURLOut);
+ return S_FALSE;
+ }
+
+ STDMETHOD(FilterDataObject)(IDataObject* pDO, IDataObject** ppDORet)
+ {
+ if (m_spDefaultDocHostUIHandler)
+ return m_spDefaultDocHostUIHandler->FilterDataObject(pDO, ppDORet);
+ return S_FALSE;
+ }
+
+ //
+ // IOleCommandTarget
+ //
+ STDMETHOD(QueryStatus)(
+ /*[in]*/ const GUID *pguidCmdGroup,
+ /*[in]*/ ULONG cCmds,
+ /*[in,out][size_is(cCmds)]*/ OLECMD *prgCmds,
+ /*[in,out]*/ OLECMDTEXT *pCmdText)
+ {
+ if(NULL == m_spDefaultOleCommandTarget)
+ return E_NOINTERFACE;
+ return m_spDefaultOleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
+ }
+
+ /// 屏蔽JS脚本错误
+ STDMETHOD(Exec)(
+ /*[in]*/ const GUID *pguidCmdGroup,
+ /*[in]*/ DWORD nCmdID,
+ /*[in]*/ DWORD nCmdExecOpt,
+ /*[in]*/ VARIANTARG *pvaIn,
+ /*[in,out]*/ VARIANTARG *pvaOut)
+ {
+ if (nCmdID == OLECMDID_SHOWSCRIPTERROR)
+ {
+ // Don't show the error dialog, but
+ // continue running scripts on the page.
+ (*pvaOut).vt = VT_BOOL;
+ (*pvaOut).boolVal = VARIANT_TRUE;
+ return S_OK;
+ }
+ if(NULL == m_spDefaultOleCommandTarget)
+ return E_NOINTERFACE;
+ return m_spDefaultOleCommandTarget->Exec(pguidCmdGroup, nCmdID, nCmdExecOpt, pvaIn, pvaOut);
+ }
+};
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginWinExe/Config.json b/ZbaSDK/SampleCode/PluginWinExe/Config.json
new file mode 100644
index 0000000000000000000000000000000000000000..e2f2dd527d5554394a59853a7365a2da79276429
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginWinExe/Config.json
@@ -0,0 +1,3 @@
+{
+ "PORT": 12800
+}
\ No newline at end of file
diff --git a/ZbaSDK/SampleCode/PluginWinExe/MainDlg.cpp b/ZbaSDK/SampleCode/PluginWinExe/MainDlg.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55b61132797ab595b674704c416cffb93e981802
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginWinExe/MainDlg.cpp
@@ -0,0 +1,414 @@
+// MainDlg.cpp : implementation of the CMainDlg class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "resource.h"
+
+#include "MainDlg.h"
+
+CComVariant g_varWebHeader = CComVariant(L"Accept: */*\r\nAccept-Language: zh-CN\r\nAccept-Charset: utf-8\r\nContent-Type: application/x-www-form-urlencoded\r\n");
+
+int Us2ToChar(const ATL::CString& strSrc, char** pDst,int nCodePage)
+{
+ int iLength=::WideCharToMultiByte(nCodePage,0,strSrc,-1,NULL,0,NULL,NULL);
+ if(!iLength)
+ return iLength;
+ iLength++;
+ char *strA=NULL;
+ strA= new char[iLength];
+ if(strA==NULL)
+ return 0;
+ ::memset(strA,0,iLength*sizeof(char));
+ int iLength1 = 0;
+ if(nCodePage)
+ iLength1 = ::WideCharToMultiByte(nCodePage,WC_COMPOSITECHECK,strSrc,-1,strA,iLength-1,NULL,NULL);
+ else
+ iLength1 = ::WideCharToMultiByte(nCodePage,0,strSrc,-1,strA,iLength-1,NULL,NULL);
+ *pDst=strA;
+ return iLength1;
+}
+
+LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+{
+ // center the dialog on the screen
+ CenterWindow();
+
+ // set icons
+ HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
+ SetIcon(hIcon, TRUE);
+ HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
+ SetIcon(hIconSmall, FALSE);
+
+ m_spiWebBrowser = NULL;
+ m_spiHtmlDoc = NULL;
+
+ m_nSocketProxyCookie = 0;
+ m_spiSocketProxy = NULL;
+ m_spiSocketProxyEvent = NULL;
+
+ this->PostMessage(WM_APP,0,0); /// 异步初始化侦听服务
+ return TRUE;
+}
+
+void CMainDlg::InitWebCtrl()
+{
+ CRect rcClient;
+ this->GetClientRect(&rcClient);
+ rcClient.left += 5;
+ rcClient.top += 5;
+ rcClient.right -= 5;
+ rcClient.bottom -= 150;
+
+ if(!m_ctlWebWindow.IsWindow())
+ {
+ HWND hWndWB = m_ctlWebWindow.Create(m_hWnd,rcClient,NULL,
+ WS_CHILD|WS_VISIBLE,0,IDC_WEB_BROWSER);
+ ATLASSERT(hWndWB);
+ if(!::IsWindow(hWndWB))
+ this->MessageBox(L"初始化IE控件窗口失败!");
+ }
+ m_ctlWebWindow.SetWindowPos(this->m_hWnd,rcClient.left,rcClient.top,rcClient.Width(),rcClient.Height(),SWP_SHOWWINDOW);
+
+ if(NULL == m_spiWebBrowser)
+ {
+ //Create the WebBrowser control(IE) with CLSID
+ CComPtr spUnkWebBrowser = NULL;
+ HRESULT hr = spUnkWebBrowser.CoCreateInstance(CLSID_WebBrowser);
+ ATLASSERT(SUCCEEDED(hr));
+ //Attach the WebBrowser control to host window
+ if(NULL != spUnkWebBrowser)
+ {
+ m_ctlWebWindow.AttachControl(spUnkWebBrowser,NULL);
+ spUnkWebBrowser = NULL;
+ }
+
+ //Advise sink map
+ hr = AtlAdviseSinkMap(this,true);
+ ATLASSERT(SUCCEEDED(hr));
+
+ //Query interface
+ hr = m_ctlWebWindow.QueryControl(&m_spiWebBrowser);
+ if(FAILED(hr))
+ this->MessageBox(L"获取IE控件对象失败!");
+
+ if(NULL != m_spiWebBrowser)
+ {
+ m_spiWebBrowser->put_Silent(VARIANT_TRUE);
+ CComVariant varVal;
+ varVal.Clear();
+ m_spiWebBrowser->Navigate(CComBSTR(L"about:blank"),&varVal,&varVal,&varVal,&g_varWebHeader);
+ }
+ }
+}
+
+LRESULT CMainDlg::OnOpenUrl(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ if(NULL == m_spiWebBrowser)
+ {
+ this->MessageBox(L"还未初始化IE控件!");
+ return 0;
+ }
+ if(m_strOpenUrl.IsEmpty())
+ {
+ this->MessageBox(L"打开URL为空!");
+ return 0;
+ }
+ CComVariant varVal;
+ varVal.Clear();
+ HRESULT hRet = m_spiWebBrowser->Navigate(CComBSTR(m_strOpenUrl),\
+ &varVal,&varVal,&varVal,&g_varWebHeader);
+ if(SUCCEEDED(hRet))
+ m_ctlWebWindow.SetFocus();
+ else
+ {
+ CString strErrCode;
+ strErrCode.Format(L"打开网站失败,错误码:%ld",hRet);
+ this->MessageBox(strErrCode);
+ }
+ return 1;
+}
+
+void CMainDlg::NavigateComplete2(IDispatch *pDisp, VARIANT *pvarURL)
+{
+ if(NULL == pvarURL)
+ return;
+ if(NULL == m_spiHtmlDoc)
+ m_spiHtmlDoc = this->GetHtmlDoc();
+ if(NULL != m_spiHtmlDoc)
+ {
+ m_DocHostUIHandler.SetHandler(m_spiWebBrowser);
+ }
+}
+
+void CMainDlg::BeforeNavigate2(IDispatch *pDisp,
+ CComVariant &URL, CComVariant &Flags, CComVariant &TargetFrameName,
+ CComVariant &PostData, CComVariant &Headers, VARIANT_BOOL* Cancel)
+{
+ (*Cancel) = VARIANT_FALSE;
+ CString strUrl(URL.bstrVal);
+}
+
+void CMainDlg::OnNewWindow3(LPDISPATCH* ppDisp, VARIANT_BOOL * Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl)
+{
+ /// 取消新窗口
+ (*Cancel) = VARIANT_TRUE;
+
+ if(NULL == m_spiWebBrowser)
+ return;
+ HRESULT hRet(E_FAIL);
+ if(NULL == m_spiHtmlDoc)
+ m_spiHtmlDoc = GetHtmlDoc();
+ if (NULL == m_spiHtmlDoc)
+ return;
+ CComPtr spiHtmlElement = NULL;
+ hRet = m_spiHtmlDoc->get_activeElement(&spiHtmlElement);
+ if(NULL == spiHtmlElement)
+ return;
+ CComPtr spiAnchorElement = NULL;
+ hRet = spiHtmlElement->QueryInterface(IID_IHTMLAnchorElement, (void**)&spiAnchorElement);
+ if (NULL == spiAnchorElement)
+ {
+ spiHtmlElement = NULL;
+ return;
+ }
+ CComBSTR bstrElementHref;
+ /// 获取当前点击的链接地址
+ hRet = spiAnchorElement->get_href(&bstrElementHref);
+ spiAnchorElement = NULL;
+ spiHtmlElement = NULL;
+
+ ATLASSERT(bstrElementHref.Length());
+ CString strReqUrl(bstrElementHref.m_str);
+ bstrElementHref.Empty();
+ if(0 == strReqUrl.Left(2).CompareNoCase(L"//"))
+ {
+ strReqUrl.Insert(0,L"http:");
+ }
+ CComVariant varVal;
+ varVal.Clear();
+ hRet = m_spiWebBrowser->Navigate(CComBSTR(strReqUrl),&varVal,&varVal,&varVal,&g_varWebHeader);
+ strReqUrl.Empty();
+}
+
+CComPtr CMainDlg::GetHtmlDoc()
+{
+ CComPtr spiHtmlDoc = NULL;
+ if(NULL == m_spiWebBrowser)
+ return spiHtmlDoc;
+ CComPtr< IDispatch > spdispDoc = NULL;
+ HRESULT hRet = m_spiWebBrowser->get_Document(&spdispDoc);
+ if (FAILED(hRet) || NULL == spdispDoc)
+ return spiHtmlDoc;
+ CComPtr spDoc = NULL;
+ hRet = spdispDoc->QueryInterface(IID_IHTMLDocument2,(void **)&spiHtmlDoc);
+ spdispDoc = NULL;
+ return spiHtmlDoc;
+}
+
+void CMainDlg::DocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
+{
+ CString strUrl(pvarURL->bstrVal);
+}
+
+LRESULT CMainDlg::OnInitConn(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+{
+ if(NULL != m_spiSocketProxy)
+ return 0;/// 已经初始化
+ HRESULT hRet = m_spiSocketProxy.CreateInstance(__uuidof(SocketProxy));
+ ATLASSERT(SUCCEEDED(hRet));
+ if(FAILED(hRet))
+ {
+ this->MessageBox(L"Web Socket基础组件还未正常注册成功!");
+ InitWebCtrl();
+ return 0;
+ }
+#ifdef NEED_FINAL_CONSTRUCT
+ CComObject::CreateInstance(&(m_spiSocketProxyEvent));
+#else
+ m_spiSocketProxyEvent = new CComObject< CProxyServerEvent >;
+#endif
+ ATLASSERT(m_spiSocketProxyEvent);
+ if(NULL != m_spiSocketProxyEvent)
+ {
+ m_spiSocketProxyEvent->SetCallPara(this->m_hWnd);
+ //建立事件连接
+ hRet = AtlAdvise(m_spiSocketProxy,this->m_spiSocketProxyEvent->GetUnknown(),
+ DIID__ISocketProxyEvents,&this->m_nSocketProxyCookie);
+ ATLASSERT(SUCCEEDED(hRet));
+ if(!m_nPort)
+ m_nPort = 12800;
+ USHORT nTruePort = 0;
+ hRet = m_spiSocketProxy->Listen(m_nPort,CComBSTR(m_strSID),CComBSTR(m_strAuthInfo),&nTruePort);
+ if(FAILED(hRet))
+ {
+ CComBSTR bstrErr;
+ m_spiSocketProxy->get_LastErrInfo(NULL,&bstrErr);
+ this->MessageBox(bstrErr.m_str);
+ bstrErr.Empty();
+ }
+ }
+ InitWebCtrl();
+ return 1;
+}
+
+LRESULT CMainDlg::OnNewConnect(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ BSTR bstrSID = (BSTR)lParam;
+ /// 这里记录连接标识,然后可以调用通知发送信息
+ m_mapConnID[bstrSID] = bstrSID;
+ this->GetDlgItem(IDC_EDIT_LOG).SetWindowText(CString(L"收到新连接通知:") + bstrSID);
+ return 0;
+}
+
+LRESULT CMainDlg::OnRecMessage(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ CString strReqName = (BSTR)wParam;
+ BSTR bstrContent = (BSTR)lParam;
+
+ CString strMsg;
+ strMsg.Format(L"收到请求为 %s 的JSON数据包:%s",strReqName,(CString)bstrContent);
+ this->GetDlgItem(IDC_EDIT_LOG).SetWindowText(strMsg);
+ strMsg.Empty();
+ ULONG nReqID = 0;
+ m_spiSocketProxy->AsynSendText(CComBSTR(m_mapConnID.begin()->first),\
+ CComBSTR(CString(L"桌面APP收到请求参数:")+bstrContent),&nReqID);
+ /// 解析收到的命令
+ IJsonServicePtr spiJsonService = NULL;
+ HRESULT hRet = spiJsonService.CreateInstance(__uuidof(JsonService));
+ if(NULL == spiJsonService)
+ return 0;
+ VARIANT_BOOL bLoadFlag = VARIANT_FALSE;
+ spiJsonService->put_CodingType(CODINGTYPE_US2);
+ spiJsonService->ParseString(bstrContent,&bLoadFlag);
+ if(VARIANT_FALSE == bLoadFlag)
+ {
+ spiJsonService = NULL;
+ return 0;
+ }
+ if(0 == strReqName.CompareNoCase(L"Demo_OpenUrl"))
+ {
+ CComBSTR bstrVal;
+ spiJsonService->GetStringValue(CComBSTR(L"url"),&bstrVal);
+ m_strOpenUrl.Empty();
+ m_strOpenUrl = bstrVal.m_str;
+ bstrVal.Empty();
+ /// 通知打开网站
+ this->PostMessage(WM_APP_OPENURL,0,0);
+ }
+ spiJsonService = NULL;
+ return 0;
+}
+
+LRESULT CMainDlg::OnRecText(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ BSTR bstrContent = (BSTR)lParam;
+ CString strMsg;
+ strMsg.Format(L"收到文本数据包:%s",(CString)bstrContent);
+ this->GetDlgItem(IDC_EDIT_LOG).SetWindowText(strMsg);
+ strMsg.Empty();
+ ULONG nReqID = 0;
+ m_spiSocketProxy->AsynSendText((BSTR)wParam,CComBSTR(CString(L"桌面APP收到内容:")+bstrContent),&nReqID);
+ return 0;
+}
+
+LRESULT CMainDlg::OnCloseConnect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ BSTR bstrSID = (BSTR)wParam;
+ BSTR bstrContent = (BSTR)lParam;
+ CString strMsg;
+ strMsg.Format(L"收到标识为 %s 的连接通知关闭:%s",(CString)bstrSID,(CString)bstrContent);
+ this->GetDlgItem(IDC_EDIT_LOG).SetWindowText(strMsg);
+ strMsg.Empty();
+ return 0;
+}
+
+LRESULT CMainDlg::OnRecByte(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ /// 暂未实现,通知收到字节流
+ return 0;
+}
+
+void CMainDlg::UnAdviseSocket()
+{
+ if(0 == m_nSocketProxyCookie)
+ return;
+ AtlUnadvise(m_spiSocketProxy,DIID__ISocketProxyEvents,m_nSocketProxyCookie);
+ m_nSocketProxyCookie = 0;
+ m_spiSocketProxyEvent = NULL;
+
+ m_spiSocketProxy->Close();
+ m_spiSocketProxy = NULL;
+}
+
+LRESULT CMainDlg::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+{
+ CSimpleDialog dlg;
+ dlg.DoModal();
+ return 0;
+}
+
+LRESULT CMainDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+{
+ // TODO: Add validation code
+ if(NULL == m_spiSocketProxy)
+ return 0;
+ VARIANT_BOOL bIsReady = VARIANT_FALSE;
+ m_spiSocketProxy->get_Ready(&bIsReady);
+ /// 通过命令行传进来端口
+ if(VARIANT_TRUE != bIsReady)
+ {
+ this->MessageBox(L"侦听服务还未就绪!");
+ return 0;
+ }
+ CComBSTR bstrContent;
+ this->GetDlgItem(IDC_EDIT_CONTENT).GetWindowText(&bstrContent);
+ ULONG nReqID = 0;
+ CString strContent(bstrContent.m_str);
+ if(!m_mapConnID.size())
+ {
+ this->MessageBox(L"还未有活动连接!");
+ return 0;
+ }
+ if(strContent.IsEmpty())
+ return 0;
+ CString strReturn;
+ strContent.Replace(L"\"",L"\\\"");
+ strReturn.Format(_T("{\"rid\":%ld,\"req\":\"Send\",\"data\":{\"Content\":\"%s\"}}"), \
+ nReqID,strContent);
+ HRESULT hRet = m_spiSocketProxy->AsynSendText(CComBSTR(m_mapConnID.begin()->first),\
+ CComBSTR(strReturn),&nReqID);
+ if(!nReqID || FAILED(hRet))
+ {
+ CComBSTR bstrErrInfo;
+ m_spiSocketProxy->get_LastErrInfo(CComBSTR(m_mapConnID.begin()->first),&bstrErrInfo);
+ this->MessageBox(bstrErrInfo.m_str);
+ bstrErrInfo.Empty();
+ }
+ else
+ {
+ this->GetDlgItem(IDC_EDIT_CONTENT).SetWindowText(L"");
+ }
+ return 0;
+}
+
+LRESULT CMainDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+{
+ UnAdviseSocket();
+
+ m_spiHtmlDoc = NULL;
+ m_DocHostUIHandler.ReleaseCom();
+ if(NULL != m_spiWebBrowser)
+ {
+ AtlAdviseSinkMap(this,false);
+ /// 调用退出
+ m_spiWebBrowser->Quit();
+ m_spiWebBrowser = NULL;
+ }
+
+ if(m_ctlWebWindow.IsWindow())
+ m_ctlWebWindow.DestroyWindow();
+
+ EndDialog(wID);
+ return 0;
+}
diff --git a/ZbaSDK/SampleCode/PluginWinExe/MainDlg.h b/ZbaSDK/SampleCode/PluginWinExe/MainDlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7b332705f79aa2f65e9b5bf0eddb9038c512e5f
--- /dev/null
+++ b/ZbaSDK/SampleCode/PluginWinExe/MainDlg.h
@@ -0,0 +1,150 @@
+// MainDlg.h : interface of the CMainDlg class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+#include