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

Project1

 找回密码
 注册会员
搜索
查看: 1901|回复: 23
打印 上一主题 下一主题

[已经过期] 如何让这个截图脚本在全屏模式下可以截图

[复制链接]

Lv3.寻梦者

梦石
0
星屑
2927
在线时间
435 小时
注册时间
2014-11-21
帖子
145
跳转到指定楼层
1
发表于 2017-9-20 17:55:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
我用了站内的不会因为窗口被遮挡导致截图不全的脚本,但是发现在全屏模式下无法正常截图,
请问该如何更改使它在全屏模式下也能截图?
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2. # ● RMXP用 Graphics.snap_to_bitmap
  3. #
  4. #    就算窗口被遮盖或者显示不全也可以正常截图
  5. #
  6. #    附赠: Graphics.snap_to_clipboard
  7. #
  8. #          截图到剪贴板
  9. #
  10. #
  11. # ● 作者:晴兰 [url=home.php?mod=space&uid=67509]@[/url] rpg.blue
  12. #   
  13. #    使用到紫苏前辈的获取窗口句柄脚本,其他部分为原创
  14. #   
  15. # ● 备注:如果你因为任何原因改变了窗口大小(或者常说的分辨率)
  16. #
  17. #    搜索并且修改"# 如果屏幕宽度改变请折腾下面这两处"附近
  18. #--------------------------------------------------------------------------
  19.  
  20.  
  21.  
  22. #--------------------------------------------------------------------------
  23. # ● 紫苏前辈的获取窗口句柄
  24. #    部分细节已修改
  25. #--------------------------------------------------------------------------
  26. module Kernel
  27.   #--------------------------------------------------------------------------
  28.   # ● 需要的 Windows API 函数
  29.   #--------------------------------------------------------------------------
  30.   GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L")
  31.   GetWindow = Win32API.new("user32", "GetWindow", "LL", "L")
  32.   GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L")
  33.   GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L")
  34.   GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L")
  35.   #--------------------------------------------------------------------------
  36.   # ● 获取窗口句柄
  37.   #--------------------------------------------------------------------------
  38.   def hwnd
  39.     # 获取调用线程(RM 的主线程)的进程标识
  40.     threadID = GetCurrentThreadId.call
  41.     # 获取 Z 次序中最靠前的窗口
  42.     hWnd = GetWindow.call(GetForegroundWindow.call, 0)
  43.     # 枚举所有窗口
  44.     while hWnd != 0
  45.       # 如果创建该窗口的线程标识匹配本线程标识
  46.       if threadID == GetWindowThreadProcessId.call(hWnd, 0)
  47.         # 分配一个 11 个字节的缓冲区
  48.         className = " " * 12                         # ●
  49.         # 获取该窗口的类名
  50.         GetClassName.call(hWnd, className, 12)       # ●
  51.         # 如果匹配 RGSS Player 则跳出循环
  52.         break if className[0, 11] == "RGSS Player"
  53.       end
  54.       # 获取下一个窗口
  55.       hWnd = GetWindow.call(hWnd, 2)
  56.     end
  57.     return hWnd
  58.   end
  59. end
  60.  
  61. module SAFX
  62.   module_function
  63.   class ::Integer; def pack; self; end; def to_param; 'i'; end; def ord; self; end; end
  64.   class ::String;def pack; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end
  65.  
  66.  
  67.   def api(dll,func)
  68.     lambda{|*args|
  69.        Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args
  70.     }
  71.   end
  72.  
  73.  
  74.   def callproc(addr, type = :cdecl)
  75.     stdcall = type == :stdcall
  76.     raise "addr == 0 " if addr.pack == 0
  77.     apicall = api('user32', 'CallWindowProcW')
  78.     lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.pack].pack('CL')}.reverse.join+[0xb8, addr.pack, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)}
  79.   end
  80.  
  81.   LL  = api("kernel32", "LoadLibrary")
  82.   GPA = api("kernel32", "GetProcAddress")
  83.   def funcaddr(dll, func)
  84.      x = GPA.call(LL.call(dll), func)
  85.      x == 0 ? nil : x
  86.   end
  87.  
  88.   def readmem(start, len)
  89.     api('kernel32', 'RtlMoveMemory').call buf = "\0"*len, start, len
  90.     buf
  91.   end
  92.  
  93.   def writemem(start, len, value)
  94.     api('kernel32', 'RtlMoveMemory').call start, value, [len, value.length].min
  95.   end
  96. end
  97.  
  98. class << Graphics
  99.   # 如果屏幕宽度改变请折腾下面这两处
  100.   def width
  101.     640
  102.   end
  103.   def height
  104.     480
  105.   end
  106.  
  107.   def do_screen_stuff
  108.     hwnd = self.hwnd
  109.     src = SAFX.api('user32', 'GetDC').call(hwnd)
  110.     memdc = SAFX.api('gdi32', 'CreateCompatibleDC').call(src)
  111.     hb = SAFX.api('gdi32', 'CreateCompatibleBitmap').call(src, width, height)
  112.     ho = SAFX.api('gdi32', 'SelectObject').call(memdc, hb)
  113.     bp = SAFX.funcaddr("user32", "GetDC")
  114.     ov = "\0"*4
  115.     str = [0xb8, memdc, 0xc2, 0x04, 0x00].pack("CLC*") # magic, touch
  116.     SAFX.api('Kernel32', 'VirtualProtect').call(bp, str.length, 0x40, ov)
  117.     oldstr = SAFX.readmem(bp, str.length)
  118.     SAFX.writemem bp, str.length, str
  119.     SAFX.api('user32', 'UpdateWindow').call(hwnd)
  120.     Graphics.update
  121.     SAFX.writemem bp, str.length, oldstr
  122.     yield hb
  123.   ensure
  124.     SAFX.api('user32', 'ReleaseDC').call(hwnd, src)
  125.     hb = SAFX.api('gdi32', 'SelectObject').call(memdc, ho)
  126.     SAFX.api('gdi32', 'DeleteObject').call(ho)
  127.     SAFX.api('gdi32', 'DeleteDC').call(memdc)
  128.   end
  129.  
  130.   def snap_to_bitmap
  131.     bm = Bitmap.new(width, height)
  132.     addr  = bm.object_id * 2
  133.     addr, = SAFX.readmem(addr + 16, 4).unpack("L")
  134.     addr, = SAFX.readmem(addr +  8, 4).unpack("L")
  135.     addr, = SAFX.readmem(addr + 16, 4).unpack("L")
  136.     do_screen_stuff do |hb|
  137.       bits = "\0"*(width * height * 4)
  138.       SAFX.api('gdi32', 'GetBitmapBits').call(hb, bits.length, bits)
  139.       r = SAFX.api('kernel32', 'RtlMoveMemory')
  140.       a = bits.pack
  141.       stride = width * 4
  142.       h = height
  143.      (h-1).downto(0){|i|
  144.         r.call addr + i * stride, a + (h - i - 1)*stride, stride
  145.       }
  146.       bm
  147.     end
  148.   end
  149.  
  150.   def snap_to_clipboard
  151.     return false if SAFX.api('user32', 'OpenClipboard').call(hwnd) == 0
  152.     do_screen_stuff do |hb|
  153.       SAFX.api('user32', 'SetClipboardData').call(2, hb)
  154.       SAFX.api('user32', 'CloseClipboard').call
  155.       true
  156.     end
  157.  
  158.   end
  159. end

