diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2021-12-27 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-03-18 15:35:13 +0500 |
commit | f19f813537c7aea1c20749c914e756b54a9c3cf5 (patch) | |
tree | 816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /CPP/Windows/Menu.cpp | |
parent | 98e06a519b63b81986abe76d28887f6984a7732b (diff) | |
download | 7zip-21.07.tar.gz 7zip-21.07.tar.bz2 7zip-21.07.zip |
'21.07'21.07
Diffstat (limited to 'CPP/Windows/Menu.cpp')
-rw-r--r-- | CPP/Windows/Menu.cpp | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/CPP/Windows/Menu.cpp b/CPP/Windows/Menu.cpp new file mode 100644 index 0000000..3ad6953 --- /dev/null +++ b/CPP/Windows/Menu.cpp | |||
@@ -0,0 +1,216 @@ | |||
1 | // Windows/Menu.cpp | ||
2 | |||
3 | #include "StdAfx.h" | ||
4 | |||
5 | #ifndef _UNICODE | ||
6 | #include "../Common/StringConvert.h" | ||
7 | #endif | ||
8 | #include "Menu.h" | ||
9 | |||
10 | #ifndef _UNICODE | ||
11 | extern bool g_IsNT; | ||
12 | #endif | ||
13 | |||
14 | namespace NWindows { | ||
15 | |||
16 | /* | ||
17 | structures | ||
18 | MENUITEMINFOA | ||
19 | MENUITEMINFOW | ||
20 | contain additional member: | ||
21 | #if (WINVER >= 0x0500) | ||
22 | HBITMAP hbmpItem; | ||
23 | #endif | ||
24 | If we compile the source code with (WINVER >= 0x0500), some functions | ||
25 | will not work at NT 4.0, if cbSize is set as sizeof(MENUITEMINFO*). | ||
26 | So we use size of old version of structure. */ | ||
27 | |||
28 | #if defined(UNDER_CE) || defined(_WIN64) || (WINVER < 0x0500) | ||
29 | #ifndef _UNICODE | ||
30 | #define my_compatib_MENUITEMINFOA_size sizeof(MENUITEMINFOA) | ||
31 | #endif | ||
32 | #define my_compatib_MENUITEMINFOW_size sizeof(MENUITEMINFOW) | ||
33 | #else | ||
34 | #define MY_STRUCT_SIZE_BEFORE(structname, member) ((UINT)(UINT_PTR)((LPBYTE)(&((structname*)0)->member) - (LPBYTE)(structname*)0)) | ||
35 | #ifndef _UNICODE | ||
36 | #define my_compatib_MENUITEMINFOA_size MY_STRUCT_SIZE_BEFORE(MENUITEMINFOA, hbmpItem) | ||
37 | #endif | ||
38 | #define my_compatib_MENUITEMINFOW_size MY_STRUCT_SIZE_BEFORE(MENUITEMINFOW, hbmpItem) | ||
39 | #endif | ||
40 | |||
41 | static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOW &si) | ||
42 | { | ||
43 | ZeroMemory(&si, sizeof(si)); | ||
44 | si.cbSize = my_compatib_MENUITEMINFOW_size; // sizeof(si); | ||
45 | si.fMask = item.fMask; | ||
46 | si.fType = item.fType; | ||
47 | si.fState = item.fState; | ||
48 | si.wID = item.wID; | ||
49 | si.hSubMenu = item.hSubMenu; | ||
50 | si.hbmpChecked = item.hbmpChecked; | ||
51 | si.hbmpUnchecked = item.hbmpUnchecked; | ||
52 | si.dwItemData = item.dwItemData; | ||
53 | } | ||
54 | |||
55 | #ifndef _UNICODE | ||
56 | static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOA &si) | ||
57 | { | ||
58 | ZeroMemory(&si, sizeof(si)); | ||
59 | si.cbSize = my_compatib_MENUITEMINFOA_size; // sizeof(si); | ||
60 | si.fMask = item.fMask; | ||
61 | si.fType = item.fType; | ||
62 | si.fState = item.fState; | ||
63 | si.wID = item.wID; | ||
64 | si.hSubMenu = item.hSubMenu; | ||
65 | si.hbmpChecked = item.hbmpChecked; | ||
66 | si.hbmpUnchecked = item.hbmpUnchecked; | ||
67 | si.dwItemData = item.dwItemData; | ||
68 | } | ||
69 | #endif | ||
70 | |||
71 | static void ConvertItemToMyForm(const MENUITEMINFOW &si, CMenuItem &item) | ||
72 | { | ||
73 | item.fMask = si.fMask; | ||
74 | item.fType = si.fType; | ||
75 | item.fState = si.fState; | ||
76 | item.wID = si.wID; | ||
77 | item.hSubMenu = si.hSubMenu; | ||
78 | item.hbmpChecked = si.hbmpChecked; | ||
79 | item.hbmpUnchecked = si.hbmpUnchecked; | ||
80 | item.dwItemData = si.dwItemData; | ||
81 | } | ||
82 | |||
83 | #ifndef _UNICODE | ||
84 | static void ConvertItemToMyForm(const MENUITEMINFOA &si, CMenuItem &item) | ||
85 | { | ||
86 | item.fMask = si.fMask; | ||
87 | item.fType = si.fType; | ||
88 | item.fState = si.fState; | ||
89 | item.wID = si.wID; | ||
90 | item.hSubMenu = si.hSubMenu; | ||
91 | item.hbmpChecked = si.hbmpChecked; | ||
92 | item.hbmpUnchecked = si.hbmpUnchecked; | ||
93 | item.dwItemData = si.dwItemData; | ||
94 | } | ||
95 | #endif | ||
96 | |||
97 | bool CMenu::GetItem(UINT itemIndex, bool byPosition, CMenuItem &item) | ||
98 | { | ||
99 | const UINT kMaxSize = 512; | ||
100 | #ifndef _UNICODE | ||
101 | if (!g_IsNT) | ||
102 | { | ||
103 | CHAR s[kMaxSize + 1]; | ||
104 | MENUITEMINFOA si; | ||
105 | ConvertItemToSysForm(item, si); | ||
106 | if (item.IsString()) | ||
107 | { | ||
108 | si.cch = kMaxSize; | ||
109 | si.dwTypeData = s; | ||
110 | } | ||
111 | if (GetItemInfo(itemIndex, byPosition, &si)) | ||
112 | { | ||
113 | ConvertItemToMyForm(si, item); | ||
114 | if (item.IsString()) | ||
115 | item.StringValue = GetUnicodeString(s); | ||
116 | return true; | ||
117 | } | ||
118 | } | ||
119 | else | ||
120 | #endif | ||
121 | { | ||
122 | wchar_t s[kMaxSize + 1]; | ||
123 | MENUITEMINFOW si; | ||
124 | ConvertItemToSysForm(item, si); | ||
125 | if (item.IsString()) | ||
126 | { | ||
127 | si.cch = kMaxSize; | ||
128 | si.dwTypeData = s; | ||
129 | } | ||
130 | if (GetItemInfo(itemIndex, byPosition, &si)) | ||
131 | { | ||
132 | ConvertItemToMyForm(si, item); | ||
133 | if (item.IsString()) | ||
134 | item.StringValue = s; | ||
135 | return true; | ||
136 | } | ||
137 | } | ||
138 | return false; | ||
139 | } | ||
140 | |||
141 | bool CMenu::SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item) | ||
142 | { | ||
143 | #ifndef _UNICODE | ||
144 | if (!g_IsNT) | ||
145 | { | ||
146 | MENUITEMINFOA si; | ||
147 | ConvertItemToSysForm(item, si); | ||
148 | AString s; | ||
149 | if (item.IsString()) | ||
150 | { | ||
151 | s = GetSystemString(item.StringValue); | ||
152 | si.dwTypeData = s.Ptr_non_const(); | ||
153 | } | ||
154 | return SetItemInfo(itemIndex, byPosition, &si); | ||
155 | } | ||
156 | else | ||
157 | #endif | ||
158 | { | ||
159 | MENUITEMINFOW si; | ||
160 | ConvertItemToSysForm(item, si); | ||
161 | if (item.IsString()) | ||
162 | si.dwTypeData = item.StringValue.Ptr_non_const(); | ||
163 | return SetItemInfo(itemIndex, byPosition, &si); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | bool CMenu::InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item) | ||
168 | { | ||
169 | #ifndef _UNICODE | ||
170 | if (!g_IsNT) | ||
171 | { | ||
172 | MENUITEMINFOA si; | ||
173 | ConvertItemToSysForm(item, si); | ||
174 | AString s; | ||
175 | if (item.IsString()) | ||
176 | { | ||
177 | s = GetSystemString(item.StringValue); | ||
178 | si.dwTypeData = s.Ptr_non_const(); | ||
179 | } | ||
180 | return InsertItem(itemIndex, byPosition, &si); | ||
181 | } | ||
182 | else | ||
183 | #endif | ||
184 | { | ||
185 | MENUITEMINFOW si; | ||
186 | ConvertItemToSysForm(item, si); | ||
187 | if (item.IsString()) | ||
188 | si.dwTypeData = item.StringValue.Ptr_non_const(); | ||
189 | #ifdef UNDER_CE | ||
190 | UINT flags = (item.fType & MFT_SEPARATOR) ? MF_SEPARATOR : MF_STRING; | ||
191 | UINT id = item.wID; | ||
192 | if ((item.fMask & MIIM_SUBMENU) != 0) | ||
193 | { | ||
194 | flags |= MF_POPUP; | ||
195 | id = (UINT)item.hSubMenu; | ||
196 | } | ||
197 | if (!Insert(itemIndex, flags | (byPosition ? MF_BYPOSITION : MF_BYCOMMAND), id, item.StringValue)) | ||
198 | return false; | ||
199 | return SetItemInfo(itemIndex, byPosition, &si); | ||
200 | #else | ||
201 | return InsertItem(itemIndex, byPosition, &si); | ||
202 | #endif | ||
203 | } | ||
204 | } | ||
205 | |||
206 | #ifndef _UNICODE | ||
207 | bool CMenu::AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem) | ||
208 | { | ||
209 | if (g_IsNT) | ||
210 | return BOOLToBool(::AppendMenuW(_menu, flags, newItemID, newItem)); | ||
211 | else | ||
212 | return AppendItem(flags, newItemID, GetSystemString(newItem)); | ||
213 | } | ||
214 | #endif | ||
215 | |||
216 | } | ||