8 Предназначен для отображения модальных диалогов.
9 Является производным от класса Frame.
12 Copyright (c) 1996 Eugene Roshal
13 Copyright (c) 2000 Far Group
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
19 1. Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
21 2. Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
24 3. The name of the authors may not be used to endorse or promote products
25 derived from this software without specific prior written permission.
27 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <farplug-wide.h>
43 #include "chgmmode.hpp"
44 #include "bitflags.hpp"
45 #include "CriticalSections.hpp"
49 // Флаги текущего режима диалога
52 DMODE_INITOBJECTS
= 0x00000001, // элементы инициализарованы?
53 DMODE_CREATEOBJECTS
= 0x00000002, // объекты (Edit,...) созданы?
54 DMODE_WARNINGSTYLE
= 0x00000004, // Warning Dialog Style?
55 DMODE_DRAGGED
= 0x00000008, // диалог двигается?
56 DMODE_ISCANMOVE
= 0x00000010, // можно ли двигать диалог?
57 DMODE_ALTDRAGGED
= 0x00000020, // диалог двигается по Alt-Стрелка?
58 DMODE_SMALLDIALOG
= 0x00000040, // "короткий диалог"
59 DMODE_DRAWING
= 0x00001000, // диалог рисуется?
60 DMODE_KEY
= 0x00002000, // Идет посылка клавиш?
61 DMODE_SHOW
= 0x00004000, // Диалог виден?
62 DMODE_MOUSEEVENT
= 0x00008000, // Нужно посылать MouseMove в обработчик?
63 DMODE_RESIZED
= 0x00010000, //
64 DMODE_ENDLOOP
= 0x00020000, // Конец цикла обработки диалога?
65 DMODE_BEGINLOOP
= 0x00040000, // Начало цикла обработки диалога?
66 // DMODE_OWNSITEMS =0x00080000, // если TRUE, Dialog освобождает список Item в деструкторе
67 DMODE_NODRAWSHADOW
= 0x00100000, // не рисовать тень?
68 DMODE_NODRAWPANEL
= 0x00200000, // не рисовать подложку?
69 DMODE_FULLSHADOW
= 0x00400000,
70 DMODE_NOPLUGINS
= 0x00800000,
71 DMODE_KEEPCONSOLETITLE
= 0x10000000, // не изменять заголовок консоли
72 DMODE_CLICKOUTSIDE
= 0x20000000, // было нажатие мыши вне диалога?
73 DMODE_MSGINTERNAL
= 0x40000000, // Внутренняя Message?
74 DMODE_OLDSTYLE
= 0x80000000, // Диалог в старом (до 1.70) стиле
77 // #define DIMODE_REDRAW 0x00000001 // требуется принудительная прорисовка итема?
79 #define MakeDialogItemsEx(Data, Item) \
80 DialogItemEx Item[ARRAYSIZE(Data)]; \
81 DataToItemEx(Data, Item, ARRAYSIZE(Data));
83 // Структура, описывающая автоматизацию для DIF_AUTOMATION
84 // на первом этапе - примитивная - выставление флагов у элементов для CheckBox
85 struct DialogItemAutomation
87 WORD ID
; // Для этого элемента...
88 DWORD Flags
[3][2]; // ...выставить вот эти флаги
89 // [0] - Unchecked, [1] - Checked, [2] - 3Checked
90 // [][0] - Set, [][1] - Skip
103 CursorVisible(false), CursorSize(static_cast<DWORD
>(-1))
105 CursorPos
.X
= CursorPos
.Y
= -1;
111 Описывает один элемент диалога - внутренне представление.
112 Для плагинов это FarDialogItem (за исключением ObjPtr)
127 FARString strHistory
;
129 std::unique_ptr
<DialogItemTrueColors
> TrueColors
;
138 unsigned AutoCount
; // Автоматизация
139 DialogItemAutomation
*AutoPtr
;
140 DWORD_PTR UserData
; // ассоциированные данные
145 DlgUserControl
*UCData
;
178 const DialogItemEx
&operator=(const DialogItemEx
&Other
)
186 Reserved
= Other
.Reserved
;
188 DefaultButton
= Other
.DefaultButton
;
189 strData
= Other
.strData
;
190 nMaxLength
= Other
.nMaxLength
;
192 IFlags
= Other
.IFlags
;
193 AutoCount
= Other
.AutoCount
;
194 AutoPtr
= Other
.AutoPtr
;
195 UserData
= Other
.UserData
;
196 ObjPtr
= Other
.ObjPtr
;
197 ListPtr
= Other
.ListPtr
;
198 UCData
= Other
.UCData
;
199 SelStart
= Other
.SelStart
;
200 SelEnd
= Other
.SelEnd
;
204 void Indent(int Delta
)
210 bool AddAutomation(int id
, FarDialogItemFlags UncheckedSet
, FarDialogItemFlags UncheckedSkip
,
211 FarDialogItemFlags CheckedSet
, FarDialogItemFlags CheckedSkip
, FarDialogItemFlags Checked3Set
,
212 FarDialogItemFlags Checked3Skip
)
214 DialogItemAutomation
*Auto
;
216 if ((Auto
= (DialogItemAutomation
*)realloc(AutoPtr
,
217 sizeof(DialogItemAutomation
) * (AutoCount
+ 1)))) {
219 Auto
= AutoPtr
+ AutoCount
;
221 Auto
->Flags
[0][0] = UncheckedSet
;
222 Auto
->Flags
[0][1] = UncheckedSkip
;
223 Auto
->Flags
[1][0] = CheckedSet
;
224 Auto
->Flags
[1][1] = CheckedSkip
;
225 Auto
->Flags
[2][0] = Checked3Set
;
226 Auto
->Flags
[2][1] = Checked3Skip
;
235 Описывает один элемент диалога - для сокращения объемов
236 Структура аналогичена структуре InitDialogItem (см. "Far PlugRinG
237 Russian Help Encyclopedia of Developer")
243 short X1
, Y1
, X2
, Y2
;
247 unsigned int Selected
;
248 const wchar_t *History
;
261 class Dialog
: public Frame
263 friend class DlgEdit
;
264 friend LONG_PTR
SendDlgMessageSynched(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
);
265 friend LONG_PTR WINAPI
DefDlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
);
269 INT_PTR PluginNumber
; // Номер плагина, для формирования HelpTopic
270 unsigned FocusPos
; // всегда известно какой элемент в фокусе
271 unsigned PrevFocusPos
; // всегда известно какой элемент был в фокусе
272 int IsEnableRedraw
; // Разрешена перерисовка диалога? ( 0 - разрешена)
273 int InCtlColorDlgItem
;
274 BitFlags DialogMode
; // Флаги текущего режима диалога
276 LONG_PTR DataDialog
; // Данные, специфические для конкретного экземпляра диалога
277 // (первоначально здесь параметр, переданный в конструктор)
279 DialogItemEx
**Item
; // массив элементов диалога
280 DialogItemEx
*pSaveItemEx
; // пользовательский массив элементов диалога
282 unsigned ItemCount
; // количество элементов диалога
284 ConsoleTitle
*OldTitle
; // предыдущий заголовок
286 FARWINDOWPROC RealDlgProc
; // функция обработки диалога
288 // переменные для перемещения диалога
289 int OldX1
, OldX2
, OldY1
, OldY2
;
293 volatile int DropDownOpened
; // Содержит статус комбобокса и хистори: TRUE - открыт, FALSE - закрыт.
297 int RealWidth
, RealHeight
;
303 void Init(FARWINDOWPROC DlgProc
, LONG_PTR InitParam
);
304 virtual void DisplayObject();
305 void DeleteDialogObjects();
306 int LenStrItem(int ID
, const wchar_t *lpwszStr
= nullptr);
308 void ShowDialog(unsigned ID
= (unsigned)-1); // ID=-1 - отрисовать весь диалог
310 DWORD
CtlColorDlgItem(int ItemPos
, const DialogItemEx
*CurItem
);
313 + Изменяет фокус ввода между двумя элементами.
314 Вынесен отдельно для того, чтобы обработать DMSG_KILLFOCUS & DMSG_SETFOCUS
316 void ChangeFocus2(unsigned SetFocusPos
);
318 unsigned ChangeFocus(unsigned FocusPos
, int Step
, int SkipGroup
);
319 BOOL
SelectFromEditHistory(DialogItemEx
*CurItem
, DlgEdit
*EditLine
, const wchar_t *HistoryName
,
321 int SelectFromComboBox(DialogItemEx
*CurItem
, DlgEdit
*EditLine
, VMenu
*List
);
322 int AddToEditHistory(const wchar_t *AddStr
, const wchar_t *HistoryName
);
324 void ProcessLastHistory(DialogItemEx
*CurItem
, int MsgIndex
); // обработка DIF_USELASTHISTORY
326 int ProcessHighlighting(FarKey Key
, unsigned FocusPos
, int Translate
);
327 int CheckHighlights(WORD Chr
, int StartPos
= 0);
329 void SelectOnEntry(unsigned Pos
, BOOL Selected
);
331 void CheckDialogCoord();
332 BOOL
GetItemRect(unsigned I
, SMALL_RECT
&Rect
);
333 bool ItemHasDropDownArrow(const DialogItemEx
*Item
);
335 // возвращает заголовок диалога (текст первого текста или фрейма)
336 const wchar_t *GetDialogTitle();
338 BOOL
SetItemRect(unsigned ID
, SMALL_RECT
*Rect
);
342 + Функции программного открытия/закрытия комбобокса и хистори
343 и получения статуса открытости/закрытости комбобокса и хистори.
345 void SetDropDownOpened(int Status
) { DropDownOpened
= Status
; }
346 int GetDropDownOpened() { return DropDownOpened
; }
348 void ProcessCenterGroup();
349 unsigned ProcessRadioButton(unsigned);
351 unsigned InitDialogObjects(unsigned ID
= (unsigned)-1);
353 int ProcessOpenComboBox(int Type
, DialogItemEx
*CurItem
, unsigned CurFocusPos
);
354 int ProcessMoveDialog(DWORD Key
);
356 int Do_ProcessTab(int Next
);
357 int Do_ProcessNextCtrl(int Next
, BOOL IsRedraw
= TRUE
);
360 * move focus to right or left dialog item.
362 int MoveToCtrlHorizontal(int right
);
364 * move focus to up or down dialog item.
366 int MoveToCtrlVertical(int up
);
368 int Do_ProcessFirstCtrl();
369 int Do_ProcessSpace();
370 void SetComboBoxPos(DialogItemEx
*Item
= nullptr);
372 LONG_PTR
CallDlgProc(int nMsg
, int nParam1
, LONG_PTR nParam2
);
374 void ProcessKey(FarKey Key
, unsigned ItemPos
);
377 Dialog(DialogItemEx
*SrcItem
, unsigned SrcItemCount
, FARWINDOWPROC DlgProc
= nullptr,
378 LONG_PTR InitParam
= 0);
379 Dialog(FarDialogItem
*SrcItem
, unsigned SrcItemCount
, FARWINDOWPROC DlgProc
= nullptr,
380 LONG_PTR InitParam
= 0);
384 virtual int ProcessKey(FarKey Key
);
385 virtual int ProcessMouse(MOUSE_EVENT_RECORD
*MouseEvent
);
386 virtual int64_t VMProcess(MacroOpcode OpCode
, void *vParam
= nullptr, int64_t iParam
= 0);
389 void FastShow() { ShowDialog(); }
391 void GetDialogObjectsData();
393 void SetDialogMode(DWORD Flags
) { DialogMode
.Set(Flags
); }
394 bool CheckDialogMode(DWORD Flags
) { return DialogMode
.Check(Flags
) != FALSE
; }
396 // метод для перемещения диалога
397 void AdjustEditPos(int dx
, int dy
);
399 int IsMoving() { return DialogMode
.Check(DMODE_DRAGGED
); }
400 void SetModeMoving(int IsMoving
) { DialogMode
.Change(DMODE_ISCANMOVE
, IsMoving
); }
401 int GetModeMoving() { return DialogMode
.Check(DMODE_ISCANMOVE
); }
402 void SetDialogData(LONG_PTR NewDataDialog
);
403 LONG_PTR
GetDialogData() { return DataDialog
; };
407 void SetPluginNumber(INT_PTR NewPluginNumber
) { PluginNumber
= NewPluginNumber
; }
409 void SetHelp(const wchar_t *Topic
);
411 int Done() { return DialogMode
.Check(DMODE_ENDLOOP
); }
413 virtual void SetExitCode(int Code
);
417 virtual int GetTypeAndName(FARString
&strType
, FARString
&strName
);
418 virtual int GetType() { return MODALTYPE_DIALOG
; }
419 virtual const wchar_t *GetTypeName() { return L
"[Dialog]"; };
421 virtual int GetMacroMode();
423 /* $ Введена для нужд CtrlAltShift OT */
424 virtual int FastHide();
425 virtual void ResizeConsole();
426 // virtual void OnDestroy();
429 const DialogItemEx
**GetAllItem() { return (const DialogItemEx
**)Item
; };
430 unsigned GetAllItemCount() { return ItemCount
; }; // количество элементов диалога
431 unsigned GetDlgFocusPos() { return FocusPos
; };
433 int SetAutomation(WORD IDParent
, WORD id
, FarDialogItemFlags UncheckedSet
,
434 FarDialogItemFlags UncheckedSkip
, FarDialogItemFlags CheckedSet
, FarDialogItemFlags CheckedSkip
,
435 FarDialogItemFlags Checked3Set
= DIF_NONE
, FarDialogItemFlags Checked3Skip
= DIF_NONE
);
437 LONG_PTR WINAPI
DlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
);
439 virtual void SetPosition(int X1
, int Y1
, int X2
, int Y2
);
442 bool ProcessEvents();
444 void SetId(const GUID
&Id
);
446 friend class History
;
449 typedef LONG_PTR(WINAPI
*SENDDLGMESSAGE
)(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
);
451 LONG_PTR WINAPI
SendDlgMessage(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
);
453 LONG_PTR WINAPI
DefDlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
);
455 bool IsKeyHighlighted(const wchar_t *Str
, FarKey Key
, int Translate
, int AmpPos
= -1);
457 void DataToItemEx(const DialogDataEx
*Data
, DialogItemEx
*Item
, int Count
);
459 extern const wchar_t *fmtSavedDialogHistory
;