0025024: BSplCLib::PrepareInsertKnots reports incorrect number of poles
[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 //                GG 07/03/00 Add MMSize() method
19
20 #include <WNT_Window.ixx>
21
22 #include <Image_AlienPixMap.hxx>
23 #include <Aspect_Convert.hxx>
24
25 #include <stdio.h>
26
27 //************************************************************************//
28 //***//
29 // callback function to manage window's background
30 extern LRESULT CALLBACK WNT_WndProc (
31                          HWND, UINT, WPARAM, LPARAM
32                         );
33
34 WNT_Window::WNT_Window (const Standard_CString           theTitle,
35                         const Handle(WNT_WClass)&        theClass,
36                         const WNT_Dword&                 theStyle,
37                         const Standard_Integer           thePxLeft,
38                         const Standard_Integer           thePxTop,
39                         const Standard_Integer           thePxWidth,
40                         const Standard_Integer           thePxHeight,
41                         const Quantity_NameOfColor       theBackColor,
42                         const Aspect_Handle              theParent,
43                         const Aspect_Handle              theMenu,
44                         const Standard_Address           theClientStruct)
45 : Aspect_Window(),
46   aXLeft (thePxLeft),
47   aYTop (thePxTop),
48   aXRight (thePxLeft + thePxWidth),
49   aYBottom (thePxTop + thePxHeight),
50   myWClass (theClass)
51 {
52   ZeroMemory (&myExtraData, sizeof (WNT_WindowData));
53   DWORD dwStyle = theStyle;
54
55   if (thePxWidth <= 0 || thePxHeight <= 0)
56   {
57     Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range");
58   }
59
60   if (theParent && !(theStyle & WS_CHILD))
61   {
62     dwStyle |= WS_CHILD | WS_CLIPSIBLINGS;
63   }
64   else if (!theParent && !(theStyle & WS_CLIPCHILDREN))
65   {
66     dwStyle |= WS_CLIPCHILDREN;
67   }
68
69   // include decorations in the window dimensions
70   // to reproduce same behaviour of Xw_Window.
71   RECT aRect;
72   aRect.top    = aYTop;
73   aRect.bottom = aYBottom;
74   aRect.left   = aXLeft;
75   aRect.right  = aXRight;
76   AdjustWindowRect (&aRect, dwStyle, theMenu != NULL ? TRUE : FALSE);
77   aXLeft   = aRect.left;
78   aYTop    = aRect.top;
79   aXRight  = aRect.right;
80   aYBottom = aRect.bottom;
81
82   myHWindow = CreateWindow (
83               myWClass->Name(),                 // window's class name
84               theTitle,                         // window's name
85               dwStyle,                          // window's style
86               aXLeft, aYTop,                    // window's coordinates
87               (aXRight - aXLeft), (aYBottom - aYTop),
88               (HWND )theParent,                 // window's parent
89               (HMENU )theMenu,                  // window's menu
90               (HINSTANCE )myWClass->Instance(), // application's instance
91               theClientStruct);                 // pointer to CLIENTCREATESTRUCT
92   if (!myHWindow)
93   {
94     Aspect_WindowDefinitionError::Raise ("Unable to create window");
95   }
96
97   myHParentWindow = theParent;
98   SetBackground (theBackColor);
99
100   myUsrData = (Standard_Address )SetWindowLongPtr ((HWND )myHWindow, GWLP_USERDATA, (LONG_PTR )&myExtraData);
101
102   myExtraData.WNT_Window_Ptr = (void* )this;
103
104   SetFlags (WDF_NOERASEBKGRND);
105 }
106
107 //***//
108 //************************* Constructor **********************************//
109 //***//
110 WNT_Window :: WNT_Window (
111                const Aspect_Handle                aHandle,
112                const Quantity_NameOfColor         aBackColor
113               ) : Aspect_Window()
114 {
115   doCreate (aHandle, aBackColor);
116
117   /* Bug OCC20596 */
118   SetFlags(WDF_NOERASEBKGRND);
119
120 }  // end constructor
121 //***//
122 //************************* Constructor **********************************//
123 //***//
124 WNT_Window :: WNT_Window (
125                const Standard_Integer             aPart1,
126                const Standard_Integer             aPart2,
127                const Quantity_NameOfColor         aBackColor
128               ) : Aspect_Window()
129 {
130   Aspect_Handle aHandle = ( Aspect_Handle )(  ( aPart1 << 16 ) + aPart2  );
131
132   doCreate (aHandle, aBackColor);
133
134   /* Bug OCC20596 */
135   SetFlags(WDF_NOERASEBKGRND);
136
137 }  // end constructor
138 //***//
139 //***************************** Destroy **********************************//
140 //***//
141 void WNT_Window :: Destroy ()
142 {
143   if (myHWindow)
144   {
145     if (myUsrData != Standard_Address(-1))
146     {
147       SetWindowLongPtr ((HWND )myHWindow, GWLP_USERDATA, (LONG_PTR )myUsrData);
148     }
149
150     if (!( myExtraData.dwFlags & WDF_FOREIGN))
151     {
152       DestroyWindow ((HWND )myHWindow);
153     }
154   }  // end if
155 }  // end WNT_Window :: Destroy
156
157 //**************************** SetCursor *********************************//
158 //***//
159 void WNT_Window :: SetCursor ( const Aspect_Handle aCursor ) const {
160  SetClassLongPtr ((HWND)myHWindow, GCLP_HCURSOR, (LONG_PTR)aCursor);
161 }  // end WNT_Window :: SetCursor
162
163 //***//
164 //***************************** IsMapped *********************************//
165 //***//
166 Standard_Boolean WNT_Window :: IsMapped () const {
167   if (IsVirtual()) {
168     return Standard_True;
169   }
170
171   WINDOWPLACEMENT wp;
172
173   wp.length = sizeof ( WINDOWPLACEMENT );
174   GetWindowPlacement (  ( HWND )myHWindow, &wp  );
175
176   return !(  wp.showCmd == SW_HIDE || wp.showCmd == SW_MINIMIZE );
177 }  // WNT_Window :: IsMapped
178
179 //***//
180 //***************************** Map (1) **********************************//
181 //***//
182 void WNT_Window :: Map () const {
183   if (IsVirtual()) {
184     return;
185   }
186   Map ( SW_SHOW );
187 }  // end WNT_Window :: Map
188
189 //***//
190 //***************************** Map (2) **********************************//
191 //***//
192 void WNT_Window :: Map ( const Standard_Integer aMapMode ) const {
193   if (IsVirtual()) {
194     return;
195   }
196   ShowWindow (  ( HWND )myHWindow, aMapMode  );
197   UpdateWindow (  ( HWND )myHWindow  );
198
199 }  // end WNT_Window :: Map
200
201 //***//
202 //**************************** Unmap *************************************//
203 //***//
204 void WNT_Window :: Unmap () const {
205
206  Map ( SW_HIDE );
207
208 }  // end WNT_Window :: Unmap
209
210 //***//
211 //**************************** DoResize **********************************//
212 //***//
213 Aspect_TypeOfResize WNT_Window :: DoResize () const
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 (wp.rcNormalPosition.left   - aXLeft  ) > 2) mask |= 1;
225     if (Abs (wp.rcNormalPosition.right  - aXRight ) > 2) mask |= 2;
226     if (Abs (wp.rcNormalPosition.top    - aYTop   ) > 2) mask |= 4;
227     if (Abs (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 }  // end WNT_Window :: DoResize
271
272 //***//
273 //**************************** DoMapping **********************************//
274 //***//
275 Standard_Boolean WNT_Window :: DoMapping () const {
276 // DO nothing on WNT.
277   return Standard_True;
278 }
279
280 //***//
281 //******************************* Ratio **********************************//
282 //***//
283 Quantity_Ratio WNT_Window :: Ratio () const {
284
285  RECT r;
286
287  GetClientRect (  ( HWND )myHWindow, &r  );
288
289  return ( Quantity_Ratio )(  ( Quantity_Ratio )r.right / ( Quantity_Ratio )r.bottom  );
290
291 }  // end WNT_Window :: Ratio
292
293 //***//
294 //**************************** Position (2) ******************************//
295 //***//
296 void WNT_Window :: Position (
297                     Standard_Integer& X1, Standard_Integer& Y1,
298                     Standard_Integer& X2, Standard_Integer& Y2
299                    ) const {
300
301  POINT ptl, ptr;
302  RECT  r;
303
304  GetClientRect (  ( HWND )myHWindow, &r  );
305
306  ptl.x = ptl.y = 0;
307  ClientToScreen (  ( HWND )myHWindow, &ptl  );
308  ptr.x = r.right;
309  ptr.y = r.bottom;
310  ClientToScreen (  ( HWND )myHWindow, &ptr  );
311
312  if ( myHParentWindow ) {
313
314   ScreenToClient (      ( HWND )myHParentWindow, &ptl  );
315   ScreenToClient (  ( HWND )myHParentWindow, &ptr  );
316
317  }  // end if
318
319  X1 = ptl.x;
320  X2 = ptr.x;
321  Y1 = ptl.y;
322  Y2 = ptr.y;
323
324 }  // end WNT_Window :: Position
325
326 //***//
327 //******************************* Size (2) *******************************//
328 //***//
329 void WNT_Window :: Size (
330                     Standard_Integer& Width, Standard_Integer& Height
331                    ) const {
332
333  RECT r;
334
335  GetClientRect (  ( HWND )myHWindow, &r  );
336
337  Width  = r.right;
338  Height = r.bottom;
339
340 }  // end WNT_Window :: Size
341
342 //***//
343 //******************************* SetPos *********************************//
344 //***//
345 void WNT_Window :: SetPos (
346                     const Standard_Integer X,  const Standard_Integer Y,
347                     const Standard_Integer X1, const Standard_Integer Y1
348                    ) {
349
350  aXLeft   = X;
351  aYTop    = Y;
352  aXRight  = X1;
353  aYBottom = Y1;
354
355 }  // end WNT_Window :: SetPos
356
357 //***//
358 //**************************** SetFlags **********************************//
359 //***//
360 void WNT_Window :: SetFlags ( const Standard_Integer aFlags ) {
361
362  myExtraData.dwFlags |= aFlags;
363
364 }  // end WNT_Window :: SetFlags
365
366 //***//
367 //*************************** ResetFlags *********************************//
368 //***//
369 void WNT_Window :: ResetFlags ( const Standard_Integer aFlags ) {
370
371  myExtraData.dwFlags &= ~aFlags;
372
373 }  // end WNT_Window :: ResetFlags
374
375 //***//
376 //*************************** doCreate **********************************//
377 //***//
378 void WNT_Window :: doCreate (
379                     const Aspect_Handle                aHandle,
380                     const Quantity_NameOfColor         aBackColor
381                    )
382 {
383   ZeroMemory (&myExtraData, sizeof (WNT_WindowData));
384
385   myHWindow        = aHandle;
386   myHParentWindow  = GetParent ((HWND )aHandle);
387   LONG_PTR uData   = GetWindowLongPtr ((HWND )aHandle, GWLP_USERDATA);
388   myUsrData        = Standard_Address(-1);
389
390   SetBackground (aBackColor);
391
392   myExtraData.WNT_Window_Ptr = (void* )this;
393
394   if (uData != (LONG_PTR )&myExtraData)
395   {
396     myUsrData = (Standard_Address )SetWindowLongPtr ((HWND )myHWindow, GWLP_USERDATA, (LONG_PTR )&myExtraData);
397   }
398
399   myExtraData.dwFlags = WDF_FOREIGN;
400
401   WINDOWPLACEMENT wp;
402   wp.length = sizeof (WINDOWPLACEMENT);
403   GetWindowPlacement ((HWND )myHWindow, &wp);
404
405   aXLeft   = wp.rcNormalPosition.left;
406   aYTop    = wp.rcNormalPosition.top;
407   aXRight  = wp.rcNormalPosition.right;
408   aYBottom = wp.rcNormalPosition.bottom;
409 }  // end WNT_Window :: doCreate