root/lang/cplusplus/i3/src/mol/include/mol/windows/GuiModule.h @ 14345

Revision 14345, 3.0 kB (checked in by saturday06, 5 years ago)

窓依存のコード追い出しとか

Line 
1#pragma once
2#include "Mol.h"
3#include "../Module.h"
4#include "WindowProcedureRedirector.h"
5
6namespace mol
7{
8const UINT WM_MOL_GUIMODULE = WM_APP+100;
9
10template <typename Child>
11class GuiModule : public boost::noncopyable {
12    Child& getChild() {
13        return *static_cast<Child*>(this);
14    }
15
16    class EventBase : boost::noncopyable
17    {
18    public:
19        void (*execute)(void* list, void* target);
20    };
21
22    template <typename T>
23    class Event : public EventBase
24    {
25    public:
26        T data;
27    };
28
29    template <typename Data, typename Target>
30    static void dispatcher(void* event_, void* target_)
31    {
32        Event<Data>* event = static_cast<Event<Data>*>(event_);
33        Target* target = static_cast<Target*>(target_);
34
35        // �C�����C�����ŏ���򂪏���邩��
36        if (target->getChild().execute(event->data)) {
37            // �폜
38            boost::singleton_pool<char, PoolSizeSelector<Event<Data> >::SIZE>::free(event);
39        } else {
40            // �����g��.
41            PostMessage(target->getWindow(), WM_MOL_GUIMODULE,
42                        0, reinterpret_cast<LPARAM>(event));
43        }
44    }
45protected:
46    HWND hWnd;
47    HWND getWindow() const {
48        return hWnd;
49    }
50
51    mol::WindowProcedureRedirector<Child> wndproc;
52    void loop() {
53        MSG msg = {};
54
55        for (BOOL result = 0; (result = GetMessage(&msg, NULL, 0, 0)), result;) {
56            if (result == -1) {
57                // error
58                mol_abort << msg.message;
59                break;
60            }
61
62            TranslateMessage(&msg);
63            DispatchMessage(&msg);
64        }
65    }
66public:
67    GuiModule(): hWnd(NULL), wndproc(getChild()) {
68    }
69    template <typename T>
70    void post(const T& event)
71    {
72        void* p = boost::singleton_pool<char, PoolSizeSelector<Event<T> >::SIZE>::malloc();
73        if (p == NULL) {
74            // XXX
75            return;
76        }
77        Event<T>* e = new(p) Event<T>;
78        e->data = event;
79        e->execute = dispatcher<T, Child>;
80
81        assert(getWindow()); // XXX hWnd initialized ???
82        PostMessage(getWindow(), WM_MOL_GUIMODULE,
83                    0, reinterpret_cast<LPARAM>(e));
84    }
85
86    LRESULT MessageMap(UINT msg, WPARAM wParam, LPARAM lParam, bool& handled) {
87        handled = false;
88        if (msg == mol::WM_MOL_GUIMODULE)
89        {
90            BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(lParam));
91            EventBase* e = reinterpret_cast<EventBase*>(lParam);
92            e->execute(e, &getChild());
93            handled = true;
94            return 0;
95        } else if (msg == WM_DESTROY) {
96            PostQuitMessage(0);
97        }
98        return 0;
99    }
100
101    LRESULT WindowProcedure(UINT msg, WPARAM wParam, LPARAM lParam)
102    {
103        bool handled = false;
104        LRESULT result = MessageMap(msg, wParam, lParam, handled);
105        if (handled) {
106            return result;
107        }
108        return DefWindowProc(hWnd, msg, wParam, lParam);
109    }
110};
111
112}
Note: See TracBrowser for help on using the browser.