闲着没事干就做了这么个东西.

第一次在C#里用了这么多跨进程的窗体操作.

还是学到不少东西.

らぶデス3的手动去码流程如下:

先去网上找到ODFConvertor.

然后进入游戏目录的ODF下,将所有的*_base_HI.odf找出来,

用ODFConvertor打开它,将*_moz的勾选去掉后再导出得到一

个!*_base_HI.odf然后用这个新文件替换掉旧文件即可.

ODFConvertor有个地方很讨厌:他只能用文件拖拽的方式打开odf

文件.于是我事先设想的模拟几个按钮单击就搞定的方法是没戏了.

于是我开始去MSDN啃那提到就让我头痛的OLE...结果看了一晚没啥结果.

到处都找不到得到对方窗体的IDropTarget的方法.倒是在Shell编程的资料

里查到一条WM_DROPFILES的消息...可是看到那个HDROP是个形似句柄

的东东,马上就放弃去睡觉了.

第二天上网问了下清洁工...结果他帮我在csdn google出了一篇用WM_DROPFILES

模拟文件拖拽的文章(囧...为啥我google半天没找到?)原来那个所谓的HDROP其实

就是指向一个DROPFILES结构的指针...囧.要是早知道就好了.

接下来就是选语言了.csdn那篇文章是用c++写的.按说这种涉及大量api调用的东西

还是C++比较顺手,但是一想到C++那繁琐的UI编写我马上就放弃了.最后还是选择了

最常用的C#.

接下来就是考虑在C#中实现跨进程的操做了.

思路如下:

Shell文件的拖拽处理事实上是在窗体过程中处理了WM_DROPFILES消息.

接受到的参数HDROP是一个指向DROPFILES的指针.DROPFILES的C++声明如下:

typedef struct _DROPFILES { DWORD pFiles; POINT pt; BOOL fNC; BOOL fWide; } DROPFILES, *LPDROPFILES;

我在C#里声明的时候把它改了一下:

struct DROPFILES { public int pFiles; public int x; public int y; public int fNC; public int fWide; };

这样我可以少声明一个不用的POINT结构,只要保证大小不变就好:)

然后就是这个指针的问题了.我自己的进程里分配的DROPFILES拿给目标进程是肯定没用的.

自然要涉及到跨进程的内存读/写;于是需要以下API:

[DllImport ("kernel32.dll")] public static extern bool CloseHandle (IntPtr hobject); [DllImport ("kernel32.dll")] public static extern IntPtr VirtualAllocEx( IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect ); [DllImport("kernel32.dll")] public static extern bool VirtualFreeEx( IntPtr hProcess, IntPtr lpAddress, int dwSize, uint dwFreeType ); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, out int lpNumberOfBytesWritten ); [DllImport("kernel32.dll")] public static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, out int lpNumberOfBytesRead );

拖动的执行流程为:

先在自己的进程里初始化一个DROPFILES结构d,然后在目标进程中分配一块同样大的空间p.

将d写过去.接着将p作为WM_DROPFILES的HDROP发送过去.

public static bool DropFile (IntPtr hWnd,string filePath) { bool ret =false; int pid; GetWindowThreadProcessId (hWnd,out pid); IntPtr hproc; //打开进程 hproc = OpenProcess (PROCESS_VM_OPERATION|PROCESS_VM_WRITE,false,pid); if (hproc == IntPtr.Zero) return false; char[] strbuf = filePath.ToCharArray (); int cbstrSize = filePath.Length*2+2;//*2因每个字符占用两字节,+2为最后的/0所占的2字节 int sizedropfiles = Marshal.SizeOf(typeof(DROPFILES)); //字符串缓存 int bufSize = sizedropfiles + cbstrSize; //申请缓存 IntPtr pdbuf = Marshal.AllocCoTaskMem (bufSize); DROPFILES* dropfiles = (DROPFILES*)pdbuf; //计算字符串的地址 IntPtr pstrbuf = new IntPtr(pdbuf.ToInt32() + sizedropfiles); //清零初始化 ZeroMemory ((IntPtr)dropfiles,bufSize); //构造本地的DROPFILES dropfiles->pFiles = sizedropfiles; dropfiles->x = 0; dropfiles->y = 0; dropfiles->fNC = 0; dropfiles->fWide = 1;//使用Unicode字符 //复制填充字符串 Marshal.Copy (strbuf,0,pstrbuf,strbuf.Length); //申请远程内存 IntPtr ptrRemote = VirtualAllocEx (hproc,IntPtr.Zero,bufSize,MEM_COMMIT,PAGE_READWRITE); if (ptrRemote==IntPtr.Zero) goto clear; int writecount; //写入目标进程 if (WriteProcessMemory (hproc,ptrRemote,(IntPtr)dropfiles,bufSize,out writecount)) { /*MessageBox.Show(string.Format( "缓存写入对方内存:{0:X}/n应写入{1}字节,成功写入{2}字节", ptrRemote.ToInt32() , bufSize, writecount));*/ //发送消息 SendMessage (hWnd,WM_DROPFILES,ptrRemote.ToInt32(),0); ret = true; } clear://收尾工作 Marshal.FreeCoTaskMem((IntPtr)(dropfiles));//释放Com里分配的缓存 if (ptrRemote!=IntPtr.Zero) { //释放远程内存 if (!VirtualFreeEx(hproc, ptrRemote,0, MEM_RELEASE)) { throw new Win32Exception(); } } //关闭句柄 CloseHandle (hproc); return ret; }

这样只要对着ODFConvertor的hwnd运行这条函数就能实现把文件拖上去的效果了:)

