changeset 2882:99311a9091af

C++: Add lambda support via Connect functions on C++11, on older compilers use traditional function pointers instead. Also added inital menu support although it is incomplete as of this commit.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 22 Dec 2022 13:59:46 +0000
parents ac404083dc6b
children d301fed4bc23
files dw.hpp dwtestoo.cpp
diffstat 2 files changed, 343 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/dw.hpp	Thu Dec 22 13:57:38 2022 +0000
+++ b/dw.hpp	Thu Dec 22 13:59:46 2022 +0000
@@ -9,7 +9,9 @@
 
 // Attempt to support compilers without nullptr type literal
 #if __cplusplus >= 201103L
+#define DW_CPP11
 #define DW_NULL nullptr
+#include <functional>
 #else
 #define DW_NULL NULL
 #endif
@@ -22,6 +24,12 @@
 namespace DW 
 {
 
+// Forward declare these so they can be referenced
+class Render;
+class Pixmap;
+class MenuItem;
+
+
 // Base handle class which allows opaque access to 
 // The base system handles
 class Handle 
@@ -105,18 +113,115 @@
 // That way we can skip adding unused signal handlers
 #define IsOverridden(a, b) true
 
+// Base class for several types of widgets including buttons and menu items
+class Clickable : virtual public Widget
+{
+private:
+    bool ClickedConnected;
+#ifdef DW_CPP11
+    std::function<int()> _ConnectClicked;
+#else
+    int (*_ConnectClicked)();
+#endif
+    static int _OnClicked(HWND window, void *data) { 
+        if(reinterpret_cast<Clickable *>(data)->_ConnectClicked) 
+            return reinterpret_cast<Clickable *>(data)->_ConnectClicked();
+        return reinterpret_cast<Clickable *>(data)->OnClicked(); }
+protected:
+    void Setup() {	
+        if(IsOverridden(Clickable::OnClicked, this)) {
+            dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this);
+            ClickedConnected = true;
+        }
+    }
+    // Our signal handler functions to be overriden...
+    // If they are not overridden and an event is generated, remove the unused handler
+    virtual int OnClicked() {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED);
+        ClickedConnected = false;
+        return FALSE;
+    }
+public:
+#ifdef DW_CPP11
+    void ConnectClicked(std::function<int()> userfunc)
+#else
+    void ConnectClicked(int (*userfunc)())
+#endif
+    {
+        _ConnectClicked = userfunc;
+        if(!ClickedConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this);
+            ClickedConnected = true;
+        }
+    }
+};
+
+class Menus : public Handle
+{
+protected:
+    void SetHMENUI(HMENUI newmenu) { 
+        menu = newmenu; 
+        SetHandle(reinterpret_cast<void *>(newmenu));
+    }
+    HMENUI menu; 
+public:
+    // User functions
+    HMENUI GetHMENUI() { return menu; }
+};
+
+class Menu : public Menus
+{
+public:
+    // Constructors
+    Menu(HWND location) { SetHMENUI(dw_menubar_new(location)); }
+    Menu(unsigned long id) { SetHMENUI(dw_menu_new(id)); }
+    Menu() { SetHMENUI(dw_menu_new(0)); }
+};
+
+class MenuItem : public Clickable
+{
+public:
+    // Constructors
+    MenuItem(Menus *menu, const char *title, unsigned long id, unsigned long flags, int end, int check, Menus *submenu) { 
+        SetHWND(dw_menu_append_item(menu->GetHMENUI(), title, id, flags, end, check, submenu ? submenu->GetHMENUI() : DW_NULL)); 
+    }
+
+    // User functions
+    void SetState(unsigned long flags) { dw_window_set_style(hwnd, flags, flags); }
+    void SetStyle(unsigned long flags, unsigned long mask) { dw_window_set_style(hwnd, flags, mask); }
+};
+
 // Top-level window class is packable
 class Window : public Boxes
 {
 private:
+    bool DeleteConnected, ConfigureConnected;
+#ifdef DW_CPP11
+    std::function<int()> _ConnectDelete;
+    std::function<int(int, int)> _ConnectConfigure;
+#else
+    int (*_ConnectDelete)();
+    int (*_ConnectConfigure)(int width, int height);
+#endif
     void Setup() {	
-        if(IsOverridden(Window::OnDelete, this))
+        if(IsOverridden(Window::OnDelete, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this);
-        if(IsOverridden(Window::OnConfigure, this))
+            DeleteConnected = true;
+        }
+        if(IsOverridden(Window::OnConfigure, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
+            ConfigureConnected = true;
+        }
     }
-    static int _OnDelete(HWND window, void *data) { return reinterpret_cast<Window *>(data)->OnDelete(); }
-    static int _OnConfigure(HWND window, int width, int height, void *data) { return reinterpret_cast<Window *>(data)->OnConfigure(width, height); }
+    static int _OnDelete(HWND window, void *data) { 
+        if(reinterpret_cast<Window *>(data)->_ConnectDelete)
+            return reinterpret_cast<Window *>(data)->_ConnectDelete();
+        return reinterpret_cast<Window *>(data)->OnDelete(); }
+    static int _OnConfigure(HWND window, int width, int height, void *data) { 
+        if(reinterpret_cast<Window *>(data)->_ConnectConfigure)
+            return reinterpret_cast<Window *>(data)->_ConnectConfigure(width, height);
+        return reinterpret_cast<Window *>(data)->OnConfigure(width, height); }
+    Menu *menu;
 public:
     // Constructors
     Window(HWND owner, const char *title, unsigned long style) { SetHWND(dw_window_new(owner, title, style)); Setup(); }
@@ -140,11 +245,44 @@
     void Redraw() { dw_window_redraw(hwnd); }
     void Default(Widget *defaultitem) { if(defaultitem) dw_window_default(hwnd, defaultitem->GetHWND()); }
     void SetIcon(HICN icon) { dw_window_set_icon(hwnd, icon); }
+    Menu *MenuBar() { if(menu == DW_NULL) menu = new Menu(hwnd); return menu; }
+#ifdef DW_CPP11
+    void ConnectDelete(std::function<int()> userfunc)
+#else
+    void ConnectDelete(int (*userfunc)()) 
+#endif
+    {
+        _ConnectDelete = userfunc;
+        if(!DeleteConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this);
+            DeleteConnected = true;
+        }
+    }
+#ifdef DW_CPP11
+    void ConnectConfigure(std::function<int(int, int)> userfunc)
+#else
+    void ConnectConfigure(int (*userfunc)(int, int)) 
+#endif
+    {
+        _ConnectConfigure = userfunc;
+        if(!ConfigureConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
+            ConfigureConnected = true;
+        }
+    }    
 protected:
     // Our signal handler functions to be overriden...
     // If they are not overridden and an event is generated, remove the unused handler
-    virtual int OnDelete() { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_DELETE); return FALSE; }
-    virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; };
+    virtual int OnDelete() {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_DELETE);
+        DeleteConnected = false;
+        return FALSE;
+    }
+    virtual int OnConfigure(int width, int height) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE);
+        ConfigureConnected = false;
+        return FALSE;
+    };
 };
 
 // Class for focusable widgets
