>From a9b86b1e9d2185e13477aa31ced535d8144f8201 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Sat, 22 Oct 2011 01:45:23 +0400
Subject: [PATCH 1/3] Fix window style set with SHSetParentHwnd()

---
 dlls/shlwapi/ordinal.c       |    8 ++--
 dlls/shlwapi/tests/ordinal.c |   85 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 7d63899..01adaa9 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -1136,14 +1136,14 @@ HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
   TRACE("%p, %p\n", hWnd, hWndParent);
 
   if(GetParent(hWnd) == hWndParent)
-    return 0;
+    return NULL;
 
   if(hWndParent)
-    SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
+    SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD | WS_POPUP, WS_CHILD);
   else
-    SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
+    SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD | WS_POPUP, WS_POPUP);
 
-  return SetParent(hWnd, hWndParent);
+  return hWndParent ? SetParent(hWnd, hWndParent) : NULL;
 }
 
 /*************************************************************************
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index 40ee62e..0cb0518 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -67,6 +67,7 @@ static HRESULT (WINAPI *pSKGetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void*, DW
 static HRESULT (WINAPI *pSKSetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD, void*, DWORD);
 static HRESULT (WINAPI *pSKDeleteValueW)(DWORD, LPCWSTR, LPCWSTR);
 static HRESULT (WINAPI *pSKAllocValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void**, DWORD*);
+static HWND    (WINAPI *pSHSetParentHwnd)(HWND, HWND);
 
 static HMODULE hmlang;
 static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
@@ -2925,6 +2926,7 @@ static void init_pointers(void)
     MAKEFUNC(SHFreeShared, 10);
     MAKEFUNC(GetAcceptLanguagesA, 14);
     MAKEFUNC(SHSetWindowBits, 165);
+    MAKEFUNC(SHSetParentHwnd, 167);
     MAKEFUNC(ConnectToConnectionPoint, 168);
     MAKEFUNC(SHSearchMapInt, 198);
     MAKEFUNC(SHCreateWorkerWindowA, 257);
@@ -2949,6 +2951,88 @@ static void init_pointers(void)
 #undef MAKEFUNC
 }
 
+static void test_SHSetParentHwnd(void)
+{
+    HWND hwnd, hwnd2, ret;
+    DWORD style;
+
+    if (!pSHSetParentHwnd)
+    {
+        win_skip("SHSetParentHwnd not available\n");
+        return;
+    }
+
+    hwnd = CreateWindowA("Button", "", WS_VISIBLE, 0, 0, 10, 10, NULL, NULL, NULL, NULL);
+    ok(hwnd != NULL, "got %p\n", hwnd);
+
+    hwnd2 = CreateWindowA("Button", "", WS_VISIBLE | WS_CHILD, 0, 0, 10, 10, hwnd, NULL, NULL, NULL);
+    ok(hwnd2 != NULL, "got %p\n", hwnd2);
+
+    /* null params */
+    ret = pSHSetParentHwnd(NULL, NULL);
+    ok(ret == NULL, "got %p\n", ret);
+
+    /* set to no parent while already no parent present */
+    ret = GetParent(hwnd);
+    ok(ret == NULL, "got %p\n", ret);
+    style = GetWindowLongA(hwnd, GWL_STYLE);
+    ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08x\n", style);
+    ret = pSHSetParentHwnd(hwnd, NULL);
+    ok(ret == NULL, "got %p\n", ret);
+    style = GetWindowLongA(hwnd, GWL_STYLE);
+    ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08x\n", style);
+
+    /* reset to null parent from not null */
+    ret = GetParent(hwnd2);
+    ok(ret == hwnd, "got %p\n", ret);
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08x\n", style);
+    ret = pSHSetParentHwnd(hwnd2, NULL);
+    ok(ret == NULL, "got %p\n", ret);
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    ok((style & (WS_POPUP|WS_CHILD)) == WS_POPUP, "got style 0x%08x\n", style);
+    ret = GetParent(hwnd2);
+    ok(ret == NULL, "got %p\n", ret);
+
+    /* set parent back */
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    SetWindowLongA(hwnd2, GWL_STYLE, style & ~(WS_CHILD|WS_POPUP));
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    ok((style & (WS_CHILD|WS_POPUP)) == 0, "got 0x%08x\n", style);
+
+    ret = pSHSetParentHwnd(hwnd2, hwnd);
+    todo_wine ok(ret == NULL, "got %p\n", ret);
+
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08x\n", style);
+    ret = GetParent(hwnd2);
+    ok(ret == hwnd, "got %p\n", ret);
+
+    /* try to set same parent again */
+    /* with WS_POPUP */
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    SetWindowLongA(hwnd2, GWL_STYLE, style | WS_POPUP);
+    ret = pSHSetParentHwnd(hwnd2, hwnd);
+    todo_wine ok(ret == NULL, "got %p\n", ret);
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08x\n", style);
+    ret = GetParent(hwnd2);
+    ok(ret == hwnd, "got %p\n", ret);
+
+    /* without WS_POPUP */
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    SetWindowLongA(hwnd2, GWL_STYLE, style | ~WS_POPUP);
+    ret = pSHSetParentHwnd(hwnd2, hwnd);
+    todo_wine ok(ret == hwnd, "got %p\n", ret);
+    style = GetWindowLongA(hwnd2, GWL_STYLE);
+    ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08x\n", style);
+    ret = GetParent(hwnd2);
+    ok(ret == hwnd, "got %p\n", ret);
+
+    DestroyWindow(hwnd);
+    DestroyWindow(hwnd2);
+}
+
 START_TEST(ordinal)
 {
     hShlwapi = GetModuleHandleA("shlwapi.dll");
@@ -2988,6 +3072,7 @@ START_TEST(ordinal)
     test_SHGetIniString();
     test_SHSetIniString();
     test_SHGetShellKey();
+    test_SHSetParentHwnd();
 
     FreeLibrary(hshell32);
     FreeLibrary(hmlang);
-- 
1.5.6.5

