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