ffi-wingui-core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2010 - 2011 Radoslav Peev
3
+ Copyright (c) 2011 Radoslav Peev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/examples/Command.rbw CHANGED
@@ -4,7 +4,7 @@ include WinGUI
4
4
 
5
5
  EnableVisualStyles()
6
6
 
7
- APPNAME = File.basename(__FILE__, '.rbw')
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
8
 
9
9
  CMD_ITEM1 = WM_APP + 1
10
10
  CTL_BUTTON1 = CMD_ITEM1 + 1
@@ -36,8 +36,8 @@ def onCreate(hwnd,
36
36
 
37
37
  hbar = CreateMenu()
38
38
  hmenu1 = CreatePopupMenu()
39
- AppendMenu(hmenu1, MF_STRING, CMD_ITEM1, "Item&1\tAlt+I")
40
- AppendMenu(hbar, MF_POPUP, hmenu1.to_i, 'Menu&1')
39
+ AppendMenu(hmenu1, MF_STRING, CMD_ITEM1, L("Item&1\tAlt+I"))
40
+ AppendMenu(hbar, MF_POPUP, hmenu1.to_i, L('Menu&1'))
41
41
  SetMenu(hwnd, hbar)
42
42
 
43
43
  accels = [
@@ -59,8 +59,8 @@ def onCreate(hwnd,
59
59
  xtra[:hmf] = CreateFontIndirect(ncm[:lfMenuFont]);
60
60
 
61
61
  hbtn1 = CreateWindowEx(
62
- 0, 'Button', '&Button1', WS_CHILD | WS_VISIBLE,
63
- 10, 10, 100, 25,
62
+ 0, L('Button'), L('&Button1'), WS_CHILD | WS_VISIBLE,
63
+ *DPIScale(10, 10, 100, 25),
64
64
  hwnd, FFI::Pointer.new(CTL_BUTTON1), GetModuleHandle(nil), nil
65
65
  )
66
66
  SendMessage(hbtn1, WM_SETFONT, xtra[:hmf].to_i, 1)
@@ -82,7 +82,7 @@ def onItem1(verb,
82
82
  hctl, hwnd
83
83
  )
84
84
  MessageBox(hwnd,
85
- __method__.to_s,
85
+ L(__method__.to_s),
86
86
  APPNAME,
87
87
  MB_ICONINFORMATION
88
88
  )
@@ -106,7 +106,7 @@ def onButton1(verb,
106
106
  hctl, hwnd
107
107
  )
108
108
  MessageBox(hwnd,
109
- __method__.to_s,
109
+ L(__method__.to_s),
110
110
  APPNAME,
111
111
  MB_ICONINFORMATION
112
112
  )
@@ -125,11 +125,12 @@ def onButton1(verb,
125
125
  0
126
126
  end
127
127
 
128
- def windowProc(hwnd,
129
- uMsg,
130
- wParam, lParam
131
- )
132
- case uMsg
128
+ WindowProc = FFI::Function.new(:long,
129
+ [:pointer, :uint, :uint, :long],
130
+ convention: :stdcall
131
+ ) { |hwnd, uMsg, wParam, lParam|
132
+ begin
133
+ result = case uMsg
133
134
  when WM_NCCREATE
134
135
  DefWindowProc(hwnd, uMsg, wParam, lParam)
135
136
 
@@ -138,47 +139,46 @@ def windowProc(hwnd,
138
139
  CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
139
140
  )
140
141
 
141
- return 1
142
+ 1
142
143
  when WM_CREATE
143
- return onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
144
+ onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
144
145
  when WM_DESTROY
145
- return onDestroy(hwnd)
146
+ onDestroy(hwnd)
146
147
  when WM_COMMAND
147
148
  id, verb = LOWORD(wParam), HIWORD(wParam)
148
149
  hctl = FFI::Pointer.new(lParam)
149
150
 
150
151
  case id
151
152
  when CMD_ITEM1
152
- return onItem1(verb, hctl, hwnd)
153
+ onItem1(verb, hctl, hwnd)
153
154
  when CTL_BUTTON1
154
- return onButton1(verb, hctl, hwnd)
155
+ onButton1(verb, hctl, hwnd)
155
156
  end
156
157
  end
157
158
 
158
- DefWindowProc(hwnd, uMsg, wParam, lParam)
159
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
159
160
  rescue
160
161
  MessageBox(nil,
161
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
162
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
162
163
  APPNAME,
163
164
  MB_ICONERROR
164
165
  ); PostQuitMessage(2)
165
166
  end
167
+ }
166
168
 
167
169
  def main
168
170
  wc = WNDCLASSEX.new
169
171
  xtra = WndExtra.new
170
172
 
171
173
  wc[:cbSize] = wc.size
172
- wc[:lpfnWndProc] = method(:windowProc)
174
+ wc[:lpfnWndProc] = WindowProc
173
175
  #wc[:cbWndExtra] = FFI::Pointer.size
174
176
  wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
175
177
  wc[:hInstance] = GetModuleHandle(nil)
176
178
  wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
177
179
  wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
178
180
  wc[:hbrBackground] = FFI::Pointer.new(CTLCOLOR_DLG + 1)
179
- wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(
180
- APPNAME
181
- )
181
+ wc[:lpszClassName] = className = PWSTR(APPNAME)
182
182
 
183
183
  DetonateLastError(0, :RegisterClassEx,
184
184
  wc
@@ -210,7 +210,7 @@ def main
210
210
  exit(msg[:wParam])
211
211
  rescue
212
212
  MessageBox(nil,
213
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
213
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
214
214
  APPNAME,
215
215
  MB_ICONERROR
216
216
  ); exit(1)
data/examples/Hello.rbw CHANGED
@@ -5,7 +5,7 @@ include WinGUI
5
5
  EnableVisualStyles()
6
6
 
7
7
  MessageBox(nil,
8
- 'Hello, world!',
9
- 'Hello',
8
+ L('Hello, world!'),
9
+ L('Hello'),
10
10
  MB_ICONINFORMATION
11
11
  )
@@ -4,14 +4,14 @@ include WinGUI
4
4
 
5
5
  EnableVisualStyles()
6
6
 
7
- APPNAME = File.basename(__FILE__, '.rbw')
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
8
 
9
9
  def onCreate(hwnd,
10
10
  cs
11
11
  )
12
12
  answer = MessageBox(nil,
13
- 'Create?',
14
- cs[:lpszName].read_string,
13
+ L('Create?'),
14
+ cs[:lpszName],
15
15
  MB_YESNO | MB_ICONQUESTION
16
16
  )
17
17
 
@@ -22,7 +22,7 @@ end
22
22
 
23
23
  def onClose(hwnd)
24
24
  answer = MessageBox(hwnd,
25
- 'Close?',
25
+ L('Close?'),
26
26
  APPNAME,
27
27
  MB_YESNO | MB_ICONQUESTION |
28
28
  MB_DEFBUTTON2
@@ -35,7 +35,7 @@ end
35
35
 
36
36
  def onDestroy(hwnd)
37
37
  MessageBox(nil,
38
- __method__.to_s,
38
+ L(__method__.to_s),
39
39
  APPNAME,
40
40
  MB_ICONINFORMATION
41
41
  )
@@ -43,40 +43,40 @@ def onDestroy(hwnd)
43
43
  PostQuitMessage(0); 0
44
44
  end
45
45
 
46
- def windowProc(hwnd,
47
- uMsg,
48
- wParam, lParam
49
- )
50
- case uMsg
46
+ WindowProc = FFI::Function.new(:long,
47
+ [:pointer, :uint, :uint, :long],
48
+ convention: :stdcall
49
+ ) { |hwnd, uMsg, wParam, lParam|
50
+ begin
51
+ result = case uMsg
51
52
  when WM_CREATE
52
- return onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
53
+ onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
53
54
  when WM_CLOSE
54
- return onClose(hwnd)
55
+ onClose(hwnd)
55
56
  when WM_DESTROY
56
- return onDestroy(hwnd)
57
+ onDestroy(hwnd)
57
58
  end
58
59
 
59
- DefWindowProc(hwnd, uMsg, wParam, lParam)
60
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
60
61
  rescue
61
62
  MessageBox(nil,
62
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
63
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
63
64
  APPNAME,
64
65
  MB_ICONERROR
65
66
  ); PostQuitMessage(2)
66
67
  end
68
+ }
67
69
 
68
70
  def main
69
71
  wc = WNDCLASSEX.new
70
72
 
71
73
  wc[:cbSize] = wc.size
72
- wc[:lpfnWndProc] = method(:windowProc)
74
+ wc[:lpfnWndProc] = WindowProc
73
75
  wc[:hInstance] = GetModuleHandle(nil)
74
76
  wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
75
77
  wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
76
78
  wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
77
- wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(
78
- APPNAME
79
- )
79
+ wc[:lpszClassName] = className = PWSTR(APPNAME)
80
80
 
81
81
  DetonateLastError(0, :RegisterClassEx,
82
82
  wc
@@ -106,7 +106,7 @@ def main
106
106
  exit(msg[:wParam])
107
107
  rescue
108
108
  MessageBox(nil,
109
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
109
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
110
110
  APPNAME,
111
111
  MB_ICONERROR
112
112
  ); exit(1)
@@ -4,14 +4,14 @@ include WinGUI
4
4
 
5
5
  EnableVisualStyles()
6
6
 
7
- APPNAME = File.basename(__FILE__, '.rbw')
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
8
 
9
9
  def onNCCreate(hwnd,
10
10
  cs
11
11
  )
12
12
  answer = MessageBox(nil,
13
- 'NCCreate?',
14
- cs[:lpszName].read_string,
13
+ L('NCCreate?'),
14
+ cs[:lpszName],
15
15
  MB_YESNO | MB_ICONQUESTION
16
16
  )
17
17
 
@@ -24,8 +24,8 @@ def onCreate(hwnd,
24
24
  cs
25
25
  )
26
26
  answer = MessageBox(nil,
27
- 'Create?',
28
- cs[:lpszName].read_string,
27
+ L('Create?'),
28
+ cs[:lpszName],
29
29
  MB_YESNO | MB_ICONQUESTION
30
30
  )
31
31
 
@@ -36,7 +36,7 @@ end
36
36
 
37
37
  def onClose(hwnd)
38
38
  answer = MessageBox(hwnd,
39
- 'Close?',
39
+ L('Close?'),
40
40
  APPNAME,
41
41
  MB_YESNO | MB_ICONQUESTION |
42
42
  MB_DEFBUTTON2
@@ -49,7 +49,7 @@ end
49
49
 
50
50
  def onDestroy(hwnd)
51
51
  MessageBox(nil,
52
- __method__.to_s,
52
+ L(__method__.to_s),
53
53
  APPNAME,
54
54
  MB_ICONINFORMATION
55
55
  )
@@ -59,7 +59,7 @@ end
59
59
 
60
60
  def onNCDestroy(hwnd)
61
61
  MessageBox(nil,
62
- __method__.to_s,
62
+ L(__method__.to_s),
63
63
  APPNAME,
64
64
  MB_ICONINFORMATION
65
65
  )
@@ -67,46 +67,46 @@ def onNCDestroy(hwnd)
67
67
  PostQuitMessage(0); 0
68
68
  end
69
69
 
70
- def windowProc(hwnd,
71
- uMsg,
72
- wParam, lParam
73
- )
74
- case uMsg
70
+ WindowProc = FFI::Function.new(:long,
71
+ [:pointer, :uint, :uint, :long],
72
+ convention: :stdcall
73
+ ) { |hwnd, uMsg, wParam, lParam|
74
+ begin
75
+ result = case uMsg
75
76
  when WM_NCCREATE
76
77
  DefWindowProc(hwnd, uMsg, wParam, lParam)
77
78
 
78
- return onNCCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
79
+ onNCCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
79
80
  when WM_CREATE
80
- return onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
81
+ onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
81
82
  when WM_CLOSE
82
- return onClose(hwnd)
83
+ onClose(hwnd)
83
84
  when WM_DESTROY
84
- return onDestroy(hwnd)
85
+ onDestroy(hwnd)
85
86
  when WM_NCDESTROY
86
- return onNCDestroy(hwnd)
87
+ onNCDestroy(hwnd)
87
88
  end
88
89
 
89
- DefWindowProc(hwnd, uMsg, wParam, lParam)
90
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
90
91
  rescue
91
92
  MessageBox(nil,
92
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
93
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
93
94
  APPNAME,
94
95
  MB_ICONERROR
95
96
  ); PostQuitMessage(2)
96
97
  end
98
+ }
97
99
 
98
100
  def main
99
101
  wc = WNDCLASSEX.new
100
102
 
101
103
  wc[:cbSize] = wc.size
102
- wc[:lpfnWndProc] = method(:windowProc)
104
+ wc[:lpfnWndProc] = WindowProc
103
105
  wc[:hInstance] = GetModuleHandle(nil)
104
106
  wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
105
107
  wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
106
108
  wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
107
- wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(
108
- APPNAME
109
- )
109
+ wc[:lpszClassName] = className = PWSTR(APPNAME)
110
110
 
111
111
  DetonateLastError(0, :RegisterClassEx,
112
112
  wc
@@ -136,7 +136,7 @@ def main
136
136
  exit(msg[:wParam])
137
137
  rescue
138
138
  MessageBox(nil,
139
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
139
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
140
140
  APPNAME,
141
141
  MB_ICONERROR
142
142
  ); exit(1)
data/examples/Minimal.rbw CHANGED
@@ -4,42 +4,42 @@ include WinGUI
4
4
 
5
5
  EnableVisualStyles()
6
6
 
7
- APPNAME = File.basename(__FILE__, '.rbw')
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
8
 
9
9
  def onDestroy(hwnd)
10
10
  PostQuitMessage(0); 0
11
11
  end
12
12
 
13
- def windowProc(hwnd,
14
- uMsg,
15
- wParam, lParam
16
- )
17
- case uMsg
13
+ WindowProc = FFI::Function.new(:long,
14
+ [:pointer, :uint, :uint, :long],
15
+ convention: :stdcall
16
+ ) { |hwnd, uMsg, wParam, lParam|
17
+ begin
18
+ result = case uMsg
18
19
  when WM_DESTROY
19
- return onDestroy(hwnd)
20
+ onDestroy(hwnd)
20
21
  end
21
22
 
22
- DefWindowProc(hwnd, uMsg, wParam, lParam)
23
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
23
24
  rescue
24
25
  MessageBox(nil,
25
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
26
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
26
27
  APPNAME,
27
28
  MB_ICONERROR
28
29
  ); PostQuitMessage(2)
29
30
  end
31
+ }
30
32
 
31
33
  def main
32
34
  wc = WNDCLASSEX.new
33
35
 
34
36
  wc[:cbSize] = wc.size
35
- wc[:lpfnWndProc] = method(:windowProc)
37
+ wc[:lpfnWndProc] = WindowProc
36
38
  wc[:hInstance] = GetModuleHandle(nil)
37
39
  wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
38
40
  wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
39
41
  wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
40
- wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(
41
- APPNAME
42
- )
42
+ wc[:lpszClassName] = className = PWSTR(APPNAME)
43
43
 
44
44
  DetonateLastError(0, :RegisterClassEx,
45
45
  wc
@@ -69,7 +69,7 @@ def main
69
69
  exit(msg[:wParam])
70
70
  rescue
71
71
  MessageBox(nil,
72
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
72
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
73
73
  APPNAME,
74
74
  MB_ICONERROR
75
75
  ); exit(1)
@@ -4,7 +4,7 @@ include WinGUI
4
4
 
5
5
  EnableVisualStyles()
6
6
 
7
- APPNAME = File.basename(__FILE__, '.rbw')
7
+ APPNAME = L(File.basename(__FILE__, '.rbw'))
8
8
 
9
9
  WndExtra = Struct.new(
10
10
  :foo
@@ -30,7 +30,7 @@ def onCreate(hwnd,
30
30
  #xtra = ObjectSpace._id2ref(GetWindowLong(hwnd, GWL_USERDATA))
31
31
  xtra = WndExtra::REFS[GetWindowLong(hwnd, GWL_USERDATA)]
32
32
 
33
- xtra[:foo] = 'Foo'
33
+ xtra[:foo] = L('Foo')
34
34
 
35
35
  -1
36
36
  end
@@ -48,11 +48,12 @@ def onDestroy(hwnd)
48
48
  PostQuitMessage(0); 0
49
49
  end
50
50
 
51
- def windowProc(hwnd,
52
- uMsg,
53
- wParam, lParam
54
- )
55
- case uMsg
51
+ WindowProc = FFI::Function.new(:long,
52
+ [:pointer, :uint, :uint, :long],
53
+ convention: :stdcall
54
+ ) { |hwnd, uMsg, wParam, lParam|
55
+ begin
56
+ result = case uMsg
56
57
  when WM_NCCREATE
57
58
  DefWindowProc(hwnd, uMsg, wParam, lParam)
58
59
 
@@ -61,37 +62,36 @@ def windowProc(hwnd,
61
62
  CREATESTRUCT.new(FFI::Pointer.new(lParam))[:lpCreateParams].to_i
62
63
  )
63
64
 
64
- return 1
65
+ 1
65
66
  when WM_CREATE
66
- return onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
67
+ onCreate(hwnd, CREATESTRUCT.new(FFI::Pointer.new(lParam)))
67
68
  when WM_DESTROY
68
- return onDestroy(hwnd)
69
+ onDestroy(hwnd)
69
70
  end
70
71
 
71
- DefWindowProc(hwnd, uMsg, wParam, lParam)
72
+ result || DefWindowProc(hwnd, uMsg, wParam, lParam)
72
73
  rescue
73
74
  MessageBox(nil,
74
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
75
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
75
76
  APPNAME,
76
77
  MB_ICONERROR
77
78
  ); PostQuitMessage(2)
78
79
  end
80
+ }
79
81
 
80
82
  def main
81
83
  wc = WNDCLASSEX.new
82
84
  xtra = WndExtra.new
83
85
 
84
86
  wc[:cbSize] = wc.size
85
- wc[:lpfnWndProc] = method(:windowProc)
87
+ wc[:lpfnWndProc] = WindowProc
86
88
  #wc[:cbWndExtra] = FFI::Pointer.size
87
89
  wc[:cbWndExtra] = FFI::Type::Builtin::POINTER.size
88
90
  wc[:hInstance] = GetModuleHandle(nil)
89
91
  wc[:hIcon] = LoadIcon(nil, IDI_APPLICATION)
90
92
  wc[:hCursor] = LoadCursor(nil, IDC_ARROW)
91
93
  wc[:hbrBackground] = FFI::Pointer.new(COLOR_WINDOW + 1)
92
- wc[:lpszClassName] = className = FFI::MemoryPointer.from_string(
93
- APPNAME
94
- )
94
+ wc[:lpszClassName] = className = PWSTR(APPNAME)
95
95
 
96
96
  DetonateLastError(0, :RegisterClassEx,
97
97
  wc
@@ -121,7 +121,7 @@ def main
121
121
  exit(msg[:wParam])
122
122
  rescue
123
123
  MessageBox(nil,
124
- %'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}',
124
+ L(%'#{$!.to_s}\n\n#{$!.backtrace.join("\n")}'),
125
125
  APPNAME,
126
126
  MB_ICONERROR
127
127
  ); exit(1)
@@ -33,16 +33,57 @@ module WinGUI
33
33
  :MAKEWORD, :LOBYTE, :HIBYTE,
34
34
  :MAKELONG, :LOWORD, :HIWORD
35
35
 
36
+ def L(s)
37
+ (s << "\0").encode!('utf-16le')
38
+ end
39
+
40
+ def PWSTR(ws)
41
+ raise 'Invalid Unicode string' unless
42
+ ws.encoding == Encoding::UTF_16LE &&
43
+ ws[-1] == L('')
44
+
45
+ p = FFI::MemoryPointer.new(:ushort, ws.length).
46
+ put_bytes(0, ws)
47
+
48
+ return p unless block_given?
49
+
50
+ begin yield p ensure p.free end
51
+
52
+ nil
53
+ end
54
+
55
+ module_function :L, :PWSTR
56
+
36
57
  class POINT < FFI::Struct
37
58
  layout \
38
59
  :x, :long,
39
60
  :y, :long
61
+
62
+ def self.[](x, y)
63
+ new.tap { |point|
64
+ point[:x], point[:y] = x, y
65
+ }
66
+ end
67
+
68
+ def to_a
69
+ [self[:x], self[:y]]
70
+ end
40
71
  end
41
72
 
42
73
  class SIZE < FFI::Struct
43
74
  layout \
44
75
  :cx, :long,
45
76
  :cy, :long
77
+
78
+ def self.[](cx, cy)
79
+ new.tap { |size|
80
+ size[:cx], size[:cy] = cx, cy
81
+ }
82
+ end
83
+
84
+ def to_a
85
+ [self[:cx], self[:cy]]
86
+ end
46
87
  end
47
88
 
48
89
  class RECT < FFI::Struct
@@ -51,6 +92,16 @@ module WinGUI
51
92
  :top, :long,
52
93
  :right, :long,
53
94
  :bottom, :long
95
+
96
+ def self.[](l, t, r, b)
97
+ new.tap { |rect|
98
+ rect[:left], rect[:top], rect[:right], rect[:bottom] = l, t, r, b
99
+ }
100
+ end
101
+
102
+ def to_a
103
+ [self[:left], self[:top], self[:right], self[:bottom]]
104
+ end
54
105
  end
55
106
 
56
107
  ffi_lib 'kernel32'
@@ -91,7 +142,7 @@ module WinGUI
91
142
  :dwMinorVersion, :ulong,
92
143
  :dwBuildNumber, :ulong,
93
144
  :dwPlatformId, :ulong,
94
- :szCSDVersion, [:char, 128],
145
+ :szCSDVersion, [:ushort, 128],
95
146
  :wServicePackMajor, :ushort,
96
147
  :wServicePackMinor, :ushort,
97
148
  :wSuiteMask, :ushort,
@@ -99,7 +150,7 @@ module WinGUI
99
150
  :wReserved, :uchar
100
151
  end
101
152
 
102
- attach_function :GetVersionEx, :GetVersionExA, [
153
+ attach_function :GetVersionEx, :GetVersionExW, [
103
154
  :pointer
104
155
  ], :int
105
156
 
@@ -163,12 +214,12 @@ module WinGUI
163
214
 
164
215
  WINVER = HIWORD(NTDDI_VERSION)
165
216
 
166
- attach_function :GetModuleHandle, :GetModuleHandleA, [
167
- :string
217
+ attach_function :GetModuleHandle, :GetModuleHandleW, [
218
+ :buffer_in
168
219
  ], :pointer
169
220
 
170
- attach_function :LoadLibrary, :LoadLibraryA, [
171
- :string
221
+ attach_function :LoadLibrary, :LoadLibraryW, [
222
+ :buffer_in
172
223
  ], :pointer
173
224
 
174
225
  attach_function :FreeLibrary, [
@@ -189,7 +240,7 @@ module WinGUI
189
240
  :hModule, :pointer
190
241
  end
191
242
 
192
- attach_function :CreateActCtx, :CreateActCtxA, [
243
+ attach_function :CreateActCtx, :CreateActCtxW, [
193
244
  :pointer
194
245
  ], :pointer
195
246
 
@@ -255,9 +306,7 @@ module WinGUI
255
306
  ac = ACTCTX.new
256
307
 
257
308
  ac[:cbSize] = ac.size
258
- ac[:lpSource] = source = FFI::MemoryPointer.from_string(
259
- File.expand_path(manifest)
260
- )
309
+ ac[:lpSource] = source = PWSTR(L(manifest))
261
310
 
262
311
  COMMON_CONTROLS_ACTCTX[:handle] =
263
312
  DetonateLastError(INVALID_HANDLE_VALUE, :CreateActCtx,
@@ -278,6 +327,12 @@ module WinGUI
278
327
 
279
328
  module_function :EnableVisualStyles
280
329
 
330
+ attach_function :MulDiv, [
331
+ :int,
332
+ :int,
333
+ :int
334
+ ], :int
335
+
281
336
  ffi_lib 'gdi32'
282
337
  ffi_convention :stdcall
283
338
 
@@ -300,6 +355,14 @@ module WinGUI
300
355
  module_function \
301
356
  :RGB, :GetRValue, :GetGValue, :GetBValue
302
357
 
358
+ LOGPIXELSX = 88
359
+ LOGPIXELSY = 90
360
+
361
+ attach_function :GetDeviceCaps, [
362
+ :pointer,
363
+ :int
364
+ ], :int
365
+
303
366
  class LOGFONT < FFI::Struct
304
367
  layout \
305
368
  :lfHeight, :long,
@@ -315,10 +378,10 @@ module WinGUI
315
378
  :lfClipPrecision, :uchar,
316
379
  :lfQuality, :uchar,
317
380
  :lfPitchAndFamily, :uchar,
318
- :lfFaceName, [:char, 32]
381
+ :lfFaceName, [:ushort, 32]
319
382
  end
320
383
 
321
- attach_function :CreateFontIndirect, :CreateFontIndirectA, [
384
+ attach_function :CreateFontIndirect, :CreateFontIndirectW, [
322
385
  :pointer
323
386
  ], :pointer
324
387
 
@@ -365,6 +428,16 @@ module WinGUI
365
428
  ffi_lib 'user32'
366
429
  ffi_convention :stdcall
367
430
 
431
+ if WINVER >= WINVISTA
432
+ attach_function :SetProcessDPIAware, [
433
+
434
+ ], :int
435
+
436
+ Detonate(0, :SetProcessDPIAware) unless
437
+ Object.const_defined?(:DPI_AWARE) &&
438
+ !DPI_AWARE
439
+ end
440
+
368
441
  #{ MB_xxx
369
442
  MB_OK = 0x00000000
370
443
  MB_OKCANCEL = 0x00000001
@@ -402,10 +475,10 @@ module WinGUI
402
475
  IDCONTINUE = 11
403
476
  #}
404
477
 
405
- attach_function :MessageBox, :MessageBoxA, [
478
+ attach_function :MessageBox, :MessageBoxW, [
406
479
  :pointer,
407
- :string,
408
- :string,
480
+ :buffer_in,
481
+ :buffer_in,
409
482
  :uint
410
483
  ], :int
411
484
 
@@ -430,7 +503,7 @@ module WinGUI
430
503
  :long
431
504
  ], :long
432
505
 
433
- attach_function :DefWindowProc, :DefWindowProcA, [
506
+ attach_function :DefWindowProc, :DefWindowProcW, [
434
507
  :pointer,
435
508
  :uint,
436
509
  :uint,
@@ -441,7 +514,7 @@ module WinGUI
441
514
  IDI_APPLICATION = FFI::Pointer.new(32512)
442
515
  #}
443
516
 
444
- attach_function :LoadIcon, :LoadIconA, [
517
+ attach_function :LoadIcon, :LoadIconW, [
445
518
  :pointer,
446
519
  :pointer
447
520
  ], :pointer
@@ -458,7 +531,7 @@ module WinGUI
458
531
  IDC_SIZENESW = FFI::Pointer.new(32643)
459
532
  #}
460
533
 
461
- attach_function :LoadCursor, :LoadCursorA, [
534
+ attach_function :LoadCursor, :LoadCursorW, [
462
535
  :pointer,
463
536
  :pointer
464
537
  ], :pointer
@@ -486,16 +559,16 @@ module WinGUI
486
559
  :hIconSm, :pointer
487
560
  end
488
561
 
489
- attach_function :RegisterClassEx, :RegisterClassExA, [
562
+ attach_function :RegisterClassEx, :RegisterClassExW, [
490
563
  :pointer
491
564
  ], :ushort
492
565
 
493
- attach_function :UnregisterClass, :UnregisterClassA, [
566
+ attach_function :UnregisterClass, :UnregisterClassW, [
494
567
  :pointer,
495
568
  :pointer
496
569
  ], :int
497
570
 
498
- attach_function :GetClassInfoEx, :GetClassInfoExA, [
571
+ attach_function :GetClassInfoEx, :GetClassInfoExW, [
499
572
  :pointer,
500
573
  :pointer,
501
574
  :pointer
@@ -542,10 +615,10 @@ module WinGUI
542
615
  HWND_MESSAGE = FFI::Pointer.new(-3)
543
616
  #}
544
617
 
545
- attach_function :CreateWindowEx, :CreateWindowExA, [
618
+ attach_function :CreateWindowEx, :CreateWindowExW, [
546
619
  :ulong,
547
- :string,
548
- :string,
620
+ :buffer_in,
621
+ :buffer_in,
549
622
  :ulong,
550
623
  :int,
551
624
  :int,
@@ -575,18 +648,18 @@ module WinGUI
575
648
  GCW_ATOM = -32
576
649
  #}
577
650
 
578
- attach_function :SetClassLong, :SetClassLongA, [
651
+ attach_function :SetClassLong, :SetClassLongW, [
579
652
  :pointer,
580
653
  :int,
581
654
  :long
582
655
  ], :ulong
583
656
 
584
- attach_function :GetClassLong, :GetClassLongA, [
657
+ attach_function :GetClassLong, :GetClassLongW, [
585
658
  :pointer,
586
659
  :int
587
660
  ], :ulong
588
661
 
589
- attach_function :GetClassName, :GetClassNameA, [
662
+ attach_function :GetClassName, :GetClassNameW, [
590
663
  :pointer,
591
664
  :pointer,
592
665
  :int
@@ -602,13 +675,13 @@ module WinGUI
602
675
  GWL_WNDPROC = -4
603
676
  #}
604
677
 
605
- attach_function :SetWindowLong, :SetWindowLongA, [
678
+ attach_function :SetWindowLong, :SetWindowLongW, [
606
679
  :pointer,
607
680
  :int,
608
681
  :long
609
682
  ], :long
610
683
 
611
- attach_function :GetWindowLong, :GetWindowLongA, [
684
+ attach_function :GetWindowLong, :GetWindowLongW, [
612
685
  :pointer,
613
686
  :int
614
687
  ], :long
@@ -731,6 +804,48 @@ module WinGUI
731
804
  :pointer
732
805
  ], :int
733
806
 
807
+ attach_function :GetDC, [
808
+ :pointer
809
+ ], :pointer
810
+
811
+ attach_function :ReleaseDC, [
812
+ :pointer,
813
+ :pointer
814
+ ], :int
815
+
816
+ Detonate(FFI::Pointer::NULL, :GetDC,
817
+ nil
818
+ ).tap { |hdc|
819
+ DPIX = GetDeviceCaps(hdc, LOGPIXELSX)
820
+ DPIY = GetDeviceCaps(hdc, LOGPIXELSY)
821
+
822
+ ReleaseDC(nil, hdc)
823
+ }
824
+
825
+ def DPIScaleX(x)
826
+ MulDiv(x, DPIX, 96)
827
+ end
828
+
829
+ def DPIScaleY(y)
830
+ MulDiv(y, DPIY, 96)
831
+ end
832
+
833
+ def DPIScale(*args)
834
+ case args.length
835
+ when 2 # POINT, SIZE
836
+ [DPIScaleX(args[0]), DPIScaleY(args[1])]
837
+ when 4 # RECT
838
+ [
839
+ DPIScaleX(args[0]), DPIScaleY(args[1]),
840
+ DPIScaleX(args[2]), DPIScaleY(args[3])
841
+ ]
842
+ else
843
+ raise ArgumentError
844
+ end
845
+ end
846
+
847
+ module_function :DPIScaleX, :DPIScaleY, :DPIScale
848
+
734
849
  class PAINTSTRUCT < FFI::Struct
735
850
  layout \
736
851
  :hdc, :pointer,
@@ -828,14 +943,14 @@ module WinGUI
828
943
  WM_APP = 0x8000
829
944
  #}
830
945
 
831
- attach_function :SendMessage, :SendMessageA, [
946
+ attach_function :SendMessage, :SendMessageW, [
832
947
  :pointer,
833
948
  :uint,
834
949
  :uint,
835
950
  :long
836
951
  ], :long
837
952
 
838
- attach_function :PostMessage, :PostMessageA, [
953
+ attach_function :PostMessage, :PostMessageW, [
839
954
  :pointer,
840
955
  :uint,
841
956
  :uint,
@@ -852,7 +967,7 @@ module WinGUI
852
967
  :pt, POINT
853
968
  end
854
969
 
855
- attach_function :GetMessage, :GetMessageA, [
970
+ attach_function :GetMessage, :GetMessageW, [
856
971
  :pointer,
857
972
  :pointer,
858
973
  :uint,
@@ -864,7 +979,7 @@ module WinGUI
864
979
  :pointer
865
980
  ], :int
866
981
 
867
- attach_function :TranslateAccelerator, :TranslateAcceleratorA, [
982
+ attach_function :TranslateAccelerator, :TranslateAcceleratorW, [
868
983
  :pointer,
869
984
  :pointer,
870
985
  :pointer
@@ -874,7 +989,7 @@ module WinGUI
874
989
  :pointer
875
990
  ], :int
876
991
 
877
- attach_function :DispatchMessage, :DispatchMessageA, [
992
+ attach_function :DispatchMessage, :DispatchMessageW, [
878
993
  :pointer
879
994
  ], :long
880
995
 
@@ -913,11 +1028,11 @@ module WinGUI
913
1028
  MF_UNHILITE = 0x00000000
914
1029
  #}
915
1030
 
916
- attach_function :AppendMenu, :AppendMenuA, [
1031
+ attach_function :AppendMenu, :AppendMenuW, [
917
1032
  :pointer,
918
1033
  :uint,
919
1034
  :uint,
920
- :string
1035
+ :buffer_in
921
1036
  ], :int
922
1037
 
923
1038
  #{ MF_xxx
@@ -972,7 +1087,7 @@ module WinGUI
972
1087
  :cmd, :ushort
973
1088
  end
974
1089
 
975
- attach_function :CreateAcceleratorTable, :CreateAcceleratorTableA, [
1090
+ attach_function :CreateAcceleratorTable, :CreateAcceleratorTableW, [
976
1091
  :pointer,
977
1092
  :int
978
1093
  ], :pointer
@@ -1010,7 +1125,7 @@ module WinGUI
1010
1125
  SPI_GETNONCLIENTMETRICS = 0x0029
1011
1126
  #}
1012
1127
 
1013
- attach_function :SystemParametersInfo, :SystemParametersInfoA, [
1128
+ attach_function :SystemParametersInfo, :SystemParametersInfoW, [
1014
1129
  :uint,
1015
1130
  :uint,
1016
1131
  :pointer,
metadata CHANGED
@@ -1,46 +1,34 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ffi-wingui-core
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 0
9
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease: !!null
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Radoslav Peev
13
- autorequire:
9
+ autorequire: !!null
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-01-26 00:00:00 +02:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-02-01 00:00:00.000000000 +02:00
13
+ default_executable: !!null
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
21
16
  name: ffi
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &22547748 !ruby/object:Gem::Requirement
24
18
  none: false
25
- requirements:
19
+ requirements:
26
20
  - - ~>
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 1
30
- - 0
31
- - 5
21
+ - !ruby/object:Gem::Version
32
22
  version: 1.0.5
33
23
  type: :runtime
34
- version_requirements: *id001
35
- description:
36
- email:
24
+ prerelease: false
25
+ version_requirements: *22547748
26
+ description: !!null
27
+ email: !!null
37
28
  executables: []
38
-
39
29
  extensions: []
40
-
41
30
  extra_rdoc_files: []
42
-
43
- files:
31
+ files:
44
32
  - lib/ffi-wingui-core.rb
45
33
  - examples/Command.rbw
46
34
  - examples/Hello.rbw
@@ -52,34 +40,26 @@ files:
52
40
  has_rdoc: true
53
41
  homepage: http://github.com/rpeev/ffi-wingui-core
54
42
  licenses: []
55
-
56
- post_install_message:
43
+ post_install_message: !!null
57
44
  rdoc_options: []
58
-
59
- require_paths:
45
+ require_paths:
60
46
  - lib
61
- required_ruby_version: !ruby/object:Gem::Requirement
47
+ required_ruby_version: !ruby/object:Gem::Requirement
62
48
  none: false
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- segments:
67
- - 0
68
- version: "0"
69
- required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
54
  none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- segments:
75
- - 0
76
- version: "0"
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
77
59
  requirements: []
78
-
79
- rubyforge_project:
80
- rubygems_version: 1.3.7
81
- signing_key:
60
+ rubyforge_project: !!null
61
+ rubygems_version: 1.5.0
62
+ signing_key: !!null
82
63
  specification_version: 3
83
64
  summary: Ruby-FFI bindings to essential GUI-related Windows APIs
84
65
  test_files: []
85
-