Created
December 11, 2012 04:58
-
-
Save ooharak/4255983 to your computer and use it in GitHub Desktop.
window arrangement (win32+Ruby1.9.x)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require 'Win32API' | |
require 'win32ole' | |
class Win32API | |
class Rect | |
def initialize(left,top,right,bottom) | |
@left = left | |
@top = top | |
@right = right | |
@bottom = bottom | |
end | |
def to_s | |
'{'+[@left,@top,@right,@bottom].join(',')+'}' | |
end | |
attr_reader :left, :top, :right, :bottom | |
def width | |
return @right - @left | |
end | |
def height | |
return @bottom - @top | |
end | |
def to_a | |
return [@left,@top,width,height] | |
end | |
def with_left(n) | |
@right += (n - @left) | |
@left=n | |
self | |
end | |
def with_width(w) | |
@right = @left + w | |
self | |
end | |
end | |
class WindowInfo | |
def WindowInfo.createBuf | |
cbSize = 60 | |
return [cbSize].pack('L') + ("\0" * (cbSize - 4)) | |
end | |
#def initialize(val) | |
# @ary = val.unpack('Ll8L3I2S2') | |
# @rect = Rect.new(@ary[1], @ary[2], @ary[3], @ary[4]) | |
#end | |
def initialize(sw) | |
@rect = Rect.new(sw.rcWindow_left, sw.rcWindow_top, sw.rcWindow_right, sw.rcWindow_bottom) | |
end | |
def rect | |
@rect | |
end | |
def to_s | |
"rect=#{@rect.to_s}" | |
end | |
end | |
def Win32API.msgbox(wnd,text,caption='',type=0) | |
Win32API.new('user32', 'MessageBox', %w(l p p i), 'i').call(wnd,text,caption,type) | |
end | |
def Win32API.get_foreground_window() | |
Win32API.new('user32', 'GetForegroundWindow', 'v', 'l').call | |
end | |
#def Win32API.get_window_info(wnd) | |
# pwindowinfo = WindowInfo.createBuf | |
# Win32API.new('user32', 'GetWindowInfo', %(l p), 'p').call(wnd, pwindowinfo) | |
# return WindowInfo.new(pwindowinfo) | |
#end | |
end | |
require 'dl/import' | |
UINT = 'unsigned int' | |
DWORD = 'unsigned long' | |
WORD = ATOM = 'unsigned short' | |
module M | |
extend DL::Importer | |
dlload 'user32' | |
# BOOL GetWindowInfo(HWND hwnd, PWINDOWINFO pwi) | |
extern 'void *GetWindowInfo(void *,void *)' | |
SWindowInfo = struct( [ | |
DWORD + ' cbSize', | |
'long rcWindow_left', | |
'long rcWindow_top', | |
'long rcWindow_right', | |
'long rcWindow_bottom', | |
'long rcClient_left', | |
'long rcClient_top', | |
'long rcClient_right', | |
'long rcClient_bottom', | |
DWORD + ' dwStyle', | |
DWORD + ' dwExStyle', | |
DWORD + ' dwWindowStatus', | |
UINT + ' cxWindowBorders', | |
UINT + ' cyWindowBorders', | |
ATOM + ' atomWindowType', | |
WORD + ' wCreatorVersion', | |
]) | |
# Ll8L3I2S2 | |
end | |
class Win32API | |
def Win32API.get_window_info(wnd) | |
pwindowinfo = M::SWindowInfo.malloc | |
M.GetWindowInfo(wnd,pwindowinfo) | |
w = WindowInfo.new(pwindowinfo) | |
#pwindowinfo.free | |
return w | |
end | |
def Win32API.set_window_pos(wnd,wndafter,x,y,cx,cy,flg) | |
Win32API.new('user32', 'SetWindowPos', %w(l p i i i i i), 'i'). | |
call(wnd,wndafter,x,y,cx,cy,flg) | |
end | |
def Win32API.get_window(wnd, dir=2) | |
Win32API.new('user32', 'GetWindow', %(l i), 'l').call(wnd,dir) | |
end | |
def Win32API.get_window_text(hwnd) | |
buf = "\0" * 300 | |
r = Win32API.new('user32', 'GetWindowText', %(l p i), 'i').call(hwnd, buf, buf.size) | |
return '' if r == 0 | |
return buf.slice(0, r) | |
end | |
def Win32API.get_window_module_file_name(hwnd) | |
buf = "\0" * 300 | |
r = Win32API.new('user32', 'GetWindowModuleFileName', %(l p i), 'i').call(hwnd,buf,buf.size) | |
return '' if r == 0 | |
return buf.slice(0, r) | |
end | |
def Win32API.get_window_thread_process_id(hwnd) | |
buf = "\0" * 4 | |
tid = Win32API.new('user32', 'GetWindowThreadProcessId', %(l p), 'l').call(hwnd, buf) | |
return buf.unpack('L')[0] | |
end | |
end | |
class VBScript | |
def VBScript.escapeVB(s) | |
return nil if s.nil? | |
s.gsub(/\t/, '"&vbtab&"').gsub('"', '""').gsub(/\n/, '"&vbcrlf&"') | |
end | |
def VBScript.inputbox(message,title="") | |
sc = WIN32OLE.new("ScriptControl") | |
sc.language = "VBScript" | |
sc.eval(%Q!Inputbox("#{VBScript.escapeVB(message)}", "#{VBScript.escapeVB(title)}")!) | |
end | |
end | |
class Window | |
def initialize(wnd) | |
@wnd = wnd | |
end | |
def Window.foreground | |
new(Win32API.get_foreground_window()) | |
end | |
def set_pos(x,y,w,h) | |
Win32API.set_window_pos(@wnd,0,x,y,w,h,0) | |
end | |
def info | |
Win32API.get_window_info(@wnd) | |
end | |
def next | |
return Window.new(Win32API.get_window(@wnd,3)) | |
end | |
def hwnd | |
return @wnd | |
end | |
def title | |
return Win32API.get_window_text(@wnd) | |
end | |
def module_file_name | |
return Win32API.get_window_module_file_name(@wnd) | |
end | |
def pid | |
return Win32API.get_window_thread_process_id(@wnd) | |
end | |
end | |
def do_win(cmd) | |
return if cmd[1].nil? | |
args = cmd.slice(1, cmd.size-1).split(/ /) | |
pos = args[0] | |
win = Window.foreground | |
rect = win.info.rect | |
w = 1920 / 2 | |
h = 1030 | |
params = { | |
'f17' =>[rect.left, rect.top, 1024, 768], | |
# f1, f86, f8, fh, fw, | |
# lc, rc, [lr][1-6ns], l, | |
'o' => [(rect.left >= 2*w ? (rect.left-2*w) : (rect.left+2*w+1)), rect.top, rect.width, rect.height], | |
'1' => [0,0,w,h], | |
'2' => [w,0,w,h], | |
'3' => [w*2,0,w,h], | |
'4' => [w*3,0,w,h], | |
'?' => :HELP, | |
'x' => rect.clone.with_left(args[1].to_i).to_a, | |
'fw' => rect.clone.with_width(args[1].to_i).to_a, | |
} | |
param = params[pos] | |
if param == :HELP | |
helpmsg = "One of the following subcommands:\r\n"+ | |
params.keys.sort.join("\r\n") | |
Win32API.msgbox(win.hwnd, helpmsg, 'macro w command', 0) | |
exit(-1) | |
else | |
win.set_pos(*param) | |
end | |
end | |
# Win32API.new('kernel32', 'Beep', %w(l l), 'i').call(440, 1000) | |
# Win32API.new('kernel32', 'Sleep', %w(l), 'v').call(100) | |
def main | |
cmd = ARGV[0] || VBScript.inputbox("Enter command", "macro.rb") | |
raise 'isnil' if cmd.nil? or cmd == "" | |
if 'w' == cmd[0].chr | |
do_win(cmd) | |
else | |
#nop | |
end | |
return | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment