Update wine to 1.2.
[sugaredwine.git] / patches / 0018-explorer-add-Exit-menu-item.patch
blob7d5226c7e67f20d36921ea562619f953b0ee28ac
1 From 04f31c57b4d78fe81e4b142f0cfb9e2759ee1f40 Mon Sep 17 00:00:00 2001
2 From: Vincent Povirk <vincent@codeweavers.com>
3 Date: Fri, 26 Sep 2008 14:53:51 -0500
4 Subject: [PATCH] explorer: add "Exit" menu item
6 ---
7 programs/explorer/startmenu.c | 77 +++++++++++++++++++++++++++++++++++------
8 1 files changed, 66 insertions(+), 11 deletions(-)
10 diff --git a/programs/explorer/startmenu.c b/programs/explorer/startmenu.c
11 index f2a0b28..fcf9935 100644
12 --- a/programs/explorer/startmenu.c
13 +++ b/programs/explorer/startmenu.c
14 @@ -26,6 +26,7 @@
15 #include <shlwapi.h>
16 #include <shobjidl.h>
17 #include "wine/debug.h"
18 +#include "wine/unicode.h"
19 #include "wine/list.h"
20 #include "explorer_private.h"
22 @@ -37,6 +38,7 @@ struct menu_item
23 BOOL initialized;
24 LPWSTR displayname;
25 HICON icon;
26 + void (*on_click)(); /* for items without a PIDL, execute this function */
28 /* parent information */
29 struct menu_item* parent; /* NULL for paths that don't have a parent menu */
30 @@ -98,17 +100,24 @@ static void exec_item(struct menu_item* item)
31 LPITEMIDLIST abs_pidl;
32 SHELLEXECUTEINFOW sei;
34 - abs_pidl = build_pidl(item);
36 - ZeroMemory(&sei, sizeof(sei));
37 - sei.cbSize = sizeof(sei);
38 - sei.fMask = SEE_MASK_IDLIST|SEE_MASK_NO_CONSOLE;
39 - sei.nShow = SW_SHOWNORMAL;
40 - sei.lpIDList = abs_pidl;
42 - ShellExecuteExW(&sei);
44 - CoTaskMemFree(abs_pidl);
45 + if (item->on_click)
46 + {
47 + item->on_click();
48 + }
49 + else
50 + {
51 + abs_pidl = build_pidl(item);
53 + ZeroMemory(&sei, sizeof(sei));
54 + sei.cbSize = sizeof(sei);
55 + sei.fMask = SEE_MASK_IDLIST|SEE_MASK_NO_CONSOLE;
56 + sei.nShow = SW_SHOWNORMAL;
57 + sei.lpIDList = abs_pidl;
59 + ShellExecuteExW(&sei);
61 + CoTaskMemFree(abs_pidl);
62 + }
65 static HICON extract_icon(IShellFolder* parent, LPCITEMIDLIST pidl, HWND hwnd)
66 @@ -355,6 +364,41 @@ static struct menu_item* add_items(struct menu_item* parent, struct menu_item* u
67 return parent;
70 +/* add an item that executes a function intead of a PIDL */
71 +static struct menu_item* add_special_item(struct menu_item* parent, struct menu_item* user_parent, LPWSTR displayname, void (*on_click)(), HICON icon, HWND hwnd)
73 + struct menu_item* item;
74 + MENUITEMINFOW mii;
76 + item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct menu_item));
77 + item->displayname = displayname;
78 + item->icon = icon;
79 + item->parent = parent;
80 + item->on_click = on_click;
82 + mii.cbSize = sizeof(mii);
83 + mii.fMask = MIIM_STRING|MIIM_DATA;
84 + mii.dwTypeData = item->displayname;
85 + mii.dwItemData = (DWORD)item;
87 + if (item->icon)
88 + {
89 + mii.fMask |= MIIM_BITMAP;
90 + mii.hbmpItem = HBMMENU_CALLBACK;
91 + }
93 + InsertMenuItemW(parent?parent->menuhandle:topmenu, -1, TRUE, &mii);
95 + list_add_tail(&items, &item->entry);
97 + return item;
100 +static void exit_windows()
102 + ExitWindows(0, 0);
105 static void destroy_menus()
107 if (!topmenu)
108 @@ -470,6 +514,8 @@ void do_startmenu(HWND hwnd, HWND button)
109 MENUINFO mi;
110 RECT rc={0,0,0,0};
111 TPMPARAMS tpm;
112 + static WCHAR Exit[] = {'E','x','i','t',0};
113 + LPWSTR exit_str;
115 /* FIXME: Our existing menu is never destroyed if the user makes no
116 selection. It seems to be impossible to detect this situation. */
117 @@ -507,6 +553,15 @@ void do_startmenu(HWND hwnd, HWND button)
118 add_item(NULL, NULL, pidl, hwnd);
121 + /* separator */
122 + AppendMenuW(topmenu, MF_SEPARATOR, 0, NULL);
124 + /* since we'll be using LoadString for this, the "Exit" caption will be
125 + heap-allocated; for now I just make a copy of the string */
126 + exit_str = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (strlenW(Exit)+1));
127 + strcpyW(exit_str, Exit);
128 + add_special_item(NULL, NULL, exit_str, exit_windows, NULL, hwnd);
130 mi.cbSize = sizeof(mi);
131 mi.fMask = MIM_STYLE;
132 mi.dwStyle = MNS_NOTIFYBYPOS|MNS_CHECKORBMP;
134 1.5.6.5