じ☆ve冰风 发表于 2024-4-20 02:11:44

win32 RGSSBitmap的“属性应用”

参考资料:RPG Maker的Bitmap类的结构
               还有一个英文网站,我找不到了……

RUBY 代码
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*')

defself.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

defself.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

defself.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 = .pack('L4')

GdipCreateBitmapFromGdiDib =
    Win32API.new('gdiplus', 'GdipCreateBitmapFromGdiDib', 'LLP', 'I')
GdipDisposeImage = Win32API.new('gdiplus', 'GdipDisposeImage', 'L', 'I')
GdipSaveImageToFile =
    Win32API.new('gdiplus', 'GdipSaveImageToFile', 'LPPP', 'I')

fixed = .pack('SSC8')
ClsidEncoder = {
    :bmp => .pack('L').pack('L').pack('L')
页: [1]
查看完整版本: win32 RGSSBitmap的“属性应用”