@@ -156,23 +294,8 @@
     void SetFocus() { dw_window_set_focus(hwnd); }
 };
 
-// Base class for several types of buttons
-class Buttons : virtual public Focusable
-{
-private:
-    static int _OnClicked(HWND window, void *data) { return reinterpret_cast<Buttons *>(data)->OnClicked(); }
-protected:
-    void Setup() {	
-        if(IsOverridden(Buttons::OnClicked, this))
-            dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this);
-    }
-    // Our signal handler functions to be overriden...
-    // If they are not overridden and an event is generated, remove the unused handler
-    virtual int OnClicked() { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED); return FALSE; }
-};
-
 // Text based button
-class TextButton : public Buttons
+class TextButton : public Clickable, public Focusable
 {
 public:
     // User functions
@@ -191,7 +314,7 @@
 };
 
 // Image based button
-class BitmapButton : public Buttons
+class BitmapButton : public Clickable, public Focusable
 {
 public:
     // Constructors
@@ -293,10 +416,6 @@
 };
 
 
-// Forward declare these so our Drawable abstract class can reference
-class Render;
-class Pixmap;
-
 // Abstract class that defines drawing, either to screen or picture (pixmap)
 class Drawable
 {
@@ -319,14 +438,32 @@
 class Render : public Drawable, public Widget
 {
 private:
+    bool ExposeConnected, ConfigureConnected;
+#ifdef DW_CPP11
+    std::function<int(DWExpose *)> _ConnectExpose;
+    std::function<int(int, int)> _ConnectConfigure;
+#else
+    int (*_ConnectExpose)(DWExpose *);
+    int (*_ConnectConfigure)(int width, int height);
+#endif
     void Setup() {	
-        if(IsOverridden(Render::OnExpose, this))
+        if(IsOverridden(Render::OnExpose, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this);
-        if(IsOverridden(Render::OnConfigure, this))
+            ExposeConnected = true;
+        }
+        if(IsOverridden(Render::OnConfigure, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
+            ConfigureConnected = true;
+        }
     }
-    static int _OnExpose(HWND window, DWExpose *exp, void *data) { return reinterpret_cast<Render *>(data)->OnExpose(exp); }
-    static int _OnConfigure(HWND window, int width, int height, void *data) { return reinterpret_cast<Render *>(data)->OnConfigure(width, height); }
+    static int _OnExpose(HWND window, DWExpose *exp, void *data) {
+        if(reinterpret_cast<Render *>(data)->_ConnectExpose)
+            return reinterpret_cast<Render *>(data)->_ConnectExpose(exp);
+        return reinterpret_cast<Render *>(data)->OnExpose(exp); }
+    static int _OnConfigure(HWND window, int width, int height, void *data) {
+        if(reinterpret_cast<Render *>(data)->_ConnectConfigure)
+            return reinterpret_cast<Render *>(data)->_ConnectConfigure(width, height);
+        return reinterpret_cast<Render *>(data)->OnConfigure(width, height); }
 public:
     // Constructors
     Render(unsigned long id) { SetHWND(dw_render_new(id)); Setup(); }
@@ -351,11 +488,43 @@
     void GetTextExtents(const char *text, int *width, int *height) { dw_font_text_extents_get(hwnd, DW_NULL, text, width, height); }
     char *GetFont() { return dw_window_get_font(hwnd); }
     void Redraw() { dw_render_redraw(hwnd); }
+#ifdef DW_CPP11
+    void ConnectExpose(std::function<int(DWExpose *)> userfunc)
+#else
+    void ConnectExpose(int (*userfunc)(DWExpose *))
+#endif
+    {
+        _ConnectExpose = userfunc;
+        if(!ExposeConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this);
+            ExposeConnected = true;
+        }
+    }
+#ifdef DW_CPP11
+    void ConnectConfigure(std::function<int(int, int)> userfunc)
+#else
+    void ConnectConfigure(int (*userfunc)(int, int))
+#endif
+    {
+        _ConnectConfigure = userfunc;
+        if(!ConfigureConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this);
+            ConfigureConnected = true;
+        }
+    }    
 protected:
     // Our signal handler functions to be overriden...
     // If they are not overridden and an event is generated, remove the unused handler
-    virtual int OnExpose(DWExpose *exp) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_EXPOSE); return FALSE; }
-    virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; };
+    virtual int OnExpose(DWExpose *exp) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_EXPOSE);
+        ExposeConnected = false;
+        return FALSE;
+    }
+    virtual int OnConfigure(int width, int height) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE);
+        ConfigureConnected = false;
+        return FALSE;
+    };
 };
 
 class Pixmap : public Drawable, public Handle
