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
)
309 WND
*wndPtr
, *parentWndPtr
;
310 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
311 CREATESTRUCT createStruct
;
313 XSetWindowAttributes win_attr
;
314 Atom XA_WM_DELETE_WINDOW
;
316 /* FIXME: windowName and className should be SEGPTRs */
318 dprintf_win( stddeb
, "CreateWindowEx: " );
319 if (HIWORD(windowName
))
320 dprintf_win( stddeb
, "'%s' ", (char *)PTR_SEG_TO_LIN(windowName
) );
322 dprintf_win( stddeb
, "%04x ", LOWORD(windowName
) );
323 if (HIWORD(className
))
324 dprintf_win( stddeb
, "'%s' ", (char *)PTR_SEG_TO_LIN(className
) );
326 dprintf_win( stddeb
, "%04x ", LOWORD(className
) );
328 dprintf_win(stddeb
, "%08lx %08lx %d,%d %dx%d "NPFMT
" "NPFMT
" "NPFMT
" %08lx\n",
329 exStyle
, style
, x
, y
, width
, height
,
330 parent
, menu
, instance
, (DWORD
)data
);
332 if (x
== CW_USEDEFAULT
) x
= y
= 0;
333 if (width
== CW_USEDEFAULT
)
339 /* Find the parent and class */
343 /* Make sure parent is valid */
344 if (!IsWindow( parent
)) {
345 dprintf_win(stddeb
,"CreateWindowEx: Parent "NPFMT
" is not a window\n", parent
);
351 if (style
& WS_CHILD
) {
352 dprintf_win(stddeb
,"CreateWindowEx: no parent\n");
353 return 0; /* WS_CHILD needs a parent */
357 if (!(class = CLASS_FindClassByName( className
, GetExePtr(instance
),
360 fprintf(stderr
,"CreateWindow BAD CLASSNAME " );
361 if (HIWORD(className
)) fprintf( stderr
, "'%s'\n",
362 (char *)PTR_SEG_TO_LIN(className
) );
363 else fprintf( stderr
, "%04x\n", LOWORD(className
) );
367 /* Correct the window style */
369 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
370 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
371 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
373 /* Create the window structure */
375 hwnd
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
377 dprintf_win(stddeb
,"CreateWindowEx: Out of memory\n");
381 /* Fill the structure */
383 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
384 wndPtr
->hwndNext
= 0;
385 wndPtr
->hwndChild
= 0;
387 wndPtr
->dwMagic
= WND_MAGIC
;
388 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
389 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : WIN_GetTopParent(parent
);
390 wndPtr
->hClass
= class;
391 wndPtr
->hInstance
= instance
;
392 wndPtr
->ptIconPos
.x
= -1;
393 wndPtr
->ptIconPos
.y
= -1;
394 wndPtr
->ptMaxPos
.x
= -1;
395 wndPtr
->ptMaxPos
.y
= -1;
396 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
397 wndPtr
->hrgnUpdate
= 0;
398 wndPtr
->hwndLastActive
= hwnd
;
399 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
400 wndPtr
->dwStyle
= style
& ~WS_VISIBLE
;
401 wndPtr
->dwExStyle
= exStyle
;
405 wndPtr
->hVScroll
= 0;
406 wndPtr
->hHScroll
= 0;
407 wndPtr
->hSysMenu
= 0;
410 if (classPtr
->wc
.cbWndExtra
)
411 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
412 classPtr
->cWindows
++;
414 /* Get class or window DC if needed */
416 if (classPtr
->wc
.style
& CS_OWNDC
)
417 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
418 else if (classPtr
->wc
.style
& CS_CLASSDC
)
419 wndPtr
->hdce
= classPtr
->hdce
;
423 /* Insert the window in the linked list */
425 WIN_LinkWindow( hwnd
, HWND_TOP
);
427 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
429 NC_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
431 if (maxSize
.x
< width
) width
= maxSize
.x
;
432 if (maxSize
.y
< height
) height
= maxSize
.y
;
433 if (width
<= 0) width
= 1;
434 if (height
<= 0) height
= 1;
436 wndPtr
->rectWindow
.left
= x
;
437 wndPtr
->rectWindow
.top
= y
;
438 wndPtr
->rectWindow
.right
= x
+ width
;
439 wndPtr
->rectWindow
.bottom
= y
+ height
;
440 wndPtr
->rectClient
= wndPtr
->rectWindow
;
441 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
443 /* Create the X window (only for top-level windows, and then only */
444 /* when there's no desktop window) */
446 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
448 if (Options
.managed
&& ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
449 (exStyle
& WS_EX_DLGMODALFRAME
)))
451 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
452 KeyReleaseMask
| PointerMotionMask
|
453 ButtonPressMask
| ButtonReleaseMask
|
454 FocusChangeMask
| StructureNotifyMask
;
455 win_attr
.override_redirect
= FALSE
;
456 wndPtr
->flags
|= WIN_MANAGED
;
460 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
461 KeyReleaseMask
| PointerMotionMask
|
462 ButtonPressMask
| ButtonReleaseMask
|
464 win_attr
.override_redirect
= TRUE
;
466 win_attr
.colormap
= COLOR_WinColormap
;
467 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
468 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
469 win_attr
.cursor
= CURSORICON_XCursor
;
470 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
471 width
, height
, 0, CopyFromParent
,
472 InputOutput
, CopyFromParent
,
473 CWEventMask
| CWOverrideRedirect
|
474 CWColormap
| CWCursor
| CWSaveUnder
|
475 CWBackingStore
, &win_attr
);
476 XStoreName( display
, wndPtr
->window
, PTR_SEG_TO_LIN(windowName
) );
477 XA_WM_DELETE_WINDOW
= XInternAtom( display
, "WM_DELETE_WINDOW",
479 XSetWMProtocols( display
, wndPtr
->window
, &XA_WM_DELETE_WINDOW
, 1 );
480 if (parent
) /* Get window owner */
482 Window win
= WIN_GetXWindow( parent
);
483 if (win
) XSetTransientForHint( display
, wndPtr
->window
, win
);
486 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
489 if ((style
& WS_CAPTION
) && !(style
& WS_CHILD
))
491 if (menu
) SetMenu(hwnd
, menu
);
492 else if (classPtr
->wc
.lpszMenuName
)
493 SetMenu( hwnd
, LoadMenu( instance
, classPtr
->wc
.lpszMenuName
) );
495 else wndPtr
->wIDmenu
= (UINT
)menu
;
497 GetSystemMenu( hwnd
, TRUE
); /* Create a copy of the system menu */
499 /* Send the WM_CREATE message */
501 createStruct
.lpCreateParams
= (LPSTR
)data
;
502 createStruct
.hInstance
= instance
;
503 createStruct
.hMenu
= menu
;
504 createStruct
.hwndParent
= parent
;
505 createStruct
.cx
= width
;
506 createStruct
.cy
= height
;
509 createStruct
.style
= style
;
510 createStruct
.lpszName
= windowName
;
511 createStruct
.lpszClass
= className
;
512 createStruct
.dwExStyle
= 0;
514 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, (LPARAM
)MAKE_SEGPTR(&createStruct
) );
517 dprintf_win(stddeb
,"CreateWindowEx: WM_NCCREATE return 0\n");
522 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
523 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
524 wmcreate
= SendMessage(hwnd
, WM_CREATE
, 0, (LPARAM
)MAKE_SEGPTR(&createStruct
));
529 /* Abort window creation */
530 dprintf_win(stddeb
,"CreateWindowEx: wmcreate==-1, aborting\n");
531 WIN_DestroyWindow( hwnd
);
535 WIN_SendParentNotify( hwnd
, WM_CREATE
, wndPtr
->wIDmenu
, (LONG
)hwnd
);
537 /* Show the window, maximizing or minimizing if needed */
539 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
541 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
542 WINPOS_FindIconPos( hwnd
);
543 SetWindowPos( hwnd
, 0, wndPtr
->ptIconPos
.x
, wndPtr
->ptIconPos
.y
,
544 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
,
546 (style
& WS_VISIBLE
) ? SWP_SHOWWINDOW
: 0 );
548 else if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
550 SetWindowPos( hwnd
, 0, maxPos
.x
, maxPos
.y
, maxSize
.x
, maxSize
.y
,
552 (style
& WS_VISIBLE
) ? SWP_SHOWWINDOW
: 0 );
554 else if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
556 dprintf_win(stddeb
, "CreateWindowEx: return "NPFMT
" \n", hwnd
);
561 /***********************************************************************
562 * DestroyWindow (USER.53)
564 BOOL
DestroyWindow( HWND hwnd
)
569 dprintf_win(stddeb
, "DestroyWindow ("NPFMT
")\n", hwnd
);
573 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
574 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
575 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
577 /* Hide the window */
579 if (wndPtr
->dwStyle
& WS_VISIBLE
)
580 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
581 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
582 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
584 WIN_SendParentNotify( hwnd
, WM_DESTROY
, wndPtr
->wIDmenu
, (LONG
)hwnd
);
586 /* Recursively destroy owned windows */
590 HWND hwndSibling
= GetWindow( hwnd
, GW_HWNDFIRST
);
593 WND
*siblingPtr
= WIN_FindWndPtr( hwndSibling
);
594 if (siblingPtr
->hwndOwner
== hwnd
) break;
595 hwndSibling
= siblingPtr
->hwndNext
;
597 if (hwndSibling
) DestroyWindow( hwndSibling
);
601 /* Send destroy messages and destroy children */
603 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
604 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
605 DestroyWindow( wndPtr
->hwndChild
);
606 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
608 /* Destroy the window */
610 WIN_DestroyWindow( hwnd
);
615 /***********************************************************************
616 * CloseWindow (USER.43)
618 BOOL
CloseWindow(HWND hWnd
)
620 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
621 if (wndPtr
->dwStyle
& WS_CHILD
) return TRUE
;
622 ShowWindow(hWnd
, SW_MINIMIZE
);
627 /***********************************************************************
630 BOOL
OpenIcon(HWND hWnd
)
632 if (!IsIconic(hWnd
)) return FALSE
;
633 ShowWindow(hWnd
, SW_SHOWNORMAL
);
638 /***********************************************************************
639 * FindWindow (USER.50)
641 HWND
FindWindow( SEGPTR ClassMatch
, LPSTR TitleMatch
)
649 hclass
= CLASS_FindClassByName( ClassMatch
, (HINSTANCE
)0xffff,
651 if (!hclass
) return 0;
655 hwnd
= GetTopWindow( hwndDesktop
);
658 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
659 if (!hclass
|| (wndPtr
->hClass
== hclass
))
661 /* Found matching class */
662 if (!TitleMatch
) return hwnd
;
665 char *textPtr
= (char *) USER_HEAP_LIN_ADDR( wndPtr
->hText
);
666 if (!strcmp( textPtr
, TitleMatch
)) return hwnd
;
669 hwnd
= wndPtr
->hwndNext
;
675 /**********************************************************************
676 * GetDesktopWindow (USER.286)
678 HWND
GetDesktopWindow(void)
684 /**********************************************************************
685 * GetDesktopHwnd (USER.278)
687 * Exactly the same thing as GetDesktopWindow(), but not documented.
688 * Don't ask me why...
690 HWND
GetDesktopHwnd(void)
696 /*******************************************************************
697 * EnableWindow (USER.34)
699 BOOL
EnableWindow( HWND hwnd
, BOOL enable
)
703 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
704 if (enable
&& (wndPtr
->dwStyle
& WS_DISABLED
))
707 wndPtr
->dwStyle
&= ~WS_DISABLED
;
708 SendMessage( hwnd
, WM_ENABLE
, TRUE
, 0 );
711 else if (!enable
&& !(wndPtr
->dwStyle
& WS_DISABLED
))
714 wndPtr
->dwStyle
|= WS_DISABLED
;
715 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus() ))
716 SetFocus( 0 ); /* A disabled window can't have the focus */
717 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
718 ReleaseCapture(); /* A disabled window can't capture the mouse */
719 SendMessage( hwnd
, WM_ENABLE
, FALSE
, 0 );
722 return ((wndPtr
->dwStyle
& WS_DISABLED
) != 0);
726 /***********************************************************************
727 * IsWindowEnabled (USER.35)
729 BOOL
IsWindowEnabled(HWND hWnd
)
733 if (!(wndPtr
= WIN_FindWndPtr(hWnd
))) return FALSE
;
734 return !(wndPtr
->dwStyle
& WS_DISABLED
);
738 /**********************************************************************
739 * GetWindowWord (USER.133)
741 WORD
GetWindowWord( HWND hwnd
, short offset
)
743 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
744 if (!wndPtr
) return 0;
745 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
748 case GWW_ID
: return wndPtr
->wIDmenu
;
752 fprintf(stderr
,"GetWindowWord called with offset %d.\n",offset
);
755 case GWW_HWNDPARENT
: return (WORD
)wndPtr
->hwndParent
;
756 case GWW_HINSTANCE
: return (WORD
)wndPtr
->hInstance
;
763 /**********************************************************************
764 * WIN_GetWindowInstance
766 HINSTANCE
WIN_GetWindowInstance(HWND hwnd
)
768 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
769 if (!wndPtr
) return (HINSTANCE
)0;
770 return wndPtr
->hInstance
;
774 /**********************************************************************
775 * SetWindowWord (USER.134)
777 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
780 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
781 if (!wndPtr
) return 0;
782 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
788 fprintf(stderr
,"SetWindowWord called with offset %d.\n",offset
);
791 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
; break;
792 case GWW_HINSTANCE
: ptr
= (WORD
*)&wndPtr
->hInstance
; break;
802 /**********************************************************************
803 * GetWindowLong (USER.135)
805 LONG
GetWindowLong( HWND hwnd
, short offset
)
807 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
808 if (!wndPtr
) return 0;
809 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
812 case GWL_STYLE
: return wndPtr
->dwStyle
;
813 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
814 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
816 case GWW_HWNDPARENT
: return (LONG
)wndPtr
->hwndParent
;
817 case GWW_HINSTANCE
: return (LONG
)wndPtr
->hInstance
;
824 /**********************************************************************
825 * SetWindowLong (USER.136)
827 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
830 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
831 if (!wndPtr
) return 0;
832 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
835 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
; break;
836 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
; break;
837 case GWL_WNDPROC
: ptr
= (LONG
*)&wndPtr
->lpfnWndProc
; break;
846 /*******************************************************************
847 * GetWindowText (USER.36)
849 int WIN16_GetWindowText( HWND hwnd
, SEGPTR lpString
, int nMaxCount
)
851 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
855 int GetWindowText( HWND hwnd
, LPSTR lpString
, int nMaxCount
)
860 /* We have to allocate a buffer on the USER heap */
861 /* to be able to pass its address to 16-bit code */
862 if (!(handle
= USER_HEAP_ALLOC( nMaxCount
))) return 0;
863 len
= (int)SendMessage( hwnd
, WM_GETTEXT
, (WPARAM
)nMaxCount
,
864 (LPARAM
)USER_HEAP_SEG_ADDR(handle
) );
865 strncpy( lpString
, USER_HEAP_LIN_ADDR(handle
), nMaxCount
);
866 USER_HEAP_FREE( handle
);
871 /*******************************************************************
872 * SetWindowText (USER.37)
874 void WIN16_SetWindowText( HWND hwnd
, SEGPTR lpString
)
876 SendMessage( hwnd
, WM_SETTEXT
, 0, (DWORD
)lpString
);
879 void SetWindowText( HWND hwnd
, LPCSTR lpString
)
883 /* We have to allocate a buffer on the USER heap */
884 /* to be able to pass its address to 16-bit code */
885 if (!(handle
= USER_HEAP_ALLOC( strlen(lpString
)+1 ))) return;
886 strcpy( USER_HEAP_LIN_ADDR(handle
), lpString
);
887 SendMessage( hwnd
, WM_SETTEXT
, 0, (LPARAM
)USER_HEAP_SEG_ADDR(handle
) );
888 USER_HEAP_FREE( handle
);
892 /*******************************************************************
893 * GetWindowTextLength (USER.38)
895 int GetWindowTextLength(HWND hwnd
)
897 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
901 /*******************************************************************
904 BOOL
IsWindow( HWND hwnd
)
906 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
907 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
911 /*****************************************************************
912 * GetParent (USER.46)
914 HWND
GetParent(HWND hwnd
)
916 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
917 if (!wndPtr
) return 0;
918 return (wndPtr
->dwStyle
& WS_CHILD
) ?
919 wndPtr
->hwndParent
: wndPtr
->hwndOwner
;
923 /*****************************************************************
926 * Get the top-level parent for a child window.
928 HWND
WIN_GetTopParent( HWND hwnd
)
932 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
933 if (wndPtr
->dwStyle
& WS_CHILD
) hwnd
= wndPtr
->hwndParent
;
940 /*****************************************************************
941 * SetParent (USER.233)
943 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
947 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
948 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
950 temp
= wndPtr
->hwndParent
;
952 WIN_UnlinkWindow(hwndChild
);
954 wndPtr
->hwndParent
= hwndNewParent
;
956 wndPtr
->hwndParent
= GetDesktopWindow();
957 WIN_LinkWindow(hwndChild
, HWND_BOTTOM
);
959 if (IsWindowVisible(hwndChild
)) UpdateWindow(hwndChild
);
966 /*******************************************************************
969 BOOL
IsChild( HWND parent
, HWND child
)
971 WND
* wndPtr
= WIN_FindWndPtr( child
);
972 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
974 if (wndPtr
->hwndParent
== parent
) return TRUE
;
975 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
981 /***********************************************************************
982 * IsWindowVisible (USER.49)
984 BOOL
IsWindowVisible( HWND hwnd
)
986 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
987 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
989 if (!(wndPtr
->dwStyle
& WS_VISIBLE
)) return FALSE
;
990 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
992 return (wndPtr
&& (wndPtr
->dwStyle
& WS_VISIBLE
));
997 /*******************************************************************
998 * GetTopWindow (USER.229)
1000 HWND
GetTopWindow( HWND hwnd
)
1002 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1003 if (wndPtr
) return wndPtr
->hwndChild
;
1008 /*******************************************************************
1009 * GetWindow (USER.262)
1011 HWND
GetWindow( HWND hwnd
, WORD rel
)
1013 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1014 if (!wndPtr
) return 0;
1018 if (wndPtr
->hwndParent
)
1020 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
1021 return parentPtr
->hwndChild
;
1026 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
1027 while (wndPtr
->hwndNext
)
1029 hwnd
= wndPtr
->hwndNext
;
1030 wndPtr
= WIN_FindWndPtr( hwnd
);
1035 return wndPtr
->hwndNext
;
1041 if (wndPtr
->hwndParent
)
1043 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
1044 hwndPrev
= parentPtr
->hwndChild
;
1046 else return 0; /* Desktop window */
1047 if (hwndPrev
== hwnd
) return 0;
1050 wndPtr
= WIN_FindWndPtr( hwndPrev
);
1051 if (wndPtr
->hwndNext
== hwnd
) break;
1052 hwndPrev
= wndPtr
->hwndNext
;
1058 return wndPtr
->hwndOwner
;
1061 return wndPtr
->hwndChild
;
1067 /*******************************************************************
1068 * GetNextWindow (USER.230)
1070 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
1072 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
1073 return GetWindow( hwnd
, flag
);
1076 /*******************************************************************
1077 * ShowOwnedPopups (USER.265)
1079 void ShowOwnedPopups( HWND owner
, BOOL fShow
)
1081 HWND hwnd
= GetWindow( hwndDesktop
, GW_CHILD
);
1084 WND
*wnd
= WIN_FindWndPtr(hwnd
);
1085 if (wnd
->hwndOwner
== owner
&& (wnd
->dwStyle
& WS_POPUP
))
1086 ShowWindow( hwnd
, fShow
? SW_SHOW
: SW_HIDE
);
1087 hwnd
= wnd
->hwndNext
;
1092 /*******************************************************************
1093 * GetLastActivePopup (USER.287)
1095 HWND
GetLastActivePopup(HWND hwnd
)
1098 wndPtr
= WIN_FindWndPtr(hwnd
);
1099 if (wndPtr
== NULL
) return hwnd
;
1100 return wndPtr
->hwndLastActive
;
1104 /*******************************************************************
1105 * EnumWindows (USER.54)
1107 BOOL
EnumWindows( WNDENUMPROC lpEnumFunc
, LPARAM lParam
)
1114 /* We have to build a list of all windows first, to avoid */
1115 /* unpleasant side-effects, for instance if the callback */
1116 /* function changes the Z-order of the windows. */
1118 /* First count the windows */
1121 for (hwnd
= GetTopWindow(hwndDesktop
); hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1123 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1126 if (!count
) return TRUE
;
1128 /* Now build the list of all windows */
1130 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1131 for (hwnd
= GetTopWindow(hwndDesktop
), pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1133 wndPtr
= WIN_FindWndPtr( hwnd
);
1137 /* Now call the callback function for every window */
1139 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1141 /* Make sure that window still exists */
1142 if (!IsWindow(*pWnd
)) continue;
1143 if (!CallEnumWindowsProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1150 /**********************************************************************
1151 * EnumTaskWindows (USER.225)
1153 BOOL
EnumTaskWindows( HTASK hTask
, WNDENUMPROC lpEnumFunc
, LPARAM lParam
)
1158 HANDLE hQueue
= GetTaskQueue( hTask
);
1161 /* This function is the same as EnumWindows(), */
1162 /* except for an added check on the window queue. */
1164 /* First count the windows */
1167 for (hwnd
= GetTopWindow(hwndDesktop
); hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1169 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1170 if (wndPtr
->hmemTaskQ
== hQueue
) count
++;
1172 if (!count
) return TRUE
;
1174 /* Now build the list of all windows */
1176 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1177 for (hwnd
= GetTopWindow(hwndDesktop
), pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1179 wndPtr
= WIN_FindWndPtr( hwnd
);
1180 if (wndPtr
->hmemTaskQ
== hQueue
) *pWnd
++ = hwnd
;
1183 /* Now call the callback function for every window */
1185 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1187 /* Make sure that window still exists */
1188 if (!IsWindow(*pWnd
)) continue;
1189 if (!CallEnumTaskWndProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1196 /*******************************************************************
1199 * o hwnd is the first child to use, loop until all next windows
1204 * o call ourselves with the next child window
1207 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1213 if (!(wndPtr
=WIN_FindWndPtr(hwnd
))) return 0;
1214 if (!CallEnumWindowsProc( wndenumprc
, hwnd
, lParam
)) return 0;
1215 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) return 0;
1216 hwnd
=wndPtr
->hwndNext
;
1221 /*******************************************************************
1222 * EnumChildWindows (USER.55)
1224 * o gets the first child of hwnd
1226 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1228 BOOL
EnumChildWindows(HWND hwnd
, WNDENUMPROC wndenumprc
, LPARAM lParam
)
1232 dprintf_enum(stddeb
,"EnumChildWindows\n");
1234 if (hwnd
== 0) return 0;
1235 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1236 hwnd
= wndPtr
->hwndChild
;
1237 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1241 /*******************************************************************
1242 * AnyPopup [USER.52]
1246 WND
*wndPtr
= WIN_FindWndPtr(hwndDesktop
);
1247 HWND hwnd
= wndPtr
->hwndChild
;
1249 for( ; hwnd
; hwnd
= wndPtr
->hwndNext
)
1251 wndPtr
= WIN_FindWndPtr(hwnd
);
1252 if(wndPtr
->hwndOwner
)
1253 if(wndPtr
->dwStyle
& WS_VISIBLE
)
1259 /*******************************************************************
1260 * FlashWindow [USER.105]
1262 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1264 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
1266 dprintf_win(stddeb
,"FlashWindow: "NPFMT
"\n", hWnd
);
1268 if (!wndPtr
) return FALSE
;
1270 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
1272 if (bInvert
&& !(wndPtr
->flags
& WIN_NCACTIVATED
))
1274 HDC hDC
= GetDC(hWnd
);
1276 if (!SendMessage( hWnd
, WM_ERASEBKGND
, (WPARAM
)hDC
, (LPARAM
)0 ))
1277 wndPtr
->flags
|= WIN_NEEDS_ERASEBKGND
;
1279 ReleaseDC( hWnd
, hDC
);
1280 wndPtr
->flags
|= WIN_NCACTIVATED
;
1284 RedrawWindow( hWnd
, 0, 0, RDW_INVALIDATE
| RDW_ERASE
|
1285 RDW_UPDATENOW
| RDW_FRAME
);
1286 wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1293 if (bInvert
) wparam
= !(wndPtr
->flags
& WIN_NCACTIVATED
);
1294 else wparam
= (hWnd
== GetActiveWindow());
1296 SendMessage( hWnd
, WM_NCACTIVATE
, wparam
, (LPARAM
)0 );
1302 /*******************************************************************
1303 * SetSysModalWindow [USER.188]
1305 HWND
SetSysModalWindow(HWND hWnd
)
1307 HWND hWndOldModal
= hwndSysModal
;
1308 hwndSysModal
= hWnd
;
1309 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow("NPFMT
") !\n", hWnd
);
1310 return hWndOldModal
;
1314 /*******************************************************************
1315 * GetSysModalWindow [USER.189]
1317 HWND
GetSysModalWindow(void)
1319 return hwndSysModal
;
1322 /*******************************************************************
1325 * recursively find a child that contains spDragInfo->pt point
1326 * and send WM_QUERYDROPOBJECT
1328 BOOL
DRAG_QueryUpdate( HWND hQueryWnd
, SEGPTR spDragInfo
)
1331 BOOL wParam
,bResult
= 0;
1333 LPDRAGINFO ptrDragInfo
= (LPDRAGINFO
) PTR_SEG_TO_LIN(spDragInfo
);
1334 WND
*ptrQueryWnd
= WIN_FindWndPtr(hQueryWnd
),*ptrWnd
;
1335 RECT tempRect
; /* this sucks */
1337 if( !ptrQueryWnd
|| !ptrDragInfo
) return 0;
1339 pt
= ptrDragInfo
->pt
;
1341 GetWindowRect(hQueryWnd
,&tempRect
);
1343 if( !PtInRect(&tempRect
,pt
) ||
1344 (ptrQueryWnd
->dwStyle
& WS_DISABLED
) )
1347 if( !(ptrQueryWnd
->dwStyle
& WS_MINIMIZE
) )
1349 tempRect
= ptrQueryWnd
->rectClient
;
1350 if(ptrQueryWnd
->dwStyle
& WS_CHILD
)
1351 MapWindowPoints(ptrQueryWnd
->hwndParent
,0,(LPPOINT
)&tempRect
,2);
1353 if( PtInRect(&tempRect
,pt
) )
1356 ptrWnd
= WIN_FindWndPtr(hWnd
= ptrQueryWnd
->hwndChild
);
1358 for( ;ptrWnd
;ptrWnd
= WIN_FindWndPtr(hWnd
= ptrWnd
->hwndNext
) )
1359 if( ptrWnd
->dwStyle
& WS_VISIBLE
)
1361 GetWindowRect(hWnd
,&tempRect
);
1363 if( PtInRect(&tempRect
,pt
) )
1368 dprintf_msg(stddeb
,"DragQueryUpdate: hwnd = "NPFMT
", %i %i - %i %i\n",hWnd
,
1369 (int)ptrWnd
->rectWindow
.left
,(int)ptrWnd
->rectWindow
.top
,
1370 (int)ptrWnd
->rectWindow
.right
,(int)ptrWnd
->rectWindow
.bottom
);
1372 dprintf_msg(stddeb
,"DragQueryUpdate: hwnd = "NPFMT
"\n",hWnd
);
1375 if( !(ptrWnd
->dwStyle
& WS_DISABLED
) )
1376 bResult
= DRAG_QueryUpdate(hWnd
, spDragInfo
);
1378 if(bResult
) return bResult
;
1384 ScreenToClient(hQueryWnd
,&ptrDragInfo
->pt
);
1386 ptrDragInfo
->hScope
= hQueryWnd
;
1388 bResult
= SendMessage( hQueryWnd
,WM_QUERYDROPOBJECT
,
1389 (WPARAM
)wParam
,(LPARAM
) spDragInfo
);
1391 ptrDragInfo
->pt
= pt
;
1396 /*******************************************************************
1397 * DragDetect ( USER.465 )
1400 BOOL
DragDetect(HWND hWnd
, POINT pt
)
1405 rect
.left
= pt
.x
- wDragWidth
;
1406 rect
.right
= pt
.x
+ wDragWidth
;
1408 rect
.top
= pt
.y
- wDragHeight
;
1409 rect
.bottom
= pt
.y
+ wDragHeight
;
1415 while(PeekMessage(&msg
,0 ,WM_MOUSEFIRST
,WM_MOUSELAST
,PM_REMOVE
))
1417 if( msg
.message
== WM_LBUTTONUP
)
1422 if( msg
.message
== WM_MOUSEMOVE
)
1424 POINT pt
= { LOWORD(msg
.lParam
), HIWORD(msg
.lParam
) };
1425 if( !PtInRect( &rect
, pt
) )
1438 /******************************************************************************
1439 * DragObject ( USER.464 )
1442 DWORD
DragObject(HWND hwndScope
, HWND hWnd
, WORD wObj
, HANDLE hOfStruct
,
1443 WORD szList
, HCURSOR hCursor
)
1446 LPDRAGINFO lpDragInfo
;
1448 HCURSOR hDragCursor
=0, hOldCursor
=0, hBummer
=0;
1449 HANDLE hDragInfo
= GlobalAlloc( GMEM_SHARE
| GMEM_ZEROINIT
, 2*sizeof(DRAGINFO
));
1450 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
1453 HCURSOR hCurrentCursor
= 0;
1454 HWND hCurrentWnd
= 0;
1457 lpDragInfo
= (LPDRAGINFO
) GlobalLock(hDragInfo
);
1458 spDragInfo
= (SEGPTR
) WIN16_GlobalLock(hDragInfo
);
1460 if( !lpDragInfo
|| !spDragInfo
) return 0L;
1462 hBummer
= LoadCursor(0,IDC_BUMMER
);
1464 if( !hBummer
|| !wndPtr
)
1466 GlobalFree(hDragInfo
);
1472 if( !(hDragCursor
= CURSORICON_IconToCursor(hCursor
)) )
1474 GlobalFree(hDragInfo
);
1478 if( hDragCursor
== hCursor
) hDragCursor
= 0;
1479 else hCursor
= hDragCursor
;
1481 hOldCursor
= SetCursor(hDragCursor
);
1484 lpDragInfo
->hWnd
= hWnd
;
1485 lpDragInfo
->hScope
= 0;
1486 lpDragInfo
->wFlags
= wObj
;
1487 lpDragInfo
->hList
= szList
; /* near pointer! */
1488 lpDragInfo
->hOfStruct
= hOfStruct
;
1498 if( !PeekMessage(&msg
,0,WM_MOUSEFIRST
,WM_MOUSELAST
,PM_REMOVE
) )
1501 *(lpDragInfo
+1) = *lpDragInfo
;
1503 lpDragInfo
->pt
= msg
.pt
;
1505 /* update DRAGINFO struct */
1506 dprintf_msg(stddeb
,"drag: lpDI->hScope = "NPFMT
"\n",lpDragInfo
->hScope
);
1508 if( (btemp
= (WORD
)DRAG_QueryUpdate(hwndScope
, spDragInfo
)) > 0 )
1509 hCurrentCursor
= hCursor
;
1512 hCurrentCursor
= hBummer
;
1513 lpDragInfo
->hScope
= 0;
1515 if( hCurrentCursor
)
1516 SetCursor(hCurrentCursor
);
1518 dprintf_msg(stddeb
,"drag: got %04x\n",btemp
);
1520 /* send WM_DRAGLOOP */
1521 SendMessage( hWnd
, WM_DRAGLOOP
, (WPARAM
)(hCurrentCursor
!= hBummer
) ,
1522 (LPARAM
) spDragInfo
);
1523 /* send WM_DRAGSELECT or WM_DRAGMOVE */
1524 if( hCurrentWnd
!= lpDragInfo
->hScope
)
1527 SendMessage( hCurrentWnd
, WM_DRAGSELECT
, 0,
1528 (LPARAM
)MAKELONG(LOWORD(spDragInfo
)+sizeof(DRAGINFO
),
1529 HIWORD(spDragInfo
)) );
1530 hCurrentWnd
= lpDragInfo
->hScope
;
1532 SendMessage( hCurrentWnd
, WM_DRAGSELECT
, 1, (LPARAM
)spDragInfo
);
1536 SendMessage( hCurrentWnd
, WM_DRAGMOVE
, 0, (LPARAM
)spDragInfo
);
1539 /* check if we're done */
1540 if( msg
.message
== WM_LBUTTONUP
|| msg
.message
== WM_NCLBUTTONUP
)
1549 SetCursor(hOldCursor
);
1551 DestroyCursor(hDragCursor
);
1554 if( hCurrentCursor
!= hBummer
)
1555 dwRet
= SendMessage( lpDragInfo
->hScope
, WM_DROPOBJECT
,
1556 (WPARAM
)hWnd
, (LPARAM
)spDragInfo
);
1557 GlobalFree(hDragInfo
);