接下来是对ODFConvertor的控制了.ODFConvertor使用一个SystemListView32来显示内容:

在查了Win32SDK的ListView控件的文档后对搞到Name列文本的方法第一反应是C++里的用Dll注入进程后操作.

最好是用C++/CLI的Dll这样可以结合.net便利的Remote功能.但想到为这么个东西还特地用C++写个dll啥的太TM

蛋疼后决定寻找完全用C#的方法.

先是解决取消勾选的问题:

根据commctrl.h里的ListView_SetCheckState宏我先写出了这样一条函数:

static void ListView_SetItemState(IntPtr hwndLV, int i, uint state, uint mask) { LVITEM _macro_lvi = new LVITEM(); _macro_lvi.stateMask = mask; _macro_lvi.state = state; SendMessage(hwndLV, LVM_SETITEMSTATE, i,ref _macro_lvi); } public static void ListView_SetCheckState(IntPtr hwndLV, int i, bool fCheck) { ListView_SetItemState(hwndLV, i, INDEXTOSTATEIMAGEMASK((fCheck) ? 2 : 1), LVIS_STATEIMAGEMASK); }

结果测试执行后ODFConvertor直接崩掉了囧...刚开始的十几分钟一直百思不得其解.

后面才反应过来:SendMessage直接传个int之类的没问题.问题是我的_macro_lvi是

一个结构体.ref _macro_lvi在平台调用中传递的是一个指针.而这个指针对于在另一个

进程中的ListView窗体处理函数来说毫无意义.当然导致非法内存访问崩掉拉~明白这点

后修改了下得到了一条可以成功运行的函数:

