1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // License Agreement: 4 // 5 // The following are Copyright � 2007, Casey Langen 6 // 7 // Sources and Binaries of: win32cpp 8 // 9 // All rights reserved. 10 // 11 // Redistribution and use in source and binary forms, with or without 12 // modification, are permitted provided that the following conditions are met: 13 // 14 // * Redistributions of source code must retain the above copyright notice, 15 // this list of conditions and the following disclaimer. 16 // 17 // * Redistributions in binary form must reproduce the above copyright 18 // notice, this list of conditions and the following disclaimer in the 19 // documentation and/or other materials provided with the distribution. 20 // 21 // * Neither the name of the author nor the names of other contributors may 22 // be used to endorse or promote products derived from this software 23 // without specific prior written permission. 24 // 25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 // POSSIBILITY OF SUCH DAMAGE. 36 // 37 ////////////////////////////////////////////////////////////////////////////// 38 39 #pragma once 40 41 ////////////////////////////////////////////////////////////////////////////// 42 // Forward declare 43 namespace win32cpp { 44 struct Color; 45 } 46 ////////////////////////////////////////////////////////////////////////////// 47 48 49 #include <win32cpp/Win32Config.hpp> 50 #include <win32cpp/Types.hpp> 51 #include <win32cpp/Exception.hpp> 52 #include <win32cpp/Font.hpp> 53 #include <win32cpp/Menu.hpp> 54 #include <win32cpp/WindowPadding.hpp> 55 56 #include <vector> 57 #include <map> 58 #include <set> 59 60 ////////////////////////////////////////////////////////////////////////////// 61 62 namespace win32cpp { 63 64 ////////////////////////////////////////////////////////////////////////////// 65 66 class Window; 67 68 ///\brief Flags used for control layout 69 enum LayoutFlags 70 { 71 LayoutFillParent = -1, /*!< */ 72 LayoutWrapContent = -2, /*!< */ 73 LayoutWrapWrap = -3, /*!< */ 74 LayoutFillWrap = -4, /*!< */ 75 LayoutWrapFill = -5, /*!< */ 76 LayoutFillFill = -6 /*!< */ 77 }; 78 79 ///\brief Specifies the alignment of a Layout's child 80 enum LayoutAlignFlag 81 { 82 LayoutAlignLeft = 0, /*!< */ 83 LayoutAlignRight = 1, /*!< */ 84 LayoutAlignCenter = 2, /*!< */ 85 LayoutAlignTop = 0, /*!< */ 86 LayoutAlignBottom = 1, /*!< */ 87 LayoutAlignMiddle = 2, /*!< */ 88 }; 89 90 ///\brief Flags used for mouse related events emitted by Window. 91 enum MouseEventFlags 92 { 93 MouseShiftKey = MK_SHIFT, /*!< */ 94 MouseCtrlKey = MK_CONTROL, /*!< */ 95 MouseLeftButton = MK_LBUTTON, /*!< */ 96 MouseMiddleButton = MK_MBUTTON, /*!< */ 97 MouseRightButton = MK_RBUTTON, /*!< */ 98 MouseX1Button = MK_XBUTTON1, /*!< */ 99 MouseX2Button = MK_XBUTTON2 /*!< */ 100 }; 101 102 /*! */ typedef DWORD VirtualKeyCode; 103 /*! */ typedef DWORD KeyEventFlags; 104 105 /*! */ typedef sigslot::signal1<Window*> DestroyedEvent; 106 /*! */ typedef sigslot::signal1<Window*> CreatedEvent; 107 /*! */ typedef sigslot::signal2<Window*, Point> MovedEvent; 108 /*! */ typedef sigslot::signal2<Window*, Size> ResizedEvent; 109 /*! */ typedef sigslot::signal1<Window*> MouseEnterEvent; 110 /*! */ typedef sigslot::signal1<Window*> MouseExitEvent; 111 /*! */ typedef sigslot::signal3<Window*, MouseEventFlags, Point> MouseMovedEvent; 112 /*! */ typedef sigslot::signal3<Window*, MouseEventFlags, Point> MouseButtonEvent; 113 /*! */ typedef sigslot::signal1<Window*> ThemeChangedEvent; 114 /*! */ typedef sigslot::signal1<Window* /*this*/> FocusEvent; 115 /*! */ typedef sigslot::signal2<Window* /*old*/, Window* /*new*/> ParentChangedEvent; 116 /*! */ typedef sigslot::signal1<unsigned int> TimerEvent; 117 /*! */ typedef sigslot::signal3<Window*, VirtualKeyCode, KeyEventFlags> KeyEvent; 118 /*! */ typedef sigslot::signal2<Window*, bool> VisibilityChangedEvent; 119 /*! */ typedef sigslot::signal1<Window*> LayoutParamsChangedEvent; 120 121 ///\brief 122 ///Window is the abstract base class for all controls. 123 /// 124 ///Based on sigslot signals, Window follows the observer/notifier pattern 125 ///and is able to "emit" notifications to listeners that are not 126 ///necessarily GUI objects. This promotes use of the model/view/controller 127 ///design pattern, which is highly recommended. Window also attempts to 128 ///automatically double buffer all drawing, so controls don't flicker when 129 ///they are moved or resized. This is accomplished using the MemoryDC 130 ///and RedrawLock classes. 131 /// 132 ///The Window class also provides "stable" mouse events for derived 133 ///classes, including consistant cursor enter and exit notifications. 134 /*abstract*/ class Window: public EventHandler 135 { 136 public: // types 137 ///\brief 138 ///This exception will be thrown if Initialize() is called on a 139 ///Window that has already been created. 140 class WindowAlreadyCreatedException: public Exception { }; 141 ///\brief 142 ///This exception may be thrown if operations are attempted on a 143 ///Window that has not been created. 144 class WindowNotCreatedException: public Exception { }; 145 ///\brief 146 ///This exception is thrown if a Window fails to be created. 147 class WindowCreationFailedException: public Exception { }; 148 ///\brief 149 ///This exception is thrown if a Window parameter is NULL where it shouldn't be. 150 class WindowIsNullException: public Exception { }; 151 ///\brief 152 ///This exception is thrown if an invalid (negative) LayoutWeight is specified. 153 class InvalidLayoutWeightException: public Exception { }; 154 ///\brief 155 ///This exception is thrown if invalid layout flags are specified. 156 class InvalidLayoutFlagsException: public Exception { }; 157 158 protected: // types 159 typedef WNDPROC WindowProcFunc; 160 typedef std::vector<Window*> WindowList; 161 typedef std::map<HWND, Window*> HandleToWindowMap; 162 typedef sigslot::_signal_base<sigslot::SIGSLOT_DEFAULT_MT_POLICY> SignalBase; 163 typedef std::set<SignalBase*> SignalList; 164 typedef std::unique_ptr<Color> ColorRef; 165 166 enum FocusDirection 167 { 168 FocusForward, 169 FocusBackward 170 }; 171 172 public: // events 173 ///\brief Emitted when the WM_DESTROY message is received. 174 DestroyedEvent Destroyed; 175 ///\brief Emitted when the Window is created. This is not necessarily 176 ///at construction time, as Windows are lazily created. 177 CreatedEvent Created; 178 ///\brief Emitted when the Window is repositioned. 179 MovedEvent Moved; 180 ///\brief Emitted when the Window is resized. 181 ResizedEvent Resized; 182 ///\brief Emitted when the cursor is moved over the Window. 183 MouseMovedEvent MouseMoved; 184 ///\brief Emitted when a mouse button has been pressed over the Window. 185 MouseButtonEvent MouseButtonDown; 186 ///\brief Emitted when a mouse button has been released over the Window. 187 MouseButtonEvent MouseButtonUp; 188 ///\brief Emitted when a mouse button has been double clicked over the Window. 189 MouseButtonEvent MouseButtonDoubleClicked; 190 ///\brief Emitted when the cursor has entered the Window. 191 MouseEnterEvent MouseEnter; 192 ///\brief Emitted when the cursor has left the Window. 193 MouseExitEvent MouseExit; 194 ///\brief Emitted when the desktop theme has changed. 195 ThemeChangedEvent ThemeChanged; 196 ///\brief Emitted when the Window has gained focus. 197 FocusEvent GainedFocus; 198 ///\brief Emitted when the Window has lost focus. 199 FocusEvent LostFocus; 200 ///\brief Emitted when the Window's parent has changed. 201 ParentChangedEvent ParentChanged; 202 ///\brief Emitted when a timer gets a timeout. 203 TimerEvent TimerTimeout; 204 ///\brief Emitted when a key on the keyboard is pressed down. 205 KeyEvent KeyDown; 206 ///\brief Emitted when a key on the keyboard is released. 207 KeyEvent KeyUp; 208 ///\brief Emitted when a key on the keyboard is pressed. 209 KeyEvent Char; 210 ///\brief Emitted when a control has requested to focus the next control. This 211 ///generally shouldn't be handled explicitly unless absolutely necessary. 212 FocusEvent RequestFocusNext; 213 ///\brief Emitted when a control has requested to focus the previous control. This 214 ///generally shouldn't be handled explicitly unless absolutely necessary. 215 FocusEvent RequestFocusPrev; 216 ///\brief Emitted when a Window's visibility has changed 217 VisibilityChangedEvent VisibilityChanged; 218 ///\brief Emitted when a Window's layout parameters have changed. 219 LayoutParamsChangedEvent LayoutParametersChanged; 220 221 public: // ctor, dtor 222 /*ctor*/ Window(); 223 /*ctor*/ Window(LayoutFlags layoutFlags); 224 /*dtor*/ virtual ~Window(); 225 226 public: // methods 227 void Initialize(Window* parent = NULL); 228 bool Show(int showCommand); 229 bool MoveTo(int x, int y); 230 bool MoveRelativeTo(int x, int y); 231 bool MoveTo(const Point& location); 232 bool Resize(int width, int height); 233 bool Resize(const Size& size); 234 bool SetRectangle(const Rect& rectangle); 235 bool Enable(bool enable); 236 uistring Caption() const; 237 bool SetCaption(const uistring& caption); 238 Rect ClientRect() const; 239 Rect WindowRect() const; 240 Size WindowSize() const; 241 virtual Size ClientSize() const; 242 Point Location() const; 243 Point CursorPosition() const; 244 LRESULT SendMessage(UINT message, WPARAM wParam, LPARAM lParam); 245 bool PostMessage(UINT message, WPARAM wParam, LPARAM lParam); 246 HWND Handle() const; 247 virtual bool Destroy(); 248 Window* Parent() const; 249 void Redraw() const; 250 void SetFont(FontRef font); 251 FontRef Font() const; 252 void SetMenu(MenuRef menu); 253 MenuRef Menu(); 254 void SetVisible(bool visible = true); 255 bool Visible(); 256 void SetBackgroundColor(const Color& color); 257 Color BackgroundColor() const; 258 bool SetFocus(); 259 bool TabStop(); 260 void SetTabStop(bool enabled); 261 LayoutFlags LayoutWidth() const; 262 LayoutFlags LayoutHeight() const; 263 LayoutAlignFlag LayoutAlignment() const; 264 void SetLayoutFlags(LayoutFlags widthFlag, LayoutFlags heightFlag); 265 void SetLayoutFlags(LayoutFlags flags); 266 void SetLayoutAlignment(LayoutAlignFlag alignment); 267 float LayoutWeight() const; 268 void SetLayoutWeight(float weight); 269 270 static Window* SubclassedWindowFromHWND(HWND hwnd); 271 272 public: // operators operator bool()273 operator bool() { return (this->windowHandle != NULL); } 274 275 protected: // methods 276 // pure virtuals 277 virtual HWND Create(Window* parent = NULL) = 0; 278 279 // subclassing, mouse capture 280 static void SubclassWindowProc(Window* window); 281 static void UnSubclassWindowProc(Window* window); 282 static bool IsWindowSubclassed(Window* window); 283 static Window* WindowUnderCursor(HWND* targetHwnd = NULL); 284 static void BeginCapture(Window* window); 285 static void EndCapture(Window* window); 286 static void SetParent(Window* child, Window* newParent); 287 static void ForceMeasureItem(const Window* window); 288 static Window* Capture(); 289 290 // win32 event wrappers (template pattern, effective c++ item 35) 291 void OnDestroyedBase(); 292 void OnCreatedBase(); 293 void OnMovedBase(const Point& location); 294 void OnResizedBase(const Size& newSize); 295 void OnMouseMovedBase(MouseEventFlags flags, const Point& location); 296 void OnMouseButtonDownBase(MouseEventFlags flags, const Point& location); 297 void OnMouseButtonUpBase(MouseEventFlags flags, const Point& location); 298 void OnMouseButtonDoubleClickedBase(MouseEventFlags flags, const Point& location); 299 void OnMouseEnterBase(); 300 void OnMouseExitBase(); 301 void OnGainedFocusBase(); 302 void OnLostFocusBase(); 303 void OnThemeChangedBase(); 304 void OnParentChangedBase(Window* oldParent, Window* newParent); 305 bool OnKeyDownBase(VirtualKeyCode keyCode, KeyEventFlags flags); 306 bool OnKeyUpBase(VirtualKeyCode keyCode, KeyEventFlags flags); 307 bool OnCharBase(VirtualKeyCode keyCode, KeyEventFlags flags); 308 void OnVisibilityChangedBase(bool visible); 309 void OnLayoutParametersChangedBase(); 310 311 // win32 event wrappers (virtual methods, for derived class use) OnDestroyed()312 virtual void OnDestroyed() { } OnCreated()313 virtual void OnCreated() { } OnMoved(const Point & location)314 virtual void OnMoved(const Point& location) { } OnResized(const Size & newSize)315 virtual void OnResized(const Size& newSize) { } OnMouseMoved(MouseEventFlags flags,const Point & location)316 virtual void OnMouseMoved(MouseEventFlags flags, const Point& location) { } OnMouseButtonDown(MouseEventFlags flags,const Point & location)317 virtual void OnMouseButtonDown(MouseEventFlags flags, const Point& location) { } OnMouseButtonUp(MouseEventFlags flags,const Point & location)318 virtual void OnMouseButtonUp(MouseEventFlags flags, const Point& location) { } OnMouseButtonDoubleClicked(MouseEventFlags flags,const Point & location)319 virtual void OnMouseButtonDoubleClicked(MouseEventFlags flags, const Point& location) { } OnMouseEnter()320 virtual void OnMouseEnter() { } OnMouseExit()321 virtual void OnMouseExit() { } OnGainedFocus()322 virtual void OnGainedFocus() { } OnLostFocus()323 virtual void OnLostFocus() { } 324 virtual void OnThemeChanged(); OnFontChanged()325 virtual void OnFontChanged() { } OnMeasureItem(MEASUREITEMSTRUCT * measureItemStruct)326 virtual void OnMeasureItem(MEASUREITEMSTRUCT* measureItemStruct) { } OnParentChanged(Window * oldParent,Window * newParent)327 virtual void OnParentChanged(Window* oldParent, Window* newParent) { } OnCaptionChanged()328 virtual void OnCaptionChanged() { } OnLayoutParametersChanged()329 virtual void OnLayoutParametersChanged() { } OnKeyDown(VirtualKeyCode keyCode,KeyEventFlags flags)330 virtual bool OnKeyDown(VirtualKeyCode keyCode, KeyEventFlags flags) { return false; } OnKeyUp(VirtualKeyCode keyCode,KeyEventFlags flags)331 virtual bool OnKeyUp(VirtualKeyCode keyCode, KeyEventFlags flags) { return false; } OnChar(VirtualKeyCode keyCode,KeyEventFlags flags)332 virtual bool OnChar(VirtualKeyCode keyCode, KeyEventFlags flags) { return false; } 333 virtual void OnEraseBackground(HDC hdc); 334 virtual void OnPaint(); 335 virtual void OnRequestFocusPrev(); 336 virtual void OnRequestFocusNext(); 337 virtual HBRUSH OnControlColor(HDC hdc); OnVisibilityChanged(bool visible)338 virtual void OnVisibilityChanged(bool visible) { } 339 DrawItem(DRAWITEMSTRUCT & item)340 virtual LRESULT DrawItem(DRAWITEMSTRUCT& item) { return 0; } 341 342 // window proc related 343 virtual LRESULT PreWindowProcBase(UINT message, WPARAM wParam, LPARAM lParam, bool& discardMessage); 344 virtual LRESULT PreWindowProc(UINT message, WPARAM wParam, LPARAM lParam, bool& discardMessage); 345 void PostWindowProcBase(UINT message, WPARAM wParam, LPARAM lParam); 346 virtual void PostWindowProc(UINT message, WPARAM wParam, LPARAM lParam); 347 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); 348 LRESULT DefaultWindowProc(UINT message, WPARAM wParam, LPARAM lParam); 349 static LRESULT CALLBACK StaticWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 350 351 // misc 352 virtual void PaintToHDC(HDC hdc, const Rect& rect); 353 void SuppressSignal(SignalBase& signal); 354 static bool WindowHasParent(Window* window); 355 static bool WindowIsValid(Window* window); 356 357 private: 358 void InitializeInstance(); 359 360 protected: // instance data 361 WindowProcFunc defaultWindowProc; 362 HWND windowHandle; 363 HBRUSH backgroundBrush; 364 FontRef font; 365 MenuRef menu; 366 ColorRef backgroundColor; 367 bool usesDefaultFont; 368 SignalList suppressedSignals; 369 bool tabStop; 370 LayoutAlignFlag layoutAlignment; 371 LayoutFlags layoutWidth, layoutHeight; 372 float layoutWeight; 373 374 protected: // class data 375 static HandleToWindowMap sHandleToWindowMap; 376 static WindowList sAllChildWindows; 377 static FontRef sDefaultFont; 378 static FocusDirection sFocusDirection; 379 }; 380 381 ////////////////////////////////////////////////////////////////////////////// 382 383 } // win32cpp 384