Back to home page

EIC code displayed by LXR

 
 

    


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     //if(m_hwnd) ::PostMessage(m_hwnd,WM_QUIT,0,0);
0045     ::PostQuitMessage(0);
0046   }
0047 public:
0048   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)
0049   :m_hwnd(0)
0050   ,m_key_shift(false)
0051   ,m_key_ctrl(false)
0052   ,m_focus_hwnd(0)
0053   {
0054     // WARNING : given a_w,a_h may not be the client area because of various decorations.
0055     //           See set_client_area_size() method to enforce a client area size.
0056     register_class();
0057     m_hwnd = ::CreateWindow((PTSTR)s_class().c_str(),
0058                               NULL,
0059                               a_mask,
0060                               a_x,a_y,
0061                               a_w,a_h,
0062                               NULL,NULL,
0063                               ::GetModuleHandle(NULL),
0064                               NULL);
0065     if(!m_hwnd) return;
0066     ::SetWindowText(m_hwnd,(PTSTR)a_title);
0067     ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(this));
0068   }
0069   virtual ~window(){
0070     if(m_hwnd) {
0071       ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(NULL));
0072       ::DestroyWindow(m_hwnd);
0073       m_hwnd = 0;
0074     }
0075   }
0076 protected:
0077   window(const window& a_from)
0078   :m_hwnd(0)
0079   ,m_key_shift(a_from.m_key_shift)
0080   ,m_key_ctrl(a_from.m_key_ctrl)
0081   ,m_focus_hwnd(0)
0082   {
0083   /*
0084     if(!a_from.m_hwnd) return;
0085     int w,h;
0086     get_size(a_from.m_hwnd,w,h);
0087     register_class();
0088     m_hwnd = ::CreateWindow(s_class().c_str(),
0089                               NULL,
0090                               WS_OVERLAPPEDWINDOW,
0091                               CW_USEDEFAULT,CW_USEDEFAULT,
0092                               w,h,
0093                               NULL,NULL,
0094                               ::GetModuleHandle(NULL),
0095                               NULL);
0096     if(!m_hwnd) return;
0097     ::SetWindowLongPtr(m_hwnd,GWLP_USERDATA,LONG_PTR(this));
0098     */
0099   }
0100   window& operator=(const window& a_from){
0101     m_key_shift = a_from.m_key_shift;
0102     m_key_ctrl = a_from.m_key_ctrl;
0103     return *this;
0104   }
0105 public:
0106   const window& get_me() const {return *this;}
0107   window& get_me() {return *this;}
0108   bool key_shift() const {return m_key_shift;}
0109   HWND hwnd() const {return m_hwnd;}
0110 
0111   void set_client_area_size(unsigned int a_w,unsigned int a_h) {
0112     if(!m_hwnd) return;
0113     RECT wrect;
0114     ::GetWindowRect(m_hwnd,&wrect);
0115     unsigned int ww = wrect.right-wrect.left;
0116     unsigned int wh = wrect.bottom-wrect.top;
0117 
0118     RECT carect;
0119     ::GetClientRect(m_hwnd,&carect);
0120     unsigned int cw = carect.right-carect.left;
0121     unsigned int ch = carect.bottom-carect.top;
0122 
0123     unsigned int woffset = ww-cw;
0124     unsigned int hoffset = wh-ch;
0125 
0126     ::MoveWindow(m_hwnd,wrect.left,wrect.top,a_w+woffset,a_h+hoffset,TRUE);
0127   }
0128   void move(unsigned int a_x,unsigned int a_y) {
0129     if(!m_hwnd) return;
0130     RECT rect;
0131     ::GetWindowRect(m_hwnd,&rect);
0132     unsigned int w = rect.right-rect.left;
0133     unsigned int h = rect.bottom-rect.top;
0134     ::MoveWindow(m_hwnd,a_x,a_y,w,h,TRUE);
0135   }
0136   
0137   void set_focus_hwnd(HWND a_hwnd) {m_focus_hwnd = a_hwnd;}
0138   HWND focus_hwnd() const {return m_focus_hwnd;}
0139 protected:
0140   static LRESULT CALLBACK proc(HWND a_hwnd,UINT a_msg,WPARAM a_wparam,LPARAM a_lparam) {
0141     switch (a_msg) {
0142     // Else :
0143     case WM_SIZE:{ // Assume one child window ! FIXME : have a message if not.
0144       int width = LOWORD(a_lparam);
0145       int height = HIWORD(a_lparam);
0146       HWND hwnd = GetFirstChild(a_hwnd);
0147       if(hwnd) {
0148         ::MoveWindow(hwnd,0,0,width,height,TRUE);
0149       }
0150     }return 0;
0151 
0152     case WM_SETFOCUS:{
0153       window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0154       if(_this) {
0155         HWND hwnd = _this->focus_hwnd();
0156         if(hwnd) ::SetFocus(hwnd);
0157       }
0158     }return 0;
0159     
0160     case WM_KEYDOWN:{
0161       switch(a_wparam){
0162       case VK_SHIFT:{
0163         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0164         if(_this) _this->m_key_shift = true;
0165         return 0;
0166       }
0167       case VK_CONTROL:{
0168         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0169         if(_this) _this->m_key_ctrl = true;
0170         return 0;
0171       }
0172       case VK_UP:{
0173         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0174         if(_this) _this->key_up();
0175         return 0;
0176       }
0177       case VK_DOWN:{
0178         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0179         if(_this) _this->key_down();
0180         return 0;
0181       }
0182       case VK_LEFT:{
0183         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0184         if(_this) _this->key_left();
0185         return 0;
0186       }
0187       case VK_RIGHT:{
0188         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0189         if(_this) _this->key_right();
0190         return 0;
0191       }
0192       case VK_ESCAPE:{
0193         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0194         if(_this) _this->key_escape();
0195         return 0;
0196       }
0197       } //end switch(a_wparam)
0198       break;
0199     }
0200     case WM_KEYUP:{
0201       switch(a_wparam){
0202       case VK_SHIFT:{
0203         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0204         if(_this) _this->m_key_shift = false;
0205         return 0;
0206       }
0207       case VK_CONTROL:{
0208         window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0209         if(_this) _this->m_key_ctrl = false;
0210         return 0;
0211       }
0212       } //end switch(a_wparam)
0213       break;
0214     }
0215 
0216     case WM_CLOSE:{
0217       window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0218       if(_this) _this->close();
0219     }break; //NOTE : can't be return 0.
0220     case WM_DESTROY:wm__destroy(a_hwnd);return 0;
0221     }
0222     return (DefWindowProc(a_hwnd,a_msg,a_wparam,a_lparam));
0223   }
0224   static void wm__destroy(HWND a_hwnd) {
0225     window* _this = (window*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
0226     if(_this) { //How to be sure that we have a window* ???
0227       if(_this->m_hwnd!=a_hwnd) {
0228         //::printf("WinTk::Component::wm_destroy : HWND mismatch !\n");
0229       }
0230       _this->m_hwnd = 0;
0231     }
0232     ::SetWindowLongPtr(a_hwnd,GWLP_USERDATA,LONG_PTR(NULL));
0233   }
0234 protected:
0235   void get_size(HWND a_hwnd,int& a_w,int& a_h){
0236     RECT rect;
0237     ::GetWindowRect(a_hwnd,&rect);
0238     a_w = rect.right-rect.left;
0239     a_h = rect.bottom-rect.top;
0240   }
0241 protected:
0242   HWND m_hwnd;
0243   bool m_key_shift;
0244   bool m_key_ctrl;
0245   HWND m_focus_hwnd;
0246 };
0247 
0248 }}
0249 
0250 #endif