设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
楼主: 一箭烂YiJL
打印 上一主题 下一主题

[RMVX发布] 解决脚本改分辨率潜在问题(欢迎进入讨论)

[复制链接]

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
11
发表于 2011-4-11 03:41:55 | 只看该作者
精准获取窗口句柄 其中API牵涉到前台(焦点)窗口,
当没把窗口显示出来的时候,会否一直停在获取窗口句柄中呢? (希望你能帮我求证下.)

当 Ruby 脚本开始被 RM 嵌入的解释器执行时,窗口已经显示了,除非之后又刻意让它隐藏。GetWindow 应该能获取到隐藏的窗口,毕竟隐藏窗口并不会改变其 Z 次序,而且连被销毁的窗口的句柄都能引用到,又何况只是被隐藏的。

不过没有测试过,不敢下定论。

“精确获取窗口句柄”这个脚本有以下问题,虽然出现概率极低:
1、GetWindow 可能导致无限循环,或是获取到已经被销毁的窗口句柄(这个在 MSDN 的文档里有说明);
2、由于是从前台窗口开始查找,如果前台窗口的类型不同,就可能找不到 RM 的窗口(比如前台窗口是“总在最上”的窗口,但 RM 窗口不是);
3、只进行了线程标识的匹配,然后一个线程可以创建多个窗口。如果 RM 主线程被用来创建别的(辅助)窗口,很可能就匹配不到预期的主窗口了;
4、只进行了窗口类名的匹配,而多个窗口可以是同一类(即属于一种窗口实例,有相同的窗口类名,比如 "RGSS Player")。

相比之下更好的办法 MSDN 也提到了,就是使用 EnumWindows,但 EnumWindows 只能解决上述第一个问题。同时由于 EnumWindows 需要回调函数,而 RM 默认无法编写本地代码,所以纯 Ruby 只能用 GetWindow。真·后台运行用的就是 EnumWindows,因为是 DLL 管理的。

现在看来,这个脚本离精确还差得远。真正意义上的精确这两种方法做到了:
http://rpg.blue/forum.php?mod=viewthread&tid=157287
http://rpg.blue/forum.php?mod=viewthread&tid=160672
前者是劫持 CreateWindow,后者是逆向工程。



还是等真正的XP游戏窗口启动控制移植VX吧。。。

本来我都移植了一半了,但后来因为全屏那块和 XP 不太一样就放弃了,以后也不打算继续弄,反正最重要的分辨率功能 David、神思、八云等人都发过逆向的方法了嘛。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1249
在线时间
669 小时
注册时间
2009-11-11
帖子
2787
12
发表于 2011-4-11 11:38:15 | 只看该作者
"出来的效果窗口内很模糊,也就是"分辨率大了,但是窗体没大"。" 没有这个问题啊,具体可一参考下我最近发的新游戏(还没发),就用了这个,除了慢一点,其他方面没什么挑剔的。。

"本来我都移植了一半了,但后来因为全屏那块和 XP 不太一样就放弃了,以后也不打算继续弄"  呜呜。。不是吧。

点评

你试我那个脚本,很明显的模糊。我都说了有人做过了,例:http://bbs.66rpg.com/forum.php?mod=viewthread&tid=163964&fromuid=115768  发表于 2011-4-11 18:23

嘿。嘿。嘿
回复 支持 反对

使用道具 举报

Lv3.寻梦者

弓箭手?剑兰

梦石
0
星屑
4854
在线时间
833 小时
注册时间
2010-11-17
帖子
1140
13
 楼主| 发表于 2011-4-11 17:25:38 | 只看该作者
回复 苏小脉 的帖子
GetWindow 应该能获取到隐藏的窗口

窗口还没显示出来针对八云这个删掉ShowWindow的exe(<--帖子)
我测试了下,还可以获取窗口句柄,那么GetWindow还可以用。

“精确获取窗口句柄”

貌似紫苏回应这个可能是因为我说:
"虽然纯Ruby的获取窗口句柄是可以,但是开了等很久才执行ShowWindow"
"Ruby窗口句柄可以"意思是不用HWND.dll(详见上面链接)来获取句柄,
也就是还没有ShowWindow的时候还可以使用“精确获取窗口句柄”。

还真想不到“精确获取窗口句柄”有缺陷。

想问一个关于Ruby语法的,主楼所以提供解决分辨率问题的第三个方法:
  1. $window_width  = 640      # 设置的长度
  2. $window_height = 480      # 设置的高度

  3. hWnd = get_hWnd
  4. IsIconic = Win32API.new("user32", "IsIconic", "l", "l")
  5. while IsIconic.call(hWnd) != 0
  6. end
  7. Graphics.resize_screen($window_width, $window_height)
