赞 | 13 |
VIP | 320 |
好人卡 | 64 |
积分 | 3 |
经验 | 112963 |
最后登录 | 2022-8-25 |
在线时间 | 2355 小时 |
Lv2.观梦者 (暗夜天使)
- 梦石
- 0
- 星屑
- 266
- 在线时间
- 2355 小时
- 注册时间
- 2009-3-13
- 帖子
- 2309
|
本帖最后由 Sion 于 2014-5-15 11:07 编辑
稍微添加了限制窗口最小大小,以及激活窗口置于最前面的功能module Seiran20 module_function class ::Integer; def to_ptr; self; end; def to_param; 'i'; end; def ord; self; end; end class ::String;def to_ptr; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end def api(dll,func) lambda{|*args| Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args } end def callproc(addr, type = :cdecl) stdcall = type == :stdcall raise "addr == 0 " if addr.to_ptr == 0 apicall = api('user32', 'CallWindowProcW') lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.to_ptr].pack('CL')}.reverse.join+[0xb8, addr.to_ptr, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)} end LL = api("kernel32", "LoadLibrary") GPA = api("kernel32", "GetProcAddress") def funcaddr(dll, func) x = GPA.call(LL.call(dll), func) x == 0 ? nil : x end def capi(dll, func) callproc(GPA.call(LL.call(dll), func)) end def hwnd msg , r, pm, ac = "\0"*24, 0, api('user32', 'PeekMessage'), api('user32', 'GetAncestor') loop do return r if pm.call(msg, 0, 0, 0, 0) != 0 and ((r = ac.call(msg.unpack('L').first, 3))!=0) ::Graphics.update if defined?(::Graphics) end end end module Mouse extend Seiran20 WINDOW = hwnd EVENT = [] GS = api 'user32', 'GetCursorPos' SC = api 'user32', 'ScreenToClient' KEY = api 'user32', 'GetKeyState' def self.x @x end def self.y @y end def self.mousepos GS.call buf = "\0"*8 SC.call WINDOW, buf buf.unpack "ll" end def self.update lastx, lasty = @x, @y @x, @y = mousepos if lastx != @x || lasty != @y EVENT.push :mouse_move end lastkey = (@key|| 0) & 0x8000 @key= KEY.call(1) & 0x8000 if lastkey != @key EVENT.push @key== 0x8000 ? :mouse_down : :mouse_up end end def self.has_event? !EVENT.empty? end end def mouse_event Mouse::EVENT.shift end def get_window_under_mouse $window_list.reverse.find{|w| #找一个包含了鼠标位置的窗体 w.x <= Mouse.x && Mouse.x < w.x + w.width && w.y <= Mouse.y && Mouse.y < w.y + w.height } end $data_system = load_data 'Data/system.rvdata2' def new_window(x, y) w = Window.new x, y, 1, 1 w.windowskin = Cache.system('window') w.tone = $data_system.window_tone w.z = $window_list.size #######add w end def active_window #######add mz = $window_list.size - 1 $window_list.each {|w| w.z -= 1 if w.z >= $window.z } $window.z = mz end def resize_window #######add $window.width = Mouse.x - $window.x $window.width = 30 if $window.width < 30 $window.height = Mouse.y - $window.y $window.height = 22 if $window.height < 22 end def main_logic case [mouse_event, $status] when [:mouse_down, :normal] if $window = get_window_under_mouse # 鼠标下能取到窗体,就当是拖动 $status = :window_selected $cx, $cy = Mouse.x - $window.x, Mouse.y - $window.y active_window #######add else $status = :create_window # 否则就是创建 $window = new_window(Mouse.x, Mouse.y) end when [:mouse_up, :window_selected] $status = :normal when [:mouse_up, :create_window] $window_list.push $window #加入到某个窗口列表 $status = :normal $window = nil when [:mouse_move, :window_selected] $window.x, $window.y = Mouse.x - $cx, Mouse.y - $cy when [:mouse_move, :create_window] resize_window #######add end while Mouse::has_event? end def ui_update main_logic $window_list.each{|x| x.update} $window.update if $window end $status = :normal $window_list = [] loop do Graphics.update Input.update Mouse.update ui_update end
module Seiran20
module_function
class ::Integer; def to_ptr; self; end; def to_param; 'i'; end; def ord; self; end; end
class ::String;def to_ptr; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end
def api(dll,func)
lambda{|*args|
Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args
}
end
def callproc(addr, type = :cdecl)
stdcall = type == :stdcall
raise "addr == 0 " if addr.to_ptr == 0
apicall = api('user32', 'CallWindowProcW')
lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.to_ptr].pack('CL')}.reverse.join+[0xb8, addr.to_ptr, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)}
end
LL = api("kernel32", "LoadLibrary")
GPA = api("kernel32", "GetProcAddress")
def funcaddr(dll, func)
x = GPA.call(LL.call(dll), func)
x == 0 ? nil : x
end
def capi(dll, func)
callproc(GPA.call(LL.call(dll), func))
end
def hwnd
msg , r, pm, ac = "\0"*24, 0, api('user32', 'PeekMessage'), api('user32', 'GetAncestor')
loop do
return r if pm.call(msg, 0, 0, 0, 0) != 0 and ((r = ac.call(msg.unpack('L').first, 3))!=0)
::Graphics.update if defined?(::Graphics)
end
end
end
module Mouse
extend Seiran20
WINDOW = hwnd
EVENT = []
GS = api 'user32', 'GetCursorPos'
SC = api 'user32', 'ScreenToClient'
KEY = api 'user32', 'GetKeyState'
def self.x
@x
end
def self.y
@y
end
def self.mousepos
GS.call buf = "\0"*8
SC.call WINDOW, buf
buf.unpack "ll"
end
def self.update
lastx, lasty = @x, @y
@x, @y = mousepos
if lastx != @x || lasty != @y
EVENT.push :mouse_move
end
lastkey = (@key|| 0) & 0x8000
@key= KEY.call(1) & 0x8000
if lastkey != @key
EVENT.push @key== 0x8000 ? :mouse_down : :mouse_up
end
end
def self.has_event?
!EVENT.empty?
end
end
def mouse_event
Mouse::EVENT.shift
end
def get_window_under_mouse
$window_list.reverse.find{|w| #找一个包含了鼠标位置的窗体
w.x <= Mouse.x && Mouse.x < w.x + w.width &&
w.y <= Mouse.y && Mouse.y < w.y + w.height
}
end
$data_system = load_data 'Data/system.rvdata2'
def new_window(x, y)
w = Window.new x, y, 1, 1
w.windowskin = Cache.system('window')
w.tone = $data_system.window_tone
w.z = $window_list.size #######add
w
end
def active_window #######add
mz = $window_list.size - 1
$window_list.each {|w|
w.z -= 1 if w.z >= $window.z
}
$window.z = mz
end
def resize_window #######add
$window.width = Mouse.x - $window.x
$window.width = 30 if $window.width < 30
$window.height = Mouse.y - $window.y
$window.height = 22 if $window.height < 22
end
def main_logic
case [mouse_event, $status]
when [:mouse_down, :normal]
if $window = get_window_under_mouse # 鼠标下能取到窗体,就当是拖动
$status = :window_selected
$cx, $cy = Mouse.x - $window.x, Mouse.y - $window.y
active_window #######add
else
$status = :create_window # 否则就是创建
$window = new_window(Mouse.x, Mouse.y)
end
when [:mouse_up, :window_selected]
$status = :normal
when [:mouse_up, :create_window]
$window_list.push $window #加入到某个窗口列表
$status = :normal
$window = nil
when [:mouse_move, :window_selected]
$window.x, $window.y = Mouse.x - $cx, Mouse.y - $cy
when [:mouse_move, :create_window]
resize_window #######add
end while Mouse::has_event?
end
def ui_update
main_logic
$window_list.each{|x| x.update}
$window.update if $window
end
$status = :normal
$window_list = []
loop do
Graphics.update
Input.update
Mouse.update
ui_update
end
|
|