| 1 | // Copyright (c) 1998-1999 Matra Datavision |
| 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
| 3 | // |
| 4 | // This file is part of Open CASCADE Technology software library. |
| 5 | // |
| 6 | // This library is free software; you can redistribute it and/or modify it under |
| 7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 8 | // by the Free Software Foundation, with special exception defined in the file |
| 9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 10 | // distribution for complete text of the license and disclaimer of any warranty. |
| 11 | // |
| 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 13 | // commercial license or contractual agreement. |
| 14 | |
| 15 | #if defined(_WIN32) |
| 16 | // include windows.h first to have all definitions available |
| 17 | #include <windows.h> |
| 18 | #endif |
| 19 | |
| 20 | #include <WNT_Window.hxx> |
| 21 | |
| 22 | #if defined(_WIN32) && !defined(OCCT_UWP) |
| 23 | |
| 24 | #include <Aspect_Convert.hxx> |
| 25 | #include <Aspect_WindowDefinitionError.hxx> |
| 26 | #include <Aspect_WindowError.hxx> |
| 27 | #include <Standard_Type.hxx> |
| 28 | #include <TCollection_ExtendedString.hxx> |
| 29 | #include <WNT_WClass.hxx> |
| 30 | |
| 31 | IMPLEMENT_STANDARD_RTTIEXT(WNT_Window, Aspect_Window) |
| 32 | |
| 33 | // ======================================================================= |
| 34 | // function : WNT_Window |
| 35 | // purpose : |
| 36 | // ======================================================================= |
| 37 | WNT_Window::WNT_Window (const Standard_CString theTitle, |
| 38 | const Handle(WNT_WClass)& theClass, |
| 39 | const WNT_Dword& theStyle, |
| 40 | const Standard_Integer thePxLeft, |
| 41 | const Standard_Integer thePxTop, |
| 42 | const Standard_Integer thePxWidth, |
| 43 | const Standard_Integer thePxHeight, |
| 44 | const Quantity_NameOfColor theBackColor, |
| 45 | const Aspect_Handle theParent, |
| 46 | const Aspect_Handle theMenu, |
| 47 | const Standard_Address theClientStruct) |
| 48 | : Aspect_Window(), |
| 49 | aXLeft (thePxLeft), |
| 50 | aYTop (thePxTop), |
| 51 | aXRight (thePxLeft + thePxWidth), |
| 52 | aYBottom (thePxTop + thePxHeight), |
| 53 | myWClass (theClass), |
| 54 | myIsForeign (Standard_False) |
| 55 | { |
| 56 | if (thePxWidth <= 0 || thePxHeight <= 0) |
| 57 | { |
| 58 | throw Aspect_WindowDefinitionError("Coordinate(s) out of range"); |
| 59 | } |
| 60 | |
| 61 | DWORD aStyle = theStyle; |
| 62 | if (theParent && !(theStyle & WS_CHILD)) |
| 63 | { |
| 64 | aStyle |= WS_CHILD | WS_CLIPSIBLINGS; |
| 65 | } |
| 66 | else if (!theParent && !(theStyle & WS_CLIPCHILDREN)) |
| 67 | { |
| 68 | aStyle |= WS_CLIPCHILDREN; |
| 69 | } |
| 70 | |
| 71 | // include decorations in the window dimensions to reproduce same behavior of Xw_Window |
| 72 | RECT aRect; |
| 73 | aRect.top = aYTop; |
| 74 | aRect.bottom = aYBottom; |
| 75 | aRect.left = aXLeft; |
| 76 | aRect.right = aXRight; |
| 77 | AdjustWindowRect (&aRect, aStyle, theMenu != NULL ? TRUE : FALSE); |
| 78 | aXLeft = aRect.left; |
| 79 | aYTop = aRect.top; |
| 80 | aXRight = aRect.right; |
| 81 | aYBottom = aRect.bottom; |
| 82 | |
| 83 | const TCollection_ExtendedString aTitleW (theTitle); |
| 84 | const TCollection_ExtendedString aClassNameW (myWClass->Name()); |
| 85 | myHWindow = CreateWindowW (aClassNameW.ToWideString(), aTitleW.ToWideString(), |
| 86 | aStyle, |
| 87 | aXLeft, aYTop, |
| 88 | (aXRight - aXLeft), (aYBottom - aYTop), |
| 89 | (HWND )theParent, |
| 90 | (HMENU )theMenu, |
| 91 | (HINSTANCE )myWClass->Instance(), |
| 92 | theClientStruct); |
| 93 | if (!myHWindow) |
| 94 | { |
| 95 | throw Aspect_WindowDefinitionError("Unable to create window"); |
| 96 | } |
| 97 | |
| 98 | myHParentWindow = theParent; |
| 99 | SetBackground (theBackColor); |
| 100 | } |
| 101 | |
| 102 | // ======================================================================= |
| 103 | // function : WNT_Window |
| 104 | // purpose : |
| 105 | // ======================================================================= |
| 106 | WNT_Window::WNT_Window (const Aspect_Handle theHandle, |
| 107 | const Quantity_NameOfColor theBackColor) |
| 108 | : myIsForeign (Standard_True) |
| 109 | { |
| 110 | myHWindow = theHandle; |
| 111 | myHParentWindow = GetParent ((HWND )theHandle); |
| 112 | |
| 113 | SetBackground (theBackColor); |
| 114 | |
| 115 | WINDOWPLACEMENT aPlace; |
| 116 | aPlace.length = sizeof (WINDOWPLACEMENT); |
| 117 | ::GetWindowPlacement ((HWND )myHWindow, &aPlace); |
| 118 | |
| 119 | aXLeft = aPlace.rcNormalPosition.left; |
| 120 | aYTop = aPlace.rcNormalPosition.top; |
| 121 | aXRight = aPlace.rcNormalPosition.right; |
| 122 | aYBottom = aPlace.rcNormalPosition.bottom; |
| 123 | } |
| 124 | |
| 125 | // ======================================================================= |
| 126 | // function : ~WNT_Window |
| 127 | // purpose : |
| 128 | // ======================================================================= |
| 129 | WNT_Window::~WNT_Window() |
| 130 | { |
| 131 | if (myHWindow == NULL |
| 132 | || myIsForeign) |
| 133 | { |
| 134 | return; |
| 135 | } |
| 136 | |
| 137 | DestroyWindow ((HWND )myHWindow); |
| 138 | myIsForeign = Standard_False; |
| 139 | } |
| 140 | |
| 141 | // ======================================================================= |
| 142 | // function : SetCursor |
| 143 | // purpose : |
| 144 | // ======================================================================= |
| 145 | void WNT_Window::SetCursor (const Aspect_Handle theCursor) const |
| 146 | { |
| 147 | ::SetClassLongPtrW ((HWND )myHWindow, GCLP_HCURSOR, (LONG_PTR )theCursor); |
| 148 | } |
| 149 | |
| 150 | // ======================================================================= |
| 151 | // function : IsMapped |
| 152 | // purpose : |
| 153 | // ======================================================================= |
| 154 | Standard_Boolean WNT_Window::IsMapped() const |
| 155 | { |
| 156 | if (IsVirtual()) |
| 157 | { |
| 158 | return Standard_True; |
| 159 | } |
| 160 | |
| 161 | WINDOWPLACEMENT aPlace; |
| 162 | aPlace.length = sizeof (WINDOWPLACEMENT); |
| 163 | ::GetWindowPlacement ((HWND )myHWindow, &aPlace); |
| 164 | return !(aPlace.showCmd == SW_HIDE |
| 165 | || aPlace.showCmd == SW_MINIMIZE); |
| 166 | } |
| 167 | |
| 168 | // ======================================================================= |
| 169 | // function : Map |
| 170 | // purpose : |
| 171 | // ======================================================================= |
| 172 | void WNT_Window::Map() const |
| 173 | { |
| 174 | if (!IsVirtual()) |
| 175 | { |
| 176 | Map (SW_SHOW); |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | // ======================================================================= |
| 181 | // function : Map |
| 182 | // purpose : |
| 183 | // ======================================================================= |
| 184 | void WNT_Window::Map (const Standard_Integer theMapMode) const |
| 185 | { |
| 186 | if (IsVirtual()) |
| 187 | { |
| 188 | return; |
| 189 | } |
| 190 | |
| 191 | ::ShowWindow ((HWND )myHWindow, theMapMode); |
| 192 | ::UpdateWindow ((HWND )myHWindow); |
| 193 | } |
| 194 | |
| 195 | // ======================================================================= |
| 196 | // function : Unmap |
| 197 | // purpose : |
| 198 | // ======================================================================= |
| 199 | void WNT_Window::Unmap() const |
| 200 | { |
| 201 | Map (SW_HIDE); |
| 202 | } |
| 203 | |
| 204 | // ======================================================================= |
| 205 | // function : DoResize |
| 206 | // purpose : |
| 207 | // ======================================================================= |
| 208 | Aspect_TypeOfResize WNT_Window::DoResize() const |
| 209 | { |
| 210 | if (IsVirtual()) |
| 211 | { |
| 212 | return Aspect_TOR_UNKNOWN; |
| 213 | } |
| 214 | |
| 215 | int mask = 0; |
| 216 | Aspect_TypeOfResize mode = Aspect_TOR_UNKNOWN; |
| 217 | WINDOWPLACEMENT wp; |
| 218 | |
| 219 | wp.length = sizeof ( WINDOWPLACEMENT ); |
| 220 | GetWindowPlacement ( ( HWND )myHWindow, &wp ); |
| 221 | |
| 222 | if (wp.showCmd != SW_SHOWMINIMIZED) |
| 223 | { |
| 224 | if (Abs ((int )wp.rcNormalPosition.left - aXLeft ) > 2) mask |= 1; |
| 225 | if (Abs ((int )wp.rcNormalPosition.right - aXRight ) > 2) mask |= 2; |
| 226 | if (Abs ((int )wp.rcNormalPosition.top - aYTop ) > 2) mask |= 4; |
| 227 | if (Abs ((int )wp.rcNormalPosition.bottom - aYBottom) > 2) mask |= 8; |
| 228 | |
| 229 | switch (mask) |
| 230 | { |
| 231 | case 0: |
| 232 | mode = Aspect_TOR_NO_BORDER; |
| 233 | break; |
| 234 | case 1: |
| 235 | mode = Aspect_TOR_LEFT_BORDER; |
| 236 | break; |
| 237 | case 2: |
| 238 | mode = Aspect_TOR_RIGHT_BORDER; |
| 239 | break; |
| 240 | case 4: |
| 241 | mode = Aspect_TOR_TOP_BORDER; |
| 242 | break; |
| 243 | case 5: |
| 244 | mode = Aspect_TOR_LEFT_AND_TOP_BORDER; |
| 245 | break; |
| 246 | case 6: |
| 247 | mode = Aspect_TOR_TOP_AND_RIGHT_BORDER; |
| 248 | break; |
| 249 | case 8: |
| 250 | mode = Aspect_TOR_BOTTOM_BORDER; |
| 251 | break; |
| 252 | case 9: |
| 253 | mode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; |
| 254 | break; |
| 255 | case 10: |
| 256 | mode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; |
| 257 | break; |
| 258 | default: |
| 259 | break; |
| 260 | } // end switch |
| 261 | |
| 262 | *((Standard_Integer* )&aXLeft ) = wp.rcNormalPosition.left; |
| 263 | *((Standard_Integer* )&aXRight ) = wp.rcNormalPosition.right; |
| 264 | *((Standard_Integer* )&aYTop ) = wp.rcNormalPosition.top; |
| 265 | *((Standard_Integer* )&aYBottom) = wp.rcNormalPosition.bottom; |
| 266 | } |
| 267 | |
| 268 | return mode; |
| 269 | } |
| 270 | |
| 271 | // ======================================================================= |
| 272 | // function : Ratio |
| 273 | // purpose : |
| 274 | // ======================================================================= |
| 275 | Standard_Real WNT_Window::Ratio() const |
| 276 | { |
| 277 | if (IsVirtual()) |
| 278 | { |
| 279 | return Standard_Real(aXRight - aXLeft)/ Standard_Real(aYBottom - aYTop); |
| 280 | } |
| 281 | |
| 282 | RECT aRect; |
| 283 | GetClientRect ((HWND )myHWindow, &aRect); |
| 284 | return Standard_Real(aRect.right - aRect.left) / Standard_Real(aRect.bottom - aRect.top); |
| 285 | } |
| 286 | |
| 287 | // ======================================================================= |
| 288 | // function : Position |
| 289 | // purpose : |
| 290 | // ======================================================================= |
| 291 | void WNT_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1, |
| 292 | Standard_Integer& theX2, Standard_Integer& theY2) const |
| 293 | { |
| 294 | if (IsVirtual()) |
| 295 | { |
| 296 | theX1 = aXLeft; |
| 297 | theX2 = aXRight; |
| 298 | theY1 = aYTop; |
| 299 | theY2 = aYBottom; |
| 300 | return; |
| 301 | } |
| 302 | |
| 303 | RECT aRect; |
| 304 | ::GetClientRect ((HWND )myHWindow, &aRect); |
| 305 | |
| 306 | POINT aPntLeft, aPntRight; |
| 307 | aPntLeft.x = aPntLeft.y = 0; |
| 308 | ::ClientToScreen ((HWND )myHWindow, &aPntLeft); |
| 309 | aPntRight.x = aRect.right; |
| 310 | aPntRight.y = aRect.bottom; |
| 311 | ::ClientToScreen ((HWND )myHWindow, &aPntRight); |
| 312 | |
| 313 | if (myHParentWindow != NULL) |
| 314 | { |
| 315 | ::ScreenToClient ((HWND )myHParentWindow, &aPntLeft); |
| 316 | ::ScreenToClient ((HWND )myHParentWindow, &aPntRight); |
| 317 | } |
| 318 | |
| 319 | theX1 = aPntLeft.x; |
| 320 | theX2 = aPntRight.x; |
| 321 | theY1 = aPntLeft.y; |
| 322 | theY2 = aPntRight.y; |
| 323 | } |
| 324 | |
| 325 | // ======================================================================= |
| 326 | // function : Size |
| 327 | // purpose : |
| 328 | // ======================================================================= |
| 329 | void WNT_Window::Size (Standard_Integer& theWidth, |
| 330 | Standard_Integer& theHeight) const |
| 331 | { |
| 332 | if (IsVirtual()) |
| 333 | { |
| 334 | theWidth = aXRight - aXLeft; |
| 335 | theHeight = aYBottom - aYTop; |
| 336 | return; |
| 337 | } |
| 338 | |
| 339 | RECT aRect; |
| 340 | ::GetClientRect ((HWND )myHWindow, &aRect); |
| 341 | theWidth = aRect.right; |
| 342 | theHeight = aRect.bottom; |
| 343 | } |
| 344 | |
| 345 | // ======================================================================= |
| 346 | // function : SetPos |
| 347 | // purpose : |
| 348 | // ======================================================================= |
| 349 | void WNT_Window::SetPos (const Standard_Integer theX, const Standard_Integer theY, |
| 350 | const Standard_Integer theX1, const Standard_Integer theY1) |
| 351 | { |
| 352 | aXLeft = theX; |
| 353 | aYTop = theY; |
| 354 | aXRight = theX1; |
| 355 | aYBottom = theY1; |
| 356 | } |
| 357 | |
| 358 | // ======================================================================= |
| 359 | // function : InvalidateContent |
| 360 | // purpose : |
| 361 | // ======================================================================= |
| 362 | void WNT_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& ) |
| 363 | { |
| 364 | if (myHWindow != NULL) |
| 365 | { |
| 366 | ::InvalidateRect ((HWND )myHWindow, NULL, TRUE); |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | #endif // _WIN32 |