2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
16 #include "cursoricon.h"
19 #include "nonclient.h"
22 #include "shm_main_blk.h"
26 /* #define DEBUG_WIN */
27 /* #define DEBUG_MENU */
30 static HWND hwndDesktop
= 0;
31 static HWND hwndSysModal
= 0;
33 static WORD wDragWidth
= 4;
34 static WORD wDragHeight
= 3;
36 extern HCURSOR
CURSORICON_IconToCursor(HICON
);
38 /***********************************************************************
41 * Return a pointer to the WND structure corresponding to a HWND.
43 WND
* WIN_FindWndPtr( HWND hwnd
)
47 if (!hwnd
) return NULL
;
48 ptr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
49 if (ptr
->dwMagic
!= WND_MAGIC
) return NULL
;
54 /***********************************************************************
57 * Return the X window associated to a window.
59 Window
WIN_GetXWindow( HWND hwnd
)
61 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
62 while (wndPtr
&& !wndPtr
->window
)
64 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
66 return wndPtr
? wndPtr
->window
: 0;
70 /***********************************************************************
73 * Remove a window from the siblings linked list.
75 BOOL
WIN_UnlinkWindow( HWND hwnd
)
78 WND
*parentPtr
, *wndPtr
;
80 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
81 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
83 curWndPtr
= &parentPtr
->hwndChild
;
85 while (*curWndPtr
!= hwnd
)
87 WND
* curPtr
= WIN_FindWndPtr( *curWndPtr
);
88 curWndPtr
= &curPtr
->hwndNext
;
90 *curWndPtr
= wndPtr
->hwndNext
;
95 /***********************************************************************
98 * Insert a window into the siblings linked list.
99 * The window is inserted after the specified window, which can also
100 * be specified as HWND_TOP or HWND_BOTTOM.
102 BOOL
WIN_LinkWindow( HWND hwnd
, HWND hwndInsertAfter
)
104 HWND
* hwndPtr
= NULL
; /* pointer to hwnd to change */
105 WND
*wndPtr
, *parentPtr
;
107 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
108 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
110 if ((hwndInsertAfter
== HWND_TOP
) || (hwndInsertAfter
== HWND_BOTTOM
))
112 hwndPtr
= &parentPtr
->hwndChild
; /* Point to first sibling hwnd */
113 if (hwndInsertAfter
== HWND_BOTTOM
) /* Find last sibling hwnd */
116 WND
* nextPtr
= WIN_FindWndPtr( *hwndPtr
);
117 hwndPtr
= &nextPtr
->hwndNext
;
120 else /* Normal case */
122 WND
* afterPtr
= WIN_FindWndPtr( hwndInsertAfter
);
123 if (afterPtr
) hwndPtr
= &afterPtr
->hwndNext
;
125 if (!hwndPtr
) return FALSE
;
126 wndPtr
->hwndNext
= *hwndPtr
;
132 /***********************************************************************
133 * WIN_FindWinToRepaint
135 * Find a window that needs repaint.
137 HWND
WIN_FindWinToRepaint( HWND hwnd
)
141 /* Note: the desktop window never gets WM_PAINT messages */
142 if (!hwnd
) hwnd
= GetTopWindow( hwndDesktop
);
143 for ( ; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
145 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
146 dprintf_win( stddeb
, "WIN_FindWinToRepaint: "NPFMT
", style %08lx\n",
147 hwnd
, wndPtr
->dwStyle
);
148 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) || (wndPtr
->flags
& WIN_NO_REDRAW
))
150 if ((wndPtr
->dwStyle
& WS_MINIMIZE
) && (WIN_CLASS_INFO(wndPtr
).hIcon
))
152 if (wndPtr
->hrgnUpdate
|| (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
154 if (wndPtr
->hwndChild
)
157 if ((child
= WIN_FindWinToRepaint( wndPtr
->hwndChild
)))
165 /***********************************************************************
166 * WIN_SendParentNotify
168 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
169 * the window has the WS_EX_NOPARENTNOTIFY style.
171 void WIN_SendParentNotify( HWND hwnd
, WORD event
, WORD idChild
, LONG lValue
)
173 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
175 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
177 if (wndPtr
->dwExStyle
& WS_EX_NOPARENTNOTIFY
) break;
179 SendMessage( wndPtr
->hwndParent
, WM_PARENTNOTIFY
,
180 MAKEWPARAM(event
,idChild
),
183 SendMessage( wndPtr
->hwndParent
, WM_PARENTNOTIFY
, event
,
184 MAKELPARAM(LOWORD(lValue
), idChild
) );
186 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
191 /***********************************************************************
194 * Destroy storage associated to a window
196 static void WIN_DestroyWindow( HWND hwnd
)
198 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
199 CLASS
*classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
);
203 DDE_DestroyWindow(hwnd
);
204 #endif /* CONFIG_IPC */
206 if (!wndPtr
|| !classPtr
) return;
207 WIN_UnlinkWindow( hwnd
); /* Remove the window from the linked list */
208 wndPtr
->dwMagic
= 0; /* Mark it as invalid */
209 if ((wndPtr
->hrgnUpdate
) || (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
211 if (wndPtr
->hrgnUpdate
) DeleteObject( wndPtr
->hrgnUpdate
);
212 MSG_DecPaintCount( wndPtr
->hmemTaskQ
);
214 if (!(wndPtr
->dwStyle
& WS_CHILD
))
216 if (wndPtr
->wIDmenu
) DestroyMenu( (HMENU
)wndPtr
->wIDmenu
);
218 if (wndPtr
->hSysMenu
) DestroyMenu( wndPtr
->hSysMenu
);
219 if (wndPtr
->window
) XDestroyWindow( display
, wndPtr
->window
);
220 if (classPtr
->wc
.style
& CS_OWNDC
) DCE_FreeDCE( wndPtr
->hdce
);
221 classPtr
->cWindows
--;
222 USER_HEAP_FREE( hwnd
);
226 /***********************************************************************
227 * WIN_CreateDesktopWindow
229 * Create the desktop window.
231 BOOL
WIN_CreateDesktopWindow(void)
238 if (!(hclass
= CLASS_FindClassByName( DESKTOP_CLASS_ATOM
, 0, &classPtr
)))
241 hwndDesktop
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
242 if (!hwndDesktop
) return FALSE
;
243 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwndDesktop
);
245 wndPtr
->hwndNext
= 0;
246 wndPtr
->hwndChild
= 0;
247 wndPtr
->dwMagic
= WND_MAGIC
;
248 wndPtr
->hwndParent
= 0;
249 wndPtr
->hwndOwner
= 0;
250 wndPtr
->hClass
= hclass
;
251 wndPtr
->hInstance
= 0;
252 wndPtr
->rectWindow
.left
= 0;
253 wndPtr
->rectWindow
.top
= 0;
254 wndPtr
->rectWindow
.right
= SYSMETRICS_CXSCREEN
;
255 wndPtr
->rectWindow
.bottom
= SYSMETRICS_CYSCREEN
;
256 wndPtr
->rectClient
= wndPtr
->rectWindow
;
257 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
258 wndPtr
->ptIconPos
.x
= -1;
259 wndPtr
->ptIconPos
.y
= -1;
260 wndPtr
->ptMaxPos
.x
= -1;
261 wndPtr
->ptMaxPos
.y
= -1;
262 wndPtr
->hmemTaskQ
= 0; /* Desktop does not belong to a task */
263 wndPtr
->hrgnUpdate
= 0;
264 wndPtr
->hwndLastActive
= hwndDesktop
;
265 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
266 wndPtr
->dwStyle
= WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
267 wndPtr
->dwExStyle
= 0;
269 wndPtr
->hVScroll
= 0;
270 wndPtr
->hHScroll
= 0;
274 wndPtr
->window
= rootWindow
;
275 wndPtr
->hSysMenu
= 0;
277 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
278 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
279 if ((hdc
= GetDC( hwndDesktop
)) != 0)
281 SendMessage( hwndDesktop
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0 );
282 ReleaseDC( hwndDesktop
, hdc
);
288 /***********************************************************************
289 * CreateWindow (USER.41)
291 HWND
CreateWindow( SEGPTR className
, SEGPTR windowName
,
292 DWORD style
, INT x
, INT y
, INT width
, INT height
,
293 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
295 return CreateWindowEx( 0, className
, windowName
, style
,
296 x
, y
, width
, height
, parent
, menu
, instance
, data
);
300 /***********************************************************************
301 * CreateWindowEx (USER.452)
303 HWND
CreateWindowEx( DWORD exStyle
, SEGPTR className
, SEGPTR windowName
,
304 DWORD style
, INT x
, INT y
, INT width
, INT height
,
305 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
310 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
311 CREATESTRUCT createStruct
;
313 XSetWindowAttributes win_attr
;
315 /* FIXME: windowName and className should be SEGPTRs */
317 dprintf_win( stddeb
, "CreateWindowEx: " );
318 if (HIWORD(windowName
))
319 dprintf_win( stddeb
, "'%s' ", (char *)PTR_SEG_TO_LIN(windowName
) );
321 dprintf_win( stddeb
, "%04x ", LOWORD(windowName
) );
322 if (HIWORD(className
))
323 dprintf_win( stddeb
, "'%s' ", (char *)PTR_SEG_TO_LIN(className
) );
325 dprintf_win( stddeb
, "%04x ", LOWORD(className
) );
327 dprintf_win(stddeb
, "%08lx %08lx %d,%d %dx%d "NPFMT
" "NPFMT
" "NPFMT
" %08lx\n",
328 exStyle
, style
, x
, y
, width
, height
,
329 parent
, menu
, instance
, (DWORD
)data
);
331 if (x
== CW_USEDEFAULT
) x
= y
= 0;
332 if (width
== CW_USEDEFAULT
)
338 /* Find the parent and class */
342 /* Make sure parent is valid */
343 if (!IsWindow( parent
)) {
344 dprintf_win(stddeb
,"CreateWindowEx: Parent "NPFMT
" is not a window\n", parent
);
350 if (style
& WS_CHILD
) {
351 dprintf_win(stddeb
,"CreateWindowEx: no parent\n");
352 return 0; /* WS_CHILD needs a parent */
356 if (!(class = CLASS_FindClassByName( className
, GetExePtr(instance
),
359 fprintf(stderr
,"CreateWindow BAD CLASSNAME " );
360 if (HIWORD(className
)) fprintf( stderr
, "'%s'\n",
361 (char *)PTR_SEG_TO_LIN(className
) );
362 else fprintf( stderr
, "%04x\n", LOWORD(className
) );
366 /* Correct the window style */
368 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
369 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
370 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
372 /* Create the window structure */
374 hwnd
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
376 dprintf_win(stddeb
,"CreateWindowEx: Out of memory\n");
380 /* Fill the structure */
382 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
383 wndPtr
->hwndNext
= 0;
384 wndPtr
->hwndChild
= 0;
386 wndPtr
->dwMagic
= WND_MAGIC
;
387 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
388 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : WIN_GetTopParent(parent
);
389 wndPtr
->hClass
= class;
390 wndPtr
->hInstance
= instance
;
391 wndPtr
->ptIconPos
.x
= -1;
392 wndPtr
->ptIconPos
.y
= -1;
393 wndPtr
->ptMaxPos
.x
= -1;
394 wndPtr
->ptMaxPos
.y
= -1;
395 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
396 wndPtr
->hrgnUpdate
= 0;
397 wndPtr
->hwndLastActive
= hwnd
;
398 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
399 wndPtr
->dwStyle
= style
& ~WS_VISIBLE
;
400 wndPtr
->dwExStyle
= exStyle
;
404 wndPtr
->hVScroll
= 0;
405 wndPtr
->hHScroll
= 0;
406 wndPtr
->hSysMenu
= 0;
409 if (classPtr
->wc
.cbWndExtra
)
410 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
411 classPtr
->cWindows
++;
413 /* Get class or window DC if needed */
415 if (classPtr
->wc
.style
& CS_OWNDC
)
416 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
417 else if (classPtr
->wc
.style
& CS_CLASSDC
)
418 wndPtr
->hdce
= classPtr
->hdce
;
422 /* Insert the window in the linked list */
424 WIN_LinkWindow( hwnd
, HWND_TOP
);
426 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
428 NC_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
430 if (maxSize
.x
< width
) width
= maxSize
.x
;
431 if (maxSize
.y
< height
) height
= maxSize
.y
;
432 if (width
<= 0) width
= 1;
433 if (height
<= 0) height
= 1;
435 wndPtr
->rectWindow
.left
= x
;
436 wndPtr
->rectWindow
.top
= y
;
437 wndPtr
->rectWindow
.right
= x
+ width
;
438 wndPtr
->rectWindow
.bottom
= y
+ height
;
439 wndPtr
->rectClient
= wndPtr
->rectWindow
;
440 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
442 /* Create the X window (only for top-level windows, and then only */
443 /* when there's no desktop window) */
445 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
447 if(Options
.managed
&& className
!= POPUPMENU_CLASS_ATOM
) {
448 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
449 KeyReleaseMask
| PointerMotionMask
|
450 ButtonPressMask
| ButtonReleaseMask
|
451 FocusChangeMask
| StructureNotifyMask
;
452 win_attr
.override_redirect
= FALSE
;
455 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
456 KeyReleaseMask
| PointerMotionMask
|
457 ButtonPressMask
| ButtonReleaseMask
|
459 win_attr
.override_redirect
= TRUE
;
461 win_attr
.colormap
= COLOR_WinColormap
;
462 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
463 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
464 win_attr
.cursor
= CURSORICON_XCursor
;
465 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
466 width
, height
, 0, CopyFromParent
,
467 InputOutput
, CopyFromParent
,
468 CWEventMask
| CWOverrideRedirect
|
469 CWColormap
| CWCursor
| CWSaveUnder
|
470 CWBackingStore
, &win_attr
);
471 XStoreName( display
, wndPtr
->window
, PTR_SEG_TO_LIN(windowName
) );
472 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
475 if ((style
& WS_CAPTION
) && !(style
& WS_CHILD
))
477 if (menu
) SetMenu(hwnd
, menu
);
478 else if (classPtr
->wc
.lpszMenuName
)
479 SetMenu( hwnd
, LoadMenu( instance
, classPtr
->wc
.lpszMenuName
) );
481 else wndPtr
->wIDmenu
= (UINT
)menu
;
483 GetSystemMenu( hwnd
, TRUE
); /* Create a copy of the system menu */
485 /* Send the WM_CREATE message */
487 createStruct
.lpCreateParams
= (LPSTR
)data
;
488 createStruct
.hInstance
= instance
;
489 createStruct
.hMenu
= menu
;
490 createStruct
.hwndParent
= parent
;
491 createStruct
.cx
= width
;
492 createStruct
.cy
= height
;
495 createStruct
.style
= style
;
496 createStruct
.lpszName
= windowName
;
497 createStruct
.lpszClass
= className
;
498 createStruct
.dwExStyle
= 0;
500 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, (LPARAM
)MAKE_SEGPTR(&createStruct
) );
503 dprintf_win(stddeb
,"CreateWindowEx: WM_NCCREATE return 0\n");
508 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
509 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
510 wmcreate
= SendMessage(hwnd
, WM_CREATE
, 0, (LPARAM
)MAKE_SEGPTR(&createStruct
));
515 /* Abort window creation */
516 dprintf_win(stddeb
,"CreateWindowEx: wmcreate==-1, aborting\n");
517 WIN_DestroyWindow( hwnd
);
521 WIN_SendParentNotify( hwnd
, WM_CREATE
, wndPtr
->wIDmenu
, (LONG
)hwnd
);
523 /* Show the window, maximizing or minimizing if needed */
525 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
527 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
528 WINPOS_FindIconPos( hwnd
);
529 SetWindowPos( hwnd
, 0, wndPtr
->ptIconPos
.x
, wndPtr
->ptIconPos
.y
,
530 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
,
532 (style
& WS_VISIBLE
) ? SWP_SHOWWINDOW
: 0 );
534 else if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
536 SetWindowPos( hwnd
, 0, maxPos
.x
, maxPos
.y
, maxSize
.x
, maxSize
.y
,
538 (style
& WS_VISIBLE
) ? SWP_SHOWWINDOW
: 0 );
540 else if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
542 dprintf_win(stddeb
, "CreateWindowEx: return "NPFMT
" \n", hwnd
);
547 /***********************************************************************
548 * DestroyWindow (USER.53)
550 BOOL
DestroyWindow( HWND hwnd
)
555 dprintf_win(stddeb
, "DestroyWindow ("NPFMT
")\n", hwnd
);
559 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
560 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
561 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
563 /* Hide the window */
565 if (wndPtr
->dwStyle
& WS_VISIBLE
)
566 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
567 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
568 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
570 WIN_SendParentNotify( hwnd
, WM_DESTROY
, wndPtr
->wIDmenu
, (LONG
)hwnd
);
572 /* Recursively destroy owned windows */
576 HWND hwndSibling
= GetWindow( hwnd
, GW_HWNDFIRST
);
579 WND
*siblingPtr
= WIN_FindWndPtr( hwndSibling
);
580 if (siblingPtr
->hwndOwner
== hwnd
) break;
581 hwndSibling
= siblingPtr
->hwndNext
;
583 if (hwndSibling
) DestroyWindow( hwndSibling
);
587 /* Send destroy messages and destroy children */
589 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
590 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
591 DestroyWindow( wndPtr
->hwndChild
);
592 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
594 /* Destroy the window */
596 WIN_DestroyWindow( hwnd
);
601 /***********************************************************************
602 * CloseWindow (USER.43)
604 void CloseWindow(HWND hWnd
)
606 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
607 if (wndPtr
->dwStyle
& WS_CHILD
) return;
608 ShowWindow(hWnd
, SW_MINIMIZE
);
612 /***********************************************************************
615 BOOL
OpenIcon(HWND hWnd
)
617 if (!IsIconic(hWnd
)) return FALSE
;
618 ShowWindow(hWnd
, SW_SHOWNORMAL
);
623 /***********************************************************************
624 * FindWindow (USER.50)
626 HWND
FindWindow( SEGPTR ClassMatch
, LPSTR TitleMatch
)
634 hclass
= CLASS_FindClassByName( ClassMatch
, (HINSTANCE
)0xffff,
636 if (!hclass
) return 0;
640 hwnd
= GetTopWindow( hwndDesktop
);
643 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
644 if (!hclass
|| (wndPtr
->hClass
== hclass
))
646 /* Found matching class */
647 if (!TitleMatch
) return hwnd
;
650 char *textPtr
= (char *) USER_HEAP_LIN_ADDR( wndPtr
->hText
);
651 if (!strcmp( textPtr
, TitleMatch
)) return hwnd
;
654 hwnd
= wndPtr
->hwndNext
;
660 /**********************************************************************
661 * GetDesktopWindow (USER.286)
662 * GetDeskTopHwnd (USER.278)
664 HWND
GetDesktopWindow(void)
670 /*******************************************************************
671 * EnableWindow (USER.34)
673 BOOL
EnableWindow( HWND hwnd
, BOOL enable
)
677 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
678 if (enable
&& (wndPtr
->dwStyle
& WS_DISABLED
))
681 wndPtr
->dwStyle
&= ~WS_DISABLED
;
682 SendMessage( hwnd
, WM_ENABLE
, TRUE
, 0 );
685 else if (!enable
&& !(wndPtr
->dwStyle
& WS_DISABLED
))
688 wndPtr
->dwStyle
|= WS_DISABLED
;
689 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus() ))
690 SetFocus( 0 ); /* A disabled window can't have the focus */
691 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
692 ReleaseCapture(); /* A disabled window can't capture the mouse */
693 SendMessage( hwnd
, WM_ENABLE
, FALSE
, 0 );
696 return ((wndPtr
->dwStyle
& WS_DISABLED
) != 0);
700 /***********************************************************************
701 * IsWindowEnabled (USER.35)
703 BOOL
IsWindowEnabled(HWND hWnd
)
707 if (!(wndPtr
= WIN_FindWndPtr(hWnd
))) return FALSE
;
708 return !(wndPtr
->dwStyle
& WS_DISABLED
);
712 /**********************************************************************
713 * GetWindowWord (USER.133)
715 WORD
GetWindowWord( HWND hwnd
, short offset
)
717 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
718 if (!wndPtr
) return 0;
719 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
722 case GWW_ID
: return wndPtr
->wIDmenu
;
726 fprintf(stderr
,"GetWindowWord called with offset %d.\n",offset
);
729 case GWW_HWNDPARENT
: return (WORD
)wndPtr
->hwndParent
;
730 case GWW_HINSTANCE
: return (WORD
)wndPtr
->hInstance
;
737 /**********************************************************************
738 * WIN_GetWindowInstance
740 HINSTANCE
WIN_GetWindowInstance(HWND hwnd
)
742 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
743 if (!wndPtr
) return (HINSTANCE
)0;
744 return wndPtr
->hInstance
;
748 /**********************************************************************
749 * SetWindowWord (USER.134)
751 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
754 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
755 if (!wndPtr
) return 0;
756 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
762 fprintf(stderr
,"SetWindowWord called with offset %d.\n",offset
);
765 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
; break;
766 case GWW_HINSTANCE
: ptr
= (WORD
*)&wndPtr
->hInstance
; break;
776 /**********************************************************************
777 * GetWindowLong (USER.135)
779 LONG
GetWindowLong( HWND hwnd
, short offset
)
781 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
782 if (!wndPtr
) return 0;
783 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
786 case GWL_STYLE
: return wndPtr
->dwStyle
;
787 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
788 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
790 case GWW_HWNDPARENT
: return (LONG
)wndPtr
->hwndParent
;
791 case GWW_HINSTANCE
: return (LONG
)wndPtr
->hInstance
;
798 /**********************************************************************
799 * SetWindowLong (USER.136)
801 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
804 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
805 if (!wndPtr
) return 0;
806 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
809 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
; break;
810 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
; break;
811 case GWL_WNDPROC
: ptr
= (LONG
*)&wndPtr
->lpfnWndProc
; break;
820 /*******************************************************************
821 * GetWindowText (USER.36)
823 int WIN16_GetWindowText( HWND hwnd
, SEGPTR lpString
, int nMaxCount
)
825 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
829 int GetWindowText( HWND hwnd
, LPSTR lpString
, int nMaxCount
)
834 /* We have to allocate a buffer on the USER heap */
835 /* to be able to pass its address to 16-bit code */
836 if (!(handle
= USER_HEAP_ALLOC( nMaxCount
))) return 0;
837 len
= (int)SendMessage( hwnd
, WM_GETTEXT
, (WPARAM
)nMaxCount
,
838 (LPARAM
)USER_HEAP_SEG_ADDR(handle
) );
839 strncpy( lpString
, USER_HEAP_LIN_ADDR(handle
), nMaxCount
);
840 USER_HEAP_FREE( handle
);
845 /*******************************************************************
846 * SetWindowText (USER.37)
848 void WIN16_SetWindowText( HWND hwnd
, SEGPTR lpString
)
850 SendMessage( hwnd
, WM_SETTEXT
, 0, (DWORD
)lpString
);
853 void SetWindowText( HWND hwnd
, LPSTR lpString
)
857 /* We have to allocate a buffer on the USER heap */
858 /* to be able to pass its address to 16-bit code */
859 if (!(handle
= USER_HEAP_ALLOC( strlen(lpString
)+1 ))) return;
860 strcpy( USER_HEAP_LIN_ADDR(handle
), lpString
);
861 SendMessage( hwnd
, WM_SETTEXT
, 0, (LPARAM
)USER_HEAP_SEG_ADDR(handle
) );
862 USER_HEAP_FREE( handle
);
866 /*******************************************************************
867 * GetWindowTextLength (USER.38)
869 int GetWindowTextLength(HWND hwnd
)
871 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
875 /*******************************************************************
878 BOOL
IsWindow( HWND hwnd
)
880 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
881 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
885 /*****************************************************************
886 * GetParent (USER.46)
888 HWND
GetParent(HWND hwnd
)
890 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
891 if (!wndPtr
) return 0;
892 return (wndPtr
->dwStyle
& WS_CHILD
) ?
893 wndPtr
->hwndParent
: wndPtr
->hwndOwner
;
897 /*****************************************************************
900 * Get the top-level parent for a child window.
902 HWND
WIN_GetTopParent( HWND hwnd
)
906 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
907 if (wndPtr
->dwStyle
& WS_CHILD
) hwnd
= wndPtr
->hwndParent
;
914 /*****************************************************************
915 * SetParent (USER.233)
917 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
921 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
922 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
924 temp
= wndPtr
->hwndParent
;
926 WIN_UnlinkWindow(hwndChild
);
928 wndPtr
->hwndParent
= hwndNewParent
;
930 wndPtr
->hwndParent
= GetDesktopWindow();
931 WIN_LinkWindow(hwndChild
, HWND_BOTTOM
);
933 if (IsWindowVisible(hwndChild
)) UpdateWindow(hwndChild
);
940 /*******************************************************************
943 BOOL
IsChild( HWND parent
, HWND child
)
945 WND
* wndPtr
= WIN_FindWndPtr( child
);
946 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
948 if (wndPtr
->hwndParent
== parent
) return TRUE
;
949 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
955 /***********************************************************************
956 * IsWindowVisible (USER.49)
958 BOOL
IsWindowVisible( HWND hwnd
)
960 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
961 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
963 if (!(wndPtr
->dwStyle
& WS_VISIBLE
)) return FALSE
;
964 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
966 return (wndPtr
&& (wndPtr
->dwStyle
& WS_VISIBLE
));
971 /*******************************************************************
972 * GetTopWindow (USER.229)
974 HWND
GetTopWindow( HWND hwnd
)
976 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
977 if (wndPtr
) return wndPtr
->hwndChild
;
982 /*******************************************************************
983 * GetWindow (USER.262)
985 HWND
GetWindow( HWND hwnd
, WORD rel
)
987 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
988 if (!wndPtr
) return 0;
992 if (wndPtr
->hwndParent
)
994 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
995 return parentPtr
->hwndChild
;
1000 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
1001 while (wndPtr
->hwndNext
)
1003 hwnd
= wndPtr
->hwndNext
;
1004 wndPtr
= WIN_FindWndPtr( hwnd
);
1009 return wndPtr
->hwndNext
;
1015 if (wndPtr
->hwndParent
)
1017 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
1018 hwndPrev
= parentPtr
->hwndChild
;
1020 else return 0; /* Desktop window */
1021 if (hwndPrev
== hwnd
) return 0;
1024 wndPtr
= WIN_FindWndPtr( hwndPrev
);
1025 if (wndPtr
->hwndNext
== hwnd
) break;
1026 hwndPrev
= wndPtr
->hwndNext
;
1032 return wndPtr
->hwndOwner
;
1035 return wndPtr
->hwndChild
;
1041 /*******************************************************************
1042 * GetNextWindow (USER.230)
1044 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
1046 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
1047 return GetWindow( hwnd
, flag
);
1050 /*******************************************************************
1051 * ShowOwnedPopups (USER.265)
1053 void ShowOwnedPopups( HWND owner
, BOOL fShow
)
1055 HWND hwnd
= GetWindow( hwndDesktop
, GW_CHILD
);
1058 WND
*wnd
= WIN_FindWndPtr(hwnd
);
1059 if (wnd
->hwndOwner
== owner
&& (wnd
->dwStyle
& WS_POPUP
))
1060 ShowWindow( hwnd
, fShow
? SW_SHOW
: SW_HIDE
);
1061 hwnd
= wnd
->hwndNext
;
1066 /*******************************************************************
1067 * GetLastActivePopup (USER.287)
1069 HWND
GetLastActivePopup(HWND hwnd
)
1072 wndPtr
= WIN_FindWndPtr(hwnd
);
1073 if (wndPtr
== NULL
) return hwnd
;
1074 return wndPtr
->hwndLastActive
;
1078 /*******************************************************************
1079 * EnumWindows (USER.54)
1081 BOOL
EnumWindows( FARPROC lpEnumFunc
, LPARAM lParam
)
1088 /* We have to build a list of all windows first, to avoid */
1089 /* unpleasant side-effects, for instance if the callback */
1090 /* function changes the Z-order of the windows. */
1092 /* First count the windows */
1095 for (hwnd
= GetTopWindow(hwndDesktop
); hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1097 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1100 if (!count
) return TRUE
;
1102 /* Now build the list of all windows */
1104 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1105 for (hwnd
= GetTopWindow(hwndDesktop
), pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1107 wndPtr
= WIN_FindWndPtr( hwnd
);
1111 /* Now call the callback function for every window */
1113 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1115 /* Make sure that window still exists */
1116 if (!IsWindow(*pWnd
)) continue;
1117 if (!CallEnumWindowsProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1124 /**********************************************************************
1125 * EnumTaskWindows (USER.225)
1127 BOOL
EnumTaskWindows( HTASK hTask
, FARPROC lpEnumFunc
, LONG lParam
)
1132 HANDLE hQueue
= GetTaskQueue( hTask
);
1135 /* This function is the same as EnumWindows(), */
1136 /* except for an added check on the window queue. */
1138 /* First count the windows */
1141 for (hwnd
= GetTopWindow(hwndDesktop
); hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1143 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1144 if (wndPtr
->hmemTaskQ
== hQueue
) count
++;
1146 if (!count
) return TRUE
;
1148 /* Now build the list of all windows */
1150 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1151 for (hwnd
= GetTopWindow(hwndDesktop
), pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1153 wndPtr
= WIN_FindWndPtr( hwnd
);
1154 if (wndPtr
->hmemTaskQ
== hQueue
) *pWnd
++ = hwnd
;
1157 /* Now call the callback function for every window */
1159 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1161 /* Make sure that window still exists */
1162 if (!IsWindow(*pWnd
)) continue;
1163 if (!CallEnumTaskWndProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1170 /*******************************************************************
1173 * o hwnd is the first child to use, loop until all next windows
1178 * o call ourselves with the next child window
1181 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1187 if (!(wndPtr
=WIN_FindWndPtr(hwnd
))) return 0;
1188 if (!CallEnumWindowsProc( wndenumprc
, hwnd
, lParam
)) return 0;
1189 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) return 0;
1190 hwnd
=wndPtr
->hwndNext
;
1195 /*******************************************************************
1196 * EnumChildWindows (USER.55)
1198 * o gets the first child of hwnd
1200 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1202 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1206 dprintf_enum(stddeb
,"EnumChildWindows\n");
1208 if (hwnd
== 0) return 0;
1209 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1210 hwnd
= wndPtr
->hwndChild
;
1211 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1215 /*******************************************************************
1216 * AnyPopup [USER.52]
1220 WND
*wndPtr
= WIN_FindWndPtr(hwndDesktop
);
1221 HWND hwnd
= wndPtr
->hwndChild
;
1223 for( ; hwnd
; hwnd
= wndPtr
->hwndNext
)
1225 wndPtr
= WIN_FindWndPtr(hwnd
);
1226 if(wndPtr
->hwndOwner
)
1227 if(wndPtr
->dwStyle
& WS_VISIBLE
)
1233 /*******************************************************************
1234 * FlashWindow [USER.105]
1236 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1238 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1243 /*******************************************************************
1244 * SetSysModalWindow [USER.188]
1246 HWND
SetSysModalWindow(HWND hWnd
)
1248 HWND hWndOldModal
= hwndSysModal
;
1249 hwndSysModal
= hWnd
;
1250 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow("NPFMT
") !\n", hWnd
);
1251 return hWndOldModal
;
1255 /*******************************************************************
1256 * GetSysModalWindow [USER.189]
1258 HWND
GetSysModalWindow(void)
1260 return hwndSysModal
;
1263 /*******************************************************************
1266 * recursively find a child that contains spDragInfo->pt point
1267 * and send WM_QUERYDROPOBJECT
1269 BOOL
DRAG_QueryUpdate( HWND hQueryWnd
, SEGPTR spDragInfo
)
1272 BOOL wParam
,bResult
= 0;
1274 LPDRAGINFO ptrDragInfo
= (LPDRAGINFO
) PTR_SEG_TO_LIN(spDragInfo
);
1275 WND
*ptrQueryWnd
= WIN_FindWndPtr(hQueryWnd
),*ptrWnd
;
1276 RECT tempRect
; /* this sucks */
1278 if( !ptrQueryWnd
|| !ptrDragInfo
) return 0;
1280 pt
= ptrDragInfo
->pt
;
1282 GetWindowRect(hQueryWnd
,&tempRect
);
1284 if( !PtInRect(&tempRect
,pt
) ||
1285 (ptrQueryWnd
->dwStyle
& WS_DISABLED
) )
1288 if( !(ptrQueryWnd
->dwStyle
& WS_MINIMIZE
) )
1290 tempRect
= ptrQueryWnd
->rectClient
;
1291 if(ptrQueryWnd
->dwStyle
& WS_CHILD
)
1292 MapWindowPoints(ptrQueryWnd
->hwndParent
,0,(LPPOINT
)&tempRect
,2);
1294 if( PtInRect(&tempRect
,pt
) )
1297 ptrWnd
= WIN_FindWndPtr(hWnd
= ptrQueryWnd
->hwndChild
);
1299 for( ;ptrWnd
;ptrWnd
= WIN_FindWndPtr(hWnd
= ptrWnd
->hwndNext
) )
1300 if( ptrWnd
->dwStyle
& WS_VISIBLE
)
1302 GetWindowRect(hWnd
,&tempRect
);
1304 if( PtInRect(&tempRect
,pt
) )
1309 dprintf_msg(stddeb
,"DragQueryUpdate: hwnd = "NPFMT
", %i %i - %i %i\n",hWnd
,
1310 (int)ptrWnd
->rectWindow
.left
,(int)ptrWnd
->rectWindow
.top
,
1311 (int)ptrWnd
->rectWindow
.right
,(int)ptrWnd
->rectWindow
.bottom
);
1313 dprintf_msg(stddeb
,"DragQueryUpdate: hwnd = "NPFMT
"\n",hWnd
);
1316 if( !(ptrWnd
->dwStyle
& WS_DISABLED
) )
1317 bResult
= DRAG_QueryUpdate(hWnd
, spDragInfo
);
1319 if(bResult
) return bResult
;
1325 ScreenToClient(hQueryWnd
,&ptrDragInfo
->pt
);
1327 ptrDragInfo
->hScope
= hQueryWnd
;
1329 bResult
= SendMessage( hQueryWnd
,WM_QUERYDROPOBJECT
,
1330 (WPARAM
)wParam
,(LPARAM
) spDragInfo
);
1332 ptrDragInfo
->pt
= pt
;
1337 /*******************************************************************
1338 * DragDetect ( USER.465 )
1341 BOOL
DragDetect(HWND hWnd
, POINT pt
)
1346 rect
.left
= pt
.x
- wDragWidth
;
1347 rect
.right
= pt
.x
+ wDragWidth
;
1349 rect
.top
= pt
.y
- wDragHeight
;
1350 rect
.bottom
= pt
.y
+ wDragHeight
;
1356 while(PeekMessage(&msg
,0 ,WM_MOUSEFIRST
,WM_MOUSELAST
,PM_REMOVE
))
1358 if( msg
.message
== WM_LBUTTONUP
)
1363 if( msg
.message
== WM_MOUSEMOVE
)
1365 POINT pt
= { LOWORD(msg
.lParam
), HIWORD(msg
.lParam
) };
1366 if( !PtInRect( &rect
, pt
) )
1379 /******************************************************************************
1380 * DragObject ( USER.464 )
1383 DWORD
DragObject(HWND hwndScope
, HWND hWnd
, WORD wObj
, HANDLE hOfStruct
,
1384 WORD szList
, HCURSOR hCursor
)
1387 LPDRAGINFO lpDragInfo
;
1389 HCURSOR hDragCursor
=0, hOldCursor
=0, hBummer
=0;
1390 HANDLE hDragInfo
= GlobalAlloc( GMEM_SHARE
| GMEM_ZEROINIT
, 2*sizeof(DRAGINFO
));
1391 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
1394 HCURSOR hCurrentCursor
= 0;
1395 HWND hCurrentWnd
= 0;
1398 fprintf(stdnimp
,"DragObject: experimental\n");
1400 lpDragInfo
= (LPDRAGINFO
) GlobalLock(hDragInfo
);
1401 spDragInfo
= (SEGPTR
) WIN16_GlobalLock(hDragInfo
);
1403 if( !lpDragInfo
|| !spDragInfo
) return 0L;
1405 hBummer
= LoadCursor(0,IDC_BUMMER
);
1407 if( !hBummer
|| !wndPtr
)
1409 GlobalFree(hDragInfo
);
1415 if( !(hDragCursor
= CURSORICON_IconToCursor(hCursor
)) )
1417 GlobalFree(hDragInfo
);
1421 if( hDragCursor
== hCursor
) hDragCursor
= 0;
1422 else hCursor
= hDragCursor
;
1424 hOldCursor
= SetCursor(hDragCursor
);
1427 lpDragInfo
->hWnd
= hWnd
;
1428 lpDragInfo
->hScope
= 0;
1429 lpDragInfo
->wFlags
= wObj
;
1430 lpDragInfo
->hList
= szList
; /* near pointer! */
1431 lpDragInfo
->hOfStruct
= hOfStruct
;
1441 if( !PeekMessage(&msg
,0,WM_MOUSEFIRST
,WM_MOUSELAST
,PM_REMOVE
) )
1444 *(lpDragInfo
+1) = *lpDragInfo
;
1446 lpDragInfo
->pt
= msg
.pt
;
1448 /* update DRAGINFO struct */
1449 dprintf_msg(stddeb
,"drag: lpDI->hScope = "NPFMT
"\n",lpDragInfo
->hScope
);
1451 if( (btemp
= (WORD
)DRAG_QueryUpdate(hwndScope
, spDragInfo
)) > 0 )
1452 hCurrentCursor
= hCursor
;
1455 hCurrentCursor
= hBummer
;
1456 lpDragInfo
->hScope
= 0;
1458 if( hCurrentCursor
)
1459 SetCursor(hCurrentCursor
);
1461 dprintf_msg(stddeb
,"drag: got %04x\n",btemp
);
1463 /* send WM_DRAGLOOP */
1464 SendMessage( hWnd
, WM_DRAGLOOP
, (WPARAM
)(hCurrentCursor
!= hBummer
) ,
1465 (LPARAM
) spDragInfo
);
1466 /* send WM_DRAGSELECT or WM_DRAGMOVE */
1467 if( hCurrentWnd
!= lpDragInfo
->hScope
)
1470 SendMessage( hCurrentWnd
, WM_DRAGSELECT
, 0,
1471 (LPARAM
)MAKELONG(LOWORD(spDragInfo
)+sizeof(DRAGINFO
),
1472 HIWORD(spDragInfo
)) );
1473 hCurrentWnd
= lpDragInfo
->hScope
;
1475 SendMessage( hCurrentWnd
, WM_DRAGSELECT
, 1, (LPARAM
)spDragInfo
);
1479 SendMessage( hCurrentWnd
, WM_DRAGMOVE
, 0, (LPARAM
)spDragInfo
);
1482 /* check if we're done */
1483 if( msg
.message
== WM_LBUTTONUP
|| msg
.message
== WM_NCLBUTTONUP
)
1492 SetCursor(hOldCursor
);
1494 DestroyCursor(hDragCursor
);
1497 if( hCurrentCursor
!= hBummer
)
1498 dwRet
= SendMessage( lpDragInfo
->hScope
, WM_DROPOBJECT
,
1499 (WPARAM
)hWnd
, (LPARAM
)spDragInfo
);
1500 GlobalFree(hDragInfo
);