1 #include "win32\win32guts.h"
2 #include <commdlg.h>
3 #ifndef _APRICOT_H_
4 #include "apricot.h"
5 #endif
6 #include "guts.h"
7 #include "File.h"
8 #include "Menu.h"
9 #include "Image.h"
10 #include "Region.h"
11 #include "Window.h"
12 #include "Application.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18
19 #define sys (( PDrawableData)(( PComponent) self)-> sysData)->
20 #define dsys( view) (( PDrawableData)(( PComponent) view)-> sysData)->
21 #define var (( PWidget) self)->
22 #define HANDLE sys handle
23 #define DHANDLE(x) dsys(x) handle
24 #define GET_REGION(obj) (&(dsys(obj)s.region))
25
26 #define WinShowWindow(WND) SetWindowPos( WND, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
27 #define WinHideWindow(WND) SetWindowPos( WND, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_HIDEWINDOW);
28 #define apc_widget_redraw(self) apc_widget_invalidate_rect(self,NULL)
29
30 void
process_transparents(Handle self)31 process_transparents( Handle self)
32 {
33 int i;
34 RECT mr;
35 objCheck;
36 GetWindowRect(( HWND) var handle, &mr);
37 for ( i = 0; i < var widgets. count; i++) {
38 HWND xwnd;
39 Handle x = var widgets. items[ i];
40 dobjCheck(x);
41 xwnd = DHANDLE(x);
42 if ( dsys(x) options. aptTransparent && IsWindowVisible( xwnd)) {
43 RECT r, dr;
44 GetWindowRect( xwnd, &r);
45 IntersectRect( &dr, &r, &mr);
46 if ( !IsRectEmpty( &dr))
47 InvalidateRect( xwnd, NULL, false);
48 }
49 }
50 }
51
52 typedef struct _ViewProfile {
53 ColorSet colors;
54 Point pos;
55 Point size;
56 Point virtSize;
57 Bool enabled;
58 Bool visible;
59 Bool focused;
60 Handle capture;
61 HRGN shape;
62 } ViewProfile, *PViewProfile;
63
64
65 static void
get_view_ex(Handle self,PViewProfile p)66 get_view_ex( Handle self, PViewProfile p)
67 {
68 int i;
69 if ( !p) return;
70 p-> capture = apc_widget_is_captured( self);
71 for ( i = 0; i <= ciMaxId; i++) p-> colors[ i] = apc_widget_get_color( self, i);
72 if ( sys className == WC_FRAME) {
73 p-> pos = apc_window_get_client_pos( self);
74 p-> size = apc_window_get_client_size( self);
75 } else {
76 p-> pos = apc_widget_get_pos( self);
77 p-> size = apc_widget_get_size( self);
78 }
79 p-> virtSize = var virtualSize;
80 p-> enabled = apc_widget_is_enabled( self);
81 p-> focused = apc_widget_is_focused( self);
82 p-> visible = apc_widget_is_visible( self);
83 p-> shape = CreateRectRgn(0,0,0,0);
84 if ( sys className == WC_FRAME && is_apt(aptLayered))
85 i = GetWindowRgn((HWND) var handle, p->shape);
86 else
87 i = GetWindowRgn( HANDLE, p->shape);
88 if (!i) {
89 DeleteObject(p->shape);
90 p->shape = NULL;
91 }
92 }
93
94 static void
set_view_ex(Handle self,PViewProfile p)95 set_view_ex( Handle self, PViewProfile p)
96 {
97 int i;
98 Bool clip_by_children;
99 if ( sys className == WC_FRAME && is_apt(aptLayered)) {
100 SetWindowRgn((HWND) var handle, p-> shape, true);
101 } else
102 SetWindowRgn( HANDLE, p-> shape, true);
103 apc_widget_set_visible( self, false);
104 for ( i = 0; i <= ciMaxId; i++) apc_widget_set_color( self, p-> colors[i], i);
105 apc_widget_set_font( self, &var font);
106 if ( sys className == WC_FRAME) {
107 apc_window_set_client_rect( self, p-> pos. x, p-> pos. y, p-> size.x, p-> size.y);
108 } else {
109 apc_widget_set_rect( self, p-> pos. x, p-> pos. y, p-> size.x, p-> size.y);
110 }
111 var virtualSize = p-> virtSize;
112 apc_widget_set_enabled( self, p-> enabled);
113 if ( p-> focused) apc_widget_set_focused( self);
114
115 clip_by_children = is_apt(aptClipByChildren);
116 apt_set(aptClipByChildren); /* by default widget created with clipping */
117 apc_widget_set_clip_by_children(self, clip_by_children);
118
119 apc_widget_set_visible( self, p-> visible);
120 if ( p-> capture) apc_widget_set_capture( self, 1, NULL_HANDLE);
121 if ( !InvalidateRect(( HWND) var handle, NULL, false)) apiErr;
122 process_transparents( self);
123 }
124
repost_msgs(PostMsg * msg,Handle self)125 static Bool repost_msgs( PostMsg * msg, Handle self)
126 {
127 PostMessage(( HWND) var handle, WM_POSTAL, ( WPARAM) self, ( LPARAM) msg);
128 return false;
129 }
130
131 static Bool
create_group(Handle self,Handle owner,Bool syncPaint,Bool clipOwner,Bool taskListed,int className,DWORD style,DWORD exstyle,Bool usePos,Bool useSize,ViewProfile * vprf,HWND parentHandle)132 create_group( Handle self, Handle owner, Bool syncPaint, Bool clipOwner,
133 Bool taskListed, int className, DWORD style, DWORD exstyle,
134 Bool usePos, Bool useSize,
135 ViewProfile * vprf, HWND parentHandle)
136 {
137 HWND ret = NULL;
138 HWND old = HANDLE;
139 HWND old2 = (HWND) var handle;
140 HWND behind = HWND_TOP;
141 HWND ownerView = ( HWND) (( PWidget) owner)-> handle;
142 HWND parentView = (( PDrawableData)(( PComponent) owner)-> sysData)-> parent;
143 int count = 0;
144 Bool reset = false;
145 Handle * list = NULL;
146 const WCHAR wnull = 0;
147
148 if ( HANDLE)
149 {
150 int i;
151 if (( DHANDLE( owner) == sys owner) && ( clipOwner == is_apt( aptClipOwner)))
152 {
153 behind = GetWindow( HANDLE, GW_HWNDPREV);
154 if ( behind == NULL) behind = HWND_TOP;
155 }
156 var stage = csAxEvents;
157 if ( kind_of( self, CWidget))
158 {
159 PWidget g = ( PWidget) self;
160 list = g-> widgets. items;
161 count = g-> widgets. count;
162 }
163 var self-> end_paint_info( self);
164 var self-> end_paint( self);
165 reset = true;
166 for( i = 0; i < count; i++)
167 get_view_ex( list[ i], ( ViewProfile*)( dsys( list[ i]) recreateData = malloc( sizeof( ViewProfile))));
168 }
169
170 switch (( int) className)
171 {
172 case WC_FRAME:
173 {
174 HWND frame;
175 RECT r;
176 int rcp[4] = {0,0,0,0};
177 Bool layered = is_apt(aptLayered);
178 if ( !clipOwner) parentView = HWND_DESKTOP;
179 if ( !taskListed && ( parentView == HWND_DESKTOP || parentView == NULL))
180 parentView = DHANDLE( application);
181 if ( !usePos) rcp[0] = rcp[1] = CW_USEDEFAULT;
182 if ( !useSize) rcp[2] = rcp[3] = CW_USEDEFAULT;
183 if ( !( frame = CreateWindowExW( exstyle, layered ? L"LayeredFrame" : L"GenericFrame", &wnull,
184 style | WS_CLIPCHILDREN,
185 rcp[0], rcp[1], rcp[2], rcp[3],
186 parentView, NULL, guts. instance, NULL)))
187 apiErrRet;
188 if ( !SetWindowPos( frame, behind, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE))
189 apiErr;
190 if ((( PApplication) application)-> topExclModal &&
191 ((( PApplication) application)-> topExclModal != self)
192 )
193 if ( !SetWindowPos( frame, DHANDLE((( PApplication) application)-> topExclModal),
194 0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE))
195 apiErr;
196 GetClientRect( frame, &r);
197 if ( old2 )
198 SetWindowLongPtr( old2, GWLP_USERDATA, 0);
199 if ( old )
200 SetWindowLongPtr( old, GWLP_USERDATA, 0);
201 if ( layered ) {
202 if ( !( ret = CreateWindowExW( WS_EX_LAYERED|WS_EX_TOOLWINDOW, L"Generic", &wnull,
203 WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
204 r. left, r. top, r. right, r. bottom, NULL, NULL,
205 guts. instance, NULL)))
206 apiErr;
207 } else {
208 if ( !( ret = CreateWindowExW( 0, L"Generic", &wnull,
209 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
210 0, 0, r. right - r. left, r. bottom - r. top, frame, NULL,
211 guts. instance, NULL)))
212 apiErr;
213 }
214 sys lastSize. x = r. right - r. left;
215 sys yOverride = sys lastSize. y = r. bottom - r. top;
216 sys handle = frame;
217 SetWindowLongPtr( frame, GWLP_USERDATA, ( LONG) self);
218 }
219 break;
220 case WC_CUSTOM:
221 if ( !parentHandle && ( !clipOwner || owner == application)) {
222 style &= ~WS_CHILD;
223 style |= WS_POPUP;
224 exstyle |= WS_EX_TOOLWINDOW;
225 }
226 if ( parentHandle) parentView = parentHandle;
227 sys parentHandle = parentHandle;
228
229 if ( old )
230 SetWindowLongPtr( old, GWLP_USERDATA, 0);
231 if ( !( ret = CreateWindowExW( exstyle, L"Generic", &wnull,
232 style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0,
233 parentView, NULL, guts. instance, NULL)))
234 apiErrRet;
235 if ( !SetWindowPos( ret, behind, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE))
236 apiErr;
237 sys handle = ret;
238 break;
239 }
240
241 apt_assign( aptClipOwner, clipOwner);
242 apt_assign( aptSyncPaint, syncPaint);
243 apt_set( aptEnabled);
244 apt_clear( aptRepaintPending );
245 apt_clear( aptMovePending );
246 sys className = className;
247 sys parent = ret;
248 var handle = ( Handle) ret;
249 sys owner = ownerView;
250 if ( !reset)
251 sys pointer = LoadCursor( guts. instance, IDC_ARROW);
252 SetWindowLongPtr( ret, GWLP_USERDATA, ( LONG) self);
253
254 if ( reset)
255 {
256 int i;
257 Handle oldOwner = var owner; var owner = owner;
258 if ( sys className == WC_FRAME) {
259 apc_window_set_client_rect( self, vprf-> pos. x, vprf-> pos. y, vprf-> size. x, vprf-> size. y);
260 } else {
261 apc_widget_set_rect( self, vprf-> pos. x, vprf-> pos. y, vprf-> size. x, vprf-> size. y);
262 }
263 var owner = oldOwner;
264 for ( i = 0; i < count; i++) ((( PComponent) list[ i])-> self)-> recreate( list[ i]);
265 if ( sys className == WC_FRAME)
266 {
267 SetMenu( HANDLE, GetMenu( old));
268 SetMenu( old, NULL);
269 }
270 if ( old2 != old ) {
271 if ( !DestroyWindow( old2 ))
272 apiErr;
273 }
274 if ( !DestroyWindow( old))
275 apiErr;
276 if ( var postList) list_first_that( var postList, repost_msgs, ( void*)self);
277 }
278 PostMessage( ret, WM_PRIMA_CREATE, 0, 0);
279
280 if ( !reset) {
281 /* set manually cmMove and cmSize when windows are configured automatically */
282 if ( !usePos) {
283 Event e;
284 Point sz = apc_window_get_client_pos( self);
285 memset( &e, 0, sizeof(e));
286 e. gen. source = self;
287 e. cmd = cmMove;
288 e. gen. P. x = sz. x;
289 e. gen. P. y = sz. y;
290 CComponent(self)->message( self, &e);
291 if ( PObject( self)-> stage == csDead) return false;
292 }
293 if ( !useSize) {
294 Event e;
295 Point sz = apc_window_get_client_size( self);
296 memset( &e, 0, sizeof(e));
297 e. gen. source = self;
298 e. cmd = cmSize;
299 e. gen. P. x = e. gen. R. right = sz. x;
300 e. gen. P. y = e. gen. R. top = sz. y;
301 CComponent(self)->message( self, &e);
302 if ( PObject( self)-> stage == csDead) return false;
303 }
304 }
305 return true;
306 }
307
308 static void
notify_sys_handle(Handle self)309 notify_sys_handle( Handle self )
310 {
311 Event ev = {cmSysHandle};
312 objCheck;
313 ev. gen. source = self;
314 var self-> message( self, &ev);
315 }
316
317 // Window
318 Bool
apc_window_create(Handle self,Handle owner,Bool syncPaint,int borderIcons,int borderStyle,Bool taskList,int windowState,int on_top,Bool usePos,Bool useSize,Bool layered)319 apc_window_create( Handle self, Handle owner, Bool syncPaint, int borderIcons,
320 int borderStyle, Bool taskList, int windowState,
321 int on_top, Bool usePos, Bool useSize, Bool layered)
322 {
323 Bool reset = false;
324 ViewProfile vprf;
325 int oStage = var stage;
326 WCHAR * saved_caption = NULL;
327 WindowData ws;
328 HICON icon = (HICON) NULL_HANDLE;
329 WINDOWPLACEMENT wp = {sizeof(WINDOWPLACEMENT)};
330 DWORD style = WS_CLIPCHILDREN | WS_OVERLAPPED
331 | (( borderIcons & biSystemMenu) ? WS_SYSMENU : 0)
332 | (( borderIcons & biMinimize) ? WS_MINIMIZEBOX : 0)
333 | (( borderIcons & biMaximize) ? WS_MAXIMIZEBOX : 0)
334 | (( borderIcons & biTitleBar) ? 0 : WS_POPUP)
335 | (( borderStyle == bsSizeable) ? WS_THICKFRAME : 0)
336 | (( borderStyle == bsSingle ) ? WS_BORDER : 0)
337 | (( borderStyle == bsDialog ) ? WS_BORDER : 0)
338 | (( windowState == wsMinimized) ? WS_MINIMIZE : 0)
339 | (( windowState == wsMaximized) ? WS_MAXIMIZE : 0)
340 ;
341 DWORD exstyle = 0
342 | (( borderStyle == bsDialog ) ? WS_EX_DLGMODALFRAME : 0)
343 ;
344
345 objCheck false;
346 dobjCheck( owner) false;
347 if ( guts. displayBMInfo. bmiHeader. biBitCount <= 8) layered = false;
348
349 if ( !kind_of( self, CWidget)) apcErrRet( errInvObject);
350 apcErrClear;
351 if (( var handle != NULL_HANDLE) && (
352 ( DHANDLE( owner) != sys owner)
353 || ( borderStyle != sys s. window. borderStyle)
354 || ( borderIcons != sys s. window. borderIcons)
355 || ( taskList != is_apt( aptTaskList))
356 || ( layered != is_apt( aptLayered))
357 ))
358 {
359 int len = GetWindowTextLengthW( HANDLE ) + 1;
360 if (( saved_caption = (WCHAR*) malloc( sizeof(WCHAR) * len)) != NULL )
361 GetWindowTextW( HANDLE, saved_caption, len );
362 // Windows 8 shell is observed to send WM_SIZE(0,0) on ShowWindow(SW_SHOWNORMAL)
363 // when application started with /min flag
364 apt_set( aptIgnoreSizeMessages );
365 apc_window_set_window_state( self, windowState);
366 apt_clear( aptIgnoreSizeMessages );
367 // prevent cmSize/cmWindowStage message loss if recreate goes with WS_XXX change.
368 if ( sys recreateData) {
369 memcpy( &vprf, sys recreateData, sizeof( vprf));
370 free( sys recreateData);
371 sys recreateData = NULL;
372 } else
373 get_view_ex( self, &vprf);
374 ws = sys s. window;
375 if ( !GetWindowPlacement( HANDLE, &wp)) apiErr;
376 if ( wp. showCmd == SW_SHOWMINIMIZED && windowState != wsMinimized )
377 wp. showCmd = ( windowState == wsMaximized ) ? SW_SHOWMAXIMIZED : SW_NORMAL;
378 usePos = useSize = 1; // prevent using shell-position flags for recreate
379 icon = ( HICON) SendMessage( HANDLE, WM_GETICON, ICON_BIG, 0);
380 reset = true;
381 }
382 HWND_lock( true);
383
384 if ( !reset) apt_set( aptClipByChildren );
385 apt_assign( aptLayeredRequested, layered );
386 apt_assign( aptLayered, layered );
387
388 if ( reset || ( var handle == NULL_HANDLE))
389 if ( !create_group( self, owner, syncPaint, false,
390 taskList, WC_FRAME, style, exstyle, usePos, useSize, &vprf, NULL)) {
391 if ( on_top >= 0) {
392 apt_assign( aptOnTop, on_top);
393 if ( on_top > 0)
394 SetWindowPos( sys handle, HWND_TOPMOST, 0, 0, 0, 0,
395 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
396 }
397 HWND_lock( false);
398 if ( saved_caption ) free( saved_caption );
399 return false;
400 }
401 ws. borderStyle = sys s. window. borderStyle = borderStyle;
402 ws. borderIcons = sys s. window. borderIcons = borderIcons;
403 ws. state = sys s. window. state = windowState;
404 apt_assign( aptSyncPaint, syncPaint);
405 apt_assign( aptTaskList, taskList);
406 if ( usePos) apt_set( aptWinPosDetermined);
407 if ( reset)
408 {
409 Handle oldOwner = var owner;
410
411 var owner = owner;
412 apc_window_set_window_state( self, windowState);
413 var owner = oldOwner;
414 set_view_ex( self, &vprf);
415 sys s. window = ws;
416 if ( windowState != wsMaximized)
417 GetWindowRect( HANDLE, &wp. rcNormalPosition);
418 if ( !SetWindowPlacement( HANDLE, &wp)) apiErr;
419 var stage = oStage;
420 if ( icon) SendMessage( HANDLE, WM_SETICON, ICON_BIG, ( LPARAM) icon);
421 }
422 else {
423 guts. topWindows++;
424 }
425 if ( on_top >= 0) {
426 apt_assign( aptOnTop, on_top);
427 if ( on_top > 0)
428 SetWindowPos( sys handle, HWND_TOPMOST, 0, 0, 0, 0,
429 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
430 }
431 SetWindowTextW( HANDLE, saved_caption );
432 if ( saved_caption ) free( saved_caption );
433 HWND_lock( false);
434 if ( reset ) {
435 notify_sys_handle( self );
436 if ( layered ) hwnd_repaint_layered(self, false);
437 }
438 return apcError == 0;
439 }
440
441 Bool
apc_window_activate(Handle self)442 apc_window_activate( Handle self)
443 {
444 if ( self) {
445 HWND w;
446 objCheck false;
447 w = HANDLE;
448 SetForegroundWindow( w);
449 SetActiveWindow( w);
450 return true;
451 }
452 return false;
453 }
454
455 Bool
apc_window_is_active(Handle self)456 apc_window_is_active( Handle self)
457 {
458 return apc_window_get_active() == self;
459 }
460
461 Handle
apc_window_get_active(void)462 apc_window_get_active( void)
463 {
464 Handle self = hwnd_to_view( GetActiveWindow());
465 if ( !self)
466 return NULL_HANDLE;
467 if ( sys className == WC_FRAME)
468 return self;
469 else if ( !is_apt( aptClipOwner)) {
470 return hwnd_top_level( self);
471 } else
472 return NULL_HANDLE;
473 }
474
475 Bool
apc_window_close(Handle self)476 apc_window_close( Handle self)
477 {
478 objCheck true;
479 if ( !PostMessage( HANDLE, WM_CLOSE, 0, 0)) apiErrRet;
480 return true;
481 }
482
483 int
apc_window_get_border_icons(Handle self)484 apc_window_get_border_icons( Handle self)
485 {
486 objCheck 0;
487 return sys s. window. borderIcons;
488 }
489
490 int
apc_window_get_border_style(Handle self)491 apc_window_get_border_style( Handle self)
492 {
493 objCheck 0;
494 return sys s. window. borderStyle;
495 }
496
497 ApiHandle
apc_window_get_client_handle(Handle self)498 apc_window_get_client_handle( Handle self)
499 {
500 objCheck 0;
501 return ( ApiHandle) var handle;
502 }
503
504 Point
apc_window_get_client_pos(Handle self)505 apc_window_get_client_pos( Handle self)
506 {
507 Point delta = get_window_borders( sys s. window. borderStyle);
508 Handle parent = var self-> get_parent( self);
509 Point p = {0,0}, sz = CWidget( parent)-> get_size( parent);
510 RECT r;
511
512 objCheck p;
513 if ( apc_window_get_window_state( self) == wsMinimized) {
514 WINDOWPLACEMENT w = { sizeof( WINDOWPLACEMENT)};
515 if ( !GetWindowPlacement( HANDLE, &w)) apiErr;
516 p. x = w. rcNormalPosition. left + delta. x;
517 p. y = sz. y - w. rcNormalPosition. bottom + delta. y;
518 } else {
519 GetWindowRect( HANDLE, &r);
520 p. x = r. left + delta. x;
521 p. y = sz. y - r. bottom + delta. y;
522 }
523 return p;
524 }
525
526 Point
apc_window_get_client_size(Handle self)527 apc_window_get_client_size( Handle self)
528 {
529 RECT r;
530 Point p = { 0,0};
531 objCheck p;
532 if ( apc_window_get_window_state( self) == wsMinimized) {
533 // cannot acquire client extension at this time. Using euristic calculations.
534 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
535 Point delta = get_window_borders( sys s. window. borderStyle);
536 int menuY = (( PWindow) self)-> menu ? GetSystemMetrics( SM_CYMENU) : 0;
537 int titleY = ( sys s. window. borderIcons & biTitleBar) ?
538 GetSystemMetrics( SM_CYCAPTION) : 0;
539 if ( !GetWindowPlacement( HANDLE, &w)) apiErr;
540 p. x = w. rcNormalPosition. right - w. rcNormalPosition. left - delta. x * 2;
541 p. y = w. rcNormalPosition. bottom - w. rcNormalPosition. top - delta. y * 2
542 - menuY - titleY;
543 } else {
544 GetWindowRect(( HWND) var handle, &r);
545 p. x = r. right - r. left;
546 p. y = r. bottom - r. top;
547 }
548 return p;
549 }
550
551 Bool
apc_window_get_icon(Handle self,Handle icon)552 apc_window_get_icon( Handle self, Handle icon)
553 {
554 HICON p;
555 HCURSOR save;
556 Bool ret;
557
558 objCheck false;
559 p = ( HICON) SendMessage( HANDLE, WM_GETICON, ICON_BIG, 0);
560 if ( icon == NULL_HANDLE) return p != NULL;
561
562 save = sys pointer;
563 sys pointer = p;
564 ret = apc_pointer_get_bitmap( self, icon);
565 sys pointer = save;
566 return ret;
567 }
568
569 int
apc_window_get_window_state(Handle self)570 apc_window_get_window_state( Handle self)
571 {
572 WINDOWPLACEMENT s = {sizeof( WINDOWPLACEMENT)};
573 objCheck wsNormal;
574 if ( !GetWindowPlacement( HANDLE, &s)) apiErr;
575 if ( s. showCmd == SW_SHOWMAXIMIZED) return wsMaximized;
576 if ( s. showCmd == SW_SHOWMINIMIZED) return wsMinimized;
577 return wsNormal;
578 }
579
580 Bool
apc_window_get_task_listed(Handle self)581 apc_window_get_task_listed( Handle self)
582 {
583 objCheck false;
584 return is_apt( aptTaskList);
585 }
586
587 Bool
apc_window_get_on_top(Handle self)588 apc_window_get_on_top( Handle self)
589 {
590 objCheck false;
591 return is_apt( aptOnTop);
592 }
593
594 Bool
apc_window_set_caption(Handle self,const char * caption,Bool utf8)595 apc_window_set_caption( Handle self, const char * caption, Bool utf8)
596 {
597 objCheck false;
598 if ( utf8) {
599 WCHAR * c = alloc_utf8_to_wchar( caption, -1, NULL);
600 if ( !( rc = SetWindowTextW( HANDLE, c))) apiErr;
601 free( c);
602 } else {
603 if ( !( rc = SetWindowTextA( HANDLE, caption))) apiErr;
604 }
605 return rc == 0;
606 }
607
608 Bool
apc_window_set_client_pos(Handle self,int x,int y)609 apc_window_set_client_pos( Handle self, int x, int y)
610 {
611 Point delta = get_window_borders( sys s. window. borderStyle);
612 RECT r;
613 Handle parent = var self-> get_parent( self);
614 Point sz = CWidget( parent)-> get_size( parent);
615
616 objCheck false;
617 if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
618 apt_set( aptWinPosDetermined);
619
620 if ( var stage == csConstructing && apc_window_get_window_state( self) != wsNormal) {
621 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
622 if ( !GetWindowPlacement( HANDLE, &w)) apiErr;
623 w. rcNormalPosition. top += sz. y - y + delta. y - w. rcNormalPosition. bottom;
624 w. rcNormalPosition. bottom = sz. y - y + delta. y;
625 w. rcNormalPosition. right += x - delta. x - w. rcNormalPosition. left;
626 w. rcNormalPosition. left = x - delta. x;
627 w. flags = 0;
628 if ( !SetWindowPlacement( HANDLE, &w)) apiErr;
629 } else {
630 if ( !GetWindowRect( HANDLE, &r)) apiErr;
631 x -= delta. x;
632 y = sz. y - ( r. bottom - r. top) - y + delta. y;
633 SetWindowPos( HANDLE, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
634 }
635 return true;
636 }
637
638 Bool
apc_window_set_client_size(Handle self,int x,int y)639 apc_window_set_client_size( Handle self, int x, int y)
640 {
641 RECT r, c, c2;
642 HWND h;
643 int ws = apc_window_get_window_state( self);
644
645 objCheck false;
646 if ( !hwnd_check_limits( x, y, false)) apcErrRet( errInvParams);
647
648 h = HANDLE;
649 if (( var stage == csConstructing && ws != wsNormal) || ws == wsMinimized) {
650 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
651 Point delta = get_window_borders( sys s. window. borderStyle);
652
653 var virtualSize. x = x;
654 var virtualSize. y = y;
655 if ( x < 0) x = 0;
656 if ( y < 0) y = 0;
657 if ( !GetWindowPlacement( h, &w)) apiErr;
658 if ( !GetWindowRect( h, &c2)) apiErr;
659 if ( ws == wsMaximized) {
660 if ( !GetClientRect( h, &c)) apiErr;
661 }
662 else {
663 // cannot acquire client extension at this time. Using euristic calculations.
664 int menuY = (( PWindow) self)-> menu ? GetSystemMetrics( SM_CYMENU) : 0;
665 int titleY = ( sys s. window. borderIcons & biTitleBar) ?
666 GetSystemMetrics( SM_CYCAPTION) : 0;
667 c = c2;
668 c. right -= delta. x * 2;
669 c. bottom -= delta. y * 2 + menuY + titleY;
670 }
671 w. rcNormalPosition. top = w. rcNormalPosition. bottom - y - ( c2. bottom - c2. top - c. bottom + c. top);
672 w. rcNormalPosition. right = x + ( c2. right - c2. left - c. right + c. left) + w. rcNormalPosition. left;
673 w. flags = 0;
674 if ( !SetWindowPlacement( h, &w)) apiErr;
675 } else {
676 if ( !GetWindowRect( h, &r)) apiErr;
677 if ( !GetClientRect( h, &c)) apiErr;
678 sys sizeLockLevel++;
679 var virtualSize. x = x;
680 var virtualSize. y = y;
681 if ( x < 0) x = 0;
682 if ( y < 0) y = 0;
683 SetWindowPos( h, 0,
684 r. left,
685 r. top - y + ( c. bottom - c. top),
686 x + r. right - r. left - c. right + c. left,
687 y + r. bottom - r. top - c. bottom + c. top,
688 SWP_NOZORDER | SWP_NOACTIVATE |
689 ( is_apt( aptWinPosDetermined) ? 0 : SWP_NOMOVE)
690 );
691 sys sizeLockLevel--;
692 }
693 return true;
694 }
695
696 Bool
apc_window_set_client_rect(Handle self,int x,int y,int width,int height)697 apc_window_set_client_rect( Handle self, int x, int y, int width, int height)
698 {
699 RECT r, c, c2;
700 HWND h;
701 int ws = apc_window_get_window_state( self);
702 Point delta = get_window_borders( sys s. window. borderStyle);
703 Handle parent = var self-> get_parent( self);
704 Point sz = CWidget( parent)-> get_size( parent);
705
706 objCheck false;
707 if ( !hwnd_check_limits( x, y, false)) apcErrRet( errInvParams);
708 if ( !hwnd_check_limits( width, height, false)) apcErrRet( errInvParams);
709 apt_set( aptWinPosDetermined);
710
711 h = HANDLE;
712 if (( var stage == csConstructing && ws != wsNormal) || ws == wsMinimized) {
713 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
714 Point delta = get_window_borders( sys s. window. borderStyle);
715
716 var virtualSize. x = width;
717 var virtualSize. y = height;
718 if ( width < 0) width = 0;
719 if ( height < 0) height = 0;
720 if ( !GetWindowPlacement( h, &w)) apiErr;
721 if ( !GetWindowRect( h, &c2)) apiErr;
722 if ( ws == wsMaximized) {
723 if ( !GetClientRect( h, &c)) apiErr;
724 }
725 else {
726 // cannot acquire client extension at this time. Using euristic calculations.
727 int menuY = (( PWindow) self)-> menu ? GetSystemMetrics( SM_CYMENU) : 0;
728 int titleY = ( sys s. window. borderIcons & biTitleBar) ?
729 GetSystemMetrics( SM_CYCAPTION) : 0;
730 c = c2;
731 c. right -= delta. x * 2;
732 c. bottom -= delta. y * 2 + menuY + titleY;
733 }
734 w. rcNormalPosition. bottom = sz. y - y + delta. y;
735 w. rcNormalPosition. left = x - delta. x;
736 w. rcNormalPosition. top = w. rcNormalPosition. bottom - height - ( c2. bottom - c2. top - c. bottom + c. top);
737 w. rcNormalPosition. right = width + ( c2. right - c2. left - c. right + c. left) + w. rcNormalPosition. left;
738 w. flags = 0;
739 if ( !SetWindowPlacement( h, &w)) apiErr;
740 } else {
741 if ( !GetWindowRect( h, &r)) apiErr;
742 if ( !GetClientRect( h, &c)) apiErr;
743 sys sizeLockLevel++;
744 x -= delta. x;
745 y = sz. y - y - height - ( r. bottom - r. top - c. bottom + c. top) + delta. y;
746 var virtualSize. x = width;
747 var virtualSize. y = height;
748 if ( width < 0) width = 0;
749 if ( height < 0) height = 0;
750 SetWindowPos( h, 0,
751 x, y,
752 width + r. right - r. left - c. right + c. left,
753 height + r. bottom - r. top - c. bottom + c. top,
754 SWP_NOZORDER | SWP_NOACTIVATE);
755 sys sizeLockLevel--;
756 }
757 return true;
758 }
759
760 Bool
apc_window_set_menu(Handle self,Handle menu)761 apc_window_set_menu( Handle self, Handle menu)
762 {
763 Point size;
764 objCheck false;
765 apcErrClear;
766 size = var self-> get_size( self);
767 SetMenu( HANDLE, menu ? ( HMENU) (( PComponent) menu)-> handle : NULL);
768 DrawMenuBar( HANDLE);
769 if ( apc_window_get_window_state( self) == wsNormal)
770 var self-> set_size( self, size);
771 return apcError == 0;
772 }
773
774 Bool
apc_window_set_effects(Handle self,HV * effects)775 apc_window_set_effects( Handle self, HV * effects )
776 {
777 return false;
778 }
779
780 Bool
apc_window_set_icon(Handle self,Handle icon)781 apc_window_set_icon( Handle self, Handle icon)
782 {
783 HICON i;
784 objCheck false;
785 i = icon ? image_make_icon_handle( icon, guts. iconSizeLarge, NULL) : NULL;
786 i = ( HICON) SendMessage( HANDLE, WM_SETICON, ICON_BIG, ( LPARAM) i);
787 if ( i) DestroyIcon( i);
788 return true;
789 }
790
791 Bool
apc_window_set_window_state(Handle self,int state)792 apc_window_set_window_state( Handle self, int state)
793 {
794 int fl = -1;
795 objCheck false;
796 switch ( state)
797 {
798 case wsMaximized: fl = SW_SHOWMAXIMIZED; break;
799 case wsMinimized: fl = SW_MINIMIZE; break;
800 case wsNormal : fl = SW_SHOWNORMAL; break;
801 }
802 if ( fl > 0)
803 {
804 ShowWindow( HANDLE, fl);
805 sys s. window. state = state;
806 }
807 return true;
808 }
809
810 static Bool
window_start_modal(Handle self,Bool shared,Handle insertBefore)811 window_start_modal( Handle self, Bool shared, Handle insertBefore)
812 {
813 HWND wnd;
814 HWND active = GetActiveWindow();
815
816 objCheck false;
817 wnd = HANDLE;
818 if ( sys className != WC_FRAME) { apcErr( errInvParams); return false; }
819
820 sys s. window. oldFoc = apc_widget_get_focused();
821 if ( sys s. window. oldFoc) protect_object( sys s. window. oldFoc);
822 sys s. window. oldActive = active;
823
824 // setting window up
825 guts. focSysDisabled = 1;
826 CWindow( self)-> exec_enter_proc( self, shared, insertBefore);
827 apc_widget_set_enabled( self, 1);
828 SetWindowPos( wnd, 0, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW);
829 if ( sys s. window. state == wsMinimized)
830 ShowWindow( wnd, SW_RESTORE);
831 if ( !insertBefore) {
832 SetActiveWindow( wnd);
833 SetForegroundWindow( wnd);
834 } else {
835 HWND zorder;
836 dobjCheck( insertBefore) false;
837 zorder = GetWindow( DHANDLE( insertBefore), GW_HWNDNEXT);
838 if ( !zorder) zorder = HWND_BOTTOM;
839 SetWindowPos( wnd, zorder, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
840 if ( active)
841 SetActiveWindow( active);
842 }
843 objCheck false;
844 PostMessage( wnd, WM_DLGENTERMODAL, 1, 0);
845 guts. focSysDisabled = 0;
846 return true;
847 }
848
849 Bool
apc_window_execute(Handle self,Handle insertBefore)850 apc_window_execute( Handle self, Handle insertBefore)
851 {
852 objCheck false;
853 if ( !window_start_modal( self, false, insertBefore))
854 return false;
855 // message loop
856 {
857 MSG msg;
858 while ( GetMessage( &msg, NULL, 0, 0)) {
859 if ( !process_msg( &msg)) {
860 if ( !appDead)
861 PostThreadMessage( guts. mainThreadId, WM_TERMINATE, 0, 0);
862 break;
863 }
864 if ( self && !(( PWindow) self)-> modal)
865 break;
866 }
867 }
868 // !!note - at this point object may be unaccessible (except var area only).
869 return true;
870 }
871
872 Bool
apc_window_execute_shared(Handle self,Handle insertBefore)873 apc_window_execute_shared( Handle self, Handle insertBefore)
874 {
875 objCheck false;
876 return window_start_modal( self, true, insertBefore);
877 }
878
879 Bool
apc_window_end_modal(Handle self)880 apc_window_end_modal( Handle self)
881 {
882 HWND wnd;
883 objCheck false;
884 wnd = HANDLE;
885 guts. focSysDisabled = 1;
886 CWindow( self)-> exec_leave_proc( self);
887 WinHideWindow( wnd);
888 objCheck false;
889 apc_widget_set_enabled( self, 0);
890 objCheck false;
891 if ( application) {
892 Handle who = Application_popup_modal( application);
893 if ( sys s. window. oldActive)
894 SetActiveWindow( sys s. window. oldActive);
895 if ( !who && var owner)
896 CWidget( var owner)-> set_selected( var owner, 1);
897 if (( who = sys s. window. oldFoc)) {
898 if ( PWidget( who)-> stage == csNormal)
899 CWidget( who)-> set_focused( who, 1);
900 unprotect_object( who);
901 }
902 }
903 guts. focSysDisabled = 0;
904 return true;
905 }
906
907 // View management
908 Bool
apc_widget_map_points(Handle self,Bool toScreen,int count,Point * p)909 apc_widget_map_points( Handle self, Bool toScreen, int count, Point * p)
910 {
911 int i;
912 Point sz = ((( PWidget) self)-> self)-> get_size( self);
913 Point appSz = apc_application_get_size( application);
914
915 if ( self == application)
916 return true;
917
918 objCheck false;
919
920 if ( toScreen) {
921 for ( i = 0; i < count; i++)
922 p[i]. y = sz. y - p[i]. y;
923 MapWindowPoints(( HWND) var handle, NULL, ( POINT * ) p, count);
924 for ( i = 0; i < count; i++)
925 p[i]. y = appSz. y - p[i].y;
926 } else {
927 for ( i = 0; i < count; i++)
928 p[i]. y = appSz. y - p[i]. y;
929 MapWindowPoints( NULL, ( HWND) var handle, ( POINT * ) p, count);
930 for ( i = 0; i < count; i++)
931 p[i]. y = sz. y - p[i]. y;
932 }
933 return true;
934 }
935
936 Color
apc_widget_map_color(Handle self,Color color)937 apc_widget_map_color( Handle self, Color color)
938 {
939 if ((( color & clSysFlag) != 0) && (( color & wcMask) == 0)) color |= var widgetClass;
940 return remap_color( remap_color( color, true), false);
941 }
942
943 Bool
apc_widget_create(Handle self,Handle owner,Bool syncPaint,Bool clipOwner,Bool transparent,ApiHandle parentHandle,Bool layered)944 apc_widget_create( Handle self, Handle owner, Bool syncPaint, Bool clipOwner,
945 Bool transparent, ApiHandle parentHandle, Bool layered)
946 {
947 Bool reset = false, redraw = false;
948 ViewProfile vprf;
949 int oStage = var stage;
950 int exstyle;
951
952 objCheck false;
953 dobjCheck( owner) false;
954
955 if ( !kind_of( self, CWidget)) apcErr( errInvObject);
956 apcErrClear;
957
958 if ( parentHandle && !IsWindow(( HWND) parentHandle))
959 return false;
960
961 exstyle = 0;
962 if ( guts. displayBMInfo. bmiHeader. biBitCount <= 8) layered = false;
963
964 redraw = is_apt( aptLayeredRequested ) != layered;
965 apt_assign( aptLayeredRequested, layered );
966 apt_clear( aptLayered );
967 if ( layered && (( owner == application || !clipOwner ))) {
968 apt_set( aptLayered );
969 exstyle |= WS_EX_LAYERED;
970 }
971
972 if (( var handle != NULL_HANDLE) &&
973 (( DHANDLE( owner) != sys owner) ||
974 (( HWND) parentHandle != sys parentHandle) ||
975 ( clipOwner != is_apt( aptClipOwner))
976 ))
977 {
978 if ( sys recreateData) {
979 memcpy( &vprf, sys recreateData, sizeof( vprf));
980 free( sys recreateData);
981 sys recreateData = NULL;
982 } else
983 get_view_ex( self, &vprf);
984 reset = true;
985 }
986 if ( !reset) apt_set( aptClipByChildren );
987 if ( reset || ( var handle == NULL_HANDLE))
988 create_group( self, owner, syncPaint, clipOwner, 0, WC_CUSTOM,
989 WS_CHILD, exstyle, 1, 1, &vprf, ( HWND) parentHandle);
990 apt_set( aptWinPosDetermined);
991 if ( reset)
992 {
993 Handle oldOwner = var owner; var owner = owner;
994 set_view_ex( self, &vprf);
995 var owner = oldOwner;
996 var stage = oStage;
997 }
998 if ( is_apt( aptTransparent) != transparent && !reset)
999 redraw = true;
1000 if ( redraw) apc_widget_redraw( self);
1001 apt_assign( aptTransparent, transparent);
1002 if ( reset) {
1003 notify_sys_handle( self );
1004 apc_widget_redraw( self);
1005 }
1006 return apcError == 0;
1007 }
1008
1009 Bool
apc_widget_begin_paint(Handle self,Bool insideOnPaint)1010 apc_widget_begin_paint( Handle self, Bool insideOnPaint)
1011 {
1012 Bool useRPDraw = false;
1013 objCheck false;
1014 apcErrClear;
1015
1016 if ( is_apt( aptLayeredPaint )) {
1017 sys transform2 = sys layeredPaintOffset;
1018 } else if ( is_apt( aptTransparent)) {
1019 if ( IsWindowVisible(( HWND) var handle)) {
1020 HWND parent = GetParent( HANDLE);
1021 if ( !parent) {
1022 MSG msg;
1023 list_add( &guts. transp, self);
1024 WinHideWindow(( HWND) var handle);
1025 if ( parent) apcUpdateWindow( parent);
1026 while ( PeekMessage( &msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE)) {
1027 DispatchMessage(&msg);
1028 exception_check_raise();
1029 }
1030 if ( !parent) Sleep( 1);
1031 WinShowWindow(( HWND) var handle);
1032 apcUpdateWindow(( HWND) var handle);
1033 list_delete( &guts. transp, self);
1034 } else
1035 useRPDraw = true;
1036 }
1037 sys transform2. x = 0;
1038 sys transform2. y = 0;
1039 } else {
1040 sys transform2. x = 0;
1041 sys transform2. y = 0;
1042 }
1043
1044 apt_set( aptWinPS);
1045 apt_set( aptCompatiblePS);
1046 apt_assign( aptWM_PAINT, insideOnPaint);
1047
1048 if ( is_apt( aptLayeredPaint )) {
1049 sys ps = sys layeredPaintSurface;
1050 } else if ( is_apt( aptLayered )) {
1051 RECT r;
1052
1053 insideOnPaint = false;
1054 GetWindowRect( HANDLE, &r);
1055 sys ps2 = GetDC(NULL);
1056 sys ps = CreateCompatibleDC(sys ps2);
1057 sys bm = CreateCompatibleBitmap(sys ps2, r. right - r. left, r. bottom - r. top);
1058 sys stockBM = SelectObject(sys ps, sys bm);
1059 } else if ( insideOnPaint) {
1060 if ( !( sys ps = BeginPaint(( HWND) var handle, &sys paintStruc))) apiErrRet;
1061 } else {
1062 if ( !( sys ps = GetDC(( HWND) var handle))) apiErrRet;
1063 }
1064
1065 if ( !is_apt(aptLayeredPaint) && is_opt( optBuffered) && insideOnPaint) {
1066 RECT r;
1067 HBITMAP bm;
1068 HDC dc;
1069
1070 GetClipBox( sys ps, &r);
1071 var w = r. right - r. left;
1072 var h = r. bottom - r. top;
1073
1074 if ( var w == 0 || var h == 0) {
1075 if ( !EndPaint(( HWND) var handle, &sys paintStruc)) apiErr;
1076 apt_clear( aptWinPS);
1077 apt_clear( aptWM_PAINT);
1078 apt_clear( aptCompatiblePS);
1079 sys ps = NULL;
1080 return false;
1081 }
1082
1083 if ( !( dc = CreateCompatibleDC( sys ps))) apiErr;
1084
1085 if ( sys pal) {
1086 sys stockPalette = SelectPalette( dc, sys pal, 1);
1087 RealizePalette( dc);
1088 sys pal2 = SelectPalette( sys ps, sys pal, 1);
1089 RealizePalette( sys ps);
1090 }
1091
1092 if ( guts. displayBMInfo. bmiHeader. biBitCount == 8)
1093 apt_clear( aptCompatiblePS);
1094
1095 bm = CreateCompatibleBitmap( sys ps, var w, var h);
1096
1097 if ( bm) {
1098 sys ps2 = sys ps;
1099 sys ps = dc;
1100 sys stockBM = SelectObject( dc, bm);
1101 sys bm = bm;
1102 SetBrushOrgEx( dc, -r. left, -r. top, NULL);
1103 apc_gp_set_transform( self, -r. left, -r. top);
1104 sys transform2. x = r. left;
1105 sys transform2. y = r. top;
1106 apt_set( aptBitmap);
1107 } else
1108 apiErr;
1109 } else if ( !is_apt(aptLayered) && !is_apt(aptLayeredPaint)) {
1110 if ( sys pal) {
1111 sys stockPalette = SelectPalette( sys ps, sys pal, 1);
1112 RealizePalette( sys ps);
1113 }
1114 }
1115
1116 if ( useRPDraw) {
1117 HDC dc;
1118 Handle owner = var owner;
1119 Point tr = dsys(owner)transform2;
1120 Point ed = apc_widget_get_pos( self);
1121 Point sz = apc_widget_get_size( self);
1122 Point so = CWidget(owner)-> get_size( owner);
1123 Bool flag;
1124 int saved_dc_state;
1125 POINT brushorg;
1126 FLOAT miter;
1127
1128 CWidget( owner)-> begin_paint( owner);
1129 dc = dsys( owner) ps;
1130 dsys( owner) ps = sys ps;
1131 dsys(owner) transform2. x += ed. x;
1132 dsys(owner) transform2. y += so. y - sz. y - ed. y;
1133 apc_gp_set_transform( owner, 0, 0);
1134 apc_gp_set_text_out_baseline( owner, dsys(owner) options. aptTextOutBaseline);
1135
1136 saved_dc_state = SaveDC( sys ps );
1137 SelectObject( sys ps, GetCurrentObject( dc, OBJ_PEN));
1138 SelectObject( sys ps, GetCurrentObject( dc, OBJ_BRUSH));
1139 SelectObject( sys ps, GetCurrentObject( dc, OBJ_FONT));
1140 SelectObject( sys ps, GetCurrentObject( dc, OBJ_PAL));
1141 SelectObject( sys ps, GetCurrentObject( dc, OBJ_EXTPEN));
1142 SetTextAlign( sys ps, GetTextAlign( dc ));
1143 GetBrushOrgEx( dc, &brushorg);
1144 SetBrushOrgEx( sys ps, brushorg.x, brushorg.y, NULL);
1145 GetMiterLimit( dc, &miter);
1146 SetMiterLimit( sys ps, miter, NULL);
1147 SetBkMode( sys ps, GetBkMode( dc ));
1148 SetROP2( sys ps, GetROP2( dc ));
1149 SetStretchBltMode( sys ps, GetStretchBltMode( dc ));
1150
1151 flag = exception_block(true);
1152 CWidget( owner)-> notify( owner, "sH", "Paint", owner);
1153 exception_block(flag);
1154
1155 RestoreDC( sys ps, saved_dc_state);
1156
1157 dsys(owner)transform2 = tr;
1158 apc_gp_set_transform( owner, 0, 0);
1159 dsys( owner) ps = dc;
1160 CWidget( owner)-> end_paint( owner);
1161 }
1162
1163 hwnd_enter_paint( self);
1164
1165 if ( useRPDraw) {
1166 apc_gp_set_transform( self, sys transform. x, sys transform. y);
1167 }
1168
1169 if ( is_apt(aptLayeredPaint)) {
1170 Rect r;
1171 r. left = 0;
1172 r. bottom = 0;
1173 r. right = sys lastSize. x - 1;
1174 r. top = sys lastSize. y - 1;
1175 apc_gp_set_clip_rect(self, r);
1176 }
1177
1178 return true;
1179 }
1180
1181 Bool
apc_widget_begin_paint_info(Handle self)1182 apc_widget_begin_paint_info( Handle self)
1183 {
1184 HRGN rgn;
1185 objCheck false;
1186 apt_set( aptWinPS);
1187 apt_set( aptCompatiblePS);
1188 sys transform2. x = 0;
1189 sys transform2. y = 0;
1190 if ( !( sys ps = GetDC(( HWND) var handle))) apiErrRet;
1191 hwnd_enter_paint( self);
1192 rgn = CreateRectRgn( 0, 0, 0, 0);
1193 SelectClipRgn( sys ps, rgn);
1194 DeleteObject( rgn);
1195 return true;
1196 }
1197
1198
1199 Bool
apc_widget_destroy(Handle self)1200 apc_widget_destroy( Handle self)
1201 {
1202 objCheck false;
1203 SetWindowLongPtr( HANDLE, GWLP_USERDATA, 0);
1204 if ( sys pointer2) {
1205 if ( sys pointer2 == sys pointer) SetCursor( NULL); // un-use resource first
1206 if ( !DestroyCursor( sys pointer2)) apiErr;
1207 }
1208 if ( sys recreateData) free( sys recreateData);
1209 if ( self == lastMouseOver) lastMouseOver = NULL_HANDLE;
1210 if ( self == guts.dragTarget) guts.dragTarget = NULL_HANDLE;
1211 if ( var handle == NULL_HANDLE) return true;
1212
1213 if ( sys className == WC_FRAME)
1214 guts. topWindows--;
1215
1216 if ( !DestroyWindow( HANDLE)) apiErrRet;
1217 return true;
1218 }
1219
1220 PFont
apc_widget_default_font(PFont copyTo)1221 apc_widget_default_font( PFont copyTo)
1222 {
1223 *copyTo = guts. windowFont;
1224 copyTo-> pitch = fpDefault;
1225 return copyTo;
1226 }
1227
1228 static void
subpaint_layered_widgets(HWND self,HDC ps,HDC alpha_dc,POINT screen_offset,HRGN parent_shape)1229 subpaint_layered_widgets( HWND self, HDC ps, HDC alpha_dc, POINT screen_offset, HRGN parent_shape)
1230 {
1231 HWND child = GetTopWindow( self );
1232 if ( child ) child = GetWindow( child, GW_HWNDLAST );
1233 while ( child != NULL ) {
1234 Handle h;
1235 RECT r;
1236 HRGN shape;
1237 Event ev;
1238 POINT child_offset, size;
1239
1240 h = hwnd_to_view(child);
1241 if ( h == NULL_HANDLE || !IsWindowVisible(child) || !dsys(h) options. aptClipOwner) {
1242 child = GetWindow( child, GW_HWNDPREV);
1243 continue;
1244 }
1245
1246 GetWindowRect( child, &r);
1247 r. left -= screen_offset. x;
1248 r. top -= screen_offset. y;
1249 r. right -= screen_offset. x;
1250 r. bottom -= screen_offset. y;
1251 size. x = r.right - r. left;
1252 size. y = r.bottom - r. top;
1253 child_offset. x = r. left;
1254 child_offset. y = r. top;
1255
1256 dsys(h) options. aptLayeredPaint = 1;
1257 dsys(h) layeredPaintOffset. x = -r. left;
1258 dsys(h) layeredPaintOffset. y = -r. top;
1259 dsys(h) layeredPaintSurface = ps;
1260
1261 shape = CreateRectRgn(0,0,0,0);
1262 if ( GetWindowRgn( child, shape)) {
1263 HRGN rect = CreateRectRgn( 0, 0, size.x, size.y);
1264 CombineRgn( shape, shape, rect, RGN_AND);
1265 DeleteObject( rect );
1266 } else {
1267 DeleteObject( shape );
1268 shape = CreateRectRgn( 0, 0, size.x, size.y);
1269 }
1270 OffsetRgn( shape, child_offset. x, child_offset. y);
1271 if ( parent_shape ) CombineRgn( shape, shape, parent_shape, RGN_AND );
1272 dsys(h) layeredParentRegion = shape;
1273
1274 ev. cmd = cmPaint;
1275 CWidget(h)-> message( h, &ev);
1276
1277 if ( !dsys(h) options. aptLayeredRequested) {
1278 /* assigning opaque alpha over the child rect so Windows passes mouse events in */
1279 StretchBlt( ps, r.left, r.top, size.x, size.y, alpha_dc, 0, 0, 1, 1, SRCPAINT);
1280 }
1281 dsys(h) options. aptLayeredPaint = 0;
1282
1283 subpaint_layered_widgets( child, ps, alpha_dc, screen_offset, shape);
1284
1285 DeleteObject( shape );
1286 child = GetWindow( child, GW_HWNDPREV);
1287 }
1288 }
1289
1290 Bool
apc_widget_end_paint(Handle self)1291 apc_widget_end_paint( Handle self)
1292 {
1293 objCheck false;
1294
1295 hwnd_leave_paint( self);
1296
1297 if ( is_apt( aptLayeredPaint )) {
1298 // do nothing
1299 } else if ( is_apt( aptLayered )) {
1300 RECT r;
1301 SIZE size;
1302 POINT src, pos, *ppos = NULL;
1303 BLENDFUNCTION bf;
1304 HBITMAP alpha_bm, stock_alpha_bm;
1305 HDC alpha_dc;
1306 uint32_t * alpha_pixels;
1307
1308 GetWindowRect((HWND) var handle, &r);
1309 if ( r. right - r. left <= 0 || r. bottom - r. top <= 0)
1310 goto SKIP_ALPHA;
1311
1312 alpha_dc = CreateCompatibleDC( sys ps );
1313 alpha_bm = image_create_argb_dib_section( alpha_dc, 1, 1, &alpha_pixels);
1314 stock_alpha_bm = SelectObject( alpha_dc, alpha_bm);
1315 *alpha_pixels = 0xFF000000;
1316
1317 /* subpaint children */
1318 src. x = r. left;
1319 src. y = r. top;
1320 subpaint_layered_widgets((HWND) var handle, sys ps, alpha_dc, src, NULL);
1321
1322 SelectObject( alpha_dc, stock_alpha_bm);
1323 DeleteObject( alpha_bm );
1324 DeleteDC( alpha_dc );
1325
1326 size. cx = r. right - r. left;
1327 size. cy = r. bottom - r. top;
1328 src. x = 0;
1329 src. y = 0;
1330 bf. AlphaFormat = AC_SRC_ALPHA;
1331 bf. SourceConstantAlpha = 255;
1332 bf. BlendFlags = 0;
1333 bf. BlendOp = AC_SRC_OVER;
1334 if (is_apt(aptMovePending)) {
1335 pos. x = sys layeredPos. x;
1336 pos. y = sys layeredPos. y;
1337 ppos = &pos;
1338 apt_clear(aptMovePending);
1339 }
1340 if ( !UpdateLayeredWindow((HWND) var handle, NULL, ppos, &size, sys ps, &src, 0, &bf, ULW_ALPHA))
1341 apiErr;
1342 SKIP_ALPHA:
1343 SelectObject(sys ps, sys stockBM);
1344 DeleteObject(sys bm);
1345 DeleteDC(sys ps);
1346 ReleaseDC(( HWND) var handle, sys ps2);
1347 sys ps = sys ps2 = NULL;
1348 sys bm = sys stockBM = NULL;
1349 } else if ( is_opt( optBuffered)) {
1350 apt_clear( aptBitmap);
1351 if ( sys bm != NULL) {
1352 if ( !BitBlt( sys ps2, sys transform2. x, sys transform2. y, var w, var h, sys ps, 0, 0, SRCCOPY)) apiErr;
1353 if ( sys stockBM)
1354 SelectObject( sys ps, sys stockBM);
1355 DeleteObject( sys bm);
1356 }
1357
1358 if ( sys pal) {
1359 SelectPalette( sys ps2, sys pal2, 1);
1360 SelectPalette( sys ps, sys stockPalette, 1);
1361 RealizePalette( sys ps2);
1362 sys pal2 = NULL;
1363 }
1364
1365 DeleteDC( sys ps);
1366 sys ps = sys ps2;
1367 sys bm = NULL;
1368 sys ps2 = NULL;
1369 sys stockBM = NULL;
1370 }
1371
1372 if ( !is_apt(aptLayeredPaint) && sys ps != NULL) {
1373 if ( is_apt( aptWinPS) && is_apt( aptWM_PAINT)) {
1374 if ( !EndPaint(( HWND) var handle, &sys paintStruc)) apiErr;
1375 } else if ( is_apt( aptWinPS))
1376 if ( !ReleaseDC(( HWND) var handle, sys ps)) apiErr;
1377 }
1378 sys ps = NULL;
1379 sys pal2 = NULL;
1380 apt_clear( aptWinPS);
1381 apt_clear( aptWM_PAINT);
1382 apt_clear( aptCompatiblePS);
1383 return true;
1384 }
1385
1386 Bool
apc_widget_end_paint_info(Handle self)1387 apc_widget_end_paint_info( Handle self)
1388 {
1389 Bool ok = true;
1390 objCheck false;
1391 hwnd_leave_paint( self);
1392 if ( !( ok = ReleaseDC(( HWND) var handle, sys ps))) apiErr;
1393 sys ps = NULL;
1394 apt_clear( aptWinPS);
1395 apt_clear( aptCompatiblePS);
1396 return ok;
1397 }
1398
1399 Bool
apc_widget_get_clip_by_children(Handle self)1400 apc_widget_get_clip_by_children( Handle self)
1401 {
1402 objCheck false;
1403 return is_apt(aptClipByChildren);
1404 }
1405
1406 Bool
apc_widget_get_clip_owner(Handle self)1407 apc_widget_get_clip_owner( Handle self)
1408 {
1409 objCheck false;
1410 return is_apt( aptClipOwner);
1411 }
1412
1413 Color
apc_widget_get_color(Handle self,int index)1414 apc_widget_get_color( Handle self, int index)
1415 {
1416 objCheck clInvalid;
1417 return sys viewColors[ index];
1418 }
1419
1420 Bool
apc_widget_get_first_click(Handle self)1421 apc_widget_get_first_click( Handle self)
1422 {
1423 objCheck false;
1424 return is_apt( aptFirstClick);
1425 }
1426
1427 Handle
apc_widget_get_focused()1428 apc_widget_get_focused()
1429 {
1430 return hwnd_to_view( GetFocus());
1431 }
1432
map_Rect(Handle self,Rect * rect)1433 static PRECT map_Rect( Handle self, Rect * rect)
1434 {
1435 RECT __rectangle;
1436 objCheck ( PRECT) rect;
1437 GetWindowRect(( HWND) var handle, &__rectangle);
1438 if ( is_apt( aptClipOwner) && ( var owner != application))
1439 MapWindowPoints( NULL, ( HWND)((( PWidget) var owner)-> handle), ( LPPOINT) &__rectangle, 2);
1440 rect-> bottom = ( __rectangle. bottom - __rectangle. top) - rect-> bottom;
1441 rect-> top = ( __rectangle. bottom - __rectangle. top) - rect-> top;
1442 // that is due the difference in field placement between Rect and RECT structures
1443 if ( rect-> bottom > rect-> top) {
1444 LONG i = rect-> bottom;
1445 rect-> bottom = rect-> top;
1446 rect-> top = i;
1447 }
1448 return ( PRECT) rect;
1449 }
1450
map_RECT(Handle self,RECT * rect)1451 static Rect * map_RECT( Handle self, RECT * rect)
1452 {
1453 RECT __rectangle;
1454 objCheck ( Rect*)rect;
1455 GetWindowRect(( HWND) var handle, &__rectangle);
1456 if ( is_apt( aptClipOwner) && ( var owner != application))
1457 MapWindowPoints( NULL, ( HWND)((( PWidget) var owner)-> handle), ( LPPOINT)&__rectangle, 2);
1458 rect-> bottom = ( __rectangle. bottom - __rectangle. top) - rect-> bottom;
1459 rect-> top = ( __rectangle. bottom - __rectangle. top) - rect-> top;
1460 // that is due the difference in field placement between Rect and RECT structures
1461 if ( rect-> bottom < rect-> top) {
1462 LONG i = rect-> bottom;
1463 rect-> bottom = rect-> top;
1464 rect-> top = i;
1465 }
1466 return ( Rect *) rect;
1467 }
1468
1469 ApiHandle
apc_widget_get_handle(Handle self)1470 apc_widget_get_handle( Handle self)
1471 {
1472 objCheck 0;
1473 return ( ApiHandle) HANDLE;
1474 }
1475
1476 ApiHandle
apc_widget_get_parent_handle(Handle self)1477 apc_widget_get_parent_handle( Handle self)
1478 {
1479 objCheck 0;
1480 return ( ApiHandle) sys parentHandle;
1481 }
1482
1483
1484 Rect
apc_widget_get_invalid_rect(Handle self)1485 apc_widget_get_invalid_rect( Handle self)
1486 {
1487 Rect r = {0,0,0,0};
1488 objCheck r;
1489 if ( GetUpdateRect(( HWND) var handle, ( PRECT) &r, false))
1490 return *( map_RECT( self, ( PRECT) &r));
1491 return r;
1492 }
1493
1494 Bool
apc_widget_get_layered_request(Handle self)1495 apc_widget_get_layered_request( Handle self)
1496 {
1497 return is_apt( aptLayeredRequested);
1498 }
1499
1500 Bool
apc_widget_surface_is_layered(Handle self)1501 apc_widget_surface_is_layered( Handle self)
1502 {
1503 Handle top;
1504 objCheck false;
1505
1506 if ( is_apt( aptLayered)) return true;
1507 top = hwnd_layered_top_level(self);
1508 if ( top && dsys(top) options. aptLayered ) return true;
1509 return false;
1510 }
1511
1512 Point
apc_widget_get_pos(Handle self)1513 apc_widget_get_pos( Handle self)
1514 {
1515 RECT r;
1516 Point p, sz = {0,0};
1517 Handle parent;
1518 objCheck sz;
1519 parent = is_apt( aptClipOwner) ? var owner : application;
1520 sz = ((( PWidget) parent)-> self)-> get_size( parent);
1521 if ( sys className == WC_FRAME && apc_window_get_window_state( self) == wsMinimized) {
1522 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
1523 if ( !GetWindowPlacement( HANDLE, &w)) apiErr;
1524 p. x = w. rcNormalPosition. left;
1525 p. y = sz. y - w. rcNormalPosition. bottom;
1526 } else if ( is_apt( aptMovePending)) {
1527 GetWindowRect( HANDLE, &r);
1528 p. x = sys layeredPos. x;
1529 p. y = sys layeredPos. y + r. bottom - r.top;
1530 } else {
1531 GetWindowRect( HANDLE, &r);
1532 if ( is_apt( aptClipOwner) && ( var owner != application))
1533 MapWindowPoints( NULL, ( HWND)((( PWidget) var owner)-> handle), ( LPPOINT)&r, 2);
1534 p. x = r. left;
1535 p. y = sz. y - r. bottom;
1536 }
1537 return p;
1538 }
1539
1540 Point
apc_widget_get_size(Handle self)1541 apc_widget_get_size( Handle self)
1542 {
1543 RECT r;
1544 Point p = {0,0};
1545 objCheck p;
1546 if ( sys className == WC_FRAME && apc_window_get_window_state( self) == wsMinimized) {
1547 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
1548 if ( !GetWindowPlacement( HANDLE, &w)) apiErr;
1549 p. x = w. rcNormalPosition. right - w. rcNormalPosition. left;
1550 p. y = w. rcNormalPosition. bottom - w. rcNormalPosition. top;
1551 } else {
1552 GetWindowRect( HANDLE, &r);
1553 if ( is_apt( aptClipOwner) && ( var owner != application))
1554 MapWindowPoints( NULL, ( HWND)((( PWidget) var owner)-> handle), ( LPPOINT)&r, 2);
1555 p. x = r. right - r. left;
1556 p. y = r. bottom - r. top;
1557 }
1558 return p;
1559 }
1560
1561 Handle
apc_widget_get_z_order(Handle self,int zOrderId)1562 apc_widget_get_z_order( Handle self, int zOrderId)
1563 {
1564 Handle h;
1565 HWND w;
1566 UINT cmd1, cmd2;
1567 objCheck NULL_HANDLE;
1568
1569 switch ( zOrderId) {
1570 case zoFirst:
1571 cmd1 = GW_HWNDFIRST;
1572 cmd2 = GW_HWNDNEXT;
1573 break;
1574 case zoLast:
1575 cmd1 = GW_HWNDLAST;
1576 cmd2 = GW_HWNDPREV;
1577 break;
1578 case zoNext:
1579 cmd1 = cmd2 = GW_HWNDNEXT;
1580 break;
1581 case zoPrev:
1582 cmd1 = cmd2 = GW_HWNDPREV;
1583 break;
1584 default:
1585 apcErr( errInvParams);
1586 return NULL_HANDLE;
1587 }
1588
1589 w = GetWindow( HANDLE, cmd1);
1590 if ( !w) return NULL_HANDLE;
1591 h = hwnd_to_view( w);
1592 while ( h == NULL_HANDLE) {
1593 w = GetWindow( w, cmd2);
1594 if ( !w) return NULL_HANDLE;
1595 h = hwnd_to_view( w);
1596 }
1597
1598 return h;
1599 }
1600
1601 Bool
apc_widget_get_shape(Handle self,Handle mask)1602 apc_widget_get_shape( Handle self, Handle mask)
1603 {
1604 HRGN rgn;
1605 int res;
1606 RECT rect;
1607
1608 if ( !mask ) {
1609 rgn = CreateRectRgn(0,0,0,0);
1610 res = GetWindowRgn( HANDLE, rgn);
1611 res = GetClipRgn( sys ps, rgn );
1612 DeleteObject(rgn);
1613 return res != ERROR;
1614 }
1615
1616 rgn = GET_REGION(mask)-> region;
1617 res = GetWindowRgn( HANDLE, rgn);
1618 if ( res == ERROR)
1619 return false;
1620
1621 GetRgnBox(rgn, &rect);
1622 OffsetRgn( rgn, -sys extraPos. x, -sys extraPos. y);
1623 GET_REGION(mask)-> aperture = sys lastSize. y - rect.top;
1624
1625 return true;
1626 }
1627
1628
1629 Bool
apc_widget_get_sync_paint(Handle self)1630 apc_widget_get_sync_paint( Handle self)
1631 {
1632 objCheck false;
1633 return is_apt( aptSyncPaint);
1634 }
1635
1636 Bool
apc_widget_get_transparent(Handle self)1637 apc_widget_get_transparent( Handle self)
1638 {
1639 objCheck false;
1640 return is_apt( aptTransparent);
1641 }
1642
1643 Bool
apc_widget_is_captured(Handle self)1644 apc_widget_is_captured( Handle self)
1645 {
1646 objCheck false;
1647 return GetCapture() == ( HWND) var handle;
1648 }
1649
1650 Bool
apc_widget_is_enabled(Handle self)1651 apc_widget_is_enabled( Handle self)
1652 {
1653 objCheck false;
1654 return is_apt( aptEnabled);
1655 // return IsWindowEnabled( HANDLE);
1656 }
1657
1658 Bool
apc_widget_is_responsive(Handle self)1659 apc_widget_is_responsive( Handle self)
1660 {
1661 Bool ena = true;
1662 objCheck false;
1663 while ( ena && self != application) {
1664 // ena = IsWindowEnabled( HANDLE);
1665 ena = is_apt( aptEnabled);
1666 self = var owner;
1667 }
1668 return ena;
1669 }
1670
1671 Bool
apc_widget_is_focused(Handle self)1672 apc_widget_is_focused( Handle self)
1673 {
1674 objCheck false;
1675 return is_apt( aptFocused);
1676 }
1677
1678 Bool
apc_widget_is_visible(Handle self)1679 apc_widget_is_visible( Handle self)
1680 {
1681 objCheck false;
1682 return ( GetWindowLong(HANDLE, GWL_STYLE) & WS_VISIBLE) ? 1 : 0;
1683 }
1684
1685 Bool
apc_widget_is_showing(Handle self)1686 apc_widget_is_showing( Handle self)
1687 {
1688 objCheck false;
1689 return IsWindowVisible( HANDLE);
1690 }
1691
1692 Bool
apc_widget_is_exposed(Handle self)1693 apc_widget_is_exposed( Handle self)
1694 {
1695 HWND h;
1696 HRGN rgnSave = NULL;
1697 HRGN rgn = NULL;
1698 int rgnSaveType, rgnType;
1699
1700 objCheck false;
1701
1702 h = ( HWND) var handle;
1703 if ( !IsWindowVisible( h)) return false;
1704
1705 rgnSave = CreateRectRgn(0,0,0,0);
1706 rgn = CreateRectRgn(0,0,0,0);
1707 rgnSaveType = GetUpdateRgn( h, rgnSave, FALSE);
1708 rgnSaveType = ( rgnSaveType == COMPLEXREGION || rgnSaveType == SIMPLEREGION);
1709
1710 if ( rgnSaveType) ValidateRect( h, NULL);
1711
1712 InvalidateRect( h, NULL, false);
1713 rgnType = GetUpdateRgn( h, rgn, FALSE);
1714 ValidateRect( h, NULL);
1715
1716 if ( rgnSaveType) InvalidateRgn( h, rgnSave, FALSE);
1717 DeleteObject( rgnSave);
1718 DeleteObject( rgn);
1719 return ( rgnType == COMPLEXREGION || rgnType == SIMPLEREGION);
1720 }
1721
1722 Bool
apc_widget_invalidate_rect(Handle self,Rect * rect)1723 apc_widget_invalidate_rect( Handle self, Rect * rect)
1724 {
1725 PRECT pRect = rect ? map_Rect( self, rect) : NULL;
1726 objCheck false;
1727 if ( !InvalidateRect (( HWND) var handle, pRect, false)) apiErr;
1728 hwnd_repaint_layered( self, false );
1729 if ( is_apt( aptSyncPaint) && !apcUpdateWindow(( HWND) var handle)) apiErr;
1730 objCheck false;
1731 process_transparents( self);
1732 return true;
1733 }
1734
1735 int
apc_widget_scroll(Handle self,int horiz,int vert,Rect * r,Rect * cr,Bool scrollChildren)1736 apc_widget_scroll( Handle self, int horiz, int vert, Rect * r, Rect *cr, Bool scrollChildren)
1737 {
1738 PRECT pRect = r ? map_Rect( self, r) : NULL;
1739 PRECT pClipRect = cr ? map_Rect( self, cr) : NULL;
1740 Point sz = apc_widget_get_size( self);
1741 int ret;
1742 objCheck scrError;
1743
1744 HideCaret(( HWND) var handle);
1745
1746 if ( pClipRect) {
1747 if ( pClipRect-> left < 0) pClipRect-> left = 0;
1748 if ( pClipRect-> top < 0) pClipRect-> top = 0;
1749 if ( pClipRect-> right > sz. x) pClipRect-> right = sz. x;
1750 if ( pClipRect-> bottom > sz. y) pClipRect-> bottom = sz. y;
1751 }
1752
1753 if ( pRect) {
1754 if ( pRect-> left < -sz. x * 2) pRect-> left = -sz. x * 2;
1755 if ( pRect-> top < -sz. y * 2) pRect-> top = -sz. y * 2;
1756 if ( pRect-> right > sz. x * 2) pRect-> right = sz. x * 2;
1757 if ( pRect-> bottom > sz. y * 2) pRect-> bottom = sz. y * 2;
1758 }
1759
1760 if ( horiz > sz. x || horiz < -sz. x || vert > sz. y || vert < -sz. y) {
1761 if ( pRect && pClipRect) {
1762 RECT rc;
1763 UnionRect( &rc, (RECT*)pRect, (RECT*)pClipRect);
1764 InvalidateRect(( HWND) var handle, &rc, false);
1765 } else
1766 InvalidateRect(( HWND) var handle, pRect ? pRect : pClipRect, false);
1767 ret = scrExpose;
1768 } else {
1769 int rr = ScrollWindowEx(( HWND) var handle,
1770 horiz, -vert, pRect, pClipRect, NULL, NULL,
1771 SW_INVALIDATE | ( scrollChildren ? SW_SCROLLCHILDREN : 0)
1772 );
1773 if (!rr) apiErr;
1774 ret = ( rr == 1 ) ? scrNoExpose : scrExpose;
1775 }
1776
1777 objCheck scrError;
1778 if ( is_apt( aptSyncPaint) && !apcUpdateWindow(( HWND) var handle)) apiErr;
1779 process_transparents( self);
1780 ShowCaret(( HWND) var handle);
1781
1782 return ret;
1783 }
1784
1785 Bool
apc_widget_set_capture(Handle self,Bool capture,Handle confineTo)1786 apc_widget_set_capture( Handle self, Bool capture, Handle confineTo)
1787 {
1788 objCheck false;
1789 if ( capture) {
1790 SetCapture(( HWND) var handle);
1791 if ( confineTo) {
1792 RECT r;
1793 GetWindowRect(( HWND) PComponent( confineTo)-> handle, &r);
1794 if ( !ClipCursor( &r)) apiErrRet;
1795 }
1796 } else {
1797 if ( !ReleaseCapture()) apiErrRet;
1798 if ( !ClipCursor( NULL)) apiErrRet;
1799 }
1800 return true;
1801 }
1802
1803 #define check_swap( parm1, parm2) if ( parm1 > parm2) { int parm3 = parm1; parm1 = parm2; parm2 = parm3;}
1804
1805 Bool
apc_widget_set_clip_by_children(Handle self,Bool clip_by_children)1806 apc_widget_set_clip_by_children( Handle self, Bool clip_by_children)
1807 {
1808 objCheck false;
1809 LONG f;
1810 MSG msg;
1811 Bool is_clipped;
1812
1813 is_clipped = is_apt(aptClipByChildren);
1814 clip_by_children = !!clip_by_children;
1815 if ( is_clipped == clip_by_children )
1816 return true;
1817
1818 if ( sys className == WC_FRAME) {
1819 f = GetWindowLong(( HWND ) var handle, GWL_STYLE);
1820 if ( clip_by_children )
1821 f |= WS_CLIPCHILDREN;
1822 else
1823 f &= ~WS_CLIPCHILDREN;
1824 SetWindowLong(( HWND ) var handle, GWL_STYLE, f);
1825 while ( PeekMessage( &msg, (HWND) var handle, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
1826 }
1827
1828 f = GetWindowLong(HANDLE, GWL_STYLE);
1829 if ( clip_by_children )
1830 f |= WS_CLIPCHILDREN;
1831 else
1832 f &= ~WS_CLIPCHILDREN;
1833 SetWindowLong( HANDLE, GWL_STYLE, f);
1834 while ( PeekMessage( &msg, HANDLE, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
1835 return true;
1836 }
1837
1838 Bool
apc_widget_set_color(Handle self,Color color,int index)1839 apc_widget_set_color( Handle self, Color color, int index)
1840 {
1841 Event ev = {cmColorChanged};
1842 objCheck false;
1843 sys viewColors[ index] = color;
1844
1845 ev. gen. source = self;
1846 ev. gen. i = index;
1847 var self-> message( self, &ev);
1848 return true;
1849 }
1850
1851 Bool
apc_widget_set_enabled(Handle self,Bool enable)1852 apc_widget_set_enabled( Handle self, Bool enable)
1853 {
1854 objCheck false;
1855 apt_assign( aptEnabled, enable);
1856 if (( sys className == WC_FRAME) || ( var owner == application))
1857 EnableWindow( HANDLE, enable);
1858 else
1859 SendMessage( HANDLE, WM_ENABLE, ( WPARAM) enable, 0);
1860 return true;
1861 }
1862
1863 Bool
apc_widget_set_first_click(Handle self,Bool firstClick)1864 apc_widget_set_first_click( Handle self, Bool firstClick)
1865 {
1866 objCheck false;
1867 apt_assign( aptFirstClick, firstClick);
1868 return true;
1869 }
1870
1871 Bool
apc_widget_set_focused(Handle self)1872 apc_widget_set_focused( Handle self)
1873 {
1874 if ( self && ( self != Application_map_focus( application, self)))
1875 return false;
1876 guts. focSysGranted++;
1877 SetFocus( self ? (( HWND) var handle) : NULL);
1878 guts. focSysGranted--;
1879 return true;
1880 }
1881
1882 Bool
apc_widget_set_font(Handle self,PFont font)1883 apc_widget_set_font( Handle self, PFont font)
1884 {
1885 Event ev = {cmFontChanged};
1886 objCheck false;
1887 ev. gen. source = self;
1888 var self-> message( self, &ev);
1889 return true;
1890 }
1891
1892 Bool
apc_widget_set_palette(Handle self)1893 apc_widget_set_palette( Handle self)
1894 {
1895 objCheck false;
1896 apc_gp_set_palette( self);
1897 if ( guts. displayBMInfo. bmiHeader. biBitCount == 8)
1898 palette_change( self);
1899 return true;
1900 }
1901
1902 Bool
apc_widget_set_pos(Handle self,int x,int y)1903 apc_widget_set_pos( Handle self, int x, int y)
1904 {
1905 Handle parent;
1906 Point sz;
1907 RECT r;
1908
1909 objCheck false;
1910 if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
1911
1912 parent = is_apt( aptClipOwner) ? var owner : application;
1913 sz = ((( PWidget) parent)-> self)-> get_size( parent);
1914 apt_set( aptWinPosDetermined);
1915
1916 if ( sys className == WC_FRAME) {
1917 HWND h = HANDLE;
1918 int ws = apc_window_get_window_state( self);
1919 if (( var stage == csConstructing && ws != wsNormal) || ( ws == wsMinimized)) {
1920 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
1921 if ( !GetWindowPlacement( h, &w)) apiErrRet;
1922 w. rcNormalPosition. top += sz. y - y - w. rcNormalPosition. bottom;
1923 w. rcNormalPosition. bottom = sz. y - y;
1924 w. rcNormalPosition. right += x - w. rcNormalPosition. left;
1925 w. rcNormalPosition. left = x;
1926 w. flags = 0;
1927 if ( !SetWindowPlacement( h, &w)) apiErrRet;
1928 return true;
1929 }
1930 }
1931 if ( !GetWindowRect( HANDLE, &r)) apiErrRet;
1932 if ( is_apt( aptClipOwner) && ( var owner != application))
1933 MapWindowPoints( NULL, ( HWND)((( PWidget) var owner)-> handle), ( LPPOINT)&r, 2);
1934 if ( sys parentHandle) {
1935 POINT ppos;
1936 ppos. x = x;
1937 ppos. y = dsys( application) lastSize. y - y;
1938 MapWindowPoints( NULL, sys parentHandle, ( LPPOINT)&ppos, 1);
1939 GetWindowRect( sys parentHandle, &r);
1940 x = ppos. x;
1941 y = ppos. y;
1942 } else
1943 y = sz. y - y - r. bottom + r. top;
1944
1945 if ( is_apt(aptLayered) && is_apt(aptRepaintPending)) {
1946 apt_set(aptMovePending);
1947 sys layeredPos. x = x;
1948 sys layeredPos. y = y;
1949 } else {
1950 if ( !SetWindowPos( HANDLE, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) apiErrRet;
1951 }
1952 return true;
1953 }
1954
1955 Bool
apc_widget_set_size(Handle self,int width,int height)1956 apc_widget_set_size( Handle self, int width, int height)
1957 {
1958 RECT r;
1959 HWND h;
1960 objCheck false;
1961
1962 if ( !hwnd_check_limits( width, height, false)) apcErrRet( errInvParams);
1963 h = HANDLE;
1964 if ( sys className == WC_FRAME) {
1965 int ws = apc_window_get_window_state( self);
1966 if (( var stage == csConstructing && ws != wsNormal) || ( ws == wsMinimized)) {
1967 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
1968 if ( !GetWindowPlacement( h, &w)) apiErrRet;
1969 if ( width < 0) width = 0;
1970 if ( height < 0) height = 0;
1971 w. rcNormalPosition. top = w. rcNormalPosition. bottom - height;
1972 w. rcNormalPosition. right = width + w. rcNormalPosition. left;
1973 w. flags = 0;
1974 if ( !SetWindowPlacement( h, &w)) apiErrRet;
1975 return true;
1976 }
1977 }
1978 if ( !GetWindowRect( h, &r)) apiErrRet;
1979 if ( is_apt( aptClipOwner) && ( var owner != application))
1980 MapWindowPoints( NULL, ( HWND)((( PWidget) var owner)-> handle), ( LPPOINT)&r, 2);
1981 if ( sys parentHandle)
1982 MapWindowPoints( NULL, sys parentHandle, ( LPPOINT)&r, 2);
1983
1984 if ( sys className != WC_FRAME) {
1985 sys sizeLockLevel++;
1986 var virtualSize. x = width;
1987 var virtualSize. y = height;
1988 }
1989 if ( height < 0) height = 0;
1990 if ( width < 0) width = 0;
1991 if ( is_apt(aptMovePending)) {
1992 int dx = r. right - r. left;
1993 int dy = r. bottom - r. top;
1994 r. left = sys layeredPos. x;
1995 r. top = sys layeredPos. y;
1996 r. right = r. left + dx;
1997 r. bottom = r. top + dy;
1998 apt_clear(aptMovePending);
1999 }
2000 if ( !SetWindowPos( h, 0,
2001 r. left, r. bottom - height,
2002 width, height,
2003 SWP_NOZORDER | SWP_NOACTIVATE |
2004 ( is_apt( aptWinPosDetermined) ? 0 : SWP_NOMOVE)
2005 )) apiErrRet;
2006 hwnd_repaint_layered( self, false );
2007 if ( sys className != WC_FRAME) sys sizeLockLevel--;
2008 return true;
2009 }
2010
2011 Bool
apc_widget_set_rect(Handle self,int x,int y,int width,int height)2012 apc_widget_set_rect( Handle self, int x, int y, int width, int height)
2013 {
2014 HWND h;
2015 Handle parent;
2016 Point sz;
2017 objCheck false;
2018
2019 if ( !hwnd_check_limits( width, height, false)) apcErrRet( errInvParams);
2020 if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
2021
2022 parent = is_apt( aptClipOwner) ? var owner : application;
2023 sz = ((( PWidget) parent)-> self)-> get_size( parent);
2024 apt_set( aptWinPosDetermined);
2025
2026 h = HANDLE;
2027 if ( sys className == WC_FRAME) {
2028 int ws = apc_window_get_window_state( self);
2029 if (( var stage == csConstructing && ws != wsNormal) || ( ws == wsMinimized)) {
2030 WINDOWPLACEMENT w = {sizeof(WINDOWPLACEMENT)};
2031 if ( !GetWindowPlacement( h, &w)) apiErrRet;
2032 if ( width < 0) width = 0;
2033 if ( height < 0) height = 0;
2034 w. rcNormalPosition. left = x;
2035 w. rcNormalPosition. bottom = sz. y - y;
2036 w. rcNormalPosition. right = x + width;
2037 w. rcNormalPosition. top = sz. y - y - height;
2038 w. flags = 0;
2039 if ( !SetWindowPlacement( h, &w)) apiErrRet;
2040 return true;
2041 }
2042 }
2043
2044 if ( sys className != WC_FRAME) {
2045 sys sizeLockLevel++;
2046 var virtualSize. x = width;
2047 var virtualSize. y = height;
2048 }
2049 if ( height < 0) height = 0;
2050 if ( width < 0) width = 0;
2051 if ( sys parentHandle) {
2052 POINT ppos;
2053 ppos. x = x;
2054 ppos. y = dsys( application) lastSize. y - y;
2055 MapWindowPoints( NULL, sys parentHandle, ( LPPOINT)&ppos, 1);
2056 x = ppos. x;
2057 y = ppos. y;
2058 } else
2059 y = sz. y - y - height;
2060
2061 apt_clear(aptMovePending);
2062 if ( !SetWindowPos( h, 0, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE))
2063 apiErrRet;
2064 hwnd_repaint_layered( self, false );
2065 if ( sys className != WC_FRAME) sys sizeLockLevel--;
2066 return true;
2067 }
2068
2069
2070 Bool
apc_widget_set_size_bounds(Handle self,Point min,Point max)2071 apc_widget_set_size_bounds( Handle self, Point min, Point max)
2072 {
2073 return true;
2074 }
2075
2076 Bool
apc_widget_set_shape(Handle self,Handle mask)2077 apc_widget_set_shape( Handle self, Handle mask)
2078 {
2079 HRGN rgn = NULL;
2080 RECT xr;
2081 objCheck false;
2082
2083 if ( !mask) {
2084 if ( sys className == WC_FRAME && is_apt(aptLayered))
2085 SetWindowRgn((HWND) var handle, NULL, true);
2086 else
2087 SetWindowRgn( HANDLE, NULL, true);
2088 hwnd_repaint_layered( self, false );
2089 return true;
2090 }
2091
2092
2093 rgn = CreateRectRgn(0,0,0,0);
2094 CombineRgn( rgn, GET_REGION(mask)->region, NULL, RGN_COPY);
2095 GetRgnBox( rgn, &xr);
2096 sys extraBounds. x = xr. right - 1;
2097 sys extraBounds. y = GET_REGION(mask)->aperture;
2098 if ( sys className == WC_FRAME && !is_apt(aptLayered)) {
2099 Point delta = get_window_borders( sys s. window. borderStyle);
2100 Point sz = apc_widget_get_size( self);
2101 Point p = sys extraBounds;
2102 HRGN r1, r2;
2103
2104 OffsetRgn( rgn, delta.x, sz. y - p.y - delta.y);
2105 sys extraPos. x = delta.x;
2106 sys extraPos. y = sz. y - p.y - delta.y;
2107 r1 = CreateRectRgn( 0, 0, 8192, 8192);
2108 r2 = CreateRectRgn( delta. x, sz. y - delta. y - p.y,
2109 delta.x + p.x, sz. y - delta. y);
2110 CombineRgn( r1, r1, r2, RGN_XOR);
2111 CombineRgn( rgn, rgn, r1, RGN_OR);
2112 DeleteObject( r1);
2113 DeleteObject( r2);
2114 if ( !SetWindowRgn( HANDLE, rgn, true))
2115 apiErrRet;
2116 DeleteObject(rgn);
2117 } else if ( sys className == WC_FRAME ) {
2118 sys extraPos. x = sys extraPos. y = 0;
2119 if ( !SetWindowRgn((HWND) var handle, rgn, true))
2120 apiErrRet;
2121 } else {
2122 sys extraPos. x = sys extraPos. y = 0;
2123 if ( !SetWindowRgn( HANDLE, rgn, true))
2124 apiErrRet;
2125 }
2126 DeleteObject(rgn);
2127
2128 if ( is_apt(aptMovePending)) {
2129 apt_clear(aptMovePending);
2130 if ( !SetWindowPos( HANDLE, 0, sys layeredPos. x, sys layeredPos. y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE))
2131 apiErrRet;
2132 }
2133 hwnd_repaint_layered( self, false );
2134 return true;
2135 }
2136
2137 Bool
apc_widget_set_visible(Handle self,Bool show)2138 apc_widget_set_visible( Handle self, Bool show)
2139 {
2140 objCheck false;
2141 if ( !SetWindowPos( HANDLE, NULL, 0, 0, 0, 0,
2142 ( show ? SWP_SHOWWINDOW : SWP_HIDEWINDOW)
2143 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) apiErrRet;
2144 objCheck false;
2145 if ( !is_apt( aptClipOwner)) {
2146 InvalidateRect(( HWND) var handle, NULL, false);
2147 objCheck false;
2148 process_transparents( self);
2149 }
2150 hwnd_repaint_layered(self, false);
2151 return true;
2152 }
2153
2154 Bool
apc_widget_set_z_order(Handle self,Handle behind,Bool top)2155 apc_widget_set_z_order( Handle self, Handle behind, Bool top)
2156 {
2157 HWND opt = ( top) ? HWND_TOP : HWND_BOTTOM;
2158 objCheck false;
2159 if ( behind != NULL_HANDLE) {
2160 dobjCheck( behind) false;
2161 opt = DHANDLE( behind);
2162 }
2163 if ( !SetWindowPos( HANDLE, opt, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE)) apiErrRet;
2164 return true;
2165 }
2166
2167 Bool
apc_widget_update(Handle self)2168 apc_widget_update( Handle self)
2169 {
2170 objCheck false;
2171 if ( !apcUpdateWindow(( HWND) var handle)) apiErrRet;
2172 return true;
2173 }
2174
2175 Bool
apc_widget_validate_rect(Handle self,Rect rect)2176 apc_widget_validate_rect( Handle self, Rect rect)
2177 {
2178 objCheck false;
2179 if ( !ValidateRect (( HWND) var handle, map_Rect( self, &rect))) apiErrRet;
2180 return true;
2181 }
2182
2183
2184 #ifdef __cplusplus
2185 }
2186 #endif
2187