g4tools  5.4.0
window
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_Windows_window
5 #define tools_Windows_window
6 
7 #include <windows.h>
8 #include <windowsx.h>
9 #include <string>
10 
11 namespace tools {
12 namespace Windows {
13 
14 class window {
15  static const std::string& s_class() {
16  static const std::string s_v("tools::Windows::window");
17  return s_v;
18  }
19  static void register_class(){
20  static bool s_done = false; //not const, then not thread safe.
21  if(!s_done) {
22  WNDCLASS wc;
23  wc.style = CS_HREDRAW | CS_VREDRAW;
24  wc.lpfnWndProc = (WNDPROC)proc;
25  wc.cbClsExtra = 0;
26  wc.cbWndExtra = 0;
27  wc.hInstance = ::GetModuleHandle(NULL);
28  wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
29  wc.hCursor = LoadCursor(NULL,IDC_ARROW);
30  wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
31  wc.lpszMenuName = s_class().c_str();
32  wc.lpszClassName = s_class().c_str();
33  ::RegisterClass(&wc);
34  s_done = true;
35  }
36  }
37 public:
38  virtual void key_up(){}
39  virtual void key_down(){}
40  virtual void key_left(){}
41  virtual void key_right(){}
42  virtual void key_escape(){}
43  virtual void close(){
44  //if(m_hwnd) ::PostMessage(m_hwnd,WM_QUIT,0,0);
45  ::PostQuitMessage(0);
46  }
47 public:
48  window(const char* a_title,int a_x,int a_y,unsigned int a_w,unsigned int a_h,unsigned int a_mask = WS_OVERLAPPEDWINDOW)
49  :m_hwnd(0)
50  ,m_key_shift(false)
51  ,m_key_ctrl(false)
52  ,m_focus_hwnd(0)
53  {
54  // WARNING : given a_w,a_h may not be the client area because of various decorations.
55  // See set_client_area_size() method to enforce a client area size.
56  register_class();
57  m_hwnd = ::CreateWindow(s_class().c_str(),
58  NULL,
59  a_mask,
60  a_x,a_y,
61  a_w,a_h,
62  NULL,NULL,
63  ::GetModuleHandle(NULL),
64  NULL);
65  if(!m_hwnd) return;
66  ::SetWindowText(m_hwnd,a_title);
67  ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(this));
68  }
69  virtual ~window(){
70  if(m_hwnd) {
71  ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(NULL));
72  ::DestroyWindow(m_hwnd);
73  m_hwnd = 0;
74  }
75  }
76 protected:
77  window(const window& a_from)
78  :m_hwnd(0)
79  ,m_key_shift(a_from.m_key_shift)
80  ,m_key_ctrl(a_from.m_key_ctrl)
81  ,m_focus_hwnd(0)
82  {
83  /*
84  if(!a_from.m_hwnd) return;
85  int w,h;
86  get_size(a_from.m_hwnd,w,h);
87  register_class();
88  m_hwnd = ::CreateWindow(s_class().c_str(),
89  NULL,
90  WS_OVERLAPPEDWINDOW,
91  CW_USEDEFAULT,CW_USEDEFAULT,
92  w,h,
93  NULL,NULL,
94  ::GetModuleHandle(NULL),
95  NULL);
96  if(!m_hwnd) return;
97  ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(this));
98  */
99  }
100  window& operator=(const window& a_from){
101  m_key_shift = a_from.m_key_shift;
102  m_key_ctrl = a_from.m_key_ctrl;
103  return *this;
104  }
105 public:
106  const window& get_me() const {return *this;}
107  window& get_me() {return *this;}
108  bool key_shift() const {return m_key_shift;}
109  HWND hwnd() const {return m_hwnd;}
110 
111  void set_client_area_size(unsigned int a_w,unsigned int a_h) {
112  if(!m_hwnd) return;
113  RECT wrect;
114  ::GetWindowRect(m_hwnd,&wrect);
115  unsigned int ww = wrect.right-wrect.left;
116  unsigned int wh = wrect.bottom-wrect.top;
117 
118  RECT carect;
119  ::GetClientRect(m_hwnd,&carect);
120  unsigned int cw = carect.right-carect.left;
121  unsigned int ch = carect.bottom-carect.top;
122 
123  unsigned int woffset = ww-cw;
124  unsigned int hoffset = wh-ch;
125 
126  ::MoveWindow(m_hwnd,wrect.left,wrect.top,a_w+woffset,a_h+hoffset,TRUE);
127  }
128  void move(unsigned int a_x,unsigned int a_y) {
129  if(!m_hwnd) return;
130  RECT rect;
131  ::GetWindowRect(m_hwnd,&rect);
132  unsigned int w = rect.right-rect.left;
133  unsigned int h = rect.bottom-rect.top;
134  ::MoveWindow(m_hwnd,a_x,a_y,w,h,TRUE);
135  }
136 
137  void set_focus_hwnd(HWND a_hwnd) {m_focus_hwnd = a_hwnd;}
138  HWND focus_hwnd() const {return m_focus_hwnd;}
139 protected:
140  static LRESULT CALLBACK proc(HWND a_hwnd,UINT a_msg,WPARAM a_wparam,LPARAM a_lparam) {
141  switch (a_msg) {
142  // Else :
143  case WM_SIZE:{ // Assume one child window ! FIXME : have a message if not.
144  int width = LOWORD(a_lparam);
145  int height = HIWORD(a_lparam);
146  HWND hwnd = GetFirstChild(a_hwnd);
147  if(hwnd) {
148  ::MoveWindow(hwnd,0,0,width,height,TRUE);
149  }
150  }return 0;
151 
152  case WM_SETFOCUS:{
153  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
154  if(_this) {
155  HWND hwnd = _this->focus_hwnd();
156  if(hwnd) ::SetFocus(hwnd);
157  }
158  }return 0;
159 
160  case WM_KEYDOWN:{
161  switch(a_wparam){
162  case VK_SHIFT:{
163  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
164  if(_this) _this->m_key_shift = true;
165  return 0;
166  }
167  case VK_CONTROL:{
168  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
169  if(_this) _this->m_key_ctrl = true;
170  return 0;
171  }
172  case VK_UP:{
173  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
174  if(_this) _this->key_up();
175  return 0;
176  }
177  case VK_DOWN:{
178  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
179  if(_this) _this->key_down();
180  return 0;
181  }
182  case VK_LEFT:{
183  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
184  if(_this) _this->key_left();
185  return 0;
186  }
187  case VK_RIGHT:{
188  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
189  if(_this) _this->key_right();
190  return 0;
191  }
192  case VK_ESCAPE:{
193  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
194  if(_this) _this->key_escape();
195  return 0;
196  }
197  } //end switch(a_wparam)
198  break;
199  }
200  case WM_KEYUP:{
201  switch(a_wparam){
202  case VK_SHIFT:{
203  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
204  if(_this) _this->m_key_shift = false;
205  return 0;
206  }
207  case VK_CONTROL:{
208  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
209  if(_this) _this->m_key_ctrl = false;
210  return 0;
211  }
212  } //end switch(a_wparam)
213  break;
214  }
215 
216  case WM_CLOSE:{
217  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
218  if(_this) _this->close();
219  }break; //NOTE : can't be return 0.
220  case WM_DESTROY:wm__destroy(a_hwnd);return 0;
221  }
222  return (DefWindowProc(a_hwnd,a_msg,a_wparam,a_lparam));
223  }
224  static void wm__destroy(HWND a_hwnd) {
225  window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
226  if(_this) { //How to be sure that we have a window* ???
227  if(_this->m_hwnd!=a_hwnd) {
228  //::printf("WinTk::Component::wm_destroy : HWND mismatch !\n");
229  }
230  _this->m_hwnd = 0;
231  }
232  ::SetWindowLongPtr(a_hwnd,GWLP_USERDATA,LONG_PTR(NULL));
233  }
234 protected:
235  void get_size(HWND a_hwnd,int& a_w,int& a_h){
236  RECT rect;
237  ::GetWindowRect(a_hwnd,&rect);
238  a_w = rect.right-rect.left;
239  a_h = rect.bottom-rect.top;
240  }
241 protected:
242  HWND m_hwnd;
246 };
247 
248 }}
249 
250 #endif
tools::Windows::window::key_left
virtual void key_left()
Definition: window:40
tools::Windows::window::get_size
void get_size(HWND a_hwnd, int &a_w, int &a_h)
Definition: window:235
tools::Windows::window::wm__destroy
static void wm__destroy(HWND a_hwnd)
Definition: window:224
tools::Windows::window::get_me
const window & get_me() const
Definition: window:106
tools::Windows::window::focus_hwnd
HWND focus_hwnd() const
Definition: window:138
tools::Windows::window::key_right
virtual void key_right()
Definition: window:41
tools::Windows::window::set_client_area_size
void set_client_area_size(unsigned int a_w, unsigned int a_h)
Definition: window:111
tools::Windows::window::key_escape
virtual void key_escape()
Definition: window:42
tools::Windows::window::key_up
virtual void key_up()
Definition: window:38
tools::Windows::window::key_shift
bool key_shift() const
Definition: window:108
tools::Windows::window::~window
virtual ~window()
Definition: window:69
tools::Windows::window::m_focus_hwnd
HWND m_focus_hwnd
Definition: window:245
tools::Windows::window::hwnd
HWND hwnd() const
Definition: window:109
tools::Windows::window::proc
static LRESULT CALLBACK proc(HWND a_hwnd, UINT a_msg, WPARAM a_wparam, LPARAM a_lparam)
Definition: window:140
tools::Windows::window::set_focus_hwnd
void set_focus_hwnd(HWND a_hwnd)
Definition: window:137
tools::Windows::window::close
virtual void close()
Definition: window:43
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::Windows::window::m_key_ctrl
bool m_key_ctrl
Definition: window:244
tools::Windows::window::operator=
window & operator=(const window &a_from)
Definition: window:100
tools::Windows::window::move
void move(unsigned int a_x, unsigned int a_y)
Definition: window:128
tools::Windows::window::key_down
virtual void key_down()
Definition: window:39
tools::Windows::window::m_hwnd
HWND m_hwnd
Definition: window:242
tools::Windows::window::window
window(const char *a_title, int a_x, int a_y, unsigned int a_w, unsigned int a_h, unsigned int a_mask=WS_OVERLAPPEDWINDOW)
Definition: window:48
tools::Windows::window::m_key_shift
bool m_key_shift
Definition: window:243
tools::Windows::window::get_me
window & get_me()
Definition: window:107
tools::Windows::window::window
window(const window &a_from)
Definition: window:77
tools::Windows::window
Definition: window:14