起因
忽然发现自己很喜欢,git
在 commit
时候,如果你没有输入-m
参数的的话,它对vim的那种调用. 你可以使用vim的各种功能,慢慢的输入所有的数据,并且可以通过文本的方式自由的提示.甚至可以用ascii画图.然后在vim 关闭之后(似乎不是这样,难道git
时在追踪文件是否被锁定?)输入的信息将会得到处理.
经过
大概的实现就是开启子进程,然后等待子进程关闭,这样.查了下Microsoft文档,很快找到了进程相关的api,然后就基本完成了.代码就是这个样子.
#pragma once
#include <windows.h>
#include <string>
#include <fstream>
#include <vector>
using std::vector;
using std::string;
using std::ofstream;
using std::ifstream;
namespace mine{
class VUI {
char s[30]="gvim temporary_file_name";//why 30 is needed? I think this should cause error.
char *cmd=s+0;
char *tmp=cmd+5;
string buffer;
const char left='(',right=')';
public:
vector<string> answer;
void setQuestion(const string& s) {//use "(" and ")" to set the boundaries for answers
buffer=s;//is copy needed?
answer.clear();
}
bool ask() {//more return value checking is needed
//write question to file
ofstream fo(tmp);
fo<<buffer;
fo.close();
//open gvim and wait until gvim is closed
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
ZeroMemory(&pi,sizeof(pi));
if(!CreateProcess(NULL,
cmd,
NULL,NULL,false,0,NULL,NULL,&si,&pi))return false;
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//read file and extract answers
ifstream fi(tmp);
fi.seekg(0,ifstream::end);
int len=fi.tellg();
fi.seekg(0,ifstream::beg);
buffer.resize(len+1);
fi.read(&buffer[0],len);
fi.close();
bool in=false;
for(int i=0;i<len;++i){
if(buffer[i]==left){
in=true;
answer.push_back("");
}
else if(buffer[i]==right)in=false;
else if(in){
answer.back()+=buffer[i];
}
}
remove(tmp);
return true;
}
};
};
结果
封装成了一个类,把一些自动提取结果的代码加进去了,其它也没什么特别的.