由于项目要用到文件的转换(word,excel,txt,图片等等转换成ceb 格式),思来想去,不知道用哪种方法来做,网上也没有一些关于 用程序来转换ceb的资料,于是就联系官网,看看他们有没有提供一些借口或者类库给我们这些程序员调用,联系了一位李经理,人蛮好的,很耐心跟我交流的一会,也发了服务版(测试)的提供我参考,看了参考资料,发现是用Java来做的,他的资料说,里面MakerSDKJNI2.dll 有提供接口,也是唯一一个接口public native int SyncConvert2(StringpszSrcFileUrl,
String pszDstFileUrl);我在调用的时候,无法进入接口,于是决定放弃调用它的接口,直接在它的转换器上,用程序直接操作。我用的版本是Apabi Maker 5.1。
看看效果图吧
点击button1的时候,程序去做批量转换的工作
现在我们来看下代码吧
- using System.Runtime.InteropServices;
- //查找主窗体
- [DllImport("user32.dll", EntryPoint = "FindWindow")]
- public static extern int FindWindow(string lpClassName, string lpWindowName);
-
- // Find Window Ex
- // 查找窗体的子窗体
- // @para1: 父窗体的句柄 如果为null,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口
- // @para2: 子窗体的句柄 如果为null,从@para1的直接子窗口的第一个开始查找
- // @para3: 子窗体的类名 为""表示所有类
- // @para4: 子窗体的标题 为""表示要查找的窗体无标题 如空白的textBox控件
- // return: 子窗体的句柄
- [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
- private static extern IntPtr FindWindowEx( IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
-
- // SendMessage
-
- // 向窗体发送消息
-
- // @para1: 窗体句柄
-
- // @para2: 消息类型
-
- // @para3: 附加的消息信息
-
- // @para4: 附加的消息信息
-
- [DllImport("User32.dll", EntryPoint = "SendMessage")]
- private static extern int SendMessage(
- IntPtr hWnd,
- int Msg,
- IntPtr wParam,
- string lParam);
- const int WM_CLICK = 0x00F5; // 发送点击消息如调用该窗体(按钮)的"button1_Click();"
- const int WM_SETTEXT = 0x000C; // 设置窗体文本 如设置文本框内容
- <pre name="code" class="csharp"> const int WM_GETTEXT = 0x000D; //获取文本 即一般是获取textbox.text和label.text
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(
IntPtr hWnd,
uint Msg,
int wParam,
int lParam);
/// <summary>
/// 向控件发送消息(异步,进入消息队列)
/// </summary>
/// <param name="hWnd">需要发送消息到的控件句柄</param>
/// <param name="Msg">消息</param>
/// <param name="wParam">附加的消息指定信息(当发送键盘消息时此值为键盘按键的十六进制虚拟键盘)</param>
/// <param name="lParam">附加的消息指定信息(当发送鼠标消息时此值为点击客户区逻辑坐标值,为x+(y<<16))</param>
/// <returns></returns>
[DllImport("user32", SetLastError = true)]
private static extern bool PostMessage(
int hWnd,
int Msg,
int wParam,
int lParam
);
IntPtr wdn;//获取主窗体句柄
IntPtr pn ;//转换窗体句柄
IntPtr pn2;
IntPtr pn3;
IntPtr pn4;
IntPtr pn5;
Process process = new Process();//在定义一个进程来启动ceb转换器
private void Form3_Load(object sender, EventArgs e)
{
process.StartInfo = new ProcessStartInfo(@"C:\Program Files\Founder\Apabi Maker 5.0\Bin\ApaMaker.exe");
process.Start();
Thread.Sleep(3000);//停顿3秒钟,等待加载完成到主窗体
int hDesktop = FindWindow("Progman", null);//获取系统句柄
hDesktop = GetWindow(hDesktop, GW_CHILD);//获取其子窗口句柄,就是桌面的句柄
//SetParent((int)this.Handle, hDesktop);//设置父窗体,第一个为要被设置的窗口,第二个参数为指定其父窗口句柄
//SendMessage((IntPtr)329266, WM_SETTEXT, (IntPtr)0, @"12345678955");
wdn = (IntPtr)FindWindow(null, "Apabi Maker");//找到主窗体
pn = FindWindowEx(wdn, IntPtr.Zero, "wxWindowClassNR", null); //找到第一个panel。转换
pn2 = FindWindowEx(wdn, pn, "wxWindowClassNR", null); //找到第二个panel。批量转换
pn3 = FindWindowEx(wdn, pn2, "wxWindowClassNR", null); //找到合并
pn4 = FindWindowEx(wdn, pn3, "wxWindowClassNR", null); //找到拆分
pn5 = FindWindowEx(wdn, pn4, "wxWindowClassNR", null); //找到结果
}
private void button1_Click(object sender, EventArgs e)
{
//给批量转换文本框赋值
IntPtr txt = FindWindowEx(pn2, IntPtr.Zero, "Edit", null);
IntPtr txt2 = FindWindowEx(pn2, txt, "Edit", null);
SendMessage(txt, WM_SETTEXT, (IntPtr)0, @"C:\Users\Administrator\Desktop\新建文件夹 (3)");
SendMessage(txt2, WM_SETTEXT, (IntPtr)0, @"C:\Users\Administrator\Desktop\新建文件夹 (4)");
//在批量转换查找相应按钮
IntPtr btn = FindWindowEx(pn2, IntPtr.Zero, "Static", null);
IntPtr btn2 = FindWindowEx(pn2, btn, "Static", null);
IntPtr btn3 = FindWindowEx(pn2, btn2, "Static", null);
IntPtr btn4 = FindWindowEx(pn2, btn3, "Static", null);//添加到列表
IntPtr btn5 = FindWindowEx(pn2, btn4, "Static", null);//删除
IntPtr btn6 = FindWindowEx(pn2, btn5, "Static", null);//清空
IntPtr btn7 = FindWindowEx(pn2, btn6, "Static", null);//开始转换
Thread.Sleep(500);
SendBtn((int)btn4);//添加到列表
Thread.Sleep(1000);
SendBtn((int)btn7);//开始转换
ti = new System.Windows.Forms.Timer();
ti.Interval = 300;
ti.Enabled = true;
ti.Tick += new EventHandler(ti_Tick);
Thread.Sleep(1000);
SendBtn((int)btn6);//清空
}
void ti_Tick(object sender, EventArgs e)
{
IntPtr lb = FindWindowEx(pn5, IntPtr.Zero, "Static", null);
IntPtr lb2 = FindWindowEx(pn5, lb, "Static", null);
const int buffer_size = 1024;
StringBuilder buffer = new StringBuilder(buffer_size);
SendMessage(lb2, WM_GETTEXT, buffer_size, buffer);
//任务列表(3成功,0失败,0跳过,0等待)
string strRet = buffer.ToString().Replace("任务列表(", "").Replace(")", "");//3成功,0失败,0跳过,0等待
string[] arrstr = strRet.Split(',');
string strR = arrstr[arrstr.Length - 1];
if (strR == "0等待")
{
ti.Dispose();
MessageBox.Show("转换已完成");
}
}
public void SendBtn(int wn)
{
const int WM_LBUTTONDOWN = 0x201;
int WM_LBUTTONUP = 0x202;
PostMessage(wn, WM_LBUTTONDOWN, 0, 20);
Thread.Sleep(200);
PostMessage(wn, WM_LBUTTONUP, 0, 20);
}
大致的代码如上。
不过在做的过程遇到了一些问题,在发送消息的时候,赋值给文本,是没有问题的,但是要触发按钮事件,貌似不行,即
- SendMessage(btn, WM_CLICK, 0, 0);
是没有效果的,然后就郁闷了很久,上午找资料,无果,只能用
来模拟鼠标点击事件,值得注意的是最后的那个参数,我在这里给的参数的20,为什么呢,因为在我给0的时候,无法触发事件,即:
- PostMessage(wn, WM_LBUTTONDOWN, 0, 0);
我又郁闷了,就用Microsoft Spy++
来看看发送的消息是怎么样的,然后发现有个坐标,如果按钮的句柄的point(0,0)的话点击是没有效果的,就好像你在桌面的坐标(0,0)点击的效果是一样
所以最后的参数我给了20,因为,按钮的大小应该也是有20的。
好了今天就说到这里吧