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     ::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