Warning, /include/Geant4/toolx/Windows/window is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef toolx_Windows_window
0005 #define toolx_Windows_window
0006
0007 #include <windows.h>
0008 #include <windowsx.h>
0009 #include <string>
0010
0011 namespace toolx {
0012 namespace Windows {
0013
0014 class window {
0015 static const std::string& s_class() {
0016 static const std::string s_v("toolx::Windows::window");
0017 return s_v;
0018 }
0019 static void register_class(){
0020 static bool s_done = false; //not const, then not thread safe.
0021 if(!s_done) {
0022 WNDCLASS wc;
0023 wc.style = CS_HREDRAW | CS_VREDRAW;
0024 wc.lpfnWndProc = (WNDPROC)proc;
0025 wc.cbClsExtra = 0;
0026 wc.cbWndExtra = 0;
0027 wc.hInstance = ::GetModuleHandle(NULL);
0028 wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
0029 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
0030 wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
0031 wc.lpszMenuName = (PTSTR)s_class().c_str();
0032 wc.lpszClassName = (PTSTR)s_class().c_str();
0033 ::RegisterClass(&wc);
0034 s_done = true;
0035 }
0036 }
0037 public:
0038 virtual void key_up(){}
0039 virtual void key_down(){}
0040 virtual void key_left(){}
0041 virtual void key_right(){}
0042 virtual void key_escape(){}
0043 virtual void close(){
0044 ::PostQuitMessage(0);
0045 }
0046 public:
0047 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)
0048 :m_hwnd(0)
0049 ,m_key_shift(false)
0050 ,m_key_ctrl(false)
0051 ,m_focus_hwnd(0)
0052 {
0053 // WARNING : given a_w,a_h may not be the client area because of various decorations.
0054 // See set_client_area_size() method to enforce a client area size.
0055 register_class();
0056 m_hwnd = ::CreateWindow((PTSTR)s_class().c_str(),
0057 NULL,
0058 a_mask,
0059 a_x,a_y,
0060 a_w,a_h,
0061 NULL,NULL,
0062 ::GetModuleHandle(NULL),
0063 NULL);
0064 if(!m_hwnd) return;
0065 ::SetWindowText(m_hwnd,(PTSTR)a_title);
0066 ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(this));
0067 }
0068 virtual ~window(){
0069 if(m_hwnd) {
0070 ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(NULL));
0071 ::DestroyWindow(m_hwnd);
0072 m_hwnd = 0;
0073 }
0074 }
0075 protected:
0076 window(const window& a_from)
0077 :m_hwnd(0)
0078 ,m_key_shift(a_from.m_key_shift)
0079 ,m_key_ctrl(a_from.m_key_ctrl)
0080 ,m_focus_hwnd(0)
0081 {
0082 }
0083 window& operator=(const window& a_from){
0084 m_key_shift = a_from.m_key_shift;
0085 m_key_ctrl = a_from.m_key_ctrl;
0086 return *this;
0087 }
0088 public:
0089 const window& get_me() const {return *this;}
0090 window& get_me() {return *this;}
0091 bool key_shift() const {return m_key_shift;}
0092 HWND hwnd() const {return m_hwnd;}
0093
0094 void set_client_area_size(unsigned int a_w,unsigned int a_h) {
0095 if(!m_hwnd) return;
0096 RECT wrect;
0097 ::GetWindowRect(m_hwnd,&wrect);
0098 unsigned int ww = wrect.right-wrect.left;
0099 unsigned int wh = wrect.bottom-wrect.top;
0100
0101 RECT carect;
0102 ::GetClientRect(m_hwnd,&carect);
0103 unsigned int cw = carect.right-carect.left;
0104 unsigned int ch = carect.bottom-carect.top;
0105
0106 unsigned int woffset = ww-cw;
0107 unsigned int hoffset = wh-ch;
0108
0109 ::MoveWindow(m_hwnd,wrect.left,wrect.top,a_w+woffset,a_h+hoffset,TRUE);
0110 }
0111 void move(unsigned int a_x,unsigned int a_y) {
0112 if(!m_hwnd) return;
0113 RECT rect;
0114 ::GetWindowRect(m_hwnd,&rect);
0115 unsigned int w = rect.right-rect.left;
0116 unsigned int h = rect.bottom-rect.top;
0117 ::MoveWindow(m_hwnd,a_x,a_y,w,h,TRUE);
0118 }
0119
0120 void set_focus_hwnd(HWND a_hwnd) {m_focus_hwnd = a_hwnd;}
0121 HWND focus_hwnd() const {return m_focus_hwnd;}
0122 protected:
0123 static LRESULT CALLBACK proc(HWND a_hwnd,UINT a_msg,WPARAM a_wparam,LPARAM a_lparam) {
0124 switch (a_msg) {
0125 // Else :
0126 case WM_SIZE:{ // Assume one child window ! FIXME : have a message if not.
0127 int width = LOWORD(a_lparam);
0128 int height = HIWORD(a_lparam);
0129 HWND hwnd = GetFirstChild(a_hwnd);
0130 if(hwnd) {
0131 ::MoveWindow(hwnd,0,0,width,height,TRUE);
0132 }
0133 }return 0;
0134
0135 case WM_SETFOCUS:{
0136 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0137 if(_this) {
0138 HWND hwnd = _this->focus_hwnd();
0139 if(hwnd) ::SetFocus(hwnd);
0140 }
0141 }return 0;
0142
0143 case WM_KEYDOWN:{
0144 switch(a_wparam){
0145 case VK_SHIFT:{
0146 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0147 if(_this) _this->m_key_shift = true;
0148 return 0;
0149 }
0150 case VK_CONTROL:{
0151 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0152 if(_this) _this->m_key_ctrl = true;
0153 return 0;
0154 }
0155 case VK_UP:{
0156 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0157 if(_this) _this->key_up();
0158 return 0;
0159 }
0160 case VK_DOWN:{
0161 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0162 if(_this) _this->key_down();
0163 return 0;
0164 }
0165 case VK_LEFT:{
0166 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0167 if(_this) _this->key_left();
0168 return 0;
0169 }
0170 case VK_RIGHT:{
0171 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0172 if(_this) _this->key_right();
0173 return 0;
0174 }
0175 case VK_ESCAPE:{
0176 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0177 if(_this) _this->key_escape();
0178 return 0;
0179 }
0180 } //end switch(a_wparam)
0181 break;
0182 }
0183 case WM_KEYUP:{
0184 switch(a_wparam){
0185 case VK_SHIFT:{
0186 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0187 if(_this) _this->m_key_shift = false;
0188 return 0;
0189 }
0190 case VK_CONTROL:{
0191 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0192 if(_this) _this->m_key_ctrl = false;
0193 return 0;
0194 }
0195 } //end switch(a_wparam)
0196 break;
0197 }
0198
0199 case WM_CLOSE:{
0200 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0201 if(_this) _this->close();
0202 }break; //NOTE : can't be return 0.
0203 case WM_DESTROY:wm__destroy(a_hwnd);return 0;
0204 }
0205 return (DefWindowProc(a_hwnd,a_msg,a_wparam,a_lparam));
0206 }
0207 static void wm__destroy(HWND a_hwnd) {
0208 window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0209 if(_this) { //How to be sure that we have a window* ???
0210 if(_this->m_hwnd!=a_hwnd) {
0211 }
0212 _this->m_hwnd = 0;
0213 }
0214 ::SetWindowLongPtr(a_hwnd,GWLP_USERDATA,LONG_PTR(NULL));
0215 }
0216 protected:
0217 void get_size(HWND a_hwnd,int& a_w,int& a_h){
0218 RECT rect;
0219 ::GetWindowRect(a_hwnd,&rect);
0220 a_w = rect.right-rect.left;
0221 a_h = rect.bottom-rect.top;
0222 }
0223 protected:
0224 HWND m_hwnd;
0225 bool m_key_shift;
0226 bool m_key_ctrl;
0227 HWND m_focus_hwnd;
0228 };
0229
0230 }}
0231
0232 #endif