@@ -410,14 +579,32 @@
 class HTML : public Widget
 {
 private:
+    bool ChangedConnected, ResultConnected;
+#ifdef DW_CPP11
+    std::function<int(int, char *)> _ConnectChanged;
+    std::function<int(int, char *, void *)> _ConnectResult;
+#else
+    int (*_ConnectChanged)(int status, char *url);
+    int (*_ConnectResult)(int status, char *result, void *scriptdata);
+#endif
     void Setup() {	
-        if(IsOverridden(HTML::OnChanged, this))
+        if(IsOverridden(HTML::OnChanged, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this);
-        if(IsOverridden(HTML::OnResult, this))
+            ChangedConnected = true;
+        }
+        if(IsOverridden(HTML::OnResult, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnResult), this);
+            ResultConnected = true;
+        }
     }
-    static int _OnChanged(HWND window, int status, char *url, void *data) { return reinterpret_cast<HTML *>(data)->OnChanged(status, url); }
-    static int _OnResult(HWND window, int status, char *result, void *scriptdata, void *data) { return reinterpret_cast<HTML *>(data)->OnResult(status, result, scriptdata); }
+    static int _OnChanged(HWND window, int status, char *url, void *data) {
+        if(reinterpret_cast<HTML *>(data)->_ConnectChanged)
+            return reinterpret_cast<HTML *>(data)->_ConnectChanged(status, url);
+        return reinterpret_cast<HTML *>(data)->OnChanged(status, url); }
+    static int _OnResult(HWND window, int status, char *result, void *scriptdata, void *data) {
+        if(reinterpret_cast<HTML *>(data)->_ConnectResult)
+            return reinterpret_cast<HTML *>(data)->_ConnectResult(status, result, scriptdata);
+        return reinterpret_cast<HTML *>(data)->OnResult(status, result, scriptdata); }
 public:
     // Constructors
     HTML(unsigned long id) { SetHWND(dw_html_new(id)); Setup(); }
