/* $Id: window.cpp,v 1.140 2004-03-09 10:06:15 sandervl Exp $ */ /* * Win32 window apis for OS/2 * * Copyright 1999-2001 Sander van Leeuwen (sandervl@xs4all.nl) * Copyright 1999 Daniela Engert (dani@ngrt.de) * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch) * * Parts based on Wine Windows code (windows\win.c, windows\property.c, windows\winpos.c) * * Copyright 1993, 1994, 1995 Alexandre Julliard * 1995, 1996, 1999 Alex Korobka * * Project Odin Software License can be found in LICENSE.TXT * * * TODO: Decide what to do about commands for OS/2 windows (non-Win32 apps) * TODO: ShowOwnedPopups needs to be tested * GetLastActivePopup needs to be rewritten * */ #include #include #include #include #include #include #include #include "win32wbase.h" #include "win32wmdiclient.h" #include "win32wdesktop.h" #include "win32dlg.h" #include "oslibwin.h" #include "oslibgdi.h" #include "user32.h" #include "winicon.h" #include "pmwindow.h" #include "oslibmsg.h" #include #include #include #include #include "hook.h" #include #include #define DBG_LOCALLOG DBG_window #include "dbglocal.h" ODINDEBUGCHANNEL(USER32-WINDOW) #ifdef __cplusplus extern "C" { #endif //****************************************************************************** //****************************************************************************** HWND WIN32API CreateWindowExA(DWORD exStyle, LPCSTR className, LPCSTR windowName, DWORD style, INT x, INT y, INT width, INT height, HWND parent, HMENU menu, HINSTANCE instance, LPVOID data ) { Win32BaseWindow *window; ATOM classAtom; CREATESTRUCTA cs; char tmpClass[20]; __con_debug(2,"CreateWindowExA(width=%d,height=%d)\n",width,height); if(exStyle & WS_EX_MDICHILD) return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data); /* Find the class atom */ if (!(classAtom = GlobalFindAtomA(className))) { if (!HIWORD(className)) dprintf(("CreateWindowEx32A: bad class name %04x\n",LOWORD(className))); else dprintf(("CreateWindowEx32A: bad class name '%s'\n", className)); SetLastError(ERROR_INVALID_PARAMETER); return 0; } // if the pointer to the classname string has the high word cleared, // then it's not a pointer but a number for one of the builtin classes if (!HIWORD(className)) { sprintf(tmpClass,"#%d", (int) className); className = tmpClass; } /* Create the window */ cs.lpCreateParams = data; cs.hInstance = instance; cs.hMenu = menu; cs.hwndParent = parent; cs.x = x; cs.y = y; cs.cx = width; cs.cy = height; cs.style = style; cs.lpszName = windowName; cs.lpszClass = className; cs.dwExStyle = exStyle; HOOK_CallOdinHookA(HODIN_PREWINDOWCREATEDA, 0, (DWORD)&cs); if(HIWORD(className)) { dprintf(("CreateWindowExA: window %s class %s parent %x (%d,%d) (%d,%d), %x %x menu=%x", windowName, className, parent, x, y, width, height, style, exStyle, menu)); } else dprintf(("CreateWindowExA: window %s class %d parent %x (%d,%d) (%d,%d), %x %x menu=%x", windowName, className, parent, x, y, width, height, style, exStyle, menu)); if(!stricmp(className, MDICLIENTCLASSNAMEA)) { window = (Win32BaseWindow *) new Win32MDIClientWindow(&cs, classAtom, FALSE); } else if(!stricmp((char *) className, DIALOG_CLASS_NAMEA)) { DLG_TEMPLATE dlgTemplate = {0}; dlgTemplate.style = cs.style; dlgTemplate.exStyle = cs.dwExStyle; dlgTemplate.x = cs.x; dlgTemplate.y = cs.y; dlgTemplate.cx = cs.cx; dlgTemplate.cy = cs.cy; dlgTemplate.className = cs.lpszClass; dlgTemplate.caption = cs.lpszName; window = (Win32BaseWindow *) new Win32Dialog(cs.hInstance, (LPCSTR) &dlgTemplate, cs.hwndParent, NULL, (LPARAM) data, FALSE); } else { window = new Win32BaseWindow( &cs, classAtom, FALSE ); } if(window == NULL) { dprintf(("Win32BaseWindow creation failed!!")); return 0; } if(GetLastError() != 0) { dprintf(("Win32BaseWindow error found!!")); RELEASE_WNDOBJ(window); delete window; return 0; } HWND hwnd = window->getWindowHandle(); // set myself as last active popup / window window->setLastActive( hwnd ); RELEASE_WNDOBJ(window); return hwnd; } //****************************************************************************** //****************************************************************************** HWND WIN32API CreateWindowExW(DWORD exStyle, LPCWSTR className, LPCWSTR windowName, DWORD style, INT x, INT y, INT width, INT height, HWND parent, HMENU menu, HINSTANCE instance, LPVOID data ) { Win32BaseWindow *window; ATOM classAtom; CREATESTRUCTA cs; WCHAR tmpClassW[20]; if(exStyle & WS_EX_MDICHILD) return CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data); /* Find the class atom */ if (!(classAtom = GlobalFindAtomW(className))) { if (!HIWORD(className)) dprintf(("CreateWindowEx32W: bad class name %04x",LOWORD(className))); else dprintf(("CreateWindowEx32W: bad class name '%ls'", className)); SetLastError(ERROR_INVALID_PARAMETER); return 0; } #ifdef DEBUG if(HIWORD(className)) { dprintf(("CreateWindowExW: class %ls name %ls parent %x (%d,%d) (%d,%d), %x %x menu=%x", className, HIWORD(windowName) ? windowName : NULL, parent, x, y, width, height, style, exStyle, menu)); } else dprintf(("CreateWindowExW: class %d name %ls parent %x (%d,%d) (%d,%d), %x %x menu=%x", className, HIWORD(windowName) ? windowName : NULL, parent, x, y, width, height, style, exStyle, menu)); #endif // if the pointer to the classname string has the high word cleared, // then it's not a pointer but a number for one of the builtin classes if (!HIWORD(className)) { wsprintfW(tmpClassW, (LPCWSTR)L"#%d", (int) className); className = tmpClassW; } /* Create the window */ cs.lpCreateParams = data; cs.hInstance = instance; cs.hMenu = menu; cs.hwndParent = parent; cs.x = x; cs.y = y; cs.cx = width; cs.cy = height; cs.style = style; cs.lpszName = (LPSTR)windowName; cs.lpszClass = (LPSTR)className; cs.dwExStyle = exStyle; if(!lstrcmpiW(className, (LPWSTR)MDICLIENTCLASSNAMEW)) { window = (Win32BaseWindow *) new Win32MDIClientWindow(&cs, classAtom, TRUE); } else if(!lstrcmpiW(className, (LPWSTR)DIALOG_CLASS_NAMEW)) { DLG_TEMPLATE dlgTemplate = {0}; dlgTemplate.style = cs.style; dlgTemplate.exStyle = cs.dwExStyle; dlgTemplate.x = cs.x; dlgTemplate.y = cs.y; dlgTemplate.cx = cs.cx; dlgTemplate.cy = cs.cy; dlgTemplate.className = cs.lpszClass; dlgTemplate.caption = cs.lpszName; window = (Win32BaseWindow *) new Win32Dialog(cs.hInstance, (LPCSTR) &dlgTemplate, cs.hwndParent, NULL, (LPARAM) data, TRUE); } else { window = new Win32BaseWindow( &cs, classAtom, TRUE ); } if(window == NULL) { dprintf(("Win32BaseWindow creation failed!!")); return 0; } if(GetLastError() != 0) { dprintf(("Win32BaseWindow error found!!")); RELEASE_WNDOBJ(window); delete window; return 0; } HWND hwnd = window->getWindowHandle(); // set myself as last active popup / window window->setLastActive( hwnd ); RELEASE_WNDOBJ(window); return hwnd; } //****************************************************************************** //****************************************************************************** BOOL WIN32API DestroyWindow(HWND hwnd) { Win32BaseWindow *window; BOOL ret; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("DestroyWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } ret = window->DestroyWindow(); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** HWND WIN32API SetActiveWindow(HWND hwnd) { Win32BaseWindow *window; HWND hwndActive; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetActiveWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } hwndActive = window->SetActiveWindow(); // check last active popup window if (hwndActive) { // TODO: // set last active popup window to the ancestor window dprintf(("support for last active popup incorrectly implemented")); } RELEASE_WNDOBJ(window); return hwndActive; } //****************************************************************************** //Note: does not set last error if no parent (verified in NT4, SP6) //****************************************************************************** HWND WIN32API GetParent(HWND hwnd) { Win32BaseWindow *window; HWND hwndParent; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetParent, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf2(("GetParent %x", hwnd)); hwndParent = window->GetParent(); RELEASE_WNDOBJ(window); return hwndParent; } //****************************************************************************** //****************************************************************************** HWND WIN32API SetParent(HWND hwndChild, HWND hwndNewParent) { Win32BaseWindow *window; HWND hwndOldParent; window = Win32BaseWindow::GetWindowFromHandle(hwndChild); if(!window) { dprintf(("SetParent, window %x not found", hwndChild)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } if(hwndNewParent == HWND_DESKTOP) { hwndNewParent = GetDesktopWindow(); } else { if(!IsWindow(hwndNewParent)) { RELEASE_WNDOBJ(window); dprintf(("SetParent, parent %x not found", hwndNewParent)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } } dprintf(("SetParent %x %x", hwndChild, hwndNewParent)); hwndOldParent = window->SetParent(hwndNewParent); RELEASE_WNDOBJ(window); return hwndOldParent; } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsChild(HWND hwndParent, HWND hwnd) { Win32BaseWindow *window; BOOL fIsChild; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("IsChild %x, window %x not found", hwndParent, hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("IsChild %x %x", hwndParent, hwnd)); fIsChild = window->IsChild(hwndParent); RELEASE_WNDOBJ(window); return fIsChild; } //****************************************************************************** //****************************************************************************** HWND WIN32API GetTopWindow(HWND hwnd) { Win32BaseWindow *window; HWND hwndTop; if(hwnd == HWND_DESKTOP) { windowDesktop->addRef(); window = windowDesktop; } else { window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetTopWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } } hwndTop = window->GetTopWindow(); dprintf2(("GetTopWindow %x returned %x", hwnd, hwndTop)); RELEASE_WNDOBJ(window); return hwndTop; } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsIconic(HWND hwnd) { Win32BaseWindow *window; BOOL fIsIconic; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("IsIconic, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } fIsIconic = window->IsWindowIconic(); dprintf(("IsIconic %x returned %d", hwnd, fIsIconic)); RELEASE_WNDOBJ(window); return fIsIconic; } //****************************************************************************** //****************************************************************************** HWND WIN32API GetWindow(HWND hwnd, UINT uCmd) { Win32BaseWindow *window; HWND hwndRelated; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } hwndRelated = window->GetWindow(uCmd); RELEASE_WNDOBJ(window); return hwndRelated; } /****************************************************************************** * GetWindowInfo (USER32.@) * * Note: tests show that Windows doesn't check cbSize of the structure. */ BOOL WINAPI GetWindowInfo( HWND hwnd, PWINDOWINFO pwi) { if (!pwi) return FALSE; if (!IsWindow(hwnd)) return FALSE; GetWindowRect(hwnd, &pwi->rcWindow); GetClientRect(hwnd, &pwi->rcClient); /* translate to screen coordinates */ MapWindowPoints(hwnd, 0, (LPPOINT)&pwi->rcClient, 2); pwi->dwStyle = GetWindowLongW(hwnd, GWL_STYLE); pwi->dwExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE); pwi->dwWindowStatus = ((GetActiveWindow() == hwnd) ? WS_ACTIVECAPTION : 0); pwi->cxWindowBorders = pwi->rcClient.left - pwi->rcWindow.left; pwi->cyWindowBorders = pwi->rcWindow.bottom - pwi->rcClient.bottom; pwi->atomWindowType = GetClassLongW( hwnd, GCW_ATOM ); pwi->wCreatorVersion = 0x0400; return TRUE; } /***************************************************************************** * UpdateLayeredWindow (USER32.@) */ BOOL WIN32API UpdateLayeredWindow(HWND hwnd, HDC hdcDst, POINT *pptDst,SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags) { dprintf(("USER32: UpdateLayeredWindow(%08xh, %08xh, %08xh, %08xh, %08xh, " "%08xh, %08xh, %08xh, %08xh) not implemented\n", hwnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags)); return FALSE; } //****************************************************************************** //****************************************************************************** BOOL WIN32API EnableWindow(HWND hwnd, BOOL fEnable) { Win32BaseWindow *window; BOOL fEnabled; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("EnableWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("EnableWindow %x %d", hwnd, fEnable)); fEnabled = window->EnableWindow(fEnable); RELEASE_WNDOBJ(window); return fEnabled; } //****************************************************************************** //****************************************************************************** BOOL WIN32API BringWindowToTop(HWND hwnd) { dprintf(("BringWindowToTop %x", hwnd)); return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); } /*********************************************************************** * SetInternalWindowPos (USER32.483) */ VOID WIN32API SetInternalWindowPos(HWND hwnd, UINT showCmd, LPRECT lpRect, LPPOINT lpPoint ) { if( IsWindow(hwnd) ) { WINDOWPLACEMENT wndpl; UINT flags; GetWindowPlacement(hwnd, &wndpl); wndpl.length = sizeof(wndpl); wndpl.showCmd = showCmd; wndpl.flags = 0; if(lpPoint) { wndpl.flags |= WPF_SETMINPOSITION; wndpl.ptMinPosition = *lpPoint; } if(lpRect) { wndpl.rcNormalPosition = *lpRect; } SetWindowPlacement(hwnd, &wndpl); } } /*********************************************************************** * GetInternalWindowPos (USER32.245) */ UINT WIN32API GetInternalWindowPos(HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon ) { WINDOWPLACEMENT wndpl; if(GetWindowPlacement( hwnd, &wndpl )) { if (rectWnd) *rectWnd = wndpl.rcNormalPosition; if (ptIcon) *ptIcon = wndpl.ptMinPosition; return wndpl.showCmd; } return 0; } //****************************************************************************** //****************************************************************************** HWND GetActiveWindow() { return Win32BaseWindow::GetActiveWindow(); } //****************************************************************************** //****************************************************************************** BOOL WIN32API ShowWindow(HWND hwnd, INT nCmdShow) { Win32BaseWindow *window; BOOL ret; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("ShowWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } //PF Start PM restoration routine first if we restore from icon //so all internal PM logic will work - this routine will always //lead to ShowWindow(SW_RESTORE) if ((nCmdShow == SW_RESTORE) && (window->getStyle() & WS_MINIMIZE) && fOS2Look ) { dprintf(("ShowWindow: Initiating OS/2 PM restore")); ret = OSLibWinRestoreWindow(window->getOS2FrameWindowHandle()); } else ret = window->ShowWindow(nCmdShow); RELEASE_WNDOBJ(window); return ret; } /***************************************************************************** * Name : BOOL WIN32API ShowWindowAsync * Purpose : The ShowWindowAsync function sets the show state of a window * created by a different thread. * Parameters: HWND hwnd handle of window * int nCmdShow show state of window * Variables : * Result : If the window was previously visible, the return value is TRUE. * If the window was previously hidden, the return value is FALSE. * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Thu, 1998/02/26 11:55] *****************************************************************************/ BOOL WIN32API ShowWindowAsync(HWND hwnd, int nCmdShow) { dprintf(("USER32:ShowWindowAsync (%08xh,%08x) not correctly implemented.\n", hwnd, nCmdShow)); return ShowWindow(hwnd, nCmdShow); } //****************************************************************************** //****************************************************************************** BOOL WIN32API SetWindowPos(HWND hwnd, HWND hwndInsertAfter, INT x, INT y, INT cx, INT cy, UINT fuFlags) { Win32BaseWindow *window; if (!hwnd) { dprintf(("SetWindowPos: Can't move desktop!")); return TRUE; } window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetWindowPos, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } dprintf(("SetWindowPos %x %x x=%d y=%d cx=%d cy=%d %x", hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags)); BOOL ret = window->SetWindowPos(hwndInsertAfter, x, y, cx, cy, fuFlags); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //NOTE: length must equal structure size or else api fails (verified in NT4, SP6) //****************************************************************************** BOOL WIN32API SetWindowPlacement(HWND hwnd, const WINDOWPLACEMENT *winpos) { Win32BaseWindow *window; if(!winpos || winpos->length != sizeof(WINDOWPLACEMENT)) { dprintf(("SetWindowPlacement %x invalid parameter", hwnd)); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetWindowPlacement, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } dprintf(("USER32: SetWindowPlacement %x %x", hwnd, winpos)); BOOL ret = window->SetWindowPlacement((WINDOWPLACEMENT *)winpos); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //NOTE: Length does not need to be correct (even though the SDK docs claim otherwise) // (Verified in NT4, SP6) //****************************************************************************** BOOL WIN32API GetWindowPlacement(HWND hwnd, LPWINDOWPLACEMENT winpos) { Win32BaseWindow *window; if(!winpos) { dprintf(("GetWindowPlacement %x invalid parameter", hwnd)); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowPlacement, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } dprintf(("USER32: GetWindowPlacement %x %x", hwnd, winpos)); BOOL ret = window->GetWindowPlacement(winpos); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsWindow(HWND hwnd) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("IsWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } dprintf2(("IsWindow %x", hwnd)); BOOL fIsWindow = window->IsWindow(); RELEASE_WNDOBJ(window); return fIsWindow; } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsWindowEnabled(HWND hwnd) { DWORD dwStyle; if(!IsWindow(hwnd)) { dprintf(("IsWindowEnabled, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("IsWindowEnabled %x", hwnd)); dwStyle = GetWindowLongA(hwnd, GWL_STYLE); if(dwStyle & WS_DISABLED) { return FALSE; } return TRUE; } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsWindowVisible(HWND hwnd) { BOOL ret; HWND hwndParent; DWORD dwStyle; if(hwnd == HWND_DESKTOP) {//TODO: verify in NT! dprintf(("IsWindowVisible DESKTOP returned TRUE")); return TRUE; //desktop is always visible } if(!IsWindow(hwnd)) { dprintf(("IsWindowVisible, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } //check visibility of this window dwStyle = GetWindowLongA(hwnd, GWL_STYLE); if(!(dwStyle & WS_VISIBLE)) { ret = FALSE; goto end; } ret = TRUE; if(dwStyle & WS_CHILD) { //check visibility of parents hwndParent = GetParent(hwnd); while(hwndParent) { dwStyle = GetWindowLongA(hwndParent, GWL_STYLE); if(!(dwStyle & WS_VISIBLE)) { dprintf(("IsWindowVisible %x returned FALSE (parent %x invisible)", hwnd, hwndParent)); return FALSE; } if(!(dwStyle & WS_CHILD)) { break; //GetParent can also return the owner } hwndParent = GetParent(hwndParent); } } end: dprintf(("IsWindowVisible %x returned %d", hwnd, ret)); return ret; } //****************************************************************************** //****************************************************************************** HWND WINAPI GetAncestor( HWND hwnd, UINT type ) { HWND hwndAncestor = 0; Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetAncestor, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } if (type == GA_PARENT) { LONG dwStyle = GetWindowLongW( hwnd, GWL_STYLE ); if(dwStyle & WS_CHILD) { hwndAncestor = GetParent(hwnd); } //else no child -> no parent (GetParent returns owner otherwise!) } else if (type == GA_ROOT) { hwndAncestor = window->GetTopParent(); } else if (type == GA_ROOTOWNER) { if(hwnd != GetDesktopWindow()) { hwndAncestor = hwnd; for(;;) { HWND parent = GetParent( hwndAncestor ); if (!parent) break; hwndAncestor = parent; } } } else dprintf(("Unsupported type %d", type)); RELEASE_WNDOBJ(window); return hwndAncestor; } //****************************************************************************** BOOL fIgnoreKeystrokes = FALSE; //****************************************************************************** void SetFocusChanged() { //Focus has changed; invalidate SetFocus(0) state fIgnoreKeystrokes = FALSE; } //****************************************************************************** //****************************************************************************** HWND WIN32API SetFocus(HWND hwnd) { Win32BaseWindow *window; Win32BaseWindow *oldfocuswnd; HWND lastFocus, lastFocus_W, hwnd_O, hwndTopParent, hwndTop; BOOL activate, ret; TEB *teb; dprintf(("SetFocus %x", hwnd)); teb = GetThreadTEB(); if(teb == NULL) { DebugInt3(); return 0; } //Special case; SetFocus(0) tells Windows to ignore keystrokes. Pressing //a key now generates WM_SYSKEYDOWN/(WM_SYSCHAR)/WM_SYSKEYUP instead //of WM_KEYDOWN/(WM_CHAR)/WM_KEYUP //WM_KILLFOCUS is sent to the window that currently has focus if(hwnd == 0) { lastFocus_W = GetFocus(); if(lastFocus_W == 0) return 0; //nothing to do if(HOOK_CallHooksA(WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)lastFocus_W)) { dprintf(("hook cancelled SetFocus call!")); return 0; } fIgnoreKeystrokes = TRUE; SendMessageA(lastFocus_W, WM_KILLFOCUS, 0, 0); return lastFocus_W; } //SetFocus is not allowed for minimized or disabled windows (this window //or any parent) hwndTop = hwnd; for (;;) { HWND parent; LONG style = GetWindowLongW( hwndTop, GWL_STYLE ); if (style & (WS_MINIMIZE | WS_DISABLED)) { dprintf(("SetFocus, %x not allowed on minimized or disabled window (%x)", hwnd, style)); return 0; } parent = GetAncestor(hwndTop, GA_PARENT); if (!parent || parent == GetDesktopWindow()) break; hwndTop = parent; } window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetFocus, window %x not found", hwnd)); //Note: last error not set (NT4, SP6), returns current focus window //SetLastError(ERROR_INVALID_WINDOW_HANDLE); return GetFocus(); } hwnd_O = window->getOS2WindowHandle(); lastFocus = OSLibWinQueryFocus (OSLIB_HWND_DESKTOP); hwndTopParent = window->GetTopParent(); activate = FALSE; lastFocus_W = OS2ToWin32Handle(lastFocus); if(lastFocus_W) { oldfocuswnd = Win32BaseWindow::GetWindowFromHandle(lastFocus_W); if(lastFocus_W != hwnd && hwndTopParent != oldfocuswnd->GetTopParent()) { activate = TRUE; } RELEASE_WNDOBJ(oldfocuswnd); } else activate = TRUE; dprintf(("SetFocus %x (%x) -> %x (%x) act %d", lastFocus_W, lastFocus, hwnd, hwnd_O, activate)); if(HOOK_CallHooksA(WH_CBT, HCBT_SETFOCUS, hwnd, (LPARAM)lastFocus_W)) { dprintf(("hook cancelled SetFocus call!")); RELEASE_WNDOBJ(window); return 0; } if(!IsWindow(hwnd)) return FALSE; //abort if window destroyed //NOTE: Don't always activate the window or else the z-order will be changed!! ret = (OSLibWinSetFocus(OSLIB_HWND_DESKTOP, hwnd_O, activate)) ? lastFocus_W : 0; RELEASE_WNDOBJ(window); //If keystrokes were ignored and focus is set to the old focus window, then //PM won't send us a WM_SETFOCUS message. (as we don't inform PM for SetFocus(0)) if(fIgnoreKeystrokes && lastFocus_W == hwnd) { dprintf(("Manually send WM_SETFOCUS; real focus window hasn't changed")); SendMessageA(lastFocus_W, WM_SETFOCUS, 0, 0); } fIgnoreKeystrokes = FALSE; return ret; } //****************************************************************************** //****************************************************************************** HWND WIN32API GetFocus() { TEB *teb; HWND hwnd; teb = GetThreadTEB(); if(teb == NULL) { DebugInt3(); return 0; } //If keystrokes are ignored (SetFocus(0)), then return 0 if(fIgnoreKeystrokes) { dprintf(("GetFocus; returning 0 after SetFocus(0) call")); return 0; } hwnd = OSLibWinQueryFocus(OSLIB_HWND_DESKTOP); hwnd = OS2ToWin32Handle(hwnd); dprintf(("USER32: GetFocus %x\n", hwnd)); return hwnd; } //****************************************************************************** //****************************************************************************** BOOL WIN32API GetGUIThreadInfo(DWORD dwThreadId, GUITHREADINFO *lpThreadInfo) { dprintf(("!WARNING!: GetGUIThreadInfo not completely implemented!!")); if(!lpThreadInfo || lpThreadInfo->cbSize != sizeof(GUITHREADINFO)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } //dwThreadId == 0 -> current thread if(!dwThreadId) dwThreadId = GetCurrentThreadId(); lpThreadInfo->flags; lpThreadInfo->hwndActive = GetActiveWindow(); if(lpThreadInfo->hwndActive) { if(dwThreadId != GetWindowThreadProcessId(lpThreadInfo->hwndActive, NULL)) {//this thread doesn't own the active window (TODO: correct??) lpThreadInfo->hwndActive = 0; } } lpThreadInfo->hwndFocus = GetFocus(); lpThreadInfo->hwndCapture = GetCapture(); lpThreadInfo->flags = 0; //TODO: lpThreadInfo->hwndMenuOwner = 0; //TODO: Handle to the window that owns any active menus lpThreadInfo->hwndMoveSize = 0; //TODO: Handle to the window in a move or size loop. lpThreadInfo->hwndCaret = 0; //TODO: Handle to the window that is displaying the caret lpThreadInfo->rcCaret.left = 0; lpThreadInfo->rcCaret.top = 0; lpThreadInfo->rcCaret.right = 0; lpThreadInfo->rcCaret.bottom = 0; SetLastError(ERROR_SUCCESS); return TRUE; } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsZoomed(HWND hwnd) { DWORD style; style = GetWindowLongA(hwnd, GWL_STYLE); dprintf(("USER32: IsZoomed %x returned %d", hwnd, ((style & WS_MAXIMIZE) != 0))); return (style & WS_MAXIMIZE) != 0; } //****************************************************************************** //****************************************************************************** BOOL WIN32API LockWindowUpdate(HWND hwnd) { return OSLibWinLockWindowUpdate(Win32ToOS2Handle(hwnd)); } //****************************************************************************** //****************************************************************************** BOOL WIN32API GetWindowRect(HWND hwnd, PRECT pRect) { Win32BaseWindow *window; if(pRect == NULL) { dprintf(("GetWindowRect %x invalid parameter!", hwnd)); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if(hwnd == HWND_DESKTOP) { windowDesktop->addRef(); window = windowDesktop; } else window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowRect, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } *pRect = *window->getWindowRect(); //convert from parent coordinates to screen (if necessary) if(window->getParent()) { MapWindowPoints(window->getParent()->getWindowHandle(), 0, (PPOINT)pRect, 2); } RELEASE_WNDOBJ(window); dprintf(("GetWindowRect %x (%d,%d) (%d,%d)", hwnd, pRect->left, pRect->top, pRect->right, pRect->bottom)); return TRUE; } //****************************************************************************** //****************************************************************************** INT WIN32API GetWindowTextLengthA(HWND hwnd) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowTextLengthA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("GetWindowTextLengthA %x", hwnd)); int ret = window->GetWindowTextLengthA(); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** int WIN32API GetWindowTextA( HWND hwnd, LPSTR lpsz, int cch) { Win32BaseWindow *window; int rc; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowTextA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } rc = window->GetWindowTextA(lpsz, cch); dprintf(("GetWindowTextA %x %s", hwnd, lpsz)); RELEASE_WNDOBJ(window); return rc; } //****************************************************************************** //****************************************************************************** int WIN32API GetWindowTextLengthW( HWND hwnd) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowTextLengthW, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("GetWindowTextLengthW %x", hwnd)); int ret = window->GetWindowTextLengthW(); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** int WIN32API GetWindowTextW(HWND hwnd, LPWSTR lpsz, int cch) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowTextW, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } int rc = window->GetWindowTextW(lpsz, cch); RELEASE_WNDOBJ(window); dprintf(("GetWindowTextW %x %ls", hwnd, lpsz)); return rc; } //****************************************************************************** //****************************************************************************** BOOL WIN32API SetWindowTextA(HWND hwnd, LPCSTR lpsz) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetWindowTextA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("SetWindowTextA %x %s", hwnd, lpsz)); BOOL ret = window->SetWindowTextA((LPSTR)lpsz); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** BOOL WIN32API SetWindowTextW( HWND hwnd, LPCWSTR lpsz) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetWindowTextA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("SetWindowTextW %x %ls", hwnd, lpsz)); BOOL ret = window->SetWindowTextW((LPWSTR)lpsz); RELEASE_WNDOBJ(window); return ret; } /******************************************************************* * InternalGetWindowText (USER32.326) */ int WIN32API InternalGetWindowText(HWND hwnd, LPWSTR lpString, INT nMaxCount ) { dprintf(("USER32: InternalGetWindowText(%08xh,%08xh,%08xh) not properly implemented.\n", hwnd, lpString, nMaxCount)); return GetWindowTextW(hwnd, lpString,nMaxCount); } //****************************************************************************** //TODO: Correct? //****************************************************************************** BOOL WIN32API SetForegroundWindow(HWND hwnd) { dprintf((" SetForegroundWindow %x", hwnd)); return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } //****************************************************************************** //****************************************************************************** BOOL WIN32API GetClientRect( HWND hwnd, PRECT pRect) { HWND hwndWin32 = hwnd; Win32BaseWindow *window; if (!pRect) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetClientRect, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } window->getClientRect(pRect); dprintf(("GetClientRect of %X returned (%d,%d) (%d,%d)\n", hwndWin32, pRect->left, pRect->top, pRect->right, pRect->bottom)); RELEASE_WNDOBJ(window); return TRUE; } //****************************************************************************** //****************************************************************************** BOOL WIN32API AdjustWindowRect(PRECT rect, DWORD style, BOOL menu) { return AdjustWindowRectEx(rect, style, menu, 0); } //****************************************************************************** //Calculate window rectangle based on given client rectangle, style, menu and extended style //****************************************************************************** BOOL WIN32API AdjustWindowRectEx( PRECT rect, DWORD style, BOOL menu, DWORD exStyle) { if(style == 0 && menu == FALSE && exStyle == 0) { dprintf(("AdjustWindowRectEx %x %x %d (%d,%d)(%d,%d) -> no change required", style, exStyle, menu, rect->left, rect->top, rect->right, rect->bottom)); return TRUE; //nothing needs to be changed (VERIFIED in NT 4) } dprintf(("AdjustWindowRectEx %x %x %d (%d,%d)(%d,%d)\n", style, exStyle, menu, rect->left, rect->top, rect->right, rect->bottom)); /* Correct the window style */ if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */ style |= WS_CAPTION; //SvL: Include WS_POPUP -> otherwise HAS_THINFRAME is true for popup windows // Also include WS_CHILD -> otherwise HAS_THICKFRAME doesn't work correctly style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_POPUP); exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_TOOLWINDOW); if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME; //Adjust rect outer (Win32BaseWindow::AdjustRectOuter) if (HAS_THICKFRAME(style,exStyle)) InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) ); else if (HAS_DLGFRAME(style,exStyle)) InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) ); else if (HAS_THINFRAME(style)) InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER)); if ((style & WS_CAPTION) == WS_CAPTION) { if (exStyle & WS_EX_TOOLWINDOW) rect->top -= GetSystemMetrics(SM_CYSMCAPTION); else rect->top -= GetSystemMetrics(SM_CYCAPTION); } if (menu) rect->top -= GetSystemMetrics(SM_CYMENU); //Adjust rect inner (Win32BaseWindow::AdjustRectInner) if(!(style & WS_ICONIC)) { if (exStyle & WS_EX_CLIENTEDGE) InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); if (exStyle & WS_EX_STATICEDGE) InflateRect (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER)); //SvL: scrollbars aren't checked *UNLESS* the style includes a border (any border) // --> VERIFIED IN NT4, SP6 (fixes MFC apps with scrollbars + bar controls) if(style & (WS_THICKFRAME|WS_BORDER|WS_DLGFRAME)) { if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL); if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL); } } dprintf(("AdjustWindowRectEx returned (%d,%d)(%d,%d)\n", rect->left, rect->top, rect->right, rect->bottom)); return TRUE; } //****************************************************************************** /* Coordinate Space and Transformation Functions */ //****************************************************************************** /******************************************************************* * WINPOS_GetWinOffset * * Calculate the offset between the origin of the two windows. Used * to implement MapWindowPoints. */ static void WINPOS_GetWinOffset( Win32BaseWindow *wndFrom, Win32BaseWindow *wndTo, POINT *offset ) { Win32BaseWindow *window; offset->x = offset->y = 0; /* Translate source window origin to screen coords */ if(wndFrom != windowDesktop) { window = wndFrom; while(window) { offset->x += window->getClientRectPtr()->left + window->getWindowRect()->left; offset->y += window->getClientRectPtr()->top + window->getWindowRect()->top; window = window->getParent(); } } /* Translate origin to destination window coords */ if(wndTo != windowDesktop) { window = wndTo; while(window) { offset->x -= window->getClientRectPtr()->left + window->getWindowRect()->left; offset->y -= window->getClientRectPtr()->top + window->getWindowRect()->top; window = window->getParent(); } } } //****************************************************************************** //****************************************************************************** int WIN32API MapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lpPoints, UINT cPoints) { Win32BaseWindow *wndfrom, *wndto; int retval = 0; POINT offset; SetLastError(0); if(lpPoints == NULL || cPoints == 0) { dprintf(("MapWindowPoints error: lpPoints %p, cPoints %d", lpPoints, cPoints)); SetLastError(ERROR_INVALID_PARAMETER); return 0; } if(hwndTo == hwndFrom) return 0; //nothing to do if(hwndFrom == HWND_DESKTOP) { windowDesktop->addRef(); wndfrom = windowDesktop; } else { wndfrom = Win32BaseWindow::GetWindowFromHandle(hwndFrom); if(!wndfrom) { dprintf(("MapWindowPoints, window %x not found", hwndFrom)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } } if(hwndTo == HWND_DESKTOP) { windowDesktop->addRef(); wndto = windowDesktop; } else { wndto = Win32BaseWindow::GetWindowFromHandle(hwndTo); if(!wndto) { dprintf(("MapWindowPoints, window %x not found", hwndTo)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } } dprintf2(("USER32: MapWindowPoints %x to %x (%d,%d) (%d)", hwndFrom, hwndTo, lpPoints->x, lpPoints->y, cPoints)); WINPOS_GetWinOffset(wndfrom, wndto, &offset); RELEASE_WNDOBJ(wndto); RELEASE_WNDOBJ(wndfrom); for(int i=0;i (%d,%d)", hwnd, tmp.x, tmp.y, pt->x, pt->y)); return TRUE; } //****************************************************************************** //****************************************************************************** HWND WIN32API GetDesktopWindow(void) { HWND hDesktopWindow = windowDesktop->getWindowHandle(); dprintf2(("USER32: GetDesktopWindow, returned %x\n", hDesktopWindow)); return hDesktopWindow; } //****************************************************************************** //****************************************************************************** HWND WIN32API FindWindowA(LPCSTR lpszClass, LPCSTR lpszWindow) { return FindWindowExA( NULL, NULL, lpszClass, lpszWindow ); } //****************************************************************************** //****************************************************************************** HWND WIN32API FindWindowW( LPCWSTR lpClassName, LPCWSTR lpWindowName) { return FindWindowExW( NULL, NULL, lpClassName, lpWindowName ); } //****************************************************************************** //****************************************************************************** HWND WIN32API FindWindowExA(HWND hwndParent, HWND hwndChildAfter, LPCSTR lpszClass, LPCSTR lpszWindow) { ATOM atom = 0; if (lpszClass) { /* If the atom doesn't exist, then no class */ /* with this name exists either. */ if (!(atom = GlobalFindAtomA( lpszClass ))) { SetLastError(ERROR_CANNOT_FIND_WND_CLASS); return 0; } } return Win32BaseWindow::FindWindowEx(hwndParent, hwndChildAfter, atom, (LPSTR)lpszWindow); } /***************************************************************************** * Name : HWND WIN32API FindWindowExW * Purpose : The FindWindowEx function retrieves the handle of a window whose * class name and window name match the specified strings. The * function searches child windows, beginning with the one following * the given child window. * Parameters: HWND hwndParent handle of parent window * HWND hwndChildAfter handle of a child window * LPCTSTR lpszClass address of class name * LPCTSTR lpszWindow address of window name * Variables : * Result : If the function succeeds, the return value is the handle of the * window that has the specified class and window names. * If the function fails, the return value is NULL. To get extended * error information, call GetLastError. * Remark : * *****************************************************************************/ HWND WIN32API FindWindowExW(HWND hwndParent, HWND hwndChildAfter, LPCWSTR lpszClass, LPCWSTR lpszWindow) { ATOM atom = 0; char *buffer; HWND hwnd; if (lpszClass) { /* If the atom doesn't exist, then no class */ /* with this name exists either. */ if (!(atom = GlobalFindAtomW( lpszClass ))) { SetLastError(ERROR_CANNOT_FIND_WND_CLASS); return 0; } } buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszWindow ); hwnd = Win32BaseWindow::FindWindowEx(hwndParent, hwndChildAfter, atom, buffer); HeapFree( GetProcessHeap(), 0, buffer ); return hwnd; } //****************************************************************************** //****************************************************************************** BOOL WIN32API FlashWindow(HWND hwnd, BOOL fFlash) { dprintf(("FlashWindow %x %d\n", hwnd, fFlash)); // return OSLibWinFlashWindow(Win32ToOS2Handle(hwnd), fFlash); return 1; } //****************************************************************************** //****************************************************************************** BOOL WIN32API FlashWindowEx( PFLASHWINFO pfwi) { dprintf(("FlashWindow %p %d\n", pfwi)); return 1; } //****************************************************************************** //****************************************************************************** BOOL WIN32API MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ) { int flags = SWP_NOZORDER | SWP_NOACTIVATE; if (!repaint) flags |= SWP_NOREDRAW; dprintf(("MoveWindow: %x %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint )); return SetWindowPos( hwnd, 0, x, y, cx, cy, flags ); } //****************************************************************************** //****************************************************************************** BOOL WIN32API ClientToScreen (HWND hwnd, PPOINT pt) { PRECT rcl; if(hwnd == HWND_DESKTOP) { return(TRUE); //nothing to do } if(!IsWindow(hwnd)) { dprintf(("warning: ClientToScreen window %x not found!", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return (FALSE); } #ifdef DEBUG POINT tmp = *pt; #endif MapWindowPoints(hwnd, 0, pt, 1); dprintf2(("ClientToScreen %x (%d,%d) -> (%d,%d)", hwnd, tmp.x, tmp.y, pt->x, pt->y)); return TRUE; } //****************************************************************************** //Note: count 0 is a legal parameter (verified in NT4) //****************************************************************************** HDWP WIN32API BeginDeferWindowPos(int count) { HDWP handle; DWP *pDWP; if (count < 0) { dprintf(("USER32: BeginDeferWindowPos invalid param %d", count)); SetLastError(ERROR_INVALID_PARAMETER); return 0; } dprintf(("USER32: BeginDeferWindowPos %d", count)); if(count == 0) count = 8; // change to any non-zero value handle = (HDWP)HeapAlloc(GetProcessHeap(), 0, sizeof(DWP) + (count-1)*sizeof(WINDOWPOS)); if (!handle) return 0; pDWP = (DWP *) handle; pDWP->actualCount = 0; pDWP->suggestedCount = count; pDWP->valid = TRUE; pDWP->wMagic = DWP_MAGIC; pDWP->hwndParent = 0; return handle; } /*********************************************************************** * DeferWindowPos (USER32.128) * * TODO: SvL: Does this need to be thread safe? * */ HDWP WIN32API DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter, INT x, INT y, INT cx, INT cy, UINT flags ) { DWP *pDWP; int i; HDWP newhdwp = hdwp,retvalue; pDWP = (DWP *)hdwp; if (!pDWP) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if (hwnd == GetDesktopWindow()) return 0; if(!IsWindow(hwnd)) { dprintf(("DeferWindowPos, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); HeapFree(GetProcessHeap(), 0, (LPVOID)hdwp); return 0; } dprintf(("USER32: DeferWindowPos hdwp %x hwnd %x hwndAfter %x (%d,%d)(%d,%d) %x", hdwp, hwnd, hwndAfter, x, y, cx, cy, flags)); /* Numega Bounds Checker Demo dislikes the following code. In fact, I've not been able to find any "same parent" requirement in any docu [AM 980509] */ #if 0 /* All the windows of a DeferWindowPos() must have the same parent */ parent = pWnd->parent->hwndSelf; if (pDWP->actualCount == 0) pDWP->hwndParent = parent; else if (parent != pDWP->hwndParent) { USER_HEAP_FREE( hdwp ); retvalue = 0; goto END; } #endif for (i = 0; i < pDWP->actualCount; i++) { if (pDWP->winPos[i].hwnd == hwnd) { /* Merge with the other changes */ if (!(flags & SWP_NOZORDER)) { pDWP->winPos[i].hwndInsertAfter = hwndAfter; } if (!(flags & SWP_NOMOVE)) { pDWP->winPos[i].x = x; pDWP->winPos[i].y = y; } if (!(flags & SWP_NOSIZE)) { pDWP->winPos[i].cx = cx; pDWP->winPos[i].cy = cy; } pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOCOPYBITS| SWP_NOOWNERZORDER); pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_FRAMECHANGED); retvalue = hdwp; goto END; } } if (pDWP->actualCount >= pDWP->suggestedCount) { //DWP structure already contains WINDOWPOS, allocated with (count-1) //in BeginDeferWindowPos; pDWP->suggestedCount alloc increases it by one newhdwp = (HDWP)HeapReAlloc(GetProcessHeap(), 0, (LPVOID)hdwp, sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS)); if (!newhdwp) { retvalue = 0; goto END; } pDWP = (DWP *) newhdwp; pDWP->suggestedCount++; } pDWP->winPos[pDWP->actualCount].hwnd = hwnd; pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter; pDWP->winPos[pDWP->actualCount].x = x; pDWP->winPos[pDWP->actualCount].y = y; pDWP->winPos[pDWP->actualCount].cx = cx; pDWP->winPos[pDWP->actualCount].cy = cy; pDWP->winPos[pDWP->actualCount].flags = flags; pDWP->actualCount++; retvalue = newhdwp; END: return retvalue; } //****************************************************************************** //****************************************************************************** BOOL WIN32API EndDeferWindowPos( HDWP hdwp) { DWP *pDWP; WINDOWPOS *winpos; BOOL res = TRUE; int i; pDWP = (DWP *) hdwp; if (!pDWP) { dprintf(("**EndDeferWindowPos invalid parameter\n")); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } dprintf(("**EndDeferWindowPos for %d windows", pDWP->actualCount)); for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++) { dprintf(("**EndDeferWindowPos %x (%d,%d) (%d,%d) %x", winpos->hwnd, winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags)); if (!(res = SetWindowPos(winpos->hwnd, winpos->hwndInsertAfter, winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags ))) break; } dprintf(("**EndDeferWindowPos DONE")); HeapFree(GetProcessHeap(), 0, (LPVOID)hdwp); return res; } //****************************************************************************** //****************************************************************************** HWND WIN32API ChildWindowFromPoint( HWND hwnd, POINT pt) { dprintf(("USER32: ChildWindowFromPoint\n")); return ChildWindowFromPointEx(hwnd, pt, 0); } /***************************************************************************** * Name : HWND WIN32API ChildWindowFromPointEx * Purpose : pt: client coordinates * Parameters: * Variables : * Result : If the function succeeds, the return value is the window handle. * If the function fails, the return value is zero * Remark : * Status : COMPLETELY IMPLEMENTED AND TESTED * * Author : Rene Pronk [Sun, 1999/08/08 23:30] *****************************************************************************/ HWND WIN32API ChildWindowFromPointEx (HWND hwndParent, POINT pt, UINT uFlags) { RECT rect; HWND hWnd; dprintf(("ChildWindowFromPointEx(%08xh,%08xh,%08xh).\n", hwndParent, pt, uFlags)); if (GetWindowRect (hwndParent, &rect) == 0) { // oops, invalid handle SetLastError(ERROR_INVALID_WINDOW_HANDLE); return NULL; } ClientToScreen(hwndParent, &pt); if (PtInRect (&rect, pt) == 0) { // point is outside window return NULL; } // get first child hWnd = GetWindow (hwndParent, GW_CHILD); while (hWnd != NULL) { // do I need to skip this window? if (((uFlags & CWP_SKIPINVISIBLE) && (IsWindowVisible (hWnd) == FALSE)) || ((uFlags & CWP_SKIPDISABLED) && (IsWindowEnabled (hWnd) == FALSE)) || ((uFlags & CWP_SKIPTRANSPARENT) && (GetWindowLongA (hWnd, GWL_EXSTYLE) & WS_EX_TRANSPARENT))) { hWnd = GetWindow (hWnd, GW_HWNDNEXT); continue; } // is the point in this window's rect? GetWindowRect (hWnd, &rect); if (PtInRect (&rect,pt) == FALSE) { hWnd = GetWindow (hWnd, GW_HWNDNEXT); continue; } dprintf(("ChildWindowFromPointEx returned %x", hWnd)); // found it! return hWnd; } // the point is in the parentwindow but the parentwindow has no child // at this coordinate dprintf(("ChildWindowFromPointEx returned parent %x", hwndParent)); return hwndParent; } //****************************************************************************** //****************************************************************************** BOOL WIN32API CloseWindow(HWND hwnd) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("CloseWindow, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("CloseWindow %x\n", hwnd)); BOOL ret = window->CloseWindow(); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** static BOOL IsPointInWindow(HWND hwnd, POINT point) { RECT rectWindow; DWORD hittest, dwStyle, dwExStyle; dwStyle = GetWindowLongA(hwnd, GWL_STYLE); dwExStyle = GetWindowLongA(hwnd, GWL_EXSTYLE); GetWindowRect(hwnd, &rectWindow); /* If point is in window, and window is visible, and it */ /* is enabled (or it's a top-level window), then explore */ /* its children. Otherwise, go to the next window. */ if( (dwStyle & WS_VISIBLE) && ((dwExStyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) != (WS_EX_LAYERED | WS_EX_TRANSPARENT)) && (!(dwStyle & WS_DISABLED) || ((dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) && ((point.x >= rectWindow.left) && (point.x < rectWindow.right) && (point.y >= rectWindow.top) && (point.y < rectWindow.bottom)) #if 1 ) #else && (wndPtr->hrgnWnd ? PtInRegion(wndPtr->hrgnWnd, 1)) #endif { DWORD dwThreadId = GetCurrentThreadId(); //Don't send WM_NCHITTEST if this window doesn't belong to the current thread if(dwThreadId != GetWindowThreadProcessId(hwnd, NULL)) { return TRUE; } hittest = SendMessageA(hwnd, WM_NCHITTEST, 0, MAKELONG(point.x, point.y)); if(hittest != HTTRANSPARENT) { return TRUE; } } return FALSE; } //****************************************************************************** //TODO: Does this return handles of hidden or disabled windows? //****************************************************************************** HWND WIN32API WindowFromPoint( POINT point) { HWND hwndOS2, hwnd; POINT wPoint; wPoint.x = point.x; wPoint.y = mapScreenY(point.y); hwndOS2 = OSLibWinWindowFromPoint(OSLIB_HWND_DESKTOP, (PVOID)&wPoint); if(hwndOS2) { hwnd = OS2ToWin32Handle(hwndOS2); while(hwnd) { if(IsPointInWindow(hwnd, point)) { dprintf(("WindowFromPoint (%d,%d) %x->%x\n", point.x, point.y, hwndOS2, hwnd)); return hwnd; } #if 0 //TODO: breaks a lot of things hwnd = GetWindow(hwnd, GW_HWNDNEXT); #else //try siblings HWND hwndSibling; HWND hwndParent = GetParent(hwnd); if(hwndParent) { hwndSibling = GetWindow(hwndParent, GW_CHILD); while(hwndSibling) { if(hwndSibling != hwnd) { if(IsPointInWindow(hwndSibling, point)) { dprintf(("WindowFromPoint (%d,%d) %x->%x\n", point.x, point.y, hwndOS2, hwndSibling)); return hwndSibling; } } hwndSibling = GetWindow(hwndSibling, GW_HWNDNEXT); } } hwnd = hwndParent; #endif } } dprintf(("WindowFromPoint (%d,%d) %x->1\n", point.x, point.y, hwndOS2)); return windowDesktop->getWindowHandle(); } //****************************************************************************** //****************************************************************************** BOOL WIN32API IsWindowUnicode(HWND hwnd) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("IsWindowUnicode, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } BOOL ret = window->IsWindowUnicode(); RELEASE_WNDOBJ(window); return ret; } /*********************************************************************** * SwitchToThisWindow (USER32.539) */ VOID WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore ) { ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED ); } //****************************************************************************** //****************************************************************************** BOOL WIN32API EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam) { return windowDesktop->EnumThreadWindows(dwThreadId, lpfn, lParam); } //****************************************************************************** //****************************************************************************** BOOL WIN32API EnumChildWindows(HWND hwnd, WNDENUMPROC lpfn, LPARAM lParam) { Win32BaseWindow *window; BOOL ret = TRUE; ULONG henum; HWND hwndNext; if(lpfn == NULL) { dprintf(("EnumChildWindows invalid parameter %x %x\n", hwnd, lParam)); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("EnumChildWindows, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } ret = window->EnumChildWindows(lpfn, lParam); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** BOOL WIN32API EnumWindows(WNDENUMPROC lpfn, LPARAM lParam) { return windowDesktop->EnumWindows(lpfn, lParam); } //****************************************************************************** //****************************************************************************** UINT WIN32API ArrangeIconicWindows( HWND parent) { RECT rectParent; HWND hwndChild; INT x, y, xspacing, yspacing; dprintf(("USER32: ArrangeIconicWindows %x", parent)); dprintf(("USER32: TODO: icon title!!")); GetClientRect(parent, &rectParent); x = rectParent.left; y = rectParent.bottom; xspacing = GetSystemMetrics(SM_CXICONSPACING); yspacing = GetSystemMetrics(SM_CYICONSPACING); hwndChild = GetWindow( parent, GW_CHILD ); while (hwndChild) { if( IsIconic( hwndChild ) ) { // WND *wndPtr = WIN_FindWndPtr(hwndChild); // WINPOS_ShowIconTitle( wndPtr, FALSE ); SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2, y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); // if( IsWindow(hwndChild) ) // WINPOS_ShowIconTitle(wndPtr , TRUE ); // WIN_ReleaseWndPtr(wndPtr); if (x <= rectParent.right - xspacing) x += xspacing; else { x = rectParent.left; y -= yspacing; } } hwndChild = GetWindow( hwndChild, GW_HWNDNEXT ); } return yspacing; } //****************************************************************************** //restores iconized window to previous size/position //****************************************************************************** BOOL WIN32API OpenIcon(HWND hwnd) { dprintf(("USER32: OpenIcon %x", hwnd)); if(!IsIconic(hwnd)) return FALSE; ShowWindow(hwnd, SW_SHOWNORMAL); return TRUE; } //****************************************************************************** //SDK: Windows can only be shown with ShowOwnedPopups if they were previously // hidden with the same api //TODO: -> needs testing //****************************************************************************** BOOL WIN32API ShowOwnedPopups(HWND hwndOwner, BOOL fShow) { Win32BaseWindow *window, *owner; HWND hwnd; owner = Win32BaseWindow::GetWindowFromHandle(hwndOwner); if(!owner) { dprintf(("ShowOwnedPopups, window %x not found", hwndOwner)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } dprintf(("USER32: ShowOwnedPopups %x %d", hwndOwner, fShow)); hwnd = GetWindow(GetDesktopWindow(), GW_CHILD); while(hwnd) { window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(window) { if(window == owner && (window->getStyle() & WS_POPUP)) { if(fShow) { if(window->getFlags() & WIN_NEEDS_SHOW_OWNEDPOPUP) { /* * In Windows, ShowOwnedPopups(TRUE) generates WM_SHOWWINDOW messages with SW_PARENTOPENING, * regardless of the state of the owner */ SendMessageA(hwnd, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING); window->setFlags(window->getFlags() & ~WIN_NEEDS_SHOW_OWNEDPOPUP); } } else { if(IsWindowVisible(hwnd)) { /* * In Windows, ShowOwnedPopups(FALSE) generates WM_SHOWWINDOW messages with SW_PARENTCLOSING, * regardless of the state of the owner */ SendMessageA(hwnd, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING); window->setFlags(window->getFlags() | WIN_NEEDS_SHOW_OWNEDPOPUP); } } } RELEASE_WNDOBJ(window); } else dprintf(("WARNING: window %x is not valid", hwnd)); hwnd = GetWindow(hwnd, GW_HWNDNEXT); } RELEASE_WNDOBJ(owner); return TRUE; } //****************************************************************************** //****************************************************************************** HWND WIN32API GetForegroundWindow() { HWND hwnd; hwnd = OS2ToWin32Handle(OSLibWinQueryActiveWindow()); return hwnd; } //****************************************************************************** /****************************************************************************** * The return value identifies the most recently active pop-up window. * The return value is the same as the hWnd parameter, if any of the * following conditions are met: * * - The window identified by hWnd was most recently active. * - The window identified by hWnd does not own any pop-up windows. * - The window identified by hWnd is not a top-level window or it is * owned by another window. */ HWND WIN32API GetLastActivePopup(HWND hWnd) { Win32BaseWindow *owner; owner = Win32BaseWindow::GetWindowFromHandle(hWnd); if(!owner) { dprintf(("GetLastActivePopup, window %x not found", hWnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return hWnd; } HWND hwndRetVal = owner->getLastActive(); if (!IsWindow( hwndRetVal )) hwndRetVal = owner->getWindowHandle(); RELEASE_WNDOBJ(owner); return hwndRetVal; } //****************************************************************************** //****************************************************************************** DWORD WIN32API GetWindowThreadProcessId(HWND hwnd, PDWORD lpdwProcessId) { Win32BaseWindow *window; DWORD dwThreadId; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowThreadProcessId, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dwThreadId = window->getThreadId(); if(lpdwProcessId) { *lpdwProcessId = window->getProcessId(); } RELEASE_WNDOBJ(window); return dwThreadId; } //****************************************************************************** //****************************************************************************** DWORD WIN32API GetWindowContextHelpId(HWND hwnd) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetWindowContextHelpId, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("GetWindowContextHelpId %x", hwnd)); DWORD ret = window->getWindowContextHelpId(); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** BOOL WIN32API SetWindowContextHelpId(HWND hwnd, DWORD dwContextHelpId) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetWindowContextHelpId, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } dprintf(("SetWindowContextHelpId %x %d", hwnd, dwContextHelpId)); window->setWindowContextHelpId(dwContextHelpId); RELEASE_WNDOBJ(window); return(TRUE); } //****************************************************************************** //****************************************************************************** HANDLE WIN32API GetPropA(HWND hwnd, LPCSTR str ) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetPropA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } HANDLE ret = window->getProp(str); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** HANDLE WIN32API GetPropW(HWND hwnd, LPCWSTR str) { Win32BaseWindow *window; LPSTR strA; HANDLE ret; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("GetPropW, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } if(HIWORD(str)) { strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str ); } else strA = (LPSTR)str; ret = window->getProp(strA); RELEASE_WNDOBJ(window); if(HIWORD(str)) HeapFree( GetProcessHeap(), 0, strA ); return ret; } //****************************************************************************** //****************************************************************************** BOOL WIN32API SetPropA(HWND hwnd, LPCSTR str, HANDLE handle ) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("SetPropA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } BOOL ret = window->setProp(str, handle); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** BOOL SetPropW(HWND hwnd, LPCWSTR str, HANDLE handle ) { BOOL ret; LPSTR strA; if (!HIWORD(str)) return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle ); strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str ); ret = SetPropA( hwnd, strA, handle ); HeapFree( GetProcessHeap(), 0, strA ); return ret; } //****************************************************************************** //****************************************************************************** HANDLE WIN32API RemovePropA(HWND hwnd, LPCSTR str) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("RemovePropA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } HANDLE ret = window->removeProp(str); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** HANDLE WIN32API RemovePropW(HWND hwnd, LPCWSTR str) { LPSTR strA; HANDLE ret; if (!HIWORD(str)) return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) ); strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str ); ret = RemovePropA( hwnd, strA ); HeapFree( GetProcessHeap(), 0, strA ); return ret; } //****************************************************************************** //****************************************************************************** INT WIN32API EnumPropsA(HWND hwnd, PROPENUMPROCA func ) { return EnumPropsExA( hwnd, (PROPENUMPROCEXA)func, 0 ); } //****************************************************************************** //****************************************************************************** INT WIN32API EnumPropsW(HWND hwnd, PROPENUMPROCW func ) { return EnumPropsExW( hwnd, (PROPENUMPROCEXW)func, 0 ); } //****************************************************************************** //****************************************************************************** INT WIN32API EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("EnumPropsExA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return -1; } INT ret = window->enumPropsExA(func, lParam); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //****************************************************************************** INT WIN32API EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam) { Win32BaseWindow *window; window = Win32BaseWindow::GetWindowFromHandle(hwnd); if(!window) { dprintf(("EnumPropsExA, window %x not found", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return -1; } INT ret = window->enumPropsExW(func, lParam); RELEASE_WNDOBJ(window); return ret; } //****************************************************************************** //The GetWindowModuleFileName function retrieves the full path and file name of //the module associated with the specified window handle. //****************************************************************************** UINT WIN32API GetWindowModuleFileNameA(HWND hwnd, LPTSTR lpszFileName, UINT cchFileNameMax) { WNDPROC lpfnWindowProc; if (!IsWindow(hwnd)) { dprintf(("warning: GetWindowModuleFileName: window %x not found!", hwnd)); SetLastError(ERROR_INVALID_WINDOW_HANDLE); return 0; } lpfnWindowProc = (WNDPROC)GetWindowLongA(hwnd, GWL_WNDPROC); return GetProcModuleFileNameA((ULONG)lpfnWindowProc, lpszFileName, cchFileNameMax); } //****************************************************************************** //****************************************************************************** /***************************************************************************** * Name : BOOL WIN32API AnyPopup * Purpose : The AnyPopup function indicates whether an owned, visible, * top-level pop-up, or overlapped window exists on the screen. The * function searches the entire Windows screen, not just the calling * application's client area. * Parameters: VOID * Variables : * Result : If a pop-up window exists, the return value is TRUE even if the * pop-up window is completely covered by other windows. Otherwise, * it is FALSE. * Remark : AnyPopup is a Windows version 1.x function and is retained for * compatibility purposes. It is generally not useful. * Status : UNTESTED STUB * * Author : Patrick Haller [Thu, 1998/02/26 11:55] *****************************************************************************/ BOOL WIN32API AnyPopup() { dprintf(("USER32:AnyPopup() not implemented.\n")); return (FALSE); } #ifdef __cplusplus } // extern "C" #endif