Skip to content

Commit 0e286fd

Browse files
authored
Merge pull request #51 from mjblack/updates_for_winmd_changes
Updates for winmd changes
2 parents 79b261a + 85fde0b commit 0e286fd

317 files changed

Lines changed: 86853 additions & 375 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/crystal.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,9 @@ jobs:
6666
shell: pwsh
6767
run: |
6868
& "$env:LOCALAPPDATA\Programs\Crystal\crystal.exe" spec --error-trace --debug
69+
- name: Setup tmate session
70+
uses: mxschmitt/action-tmate@v3
71+
with:
72+
limit-access-to-actor: true
73+
timeout-minutes: 15
74+
if: ${{ failure() }}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ For more examples, please see the [examples](https://github.com/mjblack/win32cr/
2828
require "win32cr"
2929
require "win32cr/ui/windows_and_messaging"
3030
31-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, "Message Box Body".to_utf16, "Title".to_utf16, Win32cr::UI::WindowsAndMessaging::::MESSAGEBOX_STYLE::MB_OK)
31+
alias WM = Win32cr::UI::WindowsAndMessaging # Simplifies code
32+
WM.messageBoxW(Pointer(Void).null, pwstr("Message Box Body"), pwstr("Title"), WM::MESSAGEBOX_STYLE::MB_OK)
3233
```
3334

3435
## Contributing

examples/textbox.cr

Lines changed: 114 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,44 @@ require "../src/win32cr/ui/shell"
44
require "../src/win32cr/ui/input/keyboard_and_mouse"
55
require "../src/win32cr/system/library_loader"
66

7+
alias Fd = Win32cr::Foundation
8+
alias WM = Win32cr::UI::WindowsAndMessaging
9+
alias UIShell = Win32cr::UI::Shell
10+
alias LibLoad = Win32cr::System::LibraryLoader
11+
alias GDI = Win32cr::Graphics::Gdi
12+
alias KM = Win32cr::UI::Input::KeyboardAndMouse
13+
14+
NULL = Pointer(Void).null
715

816
module Crystal
917
def self.exit(status : Int32, exception : Exception?) : Int32
1018
status = Crystal::AtExitHandlers.run status, exception
1119

1220
if exception
13-
title = "Unhandled Exception".to_utf16
14-
message = exception.inspect_with_backtrace.to_utf16
15-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, message, title, Win32cr::UI::WindowsAndMessaging::MESSAGEBOX_STYLE::MB_OK)
21+
title = pwstr("Unhandled Exception")
22+
message = pwstr(exception.inspect_with_backtrace)
23+
WM.messageBoxW(NULL, message, title, WM::MESSAGEBOX_STYLE::MB_ICONERROR)
1624
end
1725

1826
status
1927
end
2028
end
2129

2230
module AppData
23-
class_property hInstance : Win32cr::Foundation::HINSTANCE = Pointer(Void).null
31+
class_property hInstance : Fd::HINSTANCE = Pointer(Void).null
2432
class_property hPrevInstance : Void*?
25-
class_property hwnd : Win32cr::Foundation::HWND = Win32cr::Foundation::HWND.malloc(sizeof(Win32cr::Foundation::HWND))
26-
class_property hwndEdit : Win32cr::Foundation::HWND = Win32cr::Foundation::HWND.malloc(sizeof(Win32cr::Foundation::HWND))
33+
class_property hwnd : Fd::HWND = Fd::HWND.malloc(sizeof(Fd::HWND))
34+
class_property hwndEdit : Fd::HWND = Fd::HWND.malloc(sizeof(Fd::HWND))
2735

28-
def self.hwdEdit : Win32cr::Foundation::HWND
29-
if h = @@hwndEdit
30-
h
31-
else
36+
def self.hwdEdit : Fd::HWND
37+
if @@hwndEdit.nil?
3238
raise Exception.new("hwndEdit was nil!")
3339
end
40+
h = @@hwndEdit.not_nil!
41+
h
3442
end
3543
end
3644

37-
def loword(i : UInt64) : UInt16
38-
val = (i & 0xffff).to_u16
39-
val
40-
end
41-
42-
def loword(i : Int64) : UInt16
43-
val = (i.to_u64 & 0xffff).to_u16
44-
val
45-
end
46-
47-
def hiword(i : UInt32*) : UInt16
48-
val = ((i.value >> 16) & 0xFFFF).to_u16
49-
val
50-
end
51-
52-
def hiword(i : Int64*) : UInt16
53-
val = ((i.value.to_u64 >> 16) & 0xFFFF).to_u16
54-
val
55-
end
56-
5745
IDC_WIN_CLASS1 = 100
5846

5947
MNU_MAIN_FILE = 101
@@ -72,92 +60,99 @@ ID_EDIT_BOX = 600
7260
nARGV = Array.new(ARGC_UNSAFE) do |i|
7361
String.new(ARGV_UNSAFE[i])
7462
end
75-
pARGV = (PROGRAM_NAME + " " + nARGV.join(" ")).to_utf16
63+
pARGV = pwstr((PROGRAM_NAME + " " + nARGV.join(" ") + "\0"))
7664

77-
winARGV = Win32cr::UI::Shell::C.CommandLineToArgvW(pARGV, out winARGC)
78-
hInstance = Win32cr::System::LibraryLoader::C.GetModuleHandleW(nil)
79-
if hInstance.null?
80-
puts "Failed to get module handle"
81-
exit 1
82-
end
83-
HINSTANCE = hInstance
65+
winARGC = 0
66+
winARGV = UIShell.commandLineToArgvW(pARGV, pointerof(winARGC))
67+
68+
hInstance = LibLoad.getModuleHandleW(Pointer(UInt16).null)
69+
G_HINSTANCE = hInstance
8470
hPrevInstance = Pointer(Void).null
8571
AppData.hInstance = hInstance
8672
AppData.hPrevInstance = hPrevInstance
87-
CLASS_NAME = "WIN_CLASS1".to_utf16
88-
MENU_NAME = "ExampleWindow".to_utf16
89-
APP_NAME = "Simple Window".to_utf16
73+
CLASS_NAME = pwstr("WIN_CLASS1")
74+
MENU_NAME = pwstr("ExampleWindow")
75+
APP_NAME = pwstr("Simple Window")
9076

91-
def winproc(hwnd : Win32cr::Foundation::HWND, uMsg : UInt32, wParam : Win32cr::Foundation::WPARAM, lParam : Win32cr::Foundation::LPARAM) : Win32cr::Foundation::LRESULT
77+
def winproc(hwnd : Fd::HWND, uMsg : UInt32, wParam : Fd::WPARAM, lParam : Fd::LPARAM) : Fd::LRESULT
9278
lresult = 0_i64
9379
case uMsg
94-
when Win32cr::UI::WindowsAndMessaging::WM_CREATE
95-
hMenu = Win32cr::UI::WindowsAndMessaging::C.CreateMenu
96-
hFileMenu = Win32cr::UI::WindowsAndMessaging::C.CreatePopupMenu
80+
when WM::WM_CREATE
81+
hMenu = WM.createMenu
82+
hFileMenu = WM.createPopupMenu
9783

98-
Win32cr::UI::WindowsAndMessaging::C.AppendMenuW(hFileMenu, Win32cr::UI::WindowsAndMessaging::MENU_ITEM_FLAGS::MF_STRING, MNU_ITEM_FILE_QUIT, "E&xit".to_utf16)
99-
Win32cr::UI::WindowsAndMessaging::C.AppendMenuW(hMenu, Win32cr::UI::WindowsAndMessaging::MENU_ITEM_FLAGS::MF_POPUP, hFileMenu.unsafe_as(LibC::UINT_PTR), "&File".to_utf16)
84+
WM.appendMenuW(hFileMenu, :mf_string, MNU_ITEM_FILE_QUIT, pwstr("E&xit"))
85+
WM.appendMenuW(hMenu, :mf_popup, hFileMenu.unsafe_as(LibC::UINT_PTR), pwstr("&File"))
10086

101-
if Win32cr::UI::WindowsAndMessaging::C.SetMenu(hwnd, hMenu) == 0
87+
if WM.setMenu(hwnd, hMenu) == 0
10288
if (err = LibC.GetLastError) > 0
103-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, "Got error #{err}".to_utf16, "winapp log".to_utf16, Win32cr::UI::WindowsAndMessaging::MESSAGEBOX_STYLE::MB_OK)
89+
WM.messageBoxW(Pointer(Void).null, pwstr("Got error #{err}"), pwstr("winapp log"), WM::MESSAGEBOX_STYLE::MB_ICONERROR)
10490
end
10591
end
10692

107-
if Win32cr::UI::WindowsAndMessaging::C.SetMenu(hwnd, hMenu) == 0
93+
if WM.setMenu(hwnd, hMenu) == 0
10894
if (err = LibC.GetLastError) > 0
109-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, "Got error #{err}".to_utf16, "winapp log".to_utf16, Win32cr::UI::WindowsAndMessaging::MESSAGEBOX_STYLE::MB_OK)
95+
WM.messageBoxW(Pointer(Void).null, pwstr("Got error #{err}"), pwstr("winapp log"), WM::MESSAGEBOX_STYLE::MB_ICONERROR)
11096
end
11197
end
11298

113-
hwndEdit = Win32cr::UI::WindowsAndMessaging::C.CreateWindowExW(
114-
Win32cr::UI::WindowsAndMessaging::WINDOW_EX_STYLE::WS_EX_LEFT, # Optional window styles
115-
"EDIT".to_utf16, # Window class
116-
nil, # Application Name
117-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_CHILD |
118-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_VISIBLE |
119-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_BORDER |
120-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_HSCROLL |
121-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_VSCROLL |
122-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_CHILDWINDOW,
123-
# Size and position
99+
hwndEdit = WM.createWindowExW(
100+
WM::WINDOW_EX_STYLE::WS_EX_LEFT.value, # Optional window styles
101+
pwstr("EDIT"), # Window class
102+
Pointer(UInt16).null, # Application Name
103+
WM::WINDOW_STYLE[:ws_child, :ws_visible,
104+
:ws_border, :ws_hscroll,
105+
:ws_vscroll, :ws_childwindow].value,
106+
# Size and position
124107
10,
125108
10,
126109
100,
127110
50,
128-
hwnd, # Parent window
129-
0_i64, # Menu
130-
lParam.unsafe_as(Pointer(Win32cr::UI::WindowsAndMessaging::CREATESTRUCTW)).value.hInstance, # Instance handle
131-
nil # Additional application data
111+
hwnd, # Parent window
112+
0_i64, # Menu
113+
lParam.unsafe_as(Pointer(WM::CREATESTRUCTW)).value.hInstance, # Instance handle
114+
Pointer(Void).null # Additional application data
132115
)
133116

134117
if (err = LibC.GetLastError) > 0
135-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, "Got error #{err}".to_utf16, "winapp log".to_utf16, Win32cr::UI::WindowsAndMessaging::MESSAGEBOX_STYLE::MB_OK)
118+
WM.messageBoxW(Pointer(Void).null, pwstr("Got error #{err}"), pwstr("winapp log"), WM::MESSAGEBOX_STYLE::MB_ICONERROR)
136119
end
137120
AppData.hwndEdit = hwndEdit
138-
when Win32cr::UI::WindowsAndMessaging::WM_SETFOCUS
139-
Win32cr::UI::Input::KeyboardAndMouse::C.SetFocus(AppData.hwndEdit.not_nil!)
140-
when Win32cr::UI::WindowsAndMessaging::WM_SIZE
141-
Win32cr::UI::WindowsAndMessaging::C.MoveWindow(AppData.hwndEdit.unsafe_as(Win32cr::Foundation::HWND), 0, 0, loword(lParam), hiword(pointerof(lParam)), 1)
142-
when Win32cr::UI::WindowsAndMessaging::WM_COMMAND
121+
when WM::WM_SETFOCUS
122+
KM.setFocus(AppData.hwndEdit.not_nil!)
123+
when WM::WM_SIZE
124+
WM.moveWindow(AppData.hwndEdit.unsafe_as(Fd::HWND), 0, 0, loword(lParam), hiword(pointerof(lParam)), 1)
125+
when WM::WM_COMMAND
143126
case loword(wParam)
144127
when MNU_ITEM_FILE_QUIT
145-
Win32cr::UI::WindowsAndMessaging::C.PostMessageW(hwnd, Win32cr::UI::WindowsAndMessaging::WM_CLOSE, 0_u64, 0_i64)
128+
WM.postMessageW(hwnd, WM::WM_CLOSE, 0_u64, 0_i64)
146129
end
147-
when Win32cr::UI::WindowsAndMessaging::WM_CLOSE, Win32cr::UI::WindowsAndMessaging::WM_QUIT
148-
Win32cr::UI::WindowsAndMessaging::C.DestroyWindow(hwnd)
149-
Win32cr::UI::WindowsAndMessaging::C.PostQuitMessage(0)
150-
when Win32cr::UI::WindowsAndMessaging::WM_DESTROY
151-
Win32cr::UI::WindowsAndMessaging::C.PostQuitMessage(0)
152-
when Win32cr::UI::WindowsAndMessaging::WM_PAINT
153-
ps = Pointer(Win32cr::Graphics::Gdi::PAINTSTRUCT).malloc(sizeof(Win32cr::Graphics::Gdi::PAINTSTRUCT))
154-
hdc = Win32cr::Graphics::Gdi::C.BeginPaint(hwnd, ps)
155-
psrcPaint = ps.value.rcPaint
156-
Win32cr::Graphics::Gdi::C.FillRect(hdc, pointerof(psrcPaint), (Win32cr::UI::WindowsAndMessaging::SYS_COLOR_INDEX::COLOR_WINDOW + 1).unsafe_as(Win32cr::Graphics::Gdi::HBRUSH))
157-
ps.value.rcPaint = psrcPaint
158-
Win32cr::Graphics::Gdi::C.EndPaint(hwnd, ps)
130+
when WM::WM_CLOSE, WM::WM_QUIT
131+
WM.destroyWindow(hwnd)
132+
WM.postQuitMessage(0)
133+
when WM::WM_DESTROY
134+
WM.postQuitMessage(0)
135+
when WM::WM_PAINT
136+
ps = uninitialized GDI::PAINTSTRUCT
137+
# ps = GDI::PAINTSTRUCT.new(
138+
# hdc: 0,
139+
# fErase: 0,
140+
# fRestore: 0,
141+
# fIncUpdate: 0,
142+
# rcPaint: Fd::RECT.new(
143+
# left: 0,
144+
# top: 0,
145+
# right: 0,
146+
# bottom: 0
147+
# )
148+
# )
149+
hdc = GDI.beginPaint(hwnd, pointerof(ps))
150+
psrcPaint = ps.rcPaint
151+
GDI.fillRect(hdc, pointerof(psrcPaint), (WM::SYS_COLOR_INDEX::COLOR_WINDOW + 1).unsafe_as(GDI::HBRUSH))
152+
ps.rcPaint = psrcPaint
153+
GDI.endPaint(hwnd, pointerof(ps))
159154
else
160-
return Win32cr::UI::WindowsAndMessaging::C.DefWindowProcW(hwnd, uMsg, wParam, lParam)
155+
return WM.defWindowProcW(hwnd, uMsg, wParam, lParam)
161156
end
162157
return lresult
163158
end
@@ -167,63 +162,64 @@ end
167162
icon = 0_i64
168163
cursor = 0_i64
169164

170-
funptr =->winproc(Win32cr::Foundation::HWND, UInt32, Win32cr::Foundation::WPARAM, Win32cr::Foundation::LPARAM)
171-
wc = Win32cr::UI::WindowsAndMessaging::WNDCLASSEXW.new(
172-
cbSize: sizeof(Win32cr::UI::WindowsAndMessaging::WNDCLASSEXW).to_u32,
165+
funptr =->winproc(Fd::HWND, UInt32, Fd::WPARAM, Fd::LPARAM)
166+
wc = WM::WNDCLASSEXW.new(
167+
cbSize: sizeof(WM::WNDCLASSEXW).to_u32,
173168
lpfnWndProc: funptr,
174-
lpszClassName: CLASS_NAME.to_unsafe,
175-
lpszMenuName: Pointer(UInt16).null,
176-
style: Win32cr::UI::WindowsAndMessaging::WNDCLASS_STYLES::CS_HREDRAW | Win32cr::UI::WindowsAndMessaging::WNDCLASS_STYLES::CS_VREDRAW,
169+
lpszClassName: CLASS_NAME,
170+
style: WM::WNDCLASS_STYLES[:cs_hredraw, :cs_vredraw],
177171
cbClsExtra: 0,
178172
cbWndExtra: 0,
179173
hInstance: hInstance,
180174
hIcon: icon,
181175
hCursor: cursor,
182-
hbrBackground: 0_i64,
176+
hbrBackground: (WM::SYS_COLOR_INDEX::COLOR_WINDOW.value + 1),
177+
lpszMenuName: MENU_NAME,
183178
hIconSm: icon
184179
)
185180

186-
if Win32cr::UI::WindowsAndMessaging::C.RegisterClassExW(pointerof(wc)) == 0
181+
if WM.registerClassExW(pointerof(wc)) == 0
187182
err = LibC.GetLastError
188183
raise "window class register failed because #{err}"
189184
exit 1
190185
end
191186

192-
hwnd = Win32cr::UI::WindowsAndMessaging::C.CreateWindowExW(
193-
Win32cr::UI::WindowsAndMessaging::WINDOW_EX_STYLE::WS_EX_LEFT, # Optional window styles
194-
CLASS_NAME, # Window class
195-
APP_NAME, # Application Name
196-
Win32cr::UI::WindowsAndMessaging::WINDOW_STYLE::WS_OVERLAPPEDWINDOW, # Window style
187+
hwnd = WM.createWindowExW(
188+
WM::WINDOW_EX_STYLE::WS_EX_LEFT.value, # Optional window styles
189+
CLASS_NAME, # Window class
190+
APP_NAME, # Application Name
191+
WM::WINDOW_STYLE::WS_OVERLAPPEDWINDOW.value, # Window style
197192

198193
# Size and position
199-
Win32cr::UI::WindowsAndMessaging::CW_USEDEFAULT,
200-
Win32cr::UI::WindowsAndMessaging::CW_USEDEFAULT,
201-
Win32cr::UI::WindowsAndMessaging::CW_USEDEFAULT,
202-
Win32cr::UI::WindowsAndMessaging::CW_USEDEFAULT,
203-
nil, # Parent window
204-
0_i64, # Menu
205-
hInstance, # Instance handle
206-
nil # Additional application data
194+
WM::CW_USEDEFAULT,
195+
WM::CW_USEDEFAULT,
196+
WM::CW_USEDEFAULT,
197+
WM::CW_USEDEFAULT,
198+
Pointer(Void).null, # Parent window
199+
0_i64, # Menu
200+
hInstance, # Instance handle
201+
Pointer(Void).null # Additional application data
207202
)
208203

209204
AppData.hwnd = hwnd
210205

211-
Win32cr::UI::WindowsAndMessaging::C.ShowWindow(hwnd, Win32cr::UI::WindowsAndMessaging::SHOW_WINDOW_CMD::SW_NORMAL)
212-
Win32cr::UI::WindowsAndMessaging::C.DrawMenuBar(hwnd)
213-
Win32cr::Graphics::Gdi::C.UpdateWindow(hwnd)
206+
WM.showWindow(hwnd, :sw_normal)
207+
WM.drawMenuBar(hwnd)
208+
GDI.updateWindow(hwnd)
214209

215-
while (Win32cr::UI::WindowsAndMessaging::C.GetMessageW(out msg, nil, 0, 0) > 0)
216-
pmsg = pointerof(msg)
217-
Win32cr::UI::WindowsAndMessaging::C.TranslateMessage(pmsg)
218-
Win32cr::UI::WindowsAndMessaging::C.DispatchMessageW(pmsg)
219-
if msg.message == Win32cr::UI::WindowsAndMessaging::WM_QUIT
220-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, "Quit called".to_utf16, "Event".to_utf16, Win32cr::UI::WindowsAndMessaging::MESSAGEBOX_STYLE::MB_OK)
210+
msg = Pointer(WM::MSG).malloc(sizeof(WM::MSG))
211+
while (WM.getMessageW(msg, Pointer(Void).null, 0_u32, 0_u32) > 0)
212+
WM.translateMessage(msg)
213+
WM.dispatchMessageW(msg)
214+
if msg.value.message == WM::WM_QUIT
215+
WM.messageBoxW(Pointer(Void).null, pwstr("Quit called"), pwstr("Event"), WM::MESSAGEBOX_STYLE::MB_OK)
221216
break
222217
end
218+
msg.clear(sizeof(WM::MSG))
223219
end
224220

225221
if (err = LibC.GetLastError) > 0
226-
if !err == Win32cr::Foundation::WIN32_ERROR::ERROR_INVALID_WINDOW_HANDLE
227-
Win32cr::UI::WindowsAndMessaging::C.MessageBoxW(nil, "Error code: #{err}".to_utf16, "Exit Error".to_utf16, Win32cr::UI::WindowsAndMessaging::MESSAGEBOX_STYLE::MB_ICONERROR)
222+
if !err == Fd::WIN32_ERROR::ERROR_INVALID_WINDOW_HANDLE
223+
WM.messageBoxW(Pointer(Void).null, pwstr("Error code: #{err}"), pwstr("Exit Error"), WM::MESSAGEBOX_STYLE::MB_ICONERROR)
228224
end
229225
end

0 commit comments

Comments
 (0)