@@ -428,11 +615,43 @@
     int JavascriptRun(const char *script, void *scriptdata) { return dw_html_javascript_run(hwnd, script, scriptdata); }
     int Raw(const char *buffer) { return dw_html_raw(hwnd, buffer); }
     int URL(const char *url) { return dw_html_url(hwnd, url); }
+#ifdef DW_CPP11
+    void ConnectChanged(std::function<int(int, char *)> userfunc)
+#else
+    void ConnectChanged(int (*userfunc)(int, char *))
+#endif
+    { 
+        _ConnectChanged = userfunc;
+        if(!ChangedConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this);
+            ChangedConnected = true;
+        }
+    }
+#ifdef DW_CPP11
+    void ConnectResult(std::function<int(int, char *, void *)> userfunc)
+#else
+    void ConnectResult(int (*userfunc)(int, char *, void *))
+#endif
+    {
+        _ConnectResult = userfunc;
+        if(!ResultConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnResult), this);
+            ResultConnected = true;
+        }
+    }    
 protected:
     // Our signal handler functions to be overriden...
     // If they are not overridden and an event is generated, remove the unused handler
-    virtual int OnChanged(int status, char *url) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_CHANGED); return FALSE; }
-    virtual int OnResult(int status, char *result, void *scriptdata) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_RESULT); return FALSE; };
+    virtual int OnChanged(int status, char *url) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_CHANGED); 
+        ChangedConnected = false;
+        return FALSE;
+    }
+    virtual int OnResult(int status, char *result, void *scriptdata) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_RESULT);
+        ResultConnected = false;
+        return FALSE;
+    };
 };
 
 // Base class for several widgets that allow text entry
@@ -467,11 +686,23 @@
 class ListBoxes : virtual public Focusable
 {
 private:
+    bool ListSelectConnected;
+#ifdef DW_CPP11
+    std::function<int(int)> _ConnectListSelect;
+#else
+    int (*_ConnectListSelect)(int index);
+#endif
     void Setup() {	
-        if(IsOverridden(ListBoxes::OnListSelect, this))
+        if(IsOverridden(ListBoxes::OnListSelect, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_LIST_SELECT, DW_SIGNAL_FUNC(_OnListSelect), this);
+            ListSelectConnected = true;
+        }
     }
-    static int _OnListSelect(HWND window, int index, void *data) { return reinterpret_cast<ListBoxes *>(data)->OnListSelect(index); }
+    static int _OnListSelect(HWND window, int index, void *data) {
+        if(reinterpret_cast<ListBoxes *>(data)->_ConnectListSelect)
+            return reinterpret_cast<ListBoxes *>(data)->_ConnectListSelect(index);
+        return reinterpret_cast<ListBoxes *>(data)->OnListSelect(index);
+    }
 public:
     // User functions
     void Append(const char *text) { dw_listbox_append(hwnd, text); }
@@ -486,10 +717,26 @@
     int Selected() { return dw_listbox_selected(hwnd); }
     int Selected(int where) { return dw_listbox_selected_multi(hwnd, where); }
     void SetTop(int top) { dw_listbox_set_top(hwnd, top); }
+#ifdef DW_CPP11
+    void ConnectListSelect(std::function<int(int)> userfunc)
+#else
+    void ConnectListSelect(int (*userfunc)(int))
+#endif
+    {
+        _ConnectListSelect = userfunc;
+        if(!ListSelectConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_LIST_SELECT, DW_SIGNAL_FUNC(_OnListSelect), this);
+            ListSelectConnected = true;
+        }
+    }    
 protected:
     // Our signal handler functions to be overriden...
     // If they are not overridden and an event is generated, remove the unused handler
-    virtual int OnListSelect(int index) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_LIST_SELECT); return FALSE; }
+    virtual int OnListSelect(int index) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_LIST_SELECT);
+        ListSelectConnected = false;
+        return FALSE;
+    }
 };
 
 class Combobox : public TextEntry, public ListBoxes