复制代码
while是RGSS开始且窗口最小化时停下,这写法似乎不太好,有更好的写法么?

还是等真正的XP游戏窗口启动控制移植VX吧。。。

这句不是我说的= =是summer92- -
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1249
在线时间
669 小时
注册时间
2009-11-11
帖子
2787
14
发表于 2011-4-11 18:29:36 | 只看该作者
回复 一箭烂YiJL 的帖子

- -没有模糊啊,你指的模糊是画面拉伸?,分辨率是实打实的横向640像素,纵向480像素。。。。不模糊

点评

10楼我写那个是1024x768哦~  发表于 2011-4-11 19:37

嘿。嘿。嘿
回复 支持 反对

使用道具 举报

Lv3.寻梦者

弓箭手?剑兰

梦石
0
星屑
4854
在线时间
833 小时
注册时间
2010-11-17
帖子
1140
15
 楼主| 发表于 2011-4-11 20:14:54 | 只看该作者
回复 summer92 的帖子

明白了,你指的是XP,我说的是VX。VX的窗口较为诡异,(重申10楼)不用Graphics.resize_screen而用SetWindowPos和MoveWindow,分辨率无增,但窗口大小增加的问题,导致窗口模糊。


先把SetWindowPos和MoveWindow简写为:SetWnd和MoveWnd。但是如果resize_screen失效(主楼说的问题),再用SetWnd和MoveWnd放大窗口至640x480都可以,分辨率正常。

但SetWnd和MoveWnd潜在问题和resize_screen一样(主楼说的问题),
那么比较Graphics.resize_screen和(SetWnd和MoveWnd):
  • Graphics.resize_screen包含了SetWnd和MoveWnd的特性,
  • 但是同时具有改变画面分辨率的方法。

那么改变画面分辨率的方法又是什么呢?具体要问有dll逆向工程的几位了。
回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
369
在线时间
1605 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

16
发表于 2011-4-11 20:19:30 | 只看该作者
我表示用的APIhook+exe,首先窗口本身就是1024*768的,再禁用movewindow(好像是这个吧……)防止VX改窗口大小……

点评

本身是1024*768就没有主楼的问题了= =禁了MoveWindow,没有禁SetWindowPos会怎样呢?- -  发表于 2011-4-11 20:33
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
17
发表于 2011-4-12 02:43:00 | 只看该作者
回复 一箭烂YiJL 的帖子
while是RGSS开始且窗口最小化时停下,这写法似乎不太好,有更好的写法么?

处理 WM_SYSCOMMAND 消息,当 wParam 是 SC_MINIMIZE 的时候就是一个最小化事件发生之后。不过……在没有扩展的情况下纯 Ruby 并不能良好地消息处理。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1249
在线时间
669 小时
注册时间
2009-11-11
帖子
2787
18
发表于 2011-4-12 11:12:53 | 只看该作者
回复 一箭烂YiJL 的帖子

哦,明白了 你是指不用Rgss的Graphics.resize_screen 方法进行画面重设,是啊,这样的话API更改分辨率后,真实的分辨率是不会变的(应该是Rgss又把分辨率改回来了?),所以画面被拉伸了,不用Graphics.resize_screen的话怎么真分辨率似乎还要解决一下

点评

不是RGSS改回来,应该是VX实质的分辨率并不代理在窗口大小中。(15楼做了分析)  发表于 2011-4-12 18:03

嘿。嘿。嘿
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
19
发表于 2011-4-12 14:43:24 | 只看该作者
回复 summer92 的帖子
应该是Rgss又把分辨率改回来了?

是 VX 在渲染的时候按照窗口的实际矩形尺寸在渲染(通过 GetWindowRect 之类的),这一点和 XP 固定在一个预设的矩形中渲染不同。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

弓箭手?剑兰

梦石
0
星屑
4854
在线时间
833 小时
注册时间
2010-11-17
帖子
1140
20
 楼主| 发表于 2011-4-12 18:15:57 | 只看该作者
回复 苏小脉 的帖子

那么也就是一定要修改WindowProc函数了。听您说Graphics.update会导致GetMessage无法获得,那么纯Ruby就不可能了。(PeekMessage貌似不是好的办法。)

实际上我想问的是while的语法,我用while的目的是让RGSS暂停,当RM窗口为前台窗口的时候,才继续(才Graphics.resize_screen)。Ruby有一个能够暂停的方法么?一直循环在这个空的循环中似乎不是太好。
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-3 13:46

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表