Lv3.寻梦者 (暗夜天使)

精灵族の天使

梦石
0
星屑
1697
在线时间
3038 小时
注册时间
2007-3-16
帖子
33731

开拓者贵宾

2
发表于 2017-9-21 13:15:05 | 只看该作者
#    备注:如果你因为任何原因改变了窗口大小(或者常说的分辨率)
#
#    搜索并且修改"# 如果屏幕宽度改变请折腾下面这两处"附近
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
2927
在线时间
435 小时
注册时间
2014-11-21
帖子
145
3
 楼主| 发表于 2017-9-21 19:08:36 | 只看该作者
精灵使者 发表于 2017-9-21 13:15
#    备注:如果你因为任何原因改变了窗口大小(或者常说的分辨率)
#
#    搜索并且修改"# 如果屏幕宽度 ...

唔,我说的是游戏自带的alt+enter,这个也需要改吗?
如果改的话该怎么判定现在是否处于全屏啊……

点评

XP吗。 回头我试试看  发表于 2017-10-7 18:26
是XP  发表于 2017-10-7 11:57
对了,你的操作系统是?  发表于 2017-10-6 17:27
你把那段脚本随便拉进一个工程然后p一下应该行吧……  发表于 2017-10-6 15:15
如果有范例工程的话我试试测试一下……  发表于 2017-10-3 18:24
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-9-21 18:52

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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