Panda3D
|
00001 // Filename: winGraphicsWindow.h 00002 // Created by: drose (20Dec02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef WINGRAPHICSWINDOW_H 00016 #define WINGRAPHICSWINDOW_H 00017 00018 #include "pandabase.h" 00019 #include "graphicsWindow.h" 00020 #ifndef WIN32_LEAN_AND_MEAN 00021 #define WIN32_LEAN_AND_MEAN 1 00022 #endif 00023 #include <windows.h> 00024 00025 class WinGraphicsPipe; 00026 00027 #define PM_ACTIVE (WM_APP+123) 00028 00029 #define PM_INACTIVE (WM_APP+124) 00030 00031 typedef struct { 00032 int x; 00033 int y; 00034 int width; 00035 int height; 00036 } 00037 WINDOW_METRICS; 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Class : WinGraphicsWindow 00041 // Description : An abstract base class for glGraphicsWindow and 00042 // dxGraphicsWindow (and, in general, graphics windows 00043 // that interface with the Microsoft Windows API). 00044 // 00045 // This class includes all the code for manipulating 00046 // windows themselves: opening them, closing them, 00047 // responding to user keyboard and mouse input, and so 00048 // on. It does not make any 3-D rendering calls into 00049 // the window; that is the province of the 00050 // GraphicsStateGuardian. 00051 //////////////////////////////////////////////////////////////////// 00052 class EXPCL_PANDAWIN WinGraphicsWindow : public GraphicsWindow { 00053 public: 00054 WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, 00055 const string &name, 00056 const FrameBufferProperties &fb_prop, 00057 const WindowProperties &win_prop, 00058 int flags, 00059 GraphicsStateGuardian *gsg, 00060 GraphicsOutput *host); 00061 virtual ~WinGraphicsWindow(); 00062 00063 virtual bool move_pointer(int device, int x, int y); 00064 00065 virtual void close_ime(); 00066 00067 virtual void begin_flip(); 00068 00069 virtual void process_events(); 00070 virtual void set_properties_now(WindowProperties &properties); 00071 void receive_windows_message(unsigned int msg, int wparam, int lparam); 00072 virtual LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 00073 static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 00074 virtual bool handle_mouse_motion(int x, int y); 00075 virtual void handle_mouse_exit(); 00076 00077 INLINE HWND get_ime_hwnd(); 00078 00079 00080 protected: 00081 virtual void close_window(); 00082 virtual bool open_window(); 00083 virtual void fullscreen_minimized(WindowProperties &properties); 00084 virtual void fullscreen_restored(WindowProperties &properties); 00085 00086 virtual bool do_reshape_request(int x_origin, int y_origin, bool has_origin, 00087 int x_size, int y_size); 00088 00089 virtual void handle_reshape(); 00090 virtual bool do_fullscreen_resize(int x_size, int y_size); 00091 00092 virtual bool do_fullscreen_switch(); 00093 virtual bool do_windowed_switch(); 00094 virtual bool do_fullscreen_enable(); 00095 virtual bool do_fullscreen_disable(); 00096 00097 virtual bool calculate_metrics(bool fullscreen, DWORD style, 00098 WINDOW_METRICS &metrics, bool &has_origin); 00099 00100 virtual DWORD make_style(bool fullscreen); 00101 00102 virtual void reconsider_fullscreen_size(DWORD &x_size, DWORD &y_size, 00103 DWORD &bitdepth); 00104 00105 virtual void support_overlay_window(bool flag); 00106 00107 private: 00108 bool open_graphic_window(bool fullscreen); 00109 void adjust_z_order(); 00110 void adjust_z_order(WindowProperties::ZOrder last_z_order, 00111 WindowProperties::ZOrder this_z_order); 00112 void initialize_input_devices(); 00113 void handle_raw_input(HRAWINPUT hraw); 00114 void track_mouse_leaving(HWND hwnd); 00115 00116 void set_focus(); 00117 00118 static void process_1_event(); 00119 00120 INLINE void handle_keypress(ButtonHandle key, int x, int y, double time); 00121 INLINE void handle_keyresume(ButtonHandle key, double time); 00122 INLINE void handle_keyrelease(ButtonHandle key, double time); 00123 ButtonHandle lookup_key(WPARAM wparam) const; 00124 INLINE int translate_mouse(int pos) const; 00125 INLINE void set_cursor_in_window(); 00126 INLINE void set_cursor_out_of_window(); 00127 00128 INLINE static double get_message_time(); 00129 00130 void resend_lost_keypresses(); 00131 static void update_cursor_window(WinGraphicsWindow *to_window); 00132 static void hide_or_show_cursor(bool hide_cursor); 00133 00134 static bool find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, 00135 DWORD bpp, DEVMODE &dm); 00136 static void show_error_message(DWORD message_id = 0); 00137 00138 protected: 00139 HWND _hWnd; 00140 HWND _hparent; 00141 00142 private: 00143 HWND _ime_hWnd; 00144 bool _ime_open; 00145 bool _ime_active; 00146 bool _tracking_mouse_leaving; 00147 bool _maximized; 00148 bool _bCursor_in_WindowClientArea; 00149 HANDLE _input_device_handle[32]; 00150 HCURSOR _cursor; 00151 DEVMODE _fullscreen_display_mode; 00152 00153 // This is used to remember the state of the keyboard when keyboard 00154 // focus is lost. 00155 enum { num_virtual_keys = 256 }; 00156 // You might be wondering why the above is an enum. Originally the line 00157 // read "static const int num_virtual_keys = 256" 00158 // but in trying to support the MSVC6 compiler, we found that you 00159 // were not allowed to define the value of a const within a class like 00160 // that. Defining the value outside the class helps, but then we can't 00161 // use the value to define the length of the _keyboard_state array, and 00162 // also it creates multiply defined symbol errors when you link, because 00163 // other files include this header file. This enum is a clever solution 00164 // to work around the problem. 00165 00166 BYTE _keyboard_state[num_virtual_keys]; 00167 bool _lost_keypresses; 00168 00169 // These are used to store the status of the individual left and right 00170 // shift, control, and alt keys. Keyboard events are not sent for 00171 // these individual keys, but for each pair as a whole. The status 00172 // of each key must be checked as keypress and keyrelease events are 00173 // received. 00174 bool _lshift_down; 00175 bool _rshift_down; 00176 bool _lcontrol_down; 00177 bool _rcontrol_down; 00178 bool _lalt_down; 00179 bool _ralt_down; 00180 00181 private: 00182 // We need this map to support per-window calls to window_proc(). 00183 typedef map<HWND, WinGraphicsWindow *> WindowHandles; 00184 static WindowHandles _window_handles; 00185 00186 // And we need a static pointer to the current WinGraphicsWindow we 00187 // are creating at the moment, since CreateWindow() starts 00188 // generating window events before it gives us the window handle. 00189 static WinGraphicsWindow *_creating_window; 00190 00191 // This tracks the current GraphicsWindow whose client area contains 00192 // the mouse. There will only be one of these at a time, and 00193 // storing the pointer here allows us to handle ambiguities in the 00194 // order in which messages are passed from Windows to the various 00195 // windows we manage. This pointer is used by 00196 // set_cursor_in_window() to determine when it is time to call 00197 // update_cursor() to hide the cursor (or do other related 00198 // operations). 00199 static WinGraphicsWindow *_cursor_window; 00200 static bool _cursor_hidden; 00201 static bool _got_saved_params; 00202 static int _saved_mouse_trails; 00203 static BOOL _saved_cursor_shadow; 00204 static BOOL _saved_mouse_vanish; 00205 00206 // Since the Panda API requests icons and cursors by filename, we 00207 // need a table mapping filenames to handles, so we can avoid 00208 // re-reading the file each time we change icons. 00209 typedef pmap<Filename, HANDLE> IconFilenames; 00210 static IconFilenames _icon_filenames; 00211 static IconFilenames _cursor_filenames; 00212 00213 static HICON get_icon(const Filename &filename); 00214 static HCURSOR get_cursor(const Filename &filename); 00215 00216 // The table of window classes we have registered. We need to 00217 // register a different window class for each different window icon 00218 // (the cursor we can specify dynamically, later). We might have 00219 // other requirements too, later. 00220 class WindowClass { 00221 public: 00222 INLINE WindowClass(const WindowProperties &props); 00223 INLINE bool operator < (const WindowClass &other) const; 00224 00225 string _name; 00226 HICON _icon; 00227 }; 00228 00229 typedef pset<WindowClass> WindowClasses; 00230 static WindowClasses _window_classes; 00231 static int _window_class_index; 00232 00233 static const WindowClass ®ister_window_class(const WindowProperties &props); 00234 private: 00235 // This subclass of WindowHandle is stored in _window_handle to 00236 // represent this particular window. We use it to add hooks for 00237 // communicating with the parent window, in particular to receive 00238 // keyboard events from the parent window when necessary. 00239 class WinWindowHandle : public WindowHandle { 00240 public: 00241 WinWindowHandle(WinGraphicsWindow *window, 00242 const WindowHandle ©); 00243 void clear_window(); 00244 00245 protected: 00246 virtual void receive_windows_message(unsigned int msg, int wparam, int lparam); 00247 00248 private: 00249 // Not reference-counted, to avoid a circular reference count. 00250 WinGraphicsWindow *_window; 00251 00252 public: 00253 static TypeHandle get_class_type() { 00254 return _type_handle; 00255 } 00256 static void init_type() { 00257 WindowHandle::init_type(); 00258 register_type(_type_handle, "WinWindowHandle", 00259 WindowHandle::get_class_type()); 00260 } 00261 virtual TypeHandle get_type() const { 00262 return get_class_type(); 00263 } 00264 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00265 00266 private: 00267 static TypeHandle _type_handle; 00268 }; 00269 00270 public: 00271 static TypeHandle get_class_type() { 00272 return _type_handle; 00273 } 00274 static void init_type() { 00275 GraphicsWindow::init_type(); 00276 register_type(_type_handle, "WinGraphicsWindow", 00277 GraphicsWindow::get_class_type()); 00278 WinWindowHandle::init_type(); 00279 } 00280 virtual TypeHandle get_type() const { 00281 return get_class_type(); 00282 } 00283 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00284 00285 private: 00286 static TypeHandle _type_handle; 00287 }; 00288 00289 #define PRINT_LAST_ERROR 0 00290 extern EXPCL_PANDAWIN void PrintErrorMessage(DWORD msgID); 00291 extern EXPCL_PANDAWIN void ClearToBlack(HWND hWnd, const WindowProperties &props); 00292 extern EXPCL_PANDAWIN void get_client_rect_screen(HWND hwnd, RECT *view_rect); 00293 00294 #include "winGraphicsWindow.I" 00295 00296 #endif