1 // FarUtils.cpp
2
3 #include "StdAfx.h"
4
5 // #include "../../../Common/IntToString.h"
6 #include "../../../Common/StringConvert.h"
7
8 #ifndef UNDER_CE
9 #include "../../../Windows/Console.h"
10 #endif
11 #include "../../../Windows/Defs.h"
12 #include "../../../Windows/ErrorMsg.h"
13
14 #include "FarUtils.h"
15
16 using namespace NWindows;
17
18 namespace NFar {
19
20 CStartupInfo g_StartupInfo;
21
22 const char kRegistryKeyDelimiter = '\\';
23
Init(const PluginStartupInfo & pluginStartupInfo,const char * pluginNameForRegistry)24 void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo,
25 const char *pluginNameForRegistry)
26 {
27 m_Data = pluginStartupInfo;
28 m_RegistryPath = pluginStartupInfo.RootKey;
29 m_RegistryPath += kRegistryKeyDelimiter;
30 m_RegistryPath += pluginNameForRegistry;
31 }
32
GetMsgString(int messageId)33 const char *CStartupInfo::GetMsgString(int messageId)
34 {
35 return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId);
36 }
37
ShowMessage(UInt32 flags,const char * helpTopic,const char ** items,unsigned numItems,int numButtons)38 int CStartupInfo::ShowMessage(UInt32 flags,
39 const char *helpTopic, const char **items, unsigned numItems, int numButtons)
40 {
41 return m_Data.Message(m_Data.ModuleNumber, flags, helpTopic,
42 items, (int)numItems, numButtons);
43 }
44
45 namespace NMessageID
46 {
47 enum
48 {
49 kOk,
50 kCancel,
51 kWarning,
52 kError
53 };
54 }
55
ShowWarningWithOk(const char ** items,unsigned numItems)56 int CStartupInfo::ShowWarningWithOk(const char **items, unsigned numItems)
57 {
58 return ShowMessage(FMSG_WARNING | FMSG_MB_OK, NULL, items, numItems, 0);
59 }
60
61 extern const char *g_PluginName_for_Error;
62
SetErrorTitle(AString & s)63 void CStartupInfo::SetErrorTitle(AString &s)
64 {
65 if (g_PluginName_for_Error)
66 {
67 s += g_PluginName_for_Error;
68 s += ": ";
69 }
70 s += GetMsgString(NMessageID::kError);
71 }
72
73 /*
74 int CStartupInfo::ShowErrorMessage(const char *message)
75 {
76 AString s;
77 SetErrorTitle(s);
78 const char *items[]= { s, message };
79 return ShowWarningWithOk(items, Z7_ARRAY_SIZE(items));
80 }
81 */
82
ShowErrorMessage2(const char * m1,const char * m2)83 int CStartupInfo::ShowErrorMessage2(const char *m1, const char *m2)
84 {
85 AString s;
86 SetErrorTitle(s);
87 const char *items[]= { s, m1, m2 };
88 return ShowWarningWithOk(items, Z7_ARRAY_SIZE(items));
89 }
90
SplitString(const AString & src,AStringVector & destStrings)91 static void SplitString(const AString &src, AStringVector &destStrings)
92 {
93 destStrings.Clear();
94 AString s;
95 unsigned len = src.Len();
96 if (len == 0)
97 return;
98 for (unsigned i = 0; i < len; i++)
99 {
100 char c = src[i];
101 if (c == '\n')
102 {
103 if (!s.IsEmpty())
104 {
105 destStrings.Add(s);
106 s.Empty();
107 }
108 }
109 else
110 s += c;
111 }
112 if (!s.IsEmpty())
113 destStrings.Add(s);
114 }
115
ShowErrorMessage(const char * message)116 int CStartupInfo::ShowErrorMessage(const char *message)
117 {
118 AStringVector strings;
119 SplitString((AString)message, strings);
120 const unsigned kNumStringsMax = 20;
121 const char *items[kNumStringsMax + 1];
122 unsigned pos = 0;
123 items[pos++] = GetMsgString(NMessageID::kError);
124 for (unsigned i = 0; i < strings.Size() && pos < kNumStringsMax; i++)
125 items[pos++] = strings[i];
126 items[pos++] = GetMsgString(NMessageID::kOk);
127
128 return ShowMessage(FMSG_WARNING, NULL, items, pos, 1);
129 }
130
131 /*
132 int CStartupInfo::ShowMessageLines(const char *message)
133 {
134 AString s = GetMsgString(NMessageID::kError);
135 s.Add_LF();
136 s += message;
137 return ShowMessage(FMSG_WARNING | FMSG_MB_OK | FMSG_ALLINONE, NULL,
138 (const char **)(const char *)s, 1, 0);
139 }
140 */
141
ShowMessage(int messageId)142 int CStartupInfo::ShowMessage(int messageId)
143 {
144 return ShowErrorMessage(GetMsgString(messageId));
145 }
146
ShowDialog(int X1,int Y1,int X2,int Y2,const char * helpTopic,struct FarDialogItem * items,unsigned numItems)147 int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2,
148 const char *helpTopic, struct FarDialogItem *items, unsigned numItems)
149 {
150 return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, const_cast<char *>(helpTopic),
151 items, (int)numItems);
152 }
153
ShowDialog(int sizeX,int sizeY,const char * helpTopic,struct FarDialogItem * items,unsigned numItems)154 int CStartupInfo::ShowDialog(int sizeX, int sizeY,
155 const char *helpTopic, struct FarDialogItem *items, unsigned numItems)
156 {
157 return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems);
158 }
159
GetBOOLValue(bool v)160 inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); }
161
InitDialogItems(const CInitDialogItem * srcItems,FarDialogItem * destItems,unsigned numItems)162 void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems,
163 FarDialogItem *destItems, unsigned numItems)
164 {
165 for (unsigned i = 0; i < numItems; i++)
166 {
167 const CInitDialogItem &srcItem = srcItems[i];
168 FarDialogItem &destItem = destItems[i];
169
170 destItem.Type = srcItem.Type;
171 destItem.X1 = srcItem.X1;
172 destItem.Y1 = srcItem.Y1;
173 destItem.X2 = srcItem.X2;
174 destItem.Y2 = srcItem.Y2;
175 destItem.Focus = GetBOOLValue(srcItem.Focus);
176 if (srcItem.HistoryName != NULL)
177 destItem.History = srcItem.HistoryName;
178 else
179 destItem.Selected = GetBOOLValue(srcItem.Selected);
180 destItem.Flags = srcItem.Flags;
181 destItem.DefaultButton = GetBOOLValue(srcItem.DefaultButton);
182
183 if (srcItem.DataMessageId < 0)
184 MyStringCopy(destItem.Data, srcItem.DataString);
185 else
186 MyStringCopy(destItem.Data, GetMsgString(srcItem.DataMessageId));
187
188 /*
189 if ((unsigned)Init[i].Data < 0xFFF)
190 MyStringCopy(destItem.Data, GetMsg((unsigned)srcItem.Data));
191 else
192 MyStringCopy(destItem.Data,srcItem.Data);
193 */
194 }
195 }
196
197 // --------------------------------------------
198
SaveScreen(int X1,int Y1,int X2,int Y2)199 HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2)
200 {
201 return m_Data.SaveScreen(X1, Y1, X2, Y2);
202 }
203
SaveScreen()204 HANDLE CStartupInfo::SaveScreen()
205 {
206 return SaveScreen(0, 0, -1, -1);
207 }
208
RestoreScreen(HANDLE handle)209 void CStartupInfo::RestoreScreen(HANDLE handle)
210 {
211 m_Data.RestoreScreen(handle);
212 }
213
GetFullKeyName(const char * keyName) const214 CSysString CStartupInfo::GetFullKeyName(const char *keyName) const
215 {
216 AString s (m_RegistryPath);
217 if (keyName && *keyName)
218 {
219 s += kRegistryKeyDelimiter;
220 s += keyName;
221 }
222 return (CSysString)s;
223 }
224
225
CreateRegKey(HKEY parentKey,const char * keyName,NRegistry::CKey & destKey) const226 LONG CStartupInfo::CreateRegKey(HKEY parentKey,
227 const char *keyName, NRegistry::CKey &destKey) const
228 {
229 return destKey.Create(parentKey, GetFullKeyName(keyName));
230 }
231
OpenRegKey(HKEY parentKey,const char * keyName,NRegistry::CKey & destKey) const232 LONG CStartupInfo::OpenRegKey(HKEY parentKey,
233 const char *keyName, NRegistry::CKey &destKey) const
234 {
235 return destKey.Open(parentKey, GetFullKeyName(keyName));
236 }
237
SetRegKeyValue(HKEY parentKey,const char * keyName,LPCTSTR valueName,LPCTSTR value) const238 void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName,
239 LPCTSTR valueName, LPCTSTR value) const
240 {
241 NRegistry::CKey regKey;
242 CreateRegKey(parentKey, keyName, regKey);
243 regKey.SetValue(valueName, value);
244 }
245
SetRegKeyValue(HKEY parentKey,const char * keyName,LPCTSTR valueName,UInt32 value) const246 void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName,
247 LPCTSTR valueName, UInt32 value) const
248 {
249 NRegistry::CKey regKey;
250 CreateRegKey(parentKey, keyName, regKey);
251 regKey.SetValue(valueName, value);
252 }
253
SetRegKeyValue(HKEY parentKey,const char * keyName,LPCTSTR valueName,bool value) const254 void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName,
255 LPCTSTR valueName, bool value) const
256 {
257 NRegistry::CKey regKey;
258 CreateRegKey(parentKey, keyName, regKey);
259 regKey.SetValue(valueName, value);
260 }
261
QueryRegKeyValue(HKEY parentKey,const char * keyName,LPCTSTR valueName,const CSysString & valueDefault) const262 CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
263 LPCTSTR valueName, const CSysString &valueDefault) const
264 {
265 NRegistry::CKey regKey;
266 if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS)
267 return valueDefault;
268
269 CSysString value;
270 if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS)
271 return valueDefault;
272
273 return value;
274 }
275
QueryRegKeyValue(HKEY parentKey,const char * keyName,LPCTSTR valueName,UInt32 valueDefault) const276 UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
277 LPCTSTR valueName, UInt32 valueDefault) const
278 {
279 NRegistry::CKey regKey;
280 if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS)
281 return valueDefault;
282
283 UInt32 value;
284 if (regKey.GetValue_UInt32_IfOk(valueName, value) != ERROR_SUCCESS)
285 return valueDefault;
286
287 return value;
288 }
289
QueryRegKeyValue(HKEY parentKey,const char * keyName,LPCTSTR valueName,bool valueDefault) const290 bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
291 LPCTSTR valueName, bool valueDefault) const
292 {
293 NRegistry::CKey regKey;
294 if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS)
295 return valueDefault;
296
297 bool value;
298 if (regKey.GetValue_bool_IfOk(valueName, value) != ERROR_SUCCESS)
299 return valueDefault;
300
301 return value;
302 }
303
Control(HANDLE pluginHandle,int command,void * param)304 bool CStartupInfo::Control(HANDLE pluginHandle, int command, void *param)
305 {
306 return BOOLToBool(m_Data.Control(pluginHandle, command, param));
307 }
308
ControlRequestActivePanel(int command,void * param)309 bool CStartupInfo::ControlRequestActivePanel(int command, void *param)
310 {
311 return Control(INVALID_HANDLE_VALUE, command, param);
312 }
313
ControlGetActivePanelInfo(PanelInfo & panelInfo)314 bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &panelInfo)
315 {
316 return ControlRequestActivePanel(FCTL_GETPANELINFO, &panelInfo);
317 }
318
ControlSetSelection(const PanelInfo & panelInfo)319 bool CStartupInfo::ControlSetSelection(const PanelInfo &panelInfo)
320 {
321 return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&panelInfo);
322 }
323
ControlGetActivePanelCurrentItemInfo(PluginPanelItem & pluginPanelItem)324 bool CStartupInfo::ControlGetActivePanelCurrentItemInfo(
325 PluginPanelItem &pluginPanelItem)
326 {
327 PanelInfo panelInfo;
328 if (!ControlGetActivePanelInfo(panelInfo))
329 return false;
330 if (panelInfo.ItemsNumber <= 0)
331 throw "There are no items";
332 pluginPanelItem = panelInfo.PanelItems[panelInfo.CurrentItem];
333 return true;
334 }
335
ControlGetActivePanelSelectedOrCurrentItems(CObjectVector<PluginPanelItem> & pluginPanelItems)336 bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems(
337 CObjectVector<PluginPanelItem> &pluginPanelItems)
338 {
339 pluginPanelItems.Clear();
340 PanelInfo panelInfo;
341 if (!ControlGetActivePanelInfo(panelInfo))
342 return false;
343 if (panelInfo.ItemsNumber <= 0)
344 throw "There are no items";
345 if (panelInfo.SelectedItemsNumber == 0)
346 pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]);
347 else
348 for (int i = 0; i < panelInfo.SelectedItemsNumber; i++)
349 pluginPanelItems.Add(panelInfo.SelectedItems[i]);
350 return true;
351 }
352
ControlClearPanelSelection()353 bool CStartupInfo::ControlClearPanelSelection()
354 {
355 PanelInfo panelInfo;
356 if (!ControlGetActivePanelInfo(panelInfo))
357 return false;
358 for (int i = 0; i < panelInfo.ItemsNumber; i++)
359 panelInfo.PanelItems[i].Flags &= ~(DWORD)PPIF_SELECTED;
360 return ControlSetSelection(panelInfo);
361 }
362
363 ////////////////////////////////////////////////
364 // menu function
365
Menu(int x,int y,int maxHeight,unsigned flags,const char * title,const char * aBottom,const char * helpTopic,int * breakKeys,int * breakCode,struct FarMenuItem * items,unsigned numItems)366 int CStartupInfo::Menu(
367 int x,
368 int y,
369 int maxHeight,
370 unsigned flags,
371 const char *title,
372 const char *aBottom,
373 const char *helpTopic,
374 int *breakKeys,
375 int *breakCode,
376 struct FarMenuItem *items,
377 unsigned numItems)
378 {
379 return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags,
380 const_cast<char *>(title),
381 const_cast<char *>(aBottom),
382 const_cast<char *>(helpTopic),
383 breakKeys, breakCode, items, (int)numItems);
384 }
385
Menu(unsigned flags,const char * title,const char * helpTopic,struct FarMenuItem * items,unsigned numItems)386 int CStartupInfo::Menu(
387 unsigned flags,
388 const char *title,
389 const char *helpTopic,
390 struct FarMenuItem *items,
391 unsigned numItems)
392 {
393 return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL,
394 NULL, items, numItems);
395 }
396
Menu(unsigned flags,const char * title,const char * helpTopic,const AStringVector & items,int selectedItem)397 int CStartupInfo::Menu(
398 unsigned flags,
399 const char *title,
400 const char *helpTopic,
401 const AStringVector &items,
402 int selectedItem)
403 {
404 CRecordVector<FarMenuItem> farMenuItems;
405 FOR_VECTOR (i, items)
406 {
407 FarMenuItem item;
408 item.Checked = 0;
409 item.Separator = 0;
410 item.Selected = ((int)i == selectedItem);
411 const AString reducedString (items[i].Left(Z7_ARRAY_SIZE(item.Text) - 1));
412 MyStringCopy(item.Text, reducedString);
413 farMenuItems.Add(item);
414 }
415 return Menu(flags, title, helpTopic, farMenuItems.NonConstData(), farMenuItems.Size());
416 }
417
418
419 //////////////////////////////////
420 // CScreenRestorer
421
~CScreenRestorer()422 CScreenRestorer::~CScreenRestorer()
423 {
424 Restore();
425 }
Save()426 void CScreenRestorer::Save()
427 {
428 if (m_Saved)
429 return;
430 m_HANDLE = g_StartupInfo.SaveScreen();
431 m_Saved = true;
432 }
433
Restore()434 void CScreenRestorer::Restore()
435 {
436 if (m_Saved)
437 {
438 g_StartupInfo.RestoreScreen(m_HANDLE);
439 m_Saved = false;
440 }
441 }
442
PrintErrorMessage(const char * message,unsigned code)443 int PrintErrorMessage(const char *message, unsigned code)
444 {
445 AString s (message);
446 s += " #";
447 s.Add_UInt32((UInt32)code);
448 return g_StartupInfo.ShowErrorMessage(s);
449 }
450
PrintErrorMessage(const char * message,const char * text)451 int PrintErrorMessage(const char *message, const char *text)
452 {
453 return g_StartupInfo.ShowErrorMessage2(message, text);
454 }
455
456
ReduceString(UString & s,unsigned size)457 void ReduceString(UString &s, unsigned size)
458 {
459 if (s.Len() > size)
460 {
461 if (size > 5)
462 size -= 5;
463 s.Delete(size / 2, s.Len() - size);
464 s.Insert(size / 2, L" ... ");
465 }
466 }
467
PrintErrorMessage(const char * message,const wchar_t * name,unsigned maxLen)468 int PrintErrorMessage(const char *message, const wchar_t *name, unsigned maxLen)
469 {
470 UString s = name;
471 ReduceString(s, maxLen);
472 return PrintErrorMessage(message, UnicodeStringToMultiByte(s, CP_OEMCP));
473 }
474
ShowSysErrorMessage(DWORD errorCode)475 int ShowSysErrorMessage(DWORD errorCode)
476 {
477 const UString message = NError::MyFormatMessage(errorCode);
478 return g_StartupInfo.ShowErrorMessage(UnicodeStringToMultiByte(message, CP_OEMCP));
479 }
480
ShowLastErrorMessage()481 int ShowLastErrorMessage()
482 {
483 return ShowSysErrorMessage(::GetLastError());
484 }
485
ShowSysErrorMessage(DWORD errorCode,const wchar_t * name)486 int ShowSysErrorMessage(DWORD errorCode, const wchar_t *name)
487 {
488 const UString s = NError::MyFormatMessage(errorCode);
489 return g_StartupInfo.ShowErrorMessage2(
490 UnicodeStringToMultiByte(s, CP_OEMCP),
491 UnicodeStringToMultiByte(name, CP_OEMCP));
492 }
493
494
WasEscPressed()495 bool WasEscPressed()
496 {
497 #ifdef UNDER_CE
498 return false;
499 #else
500 NConsole::CIn inConsole;
501 HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE);
502 if (handle == INVALID_HANDLE_VALUE)
503 return true;
504 inConsole.Attach(handle);
505 for (;;)
506 {
507 DWORD numEvents;
508 if (!inConsole.GetNumberOfEvents(numEvents))
509 return true;
510 if (numEvents == 0)
511 return false;
512
513 INPUT_RECORD event;
514 if (!inConsole.ReadEvent(event, numEvents))
515 return true;
516 if (event.EventType == KEY_EVENT &&
517 event.Event.KeyEvent.bKeyDown &&
518 event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
519 return true;
520 }
521 #endif
522 }
523
524 }
525