@@ -516,15 +763,44 @@
 class Ranged : virtual public Widget
 {
 private:
-    static int _OnValueChanged(HWND window, int value, void *data) { return reinterpret_cast<Ranged *>(data)->OnValueChanged(value); }
+    bool ValueChangedConnected;
+#ifdef DW_CPP11
+    std::function<int(int)> _ConnectValueChanged;
+#else
+    int (*_ConnectValueChanged)(int value);
+#endif
+    static int _OnValueChanged(HWND window, int value, void *data) {
+        if(reinterpret_cast<Ranged *>(data)->_ConnectValueChanged)
+            return reinterpret_cast<Ranged *>(data)->_ConnectValueChanged(value);
+        return reinterpret_cast<Ranged *>(data)->OnValueChanged(value);
+    }
 protected:
     void Setup() {	
-        if(IsOverridden(Ranged::OnValueChanged, this))
+        if(IsOverridden(Ranged::OnValueChanged, this)) {
             dw_signal_connect(hwnd, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(_OnValueChanged), this);
+            ValueChangedConnected = true;
+        }
     }
     // Our signal handler functions to be overriden...
     // If they are not overridden and an event is generated, remove the unused handler
-    virtual int OnValueChanged(int value) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_VALUE_CHANGED); return FALSE; }    
+    virtual int OnValueChanged(int value) {
+        dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_VALUE_CHANGED);
+        ValueChangedConnected = false;
+        return FALSE;
+    }
+public:
+#ifdef DW_CPP11
+    void ConnectValueChanged(std::function<int(int)> userfunc)
+#else
+    void ConnectValueChanged(int (*userfunc)(int))
+#endif
+    {
+        _ConnectValueChanged = userfunc;
+        if(!ValueChangedConnected) {
+            dw_signal_connect(hwnd, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(_OnValueChanged), this);
+            ValueChangedConnected = true;
+        }
+    }    
 };
 
 class Slider : public Ranged
@@ -598,7 +874,7 @@
     static App *_app;
 public:
 // Allow the code to compile if handicapped on older compilers
-#if __cplusplus >= 201103L
+#ifdef DW_CPP11
     // Singletons should not be cloneable.
     App(App &other) = delete;
     // Singletons should not be assignable.
@@ -612,10 +888,12 @@
     static App *Init(int argc, char *argv[], const char *appid) { if(!_app) { _app = new App(); dw_app_id_set(appid, DW_NULL); dw_init(TRUE, argc, argv); } return _app; }
     static App *Init(int argc, char *argv[], const char *appid, const char *appname) { if(!_app) { _app = new App(); dw_app_id_set(appid, appname); dw_init(TRUE, argc, argv); } return _app; }
 
+    // User functions
     void Main() { dw_main(); }
     void MainIteration() { dw_main_iteration(); }
     void MainQuit() { dw_main_quit(); }
     void Exit(int exitcode) { dw_exit(exitcode); }
+    int MessageBox(const char *title, int flags, const char *format) { return dw_messagebox(title, flags, format); }
 };
 
 // Static singleton reference declared outside of the class
--- a/dwtestoo.cpp	Thu Dec 22 13:57:38 2022 +0000
+++ b/dwtestoo.cpp	Thu Dec 22 13:59:46 2022 +0000
@@ -14,14 +14,30 @@
      int OnConfigure(int width, int height) override { return FALSE; }
 };
 
+#ifndef DW_CPP11
+int button_clicked()
+{
+    app->MessageBox("Button", DW_MB_OK | DW_MB_WARNING, "Clicked!"); 
+    return TRUE; 
+}
+#endif
+
 int dwmain(int argc, char* argv[]) 
 {
     DW::App *app = DW::App::Init(argc, argv, "org.dbsoft.dwindows.dwtestoo");
     MyWindow *window = new MyWindow();
-    DW::Text *text = new DW::Text("Test window");
+    DW::Button *button = new DW::Button("Test window");
     
-    window->PackStart(text, DW_SIZE_AUTO, DW_SIZE_AUTO, TRUE, TRUE, 0);
-    text->SetStyle(DW_DT_CENTER | DW_DT_VCENTER, DW_DT_CENTER | DW_DT_VCENTER);
+    window->PackStart(button, DW_SIZE_AUTO, DW_SIZE_AUTO, TRUE, TRUE, 0);
+#ifdef DW_CPP11
+    button->ConnectClicked([app] () -> int 
+        { 
+            app->MessageBox("Button", DW_MB_OK | DW_MB_WARNING, "Clicked!"); 
+            return TRUE; 
+        });
+#else
+    button ->ConnectClicked(&button_clicked);
+#endif
     window->Show();
 
     app->Main();