From f6c11b91eadd9fc3ab2eec6a16216557962c0b9d Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Tue, 18 Oct 2022 18:08:38 +0200 Subject: [PATCH] [0.4.7][NTUSER] Fix taskbar panes activation (#2046) (#3294) (#3697) (#3700), [SHELL32] (#4800) This is a squashed backport of the following commits: 0.4.13-RC-53-g 4f628f6b167c0e1936eaa501efac2eeef69533b8 (partial pick of shell32-changes for Miranda CORE-14439 & Winamp CORE-13584, explorer left out) 0.4.14-dev-369-g 141cf04239f3049c1c180fb2c6c3aa84b13c8590 (#2046) NTUSER 0.4.15-dev-1126-g 58b0558f94abee52ce1c261063d4f4b884e96310 (#3294) NTUSER 0.4.15-dev-2618-g 32b0cf6fc6b8f5fab33c10c782f40d36feebbedb (#3697) NTUSER 0.4.15-dev-2621-g 59d4c1120310b7c08641cc3aab82072251900d98 (#3700) NTUSER 0.4.15-dev-5242-g e6fb0e0c25d4509bf30a6ad602c9ba7d143cd77a (#4800) Cleanup brings us closer to releases/0.4.14 In the older branches it will fix the following bugs (or prevents introducing them): CORE-13584 'Winamp 5.666 erroneously has a secret tab shown in taskbar' CORE-14380 'Effective File Search 6.8.1 when you open up the app via desktop link there is no pane in taskbar' CORE-14439 'Miranda IM 0.10.21 snap-to-monitor-border-feature brings ros to halt' CORE-15655 'Click-N-Type Virtual Keyboard 3.03.0412 has no taskbar pane' CORE-15669 'DVD Write Now 1.5.12 SP2 setup has no taskbar pane' CORE-15716 'Photofiltr 7.2.1 has no taskbar pane' CORE-15731 'Java JRE 6u45 setup, last page of setup has no taskbar pane' CORE-16030 'Moo0 Audio Recorder - the taskbar icon does not appear' (CORE-17330 Regression, many installers that should have only 1 taskbar pane, now have 2 of them erroneously) --- dll/win32/shell32/CMakeLists.txt | 1 + dll/win32/shell32/systray.cpp | 2 +- dll/win32/shell32/wine/appbar.c | 167 ++++++++++++++++++++++++++ dll/win32/shell32/wine/shell32_main.c | 66 ---------- sdk/include/reactos/undocshell.h | 5 + win32ss/user/ntuser/window.c | 16 ++- win32ss/user/ntuser/winpos.c | 31 +++-- 7 files changed, 203 insertions(+), 85 deletions(-) create mode 100644 dll/win32/shell32/wine/appbar.c diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt index 8bdf3ee56ff..eea24b02707 100644 --- a/dll/win32/shell32/CMakeLists.txt +++ b/dll/win32/shell32/CMakeLists.txt @@ -82,6 +82,7 @@ add_rc_deps(shell32.rc ${shell32_rc_deps}) add_library(shell32 SHARED ${SOURCE} + wine/appbar.c wine/brsfolder.c wine/changenotify.c wine/classes.c diff --git a/dll/win32/shell32/systray.cpp b/dll/win32/shell32/systray.cpp index 482abf0e1b2..5faeec023a3 100644 --- a/dll/win32/shell32/systray.cpp +++ b/dll/win32/shell32/systray.cpp @@ -197,7 +197,7 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid) } /* Send the data */ - data.dwData = 1; + data.dwData = TABDMC_NOTIFY; data.cbData = sizeof(tnid); data.lpData = &tnid; if (SendMessageW(hShellTrayWnd, WM_COPYDATA, (WPARAM)pnid->hWnd, (LPARAM)&data)) diff --git a/dll/win32/shell32/wine/appbar.c b/dll/win32/shell32/wine/appbar.c new file mode 100644 index 00000000000..78ca967b238 --- /dev/null +++ b/dll/win32/shell32/wine/appbar.c @@ -0,0 +1,167 @@ +/* + * SHAppBarMessage implementation + * + * Copyright 2008 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +// +// Adapted from Wine appbar.c . +// + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "undocshell.h" + +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(appbar); + +struct appbar_cmd +{ + DWORD dwMsg; + ULONG return_map; + DWORD return_process; + struct _AppBarData abd; +}; + +struct appbar_response +{ + ULONGLONG result; + struct _AppBarData abd; +}; + +/************************************************************************* + * SHAppBarMessage [SHELL32.@] + */ +UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data) +{ + struct appbar_cmd command; + struct appbar_response* response; + HANDLE return_map; + LPVOID return_view; + HWND appbarmsg_window; + COPYDATASTRUCT cds; + + UINT_PTR ret = 0; + + TRACE("msg=%d, data={cb=%d, hwnd=%p}\n", msg, data->cbSize, data->hWnd); + + /* These members are message dependent */ + switch(msg) + { + case ABM_NEW: + TRACE("callback: %x\n", data->uCallbackMessage); + break; + + case ABM_GETAUTOHIDEBAR: + TRACE("edge: %d\n", data->uEdge); + break; + + case ABM_QUERYPOS: + case ABM_SETPOS: + TRACE("edge: %d, rc: %s\n", data->uEdge, wine_dbgstr_rect(&data->rc)); + break; + + case ABM_GETTASKBARPOS: + TRACE("rc: %s\n", wine_dbgstr_rect(&data->rc)); + break; + + case ABM_SETAUTOHIDEBAR: + TRACE("edge: %d, lParam: %lx\n", data->uEdge, data->lParam); + break; + + default: + FIXME("unknown msg: %d\n", msg); + break; + } + + if (data->cbSize < sizeof(APPBARDATA)) + { + WARN("data at %p is too small\n", data); + return FALSE; + } + + command.dwMsg = msg; + command.abd.hWnd = data->hWnd; + command.abd.uCallbackMessage = data->uCallbackMessage; + command.abd.uEdge = data->uEdge; + command.abd.rc = data->rc; + command.abd.lParam = data->lParam; + + return_map = CreateFileMappingW(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(struct appbar_response), NULL); + if (return_map == NULL) + { + ERR("couldn't create file mapping\n"); + return 0; + } + command.return_map = HandleToUlong( return_map ); + + command.return_process = GetCurrentProcessId(); + + appbarmsg_window = FindWindowW(L"Shell_TrayWnd", NULL); + if (appbarmsg_window == NULL) + { + ERR("couldn't find appbar window\n"); + CloseHandle(return_map); + return 0; + } + + cds.dwData = TABDMC_APPBAR; + cds.cbData = sizeof(command); + cds.lpData = &command; + + SendMessageW(appbarmsg_window, WM_COPYDATA, (WPARAM)data->hWnd, (LPARAM)&cds); + + return_view = MapViewOfFile(return_map, FILE_MAP_READ, 0, 0, sizeof(struct appbar_response)); + if (return_view == NULL) + { + ERR("MapViewOfFile failed\n"); + CloseHandle(return_map); + return 0; + } + + response = return_view; + + ret = response->result; + if (ret) + { + data->hWnd = response->abd.hWnd; + data->uCallbackMessage = response->abd.uCallbackMessage; + data->uEdge = response->abd.uEdge; + data->rc = response->abd.rc; + data->lParam = response->abd.lParam; + } + UnmapViewOfFile(return_view); + + CloseHandle(return_map); + + return ret; +} diff --git a/dll/win32/shell32/wine/shell32_main.c b/dll/win32/shell32/wine/shell32_main.c index e0c4cfa32f0..39864787c4c 100644 --- a/dll/win32/shell32/wine/shell32_main.c +++ b/dll/win32/shell32/wine/shell32_main.c @@ -941,72 +941,6 @@ typedef struct HICON hIcon; } ABOUT_INFO; -#define DROP_FIELD_TOP (-15) -#define DROP_FIELD_HEIGHT 15 - -/************************************************************************* - * SHAppBarMessage [SHELL32.@] - */ -UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data) -{ - int width=data->rc.right - data->rc.left; - int height=data->rc.bottom - data->rc.top; - RECT rec=data->rc; - - TRACE("msg=%d, data={cb=%d, hwnd=%p, callback=%x, edge=%d, rc=%s, lparam=%lx}\n", - msg, data->cbSize, data->hWnd, data->uCallbackMessage, data->uEdge, - wine_dbgstr_rect(&data->rc), data->lParam); - - switch (msg) - { - case ABM_GETSTATE: - return ABS_ALWAYSONTOP | ABS_AUTOHIDE; - - case ABM_GETTASKBARPOS: - GetWindowRect(data->hWnd, &rec); - data->rc=rec; - return TRUE; - - case ABM_ACTIVATE: - SetActiveWindow(data->hWnd); - return TRUE; - - case ABM_GETAUTOHIDEBAR: - return 0; /* pretend there is no autohide bar */ - - case ABM_NEW: - /* cbSize, hWnd, and uCallbackMessage are used. All other ignored */ - SetWindowPos(data->hWnd,HWND_TOP,0,0,0,0,SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); - return TRUE; - - case ABM_QUERYPOS: - GetWindowRect(data->hWnd, &(data->rc)); - return TRUE; - - case ABM_REMOVE: - FIXME("ABM_REMOVE broken\n"); - /* FIXME: this is wrong; should it be DestroyWindow instead? */ - /*CloseHandle(data->hWnd);*/ - return TRUE; - - case ABM_SETAUTOHIDEBAR: - SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top, - width,height,SWP_SHOWWINDOW); - return TRUE; - - case ABM_SETPOS: - data->uEdge=(ABE_RIGHT | ABE_LEFT); - SetWindowPos(data->hWnd,HWND_TOP,data->rc.left,data->rc.top, - width,height,SWP_SHOWWINDOW); - return TRUE; - - case ABM_WINDOWPOSCHANGED: - return TRUE; - } - - return FALSE; -} - /************************************************************************* * SHHelpShortcuts_RunDLLA [SHELL32.@] * diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index 8536906e476..ef5fc90bbee 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -782,6 +782,11 @@ void DumpIdList(LPCITEMIDLIST pcidl) #define SMSET_UNKNOWN08 0x08 #define SMSET_UNKNOWN10 0x10 +// Explorer Tray Application Bar Data Message Commands +#define TABDMC_APPBAR 0 +#define TABDMC_NOTIFY 1 +#define TABDMC_LOADINPROC 2 + void WINAPI ShellDDEInit(BOOL bInit); DWORD WINAPI WinList_Init(void); diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index 6b1610323e7..cc9133b20b9 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -2257,13 +2257,17 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, IntSendParentNotify(Window, WM_CREATE); /* Notify the shell that a new window was created */ - if (UserIsDesktopWindow(Window->spwndParent) && - Window->spwndOwner == NULL && - (Window->style & WS_VISIBLE) && - (!(Window->ExStyle & WS_EX_TOOLWINDOW) || - (Window->ExStyle & WS_EX_APPWINDOW))) + if (Window->spwndOwner == NULL || + !(Window->spwndOwner->style & WS_VISIBLE) || + (Window->spwndOwner->ExStyle & WS_EX_TOOLWINDOW)) { - co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)hWnd, 0); + if (UserIsDesktopWindow(Window->spwndParent) && + (Window->style & WS_VISIBLE) && + (!(Window->ExStyle & WS_EX_TOOLWINDOW) || + (Window->ExStyle & WS_EX_APPWINDOW))) + { + co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)hWnd, 0); + } } /* Initialize and show the window's scrollbars */ diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index 0c8c5b71807..763e6a1db83 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -1850,15 +1850,23 @@ co_WinPosSetWindowPos( } else if (WinPos.flags & SWP_SHOWWINDOW) { - if (UserIsDesktopWindow(Window->spwndParent) && - Window->spwndOwner == NULL && - (!(Window->ExStyle & WS_EX_TOOLWINDOW) || - (Window->ExStyle & WS_EX_APPWINDOW))) - { - co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0); - if (!(WinPos.flags & SWP_NOACTIVATE)) - UpdateShellHook(Window); - } + if (Window->style & WS_CHILD) + { + if ((Window->style & WS_POPUP) && (Window->ExStyle & WS_EX_APPWINDOW)) + { + co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0); + if (!(WinPos.flags & SWP_NOACTIVATE)) + UpdateShellHook(Window); + } + } + else if ((Window->ExStyle & WS_EX_APPWINDOW) || + (!(Window->ExStyle & WS_EX_TOOLWINDOW) && !Window->spwndOwner && + (!Window->spwndParent || UserIsDesktopWindow(Window->spwndParent)))) + { + co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0); + if (!(WinPos.flags & SWP_NOACTIVATE)) + UpdateShellHook(Window); + } Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 ); Window->head.pti->cVisWindows++; @@ -2464,9 +2472,8 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_NOACTIVATE | SWP_NOZORDER; /* Fall through. */ case SW_SHOWMINIMIZED: + case SW_MINIMIZE: /* CORE-15669: SW_MINIMIZE also shows */ Swp |= SWP_SHOWWINDOW; - /* Fall through. */ - case SW_MINIMIZE: { Swp |= SWP_NOACTIVATE; if (!(style & WS_MINIMIZE)) @@ -2561,7 +2568,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) default: //ERR("co_WinPosShowWindow Exit Good 4\n"); - return WasVisible; + return FALSE; } ShowFlag = (Cmd != SW_HIDE);