From: Piotr Caban piotr@codeweavers.com
--- dlls/comctl32/propsheet.c | 39 +++++++++++++++++++++++++++++++-- dlls/comctl32/tests/propsheet.c | 4 ++-- 2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index e043e34a6cd..8c0d484cb9b 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -66,6 +66,8 @@
#include "wine/debug.h"
+#define HPROPSHEETPAGE_MAGIC 0x5A9234E3 + /****************************************************************************** * Data structures */ @@ -95,6 +97,7 @@ typedef struct
struct _PSP { + ULONG_PTR magic; PROPSHEETPAGEW psp; PROPSHEETPAGEW callback_psp; }; @@ -2302,6 +2305,14 @@ static BOOL PROPSHEET_InsertPage(HWND hwndDlg, HPROPSHEETPAGE hpageInsertAfter, if (!ppi) return FALSE;
+ if (hpage && hpage->magic != HPROPSHEETPAGE_MAGIC) + { + if (psInfo->unicode) + hpage = CreatePropertySheetPageW((const PROPSHEETPAGEW *)hpage); + else + hpage = CreatePropertySheetPageA((const PROPSHEETPAGEA *)hpage); + } + /* * Fill in a new PropPageInfo entry. */ @@ -2855,7 +2866,18 @@ INT_PTR WINAPI PropertySheetA(LPCPROPSHEETHEADERA lppsh) for (n = i = 0; i < lppsh->nPages; i++, n++) { if (!psInfo->usePropPage) - psInfo->proppage[n].hpage = psInfo->ppshheader.u3.phpage[i]; + { + if (psInfo->ppshheader.u3.phpage[i] && + psInfo->ppshheader.u3.phpage[i]->magic == HPROPSHEETPAGE_MAGIC) + { + psInfo->proppage[n].hpage = psInfo->ppshheader.u3.phpage[i]; + } + else + { + psInfo->proppage[n].hpage = CreatePropertySheetPageA( + (const PROPSHEETPAGEA*)psInfo->ppshheader.u3.phpage[i]); + } + } else { psInfo->proppage[n].hpage = CreatePropertySheetPageA((LPCPROPSHEETPAGEA)pByte); @@ -2895,7 +2917,18 @@ INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh) for (n = i = 0; i < lppsh->nPages; i++, n++) { if (!psInfo->usePropPage) - psInfo->proppage[n].hpage = psInfo->ppshheader.u3.phpage[i]; + { + if (psInfo->ppshheader.u3.phpage[i] && + psInfo->ppshheader.u3.phpage[i]->magic == HPROPSHEETPAGE_MAGIC) + { + psInfo->proppage[n].hpage = psInfo->ppshheader.u3.phpage[i]; + } + else + { + psInfo->proppage[n].hpage = CreatePropertySheetPageW( + (const PROPSHEETPAGEW*)psInfo->ppshheader.u3.phpage[i]); + } + } else { psInfo->proppage[n].hpage = CreatePropertySheetPageW((LPCPROPSHEETPAGEW)pByte); @@ -2974,6 +3007,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA( return NULL;
ret = Alloc(sizeof(*ret)); + ret->magic = HPROPSHEETPAGE_MAGIC; ppsp = &ret->psp; memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEA))); /* original data is used for callback notifications */ @@ -3053,6 +3087,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage return NULL;
ret = Alloc(sizeof(*ret)); + ret->magic = HPROPSHEETPAGE_MAGIC; ppsp = &ret->psp; memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEW))); /* original data is used for callback notifications */ diff --git a/dlls/comctl32/tests/propsheet.c b/dlls/comctl32/tests/propsheet.c index 7e0e7087f67..cf435703d1e 100644 --- a/dlls/comctl32/tests/propsheet.c +++ b/dlls/comctl32/tests/propsheet.c @@ -1343,7 +1343,7 @@ static void test_invalid_hpropsheetpage(void)
ret = SendMessageA(hdlg, PSM_INDEXTOPAGE, 0, 0); ok(ret, "page was not created\n"); - todo_wine ok((HPROPSHEETPAGE)ret != hpsp[0], "invalid HPROPSHEETPAGE was preserved\n"); + ok((HPROPSHEETPAGE)ret != hpsp[0], "invalid HPROPSHEETPAGE was preserved\n"); DestroyWindow(hdlg);
memset(pspW, 0, sizeof(*pspW)); @@ -1383,7 +1383,7 @@ static void test_invalid_hpropsheetpage(void) ok(hdlg != INVALID_HANDLE_VALUE, "got invalid handle value %p\n", hdlg);
ret = SendMessageA(hdlg, PSM_INDEXTOPAGE, 0, 0); - todo_wine ok(ret, "page was not created\n"); + ok(ret, "page was not created\n"); ok((HPROPSHEETPAGE)ret != hpsp[0], "invalid HPROPSHEETPAGE was preserved\n"); DestroyWindow(hdlg); }
From: Piotr Caban piotr@codeweavers.com
--- dlls/comctl32/propsheet.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index 8c0d484cb9b..17dfcec694f 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -97,7 +97,8 @@ typedef struct
struct _PSP { - ULONG_PTR magic; + DWORD magic; + BOOL unicode; PROPSHEETPAGEW psp; PROPSHEETPAGEW callback_psp; }; @@ -149,8 +150,6 @@ typedef struct
static const WCHAR PropSheetInfoStr[] = L"PropertySheetInfo";
-#define PSP_INTERNAL_UNICODE 0x80000000 - #define MAX_CAPTION_LENGTH 255 #define MAX_TABTEXT_LENGTH 255 #define MAX_BUTTONTEXT_LENGTH 64 @@ -361,7 +360,7 @@ static const DLGTEMPLATE* HPSP_load_template(HPROPSHEETPAGE hpsp, DWORD *size) return hpsp->psp.u.pResource; }
- if (hpsp->psp.dwFlags & PSP_INTERNAL_UNICODE) + if (hpsp->unicode) { res = FindResourceW(hpsp->psp.hInstance, hpsp->psp.u.pszTemplate, (LPWSTR)RT_DIALOG); @@ -428,7 +427,7 @@ static HWND HPSP_create_page(HPROPSHEETPAGE hpsp, DLGTEMPLATE *template, HWND pa { HWND hwnd;
- if(hpsp->psp.dwFlags & PSP_INTERNAL_UNICODE) + if(hpsp->unicode) { hwnd = CreateDialogIndirectParamW(hpsp->psp.hInstance, template, parent, hpsp->psp.pfnDlgProc, (LPARAM)&hpsp->psp); @@ -3017,8 +3016,6 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA( min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEA))); }
- ppsp->dwFlags &= ~PSP_INTERNAL_UNICODE; - if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) ) { if (!IS_INTRESOURCE( ppsp->u.pszTemplate )) @@ -3088,6 +3085,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage
ret = Alloc(sizeof(*ret)); ret->magic = HPROPSHEETPAGE_MAGIC; + ret->unicode = TRUE; ppsp = &ret->psp; memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEW))); /* original data is used for callback notifications */ @@ -3097,8 +3095,6 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEW))); }
- ppsp->dwFlags |= PSP_INTERNAL_UNICODE; - if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) ) { if (!IS_INTRESOURCE( ppsp->u.pszTemplate ))
From: Piotr Caban piotr@codeweavers.com
--- dlls/comctl32/propsheet.c | 370 +++++++++++++++++++------------- dlls/comctl32/tests/propsheet.c | 4 +- 2 files changed, 220 insertions(+), 154 deletions(-)
diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index 17dfcec694f..dd41d1b423d 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -99,8 +99,11 @@ struct _PSP { DWORD magic; BOOL unicode; - PROPSHEETPAGEW psp; - PROPSHEETPAGEW callback_psp; + union + { + PROPSHEETPAGEA pspA; + PROPSHEETPAGEW pspW; + }; };
typedef struct tagPropPageInfo @@ -180,6 +183,13 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
WINE_DEFAULT_DEBUG_CHANNEL(propsheet);
+static char *heap_strdupA(const char *str) +{ + int len = strlen(str) + 1; + char *ret = Alloc(len); + return strcpy(ret, str); +} + static WCHAR *heap_strdupW(const WCHAR *str) { int len = lstrlenW(str) + 1; @@ -200,6 +210,18 @@ static WCHAR *heap_strdupAtoW(const char *str) return ret; }
+static char *heap_strdupWtoA(const WCHAR *str) +{ + char *ret; + INT len; + + len = WideCharToMultiByte(CP_ACP, 0, str, -1, 0, 0, 0, 0); + ret = Alloc(len); + WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, 0, 0); + + return ret; +} + /* * Get the size of an in-memory template * @@ -336,45 +358,64 @@ static UINT get_template_size(const DLGTEMPLATE *template) static DWORD HPSP_get_flags(HPROPSHEETPAGE hpsp) { if (!hpsp) return 0; - return hpsp->psp.dwFlags; + return hpsp->unicode ? hpsp->pspW.dwFlags : hpsp->pspA.dwFlags; }
static void HPSP_call_callback(HPROPSHEETPAGE hpsp, UINT msg) { - if (!(hpsp->psp.dwFlags & PSP_USECALLBACK) || !hpsp->psp.pfnCallback || - (msg == PSPCB_ADDREF && hpsp->psp.dwSize <= PROPSHEETPAGEA_V1_SIZE)) - return; + if (hpsp->unicode) + { + if (!(hpsp->pspW.dwFlags & PSP_USECALLBACK) || !hpsp->pspW.pfnCallback || + (msg == PSPCB_ADDREF && hpsp->pspW.dwSize <= PROPSHEETPAGEA_V1_SIZE)) + return;
- hpsp->psp.pfnCallback(0, msg, &hpsp->callback_psp); + hpsp->pspW.pfnCallback(0, msg, &hpsp->pspW); + } + else + { + if (!(hpsp->pspA.dwFlags & PSP_USECALLBACK) || !hpsp->pspA.pfnCallback || + (msg == PSPCB_ADDREF && hpsp->pspA.dwSize <= PROPSHEETPAGEA_V1_SIZE)) + return; + + hpsp->pspA.pfnCallback(0, msg, &hpsp->pspA); + } }
static const DLGTEMPLATE* HPSP_load_template(HPROPSHEETPAGE hpsp, DWORD *size) { HGLOBAL template; + HINSTANCE hinst; HRSRC res;
- if (hpsp->psp.dwFlags & PSP_DLGINDIRECT) - { - if (size) - *size = get_template_size(hpsp->psp.u.pResource); - return hpsp->psp.u.pResource; - } - if (hpsp->unicode) { - res = FindResourceW(hpsp->psp.hInstance, hpsp->psp.u.pszTemplate, - (LPWSTR)RT_DIALOG); + if (hpsp->pspW.dwFlags & PSP_DLGINDIRECT) + { + if (size) + *size = get_template_size(hpsp->pspW.u.pResource); + return hpsp->pspW.u.pResource; + } + + hinst = hpsp->pspW.hInstance; + res = FindResourceW(hinst, hpsp->pspW.u.pszTemplate, (LPWSTR)RT_DIALOG); } else { - res = FindResourceA(hpsp->psp.hInstance, - (LPCSTR)hpsp->psp.u.pszTemplate, (LPSTR)RT_DIALOG); + if (hpsp->pspA.dwFlags & PSP_DLGINDIRECT) + { + if (size) + *size = get_template_size(hpsp->pspA.u.pResource); + return hpsp->pspA.u.pResource; + } + + hinst = hpsp->pspA.hInstance; + res = FindResourceA(hinst, hpsp->pspA.u.pszTemplate, (LPSTR)RT_DIALOG); }
if (size) - *size = SizeofResource(hpsp->psp.hInstance, res); + *size = SizeofResource(hinst, res);
- template = LoadResource(hpsp->psp.hInstance, res); + template = LoadResource(hinst, res); return LockResource(template); }
@@ -382,37 +423,70 @@ static WCHAR* HPSP_get_title(HPROPSHEETPAGE hpsp, const WCHAR *template_title) { const WCHAR *pTitle; WCHAR szTitle[256]; + const void *title; + HINSTANCE hinst; + + if (hpsp->unicode) + { + title = hpsp->pspW.pszTitle; + hinst = hpsp->pspW.hInstance; + } + else + { + title = hpsp->pspA.pszTitle; + hinst = hpsp->pspA.hInstance; + }
- if (IS_INTRESOURCE(hpsp->psp.pszTitle)) + if (IS_INTRESOURCE(title)) { - if (LoadStringW(hpsp->psp.hInstance, (DWORD_PTR)hpsp->psp.pszTitle, szTitle, ARRAY_SIZE(szTitle))) + if (LoadStringW(hinst, (DWORD_PTR)title, szTitle, ARRAY_SIZE(szTitle))) pTitle = szTitle; else if (*template_title) pTitle = template_title; else pTitle = L"(null)"; + + return heap_strdupW(pTitle); } - else - pTitle = hpsp->psp.pszTitle;
- return heap_strdupW(pTitle); + if (hpsp->unicode) + return heap_strdupW(title); + return heap_strdupAtoW(title); }
static HICON HPSP_get_icon(HPROPSHEETPAGE hpsp) { HICON ret;
- if (hpsp->psp.dwFlags & PSP_USEICONID) + if (hpsp->unicode) { - int cx = GetSystemMetrics(SM_CXSMICON); - int cy = GetSystemMetrics(SM_CYSMICON); + if (hpsp->pspW.dwFlags & PSP_USEICONID) + { + int cx = GetSystemMetrics(SM_CXSMICON); + int cy = GetSystemMetrics(SM_CYSMICON);
- ret = LoadImageW(hpsp->psp.hInstance, hpsp->psp.u2.pszIcon, IMAGE_ICON, - cx, cy, LR_DEFAULTCOLOR); + ret = LoadImageW(hpsp->pspW.hInstance, hpsp->pspW.u2.pszIcon, IMAGE_ICON, + cx, cy, LR_DEFAULTCOLOR); + } + else + { + ret = hpsp->pspW.u2.hIcon; + } } else { - ret = hpsp->psp.u2.hIcon; + if (hpsp->pspA.dwFlags & PSP_USEICONID) + { + int cx = GetSystemMetrics(SM_CXSMICON); + int cy = GetSystemMetrics(SM_CYSMICON); + + ret = LoadImageA(hpsp->pspA.hInstance, hpsp->pspA.u2.pszIcon, IMAGE_ICON, + cx, cy, LR_DEFAULTCOLOR); + } + else + { + ret = hpsp->pspA.u2.hIcon; + } }
return ret; @@ -420,7 +494,9 @@ static HICON HPSP_get_icon(HPROPSHEETPAGE hpsp)
static LRESULT HPSP_get_template(HPROPSHEETPAGE hpsp) { - return (LRESULT)hpsp->psp.u.pszTemplate; + if (hpsp->unicode) + return (LRESULT)hpsp->pspW.u.pszTemplate; + return (LRESULT)hpsp->pspA.u.pszTemplate; }
static HWND HPSP_create_page(HPROPSHEETPAGE hpsp, DLGTEMPLATE *template, HWND parent) @@ -429,13 +505,13 @@ static HWND HPSP_create_page(HPROPSHEETPAGE hpsp, DLGTEMPLATE *template, HWND pa
if(hpsp->unicode) { - hwnd = CreateDialogIndirectParamW(hpsp->psp.hInstance, template, - parent, hpsp->psp.pfnDlgProc, (LPARAM)&hpsp->psp); + hwnd = CreateDialogIndirectParamW(hpsp->pspW.hInstance, template, + parent, hpsp->pspW.pfnDlgProc, (LPARAM)&hpsp->pspW); } else { - hwnd = CreateDialogIndirectParamA(hpsp->psp.hInstance, template, - parent, hpsp->psp.pfnDlgProc, (LPARAM)&hpsp->psp); + hwnd = CreateDialogIndirectParamA(hpsp->pspA.hInstance, template, + parent, hpsp->pspA.pfnDlgProc, (LPARAM)&hpsp->pspA); }
return hwnd; @@ -443,36 +519,67 @@ static HWND HPSP_create_page(HPROPSHEETPAGE hpsp, DLGTEMPLATE *template, HWND pa
static void HPSP_set_header_title(HPROPSHEETPAGE hpsp, const WCHAR *title) { - if (!IS_INTRESOURCE(hpsp->psp.pszHeaderTitle)) - Free((void *)hpsp->psp.pszHeaderTitle); + if (hpsp->unicode) + { + if (!IS_INTRESOURCE(hpsp->pspW.pszHeaderTitle)) + Free((void *)hpsp->pspW.pszHeaderTitle);
- hpsp->psp.pszHeaderTitle = heap_strdupW(title); - hpsp->psp.dwFlags |= PSP_USEHEADERTITLE; + hpsp->pspW.pszHeaderTitle = heap_strdupW(title); + hpsp->pspW.dwFlags |= PSP_USEHEADERTITLE; + } + else + { + if (!IS_INTRESOURCE(hpsp->pspA.pszHeaderTitle)) + Free((void *)hpsp->pspA.pszHeaderTitle); + + hpsp->pspA.pszHeaderTitle = heap_strdupWtoA(title); + hpsp->pspA.dwFlags |= PSP_USEHEADERTITLE; + } }
static void HPSP_set_header_subtitle(HPROPSHEETPAGE hpsp, const WCHAR *subtitle) { - if (!IS_INTRESOURCE(hpsp->psp.pszHeaderTitle)) - Free((void *)hpsp->psp.pszHeaderTitle); + if (hpsp->unicode) + { + if (!IS_INTRESOURCE(hpsp->pspW.pszHeaderTitle)) + Free((void *)hpsp->pspW.pszHeaderTitle);
- hpsp->psp.pszHeaderTitle = heap_strdupW(subtitle); - hpsp->psp.dwFlags |= PSP_USEHEADERSUBTITLE; + hpsp->pspW.pszHeaderTitle = heap_strdupW(subtitle); + hpsp->pspW.dwFlags |= PSP_USEHEADERSUBTITLE; + } + else + { + if (!IS_INTRESOURCE(hpsp->pspA.pszHeaderTitle)) + Free((void *)hpsp->pspA.pszHeaderTitle); + + hpsp->pspA.pszHeaderTitle = heap_strdupWtoA(subtitle); + hpsp->pspA.dwFlags |= PSP_USEHEADERSUBTITLE; + } }
static void HPSP_draw_text(HPROPSHEETPAGE hpsp, HDC hdc, BOOL title, RECT *r, UINT format) { - const WCHAR *text = title ? hpsp->psp.pszHeaderTitle : hpsp->psp.pszHeaderSubTitle; - WCHAR buf[256]; - INT len; + const void *text;
- if (!IS_INTRESOURCE(text)) - DrawTextW(hdc, text, -1, r, format); + if (hpsp->unicode) + text = title ? hpsp->pspW.pszHeaderTitle : hpsp->pspW.pszHeaderSubTitle; else + text = title ? hpsp->pspA.pszHeaderTitle : hpsp->pspA.pszHeaderSubTitle; + + if (IS_INTRESOURCE(text)) { - len = LoadStringW(hpsp->psp.hInstance, (UINT_PTR)text, buf, ARRAY_SIZE(buf)); + WCHAR buf[256]; + INT len; + + len = LoadStringW(hpsp->unicode ? hpsp->pspW.hInstance : hpsp->pspA.hInstance, + (UINT_PTR)text, buf, ARRAY_SIZE(buf)); if (len != 0) DrawTextW(hdc, buf, len, r, format); } + else if (hpsp->unicode) + DrawTextW(hdc, text, -1, r, format); + else + DrawTextA(hdc, text, -1, r, format); }
#define add_flag(a) if (dwFlags & a) {strcat(string, #a );strcat(string," ");} @@ -2946,42 +3053,6 @@ INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh) return PROPSHEET_PropertySheet(psInfo, TRUE); }
-static LPWSTR load_string( HINSTANCE instance, LPCWSTR str ) -{ - LPWSTR ret; - - if (IS_INTRESOURCE(str)) - { - HRSRC hrsrc; - HGLOBAL hmem; - WCHAR *ptr; - WORD i, id = LOWORD(str); - UINT len; - - if (!(hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((id >> 4) + 1), (LPWSTR)RT_STRING ))) - return NULL; - if (!(hmem = LoadResource( instance, hrsrc ))) return NULL; - if (!(ptr = LockResource( hmem ))) return NULL; - for (i = id & 0x0f; i > 0; i--) ptr += *ptr + 1; - len = *ptr; - if (!len) return NULL; - ret = Alloc( (len + 1) * sizeof(WCHAR) ); - if (ret) - { - memcpy( ret, ptr + 1, len * sizeof(WCHAR) ); - ret[len] = 0; - } - } - else - { - int len = (lstrlenW(str) + 1) * sizeof(WCHAR); - ret = Alloc( len ); - if (ret) memcpy( ret, str, len ); - } - return ret; -} - - /****************************************************************************** * CreatePropertySheetPage (COMCTL32.@) * CreatePropertySheetPageA (COMCTL32.@) @@ -2999,7 +3070,7 @@ static LPWSTR load_string( HINSTANCE instance, LPCWSTR str ) HPROPSHEETPAGE WINAPI CreatePropertySheetPageA( LPCPROPSHEETPAGEA lpPropSheetPage) { - PROPSHEETPAGEW *ppsp; + PROPSHEETPAGEA *ppsp; HPROPSHEETPAGE ret;
if (lpPropSheetPage->dwSize < PROPSHEETPAGEA_V1_SIZE) @@ -3007,64 +3078,41 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
ret = Alloc(sizeof(*ret)); ret->magic = HPROPSHEETPAGE_MAGIC; - ppsp = &ret->psp; + ppsp = &ret->pspA; memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEA))); - /* original data is used for callback notifications */ - if ((lpPropSheetPage->dwFlags & PSP_USECALLBACK) && lpPropSheetPage->pfnCallback) - { - memcpy(&ret->callback_psp, lpPropSheetPage, - min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEA))); - }
if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) ) { if (!IS_INTRESOURCE( ppsp->u.pszTemplate )) - { - int len = strlen(lpPropSheetPage->u.pszTemplate) + 1; - char *template = Alloc( len ); - - ppsp->u.pszTemplate = (LPWSTR)strcpy( template, lpPropSheetPage->u.pszTemplate ); - } + ppsp->u.pszTemplate = heap_strdupA( lpPropSheetPage->u.pszTemplate ); }
if (ppsp->dwFlags & PSP_USEICONID) { if (!IS_INTRESOURCE( ppsp->u2.pszIcon )) - ppsp->u2.pszIcon = heap_strdupAtoW( lpPropSheetPage->u2.pszIcon ); + ppsp->u2.pszIcon = heap_strdupA( lpPropSheetPage->u2.pszIcon ); }
if (ppsp->dwFlags & PSP_USETITLE) { - if (IS_INTRESOURCE( ppsp->pszTitle )) - ppsp->pszTitle = load_string( ppsp->hInstance, ppsp->pszTitle ); - else - ppsp->pszTitle = heap_strdupAtoW( lpPropSheetPage->pszTitle ); + if (!IS_INTRESOURCE( ppsp->pszTitle )) + ppsp->pszTitle = heap_strdupA( lpPropSheetPage->pszTitle ); } - else - ppsp->pszTitle = NULL;
if (ppsp->dwFlags & PSP_HIDEHEADER) ppsp->dwFlags &= ~(PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE);
if (ppsp->dwFlags & PSP_USEHEADERTITLE) { - if (IS_INTRESOURCE( ppsp->pszHeaderTitle )) - ppsp->pszHeaderTitle = load_string( ppsp->hInstance, ppsp->pszHeaderTitle ); - else - ppsp->pszHeaderTitle = heap_strdupAtoW( lpPropSheetPage->pszHeaderTitle ); + if (!IS_INTRESOURCE( ppsp->pszHeaderTitle )) + ppsp->pszHeaderTitle = heap_strdupA( lpPropSheetPage->pszHeaderTitle ); } - else - ppsp->pszHeaderTitle = NULL;
if (ppsp->dwFlags & PSP_USEHEADERSUBTITLE) { - if (IS_INTRESOURCE( ppsp->pszHeaderSubTitle )) - ppsp->pszHeaderSubTitle = load_string( ppsp->hInstance, ppsp->pszHeaderSubTitle ); - else - ppsp->pszHeaderSubTitle = heap_strdupAtoW( lpPropSheetPage->pszHeaderSubTitle ); + if (!IS_INTRESOURCE( ppsp->pszHeaderSubTitle )) + ppsp->pszHeaderSubTitle = heap_strdupA( lpPropSheetPage->pszHeaderSubTitle ); } - else - ppsp->pszHeaderSubTitle = NULL;
HPSP_call_callback(ret, PSPCB_ADDREF); return ret; @@ -3086,14 +3134,8 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage ret = Alloc(sizeof(*ret)); ret->magic = HPROPSHEETPAGE_MAGIC; ret->unicode = TRUE; - ppsp = &ret->psp; + ppsp = &ret->pspW; memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEW))); - /* original data is used for callback notifications */ - if ((lpPropSheetPage->dwFlags & PSP_USECALLBACK) && lpPropSheetPage->pfnCallback) - { - memcpy(&ret->callback_psp, lpPropSheetPage, - min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEW))); - }
if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) ) { @@ -3108,22 +3150,25 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage }
if (ppsp->dwFlags & PSP_USETITLE) - ppsp->pszTitle = load_string( ppsp->hInstance, ppsp->pszTitle ); - else - ppsp->pszTitle = NULL; + { + if (!IS_INTRESOURCE( ppsp->pszTitle )) + ppsp->pszTitle = heap_strdupW( lpPropSheetPage->pszTitle ); + }
if (ppsp->dwFlags & PSP_HIDEHEADER) ppsp->dwFlags &= ~(PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE);
if (ppsp->dwFlags & PSP_USEHEADERTITLE) - ppsp->pszHeaderTitle = load_string( ppsp->hInstance, ppsp->pszHeaderTitle ); - else - ppsp->pszHeaderTitle = NULL; + { + if (!IS_INTRESOURCE( ppsp->pszHeaderTitle )) + ppsp->pszHeaderTitle = heap_strdupW( ppsp->pszHeaderTitle ); + }
if (ppsp->dwFlags & PSP_USEHEADERSUBTITLE) - ppsp->pszHeaderSubTitle = load_string( ppsp->hInstance, ppsp->pszHeaderSubTitle ); - else - ppsp->pszHeaderSubTitle = NULL; + { + if (!IS_INTRESOURCE( ppsp->pszHeaderSubTitle )) + ppsp->pszHeaderSubTitle = heap_strdupW( ppsp->pszHeaderSubTitle ); + }
HPSP_call_callback(ret, PSPCB_ADDREF); return ret; @@ -3140,33 +3185,54 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage * Success: TRUE * Failure: FALSE */ -BOOL WINAPI DestroyPropertySheetPage(HPROPSHEETPAGE hPropPage) +BOOL WINAPI DestroyPropertySheetPage(HPROPSHEETPAGE hpsp) { - PROPSHEETPAGEW *psp = &hPropPage->psp; + if (!hpsp) + return FALSE;
- if (!hPropPage) - return FALSE; + HPSP_call_callback(hpsp, PSPCB_RELEASE);
- HPSP_call_callback(hPropPage, PSPCB_RELEASE); + if (hpsp->unicode) + { + PROPSHEETPAGEW *psp = &hpsp->pspW;
- if (!(psp->dwFlags & PSP_DLGINDIRECT) && !IS_INTRESOURCE( psp->u.pszTemplate )) - Free((void*)psp->u.pszTemplate); + if (!(psp->dwFlags & PSP_DLGINDIRECT) && !IS_INTRESOURCE(psp->u.pszTemplate)) + Free((void*)psp->u.pszTemplate);
- if ((psp->dwFlags & PSP_USEICONID) && !IS_INTRESOURCE( psp->u2.pszIcon )) - Free((void*)psp->u2.pszIcon); + if ((psp->dwFlags & PSP_USEICONID) && !IS_INTRESOURCE(psp->u2.pszIcon)) + Free((void*)psp->u2.pszIcon);
- if ((psp->dwFlags & PSP_USETITLE) && !IS_INTRESOURCE( psp->pszTitle )) - Free((void*)psp->pszTitle); + if ((psp->dwFlags & PSP_USETITLE) && !IS_INTRESOURCE(psp->pszTitle)) + Free((void*)psp->pszTitle);
- if ((psp->dwFlags & PSP_USEHEADERTITLE) && !IS_INTRESOURCE( psp->pszHeaderTitle )) - Free((void*)psp->pszHeaderTitle); + if ((psp->dwFlags & PSP_USEHEADERTITLE) && !IS_INTRESOURCE(psp->pszHeaderTitle)) + Free((void*)psp->pszHeaderTitle);
- if ((psp->dwFlags & PSP_USEHEADERSUBTITLE) && !IS_INTRESOURCE( psp->pszHeaderSubTitle )) - Free((void*)psp->pszHeaderSubTitle); + if ((psp->dwFlags & PSP_USEHEADERSUBTITLE) && !IS_INTRESOURCE(psp->pszHeaderSubTitle)) + Free((void*)psp->pszHeaderSubTitle); + } + else + { + PROPSHEETPAGEA *psp = &hpsp->pspA;
- Free(hPropPage); + if (!(psp->dwFlags & PSP_DLGINDIRECT) && !IS_INTRESOURCE(psp->u.pszTemplate)) + Free((void*)psp->u.pszTemplate);
- return TRUE; + if ((psp->dwFlags & PSP_USEICONID) && !IS_INTRESOURCE(psp->u2.pszIcon)) + Free((void*)psp->u2.pszIcon); + + if ((psp->dwFlags & PSP_USETITLE) && !IS_INTRESOURCE(psp->pszTitle)) + Free((void*)psp->pszTitle); + + if ((psp->dwFlags & PSP_USEHEADERTITLE) && !IS_INTRESOURCE(psp->pszHeaderTitle)) + Free((void*)psp->pszHeaderTitle); + + if ((psp->dwFlags & PSP_USEHEADERSUBTITLE) && !IS_INTRESOURCE(psp->pszHeaderSubTitle)) + Free((void*)psp->pszHeaderSubTitle); + } + + Free(hpsp); + return TRUE; }
/****************************************************************************** diff --git a/dlls/comctl32/tests/propsheet.c b/dlls/comctl32/tests/propsheet.c index cf435703d1e..70f46c83d85 100644 --- a/dlls/comctl32/tests/propsheet.c +++ b/dlls/comctl32/tests/propsheet.c @@ -122,7 +122,7 @@ static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
if (psp->dwFlags & PSP_USETITLE) { - todo_wine ok(!strcmp(psp->pszTitle, "page title"), "psp->pszTitle = %s\n", + ok(!strcmp(psp->pszTitle, "page title"), "psp->pszTitle = %s\n", wine_dbgstr_a(psp->pszTitle)); } return TRUE; @@ -1051,7 +1051,7 @@ static UINT CALLBACK proppage_callback_a(HWND hwnd, UINT msg, PROPSHEETPAGEA *ps ok(psp->lParam && psp->lParam != (LPARAM)psp, "Expected newly allocated page description, got %Ix, %p\n", psp->lParam, psp); if (psp->dwFlags & PSP_USETITLE) - todo_wine ok(psp_orig->pszTitle != psp->pszTitle, "Expected different page title pointer\n"); + ok(psp_orig->pszTitle != psp->pszTitle, "Expected different page title pointer\n"); else ok(psp_orig->pszTitle == psp->pszTitle, "Expected same page title pointer\n"); ok(!lstrcmpA(psp_orig->pszTitle, psp->pszTitle), "Expected same page title string\n");
From: Piotr Caban piotr@codeweavers.com
--- dlls/comctl32/propsheet.c | 9 +++++---- dlls/comctl32/tests/propsheet.c | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index dd41d1b423d..40b0cf83c69 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -103,6 +103,7 @@ struct _PSP { PROPSHEETPAGEA pspA; PROPSHEETPAGEW pspW; + BYTE data[1]; }; };
@@ -3076,10 +3077,10 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA( if (lpPropSheetPage->dwSize < PROPSHEETPAGEA_V1_SIZE) return NULL;
- ret = Alloc(sizeof(*ret)); + ret = Alloc(FIELD_OFFSET(struct _PSP, data[lpPropSheetPage->dwSize])); ret->magic = HPROPSHEETPAGE_MAGIC; ppsp = &ret->pspA; - memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEA))); + memcpy(ppsp, lpPropSheetPage, lpPropSheetPage->dwSize);
if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) ) { @@ -3131,11 +3132,11 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage if (lpPropSheetPage->dwSize < PROPSHEETPAGEW_V1_SIZE) return NULL;
- ret = Alloc(sizeof(*ret)); + ret = Alloc(FIELD_OFFSET(struct _PSP, data[lpPropSheetPage->dwSize])); ret->magic = HPROPSHEETPAGE_MAGIC; ret->unicode = TRUE; ppsp = &ret->pspW; - memcpy(ppsp, lpPropSheetPage, min(lpPropSheetPage->dwSize, sizeof(PROPSHEETPAGEW))); + memcpy(ppsp, lpPropSheetPage, lpPropSheetPage->dwSize);
if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) ) { diff --git a/dlls/comctl32/tests/propsheet.c b/dlls/comctl32/tests/propsheet.c index 70f46c83d85..7c0d5f81642 100644 --- a/dlls/comctl32/tests/propsheet.c +++ b/dlls/comctl32/tests/propsheet.c @@ -1058,7 +1058,7 @@ static UINT CALLBACK proppage_callback_a(HWND hwnd, UINT msg, PROPSHEETPAGEA *ps if (psp->dwSize >= FIELD_OFFSET(struct custom_proppage, addref_called)) { struct custom_proppage *extra_data = (struct custom_proppage *)psp; - todo_wine ok(extra_data->extra_data == 0x1234, "Expected extra_data to be preserved, got %lx\n", + ok(extra_data->extra_data == 0x1234, "Expected extra_data to be preserved, got %lx\n", extra_data->extra_data); }
@@ -1092,7 +1092,7 @@ static UINT CALLBACK proppage_callback_w(HWND hwnd, UINT msg, PROPSHEETPAGEW *ps if (psp->dwSize >= FIELD_OFFSET(struct custom_proppage, addref_called)) { struct custom_proppage *extra_data = (struct custom_proppage *)psp; - todo_wine ok(extra_data->extra_data == 0x4321, "Expected extra_data to be preserved, got %lx\n", + ok(extra_data->extra_data == 0x4321, "Expected extra_data to be preserved, got %lx\n", extra_data->extra_data); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125197
Your paranoid android.
=== debian11 (build log) ===
Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24865. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24865. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24865.
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/propsheet.c:
static DWORD HPSP_get_flags(HPROPSHEETPAGE hpsp) { if (!hpsp) return 0;
- return hpsp->psp.dwFlags;
- return hpsp->unicode ? hpsp->pspW.dwFlags : hpsp->pspA.dwFlags;
}
static void HPSP_call_callback(HPROPSHEETPAGE hpsp, UINT msg) {
- if (!(hpsp->psp.dwFlags & PSP_USECALLBACK) || !hpsp->psp.pfnCallback ||
(msg == PSPCB_ADDREF && hpsp->psp.dwSize <= PROPSHEETPAGEA_V1_SIZE))
return;
- if (hpsp->unicode)
- {
if (!(hpsp->pspW.dwFlags & PSP_USECALLBACK) || !hpsp->pspW.pfnCallback ||
(msg == PSPCB_ADDREF && hpsp->pspW.dwSize <= PROPSHEETPAGEA_V1_SIZE))
PROPSHEETPAGEA_V1_SIZE is used instead of PROPSHEETPAGEW_V1_SIZE. Is it correct?
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/propsheet.c:
for (n = i = 0; i < lppsh->nPages; i++, n++) { if (!psInfo->usePropPage)
psInfo->proppage[n].hpage = psInfo->ppshheader.u3.phpage[i];
- {
if (psInfo->ppshheader.u3.phpage[i] &&
psInfo->ppshheader.u3.phpage[i]->magic == HPROPSHEETPAGE_MAGIC)
{
psInfo->proppage[n].hpage = psInfo->ppshheader.u3.phpage[i];
}
else
{
psInfo->proppage[n].hpage = CreatePropertySheetPageA(
(const PROPSHEETPAGEA*)psInfo->ppshheader.u3.phpage[i]);
Minor style issues. Please add a space before *.
On Mon Oct 24 13:38:45 2022 +0000, Zhiyi Zhang wrote:
PROPSHEETPAGEA_V1_SIZE is used instead of PROPSHEETPAGEW_V1_SIZE. Is it correct?
It's a mistake, I'll push a fix (but it doesn't affect the result since PROPSHEETPAGEA_V1_SIZE == PROPSHEETPAGEW_V1_SIZE).