static void RemoteListView_SetItemState(int pid,IntPtr hwndLV, int i, uint state, uint mask) { LVITEM _macro_lvi = new LVITEM(); _macro_lvi.stateMask = mask; _macro_lvi.state = state; LVITEM* plvi = &_macro_lvi; { int bufsize = Marshal.SizeOf(_macro_lvi); RemoteProcessMemory rpm = new RemoteProcessMemory (pid); IntPtr ptrRemote = rpm.VirtualAlloc(bufsize); rpm.Write(ptrRemote, new IntPtr(plvi), bufsize); SendMessage(hwndLV, LVM_SETITEMSTATE, i, ptrRemote); rpm.VirtualFree(ptrRemote);//释放掉内存 rpm.Close(); } } public static void RemoteListView_SetCheckState(int pid,IntPtr hwndLV, int i, bool fCheck) { RemoteListView_SetItemState(pid,hwndLV, i, INDEXTOSTATEIMAGEMASK((fCheck) ? 2 : 1), LVIS_STATEIMAGEMASK); }

顺便把远程进程内存的管理封装成了一个RemoteProcessMemory类.嗯...看起来比之前那个实现文件拖拽的直接调用API好看多了:P.

有了解决CheckBox问题的教训后做获取Name列的字符就顺利多了:

unsafe string GetChunkName(int index)//读取远程ListView Name列的字符 { string ret = null; const int cbstrbuf = 250; WinAPI.LVITEM lvitem = new WinAPI.LVITEM(); int cblvitem = Marshal.SizeOf(lvitem); WinAPI.RemoteProcessMemory rpm = new WinAPI.RemoteProcessMemory(pid); lvitem.pszText = rpm.VirtualAlloc(cbstrbuf); lvitem.iItem = index; lvitem.cchTextMax = 250; lvitem.iSubItem = 1;//NAME在第二列 lvitem.mask = WinAPI.LVIF_TEXT; var rplvitem = rpm.VirtualAlloc(cblvitem); rpm.Write(rplvitem, new IntPtr(&lvitem), cblvitem); WinAPI.SendMessage(odflistwnd, WinAPI.LVM_GETITEM, 0, rplvitem); byte* localstrbuf = stackalloc byte[cbstrbuf]; rpm.Read(lvitem.pszText, new IntPtr(localstrbuf), cbstrbuf); ret = Marshal.PtrToStringAnsi(new IntPtr(localstrbuf)); //释放掉远程内存 rpm.VirtualFree(lvitem.pszText); rpm.VirtualFree(rplvitem); rpm.Close(); return ret; }

解决了这几个问题后剩下的就简单了.也就是用SendMessage发个BM_CLICK之类的东西.于是乎最后得到了这么个BT东西:

补丁下载

らぶデス海茶3去码补丁.相关推荐

  1. 海茶3 らぶデス3 入门经典教程

    又一次在百忙之中给大家写教程了 真的很忙啊,4个汉化组=1个程序坑+1个润色坑+2个翻译坑..... 所以本文第一句话就是: 这么简单的游戏要什么教程,不算LOADGAME,10分钟上手!有时间去汉化 ...

  2. AI技术已达如此高度:去码、上色6到飞起

    简介:AI技术已达如此高度:去码.上色6到飞起 在图片处理领域这块,AI刷的存在感越来越多.早前笔者就介绍过AI无损放大图片.AI去除马赛克.AI自动给线稿上色之类的玩法,现在,又有人给笔者推荐了一个 ...

  3. 再厚的马赛克都能被扒干净?这款去码神器火了

    来自:扩展迷EXTFANS(ID:infinitydaily) 有人说,马赛克的发明,就是人类文明史上一次重大的"开倒车". 也有人说,马赛克就是阻碍人类进步的绊脚石. 从功能上讲 ...

  4. 再厚的马赛克都能被扒干净?这款「去码」神器火了

    有人说,马赛克的发明,就是人类文明史上一次重大的"开倒车". 也有人说,马赛克就是阻碍人类进步的绊脚石. 从功能上讲,马赛克是一种用来遮盖原画面的手段,有利也有弊. 从技术上讲,马 ...

  5. 迅播Gvod最新版本去广告补丁,不留任何广告

    一.软件说明: 迅播Gvod是迅雷出品的一个P2P播放器,是一款观看的人数越多,速度越快的播放器,凭借迅雷丰富的资源和流量支持,Gvod目前已经获得了广大站长和用户的认可 但是由于官方的一些原因,导致 ...

  6. 海康sdk捕获码流数据通过JavaCV推成rtmp流的实现思路(PS流转封装RTMP)

    海康sdk捕获码流数据通过JavaCV推成rtmp流的实现思路(PS流转封装RTMP) 问题分析 转码推rtmp PS流转封装 码云(Gitee)主页:https://gitee.com/banmaj ...

  7. 要是我早点学会了使用三叉戟(Docker),那我不是就有时间像海王一样去找小姐姐们

    要是我早点学会了使用三叉戟(Docker),那我不是就有时间像海王一样去找小姐姐们 1.Docker简介 首先要知道Docker三大基础组件:仓库(Repository),镜像(Image),容器(C ...

  8. GitHub开源神器!再厚的马赛克都能被扒干净?这款去码神器火了。。。

    点击上方"Github爱好者社区",选择星标 回复"资料",获取小编整理的一份资料 来自:扩展迷EXTFANS(ID:infinitydaily) 有人说,马赛 ...

  9. 迅雷资源优化去广告补丁

    迅雷资源优化去广告补丁1.1 适合迅雷任何版本以及未来版本 迅雷资源优化去广告补丁1.1 适合迅雷任何版本以及未来版本 迅雷通用资源优化去广告补丁1.1版. 请自行解压到迅雷安装文件夹覆盖即可 /Th ...

最新文章

  1. python爬取图片全网通_UC头条:全网通杀——暴强工具推荐: 下载你看到的任意视频...
  2. 北斗导航 | RAIM奇偶矢量法理论分析(公式推导:原理图)
  3. 有几个人会用计算机,怎么知道我家的wifi有几个人在使用
  4. 麦森数(洛谷P1045题题解,Java语言描述)
  5. 【原创】MapReduce实战(一)
  6. 通过Ajax进行POST提交JSON类型的数据到SpringMVC Controller的方法
  7. python(3)-内置函数2
  8. 有趣的问题:C的表达式x == x,何时为假?!
  9. C++ QT中国象棋双人单机对战代码总结
  10. 电脑的脉搏---时钟频率的来龙去脉
  11. 时间差太大导致Windows时间同步无法自动更新时间
  12. JavaScript引用类型之Date类型
  13. 【转】怎样运行 Vue 打包后的项目
  14. 全连接网络和卷积神经网络
  15. 磁盘分区管理工具(DiskGenius Pro 5.3)pjb 附安装教程
  16. 在领悟到什么道理后,你的人生从此轻松了起来?
  17. 华为服务器有海光芯片,刚拿下高通,华为又获得中国电信服务器订单,英特尔急了...
  18. 太极链,从智能容器到智能供应链
  19. 地税计算机发展,金税三期背景下湛江地税信息化发展策略研究
  20. java违反了唯一约束_Caused by: java.sql.BatchUpdateException: ORA-00001: 违反唯一约束条件...

热门文章

  1. ESP32学习microPython之(1)--machine内置函数
  2. Java和JavaEE和JavaSE的介绍和区别
  3. 心理学 教你怎么去看懂人心,100条格言要记牢
  4. [C#]Npoi导出excel整理(附源码)
  5. Collaborative Knowledge Base Embedding for Recommender Systems学习心得
  6. 计算机毕业设计asp.net在线音乐网站(源码+系统+mysql数据库+Lw文档)
  7. MP4文件格式解析之结合实例分析
  8. linux dns子域委派,bind服务器子域委派
  9. java输入流从指定字节读取,JAVA输入输出流-字节流篇
  10. C++ 学习路线及推荐学习时间: