Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2018
- 75 participants
- 1236 messages
Re: [PATCH 2/2] wininet: Add support for INTERNET_OPTION_SETTINGS_CHANGED in InternetSetOption.
by Jacek Caban
Hi Alistair,
On 04/30/2018 03:00 AM, Alistair Leslie-Hughes wrote:
> + ret = InternetSetOptionA(ses, INTERNET_OPTION_REFRESH, NULL, 0);
> + ok(ret == TRUE, "InternetSetOption should've succeeded\n");
> +
> + SetLastError(0xdeadbeef);
> + ret = InternetSetOptionA(req, INTERNET_OPTION_REFRESH, NULL, 0);
> + todo_wine ok(ret == FALSE, "InternetSetOption should've failed\n");
> + todo_wine ok(GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "GetLastError() = %x\n", GetLastError());
Given those tests, I think the implementation should go to
HTTPSESSION_SetOption instead.
Thanks,
Jacek
April 30, 2018
Re: [PATCH 2/2] d3d11/tests: Add tests for D3D11_FEATURE_ARCHITECTURE_INFO in CheckFeatureSupport.
by Zebediah Figura
On 30/04/18 10:03, Pablo Martin wrote:
> Also, I have another question, doesn't wine have some facility for
> submitting patches just for doing the tests on all platforms? That way I
> could avoid noise on the devel ml.
>
>
Yes, you can register for a testbot account here:
https://testbot.winehq.org/
Thanks for your interest in Wine!
April 30, 2018
Re: [PATCH 2/2] d3d11/tests: Add tests for D3D11_FEATURE_ARCHITECTURE_INFO in CheckFeatureSupport.
by Pablo Martin
Ok, this is my fault, since I assumed windows would return E_NOTIMPL
when the query is not available, but I see it actually returns
E_INVALIDARG. Will resend the patches with a fix.
Question is: we are returning E_NOTIMPL when a query is not available in
CheckFormatSupport, shouldn't we be returning E_INVALIDARG as well? This
might allow applications querying this to properly handle the result
when the query is not available.
Also, I have another question, doesn't wine have some facility for
submitting patches just for doing the tests on all platforms? That way I
could avoid noise on the devel ml.
April 30, 2018
Re: [PATCH 2/2] d3d11/tests: Add tests for D3D11_FEATURE_ARCHITECTURE_INFO in CheckFeatureSupport.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=38104
Your paranoid android.
=== wvistau64 (32 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
=== wvistau64_zh_CN (32 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
=== wvistau64_fr (32 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
=== wvistau64_he (32 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
=== w2008s64 (32 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
=== wvistau64 (64 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
=== w2008s64 (64 bit d3d11) ===
d3d11.c:15549: Test failed: Got unexpected hr 0x80070057.
April 30, 2018
[PATCH 2/2] d3d11/tests: Add tests for D3D11_FEATURE_ARCHITECTURE_INFO in CheckFeatureSupport.
by Pablo Martin
This query is not available in all windows versions so I added broken() checks in the tests.
Tested on Ubuntu 17.10.
Signed-off-by: Pablo Martin <pmart-wine(a)riseup.net>
---
dlls/d3d11/tests/d3d11.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 8ca6634626..9c499259f6 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -15486,6 +15486,7 @@ static void test_check_feature_support(void)
{
D3D11_FEATURE_DATA_THREADING threading[2];
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts;
+ D3D11_FEATURE_DATA_ARCHITECTURE_INFO archinfo;
ID3D11Device *device;
ULONG refcount;
HRESULT hr;
@@ -15544,6 +15545,13 @@ static void test_check_feature_support(void)
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
trace("Compute shader support via SM4 %#x.\n", hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x);
+ hr = ID3D11Device_CheckFeatureSupport(device, D3D11_FEATURE_ARCHITECTURE_INFO, &archinfo, sizeof(archinfo));
+ ok(hr == S_OK || broken(hr == E_NOTIMPL) /* Not available on all Windows versions. */,
+ "Got unexpected hr %#x.\n", hr);
+ hr = ID3D11Device_CheckFeatureSupport(device, D3D11_FEATURE_ARCHITECTURE_INFO, &archinfo, sizeof(archinfo)*2);
+ ok(hr == E_INVALIDARG || broken(hr == E_NOTIMPL) /* Not available on all Windows versions. */,
+ "Got unexpected hr %#x.\n", hr);
+
refcount = ID3D11Device_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
}
--
2.14.1
April 30, 2018
[PATCH 1/2] d3d11: Handle D3D11_FEATURE_ARCHITECTURE_INFO in d3d11_device_CheckFeatureSupport.
by Pablo Martin
Some applications will not start if they find this query not available.
Tested on Ubuntu 17.10.
Signed-off-by: Pablo Martin <pmart-wine(a)riseup.net>
---
dlls/d3d11/device.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index d3155d56bf..02dff99452 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -3445,6 +3445,18 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFeatureSupport(ID3D11Device *
return S_OK;
}
+ case D3D11_FEATURE_ARCHITECTURE_INFO:
+ {
+ D3D11_FEATURE_DATA_ARCHITECTURE_INFO *options = feature_support_data;
+ if (feature_support_data_size != sizeof(*options))
+ {
+ WARN("Invalid data size.\n");
+ return E_INVALIDARG;
+ }
+ options->TileBasedDeferredRenderer = FALSE;
+ return S_OK;
+ }
+
default:
FIXME("Unhandled feature %#x.\n", feature);
return E_NOTIMPL;
--
2.14.1
April 30, 2018
[v2 PATCH] wined3d: Add new functions to set and get maximum frame latency for the device.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
v2: changed returned default value
dlls/wined3d/cs.c | 5 ++---
dlls/wined3d/device.c | 19 +++++++++++++++++++
dlls/wined3d/swapchain.c | 6 ++++++
dlls/wined3d/wined3d.spec | 2 ++
dlls/wined3d/wined3d_private.h | 4 ++++
include/wine/wined3d.h | 2 ++
6 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 173490d789..e4a29406a4 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -496,9 +496,8 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
/* Limit input latency by limiting the number of presents that we can get
- * ahead of the worker thread. We have a constant limit here, but
- * IDXGIDevice1 allows tuning this. */
- while (pending > 1)
+ * ahead of the worker thread. */
+ while (pending >= swapchain->max_frame_latency)
{
wined3d_pause();
pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 86c36d5a26..df32350692 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3081,6 +3081,23 @@ struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access
return wined3d_device_get_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx);
}
+void CDECL wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int max_frame_latency)
+{
+ unsigned int i;
+
+ if (!max_frame_latency)
+ max_frame_latency = 3;
+
+ device->max_frame_latency = max_frame_latency;
+ for (i = 0; i < device->swapchain_count; ++i)
+ swapchain_set_max_frame_latency(device->swapchains[i], device);
+}
+
+UINT CDECL wined3d_device_get_max_frame_latency(const struct wined3d_device *device)
+{
+ return device->max_frame_latency;
+}
+
/* Context activation is done by the caller. */
#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount,
@@ -5225,6 +5242,8 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
&adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
device->update_state = &device->state;
+ device->max_frame_latency = 3;
+
if (!(device->cs = wined3d_cs_create(device)))
{
WARN("Failed to create command stream.\n");
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 2aec612018..9112e4264a 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -740,6 +740,11 @@ static void wined3d_swapchain_cs_init(void *object)
context_release(swapchain->context[0]);
}
+void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const struct wined3d_device *device)
+{
+ swapchain->max_frame_latency = device->max_frame_latency >= 2 ? device->max_frame_latency - 1 : 1;
+}
+
static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
@@ -777,6 +782,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
swapchain->win_handle = window;
swapchain->device_window = window;
swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT;
+ swapchain_set_max_frame_latency(swapchain, device);
if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d,
adapter->ordinal, &swapchain->original_mode, NULL)))
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 357b76ebac..bf29e206b5 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -86,6 +86,7 @@
@ cdecl wined3d_device_get_light(ptr long ptr)
@ cdecl wined3d_device_get_light_enable(ptr long ptr)
@ cdecl wined3d_device_get_material(ptr ptr)
+@ cdecl wined3d_device_get_max_frame_latency(ptr)
@ cdecl wined3d_device_get_npatch_mode(ptr)
@ cdecl wined3d_device_get_pixel_shader(ptr)
@ cdecl wined3d_device_get_predication(ptr ptr)
@@ -161,6 +162,7 @@
@ cdecl wined3d_device_set_light(ptr long ptr)
@ cdecl wined3d_device_set_light_enable(ptr long long)
@ cdecl wined3d_device_set_material(ptr ptr)
+@ cdecl wined3d_device_set_max_frame_latency(ptr long)
@ cdecl wined3d_device_set_multithreaded(ptr)
@ cdecl wined3d_device_set_npatch_mode(ptr float)
@ cdecl wined3d_device_set_pixel_shader(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ab13a29530..b297799f82 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2957,6 +2957,7 @@ struct wined3d_device
struct wined3d_rendertarget_view *back_buffer_view;
struct wined3d_swapchain **swapchains;
UINT swapchain_count;
+ unsigned int max_frame_latency;
struct list resources; /* a linked list to track resources created by the device */
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
@@ -3821,6 +3822,7 @@ struct wined3d_swapchain
struct wined3d_palette *palette;
RECT front_buffer_update;
unsigned int swap_interval;
+ unsigned int max_frame_latency;
LONG prev_time, frames; /* Performance tracking */
@@ -3841,6 +3843,8 @@ struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchai
void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain,
+ const struct wined3d_device *device) DECLSPEC_HIDDEN;
/*****************************************************************************
* Utility function prototypes
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 13e83da626..4d973ccdca 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2281,6 +2281,7 @@ HRESULT __cdecl wined3d_device_get_light(const struct wined3d_device *device,
UINT light_idx, struct wined3d_light *light);
HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable);
void __cdecl wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material);
+UINT __cdecl wined3d_device_get_max_frame_latency(const struct wined3d_device *device);
float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device);
struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device);
struct wined3d_query * __cdecl wined3d_device_get_predication(struct wined3d_device *device, BOOL *value);
@@ -2402,6 +2403,7 @@ HRESULT __cdecl wined3d_device_set_light(struct wined3d_device *device,
UINT light_idx, const struct wined3d_light *light);
HRESULT __cdecl wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable);
void __cdecl wined3d_device_set_material(struct wined3d_device *device, const struct wined3d_material *material);
+void __cdecl wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int max_frame_latency);
void __cdecl wined3d_device_set_multithreaded(struct wined3d_device *device);
HRESULT __cdecl wined3d_device_set_npatch_mode(struct wined3d_device *device, float segments);
void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader);
--
2.17.0
April 30, 2018
Re: [v2 PATCH] user32/menu: Return locked menu data when looking for menu items.
by Nikolay Sivov
On 04/30/2018 10:47 AM, Huw Davies wrote:
> On Wed, Apr 25, 2018 at 07:27:36PM +0300, Nikolay Sivov wrote:
>> Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
>> ---
>>
>> This hopefully addresses comments I got for original patch. It takes
>> handle on input, and returns locked menu data and item pointer in a single
>> structure.
>>
>> dlls/user32/menu.c | 566 ++++++++++++++++++++++++++++-----------------
>> 1 file changed, 359 insertions(+), 207 deletions(-)
>>
>> diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
>> index 537c2ebe1a..5778af2a0a 100644
>> --- a/dlls/user32/menu.c
>> +++ b/dlls/user32/menu.c
>> @@ -584,7 +584,12 @@ static UINT MENU_GetStartOfPrevColumn(
>> return i;
>> }
>>
>> -
>> +struct menu_item_desc
>> +{
>> + MENUITEM *item;
>> + POPUPMENU *menu;
>> + UINT id;
>> +};
>>
>> /***********************************************************************
>> * MENU_FindItem
>> @@ -592,18 +597,29 @@ static UINT MENU_GetStartOfPrevColumn(
>> * Find a menu item. Return a pointer on the item, and modifies *hmenu
>> * in case the item was in a sub-menu.
>> */
>> -static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
>> +static BOOL MENU_FindItem(HMENU hmenu, UINT wFlags, struct menu_item_desc *desc)
>> {
> IMHO using the 'id' member of desc as an [in,out] param is confusing,
> not least because of its name. I'd suggest changing the name to 'pos'
> and using it as [out]-only, then adding a UINT 'id' parameter to the
> function.
Ok, that makes sense.
>
> Huw.
April 30, 2018
[v3 PATCH] user32/menu: Return locked menu data when looking for menu items.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
v3: changed helper prototype, it's closer to what we currently have. All structure
members are out-only now.
dlls/user32/menu.c | 550 +++++++++++++++++++++++++++------------------
1 file changed, 337 insertions(+), 213 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 537c2ebe1a..8a50067063 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -584,26 +584,39 @@ static UINT MENU_GetStartOfPrevColumn(
return i;
}
-
+struct menu_item_desc
+{
+ MENUITEM *item;
+ POPUPMENU *menu;
+ UINT pos;
+};
/***********************************************************************
* MENU_FindItem
- *
- * Find a menu item. Return a pointer on the item, and modifies *hmenu
- * in case the item was in a sub-menu.
*/
-static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
+static BOOL MENU_FindItem(HMENU hmenu, UINT id, UINT flags, struct menu_item_desc *desc)
{
+ UINT fallback_pos = ~0u, i;
POPUPMENU *menu;
- MENUITEM *fallback = NULL;
- UINT fallback_pos = 0;
- UINT i;
- if ((*hmenu == (HMENU)0xffff) || (!(menu = MENU_GetMenu(*hmenu)))) return NULL;
- if (wFlags & MF_BYPOSITION)
+ memset(desc, 0, sizeof(*desc));
+
+ menu = grab_menu_ptr(hmenu);
+ if (!menu)
+ return FALSE;
+
+ if (flags & MF_BYPOSITION)
{
- if (*nPos >= menu->nItems) return NULL;
- return &menu->items[*nPos];
+ if (id >= menu->nItems)
+ {
+ release_menu_ptr(menu);
+ return FALSE;
+ }
+
+ desc->menu = menu;
+ desc->item = &menu->items[id];
+ desc->pos = id;
+ return TRUE;
}
else
{
@@ -612,32 +625,37 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
{
if (item->fType & MF_POPUP)
{
- HMENU hsubmenu = item->hSubMenu;
- MENUITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags );
- if (subitem)
- {
- *hmenu = hsubmenu;
- return subitem;
- }
- else if (item->wID == *nPos)
+ if (MENU_FindItem(item->hSubMenu, id, flags, desc))
+ {
+ release_menu_ptr(menu);
+ return TRUE;
+ }
+ else if (item->wID == id)
{
/* fallback to this item if nothing else found */
fallback_pos = i;
- fallback = item;
}
}
- else if (item->wID == *nPos)
+ else if (item->wID == id)
{
- *nPos = i;
- return item;
+ desc->menu = menu;
+ desc->item = item;
+ desc->pos = i;
+ return TRUE;
}
}
}
- if (fallback)
- *nPos = fallback_pos;
+ if (fallback_pos != ~0u)
+ {
+ desc->menu = menu;
+ desc->item = &menu->items[fallback_pos];
+ desc->pos = fallback_pos;
+ }
+ else
+ release_menu_ptr(menu);
- return fallback;
+ return fallback_pos != ~0u;
}
/***********************************************************************
@@ -2135,28 +2153,34 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
*
* Insert (allocate) a new item into a menu.
*/
-static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags )
+static BOOL MENU_InsertItem(HMENU hMenu, UINT id, UINT flags, struct menu_item_desc *desc)
{
+ UINT pos = id;
MENUITEM *newItems;
POPUPMENU *menu;
- if (!(menu = MENU_GetMenu(hMenu)))
- return NULL;
+ memset(desc, 0, sizeof(*desc));
/* Find where to insert new item */
-
if (flags & MF_BYPOSITION) {
- if (pos > menu->nItems)
+ menu = grab_menu_ptr(hMenu);
+ if (id > menu->nItems)
pos = menu->nItems;
} else {
- if (!MENU_FindItem( &hMenu, &pos, flags ))
+ struct menu_item_desc item_desc;
+
+ if (!MENU_FindItem(hMenu, id, flags, &item_desc))
+ {
+ menu = grab_menu_ptr(hMenu);
pos = menu->nItems;
- else {
- if (!(menu = MENU_GetMenu( hMenu )))
- return NULL;
}
+ else
+ menu = item_desc.menu;
}
+ if (!menu)
+ return FALSE;
+
/* Make sure that MDI system buttons stay on the right side.
* Note: XP treats only bitmap handles 1 - 6 as "magic" ones
* regardless of their id.
@@ -2172,8 +2196,9 @@ static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags )
newItems = HeapAlloc( GetProcessHeap(), 0, sizeof(MENUITEM) * (menu->nItems+1) );
if (!newItems)
{
+ release_menu_ptr(menu);
WARN("allocation failed\n" );
- return NULL;
+ return FALSE;
}
if (menu->nItems > 0)
{
@@ -2187,7 +2212,12 @@ static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags )
menu->nItems++;
memset( &newItems[pos], 0, sizeof(*newItems) );
menu->Height = 0; /* force size recalculate */
- return &newItems[pos];
+
+ desc->menu = menu;
+ desc->pos = pos;
+ desc->item = &newItems[pos];
+
+ return TRUE;
}
@@ -3706,13 +3736,14 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UINT pos, LPCWSTR data,
*/
DWORD WINAPI CheckMenuItem( HMENU hMenu, UINT id, UINT flags )
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
DWORD ret;
- if (!(item = MENU_FindItem( &hMenu, &id, flags ))) return -1;
- ret = item->fState & MF_CHECKED;
- if (flags & MF_CHECKED) item->fState |= MF_CHECKED;
- else item->fState &= ~MF_CHECKED;
+ if (!MENU_FindItem(hMenu, id, flags, &item_desc)) return -1;
+ ret = item_desc.item->fState & MF_CHECKED;
+ if (flags & MF_CHECKED) item_desc.item->fState |= MF_CHECKED;
+ else item_desc.item->fState &= ~MF_CHECKED;
+ release_menu_ptr(item_desc.menu);
return ret;
}
@@ -3720,42 +3751,46 @@ DWORD WINAPI CheckMenuItem( HMENU hMenu, UINT id, UINT flags )
/**********************************************************************
* EnableMenuItem (USER32.@)
*/
-BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
+BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
{
+ struct menu_item_desc item_desc;
UINT oldflags;
- MENUITEM *item;
- POPUPMENU *menu;
- TRACE("(%p, %04x, %04x) !\n", hMenu, wItemID, wFlags);
+ TRACE("(%p, %04x, %04x)\n", hMenu, id, wFlags);
/* Get the Popupmenu to access the owner menu */
- if (!(menu = MENU_GetMenu(hMenu)))
- return (UINT)-1;
-
- if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags )))
+ if (!MENU_FindItem(hMenu, id, wFlags, &item_desc))
return (UINT)-1;
- oldflags = item->fState & (MF_GRAYED | MF_DISABLED);
- item->fState ^= (oldflags ^ wFlags) & (MF_GRAYED | MF_DISABLED);
+ oldflags = item_desc.item->fState & (MF_GRAYED | MF_DISABLED);
+ item_desc.item->fState ^= (oldflags ^ wFlags) & (MF_GRAYED | MF_DISABLED);
/* If the close item in the system menu change update the close button */
- if((item->wID == SC_CLOSE) && (oldflags != wFlags))
+ if ((item_desc.item->wID == SC_CLOSE) && (oldflags != wFlags))
{
- if (menu->hSysMenuOwner != 0)
+ if (item_desc.menu->hSysMenuOwner)
{
RECT rc;
POPUPMENU* parentMenu;
+ HWND hwnd;
/* Get the parent menu to access*/
- if (!(parentMenu = MENU_GetMenu(menu->hSysMenuOwner)))
- return (UINT)-1;
+ parentMenu = grab_menu_ptr(item_desc.menu->hSysMenuOwner);
+ release_menu_ptr(item_desc.menu);
+ if (!parentMenu)
+ return (UINT)-1;
+
+ hwnd = parentMenu->hWnd;
+ release_menu_ptr(parentMenu);
/* Refresh the frame to reflect the change */
- WIN_GetRectangles( parentMenu->hWnd, COORDS_CLIENT, &rc, NULL );
+ WIN_GetRectangles( hwnd, COORDS_CLIENT, &rc, NULL );
rc.bottom = 0;
- RedrawWindow(parentMenu->hWnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
+ RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
}
+ else
+ release_menu_ptr(item_desc.menu);
return oldflags;
}
@@ -3770,21 +3805,33 @@ INT WINAPI GetMenuStringA(
LPSTR str, /* [out] outbuffer. If NULL, func returns entry length*/
INT nMaxSiz, /* [in] length of buffer. if 0, func returns entry len*/
UINT wFlags /* [in] MF_ flags */
-) {
- MENUITEM *item;
+)
+{
+ struct menu_item_desc item_desc;
+ INT ret;
TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags );
if (str && nMaxSiz) str[0] = '\0';
- if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) {
+
+ if (!MENU_FindItem(hMenu, wItemID, wFlags, &item_desc)) {
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return 0;
}
- if (!item->text) return 0;
- if (!str || !nMaxSiz) return WideCharToMultiByte( CP_ACP, 0, item->text, -1, NULL, 0, NULL, NULL );
- if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1, str, nMaxSiz, NULL, NULL ))
- str[nMaxSiz-1] = 0;
+
+ if (!item_desc.item->text)
+ ret = 0;
+ else if (!str || !nMaxSiz)
+ ret = WideCharToMultiByte( CP_ACP, 0, item_desc.item->text, -1, NULL, 0, NULL, NULL );
+ else
+ {
+ if (!WideCharToMultiByte( CP_ACP, 0, item_desc.item->text, -1, str, nMaxSiz, NULL, NULL ))
+ str[nMaxSiz-1] = 0;
+ ret = strlen(str);
+ }
+ release_menu_ptr(item_desc.menu);
+
TRACE("returning %s\n", debugstr_a(str));
- return strlen(str);
+ return ret;
}
@@ -3794,22 +3841,32 @@ INT WINAPI GetMenuStringA(
INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID,
LPWSTR str, INT nMaxSiz, UINT wFlags )
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
+ INT ret;
TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags );
if (str && nMaxSiz) str[0] = '\0';
- if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) {
+
+ if (!MENU_FindItem(hMenu, wItemID, wFlags, &item_desc)) {
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return 0;
}
- if (!str || !nMaxSiz) return item->text ? strlenW(item->text) : 0;
- if( !(item->text)) {
+ if (!str || !nMaxSiz)
+ ret = item_desc.item->text ? strlenW(item_desc.item->text) : 0;
+ else if (!item_desc.item->text)
+ {
str[0] = 0;
- return 0;
+ ret = 0;
}
- lstrcpynW( str, item->text, nMaxSiz );
+ else
+ {
+ lstrcpynW( str, item_desc.item->text, nMaxSiz );
+ ret = strlenW(str);
+ }
+ release_menu_ptr(item_desc.menu);
+
TRACE("returning %s\n", debugstr_w(str));
- return strlenW(str);
+ return ret;
}
@@ -3819,13 +3876,18 @@ INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID,
BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
UINT wHilite )
{
- LPPOPUPMENU menu;
+ struct menu_item_desc item_desc;
+
TRACE("(%p, %p, %04x, %04x);\n", hWnd, hMenu, wItemID, wHilite);
- if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE;
- if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
- if (menu->FocusedItem == wItemID) return TRUE;
- MENU_HideSubPopups( hWnd, hMenu, FALSE, 0 );
- MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 );
+
+ if (!MENU_FindItem(hMenu, wItemID, wHilite, &item_desc)) return FALSE;
+
+ if (item_desc.menu->FocusedItem != item_desc.pos)
+ {
+ MENU_HideSubPopups( hWnd, item_desc.menu->obj.handle, FALSE, 0 );
+ MENU_SelectItem( hWnd, item_desc.menu->obj.handle, item_desc.pos, TRUE, 0 );
+ }
+ release_menu_ptr(item_desc.menu);
return TRUE;
}
@@ -3835,23 +3897,31 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
*/
UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags )
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
+ UINT state;
+
TRACE("(menu=%p, id=%04x, flags=%04x);\n", hMenu, wItemID, wFlags);
- if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
- debug_print_menuitem (" item: ", item, "");
- if (item->fType & MF_POPUP)
+
+ if (!MENU_FindItem(hMenu, wItemID, wFlags, &item_desc)) return -1;
+ debug_print_menuitem (" item: ", item_desc.item, "");
+ if (item_desc.item->fType & MF_POPUP)
{
- POPUPMENU *menu = MENU_GetMenu( item->hSubMenu );
- if (!menu) return -1;
- else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff);
+ POPUPMENU *submenu = grab_menu_ptr(item_desc.item->hSubMenu);
+ if (submenu)
+ state = (submenu->nItems << 8) | ((item_desc.item->fState | item_desc.item->fType) & 0xff);
+ else
+ state = -1;
+ release_menu_ptr(submenu);
}
else
{
/* We used to (from way back then) mask the result to 0xff. */
/* I don't know why and it seems wrong as the documented */
/* return flag MF_SEPARATOR is outside that mask. */
- return (item->fType | item->fState);
+ state = (item_desc.item->fType | item_desc.item->fState);
}
+ release_menu_ptr(item_desc.menu);
+ return state;
}
@@ -3877,12 +3947,14 @@ INT WINAPI GetMenuItemCount( HMENU hMenu )
*/
UINT WINAPI GetMenuItemID( HMENU hMenu, INT nPos )
{
- MENUITEM * lpmi;
+ struct menu_item_desc item_desc;
+ UINT id;
- if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return -1;
- if (lpmi->fType & MF_POPUP) return -1;
- return lpmi->wID;
+ if (!MENU_FindItem(hMenu, nPos, MF_BYPOSITION, &item_desc)) return -1;
+ id = item_desc.item->fType & MF_POPUP ? -1 : item_desc.item->wID;
+ release_menu_ptr(item_desc.menu);
+ return id;
}
@@ -3935,8 +4007,9 @@ static void MENU_mnu2mnuii( UINT flags, UINT_PTR id, LPCWSTR str,
BOOL WINAPI InsertMenuW( HMENU hMenu, UINT pos, UINT flags,
UINT_PTR id, LPCWSTR str )
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
MENUITEMINFOW mii;
+ BOOL ret;
if (IS_STRING_ITEM(flags) && str)
TRACE("hMenu %p, pos %d, flags %08x, id %04lx, str %s\n",
@@ -3944,16 +4017,17 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UINT pos, UINT flags,
else TRACE("hMenu %p, pos %d, flags %08x, id %04lx, str %p (not a string)\n",
hMenu, pos, flags, id, str );
- if (!(item = MENU_InsertItem( hMenu, pos, flags ))) return FALSE;
+ if (!MENU_InsertItem(hMenu, pos, flags, &item_desc)) return FALSE;
MENU_mnu2mnuii( flags, id, str, &mii);
- if (!(SetMenuItemInfo_common( item, &mii, TRUE)))
- {
+
+ ret = SetMenuItemInfo_common( item_desc.item, &mii, TRUE);
+ if (ret)
+ item_desc.item->hCheckBit = item_desc.item->hUnCheckBit = 0;
+ else
RemoveMenu( hMenu, pos, flags );
- return FALSE;
- }
+ release_menu_ptr(item_desc.menu);
- item->hCheckBit = item->hUnCheckBit = 0;
- return TRUE;
+ return ret;
}
@@ -4006,35 +4080,37 @@ BOOL WINAPI AppendMenuW( HMENU hMenu, UINT flags,
*/
BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
{
- LPPOPUPMENU menu;
- MENUITEM *item;
+ struct menu_item_desc item_desc;
TRACE("(menu=%p pos=%04x flags=%04x)\n",hMenu, nPos, wFlags);
- if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
- if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
- /* Remove item */
+ if (!MENU_FindItem(hMenu, nPos, wFlags, &item_desc))
+ return FALSE;
- MENU_FreeItemData( item );
+ /* Remove item */
+ MENU_FreeItemData( item_desc.item );
- if (--menu->nItems == 0)
+ if (--item_desc.menu->nItems == 0)
{
- HeapFree( GetProcessHeap(), 0, menu->items );
- menu->items = NULL;
+ HeapFree( GetProcessHeap(), 0, item_desc.menu->items );
+ item_desc.menu->items = NULL;
}
else
{
- MENUITEM *new_items;
- while(nPos < menu->nItems)
+ MENUITEM *new_items, *item = item_desc.item;
+
+ while (nPos < item_desc.menu->nItems)
{
*item = *(item+1);
item++;
nPos++;
}
- new_items = HeapReAlloc( GetProcessHeap(), 0, menu->items,
- menu->nItems * sizeof(MENUITEM) );
- if (new_items) menu->items = new_items;
+ new_items = HeapReAlloc( GetProcessHeap(), 0, item_desc.menu->items,
+ item_desc.menu->nItems * sizeof(MENUITEM) );
+ if (new_items) item_desc.menu->items = new_items;
}
+ release_menu_ptr(item_desc.menu);
+
return TRUE;
}
@@ -4044,11 +4120,17 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
*/
BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags )
{
- MENUITEM *item = MENU_FindItem( &hMenu, &nPos, wFlags );
- if (!item) return FALSE;
- if (item->fType & MF_POPUP) DestroyMenu( item->hSubMenu );
- /* nPos is now the position of the item */
- RemoveMenu( hMenu, nPos, wFlags | MF_BYPOSITION );
+ struct menu_item_desc item_desc;
+
+ if (!MENU_FindItem(hMenu, nPos, wFlags, &item_desc))
+ return FALSE;
+
+ if (item_desc.item->fType & MF_POPUP)
+ DestroyMenu(item_desc.item->hSubMenu);
+
+ /* nPos is now the position of the item */
+ RemoveMenu(item_desc.menu->obj.handle, item_desc.pos, wFlags | MF_BYPOSITION);
+ release_menu_ptr(item_desc.menu);
return TRUE;
}
@@ -4059,23 +4141,26 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags )
BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
UINT_PTR id, LPCWSTR str )
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
MENUITEMINFOW mii;
+ BOOL ret;
if (IS_STRING_ITEM(flags))
TRACE("%p %d %04x %04lx %s\n", hMenu, pos, flags, id, debugstr_w(str) );
else
TRACE("%p %d %04x %04lx %p\n", hMenu, pos, flags, id, str );
- if (!(item = MENU_FindItem( &hMenu, &pos, flags )))
+ if (!MENU_FindItem(hMenu, pos, flags, &item_desc))
{
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
if (pos == SC_TASKLIST && !(flags & MF_BYPOSITION)) return TRUE;
return FALSE;
}
- MENU_GetMenu(hMenu)->Height = 0; /* force size recalculate */
+ item_desc.menu->Height = 0; /* force size recalculate */
MENU_mnu2mnuii( flags, id, str, &mii);
- return SetMenuItemInfo_common( item, &mii, TRUE);
+ ret = SetMenuItemInfo_common(item_desc.item, &mii, TRUE);
+ release_menu_ptr(item_desc.menu);
+ return ret;
}
@@ -4134,20 +4219,22 @@ DWORD WINAPI GetMenuCheckMarkDimensions(void)
BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags,
HBITMAP hNewUnCheck, HBITMAP hNewCheck)
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
- if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+ if (!MENU_FindItem(hMenu, nPos, wFlags, &item_desc)) return FALSE;
if (!hNewCheck && !hNewUnCheck)
{
- item->fState &= ~MF_USECHECKBITMAPS;
+ item_desc.item->fState &= ~MF_USECHECKBITMAPS;
}
else /* Install new bitmaps */
{
- item->hCheckBit = hNewCheck;
- item->hUnCheckBit = hNewUnCheck;
- item->fState |= MF_USECHECKBITMAPS;
+ item_desc.item->hCheckBit = hNewCheck;
+ item_desc.item->hUnCheckBit = hNewUnCheck;
+ item_desc.item->fState |= MF_USECHECKBITMAPS;
}
+ release_menu_ptr(item_desc.menu);
+
return TRUE;
}
@@ -4418,11 +4505,18 @@ BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
*/
HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos )
{
- MENUITEM * lpmi;
+ struct menu_item_desc item_desc;
+ HMENU submenu;
+
+ if (!MENU_FindItem(hMenu, nPos, MF_BYPOSITION, &item_desc)) return 0;
+
+ if (item_desc.item->fType & MF_POPUP)
+ submenu = item_desc.item->hSubMenu;
+ else
+ submenu = 0;
- if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return 0;
- if (!(lpmi->fType & MF_POPUP)) return 0;
- return lpmi->hSubMenu;
+ release_menu_ptr(item_desc.menu);
+ return submenu;
}
@@ -4634,28 +4728,32 @@ BOOL WINAPI IsMenu(HMENU hmenu)
static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
LPMENUITEMINFOW lpmii, BOOL unicode)
{
- MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos ? MF_BYPOSITION : 0);
+ struct menu_item_desc item_desc;
- debug_print_menuitem("GetMenuItemInfo_common: ", menu, "");
+ MENU_FindItem(hmenu, item, bypos ? MF_BYPOSITION : 0, &item_desc);
- if (!menu) {
+ debug_print_menuitem("GetMenuItemInfo_common: ", item_desc.item, "");
+
+ if (!item_desc.item)
+ {
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return FALSE;
}
if( lpmii->fMask & MIIM_TYPE) {
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
+ release_menu_ptr(item_desc.menu);
WARN("invalid combination of fMask bits used\n");
/* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
- lpmii->fType = menu->fType & MENUITEMINFO_TYPE_MASK;
- if (menu->hbmpItem && !IS_MAGIC_BITMAP(menu->hbmpItem))
+ lpmii->fType = item_desc.item->fType & MENUITEMINFO_TYPE_MASK;
+ if (item_desc.item->hbmpItem && !IS_MAGIC_BITMAP(item_desc.item->hbmpItem))
lpmii->fType |= MFT_BITMAP;
- lpmii->hbmpItem = menu->hbmpItem; /* not on Win9x/ME */
+ lpmii->hbmpItem = item_desc.item->hbmpItem; /* not on Win9x/ME */
if( lpmii->fType & MFT_BITMAP) {
- lpmii->dwTypeData = (LPWSTR) menu->hbmpItem;
+ lpmii->dwTypeData = (LPWSTR) item_desc.item->hbmpItem;
lpmii->cch = 0;
} else if( lpmii->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) {
/* this does not happen on Win9x/ME */
@@ -4666,7 +4764,7 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
/* copy the text string */
if ((lpmii->fMask & (MIIM_TYPE|MIIM_STRING))) {
- if( !menu->text ) {
+ if (!item_desc.item->text) {
if(lpmii->dwTypeData && lpmii->cch) {
if( unicode)
*((WCHAR *)lpmii->dwTypeData) = 0;
@@ -4678,16 +4776,16 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
int len;
if (unicode)
{
- len = strlenW(menu->text);
+ len = strlenW(item_desc.item->text);
if(lpmii->dwTypeData && lpmii->cch)
- lstrcpynW(lpmii->dwTypeData, menu->text, lpmii->cch);
+ lstrcpynW(lpmii->dwTypeData, item_desc.item->text, lpmii->cch);
}
else
{
- len = WideCharToMultiByte( CP_ACP, 0, menu->text, -1, NULL,
+ len = WideCharToMultiByte( CP_ACP, 0, item_desc.item->text, -1, NULL,
0, NULL, NULL ) - 1;
if(lpmii->dwTypeData && lpmii->cch)
- if (!WideCharToMultiByte( CP_ACP, 0, menu->text, -1,
+ if (!WideCharToMultiByte( CP_ACP, 0, item_desc.item->text, -1,
(LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL ))
((LPSTR)lpmii->dwTypeData)[lpmii->cch - 1] = 0;
}
@@ -4706,19 +4804,19 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
}
if (lpmii->fMask & MIIM_FTYPE)
- lpmii->fType = menu->fType & MENUITEMINFO_TYPE_MASK;
+ lpmii->fType = item_desc.item->fType & MENUITEMINFO_TYPE_MASK;
if (lpmii->fMask & MIIM_BITMAP)
- lpmii->hbmpItem = menu->hbmpItem;
+ lpmii->hbmpItem = item_desc.item->hbmpItem;
if (lpmii->fMask & MIIM_STATE)
- lpmii->fState = menu->fState & MENUITEMINFO_STATE_MASK;
+ lpmii->fState = item_desc.item->fState & MENUITEMINFO_STATE_MASK;
if (lpmii->fMask & MIIM_ID)
- lpmii->wID = menu->wID;
+ lpmii->wID = item_desc.item->wID;
if (lpmii->fMask & MIIM_SUBMENU)
- lpmii->hSubMenu = menu->hSubMenu;
+ lpmii->hSubMenu = item_desc.item->hSubMenu;
else {
/* hSubMenu is always cleared
* (not on Win9x/ME ) */
@@ -4726,13 +4824,14 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
}
if (lpmii->fMask & MIIM_CHECKMARKS) {
- lpmii->hbmpChecked = menu->hCheckBit;
- lpmii->hbmpUnchecked = menu->hUnCheckBit;
+ lpmii->hbmpChecked = item_desc.item->hCheckBit;
+ lpmii->hbmpUnchecked = item_desc.item->hUnCheckBit;
}
if (lpmii->fMask & MIIM_DATA)
- lpmii->dwItemData = menu->dwItemData;
+ lpmii->dwItemData = item_desc.item->dwItemData;
- return TRUE;
+ release_menu_ptr(item_desc.menu);
+ return TRUE;
}
/**********************************************************************
@@ -4949,20 +5048,23 @@ static BOOL MENU_NormalizeMenuItemInfoStruct( const MENUITEMINFOW *pmii_in,
BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
const MENUITEMINFOA *lpmii)
{
- MENUITEM *menuitem;
+ struct menu_item_desc item_desc;
MENUITEMINFOW mii;
+ BOOL ret;
TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE;
- if (!(menuitem = MENU_FindItem( &hmenu, &item, bypos? MF_BYPOSITION : 0 )))
+ if (!MENU_FindItem(hmenu, item, bypos ? MF_BYPOSITION : 0, &item_desc))
{
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
if (item == SC_TASKLIST && !bypos) return TRUE;
return FALSE;
}
- return SetMenuItemInfo_common( menuitem, &mii, FALSE );
+ ret = SetMenuItemInfo_common(item_desc.item, &mii, FALSE);
+ release_menu_ptr(item_desc.menu);
+ return ret;
}
/**********************************************************************
@@ -4971,19 +5073,24 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
BOOL WINAPI SetMenuItemInfoW(HMENU hmenu, UINT item, BOOL bypos,
const MENUITEMINFOW *lpmii)
{
- MENUITEM *menuitem;
+ struct menu_item_desc item_desc;
MENUITEMINFOW mii;
+ BOOL ret;
TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
if (!MENU_NormalizeMenuItemInfoStruct( lpmii, &mii )) return FALSE;
- if (!(menuitem = MENU_FindItem( &hmenu, &item, bypos? MF_BYPOSITION : 0 )))
+
+ if (!MENU_FindItem(hmenu, item, bypos ? MF_BYPOSITION : 0, &item_desc))
{
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
if (item == SC_TASKLIST && !bypos) return TRUE;
return FALSE;
}
- return SetMenuItemInfo_common( menuitem, &mii, TRUE );
+
+ ret = SetMenuItemInfo_common(item_desc.item, &mii, TRUE);
+ release_menu_ptr(item_desc.menu);
+ return ret;
}
static BOOL set_menu_default_item(POPUPMENU *menu, UINT uItem, UINT bypos)
@@ -5090,15 +5197,20 @@ UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags)
BOOL WINAPI InsertMenuItemA(HMENU hMenu, UINT uItem, BOOL bypos,
const MENUITEMINFOA *lpmii)
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
MENUITEMINFOW mii;
+ BOOL ret;
TRACE("hmenu %p, item %04x, by pos %d, info %p\n", hMenu, uItem, bypos, lpmii);
if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE;
- item = MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0 );
- return SetMenuItemInfo_common(item, &mii, FALSE);
+ if (!MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0, &item_desc))
+ return FALSE;
+
+ ret = SetMenuItemInfo_common(item_desc.item, &mii, FALSE);
+ release_menu_ptr(item_desc.menu);
+ return ret;
}
@@ -5108,64 +5220,71 @@ BOOL WINAPI InsertMenuItemA(HMENU hMenu, UINT uItem, BOOL bypos,
BOOL WINAPI InsertMenuItemW(HMENU hMenu, UINT uItem, BOOL bypos,
const MENUITEMINFOW *lpmii)
{
- MENUITEM *item;
+ struct menu_item_desc item_desc;
MENUITEMINFOW mii;
+ BOOL ret;
TRACE("hmenu %p, item %04x, by pos %d, info %p\n", hMenu, uItem, bypos, lpmii);
if (!MENU_NormalizeMenuItemInfoStruct( lpmii, &mii )) return FALSE;
- item = MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0 );
- return SetMenuItemInfo_common(item, &mii, TRUE);
+ if (!MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0, &item_desc))
+ return FALSE;
+
+ ret = SetMenuItemInfo_common(item_desc.item, &mii, TRUE);
+ release_menu_ptr(item_desc.menu);
+ return ret;
}
/**********************************************************************
* CheckMenuRadioItem (USER32.@)
*/
-BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
- UINT first, UINT last, UINT check,
- UINT bypos)
+BOOL WINAPI CheckMenuRadioItem(HMENU hMenu, UINT first, UINT last,
+ UINT check, UINT flags)
{
+ struct menu_item_desc first_item = { 0 }, check_item = { 0 };
BOOL done = FALSE;
UINT i;
- MENUITEM *mi_first = NULL, *mi_check;
- HMENU m_first, m_check;
for (i = first; i <= last; i++)
{
- UINT pos = i;
-
- if (!mi_first)
+ if (!first_item.menu)
{
- m_first = hMenu;
- mi_first = MENU_FindItem(&m_first, &pos, bypos);
- if (!mi_first) continue;
- mi_check = mi_first;
- m_check = m_first;
+ if (!MENU_FindItem(hMenu, i, flags, &first_item)) continue;
+
+ check_item = first_item;
+ check_item.menu = grab_menu_ptr(first_item.menu->obj.handle);
}
else
{
- m_check = hMenu;
- mi_check = MENU_FindItem(&m_check, &pos, bypos);
- if (!mi_check) continue;
+ if (!MENU_FindItem(hMenu, i, flags, &check_item)) continue;
}
- if (m_first != m_check) continue;
- if (mi_check->fType == MFT_SEPARATOR) continue;
-
- if (i == check)
+ if (first_item.menu != check_item.menu)
{
- mi_check->fType |= MFT_RADIOCHECK;
- mi_check->fState |= MFS_CHECKED;
- done = TRUE;
+ release_menu_ptr(check_item.menu);
+ continue;
}
- else
+
+ if (check_item.item->fType != MFT_SEPARATOR)
{
- /* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
- mi_check->fState &= ~MFS_CHECKED;
+ if (i == check)
+ {
+ check_item.item->fType |= MFT_RADIOCHECK;
+ check_item.item->fState |= MFS_CHECKED;
+ done = TRUE;
+ }
+ else
+ {
+ /* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
+ check_item.item->fState &= ~MFS_CHECKED;
+ }
}
+
+ release_menu_ptr(check_item.menu);
}
+ release_menu_ptr(first_item.menu);
return done;
}
@@ -5181,27 +5300,29 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
*/
BOOL WINAPI GetMenuItemRect(HWND hwnd, HMENU hMenu, UINT uItem, RECT *rect)
{
- POPUPMENU *menu;
- MENUITEM *item;
-
- TRACE("(%p,%p,%d,%p)\n", hwnd, hMenu, uItem, rect);
+ struct menu_item_desc item_desc;
- item = MENU_FindItem (&hMenu, &uItem, MF_BYPOSITION);
- if ((rect == NULL) || (item == NULL))
- return FALSE;
+ TRACE("(%p,%p,%d,%p)\n", hwnd, hMenu, uItem, rect);
- menu = MENU_GetMenu(hMenu);
- if (!menu) return FALSE;
+ if (!rect)
+ return FALSE;
- if (!hwnd) hwnd = menu->hWnd;
- if (!hwnd) return FALSE;
+ if (!MENU_FindItem(hMenu, uItem, MF_BYPOSITION, &item_desc))
+ return FALSE;
- *rect = item->rect;
+ if (!hwnd) hwnd = item_desc.menu->hWnd;
+ if (!hwnd)
+ {
+ release_menu_ptr(item_desc.menu);
+ return FALSE;
+ }
- OffsetRect(rect, menu->items_rect.left, menu->items_rect.top);
- MapWindowPoints(hwnd, 0, (POINT *)rect, 2);
+ *rect = item_desc.item->rect;
+ OffsetRect(rect, item_desc.menu->items_rect.left, item_desc.menu->items_rect.top);
+ release_menu_ptr(item_desc.menu);
- return TRUE;
+ MapWindowPoints(hwnd, 0, (POINT *)rect, 2);
+ return TRUE;
}
/**********************************************************************
@@ -5415,16 +5536,18 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
{
HMENU hMenu, hSubMenu, hSysMenu;
UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
+ struct menu_item_desc item_desc;
hMenu = (GetWindowLongW( hWnd, GWL_STYLE ) & WS_CHILD) ? 0 : GetMenu(hWnd);
hSysMenu = get_win_sys_menu( hWnd );
/* find menu item and ask application to initialize it */
/* 1. in the system menu */
- hSubMenu = hSysMenu;
- nPos = cmd;
- if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
+ if (MENU_FindItem(hSysMenu, cmd, MF_BYCOMMAND, &item_desc))
{
+ hSubMenu = item_desc.menu->obj.handle;
+ release_menu_ptr(item_desc.menu);
+
if (GetCapture())
mesg = 2;
if (!IsWindowEnabled(hWnd))
@@ -5443,10 +5566,11 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
}
else /* 2. in the window's menu */
{
- hSubMenu = hMenu;
- nPos = cmd;
- if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
+ if (MENU_FindItem(hMenu, cmd, MF_BYCOMMAND, &item_desc))
{
+ hSubMenu = item_desc.menu->obj.handle;
+ release_menu_ptr(item_desc.menu);
+
if (GetCapture())
mesg = 2;
if (!IsWindowEnabled(hWnd))
--
2.17.0
April 30, 2018
Re: [PATCH 2/2] msi: Don't load a custom action DLL in the main process.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
April 30, 2018