查看: 2801|回复: 1

[原创发布] 【教程向】对窗口的微调

[复制链接]
梦石
0
星屑
900
在线时间
76 小时
注册时间
2017-7-10
回帖
20
发表于 2017-7-10 12:55:43 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 antilmid 于 2017-7-10 23:10 编辑

【所需要的知识】
  • 了解/熟悉win API。
  • 有ruby入门级知识。

第一部分:从句柄开始     在Windows系统中,我们对窗口操作的基础就是要知道某个窗口的句柄。有人会问,什么是句柄?打个不恰当的比方:窗口的身份证号码... ...也是唯一识别窗口的。当我们知道了句柄,就知道了窗口的“家庭地址”,就可以去他家,找他做“羞羞的事情”。
     关于如何获取句柄,Windows API 的user库提供了许多函数,期中FindWindow最常见。
     FindWindow这个函数检索处理顶级窗口的类名和窗口名称匹配指定的字符串。这个函数不搜索子窗口。
     HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);
  • 参数一:窗口类名
  • 参数二:窗口名
  • 返回值:句柄

     好,我们尝试在rmxp中调用。打开编辑器,找到脚本编辑,然后在main函数前方插入新页面。如图所示:
      1.png

     接着,你需要用到ruby语言自身自带的一个函数:Win32API.new 来对winAPI进行调用。
   
  1. FindWindow = Win32API.new('user32', 'FindWindow', 'pp', 'i')
复制代码

     = =没用过ruby语言的人,看到这个调用可能会有点懵逼,‘pp’是什么鬼?‘i’是什么鬼?!!
     好,我详解一些Win32API这个类:
     Win32API.new(dllname, proc, import, export)加载名为dllname的DLL,生成API函数proc的对象。在import中指定proc的参数类型列表,在export中指定proc返回值的类型。
  •      参数一:dll文件路径(名称)
  •      参数二:接口地址(名称)
  •      参数三:接口函数参数类型
  •      参数四:返回类型
     使用下列字符串或数组来指定类型。
     "p" 指针
     "n", "l" long
     "i" int
     "v" void
     若import为nil,则看成是没有参数。若export为nil,则看做是没有返回值(void)。


     有人看到这里,开始安奈不住了,凭什么窗口类名,窗口名是指针传参,而不是字符串??黑人问号??凭什么指定类型中没有字符串这个选项??
     有C语言基础的人,很快就反应过来了,字符串是由字符组成的数组,字符char型本身就是-128~+127的整数,对于数组传参,我们只需要传递指针就行。

     好,我们来试用一下,能否得到我们想要的句柄:   
  1. FindWindow = Win32API.new('user32', 'FindWindow', 'pp', 'i')
  2. print FindWindow.call("RGSS Player","Mygame")
复制代码

      2.png
     可以看见,我们是成功的!但是呢,有个缺陷,如果你的窗口名带有中文,这个就只会显示0
     这是为啥呢?是这样的,ruby代码编辑是用Unicode的编码方式,而我们的窗口标题是Ascii方式,这就要涉及到编码转换,我们先不要急着去转换,因为转换我们会用到winAPI里的WideCharToMultiByte函数,该函数传参过于复杂(说白了,就是我还没弄懂,毕竟我都不知道ruby指针怎么做。。。。哈哈哈,如果你们有大佬会,请楼下教我。)那我们尝试用其他方式,比如尽量避免中文使用。。。那是不太可能,还有一种方式,我们的RPG maker player有个配置文件,窗口标题的改变跟这个配置文件有关,我们可以尝试读取他,得到我们想要的内容。
      3.png 4.png



     好,说做就做,那么问题来了,怎么读取?我给大家提供两种方法:
          第一种:直接读取文件流(操作难度:3星)
          第二种:通过winAPI自带的ini读取函数进行读取(操作难度:1星)


     我觉得你们会选第二种,而我选第一种,想给你多一点知识学习。话虽至此,先把第二种方案的代码贴出了,自行百度:
   
  1. ini路径=".\\Game.ini"   
  2. val = "\0"*256
  3. GetPrivateProfileString = Win32API.new('kernel32', 'GetPrivateProfileString','pppplp', 'l')
  4. GetPrivateProfileString.call("Game", "Title", "", val, 256, ini路径)
  5. val.delete!("\0")
  6. title = val
复制代码


     

第二部分:是文件就给我读!   话接前文,我们要通过读取文件流来获得信息。读取文件流有很多方法,我们现用直接一点的,读取文本行。读取文本行,顾名思义,就是遇到换行代表结束。下面,请开始我的表演!
     关于文件的操作,Ruby库自带一个File类,避免我们苦逼的调用api。在开始之前,我们先来看看File库中的内容。
     = =想了一下,我觉得还是给你们网址看吧,就是了解下File类库,毕竟,它是相当有用的!>>File类(htt(防和谐)p://ww(防和谐)w.runoob.c(防和谐)om/ruby/ruby-file-metho(防和谐)ds.h(防和谐)tml)<<     在上次代码的基础上,写上这几句:
   
  1. File.open("Game.ini","r") do |file|
  2.     while line  = file.gets
  3.       #nothing
  4.     end
  5. end
复制代码
    如果我们将#nothing换成p line,再次运行就会发生这样的事情:     
      1.gif
     现在我们用一个新变量,将读出的文本合并在一起:
  1. str=""
  2. File.open("Game.ini","r") do |file|
  3.     while line  = file.gets
  4.       str+=line
  5.     end
  6.   end
  7. p str
复制代码

5.png





评分

参与人数 1星屑 +32 收起 理由
百里_飞柳 + 32 塞糖

查看全部评分

梦石
0
星屑
900
在线时间
76 小时
注册时间
2017-7-10
回帖
20
 楼主| 发表于 2017-7-10 15:39:29 | 显示全部楼层
= =我的怎么发出去了?我记得我保存在草稿箱的,尴尬了,我没写完!!!想一点点写的。。。。

评分

参与人数 1星屑 +45 收起 理由
imsy + 45 感兴趣的内容,加油

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部