aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows/Menu.cpp
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2021-12-27 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2022-03-18 15:35:13 +0500
commitf19f813537c7aea1c20749c914e756b54a9c3cf5 (patch)
tree816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /CPP/Windows/Menu.cpp
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-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.cpp216
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
11extern bool g_IsNT;
12#endif
13
14namespace NWindows {
15
16/*
17structures
18 MENUITEMINFOA
19 MENUITEMINFOW
20contain additional member:
21 #if (WINVER >= 0x0500)
22 HBITMAP hbmpItem;
23 #endif
24If we compile the source code with (WINVER >= 0x0500), some functions
25will not work at NT 4.0, if cbSize is set as sizeof(MENUITEMINFO*).
26So 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
41static 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
56static 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
71static 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
84static 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
97bool 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
141bool 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
167bool 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
207bool 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}