implement button onclick event (win32)

Thu, 09 Oct 2025 18:49:19 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 09 Oct 2025 18:49:19 +0200
changeset 825
1bac7e45712b
parent 824
a0ea8f3aa6e8
child 827
eae5b817aa47

implement button onclick event (win32)

application/main.c file | annotate | diff | comparison | revisions
ui/win32/button.c file | annotate | diff | comparison | revisions
ui/win32/button.h file | annotate | diff | comparison | revisions
ui/win32/toolkit.h file | annotate | diff | comparison | revisions
ui/win32/win32.c file | annotate | diff | comparison | revisions
ui/win32/window.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Thu Oct 09 18:24:09 2025 +0200
+++ b/application/main.c	Thu Oct 09 18:49:19 2025 +0200
@@ -1135,13 +1135,17 @@
 
 #ifdef UI_WIN32
 
+static void action_button(UiEvent *event, void *data) {
+    printf("button clicked\n");
+}
+
 void application_startup(UiEvent *event, void *data) {
 	UiObject *obj = ui_window("Test w32", NULL);
     ui_button(obj, .label = "Test", .hfill = TRUE, .hexpand = TRUE, .colspan = 3, .margin = 10);
     ui_button(obj, .label = "Test 2-1", .margin_left = 10);
     ui_button(obj, .label = "Test 2-2", .hfill = TRUE, .hexpand = TRUE, .margin_left = 20);
     ui_button(obj, .label = "Test 2-3", .margin_left = 30);
-    ui_button(obj, .label = "Test 3XX", .colspan = 3, .fill = TRUE);
+    ui_button(obj, .label = "Test 3XX", .colspan = 3, .fill = TRUE, .onclick = action_button);
 	ui_show(obj);
 }
 
--- a/ui/win32/button.c	Thu Oct 09 18:24:09 2025 +0200
+++ b/ui/win32/button.c	Thu Oct 09 18:49:19 2025 +0200
@@ -29,7 +29,11 @@
 #include "button.h"
 #include "widget.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+
 static W32WidgetClass button_widget_class = {
+    .eventproc = ui_button_eventproc,
     .enable = w32_widget_default_enable,
     .show = w32_widget_default_show,
     .get_preferred_size = ui_button_get_preferred_size,
@@ -53,9 +57,14 @@
             NULL);
     ui_win32_set_ui_font(hwnd);
 
-    W32Widget *widget = w32_widget_create(&button_widget_class, hwnd, sizeof(UiButton));
+    W32Widget *widget = w32_widget_create(&button_widget_class, hwnd, sizeof(UiWidget));
     ui_container_add(container, widget, &layout);
 
+    UiWidget *btn = (UiWidget*)widget;
+    btn->obj = obj;
+    btn->callback = args->onclick;
+    btn->callbackdata = args->onclickdata;
+
     return widget;
 }
 
@@ -65,3 +74,20 @@
     size.height = 30;
     return size;
 }
+
+void ui_button_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+    UiWidget *w = (UiWidget*)widget;
+
+    UiEvent e;
+    e.obj = w->obj;
+    e.document = e.obj->ctx->document;
+    e.window = e.obj->window;
+    e.eventdata = NULL;
+    e.eventdatatype = 0;
+    e.intval = 0;
+    e.set = ui_get_setop();
+
+    if (w->callback) {
+        w->callback(&e, w->callbackdata);
+    }
+}
--- a/ui/win32/button.h	Thu Oct 09 18:24:09 2025 +0200
+++ b/ui/win32/button.h	Thu Oct 09 18:49:19 2025 +0200
@@ -32,10 +32,8 @@
 #include "../ui/button.h"
 #include "container.h"
 
-typedef struct UiButton {
-    W32Widget widget;
-} UiButton;
-
 W32Size ui_button_get_preferred_size(W32Widget *widget);
 
+void ui_button_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
 #endif //BUTTON_H
--- a/ui/win32/toolkit.h	Thu Oct 09 18:24:09 2025 +0200
+++ b/ui/win32/toolkit.h	Thu Oct 09 18:49:19 2025 +0200
@@ -40,6 +40,19 @@
 extern "C" {
 #endif
 
+/*
+ * widget struct that can be used for most primitive widgets,
+ * like buttons, checkboxes
+ */
+typedef struct UiWidget {
+    W32Widget widget;
+    UiObject *obj;
+    UiVar *var;
+    ui_callback callback;
+    void *callbackdata;
+    int64_t intvalue;
+} UiWidget;
+
 HFONT ui_win32_get_font(void);
 void ui_win32_set_ui_font(HWND control);
 
--- a/ui/win32/win32.c	Thu Oct 09 18:24:09 2025 +0200
+++ b/ui/win32/win32.c	Thu Oct 09 18:49:19 2025 +0200
@@ -35,7 +35,7 @@
 }
 
 void* w32_widget_create(W32WidgetClass *wclass, HWND hwnd, size_t obj_size) {
-    W32Widget *w = malloc(obj_size);
+    W32Widget *w = calloc(obj_size, 1);
     w->wclass = wclass;
     w->hwnd = hwnd;
     SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)w);
--- a/ui/win32/window.c	Thu Oct 09 18:24:09 2025 +0200
+++ b/ui/win32/window.c	Thu Oct 09 18:49:19 2025 +0200
@@ -58,11 +58,18 @@
 		widget->wclass->eventproc(widget, hwnd, uMsg, wParam, lParam);
 	}
     switch(uMsg) {
-        case WM_DESTROY:
-            PostQuitMessage(0);
-            break;
-        default:
-            return DefWindowProc(hwnd, uMsg, wParam, lParam);
+        case WM_DESTROY: {
+	        PostQuitMessage(0);
+        	break;
+        }
+		case WM_COMMAND: {
+        	HWND hwndCtrl = (HWND)lParam;
+        	W32Widget *cmdWidget = (W32Widget*)GetWindowLongPtr(hwndCtrl, GWLP_USERDATA);
+        	if (cmdWidget && cmdWidget->wclass->eventproc) {
+        		cmdWidget->wclass->eventproc(cmdWidget, hwnd, uMsg, wParam, lParam);
+        	}
+        }
+        default: return DefWindowProc(hwnd, uMsg, wParam, lParam);
     }
     return 0;
 }

mercurial