neoWidgets
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
WindowBase.h
1 #ifndef NEO_WINDOW_BASE_H
2 #define NEO_WINDOW_BASE_H
3 
4 namespace neo
5 {
6 
7 class WindowBase;
8 
10 namespace dev
11 {
12  class Functor
13  {
14  public:
15  virtual ~Functor() {}
16 
17  virtual bool operator() (HWND hwnd, UINT message, WPARAM wp, LPARAM lp, LRESULT& result, WindowBase* origin) = 0;
18  };
19 
20  class MessageHandlerMap
21  {
22  public:
23  typedef std::pair<MessageId, std::unique_ptr<Functor>> PAIR;
24  typedef std::vector<PAIR> DATA;
25 
26  MessageHandlerMap() {}
27  // make it copyable but dont actually copy anything
28  MessageHandlerMap(const MessageHandlerMap& rhs) {}
29 
30  DATA::const_iterator FindHandler(const MessageId& key) const
31  {
32  auto end = map.end();
33  for(auto it = map.begin(); it < end; ++it)
34  if(it->first == key)
35  return it;
36  return end;
37  }
38  // find the first element that is not less than key
39  DATA::iterator GetLowerBound(const MessageId& key)
40  {
41  auto it = map.begin();
42  auto end = map.end();
43  while(it != end)
44  {
45  if(!(it->first < key))
46  break;
47  ++it;
48  }
49  return it;
50  }
51  // insert into the map, sorted
52  void AddHandler(const MessageId& key, Functor* handler)
53  {
54  auto it = GetLowerBound(key);
55  if(it != map.end())
56  {
57  if(it->first == key)
58  {
59  it->second.reset(handler);
60  }
61  else
62  {
63  map.insert(it, std::make_pair(key, std::unique_ptr<Functor>(handler)));
64  }
65  }
66  else
67  map.push_back(std::make_pair(key, std::unique_ptr<Functor>(handler)));
68  }
69  void RemoveHandler(const MessageId& key)
70  {
71  auto found = FindHandler(key);
72  if(found != map.end())
73  map.erase(found);
74  }
75  Functor* GetHandler(const MessageId& key) const
76  {
77  for(size_t i = 0; i < map.size(); ++i)
78  if(key.EqualOrSpecializationOf(map[i].first))
79  return map[i].second.get();
80  return 0;
81  }
82 
83  DATA map;
84  };
85 
86  class StrongHwnd
87  {
88  public:
89  StrongHwnd();
90  // make it copiable but dont actually copy anything
91  StrongHwnd(const StrongHwnd& rhs);
92  ~StrongHwnd();
93 
94  void Create(DWORD exStyle,
95  const tstring& cls,
96  const tstring& text,
97  DWORD style,
98  const Rect& r,
99  HWND parent,
100  HMENU menu,
101  HINSTANCE instance,
102  WindowBase* obj);
103  void Attach(HWND hwnd);
104  void Clear();
105  HWND GetHandle() const { return handle; }
106 
107  HWND handle;
108  WNDPROC subclassedProc;
109  bool isOnlyAttached;
110  };
111 
112  class WeakHwnd
113  {
114  public:
115  WeakHwnd() { handle = 0; }
116 
117  void Create(DWORD exStyle,
118  const tstring& cls,
119  const tstring& text,
120  DWORD style,
121  const Rect& r,
122  HWND parent,
123  HMENU menu,
124  HINSTANCE instance);
125  void Attach(HWND hwnd) { handle = hwnd; }
126  void Clear() { handle = 0; }
127  HWND GetHandle() const { return handle; }
128 
129  HWND handle;
130  };
131 } // dev
133 
153 {
154 public:
155  WindowBase();
156  WindowBase(const WindowBase& rhs);
157  WindowBase& operator=(const WindowBase& rhs);
158  virtual ~WindowBase();
159 
160  operator HWND() const { return GetHandle(); }
161  HWND GetHandle() const { return strong.handle ? strong.handle : weak.handle; }
162 
163  void Create(DWORD exStyle,
164  const tstring& cls,
165  const tstring& text,
166  DWORD style,
167  const Rect& r,
168  HWND parent,
169  HMENU menu,
170  NEO_WINDOW_MODE mode);
171 
172  void Attach(HWND handle, NEO_WINDOW_MODE mode);
173  void Clear();
174 
178  template<typename MESSAGE>
179  void Bind(UINT message, void (*function)(MESSAGE&))
180  {
181  Bind(MessageId(message), function);
182  }
183 
187  template<typename MESSAGE, typename FUNCTOR>
188  void Bind(UINT message, FUNCTOR function)
189  {
190  Bind(MessageId(message), function);
191  }
192 
196  template<typename CLASS, typename MESSAGE, typename HANDLER>
197  void Bind(UINT message, void (CLASS::*function)(MESSAGE&), HANDLER* handler)
198  {
199  Bind(MessageId(message), function, handler);
200  }
201 
207  template<typename MESSAGE>
208  void Bind(const MessageId& message, void (*function)(MESSAGE&))
209  {
210  handlerMap.AddHandler(message, new FunctionCallback<MESSAGE>(function));
211  }
212 
213  template<typename MESSAGE, typename FUNCTOR>
214  void Bind(const MessageId& message, FUNCTOR function)
215  {
216  handlerMap.AddHandler(message, new FunctorCallback<MESSAGE, FUNCTOR>(function));
217  }
218 
219  template<typename CLASS, typename MESSAGE, typename HANDLER>
220  void Bind(const MessageId& message, void (CLASS::*function)(MESSAGE&), HANDLER* handler)
221  {
222  handlerMap.AddHandler(message, new MemberCallback<CLASS, MESSAGE, HANDLER>(function, handler));
223  }
224 
226  void UnBind(UINT message)
227  {
228  handlerMap.RemoveHandler(MessageId(message));
229  }
230 
232  void UnBind(const MessageId& message)
233  {
234  handlerMap.RemoveHandler(message);
235  }
236 
240  bool IsMessageHandlerBound(UINT message) const { return handlerMap.GetHandler(MessageId(message)) != 0; }
241 
242  void Destroy();
243 
247  tstring GetText() const;
248 
252  void SetText(const tstring& text);
253 
254  bool IsEnabled() const;
255  void Enable(bool enable);
256 
257  bool IsVisible() const;
258  void Show(bool show = true);
259  void Hide() { Show(false); }
260 
264  void SetRedraw(bool allowRedraw);
265 
266  HFONT GetFont() const;
267  void SetFont(HFONT font, bool redraw = true);
268 
272  HICON GetIcon(bool bigIcon) const;
278  HICON SetIcon(HICON icon, bool bigIcon);
279  HMENU GetMenu() const;
280  void SetMenu(HMENU menu);
281 
285  DWORD GetStyle() const;
289  DWORD GetExStyle() const;
290 
294  DWORD GetID() const;
295 
299  HWND GetParentHandle() const;
300 
306  UINT_PTR SetTimer(int timerID, UINT interval, TIMERPROC proc = 0);
310  void KillTimer(int timerID);
311 
316  Rect GetClientRect() const;
317 
322  Rect GetWindowRect() const;
323 
328  Rect GetRectOnParent() const;
329 
330  void Move(int x, int y, bool redraw = true);
331  void Move(const POINT& p, bool redraw = true);
332  void Move(int x, int y, int width, int height, bool redraw = true);
333  void Move(const POINT& p, const SIZE& s, bool redraw = true);
334  void Move(const RECT& r, bool redraw = true);
335 
336  void SetClientSize(int width, int height);
337 
338  bool Invalidate(const RECT* rect = 0, bool eraseBkgnd = true);
339  bool Redraw(const RECT* rect = 0, HRGN region = 0, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
340 
344  HWND SetFocus();
345 
350  void ModifyStyle(DWORD add, DWORD remove);
351 
355  void DragAcceptFiles(bool accept = true);
356 
357  LRESULT GenerateMessage(UINT message, WPARAM wp, LPARAM lp) const;
358 
359  static HFONT GetDefaultFont();
360  static void SetDefaultFont(HFONT font);
361 
362  static HCURSOR GetDefaultCursor();
363  static void SetDefaultCursor(HCURSOR cursor);
364 
365  static HICON GetDefaultIcon();
366  static void SetDefaultIcon(HICON icon);
367 
368  static WindowBase* GetWindowFromHWND(HWND _handle);
369 
370  static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
371  LRESULT DefaultWndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
376  virtual LRESULT WndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
377 private:
378  bool ExecuteMessageHandler(HWND hwnd, UINT message, WPARAM wp, LPARAM lp, LRESULT& result);
379 
380  static HFONT& _DefaultFont()
381  {
382  static HFONT font = 0;
383  return font;
384  }
385 
386  static HCURSOR& _DefaultCursor()
387  {
388  static HCURSOR defaultCursor = LoadCursor(0, IDC_ARROW);
389  return defaultCursor;
390  }
391 
392  static HICON& _DefaultIcon()
393  {
394  static HICON defaultIcon = LoadIcon(0, IDI_APPLICATION);
395  return defaultIcon;
396  }
397 
398  // map HWND to WindowBase* with this little function
399  typedef std::unordered_map<HWND, WindowBase*> HwndMap;
400  static HwndMap& _GetHwndMap()
401  {
402  static HwndMap map;
403  return map;
404  };
405 
406  // functor to global function
407  template<typename MESSAGE>
408  struct FunctionCallback : public dev::Functor
409  {
410  typedef void (*FUNCTION)(MESSAGE&);
411 
412  FunctionCallback(const FUNCTION& f)
413  : function(f)
414  {}
415 
416  virtual bool operator() (HWND hwnd, UINT message, WPARAM wp, LPARAM lp, LRESULT& result, WindowBase* origin)
417  {
418  MESSAGE m;
419  m.Init(hwnd, message, wp, lp);
420  m.messageHandler = origin;
421 
422  function(m);
423 
424  if(m.resultSet && result)
425  result = m.result;
426  return m.resultSet;
427  }
428 
429  FUNCTION function;
430  };
431 
432  // functor to function object
433  template<typename MESSAGE, typename FUNCTOR>
434  struct FunctorCallback : public dev::Functor
435  {
436  FunctorCallback(const FUNCTOR& f)
437  : function(f)
438  {}
439 
440  virtual bool operator() (HWND hwnd, UINT message, WPARAM wp, LPARAM lp, LRESULT& result, WindowBase* origin)
441  {
442  MESSAGE m;
443  m.Init(hwnd, message, wp, lp);
444  m.messageHandler = origin;
445 
446  function(m);
447 
448  if(m.resultSet && result)
449  result = m.result;
450  return m.resultSet;
451  }
452 
453  FUNCTOR function;
454  };
455 
456  // functor to member function
457  template<typename CLASS, typename MESSAGE, typename HANDLER>
458  struct MemberCallback : public dev::Functor
459  {
460  typedef void (CLASS::*FUNCTION)(MESSAGE& m);
461 
462  MemberCallback(FUNCTION f, HANDLER* inst)
463  : function(f)
464  , instance(inst)
465  {}
466 
467  virtual bool operator() (HWND hwnd, UINT message, WPARAM wp, LPARAM lp, LRESULT& result, WindowBase* origin)
468  {
469  MESSAGE m;
470  m.Init(hwnd, message, wp, lp);
471  m.messageHandler = origin;
472 
473  (instance->*function)(m);
474 
475  if(m.resultSet && result)
476  result = m.result;
477  return m.resultSet;
478  }
479 
480  FUNCTION function;
481  HANDLER* instance;
482  };
483 
484  dev::StrongHwnd strong;
485  dev::WeakHwnd weak;
486  dev::MessageHandlerMap handlerMap;
487 };
488 
489 } // namespace neo
490 
491 #endif
void Bind(UINT message, FUNCTOR function)
Definition: WindowBase.h:188
virtual LRESULT WndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Can be overridden for old school message handling.
Definition: WindowBase.inl:202
The big window class that every other class descends from.
Definition: WindowBase.h:152
HWND GetParentHandle() const
Definition: WindowBase.inl:387
void Bind(UINT message, void(*function)(MESSAGE &))
Definition: WindowBase.h:179
DWORD GetExStyle() const
Definition: WindowBase.inl:377
void Bind(UINT message, void(CLASS::*function)(MESSAGE &), HANDLER *handler)
Definition: WindowBase.h:197
void SetRedraw(bool allowRedraw)
Definition: WindowBase.inl:337
bool IsMessageHandlerBound(UINT message) const
Definition: WindowBase.h:240
DWORD GetID() const
Definition: WindowBase.inl:382
void SetText(const tstring &text)
Definition: WindowBase.inl:312
Rect GetWindowRect() const
Definition: WindowBase.inl:409
UINT_PTR SetTimer(int timerID, UINT interval, TIMERPROC proc=0)
Definition: WindowBase.inl:392
HICON GetIcon(bool bigIcon) const
Definition: WindowBase.inl:352
Rect GetRectOnParent() const
Definition: WindowBase.inl:416
void ModifyStyle(DWORD add, DWORD remove)
Definition: WindowBase.inl:467
void UnBind(const MessageId &message)
Definition: WindowBase.h:232
Unified message identifier.
Definition: MessageId.h:14
void DragAcceptFiles(bool accept=true)
Definition: WindowBase.inl:473
void Bind(const MessageId &message, void(*function)(MESSAGE &))
Definition: WindowBase.h:208
HWND SetFocus()
Definition: WindowBase.inl:462
Windows RECT structure with constructor.
Definition: Rect.h:108
void KillTimer(int timerID)
Definition: WindowBase.inl:397
void UnBind(UINT message)
Definition: WindowBase.h:226
HICON SetIcon(HICON icon, bool bigIcon)
Definition: WindowBase.inl:357
tstring GetText() const
Definition: WindowBase.inl:302
NEO_WINDOW_MODE
Definition: neo.h:23
DWORD GetStyle() const
Definition: WindowBase.inl:372
Rect GetClientRect() const
Definition: WindowBase.inl:402