fzeet 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/examples/Raw/Command.rbw +121 -0
- data/examples/Raw/Hello.rbw +7 -0
- data/examples/Raw/LifeCycle.rbw +82 -0
- data/examples/Raw/Minimal.rbw +60 -0
- data/lib/fzeet/windows/common.rb +14 -0
- data/lib/fzeet/windows/gdi.rb +12 -0
- data/lib/fzeet/windows/kernel.rb +29 -0
- data/lib/fzeet/windows/libc.rb +9 -0
- data/lib/fzeet/windows/user.rb +160 -0
- data/lib/fzeet/windows.rb +53 -0
- metadata +92 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2010 Radoslav Peev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'fzeet/windows'
|
2
|
+
|
3
|
+
include Fzeet::Windows
|
4
|
+
|
5
|
+
EnableVisualStyles()
|
6
|
+
|
7
|
+
APPNAME = File.basename(__FILE__, '.rbw')
|
8
|
+
|
9
|
+
CMD_ITEM1 = WM_APP + 1
|
10
|
+
CTL_BUTTON1 = CMD_ITEM1 + 1
|
11
|
+
|
12
|
+
def onCreate(hwnd, cs)
|
13
|
+
bar = CreateMenu()
|
14
|
+
menu1 = CreatePopupMenu()
|
15
|
+
AppendMenu(menu1, MF_STRING, CMD_ITEM1, "Item&1\tAlt+I")
|
16
|
+
AppendMenu(bar, MF_POPUP, menu1.to_i, 'Menu&1')
|
17
|
+
SetMenu(hwnd, bar)
|
18
|
+
|
19
|
+
accels = [
|
20
|
+
[FALT | FVIRTKEY, 'I'.ord, CMD_ITEM1]
|
21
|
+
]
|
22
|
+
|
23
|
+
FFI::MemoryPointer.new(ACCEL, accels.size) { |paccels|
|
24
|
+
accels.each_with_index { |data, i|
|
25
|
+
accel = ACCEL.new(paccels + i * ACCEL.size)
|
26
|
+
|
27
|
+
accel.members.each_with_index { |k, i| accel[k] = data[i] }
|
28
|
+
}
|
29
|
+
|
30
|
+
@haccel = CreateAcceleratorTable(paccels, accels.size)
|
31
|
+
}
|
32
|
+
|
33
|
+
hbtn = CreateWindowEx(0, 'Button', '&Button1', WS_CHILD | WS_VISIBLE, 10, 10, 76, 24, hwnd, FFI::Pointer.new(CTL_BUTTON1), GetModuleHandle(nil), nil)
|
34
|
+
SendMessage(hbtn, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT).to_i, 1)
|
35
|
+
|
36
|
+
0
|
37
|
+
end
|
38
|
+
|
39
|
+
def onDestroy(hwnd)
|
40
|
+
DestroyAcceleratorTable(@haccel)
|
41
|
+
|
42
|
+
PostQuitMessage(0); 0
|
43
|
+
end
|
44
|
+
|
45
|
+
def onItem1(hwnd, notification)
|
46
|
+
MessageBox(hwnd, __method__.to_s, APPNAME, MB_ICONINFORMATION)
|
47
|
+
|
48
|
+
EnableWindow(GetDlgItem(hwnd, CTL_BUTTON1), 1)
|
49
|
+
EnableMenuItem(GetMenu(hwnd), CMD_ITEM1, MF_GRAYED)
|
50
|
+
|
51
|
+
0
|
52
|
+
end
|
53
|
+
|
54
|
+
def onButton1(hwnd, notification, hctl)
|
55
|
+
MessageBox(hwnd, __method__.to_s, APPNAME, MB_ICONINFORMATION)
|
56
|
+
|
57
|
+
EnableMenuItem(GetMenu(hwnd), CMD_ITEM1, MF_ENABLED)
|
58
|
+
EnableWindow(hctl, 0)
|
59
|
+
|
60
|
+
0
|
61
|
+
end
|
62
|
+
|
63
|
+
WindowProc = FFI::Function.new(:long, [:pointer, :uint, :uint, :long], convention: :stdcall) { |hwnd, uMsg, wParam, lParam|
|
64
|
+
result = case uMsg
|
65
|
+
when WM_CREATE
|
66
|
+
onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
|
67
|
+
when WM_DESTROY
|
68
|
+
onDestroy(hwnd)
|
69
|
+
when WM_COMMAND; command, notification, hctl = LOWORD(wParam), HIWORD(wParam), FFI::Pointer.new(lParam)
|
70
|
+
case command
|
71
|
+
when CMD_ITEM1
|
72
|
+
onItem1(hwnd, notification)
|
73
|
+
when CTL_BUTTON1
|
74
|
+
onButton1(hwnd, notification, hctl)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
(result.nil?) ? DefWindowProc(hwnd, uMsg, wParam, lParam) : result
|
79
|
+
}
|
80
|
+
|
81
|
+
wc = WNDCLASSEX.new
|
82
|
+
|
83
|
+
wc[:cbSize] = wc.size
|
84
|
+
wc[:lpfnWndProc] = WindowProc
|
85
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
86
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
87
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
88
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
89
|
+
wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(APPNAME)
|
90
|
+
|
91
|
+
if RegisterClassEx(wc).tap { className.free } == 0
|
92
|
+
MessageBox(nil, 'RegisterClassEx failed.', APPNAME, MB_ICONERROR); exit(0)
|
93
|
+
end
|
94
|
+
|
95
|
+
hwnd = CreateWindowEx(
|
96
|
+
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
97
|
+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
98
|
+
nil, nil, GetModuleHandle(nil), nil
|
99
|
+
)
|
100
|
+
|
101
|
+
if hwnd.null?
|
102
|
+
MessageBox(nil, 'CreateWindowEx failed.', APPNAME, MB_ICONERROR); exit(0)
|
103
|
+
end
|
104
|
+
|
105
|
+
ShowWindow(hwnd, SW_SHOWNORMAL)
|
106
|
+
UpdateWindow(hwnd)
|
107
|
+
|
108
|
+
msg = MSG.new
|
109
|
+
|
110
|
+
while (get = GetMessage(msg, nil, 0, 0)) != 0
|
111
|
+
if get == -1
|
112
|
+
MessageBox(nil, 'GetMessage failed.', APPNAME, MB_ICONERROR); exit(0)
|
113
|
+
end
|
114
|
+
|
115
|
+
if TranslateAccelerator(hwnd, @haccel, msg) == 0
|
116
|
+
TranslateMessage(msg)
|
117
|
+
DispatchMessage(msg)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
exit(msg[:wParam])
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'fzeet/windows'
|
2
|
+
|
3
|
+
include Fzeet::Windows
|
4
|
+
|
5
|
+
EnableVisualStyles()
|
6
|
+
|
7
|
+
APPNAME = File.basename(__FILE__, '.rbw')
|
8
|
+
|
9
|
+
def onCreate(hwnd, cs)
|
10
|
+
answer = MessageBox(nil, 'Create?', cs[:lpszName].read_string, MB_YESNO | MB_ICONQUESTION)
|
11
|
+
|
12
|
+
return -1 if answer == IDNO
|
13
|
+
|
14
|
+
0
|
15
|
+
end
|
16
|
+
|
17
|
+
def onClose(hwnd)
|
18
|
+
answer = MessageBox(hwnd, 'Close?', APPNAME, MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION)
|
19
|
+
|
20
|
+
DestroyWindow(hwnd) if answer == IDYES
|
21
|
+
|
22
|
+
0
|
23
|
+
end
|
24
|
+
|
25
|
+
def onDestroy(hwnd)
|
26
|
+
MessageBox(nil, __method__.to_s, APPNAME, MB_ICONINFORMATION)
|
27
|
+
|
28
|
+
PostQuitMessage(0); 0
|
29
|
+
end
|
30
|
+
|
31
|
+
WindowProc = FFI::Function.new(:long, [:pointer, :uint, :uint, :long], convention: :stdcall) { |hwnd, uMsg, wParam, lParam|
|
32
|
+
result = case uMsg
|
33
|
+
when WM_CREATE
|
34
|
+
onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
|
35
|
+
when WM_CLOSE
|
36
|
+
onClose(hwnd)
|
37
|
+
when WM_DESTROY
|
38
|
+
onDestroy(hwnd)
|
39
|
+
end
|
40
|
+
|
41
|
+
(result.nil?) ? DefWindowProc(hwnd, uMsg, wParam, lParam) : result
|
42
|
+
}
|
43
|
+
|
44
|
+
wc = WNDCLASSEX.new
|
45
|
+
|
46
|
+
wc[:cbSize] = wc.size
|
47
|
+
wc[:lpfnWndProc] = WindowProc
|
48
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
49
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
50
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
51
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
52
|
+
wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(APPNAME)
|
53
|
+
|
54
|
+
if RegisterClassEx(wc).tap { className.free } == 0
|
55
|
+
MessageBox(nil, 'RegisterClassEx failed.', APPNAME, MB_ICONERROR); exit(0)
|
56
|
+
end
|
57
|
+
|
58
|
+
hwnd = CreateWindowEx(
|
59
|
+
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
60
|
+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
61
|
+
nil, nil, GetModuleHandle(nil), nil
|
62
|
+
)
|
63
|
+
|
64
|
+
if hwnd.null?
|
65
|
+
MessageBox(nil, 'CreateWindowEx failed.', APPNAME, MB_ICONERROR); exit(0)
|
66
|
+
end
|
67
|
+
|
68
|
+
ShowWindow(hwnd, SW_SHOWNORMAL)
|
69
|
+
UpdateWindow(hwnd)
|
70
|
+
|
71
|
+
msg = MSG.new
|
72
|
+
|
73
|
+
while (get = GetMessage(msg, nil, 0, 0)) != 0
|
74
|
+
if get == -1
|
75
|
+
MessageBox(nil, 'GetMessage failed.', APPNAME, MB_ICONERROR); exit(0)
|
76
|
+
end
|
77
|
+
|
78
|
+
TranslateMessage(msg)
|
79
|
+
DispatchMessage(msg)
|
80
|
+
end
|
81
|
+
|
82
|
+
exit(msg[:wParam])
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'fzeet/windows'
|
2
|
+
|
3
|
+
include Fzeet::Windows
|
4
|
+
|
5
|
+
EnableVisualStyles()
|
6
|
+
|
7
|
+
APPNAME = File.basename(__FILE__, '.rbw')
|
8
|
+
|
9
|
+
def onDestroy(hwnd)
|
10
|
+
PostQuitMessage(0); 0
|
11
|
+
end
|
12
|
+
|
13
|
+
WindowProc = FFI::Function.new(:long, [:pointer, :uint, :uint, :long], convention: :stdcall) { |hwnd, uMsg, wParam, lParam|
|
14
|
+
result = case uMsg
|
15
|
+
when WM_DESTROY
|
16
|
+
onDestroy(hwnd)
|
17
|
+
end
|
18
|
+
|
19
|
+
(result.nil?) ? DefWindowProc(hwnd, uMsg, wParam, lParam) : result
|
20
|
+
}
|
21
|
+
|
22
|
+
wc = WNDCLASSEX.new
|
23
|
+
|
24
|
+
wc[:cbSize] = wc.size
|
25
|
+
wc[:lpfnWndProc] = WindowProc
|
26
|
+
wc[:hInstance] = GetModuleHandle(nil)
|
27
|
+
wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
|
28
|
+
wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
|
29
|
+
wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
|
30
|
+
wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(APPNAME)
|
31
|
+
|
32
|
+
if RegisterClassEx(wc).tap { className.free } == 0
|
33
|
+
MessageBox(nil, 'RegisterClassEx failed.', APPNAME, MB_ICONERROR); exit(0)
|
34
|
+
end
|
35
|
+
|
36
|
+
hwnd = CreateWindowEx(
|
37
|
+
0, APPNAME, APPNAME, WS_OVERLAPPEDWINDOW,
|
38
|
+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
39
|
+
nil, nil, GetModuleHandle(nil), nil
|
40
|
+
)
|
41
|
+
|
42
|
+
if hwnd.null?
|
43
|
+
MessageBox(nil, 'CreateWindowEx failed.', APPNAME, MB_ICONERROR); exit(0)
|
44
|
+
end
|
45
|
+
|
46
|
+
ShowWindow(hwnd, SW_SHOWNORMAL)
|
47
|
+
UpdateWindow(hwnd)
|
48
|
+
|
49
|
+
msg = MSG.new
|
50
|
+
|
51
|
+
while (get = GetMessage(msg, nil, 0, 0)) != 0
|
52
|
+
if get == -1
|
53
|
+
MessageBox(nil, 'GetMessage failed.', APPNAME, MB_ICONERROR); exit(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
TranslateMessage(msg)
|
57
|
+
DispatchMessage(msg)
|
58
|
+
end
|
59
|
+
|
60
|
+
exit(msg[:wParam])
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
|
3
|
+
module Fzeet
|
4
|
+
module Windows
|
5
|
+
ffi_lib 'kernel32'
|
6
|
+
ffi_convention :stdcall
|
7
|
+
|
8
|
+
class ACTCTX < FFI::Struct
|
9
|
+
layout \
|
10
|
+
:cbSize, :ulong,
|
11
|
+
:dwFlags, :ulong,
|
12
|
+
:lpSource, :pointer,
|
13
|
+
:wProcessorArchitecture, :ushort,
|
14
|
+
:wLangId, :ushort,
|
15
|
+
:lpAssemblyDirectory, :pointer,
|
16
|
+
:lpResourceName, :pointer,
|
17
|
+
:lpApplicationName, :pointer,
|
18
|
+
:hModule, :pointer
|
19
|
+
end
|
20
|
+
|
21
|
+
attach_function :CreateActCtx, :CreateActCtxA, [:pointer], :pointer
|
22
|
+
attach_function :ReleaseActCtx, [:pointer], :void
|
23
|
+
|
24
|
+
attach_function :ActivateActCtx, [:pointer, :pointer], :int
|
25
|
+
attach_function :DeactivateActCtx, [:ulong, :ulong], :int
|
26
|
+
|
27
|
+
attach_function :GetModuleHandle, :GetModuleHandleA, [:string], :pointer
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
|
3
|
+
module Fzeet
|
4
|
+
module Windows
|
5
|
+
ffi_lib 'user32'
|
6
|
+
ffi_convention :stdcall
|
7
|
+
|
8
|
+
MB_OKCANCEL = 0x00000001
|
9
|
+
MB_YESNOCANCEL = 0x00000003
|
10
|
+
MB_YESNO = 0x00000004
|
11
|
+
MB_ICONHAND = 0x00000010
|
12
|
+
MB_ICONQUESTION = 0x00000020
|
13
|
+
MB_ICONEXCLAMATION = 0x00000030
|
14
|
+
MB_ICONASTERISK = 0x00000040
|
15
|
+
MB_ICONERROR = MB_ICONHAND
|
16
|
+
MB_ICONINFORMATION = MB_ICONASTERISK
|
17
|
+
MB_DEFBUTTON2 = 0x00000100
|
18
|
+
MB_DEFBUTTON3 = 0x00000200
|
19
|
+
|
20
|
+
IDOK = 1
|
21
|
+
IDCANCEL = 2
|
22
|
+
IDYES = 6
|
23
|
+
IDNO = 7
|
24
|
+
|
25
|
+
attach_function :MessageBox, :MessageBoxA, [:pointer, :string, :string, :uint], :int
|
26
|
+
|
27
|
+
callback :WNDPROC, [:pointer, :uint, :uint, :long], :long
|
28
|
+
|
29
|
+
attach_function :DefWindowProc, :DefWindowProcA, [:pointer, :uint, :uint, :long], :long
|
30
|
+
|
31
|
+
IDI_APPLICATION = FFI::Pointer.new(32512)
|
32
|
+
|
33
|
+
attach_function :LoadIcon, :LoadIconA, [:pointer, :pointer], :pointer
|
34
|
+
|
35
|
+
IDC_ARROW = FFI::Pointer.new(32512)
|
36
|
+
|
37
|
+
attach_function :LoadCursor, :LoadCursorA, [:pointer, :pointer], :pointer
|
38
|
+
|
39
|
+
COLOR_WINDOW = 5
|
40
|
+
|
41
|
+
class WNDCLASSEX < FFI::Struct
|
42
|
+
layout \
|
43
|
+
:cbSize, :uint,
|
44
|
+
:style, :uint,
|
45
|
+
:lpfnWndProc, :WNDPROC,
|
46
|
+
:cbClsExtra, :int,
|
47
|
+
:cbWndExtra, :int,
|
48
|
+
:hInstance, :pointer,
|
49
|
+
:hIcon, :pointer,
|
50
|
+
:hCursor, :pointer,
|
51
|
+
:hbrBackground, :pointer,
|
52
|
+
:lpszMenuName, :pointer,
|
53
|
+
:lpszClassName, :pointer,
|
54
|
+
:hIconSm, :pointer
|
55
|
+
end
|
56
|
+
|
57
|
+
attach_function :RegisterClassEx, :RegisterClassExA, [:pointer], :ushort
|
58
|
+
|
59
|
+
WS_OVERLAPPED = 0x00000000
|
60
|
+
WS_CHILD = 0x40000000
|
61
|
+
WS_VISIBLE = 0x10000000
|
62
|
+
WS_CAPTION = 0x00C00000
|
63
|
+
WS_SYSMENU = 0x00080000
|
64
|
+
WS_THICKFRAME = 0x00040000
|
65
|
+
WS_MINIMIZEBOX = 0x00020000
|
66
|
+
WS_MAXIMIZEBOX = 0x00010000
|
67
|
+
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
|
68
|
+
|
69
|
+
CW_USEDEFAULT = -0x80000000
|
70
|
+
|
71
|
+
class CREATESTRUCT < FFI::Struct
|
72
|
+
layout \
|
73
|
+
:lpCreateParams, :pointer,
|
74
|
+
:hInstance, :pointer,
|
75
|
+
:hMenu, :pointer,
|
76
|
+
:hwndParent, :pointer,
|
77
|
+
:cy, :int,
|
78
|
+
:cx, :int,
|
79
|
+
:y, :int,
|
80
|
+
:x, :int,
|
81
|
+
:style, :long,
|
82
|
+
:lpszName, :pointer,
|
83
|
+
:lpszClass, :pointer,
|
84
|
+
:dwExStyle, :ulong
|
85
|
+
end
|
86
|
+
|
87
|
+
attach_function :CreateWindowEx, :CreateWindowExA, [:ulong, :string, :string, :ulong, :int, :int, :int, :int, :pointer, :pointer, :pointer, :pointer], :pointer
|
88
|
+
attach_function :DestroyWindow, [:pointer], :int
|
89
|
+
|
90
|
+
SW_SHOWNORMAL = 1
|
91
|
+
|
92
|
+
attach_function :ShowWindow, [:pointer, :int], :int
|
93
|
+
|
94
|
+
attach_function :UpdateWindow, [:pointer], :int
|
95
|
+
attach_function :EnableWindow, [:pointer, :int], :int
|
96
|
+
|
97
|
+
attach_function :GetDlgItem, [:pointer, :int], :pointer
|
98
|
+
|
99
|
+
attach_function :GetMenu, [:pointer], :pointer
|
100
|
+
attach_function :SetMenu, [:pointer, :pointer], :int
|
101
|
+
|
102
|
+
attach_function :CreateMenu, [], :pointer
|
103
|
+
attach_function :CreatePopupMenu, [], :pointer
|
104
|
+
attach_function :DestroyMenu, [:pointer], :int
|
105
|
+
|
106
|
+
MF_ENABLED = 0x00000000
|
107
|
+
MF_GRAYED = 0x00000001
|
108
|
+
MF_STRING = 0x00000000
|
109
|
+
MF_POPUP = 0x00000010
|
110
|
+
|
111
|
+
attach_function :AppendMenu, :AppendMenuA, [:pointer, :uint, :uint, :string], :int
|
112
|
+
attach_function :EnableMenuItem, [:pointer, :uint, :uint], :int
|
113
|
+
|
114
|
+
FVIRTKEY = 1
|
115
|
+
FSHIFT = 0x04
|
116
|
+
FCONTROL = 0x08
|
117
|
+
FALT = 0x10
|
118
|
+
|
119
|
+
class ACCEL < FFI::Struct
|
120
|
+
layout \
|
121
|
+
:fVirt, :uchar,
|
122
|
+
:key, :ushort,
|
123
|
+
:cmd, :ushort
|
124
|
+
end
|
125
|
+
|
126
|
+
attach_function :CreateAcceleratorTable, :CreateAcceleratorTableA, [:pointer, :int], :pointer
|
127
|
+
attach_function :DestroyAcceleratorTable, [:pointer], :int
|
128
|
+
|
129
|
+
WM_CREATE = 0x0001
|
130
|
+
WM_DESTROY = 0x0002
|
131
|
+
WM_CLOSE = 0x0010
|
132
|
+
WM_SETFONT = 0x0030
|
133
|
+
WM_COMMAND = 0x0111
|
134
|
+
WM_APP = 0x8000
|
135
|
+
|
136
|
+
class POINT < FFI::Struct
|
137
|
+
layout \
|
138
|
+
:x, :long,
|
139
|
+
:y, :long
|
140
|
+
end
|
141
|
+
|
142
|
+
class MSG < FFI::Struct
|
143
|
+
layout \
|
144
|
+
:hwnd, :pointer,
|
145
|
+
:message, :uint,
|
146
|
+
:wParam, :uint,
|
147
|
+
:lParam, :long,
|
148
|
+
:time, :ulong,
|
149
|
+
:pt, POINT
|
150
|
+
end
|
151
|
+
|
152
|
+
attach_function :GetMessage, :GetMessageA, [:pointer, :pointer, :uint, :uint], :int
|
153
|
+
attach_function :TranslateAccelerator, :TranslateAcceleratorA, [:pointer, :pointer, :pointer], :int
|
154
|
+
attach_function :TranslateMessage, [:pointer], :int
|
155
|
+
attach_function :DispatchMessage, :DispatchMessageA, [:pointer], :long
|
156
|
+
attach_function :SendMessage, :SendMessageA, [:pointer, :uint, :uint, :long], :long
|
157
|
+
attach_function :PostMessage, :PostMessageA, [:pointer, :uint, :uint, :long], :int
|
158
|
+
attach_function :PostQuitMessage, [:int], :void
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'windows/libc'
|
2
|
+
|
3
|
+
require_relative 'windows/kernel'
|
4
|
+
require_relative 'windows/user'
|
5
|
+
require_relative 'windows/gdi'
|
6
|
+
|
7
|
+
module Fzeet
|
8
|
+
module Windows
|
9
|
+
COMMON_CONTROLS_ACTCTX = {handle: INVALID_HANDLE_VALUE, cookie: FFI::MemoryPointer.new(:ulong), activated: false}
|
10
|
+
|
11
|
+
at_exit {
|
12
|
+
DeactivateActCtx(0, COMMON_CONTROLS_ACTCTX[:cookie].get_ulong(0)) if COMMON_CONTROLS_ACTCTX[:activated]
|
13
|
+
COMMON_CONTROLS_ACTCTX[:cookie].free
|
14
|
+
ReleaseActCtx(COMMON_CONTROLS_ACTCTX[:handle]) unless COMMON_CONTROLS_ACTCTX[:handle] == INVALID_HANDLE_VALUE
|
15
|
+
}
|
16
|
+
|
17
|
+
def EnableVisualStyles
|
18
|
+
raise 'Visual styles already enabled.' if COMMON_CONTROLS_ACTCTX[:activated]
|
19
|
+
|
20
|
+
manifest = "#{ENV['TEMP']}/Fzeet.Common-Controls.manifest"
|
21
|
+
|
22
|
+
File.open(manifest, 'w:utf-8') { |file|
|
23
|
+
file << <<-XML
|
24
|
+
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
|
25
|
+
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
|
26
|
+
<dependency>
|
27
|
+
<dependentAssembly>
|
28
|
+
<assemblyIdentity type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
|
29
|
+
</dependentAssembly>
|
30
|
+
</dependency>
|
31
|
+
</assembly>
|
32
|
+
XML
|
33
|
+
}
|
34
|
+
|
35
|
+
ac = ACTCTX.new
|
36
|
+
|
37
|
+
ac[:cbSize] = ac.size
|
38
|
+
ac[:lpSource] = source = FFI::MemoryPointer.from_string(File.expand_path(manifest))
|
39
|
+
|
40
|
+
raise 'CreateActCtx failed.' if (COMMON_CONTROLS_ACTCTX[:handle] = CreateActCtx(ac).tap { source.free }) == INVALID_HANDLE_VALUE
|
41
|
+
|
42
|
+
if ActivateActCtx(COMMON_CONTROLS_ACTCTX[:handle], COMMON_CONTROLS_ACTCTX[:cookie]) == 0
|
43
|
+
ReleaseActCtx(COMMON_CONTROLS_ACTCTX[:handle]); COMMON_CONTROLS_ACTCTX[:handle] = INVALID_HANDLE_VALUE
|
44
|
+
|
45
|
+
raise 'ActivateActCtx failed.'
|
46
|
+
end
|
47
|
+
|
48
|
+
COMMON_CONTROLS_ACTCTX[:activated] = true
|
49
|
+
end
|
50
|
+
|
51
|
+
module_function :EnableVisualStyles
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fzeet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Radoslav Peev
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-07 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: ffi
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 1
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 6
|
33
|
+
- 3
|
34
|
+
version: 0.6.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description:
|
38
|
+
email:
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- lib/fzeet/windows/common.rb
|
47
|
+
- lib/fzeet/windows/gdi.rb
|
48
|
+
- lib/fzeet/windows/kernel.rb
|
49
|
+
- lib/fzeet/windows/libc.rb
|
50
|
+
- lib/fzeet/windows/user.rb
|
51
|
+
- lib/fzeet/windows.rb
|
52
|
+
- examples/Raw/Command.rbw
|
53
|
+
- examples/Raw/Hello.rbw
|
54
|
+
- examples/Raw/LifeCycle.rbw
|
55
|
+
- examples/Raw/Minimal.rbw
|
56
|
+
- LICENSE
|
57
|
+
has_rdoc: true
|
58
|
+
homepage:
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
hash: 3
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
requirements: []
|
85
|
+
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 1.3.7
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: GUI Library
|
91
|
+
test_files: []
|
92
|
+
|