module CWP
CallWndProc = Win32API.new('user32', 'CallWindowProc', 'PLLLL', 'L')
CodeMove = [139,68,36,4,133,192,116,23,209,224,185,2,0,0,0,139,20,140,133,
210,116,9,139,4,16,65,131,249,5,117,240,194,16,0].pack('C*')
def self.move(obj, offsetA=16, offsetB=0, offsetC=0)
CallWndProc.call(CodeMove, obj, offsetA, offsetB, offsetC)
end
end
class Bitmap
def to_int
self.object_id
end
def hBitmap
@_hBitmap ||= CWP.move(self, 16, 8, 44)
end
def pBits
@_pBits ||= CWP.move(self, 16, 8, 16)
end
def pScan0
@_pScan0 ||= CWP.move(self, 16, 8, 12)
end
def pIHr
@_pIHr ||= CWP.move(self, 16, 8, 8) # 或者 CWP.move(self, 16, 8, 32)
end
end
module WIN32API
@@default_w = 640
@@default_h = 480
threadID = Win32API.new('kernel32', 'GetCurrentThreadId', 'V', 'L').call()
hwnd = Win32API.new('user32', 'GetForegroundWindow', 'V', 'L').call()
_GetWndTidPid = Win32API.new('user32','GetWindowThreadProcessId', 'LP', 'L')
_FindWindowEx = Win32API.new('user32', 'FindWindowEx', 'LLPP', 'L')
while _GetWndTidPid.call(hwnd, nil) != threadID
hwnd = _FindWindowEx.call(0, hwnd, "RGSS Player", nil)
end
Hwnd = hwnd
GetDC = Win32API.new('user32', 'GetDC', 'L', 'L')
ReleaseDC = Win32API.new('user32', 'ReleaseDC', 'LL', 'L')
CreateCompatibleDC = Win32API.new('gdi32', 'CreateCompatibleDC', 'L', 'L')
DeleteDC = Win32API.new('gdi32', 'DeleteDC', 'L', 'I')
DeleteObject = Win32API.new('gdi32', 'DeleteObject', 'L', 'I')
SelectObject = Win32API.new('gdi32', 'SelectObject', 'LL', 'L')
BitBlt = Win32API.new('gdi32', 'BitBlt', 'LIIIILIIL', 'I')
StretchBlt = Win32API.new('gdi32', 'StretchBlt', 'LIIIILIIIIL', 'I')
SetStretchBltMode = Win32API.new('gdi32', 'SetStretchBltMode', 'LI', 'I')
SetBrushOrgEx = Win32API.new('gdi32', 'SetBrushOrgEx', 'LIIP', 'I')
SRCCOPY = 0xCC0020
SRCPAINT = 0xEE0086
STRETCH_HALFTONE = 4
def self.snap_to_bitmap(src_x = 0, src_y = 0, src_w = @@default_w,
src_h = @@default_h, dest_w = @@default_w, dest_h = @@default_h)
bitmap = Bitmap.new(dest_w, dest_h)
hDC = GetDC.call(Hwnd)
mCDC = CreateCompatibleDC.call(hDC)
oldBitmap = SelectObject.call(mCDC, bitmap.hBitmap)
if src_w == dest_w && src_h == dest_h
BitBlt.call(mCDC, 0, 0, dest_w, dest_h, hDC, 0, 0, SRCCOPY)
else
SetStretchBltMode.call(mCDC, STRETCH_HALFTONE)
SetBrushOrgEx.call(mCDC, 0, 0, nil)
StretchBlt.call(mCDC, 0, 0, dest_w, dest_h, hDC, src_x, src_y, src_w,
src_h, SRCPAINT)
end
SelectObject.call(mCDC, oldBitmap)
DeleteDC.call(mCDC)
ReleaseDC.call(Hwnd, hDC)
bitmap
end
MultiByteToWideChar =
Win32API.new('kernel32', 'MultiByteToWideChar', 'ILPIPI', 'I')
CP_UTF8 = 65001
def self.utf16(text)
len = MultiByteToWideChar.call(CP_UTF8, 0, text, -1, nil, 0)
buf = "\0" * (len * 2)
MultiByteToWideChar.call(CP_UTF8, 0, text, -1, buf, len)
buf
end
GdiplusStartup = Win32API.new('gdiplus', 'GdiplusStartup', 'PPP', 'I')
GdiplusShutdown = Win32API.new('gdiplus', 'GdiplusShutdown', 'L', 'V')
GdipStartupInput = [1, 0, 0, 0].pack('L4')
GdipCreateBitmapFromGdiDib =
Win32API.new('gdiplus', 'GdipCreateBitmapFromGdiDib', 'LLP', 'I')
GdipDisposeImage = Win32API.new('gdiplus', 'GdipDisposeImage', 'L', 'I')
GdipSaveImageToFile =
Win32API.new('gdiplus', 'GdipSaveImageToFile', 'LPPP', 'I')
fixed = [6660, 4563, 154, 115, 0, 0, 248, 30, 243, 46].pack('SSC8')
ClsidEncoder = {
:bmp => [1434252288].pack('L') << fixed,
:jpg => [1434252289].pack('L') << fixed,
:png => [1434252294].pack('L') << fixed
}
def self.save_bitmap_to_pic(rgss_bitmap, filename, type=:png)
buf = "\0" * 4
GdiplusStartup.call(buf, GdipStartupInput, nil)
token = buf.unpack('L')[0]
GdipCreateBitmapFromGdiDib.call(rgss_bitmap.pIHr, rgss_bitmap.pBits, buf)
pBitmap = buf.unpack('L')[0]
GdipSaveImageToFile.call(pBitmap, self.utf16(filename),
ClsidEncoder[type] || ClsidEncoder[:png], nil)
GdipDisposeImage.call(pBitmap)
GdiplusShutdown.call(token)
end
end
module CWP
CallWndProc = Win32API.new('user32', 'CallWindowProc', 'PLLLL', 'L')
CodeMove = [139,68,36,4,133,192,116,23,209,224,185,2,0,0,0,139,20,140,133,
210,116,9,139,4,16,65,131,249,5,117,240,194,16,0].pack('C*')
def self.move(obj, offsetA=16, offsetB=0, offsetC=0)
CallWndProc.call(CodeMove, obj, offsetA, offsetB, offsetC)
end
end
class Bitmap
def to_int
self.object_id
end
def hBitmap
@_hBitmap ||= CWP.move(self, 16, 8, 44)
end
def pBits
@_pBits ||= CWP.move(self, 16, 8, 16)
end
def pScan0
@_pScan0 ||= CWP.move(self, 16, 8, 12)
end
def pIHr
@_pIHr ||= CWP.move(self, 16, 8, 8) # 或者 CWP.move(self, 16, 8, 32)
end
end
module WIN32API
@@default_w = 640
@@default_h = 480
threadID = Win32API.new('kernel32', 'GetCurrentThreadId', 'V', 'L').call()
hwnd = Win32API.new('user32', 'GetForegroundWindow', 'V', 'L').call()
_GetWndTidPid = Win32API.new('user32','GetWindowThreadProcessId', 'LP', 'L')
_FindWindowEx = Win32API.new('user32', 'FindWindowEx', 'LLPP', 'L')
while _GetWndTidPid.call(hwnd, nil) != threadID
hwnd = _FindWindowEx.call(0, hwnd, "RGSS Player", nil)
end
Hwnd = hwnd
GetDC = Win32API.new('user32', 'GetDC', 'L', 'L')
ReleaseDC = Win32API.new('user32', 'ReleaseDC', 'LL', 'L')
CreateCompatibleDC = Win32API.new('gdi32', 'CreateCompatibleDC', 'L', 'L')
DeleteDC = Win32API.new('gdi32', 'DeleteDC', 'L', 'I')
DeleteObject = Win32API.new('gdi32', 'DeleteObject', 'L', 'I')
SelectObject = Win32API.new('gdi32', 'SelectObject', 'LL', 'L')
BitBlt = Win32API.new('gdi32', 'BitBlt', 'LIIIILIIL', 'I')
StretchBlt = Win32API.new('gdi32', 'StretchBlt', 'LIIIILIIIIL', 'I')
SetStretchBltMode = Win32API.new('gdi32', 'SetStretchBltMode', 'LI', 'I')
SetBrushOrgEx = Win32API.new('gdi32', 'SetBrushOrgEx', 'LIIP', 'I')
SRCCOPY = 0xCC0020
SRCPAINT = 0xEE0086
STRETCH_HALFTONE = 4
def self.snap_to_bitmap(src_x = 0, src_y = 0, src_w = @@default_w,
src_h = @@default_h, dest_w = @@default_w, dest_h = @@default_h)
bitmap = Bitmap.new(dest_w, dest_h)
hDC = GetDC.call(Hwnd)
mCDC = CreateCompatibleDC.call(hDC)
oldBitmap = SelectObject.call(mCDC, bitmap.hBitmap)
if src_w == dest_w && src_h == dest_h
BitBlt.call(mCDC, 0, 0, dest_w, dest_h, hDC, 0, 0, SRCCOPY)
else
SetStretchBltMode.call(mCDC, STRETCH_HALFTONE)
SetBrushOrgEx.call(mCDC, 0, 0, nil)
StretchBlt.call(mCDC, 0, 0, dest_w, dest_h, hDC, src_x, src_y, src_w,
src_h, SRCPAINT)
end
SelectObject.call(mCDC, oldBitmap)
DeleteDC.call(mCDC)
ReleaseDC.call(Hwnd, hDC)
bitmap
end
MultiByteToWideChar =
Win32API.new('kernel32', 'MultiByteToWideChar', 'ILPIPI', 'I')
CP_UTF8 = 65001
def self.utf16(text)
len = MultiByteToWideChar.call(CP_UTF8, 0, text, -1, nil, 0)
buf = "\0" * (len * 2)
MultiByteToWideChar.call(CP_UTF8, 0, text, -1, buf, len)
buf
end
GdiplusStartup = Win32API.new('gdiplus', 'GdiplusStartup', 'PPP', 'I')
GdiplusShutdown = Win32API.new('gdiplus', 'GdiplusShutdown', 'L', 'V')
GdipStartupInput = [1, 0, 0, 0].pack('L4')
GdipCreateBitmapFromGdiDib =
Win32API.new('gdiplus', 'GdipCreateBitmapFromGdiDib', 'LLP', 'I')
GdipDisposeImage = Win32API.new('gdiplus', 'GdipDisposeImage', 'L', 'I')
GdipSaveImageToFile =
Win32API.new('gdiplus', 'GdipSaveImageToFile', 'LPPP', 'I')
fixed = [6660, 4563, 154, 115, 0, 0, 248, 30, 243, 46].pack('SSC8')
ClsidEncoder = {
:bmp => [1434252288].pack('L') << fixed,
:jpg => [1434252289].pack('L') << fixed,
:png => [1434252294].pack('L') << fixed
}
def self.save_bitmap_to_pic(rgss_bitmap, filename, type=:png)
buf = "\0" * 4
GdiplusStartup.call(buf, GdipStartupInput, nil)
token = buf.unpack('L')[0]
GdipCreateBitmapFromGdiDib.call(rgss_bitmap.pIHr, rgss_bitmap.pBits, buf)
pBitmap = buf.unpack('L')[0]
GdipSaveImageToFile.call(pBitmap, self.utf16(filename),
ClsidEncoder[type] || ClsidEncoder[:png], nil)
GdipDisposeImage.call(pBitmap)
GdiplusShutdown.call(token)
end
end