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