msi/tests: Delete the temp .msi file in all failure cases.
[wine.git] / dlls / user32 / win.c
blobf241d1371f327dcd497ff64588cdf6378b3e02ef
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "user_private.h"
22 #include "controls.h"
23 #include "winver.h"
24 #include "wine/server.h"
25 #include "wine/asm.h"
26 #include "wine/exception.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(win);
32 /*******************************************************************
33 * list_window_children
35 * Build an array of the children of a given window. The array must be
36 * freed with HeapFree. Returns NULL when no windows are found.
38 static HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *class, DWORD tid )
40 HWND *list;
41 int i, size = 128;
42 ATOM atom = class ? get_int_atom_value( class ) : 0;
44 /* empty class is not the same as NULL class */
45 if (!atom && class && !class->Length) return NULL;
47 for (;;)
49 int count = 0;
51 if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) break;
53 SERVER_START_REQ( get_window_children )
55 req->desktop = wine_server_obj_handle( desktop );
56 req->parent = wine_server_user_handle( hwnd );
57 req->tid = tid;
58 req->atom = atom;
59 if (!atom && class) wine_server_add_data( req, class->Buffer, class->Length );
60 wine_server_set_reply( req, list, (size-1) * sizeof(user_handle_t) );
61 if (!wine_server_call( req )) count = reply->count;
63 SERVER_END_REQ;
64 if (count && count < size)
66 /* start from the end since HWND is potentially larger than user_handle_t */
67 for (i = count - 1; i >= 0; i--)
68 list[i] = wine_server_ptr_handle( ((user_handle_t *)list)[i] );
69 list[count] = 0;
70 return list;
72 HeapFree( GetProcessHeap(), 0, list );
73 if (!count) break;
74 size = count + 1; /* restart with a large enough buffer */
76 return NULL;
80 /*******************************************************************
81 * is_desktop_window
83 * Check if window is the desktop or the HWND_MESSAGE top parent.
85 BOOL is_desktop_window( HWND hwnd )
87 struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
89 if (!hwnd) return FALSE;
90 if (hwnd == UlongToHandle( thread_info->top_window )) return TRUE;
91 if (hwnd == UlongToHandle( thread_info->msg_window )) return TRUE;
93 if (!HIWORD(hwnd) || HIWORD(hwnd) == 0xffff)
95 if (LOWORD(thread_info->top_window) == LOWORD(hwnd)) return TRUE;
96 if (LOWORD(thread_info->msg_window) == LOWORD(hwnd)) return TRUE;
98 return FALSE;
102 /* check if hwnd is a broadcast magic handle */
103 static inline BOOL is_broadcast( HWND hwnd )
105 return hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST;
109 /***********************************************************************
110 * WIN_IsCurrentProcess
112 * Check whether a given window belongs to the current process (and return the full handle).
114 HWND WIN_IsCurrentProcess( HWND hwnd )
116 return UlongToHandle( NtUserCallHwnd( hwnd, NtUserIsCurrentProcessWindow ));
120 /***********************************************************************
121 * WIN_IsCurrentThread
123 * Check whether a given window belongs to the current thread (and return the full handle).
125 HWND WIN_IsCurrentThread( HWND hwnd )
127 return UlongToHandle( NtUserCallHwnd( hwnd, NtUserIsCurrentThreadWindow ));
131 /***********************************************************************
132 * WIN_GetFullHandle
134 * Convert a possibly truncated window handle to a full 32-bit handle.
136 HWND WIN_GetFullHandle( HWND hwnd )
138 return UlongToHandle( NtUserCallHwnd( hwnd, NtUserGetFullWindowHandle ));
142 /***********************************************************************
143 * WIN_SetStyle
145 * Change the style of a window.
147 ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
149 /* FIXME: Use SetWindowLong or move callers to win32u instead.
150 * We use STYLESTRUCT to pass params, but meaning of its field does not match our usage. */
151 STYLESTRUCT style = { .styleNew = set_bits, .styleOld = clear_bits };
152 return NtUserCallHwndParam( hwnd, (UINT_PTR)&style, NtUserSetWindowStyle );
156 /***********************************************************************
157 * dump_window_styles
159 static void dump_window_styles( DWORD style, DWORD exstyle )
161 TRACE( "style:" );
162 if(style & WS_POPUP) TRACE(" WS_POPUP");
163 if(style & WS_CHILD) TRACE(" WS_CHILD");
164 if(style & WS_MINIMIZE) TRACE(" WS_MINIMIZE");
165 if(style & WS_VISIBLE) TRACE(" WS_VISIBLE");
166 if(style & WS_DISABLED) TRACE(" WS_DISABLED");
167 if(style & WS_CLIPSIBLINGS) TRACE(" WS_CLIPSIBLINGS");
168 if(style & WS_CLIPCHILDREN) TRACE(" WS_CLIPCHILDREN");
169 if(style & WS_MAXIMIZE) TRACE(" WS_MAXIMIZE");
170 if((style & WS_CAPTION) == WS_CAPTION) TRACE(" WS_CAPTION");
171 else
173 if(style & WS_BORDER) TRACE(" WS_BORDER");
174 if(style & WS_DLGFRAME) TRACE(" WS_DLGFRAME");
176 if(style & WS_VSCROLL) TRACE(" WS_VSCROLL");
177 if(style & WS_HSCROLL) TRACE(" WS_HSCROLL");
178 if(style & WS_SYSMENU) TRACE(" WS_SYSMENU");
179 if(style & WS_THICKFRAME) TRACE(" WS_THICKFRAME");
180 if (style & WS_CHILD)
182 if(style & WS_GROUP) TRACE(" WS_GROUP");
183 if(style & WS_TABSTOP) TRACE(" WS_TABSTOP");
185 else
187 if(style & WS_MINIMIZEBOX) TRACE(" WS_MINIMIZEBOX");
188 if(style & WS_MAXIMIZEBOX) TRACE(" WS_MAXIMIZEBOX");
191 /* FIXME: Add dumping of BS_/ES_/SBS_/LBS_/CBS_/DS_/etc. styles */
192 #define DUMPED_STYLES \
193 ((DWORD)(WS_POPUP | \
194 WS_CHILD | \
195 WS_MINIMIZE | \
196 WS_VISIBLE | \
197 WS_DISABLED | \
198 WS_CLIPSIBLINGS | \
199 WS_CLIPCHILDREN | \
200 WS_MAXIMIZE | \
201 WS_BORDER | \
202 WS_DLGFRAME | \
203 WS_VSCROLL | \
204 WS_HSCROLL | \
205 WS_SYSMENU | \
206 WS_THICKFRAME | \
207 WS_GROUP | \
208 WS_TABSTOP | \
209 WS_MINIMIZEBOX | \
210 WS_MAXIMIZEBOX))
212 if(style & ~DUMPED_STYLES) TRACE(" %08lx", style & ~DUMPED_STYLES);
213 TRACE("\n");
214 #undef DUMPED_STYLES
216 TRACE( "exstyle:" );
217 if(exstyle & WS_EX_DLGMODALFRAME) TRACE(" WS_EX_DLGMODALFRAME");
218 if(exstyle & WS_EX_DRAGDETECT) TRACE(" WS_EX_DRAGDETECT");
219 if(exstyle & WS_EX_NOPARENTNOTIFY) TRACE(" WS_EX_NOPARENTNOTIFY");
220 if(exstyle & WS_EX_TOPMOST) TRACE(" WS_EX_TOPMOST");
221 if(exstyle & WS_EX_ACCEPTFILES) TRACE(" WS_EX_ACCEPTFILES");
222 if(exstyle & WS_EX_TRANSPARENT) TRACE(" WS_EX_TRANSPARENT");
223 if(exstyle & WS_EX_MDICHILD) TRACE(" WS_EX_MDICHILD");
224 if(exstyle & WS_EX_TOOLWINDOW) TRACE(" WS_EX_TOOLWINDOW");
225 if(exstyle & WS_EX_WINDOWEDGE) TRACE(" WS_EX_WINDOWEDGE");
226 if(exstyle & WS_EX_CLIENTEDGE) TRACE(" WS_EX_CLIENTEDGE");
227 if(exstyle & WS_EX_CONTEXTHELP) TRACE(" WS_EX_CONTEXTHELP");
228 if(exstyle & WS_EX_RIGHT) TRACE(" WS_EX_RIGHT");
229 if(exstyle & WS_EX_RTLREADING) TRACE(" WS_EX_RTLREADING");
230 if(exstyle & WS_EX_LEFTSCROLLBAR) TRACE(" WS_EX_LEFTSCROLLBAR");
231 if(exstyle & WS_EX_CONTROLPARENT) TRACE(" WS_EX_CONTROLPARENT");
232 if(exstyle & WS_EX_STATICEDGE) TRACE(" WS_EX_STATICEDGE");
233 if(exstyle & WS_EX_APPWINDOW) TRACE(" WS_EX_APPWINDOW");
234 if(exstyle & WS_EX_LAYERED) TRACE(" WS_EX_LAYERED");
235 if(exstyle & WS_EX_NOINHERITLAYOUT) TRACE(" WS_EX_NOINHERITLAYOUT");
236 if(exstyle & WS_EX_LAYOUTRTL) TRACE(" WS_EX_LAYOUTRTL");
237 if(exstyle & WS_EX_COMPOSITED) TRACE(" WS_EX_COMPOSITED");
238 if(exstyle & WS_EX_NOACTIVATE) TRACE(" WS_EX_NOACTIVATE");
240 #define DUMPED_EX_STYLES \
241 ((DWORD)(WS_EX_DLGMODALFRAME | \
242 WS_EX_DRAGDETECT | \
243 WS_EX_NOPARENTNOTIFY | \
244 WS_EX_TOPMOST | \
245 WS_EX_ACCEPTFILES | \
246 WS_EX_TRANSPARENT | \
247 WS_EX_MDICHILD | \
248 WS_EX_TOOLWINDOW | \
249 WS_EX_WINDOWEDGE | \
250 WS_EX_CLIENTEDGE | \
251 WS_EX_CONTEXTHELP | \
252 WS_EX_RIGHT | \
253 WS_EX_RTLREADING | \
254 WS_EX_LEFTSCROLLBAR | \
255 WS_EX_CONTROLPARENT | \
256 WS_EX_STATICEDGE | \
257 WS_EX_APPWINDOW | \
258 WS_EX_LAYERED | \
259 WS_EX_NOINHERITLAYOUT | \
260 WS_EX_LAYOUTRTL | \
261 WS_EX_COMPOSITED |\
262 WS_EX_NOACTIVATE))
264 if(exstyle & ~DUMPED_EX_STYLES) TRACE(" %08lx", exstyle & ~DUMPED_EX_STYLES);
265 TRACE("\n");
266 #undef DUMPED_EX_STYLES
269 static BOOL is_default_coord( int x )
271 return x == CW_USEDEFAULT || x == 0x8000;
274 /***********************************************************************
275 * WIN_CreateWindowEx
277 * Implementation of CreateWindowEx().
279 HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode )
281 UNICODE_STRING class, window_name = {0};
282 HWND hwnd, top_child = 0;
283 MDICREATESTRUCTW mdi_cs;
284 WNDCLASSEXW info;
285 WCHAR name_buf[8];
286 HMENU menu;
288 if (!get_class_info( module, className, &info, &class, FALSE )) return FALSE;
290 TRACE("%s %s%s%s ex=%08lx style=%08lx %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
291 unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName),
292 debugstr_w(className), class.Buffer != className ? "->" : "",
293 class.Buffer != className ? debugstr_wn(class.Buffer, class.Length / sizeof(WCHAR)) : "",
294 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
295 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
296 if(TRACE_ON(win)) dump_window_styles( cs->style, cs->dwExStyle );
298 /* Fix the styles for MDI children */
299 if (cs->dwExStyle & WS_EX_MDICHILD)
301 POINT pos[2];
302 UINT id = 0;
304 if (!NtUserGetMDIClientInfo( cs->hwndParent ))
306 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", cs->hwndParent);
307 return 0;
310 /* cs->lpCreateParams of WM_[NC]CREATE is different for MDI children.
311 * MDICREATESTRUCT members have the originally passed values.
313 * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
314 * have the same layout.
316 mdi_cs.szClass = cs->lpszClass;
317 mdi_cs.szTitle = cs->lpszName;
318 mdi_cs.hOwner = cs->hInstance;
319 mdi_cs.x = cs->x;
320 mdi_cs.y = cs->y;
321 mdi_cs.cx = cs->cx;
322 mdi_cs.cy = cs->cy;
323 mdi_cs.style = cs->style;
324 mdi_cs.lParam = (LPARAM)cs->lpCreateParams;
326 cs->lpCreateParams = &mdi_cs;
328 if (GetWindowLongW(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
330 if (cs->style & WS_POPUP)
332 TRACE("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
333 return 0;
335 cs->style |= WS_CHILD | WS_CLIPSIBLINGS;
337 else
339 cs->style &= ~WS_POPUP;
340 cs->style |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
341 WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
344 top_child = GetWindow(cs->hwndParent, GW_CHILD);
346 if (top_child)
348 /* Restore current maximized child */
349 if((cs->style & WS_VISIBLE) && IsZoomed(top_child))
351 TRACE("Restoring current maximized child %p\n", top_child);
352 if (cs->style & WS_MAXIMIZE)
354 /* if the new window is maximized don't bother repainting */
355 SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
356 NtUserShowWindow( top_child, SW_SHOWNORMAL );
357 SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
359 else NtUserShowWindow( top_child, SW_SHOWNORMAL );
363 MDI_CalcDefaultChildPos( cs->hwndParent, -1, pos, 0, &id );
364 if (!(cs->style & WS_POPUP)) cs->hMenu = ULongToHandle(id);
366 TRACE( "MDI child id %04x\n", id );
368 if (cs->style & (WS_CHILD | WS_POPUP))
370 if (is_default_coord( cs->x ))
372 cs->x = pos[0].x;
373 cs->y = pos[0].y;
375 if (is_default_coord( cs->cx ) || !cs->cx) cs->cx = pos[1].x;
376 if (is_default_coord( cs->cy ) || !cs->cy) cs->cy = pos[1].y;
380 if (!unicode && cs->lpszName)
382 const char *nameA = (const char *)cs->lpszName;
383 /* resource ID string is a special case */
384 if (nameA[0] == '\xff')
386 name_buf[0] = 0xffff;
387 name_buf[1] = MAKEWORD( nameA[1], nameA[2] );
388 name_buf[2] = 0;
389 RtlInitUnicodeString( &window_name, name_buf );
391 else if (!RtlCreateUnicodeStringFromAsciiz( &window_name, (const char *)cs->lpszName ))
392 return 0;
394 else RtlInitUnicodeString( &window_name, cs->lpszName );
396 menu = cs->hMenu;
397 if (!menu && info.lpszMenuName && (cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
398 menu = LoadMenuW( cs->hInstance, info.lpszMenuName );
400 hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, &window_name, cs->style,
401 cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, menu, module,
402 cs->lpCreateParams, 0, cs->hInstance, 0, !unicode );
403 if (!hwnd && menu && menu != cs->hMenu) NtUserDestroyMenu( menu );
404 if (!unicode && window_name.Buffer != name_buf) RtlFreeUnicodeString( &window_name );
405 return hwnd;
409 /***********************************************************************
410 * CreateWindowExA (USER32.@)
412 HWND WINAPI DECLSPEC_HOTPATCH CreateWindowExA( DWORD exStyle, LPCSTR className,
413 LPCSTR windowName, DWORD style, INT x,
414 INT y, INT width, INT height,
415 HWND parent, HMENU menu,
416 HINSTANCE instance, LPVOID data )
418 CREATESTRUCTA cs;
420 cs.lpCreateParams = data;
421 cs.hInstance = instance;
422 cs.hMenu = menu;
423 cs.hwndParent = parent;
424 cs.x = x;
425 cs.y = y;
426 cs.cx = width;
427 cs.cy = height;
428 cs.style = style;
429 cs.lpszName = windowName;
430 cs.lpszClass = className;
431 cs.dwExStyle = exStyle;
433 if (!IS_INTRESOURCE(className))
435 WCHAR bufferW[256];
436 if (!MultiByteToWideChar( CP_ACP, 0, className, -1, bufferW, ARRAY_SIZE( bufferW )))
437 return 0;
438 return wow_handlers.create_window( (CREATESTRUCTW *)&cs, bufferW, instance, FALSE );
440 /* Note: we rely on the fact that CREATESTRUCTA and */
441 /* CREATESTRUCTW have the same layout. */
442 return wow_handlers.create_window( (CREATESTRUCTW *)&cs, (LPCWSTR)className, instance, FALSE );
446 /***********************************************************************
447 * CreateWindowExW (USER32.@)
449 HWND WINAPI DECLSPEC_HOTPATCH CreateWindowExW( DWORD exStyle, LPCWSTR className,
450 LPCWSTR windowName, DWORD style, INT x,
451 INT y, INT width, INT height,
452 HWND parent, HMENU menu,
453 HINSTANCE instance, LPVOID data )
455 CREATESTRUCTW cs;
457 cs.lpCreateParams = data;
458 cs.hInstance = instance;
459 cs.hMenu = menu;
460 cs.hwndParent = parent;
461 cs.x = x;
462 cs.y = y;
463 cs.cx = width;
464 cs.cy = height;
465 cs.style = style;
466 cs.lpszName = windowName;
467 cs.lpszClass = className;
468 cs.dwExStyle = exStyle;
470 return wow_handlers.create_window( &cs, className, instance, TRUE );
474 /***********************************************************************
475 * CloseWindow (USER32.@)
477 BOOL WINAPI CloseWindow( HWND hwnd )
479 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) return FALSE;
480 NtUserShowWindow( hwnd, SW_MINIMIZE );
481 return TRUE;
485 /***********************************************************************
486 * OpenIcon (USER32.@)
488 BOOL WINAPI OpenIcon( HWND hwnd )
490 if (!IsIconic( hwnd )) return FALSE;
491 NtUserShowWindow( hwnd, SW_SHOWNORMAL );
492 return TRUE;
496 /***********************************************************************
497 * FindWindowExW (USER32.@)
499 HWND WINAPI FindWindowExW( HWND parent, HWND child, const WCHAR *class, const WCHAR *title )
501 UNICODE_STRING class_str, title_str;
503 if (title) RtlInitUnicodeString( &title_str, title );
505 if (class)
507 if (IS_INTRESOURCE(class))
509 class_str.Buffer = (WCHAR *)class;
510 class_str.Length = class_str.MaximumLength = 0;
512 else RtlInitUnicodeString( &class_str, class );
515 return NtUserFindWindowEx( parent, child, class ? &class_str : NULL,
516 title ? &title_str : NULL, 0 );
521 /***********************************************************************
522 * FindWindowA (USER32.@)
524 HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
526 HWND ret = FindWindowExA( 0, 0, className, title );
527 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
528 return ret;
532 /***********************************************************************
533 * FindWindowExA (USER32.@)
535 HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR title )
537 LPWSTR titleW = NULL;
538 HWND hwnd = 0;
540 if (title)
542 DWORD len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 );
543 if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0;
544 MultiByteToWideChar( CP_ACP, 0, title, -1, titleW, len );
547 if (!IS_INTRESOURCE(className))
549 WCHAR classW[256];
550 if (MultiByteToWideChar( CP_ACP, 0, className, -1, classW, ARRAY_SIZE( classW )))
551 hwnd = FindWindowExW( parent, child, classW, titleW );
553 else
555 hwnd = FindWindowExW( parent, child, (LPCWSTR)className, titleW );
558 HeapFree( GetProcessHeap(), 0, titleW );
559 return hwnd;
563 /***********************************************************************
564 * FindWindowW (USER32.@)
566 HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
568 return FindWindowExW( 0, 0, className, title );
572 /**********************************************************************
573 * GetDesktopWindow (USER32.@)
575 HWND WINAPI GetDesktopWindow(void)
577 struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
579 if (thread_info->top_window) return UlongToHandle( thread_info->top_window );
580 return NtUserGetDesktopWindow();
584 /*******************************************************************
585 * EnableWindow (USER32.@)
587 BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
589 return NtUserEnableWindow( hwnd, enable );
593 /***********************************************************************
594 * IsWindowEnabled (USER32.@)
596 BOOL WINAPI IsWindowEnabled( HWND hwnd )
598 return NtUserIsWindowEnabled( hwnd );
601 /***********************************************************************
602 * IsWindowUnicode (USER32.@)
604 BOOL WINAPI IsWindowUnicode( HWND hwnd )
606 return NtUserIsWindowUnicode( hwnd );
610 /***********************************************************************
611 * GetWindowDpiAwarenessContext (USER32.@)
613 DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( HWND hwnd )
615 return NtUserGetWindowDpiAwarenessContext( hwnd );
619 /***********************************************************************
620 * GetWindowDpiHostingBehavior (USER32.@)
622 DPI_HOSTING_BEHAVIOR WINAPI GetWindowDpiHostingBehavior( HWND hwnd )
624 FIXME("(%p): stub\n", hwnd);
625 return DPI_HOSTING_BEHAVIOR_DEFAULT;
629 static LONG_PTR get_window_long_ptr( HWND hwnd, int offset, LONG_PTR ret, BOOL ansi )
631 if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd ))
633 DLGPROC proc = NtUserGetDialogProc( (DLGPROC)ret, ansi );
634 if (proc && proc != WINPROC_PROC16) return (LONG_PTR)proc;
636 return ret;
640 static LONG_PTR set_dialog_proc( HWND hwnd, LONG_PTR newval, BOOL ansi )
642 DLGPROC proc;
643 LONG_PTR ret;
644 newval = NtUserCallTwoParam( newval, ansi, NtUserAllocWinProc );
645 ret = NtUserSetWindowLongPtr( hwnd, DWLP_DLGPROC, newval, ansi );
646 proc = NtUserGetDialogProc( (DLGPROC)ret, ansi );
647 if (proc) ret = (UINT_PTR)proc;
648 return ret;
652 /***********************************************************************
653 * GetDpiForWindow (USER32.@)
655 UINT WINAPI GetDpiForWindow( HWND hwnd )
657 return NtUserGetDpiForWindow( hwnd );
661 /***********************************************************************
662 * SwitchToThisWindow (USER32.@)
664 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL alt_tab )
666 if (IsIconic( hwnd )) NtUserShowWindow( hwnd, SW_RESTORE );
667 else BringWindowToTop( hwnd );
671 /***********************************************************************
672 * GetWindowRect (USER32.@)
674 BOOL WINAPI GetWindowRect( HWND hwnd, RECT *rect )
676 BOOL ret = NtUserGetWindowRect( hwnd, rect );
677 if (ret) TRACE( "hwnd %p %s\n", hwnd, wine_dbgstr_rect(rect) );
678 return ret;
682 /***********************************************************************
683 * GetWindowRgn (USER32.@)
685 int WINAPI GetWindowRgn( HWND hwnd, HRGN hrgn )
687 return NtUserGetWindowRgnEx( hwnd, hrgn, 0 );
691 /***********************************************************************
692 * GetWindowRgnBox (USER32.@)
694 int WINAPI GetWindowRgnBox( HWND hwnd, RECT *rect )
696 int ret = ERROR;
697 HRGN hrgn;
699 if (!rect)
700 return ERROR;
702 if ((hrgn = CreateRectRgn( 0, 0, 0, 0 )))
704 if ((ret = GetWindowRgn( hwnd, hrgn )) != ERROR )
705 ret = GetRgnBox( hrgn, rect );
706 DeleteObject( hrgn );
709 return ret;
713 /***********************************************************************
714 * GetClientRect (USER32.@)
716 BOOL WINAPI GetClientRect( HWND hwnd, RECT *rect )
718 return NtUserGetClientRect( hwnd, rect );
722 /*******************************************************************
723 * WindowFromPoint (USER32.@)
725 HWND WINAPI WindowFromPoint( POINT pt )
727 return NtUserWindowFromPoint( pt.x, pt.y );
731 /*******************************************************************
732 * ChildWindowFromPoint (USER32.@)
734 HWND WINAPI ChildWindowFromPoint( HWND parent, POINT pt )
736 return NtUserChildWindowFromPointEx( parent, pt.x, pt.y, CWP_ALL );
739 /*******************************************************************
740 * RealChildWindowFromPoint (USER32.@)
742 HWND WINAPI RealChildWindowFromPoint( HWND parent, POINT pt )
744 return NtUserRealChildWindowFromPoint( parent, pt.x, pt.y );
747 /*******************************************************************
748 * ChildWindowFromPointEx (USER32.@)
750 HWND WINAPI ChildWindowFromPointEx( HWND parent, POINT pt, UINT flags )
752 return NtUserChildWindowFromPointEx( parent, pt.x, pt.y, flags );
756 /*******************************************************************
757 * MapWindowPoints (USER32.@)
759 INT WINAPI MapWindowPoints( HWND hwnd_from, HWND hwnd_to, POINT *points, UINT count )
761 return NtUserMapWindowPoints( hwnd_from, hwnd_to, points, count );
765 /*******************************************************************
766 * ClientToScreen (USER32.@)
768 BOOL WINAPI ClientToScreen( HWND hwnd, POINT *pt )
770 return NtUserClientToScreen( hwnd, pt );
774 /*******************************************************************
775 * ScreenToClient (USER32.@)
777 BOOL WINAPI ScreenToClient( HWND hwnd, POINT *pt )
779 return NtUserScreenToClient( hwnd, pt );
783 /***********************************************************************
784 * IsIconic (USER32.@)
786 BOOL WINAPI IsIconic( HWND hwnd )
788 return (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
792 /***********************************************************************
793 * IsZoomed (USER32.@)
795 BOOL WINAPI IsZoomed( HWND hwnd )
797 return (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
801 /*******************************************************************
802 * AllowSetForegroundWindow (USER32.@)
804 BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
806 /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
807 * implemented, then fix this function. */
808 return TRUE;
812 /*******************************************************************
813 * LockSetForegroundWindow (USER32.@)
815 BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
817 /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
818 * implemented, then fix this function. */
819 return TRUE;
823 /***********************************************************************
824 * BringWindowToTop (USER32.@)
826 BOOL WINAPI BringWindowToTop( HWND hwnd )
828 return NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
832 /***********************************************************************
833 * AnimateWindow (USER32.@)
835 BOOL WINAPI AnimateWindow( HWND hwnd, DWORD time, DWORD flags )
837 FIXME( "partial stub\n" );
839 /* If trying to show/hide and it's already shown/hidden or invalid window,
840 * fail with invalid parameter. */
841 if (!IsWindow( hwnd ) || (!(flags & AW_HIDE)) == IsWindowVisible( hwnd ))
843 SetLastError(ERROR_INVALID_PARAMETER);
844 return FALSE;
847 NtUserShowWindow( hwnd, (flags & AW_HIDE) ? SW_HIDE : ((flags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA) );
848 return TRUE;
852 /***********************************************************************
853 * BeginDeferWindowPos (USER32.@)
855 HDWP WINAPI BeginDeferWindowPos( INT count )
857 return NtUserBeginDeferWindowPos( count );
861 /***********************************************************************
862 * DeferWindowPos (USER32.@)
864 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND after, INT x, INT y,
865 INT cx, INT cy, UINT flags )
867 return NtUserDeferWindowPosAndBand( hdwp, hwnd, after, x, y, cx, cy, flags, 0, 0 );
871 /***********************************************************************
872 * EndDeferWindowPos (USER32.@)
874 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
876 return NtUserEndDeferWindowPosEx( hdwp, FALSE );
880 /***********************************************************************
881 * ArrangeIconicWindows (USER32.@)
883 UINT WINAPI ArrangeIconicWindows( HWND parent )
885 return NtUserArrangeIconicWindows( parent );
889 /**********************************************************************
890 * GetWindowWord (USER32.@)
892 WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
894 return NtUserGetWindowWord( hwnd, offset );
898 /**********************************************************************
899 * GetWindowLongA (USER32.@)
902 #ifdef __i386__
904 /* This wrapper is here to workaround a ntlea quirk. First of all, ntlea
905 * checks whether GetWindowLongA starts with the Win32 hotpatchable prologue,
906 * if it can find that, it will use a hooking strategy more difficult for us
907 * to deal with. Secondly, it assumes what follows the prologue is a `pushl $-2`,
908 * and will try to skip over this instruction when calling `GetWindowLongA`,
909 * (i.e. it tries to jump to `GetWindowLongA + 7`, 5 bytes for the prologue, 2
910 * bytes for the `pushl`.). We have to anticipate that and make sure the result
911 * of doing this won't be a messed up stack, or a desynced PC.
913 __ASM_STDCALL_FUNC( GetWindowLongA, 8,
914 ".byte 0x8b, 0xff, 0x55, 0x8b, 0xec\n" /* Win32 hotpatchable prologue. */
915 "pushl $-2\n"
916 "addl $4, %esp\n"
917 "popl %ebp\n"
918 "jmp " __ASM_STDCALL("get_window_longA", 8) )
919 LONG WINAPI get_window_longA( HWND hwnd, INT offset )
920 #else
921 LONG WINAPI DECLSPEC_HOTPATCH GetWindowLongA( HWND hwnd, INT offset )
922 #endif
924 switch (offset)
926 #ifdef _WIN64
927 case GWLP_WNDPROC:
928 case GWLP_HINSTANCE:
929 case GWLP_HWNDPARENT:
930 WARN( "Invalid offset %d\n", offset );
931 SetLastError( ERROR_INVALID_INDEX );
932 return 0;
933 #endif
934 default:
935 if (sizeof(void *) == sizeof(LONG))
937 LONG_PTR ret = NtUserGetWindowLongA( hwnd, offset );
938 return get_window_long_ptr( hwnd, offset, ret, TRUE );
940 return NtUserGetWindowLongA( hwnd, offset );
945 /**********************************************************************
946 * GetWindowLongW (USER32.@)
948 LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
950 switch (offset)
952 #ifdef _WIN64
953 case GWLP_WNDPROC:
954 case GWLP_HINSTANCE:
955 case GWLP_HWNDPARENT:
956 WARN( "Invalid offset %d\n", offset );
957 SetLastError( ERROR_INVALID_INDEX );
958 return 0;
959 #endif
960 default:
961 if (sizeof(void *) == sizeof(LONG))
963 LONG_PTR ret = NtUserGetWindowLongW( hwnd, offset );
964 return get_window_long_ptr( hwnd, offset, ret, FALSE );
966 return NtUserGetWindowLongW( hwnd, offset );
971 /**********************************************************************
972 * SetWindowLongA (USER32.@)
974 * See SetWindowLongW.
976 LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongA( HWND hwnd, INT offset, LONG newval )
978 switch (offset)
980 #ifdef _WIN64
981 case GWLP_WNDPROC:
982 case GWLP_HINSTANCE:
983 case GWLP_HWNDPARENT:
984 WARN( "Invalid offset %d\n", offset );
985 SetLastError( ERROR_INVALID_INDEX );
986 return 0;
987 #else
988 case DWLP_DLGPROC:
989 if (NtUserGetDialogInfo( hwnd )) return set_dialog_proc( hwnd, newval, TRUE );
990 /* fall through */
991 #endif
992 default:
993 return NtUserSetWindowLong( hwnd, offset, newval, TRUE );
998 /**********************************************************************
999 * SetWindowLongW (USER32.@) Set window attribute
1001 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1002 * value in a window's extra memory.
1004 * The _hwnd_ parameter specifies the handle to a window that
1005 * has extra memory. The _newval_ parameter contains the new
1006 * attribute or extra memory value. If positive, the _offset_
1007 * parameter is the byte-addressed location in the window's extra
1008 * memory to set. If negative, _offset_ specifies the window
1009 * attribute to set, and should be one of the following values:
1011 * GWL_EXSTYLE The window's extended window style
1013 * GWL_STYLE The window's window style.
1015 * GWLP_WNDPROC Pointer to the window's window procedure.
1017 * GWLP_HINSTANCE The window's application instance handle.
1019 * GWLP_ID The window's identifier.
1021 * GWLP_USERDATA The window's user-specified data.
1023 * If the window is a dialog box, the _offset_ parameter can be one of
1024 * the following values:
1026 * DWLP_DLGPROC The address of the window's dialog box procedure.
1028 * DWLP_MSGRESULT The return value of a message
1029 * that the dialog box procedure processed.
1031 * DWLP_USER Application specific information.
1033 * RETURNS
1035 * If successful, returns the previous value located at _offset_. Otherwise,
1036 * returns 0.
1038 * NOTES
1040 * Extra memory for a window class is specified by a nonzero cbWndExtra
1041 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1042 * time of class creation.
1044 * Using GWL_WNDPROC to set a new window procedure effectively creates
1045 * a window subclass. Use CallWindowProc() in the new windows procedure
1046 * to pass messages to the superclass's window procedure.
1048 * The user data is reserved for use by the application which created
1049 * the window.
1051 * Do not use GWL_STYLE to change the window's WS_DISABLED style;
1052 * instead, call the EnableWindow() function to change the window's
1053 * disabled state.
1055 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1056 * SetParent() instead.
1058 * Win95:
1059 * When offset is GWL_STYLE and the calling app's ver is 4.0,
1060 * it sends WM_STYLECHANGING before changing the settings
1061 * and WM_STYLECHANGED afterwards.
1062 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
1064 LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongW(
1065 HWND hwnd, /* [in] window to alter */
1066 INT offset, /* [in] offset, in bytes, of location to alter */
1067 LONG newval /* [in] new value of location */
1070 switch (offset)
1072 #ifdef _WIN64
1073 case GWLP_WNDPROC:
1074 case GWLP_HINSTANCE:
1075 case GWLP_HWNDPARENT:
1076 WARN("Invalid offset %d\n", offset );
1077 SetLastError( ERROR_INVALID_INDEX );
1078 return 0;
1079 #else
1080 case DWLP_DLGPROC:
1081 if (NtUserGetDialogInfo( hwnd )) return set_dialog_proc( hwnd, newval, FALSE );
1082 /* fall through */
1083 #endif
1084 default:
1085 return NtUserSetWindowLong( hwnd, offset, newval, FALSE );
1090 /*******************************************************************
1091 * GetWindowTextA (USER32.@)
1093 INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
1095 WCHAR *buffer;
1096 int ret = 0;
1098 if (!lpString || nMaxCount <= 0) return 0;
1100 __TRY
1102 lpString[0] = 0;
1104 if (WIN_IsCurrentProcess( hwnd ))
1106 ret = (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
1108 else if ((buffer = HeapAlloc( GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR) )))
1110 /* when window belongs to other process, don't send a message */
1111 NtUserInternalGetWindowText( hwnd, buffer, nMaxCount );
1112 if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, lpString, nMaxCount, NULL, NULL ))
1113 lpString[nMaxCount-1] = 0;
1114 HeapFree( GetProcessHeap(), 0, buffer );
1115 ret = strlen(lpString);
1118 __EXCEPT_PAGE_FAULT
1120 ret = 0;
1122 __ENDTRY
1124 return ret;
1128 /*******************************************************************
1129 * GetWindowTextW (USER32.@)
1131 INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
1133 int ret;
1135 if (!lpString || nMaxCount <= 0) return 0;
1137 __TRY
1139 lpString[0] = 0;
1141 if (WIN_IsCurrentProcess( hwnd ))
1143 ret = (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
1145 else
1147 /* when window belongs to other process, don't send a message */
1148 ret = NtUserInternalGetWindowText( hwnd, lpString, nMaxCount );
1151 __EXCEPT_PAGE_FAULT
1153 ret = 0;
1155 __ENDTRY
1157 return ret;
1161 /*******************************************************************
1162 * SetWindowTextA (USER32.@)
1163 * SetWindowText (USER32.@)
1165 BOOL WINAPI DECLSPEC_HOTPATCH SetWindowTextA( HWND hwnd, LPCSTR lpString )
1167 if (is_broadcast(hwnd))
1169 SetLastError( ERROR_INVALID_PARAMETER );
1170 return FALSE;
1172 if (!WIN_IsCurrentProcess( hwnd ))
1173 WARN( "setting text %s of other process window %p should not use SendMessage\n",
1174 debugstr_a(lpString), hwnd );
1175 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1179 /*******************************************************************
1180 * SetWindowTextW (USER32.@)
1182 BOOL WINAPI DECLSPEC_HOTPATCH SetWindowTextW( HWND hwnd, LPCWSTR lpString )
1184 if (is_broadcast(hwnd))
1186 SetLastError( ERROR_INVALID_PARAMETER );
1187 return FALSE;
1189 if (!WIN_IsCurrentProcess( hwnd ))
1190 WARN( "setting text %s of other process window %p should not use SendMessage\n",
1191 debugstr_w(lpString), hwnd );
1192 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1196 /*******************************************************************
1197 * GetWindowTextLengthA (USER32.@)
1199 INT WINAPI GetWindowTextLengthA( HWND hwnd )
1201 CPINFO info;
1203 if (WIN_IsCurrentProcess( hwnd )) return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1205 /* when window belongs to other process, don't send a message */
1206 GetCPInfo( CP_ACP, &info );
1207 return NtUserGetWindowTextLength( hwnd ) * info.MaxCharSize;
1210 /*******************************************************************
1211 * GetWindowTextLengthW (USER32.@)
1213 INT WINAPI GetWindowTextLengthW( HWND hwnd )
1215 if (WIN_IsCurrentProcess( hwnd )) return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1217 /* when window belongs to other process, don't send a message */
1218 return NtUserGetWindowTextLength( hwnd );
1222 /*******************************************************************
1223 * IsWindow (USER32.@)
1225 BOOL WINAPI IsWindow( HWND hwnd )
1227 return NtUserIsWindow( hwnd );
1231 /***********************************************************************
1232 * GetWindowThreadProcessId (USER32.@)
1234 DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
1236 return NtUserGetWindowThread( hwnd, process );
1240 /*****************************************************************
1241 * GetParent (USER32.@)
1243 HWND WINAPI GetParent( HWND hwnd )
1245 return NtUserGetParent( hwnd );
1249 /*******************************************************************
1250 * IsChild (USER32.@)
1252 BOOL WINAPI IsChild( HWND parent, HWND child )
1254 return NtUserIsChild( parent, child );
1258 /***********************************************************************
1259 * IsWindowVisible (USER32.@)
1261 BOOL WINAPI IsWindowVisible( HWND hwnd )
1263 return NtUserIsWindowVisible( hwnd );
1267 /*******************************************************************
1268 * GetTopWindow (USER32.@)
1270 HWND WINAPI GetTopWindow( HWND hwnd )
1272 if (!hwnd) hwnd = GetDesktopWindow();
1273 return GetWindow( hwnd, GW_CHILD );
1277 /*******************************************************************
1278 * GetWindow (USER32.@)
1280 HWND WINAPI GetWindow( HWND hwnd, UINT rel )
1282 return NtUserGetWindowRelative( hwnd, rel );
1286 /*******************************************************************
1287 * ShowOwnedPopups (USER32.@)
1289 BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL show )
1291 return NtUserShowOwnedPopups( owner, show );
1295 /*******************************************************************
1296 * GetLastActivePopup (USER32.@)
1298 HWND WINAPI GetLastActivePopup( HWND hwnd )
1300 HWND retval = hwnd;
1302 SERVER_START_REQ( get_window_info )
1304 req->handle = wine_server_user_handle( hwnd );
1305 if (!wine_server_call_err( req )) retval = wine_server_ptr_handle( reply->last_active );
1307 SERVER_END_REQ;
1308 return retval;
1312 /*******************************************************************
1313 * WIN_ListChildren
1315 * Build an array of the children of a given window. The array must be
1316 * freed with HeapFree. Returns NULL when no windows are found.
1318 HWND *WIN_ListChildren( HWND hwnd )
1320 if (!hwnd)
1322 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1323 return NULL;
1325 return list_window_children( 0, hwnd, NULL, 0 );
1329 /*******************************************************************
1330 * EnumWindows (USER32.@)
1332 BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
1334 HWND *list;
1335 BOOL ret = TRUE;
1336 int i;
1338 /* We have to build a list of all windows first, to avoid */
1339 /* unpleasant side-effects, for instance if the callback */
1340 /* function changes the Z-order of the windows. */
1342 if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return TRUE;
1344 /* Now call the callback function for every window */
1346 for (i = 0; list[i]; i++)
1348 /* Make sure that the window still exists */
1349 if (!IsWindow( list[i] )) continue;
1350 if (!(ret = lpEnumFunc( list[i], lParam ))) break;
1352 HeapFree( GetProcessHeap(), 0, list );
1353 return ret;
1357 /**********************************************************************
1358 * EnumThreadWindows (USER32.@)
1360 BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
1362 HWND *list;
1363 int i;
1364 BOOL ret = TRUE;
1366 if (!(list = list_window_children( 0, GetDesktopWindow(), NULL, id ))) return TRUE;
1368 /* Now call the callback function for every window */
1370 for (i = 0; list[i]; i++)
1371 if (!(ret = func( list[i], lParam ))) break;
1372 HeapFree( GetProcessHeap(), 0, list );
1373 return ret;
1377 /***********************************************************************
1378 * EnumDesktopWindows (USER32.@)
1380 BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
1382 HWND *list;
1383 int i;
1385 if (!(list = list_window_children( desktop, 0, NULL, 0 ))) return TRUE;
1387 for (i = 0; list[i]; i++)
1388 if (!func( list[i], lparam )) break;
1389 HeapFree( GetProcessHeap(), 0, list );
1390 return TRUE;
1394 #ifdef __i386__
1395 /* Some apps pass a non-stdcall proc to EnumChildWindows,
1396 * so we need a small assembly wrapper to call the proc.
1398 extern LRESULT enum_callback_wrapper( WNDENUMPROC proc, HWND hwnd, LPARAM lparam );
1399 __ASM_GLOBAL_FUNC( enum_callback_wrapper,
1400 "pushl %ebp\n\t"
1401 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
1402 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
1403 "movl %esp,%ebp\n\t"
1404 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
1405 "pushl 16(%ebp)\n\t"
1406 "pushl 12(%ebp)\n\t"
1407 "call *8(%ebp)\n\t"
1408 "leave\n\t"
1409 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
1410 __ASM_CFI(".cfi_same_value %ebp\n\t")
1411 "ret" )
1412 #else
1413 static inline LRESULT enum_callback_wrapper( WNDENUMPROC proc, HWND hwnd, LPARAM lparam )
1415 return proc( hwnd, lparam );
1417 #endif /* __i386__ */
1419 /**********************************************************************
1420 * WIN_EnumChildWindows
1422 * Helper function for EnumChildWindows().
1424 static BOOL WIN_EnumChildWindows( HWND *list, WNDENUMPROC func, LPARAM lParam )
1426 HWND *childList;
1427 BOOL ret = FALSE;
1429 for ( ; *list; list++)
1431 /* Make sure that the window still exists */
1432 if (!IsWindow( *list )) continue;
1433 /* Build children list first */
1434 childList = WIN_ListChildren( *list );
1436 ret = enum_callback_wrapper( func, *list, lParam );
1438 if (childList)
1440 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
1441 HeapFree( GetProcessHeap(), 0, childList );
1443 if (!ret) return FALSE;
1445 return TRUE;
1449 /**********************************************************************
1450 * EnumChildWindows (USER32.@)
1452 BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func, LPARAM lParam )
1454 HWND *list;
1455 BOOL ret;
1457 if (!(list = WIN_ListChildren( parent ))) return FALSE;
1458 ret = WIN_EnumChildWindows( list, func, lParam );
1459 HeapFree( GetProcessHeap(), 0, list );
1460 return ret;
1464 /*******************************************************************
1465 * AnyPopup (USER32.@)
1467 BOOL WINAPI AnyPopup(void)
1469 int i;
1470 BOOL retvalue;
1471 HWND *list = WIN_ListChildren( GetDesktopWindow() );
1473 if (!list) return FALSE;
1474 for (i = 0; list[i]; i++)
1476 if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break;
1478 retvalue = (list[i] != 0);
1479 HeapFree( GetProcessHeap(), 0, list );
1480 return retvalue;
1484 /*******************************************************************
1485 * FlashWindow (USER32.@)
1487 BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
1489 FLASHWINFO finfo;
1491 finfo.cbSize = sizeof(FLASHWINFO);
1492 finfo.dwFlags = bInvert ? FLASHW_ALL : FLASHW_STOP;
1493 finfo.uCount = 1;
1494 finfo.dwTimeout = 0;
1495 finfo.hwnd = hWnd;
1496 return NtUserFlashWindowEx( &finfo );
1500 /*******************************************************************
1501 * GetWindowContextHelpId (USER32.@)
1503 DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
1505 return NtUserGetWindowContextHelpId( hwnd );
1509 /*******************************************************************
1510 * SetWindowContextHelpId (USER32.@)
1512 BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
1514 return NtUserSetWindowContextHelpId( hwnd, id );
1518 /*******************************************************************
1519 * DragDetect (USER32.@)
1521 BOOL WINAPI DragDetect( HWND hwnd, POINT pt )
1523 return NtUserDragDetect( hwnd, pt.x, pt.y );
1526 /******************************************************************************
1527 * GetWindowModuleFileNameA (USER32.@)
1529 UINT WINAPI GetWindowModuleFileNameA( HWND hwnd, LPSTR module, UINT size )
1531 HINSTANCE hinst;
1533 TRACE( "%p, %p, %u\n", hwnd, module, size );
1535 if (!WIN_IsCurrentProcess( hwnd ))
1537 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1538 return 0;
1541 hinst = (HINSTANCE)GetWindowLongPtrA( hwnd, GWLP_HINSTANCE );
1542 return GetModuleFileNameA( hinst, module, size );
1545 /******************************************************************************
1546 * GetWindowModuleFileNameW (USER32.@)
1548 UINT WINAPI GetWindowModuleFileNameW( HWND hwnd, LPWSTR module, UINT size )
1550 HINSTANCE hinst;
1552 TRACE( "%p, %p, %u\n", hwnd, module, size );
1554 if (!WIN_IsCurrentProcess( hwnd ))
1556 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1557 return 0;
1560 hinst = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
1561 return GetModuleFileNameW( hinst, module, size );
1564 /******************************************************************************
1565 * GetWindowInfo (USER32.@)
1567 * Note: tests show that Windows doesn't check cbSize of the structure.
1569 BOOL WINAPI DECLSPEC_HOTPATCH GetWindowInfo( HWND hwnd, WINDOWINFO *info )
1571 return NtUserGetWindowInfo( hwnd, info );
1574 /*****************************************************************************
1575 * UpdateLayeredWindowIndirect (USER32.@)
1577 BOOL WINAPI UpdateLayeredWindowIndirect( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info )
1579 if (!info || info->cbSize != sizeof(*info))
1581 SetLastError( ERROR_INVALID_PARAMETER );
1582 return FALSE;
1585 return NtUserUpdateLayeredWindow( hwnd, info->hdcDst, info->pptDst, info->psize,
1586 info->hdcSrc, info->pptSrc, info->crKey,
1587 info->pblend, info->dwFlags, info->prcDirty );
1591 /*****************************************************************************
1592 * UpdateLayeredWindow (USER32.@)
1594 BOOL WINAPI UpdateLayeredWindow( HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize,
1595 HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend,
1596 DWORD flags)
1598 UPDATELAYEREDWINDOWINFO info;
1600 if (flags & ULW_EX_NORESIZE) /* only valid for UpdateLayeredWindowIndirect */
1602 SetLastError( ERROR_INVALID_PARAMETER );
1603 return FALSE;
1605 info.cbSize = sizeof(info);
1606 info.hdcDst = hdcDst;
1607 info.pptDst = pptDst;
1608 info.psize = psize;
1609 info.hdcSrc = hdcSrc;
1610 info.pptSrc = pptSrc;
1611 info.crKey = crKey;
1612 info.pblend = pblend;
1613 info.dwFlags = flags;
1614 info.prcDirty = NULL;
1615 return UpdateLayeredWindowIndirect( hwnd, &info );
1619 /******************************************************************************
1620 * GetProcessDefaultLayout [USER32.@]
1622 * Gets the default layout for parentless windows.
1624 BOOL WINAPI GetProcessDefaultLayout( DWORD *layout )
1626 if (!layout)
1628 SetLastError( ERROR_NOACCESS );
1629 return FALSE;
1631 *layout = NtUserGetProcessDefaultLayout();
1632 if (*layout == ~0u)
1634 WCHAR *str, buffer[MAX_PATH];
1635 DWORD i, version_layout = 0;
1636 UINT len;
1637 DWORD user_lang = GetUserDefaultLangID();
1638 DWORD *languages;
1639 void *data = NULL;
1641 GetModuleFileNameW( 0, buffer, MAX_PATH );
1642 if (!(len = GetFileVersionInfoSizeW( buffer, NULL ))) goto done;
1643 if (!(data = HeapAlloc( GetProcessHeap(), 0, len ))) goto done;
1644 if (!GetFileVersionInfoW( buffer, 0, len, data )) goto done;
1645 if (!VerQueryValueW( data, L"\\VarFileInfo\\Translation", (void **)&languages, &len ) || !len) goto done;
1647 len /= sizeof(DWORD);
1648 for (i = 0; i < len; i++) if (LOWORD(languages[i]) == user_lang) break;
1649 if (i == len) /* try neutral language */
1650 for (i = 0; i < len; i++)
1651 if (LOWORD(languages[i]) == MAKELANGID( PRIMARYLANGID(user_lang), SUBLANG_NEUTRAL )) break;
1652 if (i == len) i = 0; /* default to the first one */
1654 swprintf( buffer, ARRAY_SIZE(buffer), L"\\StringFileInfo\\%04x%04x\\FileDescription",
1655 LOWORD(languages[i]), HIWORD(languages[i]) );
1656 if (!VerQueryValueW( data, buffer, (void **)&str, &len )) goto done;
1657 TRACE( "found description %s\n", debugstr_w( str ));
1658 if (str[0] == 0x200e && str[1] == 0x200e) version_layout = LAYOUT_RTL;
1660 done:
1661 HeapFree( GetProcessHeap(), 0, data );
1662 NtUserSetProcessDefaultLayout( *layout = version_layout );
1664 return TRUE;
1668 /******************************************************************************
1669 * SetProcessDefaultLayout [USER32.@]
1671 * Sets the default layout for parentless windows.
1673 BOOL WINAPI SetProcessDefaultLayout( DWORD layout )
1675 return NtUserSetProcessDefaultLayout( layout );
1679 /***********************************************************************
1680 * UpdateWindow (USER32.@)
1682 BOOL WINAPI UpdateWindow( HWND hwnd )
1684 if (!hwnd)
1686 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1687 return FALSE;
1690 return NtUserRedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
1694 /***********************************************************************
1695 * ValidateRgn (USER32.@)
1697 BOOL WINAPI ValidateRgn( HWND hwnd, HRGN hrgn )
1699 if (!hwnd)
1701 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1702 return FALSE;
1705 return NtUserRedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE );
1709 /*************************************************************************
1710 * ScrollWindow (USER32.@)
1712 BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy, const RECT *rect, const RECT *clip_rect )
1714 UINT flags = SW_INVALIDATE | SW_ERASE | (rect ? 0 : SW_SCROLLCHILDREN) | SW_NODCCACHE;
1715 return NtUserScrollWindowEx( hwnd, dx, dy, rect, clip_rect, 0, NULL, flags );
1718 #ifdef _WIN64
1720 /* 64bit versions */
1722 #undef GetWindowLongPtrW
1723 #undef GetWindowLongPtrA
1724 #undef SetWindowLongPtrW
1725 #undef SetWindowLongPtrA
1727 /*****************************************************************************
1728 * GetWindowLongPtrW (USER32.@)
1730 LONG_PTR WINAPI GetWindowLongPtrW( HWND hwnd, INT offset )
1732 LONG_PTR ret = NtUserGetWindowLongPtrW( hwnd, offset );
1733 return get_window_long_ptr( hwnd, offset, ret, FALSE );
1736 /*****************************************************************************
1737 * GetWindowLongPtrA (USER32.@)
1739 LONG_PTR WINAPI GetWindowLongPtrA( HWND hwnd, INT offset )
1741 LONG_PTR ret = NtUserGetWindowLongPtrA( hwnd, offset );
1742 return get_window_long_ptr( hwnd, offset, ret, TRUE );
1745 /*****************************************************************************
1746 * SetWindowLongPtrW (USER32.@)
1748 LONG_PTR WINAPI SetWindowLongPtrW( HWND hwnd, INT offset, LONG_PTR newval )
1750 if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd ))
1751 return set_dialog_proc( hwnd, newval, FALSE );
1753 return NtUserSetWindowLongPtr( hwnd, offset, newval, FALSE );
1756 /*****************************************************************************
1757 * SetWindowLongPtrA (USER32.@)
1759 LONG_PTR WINAPI SetWindowLongPtrA( HWND hwnd, INT offset, LONG_PTR newval )
1761 if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd ))
1762 return set_dialog_proc( hwnd, newval, TRUE );
1764 return NtUserSetWindowLongPtr( hwnd, offset, newval, TRUE );
1767 #endif /* _WIN64 */
1769 /*****************************************************************************
1770 * GetWindowDisplayAffinity (USER32.@)
1772 BOOL WINAPI GetWindowDisplayAffinity(HWND hwnd, DWORD *affinity)
1774 FIXME("(%p, %p): stub\n", hwnd, affinity);
1776 if (!hwnd || !affinity)
1778 SetLastError(hwnd ? ERROR_NOACCESS : ERROR_INVALID_WINDOW_HANDLE);
1779 return FALSE;
1782 *affinity = WDA_NONE;
1783 return TRUE;
1786 /*****************************************************************************
1787 * SetWindowDisplayAffinity (USER32.@)
1789 BOOL WINAPI SetWindowDisplayAffinity(HWND hwnd, DWORD affinity)
1791 FIXME("(%p, %lu): stub\n", hwnd, affinity);
1793 if (!hwnd)
1795 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1796 return FALSE;
1799 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1800 return FALSE;
1803 /**********************************************************************
1804 * SetWindowCompositionAttribute (USER32.@)
1806 BOOL WINAPI SetWindowCompositionAttribute(HWND hwnd, void *data)
1808 FIXME("(%p, %p): stub\n", hwnd, data);
1809 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1810 return FALSE;