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