@@ -4,56 +4,44 @@ require "../src/win32cr/ui/shell"
44require " ../src/win32cr/ui/input/keyboard_and_mouse"
55require " ../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
816module 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
2028end
2129
2230module 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
3543end
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-
5745IDC_WIN_CLASS1 = 100
5846
5947MNU_MAIN_FILE = 101
@@ -72,92 +60,99 @@ ID_EDIT_BOX = 600
7260nARGV = Array .new(ARGC_UNSAFE ) do |i |
7361 String .new(ARGV_UNSAFE [i])
7462end
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
8470hPrevInstance = Pointer (Void ).null
8571AppData .hInstance = hInstance
8672AppData .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
163158end
@@ -167,63 +162,64 @@ end
167162icon = 0 _i64
168163cursor = 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
190185end
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
209204AppData .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 ))
223219end
224220
225221if (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
229225end
0 commit comments