设计流程
具体流程
- 利用开源jar包,jRE自带的sax解析器实现把Fastinfoset文档转换成XML文档。
- 生成JAR包。
- 下载现有的Notepad++开发模板,修改模板,调用JAR包实现FIS转换
参考网址
利用 Notepad++ 插件技术开发直接打开 FastInfoset 格式 XML 文件
java实现FIS到XML
部分代码
InputStream bis = new BufferedInputStream(new FileInputStream(args[0]),2048);
OutputStream xmlDocument = new ByteArrayOutputStream();
// Create the transformer
Transformer tx = TransformerFactory.newInstance().newTransformer();
// Transform to convert the FI document to an XML document
tx.transform(new FastInfosetSource(bis), new StreamResult(xmlDocument));
byte[] b=((ByteArrayOutputStream) xmlDocument).toByteArray();
String rtStr= new String(b, "GB2312");
代码实现
生成JAR包
有外部依赖JAR包,可以手工配置MANIFEST.MF,
编写格式
第一行不能空,行与行之间不能有空行,每一行的最后一个字符不能是空格
最后一行一定是空行
每个属性的名称和值之间(冒号后面)一定要有空格
文件的每一行都不能超过72个字节(一般是70个ASCII字母加上回车换行符);如果72个字节不够用,则另起一行并以空格开头:以空格开头的行都被视为前一行的续行。
demo格式:
Manifest-Version: 1.0
Class-Path: FastInfoset-1.2.9.jar sax2.jar
Main-Class: FIS.FIS
参考资料
c++调用JAR
具体流程
CreateProcess
使用CreateProcess,可以解决system()弹出控制台的问题。
CreatePipe
利用管道共享内存,实现进程间通信。获得子进程的返回结果
WaitForSingleObject
应为子进程的调用是异步调用,使用WaitForSingleObject等待子进程执行完成。
实现代码
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR cmdline1[] = TEXT("java -jar fasttoxml.jar E:\\Study\\Ctrip\\FISerialization\\FISerialization\\bin\\Debug\\Noemax.FastInfoset.Net41.fi");
string buffer = call(cmdline1);
int lll = buffer.size();
int len = strlen(buffer.c_str());
char *dd = (char*)malloc((len + 1)*sizeof(char));
strcpy_s(dd, len + 1, buffer.c_str());
printf("%s", dd);
system("pause");
}
char* call(TCHAR cmdline[])
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead, hWrite;
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
return 0;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.hStdInput = hRead;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//TCHAR cmdline[] = TEXT("ipconfig ");
//关键步骤,CreateProcess函数参数意义请查阅MSDN
//cmdline 必须是传形参
if (!CreateProcess(NULL, cmdline, NULL, NULL, true, NULL, NULL, NULL, &si, &pi))
{
return 0;
}
CloseHandle(hWrite);
char buffer[MAX_SIZE];
DWORD bytesRead, dwWritten;
std::string s3s = "";
WaitForSingleObject(pi.hProcess, INFINITE);
while (true)
{
if (!ReadFile(hRead, buffer, MAX_SIZE, &bytesRead, NULL) ||
bytesRead == 0)
{
break;
}
else
{
buffer[bytesRead] = '\0';
}
/*if (!WriteFile(hStdout, buffer, bytesRead, &dwWritten, NULL))
break;*/
s3s = buffer;
}
int len = s3s.size();
return buffer;
}
具体示例代码
notepad++插件开发
具体流程说明
Notepad++ 开发的要点主要分布在以下几个接口中,描述如下:
插件的名称和自我描述,这一部分定义了插件在 plugin 菜单的显示,包括入口名称和子菜单条目。一般来说入口的名称显示在菜单向上,Notepad++ 定义了一个全局变量 NPP_PLUGIN_NAME 来描述这个名称,我们只需要更改它即可
。所有的插件依赖 UI 的 plugin 菜单来激发一个特定的任务,所有的菜单初始化选项必须在 commandMenuInit 函数中完成。利用 Notepad++暴露的方法 setCommand 方法,可以把菜单项与插件自定的方法体关联起来,setCommand 的方法定义如下:
清单 3. setCommand 定义
bool setCommand(size_t index,
TCHAR *cmdName,
PFUNCPLUGINCMD pFunc,
ShortcutKey *sk = NULL,
bool check0nInit = false);
其中的参数意义如下 :
index:从零开始,表示菜单项目的顺序;
commandName: 显示在菜单上的名称;
functionPointer: 函数指针,表示函数的确切地址;
shortcut: 可选择,快捷键定义;
check0nInit: 可选择,定义这个菜单项是否为默认已选择条目。
利用 setCommand 函数所设置的相会自动显示在已定义的插件菜单条目中。
与 Notepad++的交互。在自定义的函数体内,可以获取 Notepad++的句柄,用来设置一些全局的条目,利用模板中定义好的导出函数 setInfo,Notepad++ 程序就会给插件提供一个 NppData 结构实例,其中就有当前 Notepad++的句柄。在本文中所示的插件视线中,打开 FastInfoset文件后,为了显示 XML 着色,必须发送一条切换语言的消息如下:
清单 4. 发送消息到 Notepad++
::SendMessage(nppData._nppHandle,NPPM_SETCURRENTLANGTYPE,
0,(LPARAM)LangType::L_XML);
这样就可以在打开 FastInfoset 文件立刻切换至 XML 语言。 更重要的,插件需要与 Scintilla 控件交互,为了获取 Scintilla 的句柄,需要对 Notepad++ 程序问询,使得 Notepad++ 能够返回当前需要的 Scintilla 句柄。有了 Scintilla 句柄 ,就可以通过多种消息来控制显示和获取当前的文本了。
清单 5. 设置文本
// 设置文本
::SendMessage(curScintilla, SCI_SETTEXT, 0, (LPARAM)str);
清单 6. 获取文本
// 获取文本
::SendMessage(curScintilla, SCI_GETTEXT, (WPARAM)(Length+1), (LPARAM)str);
需要说明的是,文本的获取必须传递文本的大小和存储缓存,文本大小可以通过 SCI_GETLENGTH 消息来取得。