@@ -55,6 +55,7 @@ var hInst: HINSTANCE = undefined;
5555/// anti-aliasing. So we take the real default caption font from
5656/// NONFCLIENTEMETRICS and apply it manually to every widget.
5757var captionFont : win32.HFONT = undefined ;
58+ var monospaceFont : win32.HFONT = undefined ;
5859/// Default arrow cursor used to avoid components keeping the last cursor icon
5960/// that's been set (which is usually the resize cursor or loading cursor)
6061var defaultCursor : win32.HCURSOR = undefined ;
@@ -101,6 +102,23 @@ pub fn init() !void {
101102 win32 .SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS .initFlags (.{}),
102103 );
103104 captionFont = win32 .CreateFontIndirectW (& ncMetrics .lfCaptionFont ).? ;
105+ monospaceFont = @ptrCast (win32 .GetStockObject (win32 .ANSI_FIXED_FONT ));
106+ monospaceFont = win32 .CreateFontW (
107+ ncMetrics .lfCaptionFont .lfHeight ,
108+ ncMetrics .lfCaptionFont .lfWidth ,
109+ 0 ,
110+ 0 ,
111+ win32 .FW_REGULAR ,
112+ 0 ,
113+ 0 ,
114+ 0 ,
115+ win32 .DEFAULT_CHARSET ,
116+ win32 .OUT_DEFAULT_PRECIS ,
117+ win32 .CLIP_DEFAULT_PRECIS ,
118+ win32 .DEFAULT_QUALITY ,
119+ .MODERN ,
120+ _T ("Courier" ),
121+ ).? ;
104122
105123 // Load the default arrow cursor so that components can use it
106124 // This avoids components keeping the last cursor (resize cursor or loading cursor)
@@ -834,6 +852,68 @@ pub const TextField = struct {
834852 }
835853};
836854
855+ pub const TextArea = struct {
856+ peer : HWND ,
857+ arena : std.heap.ArenaAllocator ,
858+
859+ pub usingnamespace Events (TextArea );
860+
861+ pub fn create () ! TextArea {
862+ const hwnd = win32 .CreateWindowExW (win32 .WS_EX_LEFT , // dwExtStyle
863+ _T ("EDIT" ), // lpClassName
864+ _T ("" ), // lpWindowName
865+ @as (win32 .WINDOW_STYLE , @enumFromInt (@intFromEnum (win32 .WS_TABSTOP ) | @intFromEnum (win32 .WS_CHILD ) | @intFromEnum (win32 .WS_BORDER ) | win32 .ES_MULTILINE | win32 .ES_AUTOVSCROLL | win32 .ES_WANTRETURN )), // dwStyle
866+ 0 , // X
867+ 0 , // Y
868+ 100 , // nWidth
869+ 100 , // nHeight
870+ defaultWHWND , // hWindParent
871+ null , // hMenu
872+ hInst , // hInstance
873+ null // lpParam
874+ ) orelse return Win32Error .InitializationError ;
875+ try TextArea .setupEvents (hwnd );
876+ _ = win32 .SendMessageW (hwnd , win32 .WM_SETFONT , @intFromPtr (captionFont ), 1 );
877+
878+ return TextArea { .peer = hwnd , .arena = std .heap .ArenaAllocator .init (lib .internal .lasting_allocator ) };
879+ }
880+
881+ pub fn setText (self : * TextArea , text : []const u8 ) void {
882+ const allocator = lib .internal .scratch_allocator ;
883+ const wide = std .unicode .utf8ToUtf16LeWithNull (allocator , text ) catch return ; // invalid utf8 or not enough memory
884+ defer allocator .free (wide );
885+ if (win32 .SetWindowTextW (self .peer , wide ) == 0 ) {
886+ std .os .windows .unexpectedError (transWinError (win32 .GetLastError ())) catch {};
887+ }
888+
889+ const len = win32 .GetWindowTextLengthW (self .peer );
890+ getEventUserData (self .peer ).last_text_len = len ;
891+ }
892+
893+ pub fn getText (self : * TextArea ) [:0 ]const u8 {
894+ const allocator = self .arena .allocator ();
895+ const len = win32 .GetWindowTextLengthW (self .peer );
896+ var buf = allocator .allocSentinel (u16 , @as (usize , @intCast (len )), 0 ) catch unreachable ; // TODO return error
897+ defer allocator .free (buf );
898+ const realLen = @as (usize , @intCast (win32 .GetWindowTextW (self .peer , buf .ptr , len + 1 )));
899+ const utf16Slice = buf [0.. realLen ];
900+ const text = std .unicode .utf16leToUtf8AllocZ (allocator , utf16Slice ) catch unreachable ; // TODO return error
901+ return text ;
902+ }
903+
904+ pub fn setReadOnly (self : * TextArea , readOnly : bool ) void {
905+ _ = win32 .SendMessageW (self .peer , win32 .EM_SETREADONLY , @intFromBool (readOnly ), undefined );
906+ }
907+
908+ pub fn setMonospaced (self : * TextArea , monospaced : bool ) void {
909+ if (monospaced ) {
910+ _ = win32 .SendMessageW (self .peer , win32 .WM_SETFONT , @intFromPtr (monospaceFont ), 1 );
911+ } else {
912+ _ = win32 .SendMessageW (self .peer , win32 .WM_SETFONT , @intFromPtr (captionFont ), 1 );
913+ }
914+ }
915+ };
916+
837917pub const Button = struct {
838918 peer : HWND ,
839919 arena : std.heap.ArenaAllocator ,
@@ -892,10 +972,10 @@ pub const CheckBox = struct {
892972 pub usingnamespace Events (CheckBox );
893973
894974 pub fn create () ! CheckBox {
895- const hwnd = win32 .CreateWindowEx (win32 .WS_EX_LEFT , // dwExtStyle
896- "BUTTON" , // lpClassName
897- "" , // lpWindowName
898- win32 .WS_TABSTOP | win32 .WS_CHILD | win32 .BS_AUTOCHECKBOX , // dwStyle
975+ const hwnd = win32 .CreateWindowExW (win32 .WS_EX_LEFT , // dwExtStyle
976+ _T ( "BUTTON" ) , // lpClassName
977+ _T ( "" ) , // lpWindowName
978+ @as ( win32 .WINDOW_STYLE , @enumFromInt ( @intFromEnum ( win32 . WS_TABSTOP ) | @intFromEnum ( win32 .WS_CHILD ) | win32 .BS_AUTOCHECKBOX )) , // dwStyle
899979 0 , // X
900980 0 , // Y
901981 100 , // nWidth
@@ -904,7 +984,7 @@ pub const CheckBox = struct {
904984 null , // hMenu
905985 hInst , // hInstance
906986 null // lpParam
907- );
987+ ) orelse return Win32Error . InitializationError ;
908988 try CheckBox .setupEvents (hwnd );
909989 _ = win32 .SendMessageW (hwnd , win32 .WM_SETFONT , @intFromPtr (captionFont ), 1 );
910990
@@ -926,14 +1006,17 @@ pub const CheckBox = struct {
9261006
9271007 pub fn setChecked (self : * CheckBox , checked : bool ) void {
9281008 const state : win32.WPARAM = switch (checked ) {
929- true = > win32 .BST_CHECKED ,
930- false = > win32 .BST_UNCHECKED ,
1009+ true = > @intFromEnum ( win32 .BST_CHECKED ) ,
1010+ false = > @intFromEnum ( win32 .BST_UNCHECKED ) ,
9311011 };
9321012 _ = win32 .SendMessageW (self .peer , win32 .BM_SETCHECK , state , 0 );
9331013 }
9341014
9351015 pub fn isChecked (self : * CheckBox ) bool {
936- return win32 .SendMessageW (self .peer , win32 .BM_GETCHECK , 0 , 0 ) != win32 .BST_UNCHECKED ;
1016+ const state : win32.DLG_BUTTON_CHECK_STATE = @enumFromInt (
1017+ win32 .SendMessageW (self .peer , win32 .BM_GETCHECK , 0 , 0 ),
1018+ );
1019+ return state != win32 .BST_UNCHECKED ;
9371020 }
9381021};
9391022
0 commit comments