7 Copyright (c) 1996 Eugene Roshal
8 Copyright (c) 2000 Far Group
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19 3. The name of the authors may not be used to endorse or promote products
20 derived from this software without specific prior written permission.
22 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "headers.hpp"
38 #include "keyboard.hpp"
39 #include "macroopcode.hpp"
41 #include "ctrlobj.hpp"
42 #include "chgprior.hpp"
44 #include "dlgedit.hpp"
47 #include "manager.hpp"
48 #include "savescr.hpp"
49 #include "constitle.hpp"
50 #include "lockscrn.hpp"
51 #include "TPreRedrawFunc.hpp"
54 #include "palette.hpp"
55 #include "message.hpp"
57 #include "history.hpp"
58 #include "InterThreadCall.hpp"
59 #include <VT256ColorTable.h>
63 #define VTEXT_ADN_SEPARATORS 1
65 // Флаги для функции ConvertItem
69 CVTITEM_FROMPLUGIN
= 1,
70 CVTITEM_TOPLUGINSHORT
= 2,
71 CVTITEM_FROMPLUGINSHORT
= 3
76 DLGEDITLINE_CLEARSELONKILLFOCUS
= 0x00000001, // управляет выделением блока при потере фокуса ввода
77 DLGEDITLINE_SELALLGOTFOCUS
= 0x00000002, // управляет выделением блока при получении фокуса ввода
78 DLGEDITLINE_NOTSELONGOTFOCUS
= 0x00000004, // не восстанавливать выделение строки редактирования при получении фокуса ввода
79 DLGEDITLINE_NEWSELONGOTFOCUS
= 0x00000008, // управляет процессом выделения блока при получении фокуса
80 DLGEDITLINE_GOTOEOLGOTFOCUS
= 0x00000010, // при получении фокуса ввода переместить курсор в конец строки
83 enum DLGITEMINTERNALFLAGS
85 DLGIIF_LISTREACTIONFOCUS
= 0x00000001, // MouseReaction для фокусного элемента
86 DLGIIF_LISTREACTIONNOFOCUS
= 0x00000002, // MouseReaction для не фокусного элемента
88 DLGIIF_COMBOBOXNOREDRAWEDIT
= 0x00000008, // не прорисовывать строку редактирования при изменениях в комбо
89 DLGIIF_COMBOBOXEVENTKEY
= 0x00000010, // посылать события клавиатуры в диалоговую проц. для открытого комбобокса
90 DLGIIF_COMBOBOXEVENTMOUSE
= 0x00000020, // посылать события мыши в диалоговую проц. для открытого комбобокса
93 const wchar_t *fmtSavedDialogHistory
= L
"SavedDialogHistory/";
95 //////////////////////////////////////////////////////////////////////////
97 Функция, определяющая - "Может ли элемент диалога иметь фокус ввода"
99 static inline bool CanGetFocus(int Type
)
118 bool IsKeyHighlighted(const wchar_t *Str
, FarKey Key
, int Translate
, int AmpPos
)
121 if (!(Str
= wcschr(Str
, L
'&')))
126 if (AmpPos
>= StrLength(Str
))
132 if (Str
[AmpPos
] == L
'&')
136 wchar_t UpperStrKey
= Upper(Str
[AmpPos
]);
138 if (WCHAR_IS_VALID(Key
)) {
139 return UpperStrKey
== Upper(Key
) || (Translate
&& KeyToKeyLayoutCompare(Upper(Key
), UpperStrKey
));
143 uint32_t AltKey
= Key
& (~KEY_ALT
);
145 if (WCHAR_IS_VALID(AltKey
)) {
146 if (iswdigit(AltKey
) != 0)
147 return (AltKey
== (uint32_t)UpperStrKey
);
150 // (AltKey=='-' || AltKey=='/' || AltKey==',' || AltKey=='.' ||
151 // AltKey=='\\' || AltKey=='=' || AltKey=='[' || AltKey==']' ||
152 // AltKey==':' || AltKey=='"' || AltKey=='~'))
154 return (UpperStrKey
== Upper(AltKey
)
155 || (Translate
&& KeyToKeyLayoutCompare(AltKey
, UpperStrKey
)));
163 void DialogItemExToDialogItemEx(DialogItemEx
*pSrc
, DialogItemEx
*pDest
)
165 pDest
->Type
= pSrc
->Type
;
166 pDest
->X1
= pSrc
->X1
;
167 pDest
->Y1
= pSrc
->Y1
;
168 pDest
->X2
= pSrc
->X2
;
169 pDest
->Y2
= pSrc
->Y2
;
170 pDest
->Focus
= pSrc
->Focus
;
171 pDest
->Reserved
= pSrc
->Reserved
;
172 pDest
->strHistory
= pSrc
->strHistory
;
173 pDest
->strMask
= pSrc
->strMask
;
174 pDest
->Flags
= pSrc
->Flags
;
175 pDest
->DefaultButton
= pSrc
->DefaultButton
;
176 pDest
->nMaxLength
= 0;
177 pDest
->strData
= pSrc
->strData
;
178 pDest
->ID
= pSrc
->ID
;
179 pDest
->IFlags
= pSrc
->IFlags
;
180 pDest
->AutoCount
= pSrc
->AutoCount
;
181 pDest
->AutoPtr
= pSrc
->AutoPtr
;
182 pDest
->UserData
= pSrc
->UserData
;
183 pDest
->ObjPtr
= pSrc
->ObjPtr
;
184 pDest
->ListPtr
= pSrc
->ListPtr
;
185 pDest
->UCData
= pSrc
->UCData
;
186 pDest
->SelStart
= pSrc
->SelStart
;
187 pDest
->SelEnd
= pSrc
->SelEnd
;
190 void ConvertItemSmall(FarDialogItem
*Item
, DialogItemEx
*Data
)
192 Item
->Type
= Data
->Type
;
197 Item
->Focus
= Data
->Focus
;
198 Item
->Flags
= Data
->Flags
;
199 Item
->DefaultButton
= Data
->DefaultButton
;
200 Item
->MaxLen
= Data
->nMaxLength
;
201 Item
->PtrData
= nullptr;
203 Item
->Param
.History
= nullptr;
204 if (Data
->Type
== DI_LISTBOX
|| Data
->Type
== DI_COMBOBOX
) {
205 Item
->Param
.ListPos
= Data
->ListPtr
? Data
->ListPtr
->GetSelectPos() : 0;
207 if ((Data
->Type
== DI_EDIT
|| Data
->Type
== DI_FIXEDIT
) && Data
->Flags
& DIF_HISTORY
) {
208 Item
->Param
.History
= Data
->strHistory
;
209 } else if (Data
->Type
== DI_FIXEDIT
&& Data
->Flags
& DIF_MASKEDIT
) {
210 Item
->Param
.Mask
= Data
->strMask
;
212 Item
->Param
.Reserved
= Data
->Reserved
;
216 size_t ItemStringAndSize(DialogItemEx
*Data
, FARString
&ItemString
)
219 if (FarIsEdit(Data
->Type
) && (EditPtr
= (DlgEdit
*)(Data
->ObjPtr
)) != nullptr)
220 EditPtr
->GetString(ItemString
);
222 ItemString
= Data
->strData
;
224 size_t sz
= ItemString
.GetLength();
226 if (sz
> Data
->nMaxLength
&& Data
->nMaxLength
> 0)
227 sz
= Data
->nMaxLength
;
232 bool ConvertItemEx(CVTITEMFLAGS FromPlugin
, FarDialogItem
*Item
, DialogItemEx
*Data
, unsigned Count
)
239 switch (FromPlugin
) {
240 case CVTITEM_TOPLUGIN
:
241 case CVTITEM_TOPLUGINSHORT
:
243 for (I
= 0; I
< Count
; I
++, ++Item
, ++Data
) {
244 ConvertItemSmall(Item
, Data
);
246 if (FromPlugin
== CVTITEM_TOPLUGIN
) {
248 size_t sz
= ItemStringAndSize(Data
, str
);
250 wchar_t *p
= (wchar_t *)malloc((sz
+ 1) * sizeof(wchar_t));
253 if (!p
) // TODO: may be needed message?
256 wmemcpy(p
, str
.CPtr(), sz
);
263 case CVTITEM_FROMPLUGIN
:
264 case CVTITEM_FROMPLUGINSHORT
:
266 for (I
= 0; I
< Count
; I
++, ++Item
, ++Data
) {
271 Data
->Focus
= Item
->Focus
;
273 if ((Item
->Type
== DI_EDIT
|| Item
->Type
== DI_FIXEDIT
) && Item
->Flags
& DIF_HISTORY
) {
274 Data
->strHistory
= Item
->Param
.History
;
275 } else if (Item
->Type
== DI_FIXEDIT
&& Item
->Flags
& DIF_MASKEDIT
) {
276 Data
->strMask
= Item
->Param
.Mask
;
278 Data
->Reserved
= Item
->Param
.Reserved
;
280 Data
->Flags
= Item
->Flags
;
281 Data
->DefaultButton
= Item
->DefaultButton
;
282 Data
->Type
= Item
->Type
;
284 if (FromPlugin
== CVTITEM_FROMPLUGIN
) {
285 Data
->strData
= Item
->PtrData
;
286 Data
->nMaxLength
= Item
->MaxLen
;
288 if (Data
->nMaxLength
> 0)
289 Data
->strData
.Truncate(Data
->nMaxLength
);
292 Data
->ListItems
= Item
->Param
.ListItems
;
294 if (Data
->X2
< Data
->X1
)
297 if (Data
->Y2
< Data
->Y1
)
300 if ((Data
->Type
== DI_COMBOBOX
|| Data
->Type
== DI_LISTBOX
) && !IsPtr(Item
->Param
.ListItems
))
301 Data
->ListItems
= nullptr;
310 size_t ConvertItemEx2(FarDialogItem
*Item
, DialogItemEx
*Data
)
312 size_t size
= sizeof(*Item
);
314 size_t sz
= ItemStringAndSize(Data
, str
);
315 size
+= (sz
+ 1) * sizeof(wchar_t);
318 ConvertItemSmall(Item
, Data
);
320 wchar_t *p
= (wchar_t *)(Item
+ 1);
322 wmemcpy(p
, str
.CPtr(), sz
);
329 void DataToItemEx(const DialogDataEx
*Data
, DialogItemEx
*Item
, int Count
)
334 for (int i
= 0; i
< Count
; i
++) {
336 Item
[i
].ID
= static_cast<WORD
>(i
);
337 Item
[i
].Type
= Data
[i
].Type
;
338 Item
[i
].X1
= Data
[i
].X1
;
339 Item
[i
].Y1
= Data
[i
].Y1
;
340 Item
[i
].X2
= Data
[i
].X2
;
341 Item
[i
].Y2
= Data
[i
].Y2
;
343 if (Item
[i
].X2
< Item
[i
].X1
)
344 Item
[i
].X2
= Item
[i
].X1
;
346 if (Item
[i
].Y2
< Item
[i
].Y1
)
347 Item
[i
].Y2
= Item
[i
].Y1
;
350 Item
[i
].Type
!= DI_SINGLEBOX
&& Item
[i
].Type
!= DI_DOUBLEBOX
&& (Data
[i
].Flags
& DIF_FOCUS
);
351 if ((Data
[i
].Type
== DI_EDIT
|| Data
[i
].Type
== DI_FIXEDIT
) && Data
[i
].Flags
& DIF_HISTORY
) {
352 Item
[i
].strHistory
= Data
[i
].History
;
353 } else if (Data
[i
].Type
== DI_FIXEDIT
&& Data
[i
].Flags
& DIF_MASKEDIT
) {
354 Item
[i
].strMask
= Data
[i
].Mask
;
356 Item
[i
].Reserved
= Data
[i
].Reserved
;
358 Item
[i
].Flags
= Data
[i
].Flags
;
359 Item
[i
].DefaultButton
=
360 Item
[i
].Type
!= DI_TEXT
&& Item
[i
].Type
!= DI_VTEXT
&& (Data
[i
].Flags
& DIF_DEFAULT
);
361 Item
[i
].SelStart
= -1;
363 if (!IsPtr(Data
[i
].Data
)) // awful
364 Item
[i
].strData
= FarLangMsg
{(int)(DWORD_PTR
)Data
[i
].Data
};
366 Item
[i
].strData
= Data
[i
].Data
;
370 Dialog::Dialog(DialogItemEx
*SrcItem
, // Набор элементов диалога
371 unsigned SrcItemCount
, // Количество элементов
372 FARWINDOWPROC DlgProc
, // Диалоговая процедура
373 LONG_PTR InitParam
) // Ассоцированные с диалогом данные
377 Dialog::Item
= (DialogItemEx
**)malloc(sizeof(DialogItemEx
*) * SrcItemCount
);
379 for (unsigned i
= 0; i
< SrcItemCount
; i
++) {
380 Dialog::Item
[i
] = new DialogItemEx
;
381 Dialog::Item
[i
]->Clear();
382 DialogItemExToDialogItemEx(&SrcItem
[i
], Dialog::Item
[i
]);
385 Dialog::ItemCount
= SrcItemCount
;
386 Dialog::pSaveItemEx
= SrcItem
;
387 Init(DlgProc
, InitParam
);
390 Dialog::Dialog(FarDialogItem
*SrcItem
, // Набор элементов диалога
391 unsigned SrcItemCount
, // Количество элементов
392 FARWINDOWPROC DlgProc
, // Диалоговая процедура
393 LONG_PTR InitParam
) // Ассоцированные с диалогом данные
397 Dialog::Item
= (DialogItemEx
**)malloc(sizeof(DialogItemEx
*) * SrcItemCount
);
399 for (unsigned i
= 0; i
< SrcItemCount
; i
++) {
400 Dialog::Item
[i
] = new DialogItemEx
;
401 Dialog::Item
[i
]->Clear();
402 // BUGBUG add error check
403 ConvertItemEx(CVTITEM_FROMPLUGIN
, &SrcItem
[i
], Dialog::Item
[i
], 1);
406 Dialog::ItemCount
= SrcItemCount
;
407 Dialog::pSaveItemEx
= nullptr;
408 Init(DlgProc
, InitParam
);
411 void Dialog::Init(FARWINDOWPROC DlgProc
, // Диалоговая процедура
412 LONG_PTR InitParam
) // Ассоцированные с диалогом данные
414 SetDynamicallyBorn(FALSE
); // $OT: По умолчанию все диалоги создаются статически
415 CanLoseFocus
= FALSE
;
417 // Номер плагина, вызвавшего диалог (-1 = Main)
419 Dialog::DataDialog
= InitParam
;
420 DialogMode
.Set(DMODE_ISCANMOVE
);
421 SetDropDownOpened(FALSE
);
423 InCtlColorDlgItem
= 0;
424 FocusPos
= (unsigned)-1;
425 PrevFocusPos
= (unsigned)-1;
427 if (!DlgProc
) // функция должна быть всегда!!!
429 DlgProc
= DefDlgProc
;
430 // знать диалог в старом стиле - учтем этот факт!
431 DialogMode
.Set(DMODE_OLDSTYLE
);
434 Dialog::RealDlgProc
= DlgProc
;
436 //_SVS(SysLog(L"Dialog =%d",CtrlObject->Macro.GetMode()));
437 // запоминаем предыдущий заголовок консоли
438 OldTitle
= new ConsoleTitle
;
440 memset(&Id
, 0, sizeof(Id
));
443 //////////////////////////////////////////////////////////////////////////
446 Деструктор класса Dialog
450 _tran(SysLog(L
"[%p] Dialog::~Dialog()", this));
452 DeleteDialogObjects();
460 for (unsigned i
= 0; i
< ItemCount
; i
++)
466 if (!WinPortTesting()) {
468 PeekInputRecord(&rec
);
471 _DIALOG(CleverSysLog
CL(L
"Destroy Dialog"));
474 void Dialog::CheckDialogCoord()
476 CriticalSectionLock
Lock(CS
);
478 if (X1
== -1) // задано центрирование диалога по горизонтали?
479 { // X2 при этом = ширине диалога.
480 X1
= (ScrX
- X2
+ 1) / 2;
482 if (X1
< 0) // ширина диалога больше ширины экрана?
490 if (Y1
== -1) // задано центрирование диалога по вертикали?
491 { // Y2 при этом = высоте диалога.
492 Y1
= (ScrY
- Y2
+ 1) / 2;
494 if (!DialogMode
.Check(DMODE_SMALLDIALOG
)) //????
506 void Dialog::InitDialog()
508 CriticalSectionLock
Lock(CS
);
510 if (!DialogMode
.Check(DMODE_INITOBJECTS
)) // самодостаточный вариант, когда
511 { // элементы инициализируются при первом вызове.
513 unsigned InitFocus
= InitDialogObjects();
514 int Result
= (int)DlgProc((HANDLE
)this, DN_INITDIALOG
, InitFocus
, DataDialog
);
516 if (ExitCode
== -1) {
518 // еще разок, т.к. данные могли быть изменены
519 InitFocus
= InitDialogObjects(); // InitFocus=????
522 if (!DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
523 ConsoleTitle::SetFarTitle(GetDialogTitle());
526 // все объекты проинициализированы!
527 DialogMode
.Set(DMODE_INITOBJECTS
);
528 DialogInfo di
= {sizeof(di
)};
530 if (DlgProc(reinterpret_cast<HANDLE
>(this), DN_GETDIALOGINFO
, 0, reinterpret_cast<LONG_PTR
>(&di
))) {
535 DlgProc((HANDLE
)this, DN_GOTFOCUS
, InitFocus
, 0);
539 //////////////////////////////////////////////////////////////////////////
542 Расчет значений координат окна диалога и вызов функции
543 ScreenObject::Show() для вывода диалога на экран.
547 CriticalSectionLock
Lock(CS
);
548 _tran(SysLog(L
"[%p] Dialog::Show()", this));
550 if (!DialogMode
.Check(DMODE_INITOBJECTS
))
553 if (!Locked() && DialogMode
.Check(DMODE_RESIZED
)) {
554 PreRedrawItem preRedrawItem
= PreRedraw
.Peek();
556 if (preRedrawItem
.PreRedrawFunc
)
557 preRedrawItem
.PreRedrawFunc();
560 DialogMode
.Clear(DMODE_RESIZED
);
565 DialogMode
.Set(DMODE_SHOW
);
566 ScreenObject::Show();
569 // Цель перехвата данной функции - управление видимостью...
572 CriticalSectionLock
Lock(CS
);
573 _tran(SysLog(L
"[%p] Dialog::Hide()", this));
575 if (!DialogMode
.Check(DMODE_INITOBJECTS
))
578 DialogMode
.Clear(DMODE_SHOW
);
579 ScreenObject::Hide();
582 //////////////////////////////////////////////////////////////////////////
585 Инициализация объектов и вывод диалога на экран.
587 void Dialog::DisplayObject()
589 CriticalSectionLock
Lock(CS
);
591 if (DialogMode
.Check(DMODE_SHOW
)) {
592 ChangePriority
ChPriority(ChangePriority::NORMAL
);
593 ShowDialog(); // "нарисуем" диалог
597 // пересчитать координаты для элементов с DIF_CENTERGROUP
598 void Dialog::ProcessCenterGroup()
600 CriticalSectionLock
Lock(CS
);
602 for (unsigned I
= 0; I
< ItemCount
; I
++) {
604 Последовательно объявленные элементы с флагом DIF_CENTERGROUP
605 и одинаковой вертикальной позицией будут отцентрированы в диалоге.
606 Их координаты X не важны. Удобно использовать для центрирования
609 if ((Item
[I
]->Flags
& DIF_CENTERGROUP
)
610 && (I
== 0 || (Item
[I
- 1]->Flags
& DIF_CENTERGROUP
) == 0
611 || Item
[I
- 1]->Y1
!= Item
[I
]->Y1
)) {
615 J
< ItemCount
&& (Item
[J
]->Flags
& DIF_CENTERGROUP
) && Item
[J
]->Y1
== Item
[I
]->Y1
; J
++) {
616 Length
+= LenStrItem(J
);
618 if (!Item
[J
]->strData
.IsEmpty())
619 switch (Item
[J
]->Type
) {
630 if (!Item
[I
]->strData
.IsEmpty())
631 switch (Item
[I
]->Type
) {
639 } // Бля, це ж ботва какая-то
641 int StartX
= Max(0, (X2
- X1
+ 1 - Length
) / 2);
644 J
< ItemCount
&& (Item
[J
]->Flags
& DIF_CENTERGROUP
) && Item
[J
]->Y1
== Item
[I
]->Y1
; J
++) {
645 Item
[J
]->X1
= StartX
;
646 StartX
+= LenStrItem(J
);
648 if (!Item
[J
]->strData
.IsEmpty())
649 switch (Item
[J
]->Type
) {
659 if (StartX
== Item
[J
]->X1
)
660 Item
[J
]->X2
= StartX
;
662 Item
[J
]->X2
= StartX
- 1;
668 //////////////////////////////////////////////////////////////////////////
671 Инициализация элементов диалога.
673 InitDialogObjects возвращает ID элемента с фокусом ввода
674 Параметр - для выборочной реинициализации элементов. ID = -1 - касаемо всех объектов
677 TODO: Необходимо применить ProcessRadioButton для исправления
678 кривых рук некоторых плагинописателей (а надо?)
680 unsigned Dialog::InitDialogObjects(unsigned ID
)
682 CriticalSectionLock
Lock(CS
);
685 DialogItemEx
*CurItem
;
686 unsigned InitItemCount
;
688 _DIALOG(CleverSysLog
CL(L
"Init Dialog"));
690 if (ID
== (unsigned)-1) // инициализируем все?
693 InitItemCount
= ItemCount
;
694 } else if (ID
+ 1 > ItemCount
) {
697 InitItemCount
= ID
+ 1;
700 // если FocusPos в пределах и элемент задисаблен, то ищем сначала
701 if (FocusPos
!= (unsigned)-1 && FocusPos
< ItemCount
702 && (Item
[FocusPos
]->Flags
& (DIF_DISABLE
| DIF_NOFOCUS
| DIF_HIDDEN
)))
703 FocusPos
= (unsigned)-1; // будем искать сначала!
705 // предварительный цикл по поводу кнопок
706 for (I
= ID
; I
< InitItemCount
; I
++) {
708 ItemFlags
= CurItem
->Flags
;
709 Type
= CurItem
->Type
;
711 if (Type
== DI_BUTTON
&& ItemFlags
& DIF_SETSHIELD
) {
712 CurItem
->strData
= FARString(L
"\x2580\x2584 ") + CurItem
->strData
;
716 для кнопок не имеющи стиля "Показывает заголовок кнопки без скобок"
717 добавим энти самые скобки
719 if (Type
== DI_BUTTON
&& !(ItemFlags
& DIF_NOBRACKETS
)) {
720 LPCWSTR Brackets
[] = {L
"[ ", L
" ]", L
"{ ", L
" }"};
721 int Start
= (CurItem
->DefaultButton
? 2 : 0);
722 if (CurItem
->strData
.At(0) != *Brackets
[Start
]) {
723 CurItem
->strData
= Brackets
[Start
] + CurItem
->strData
+ Brackets
[Start
+ 1];
726 // предварительный поик фокуса
727 if (FocusPos
== (unsigned)-1 && CanGetFocus(Type
) && CurItem
->Focus
728 && !(ItemFlags
& (DIF_DISABLE
| DIF_NOFOCUS
| DIF_HIDDEN
)))
729 FocusPos
= I
; // запомним первый фокусный элемент
731 CurItem
->Focus
= 0; // сбросим для всех, чтобы не оказалось,
732 // что фокусов - как у дурочка фантиков
734 // сбросим флаг DIF_CENTERGROUP для редакторов
740 case DI_VTEXT
: // ????
744 if (ItemFlags
& DIF_CENTERGROUP
)
745 CurItem
->Flags
&= ~DIF_CENTERGROUP
;
750 Опять про фокус ввода - теперь, если "чудо" забыло выставить
751 хотя бы один, то ставим на первый подходящий
753 if (FocusPos
== (unsigned)-1) {
754 for (I
= 0; I
< ItemCount
; I
++) // по всем!!!!
758 if (CanGetFocus(CurItem
->Type
) && !(CurItem
->Flags
& (DIF_DISABLE
| DIF_NOFOCUS
| DIF_HIDDEN
))) {
765 if (FocusPos
== (unsigned)-1) // ну ни хрена себе - нет ни одного
766 { // элемента с возможностью фокуса
767 FocusPos
= 0; // убится, блин
770 // ну вот и добрались до!
771 Item
[FocusPos
]->Focus
= 1;
772 // а теперь все сначала и по полной программе...
773 ProcessCenterGroup(); // сначала отцентрируем
775 for (I
= ID
; I
< InitItemCount
; I
++) {
777 Type
= CurItem
->Type
;
778 ItemFlags
= CurItem
->Flags
;
780 if (Type
== DI_LISTBOX
) {
781 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
782 CurItem
->ListPtr
= new VMenu(nullptr, nullptr, 0, CurItem
->Y2
- CurItem
->Y1
+ 1,
783 VMENU_ALWAYSSCROLLBAR
| VMENU_LISTBOX
, nullptr, this);
786 if (CurItem
->ListPtr
) {
787 VMenu
*ListPtr
= CurItem
->ListPtr
;
788 ListPtr
->SetVDialogItemID(I
);
791 + Флаг DIF_LISTNOAMPERSAND. По умолчанию для DI_LISTBOX &
792 DI_COMBOBOX выставляется флаг MENU_SHOWAMPERSAND. Этот флаг
793 подавляет такое поведение
795 CurItem
->IFlags
.Set(DLGIIF_LISTREACTIONFOCUS
| DLGIIF_LISTREACTIONNOFOCUS
); // всегда!
796 ListPtr
->ChangeFlags(VMENU_DISABLED
, ItemFlags
& DIF_DISABLE
);
797 ListPtr
->ChangeFlags(VMENU_SHOWAMPERSAND
, !(ItemFlags
& DIF_LISTNOAMPERSAND
));
798 ListPtr
->ChangeFlags(VMENU_SHOWNOBOX
, ItemFlags
& DIF_LISTNOBOX
);
799 ListPtr
->ChangeFlags(VMENU_WRAPMODE
, ItemFlags
& DIF_LISTWRAPMODE
);
800 ListPtr
->ChangeFlags(VMENU_AUTOHIGHLIGHT
, ItemFlags
& DIF_LISTAUTOHIGHLIGHT
);
802 if (ItemFlags
& DIF_LISTAUTOHIGHLIGHT
)
803 ListPtr
->AssignHighlights(FALSE
);
805 ListPtr
->SetDialogStyle(DialogMode
.Check(DMODE_WARNINGSTYLE
));
806 ListPtr
->SetPosition(X1
+ CurItem
->X1
, Y1
+ CurItem
->Y1
, X1
+ CurItem
->X2
, Y1
+ CurItem
->Y2
);
807 ListPtr
->SetBoxType(SHORT_SINGLE_BOX
);
809 // поле FarDialogItem.Data для DI_LISTBOX используется как верхний заголовок листа
810 if (!(ItemFlags
& DIF_LISTNOBOX
) && !DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
811 ListPtr
->SetTitle(CurItem
->strData
);
815 // ListBox->DeleteItems(); //???? А НАДО ЛИ ????
816 if (CurItem
->ListItems
&& !DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
817 ListPtr
->AddItem(CurItem
->ListItems
);
820 ListPtr
->ChangeFlags(VMENU_LISTHASFOCUS
, CurItem
->Focus
);
823 // "редакторы" - разговор особый...
824 else if (FarIsEdit(Type
)) {
826 сбросим флаг DIF_EDITOR для строки ввода, отличной от DI_EDIT,
827 DI_FIXEDIT и DI_PSWEDIT
829 if (Type
!= DI_COMBOBOX
)
830 if ((ItemFlags
& DIF_EDITOR
) && Type
!= DI_EDIT
&& Type
!= DI_FIXEDIT
&& Type
!= DI_PSWEDIT
)
831 ItemFlags
&= ~DIF_EDITOR
;
833 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
835 new DlgEdit(this, I
, Type
== DI_MEMOEDIT
? DLGEDIT_MULTILINE
: DLGEDIT_SINGLELINE
);
837 if (Type
== DI_COMBOBOX
) {
838 CurItem
->ListPtr
= new VMenu(L
"", nullptr, 0, Opt
.Dialogs
.CBoxMaxHeight
,
839 VMENU_ALWAYSSCROLLBAR
| VMENU_NOTCHANGE
, nullptr, this);
840 CurItem
->ListPtr
->SetVDialogItemID(I
);
843 CurItem
->SelStart
= -1;
846 DlgEdit
*DialogEdit
= (DlgEdit
*)CurItem
->ObjPtr
;
847 // Mantis#58 - символ-маска с кодом 0х0А - пропадает
848 // DialogEdit->SetDialogParent((Type != DI_COMBOBOX && (ItemFlags & DIF_EDITOR) || (CurItem->Type==DI_PSWEDIT || CurItem->Type==DI_FIXEDIT))?
849 // FEDITLINE_PARENT_SINGLELINE:FEDITLINE_PARENT_MULTILINE);
850 DialogEdit
->SetDialogParent(
851 Type
== DI_MEMOEDIT
? FEDITLINE_PARENT_MULTILINE
: FEDITLINE_PARENT_SINGLELINE
);
852 DialogEdit
->SetReadOnly(0);
854 if (Type
== DI_COMBOBOX
) {
855 if (CurItem
->ListPtr
) {
856 VMenu
*ListPtr
= CurItem
->ListPtr
;
857 ListPtr
->SetBoxType(SHORT_SINGLE_BOX
);
858 DialogEdit
->SetDropDownBox(ItemFlags
& DIF_DROPDOWNLIST
);
859 ListPtr
->ChangeFlags(VMENU_WRAPMODE
, ItemFlags
& DIF_LISTWRAPMODE
);
860 ListPtr
->ChangeFlags(VMENU_DISABLED
, ItemFlags
& DIF_DISABLE
);
861 ListPtr
->ChangeFlags(VMENU_SHOWAMPERSAND
, !(ItemFlags
& DIF_LISTNOAMPERSAND
));
862 ListPtr
->ChangeFlags(VMENU_AUTOHIGHLIGHT
, ItemFlags
& DIF_LISTAUTOHIGHLIGHT
);
864 if (ItemFlags
& DIF_LISTAUTOHIGHLIGHT
)
865 ListPtr
->AssignHighlights(FALSE
);
867 if (CurItem
->ListItems
&& !DialogMode
.Check(DMODE_CREATEOBJECTS
))
868 ListPtr
->AddItem(CurItem
->ListItems
);
870 ListPtr
->SetFlags(VMENU_COMBOBOX
);
871 ListPtr
->SetDialogStyle(DialogMode
.Check(DMODE_WARNINGSTYLE
));
877 строка редакторирование должна иметь максимум в 511 символов
878 выставляем максимальный размер в том случае, если он еще не выставлен
882 if (DialogEdit
->GetMaxLength() == -1)
883 DialogEdit
->SetMaxLength(CurItem
->nMaxLength
? (int)CurItem
->nMaxLength
: -1);
885 DialogEdit
->SetPosition(X1
+ CurItem
->X1
, Y1
+ CurItem
->Y1
, X1
+ CurItem
->X2
, Y1
+ CurItem
->Y2
);
888 DialogEdit->SetObjectColor(
889 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE) ?
890 ((ItemFlags&DIF_DISABLE)?COL_WARNDIALOGEDITDISABLED:COL_WARNDIALOGEDIT):
891 ((ItemFlags&DIF_DISABLE)?COL_DIALOGEDITDISABLED:COL_DIALOGEDIT)),
892 FarColorToReal((ItemFlags&DIF_DISABLE)?COL_DIALOGEDITDISABLED:COL_DIALOGEDITSELECTED)
895 if (CurItem
->Type
== DI_PSWEDIT
) {
896 DialogEdit
->SetPasswordMode(TRUE
);
897 // ...Что бы небыло повадно... и для повыщения защиты, т.с.
898 ItemFlags
&= ~DIF_HISTORY
;
901 if (Type
== DI_FIXEDIT
) {
902 // DIF_HISTORY имеет более высокий приоритет, чем DIF_MASKEDIT
903 if (ItemFlags
& DIF_HISTORY
)
904 ItemFlags
&= ~DIF_MASKEDIT
;
907 если DI_FIXEDIT, то курсор сразу ставится на замену...
908 ай-ай - было недокументированно :-)
910 DialogEdit
->SetMaxLength(CurItem
->X2
- CurItem
->X1
+ 1
911 + (CurItem
->X2
== CurItem
->X1
|| !(ItemFlags
& DIF_HISTORY
) ? 0 : 1));
912 DialogEdit
->SetOvertypeMode(TRUE
);
915 Если тип строки ввода DI_FIXEDIT и установлен флаг DIF_MASKEDIT
916 и непустой параметр CurItem->Mask, то вызываем новую функцию
917 для установки маски в объект DlgEdit.
920 // Маска не должна быть пустой (строка из пробелов не учитывается)!
921 if ((ItemFlags
& DIF_MASKEDIT
) && !CurItem
->strMask
.IsEmpty()) {
922 RemoveExternalSpaces(CurItem
->strMask
);
923 if (!CurItem
->strMask
.IsEmpty()) {
924 DialogEdit
->SetInputMask(CurItem
->strMask
);
926 ItemFlags
&= ~DIF_MASKEDIT
;
933 Последовательно определенные поля ввода (edit controls),
934 имеющие этот флаг группируются в редактор с возможностью
935 вставки и удаления строк
937 if (!(ItemFlags
& DIF_EDITOR
) && CurItem
->Type
!= DI_COMBOBOX
) {
938 DialogEdit
->SetEditBeyondEnd(FALSE
);
940 if (!DialogMode
.Check(DMODE_INITOBJECTS
))
941 DialogEdit
->SetClearFlag(1);
944 if (CurItem
->Type
== DI_COMBOBOX
)
945 DialogEdit
->SetClearFlag(1);
949 Еже ли стоит флаг DIF_USELASTHISTORY и непустая строка ввода,
950 то подстанавливаем первое значение из History
952 if (CurItem
->Type
== DI_EDIT
953 && (ItemFlags
& (DIF_HISTORY
| DIF_USELASTHISTORY
))
954 == (DIF_HISTORY
| DIF_USELASTHISTORY
)) {
955 ProcessLastHistory(CurItem
, -1);
958 if ((ItemFlags
& DIF_MANUALADDHISTORY
) && !(ItemFlags
& DIF_HISTORY
))
959 ItemFlags
&= ~DIF_MANUALADDHISTORY
; // сбросим нафиг.
963 Если это ComBoBox и данные не установлены, то берем из списка
964 при условии, что хоть один из пунктов имеет Selected
967 if (Type
== DI_COMBOBOX
&& CurItem
->strData
.IsEmpty() && CurItem
->ListItems
) {
968 FarListItem
*ListItems
= CurItem
->ListItems
->Items
;
969 unsigned Length
= CurItem
->ListItems
->ItemsNumber
;
970 // CurItem->ListPtr->AddItem(CurItem->ListItems);
972 for (J
= 0; J
< Length
; J
++) {
973 if (ListItems
[J
].Flags
& LIF_SELECTED
) {
974 if (ItemFlags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
))
975 HiText2Str(CurItem
->strData
, ListItems
[J
].Text
);
977 CurItem
->strData
= ListItems
[J
].Text
;
984 DialogEdit
->SetCallbackState(false);
985 DialogEdit
->SetString(CurItem
->strData
);
986 DialogEdit
->SetCallbackState(true);
988 if (Type
== DI_FIXEDIT
)
989 DialogEdit
->SetCurPos(0);
991 // Для обычных строк отрубим постоянные блоки
992 if (!(ItemFlags
& DIF_EDITOR
))
993 DialogEdit
->SetPersistentBlocks(Opt
.Dialogs
.EditBlock
);
995 DialogEdit
->SetDelRemovesBlocks(Opt
.Dialogs
.DelRemovesBlocks
);
997 if (ItemFlags
& DIF_READONLY
)
998 DialogEdit
->SetReadOnly(1);
999 } else if (Type
== DI_USERCONTROL
) {
1000 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
))
1001 CurItem
->UCData
= new DlgUserControl
;
1004 CurItem
->Flags
= ItemFlags
;
1007 // если будет редактор, то обязательно будет выделен.
1008 SelectOnEntry(FocusPos
, TRUE
);
1009 // все объекты созданы!
1010 DialogMode
.Set(DMODE_CREATEOBJECTS
);
1014 const wchar_t *Dialog::GetDialogTitle()
1016 CriticalSectionLock
Lock(CS
);
1017 DialogItemEx
*CurItem
, *CurItemList
= nullptr;
1019 for (unsigned I
= 0; I
< ItemCount
; I
++) {
1022 // по первому попавшемуся "тексту" установим заголовок консоли!
1023 if ((CurItem
->Type
== DI_TEXT
|| CurItem
->Type
== DI_DOUBLEBOX
|| CurItem
->Type
== DI_SINGLEBOX
)) {
1024 const wchar_t *Ptr
= CurItem
->strData
;
1027 if (IsAlpha(*Ptr
) || iswdigit(*Ptr
))
1029 } else if (CurItem
->Type
== DI_LISTBOX
&& !I
)
1030 CurItemList
= CurItem
;
1034 return CurItemList
->ListPtr
->GetPtrTitle();
1037 return nullptr; //""
1040 void Dialog::ProcessLastHistory(DialogItemEx
*CurItem
, int MsgIndex
)
1042 CriticalSectionLock
Lock(CS
);
1043 FARString
&strData
= CurItem
->strData
;
1045 if (strData
.IsEmpty()) {
1046 FARString strRegKey
= fmtSavedDialogHistory
;
1047 strRegKey
+= CurItem
->strHistory
;
1048 History::ReadLastItem(strRegKey
.GetMB().c_str(), strData
);
1050 if (MsgIndex
!= -1) {
1051 // обработка DM_SETHISTORY => надо пропустить изменение текста через
1052 // диалоговую функцию
1053 FarDialogItemData IData
;
1054 IData
.PtrData
= const_cast<wchar_t *>(strData
.CPtr());
1055 IData
.PtrLength
= (int)strData
.GetLength();
1056 SendDlgMessage(this, DM_SETTEXT
, MsgIndex
, (LONG_PTR
)&IData
);
1062 static int ToRange(int Val
, int Min
, int Max
)
1064 return std::min(std::max(Val
, Min
), Max
);
1067 // Изменение координат и/или размеров итема диалога.
1068 BOOL
Dialog::SetItemRect(unsigned ID
, SMALL_RECT
*aRect
)
1070 CriticalSectionLock
Lock(CS
);
1072 if (ID
>= ItemCount
)
1077 Rect
.Left
= ToRange(Rect
.Left
, 0, X2
-X1
);
1078 Rect
.Top
= ToRange(Rect
.Top
, 0, Y2
-Y1
);
1079 Rect
.Right
= ToRange(Rect
.Right
, Rect
.Left
, X2
-X1
);
1080 Rect
.Bottom
= ToRange(Rect
.Bottom
, Rect
.Top
, Y2
-Y1
);
1082 DialogItemEx
*CurItem
= Item
[ID
];
1083 int Type
= CurItem
->Type
;
1084 CurItem
->X1
= Rect
.Left
;
1085 CurItem
->Y1
= (Rect
.Top
< 0) ? 0 : Rect
.Top
;
1087 if (FarIsEdit(Type
)) {
1088 DlgEdit
*DialogEdit
= (DlgEdit
*)CurItem
->ObjPtr
;
1089 CurItem
->X2
= Rect
.Right
;
1090 CurItem
->Y2
= (Type
== DI_MEMOEDIT
? Rect
.Bottom
: 0);
1091 DialogEdit
->SetPosition(X1
+ Rect
.Left
, Y1
+ Rect
.Top
, X1
+ Rect
.Right
, Y1
+ Rect
.Top
);
1092 } else if (Type
== DI_LISTBOX
) {
1093 CurItem
->X2
= Rect
.Right
;
1094 CurItem
->Y2
= Rect
.Bottom
;
1095 CurItem
->ListPtr
->SetPosition(X1
+ Rect
.Left
, Y1
+ Rect
.Top
, X1
+ Rect
.Right
, Y1
+ Rect
.Bottom
);
1096 CurItem
->ListPtr
->SetMaxHeight(CurItem
->Y2
- CurItem
->Y1
+ 1);
1101 CurItem
->X2
= Rect
.Right
;
1102 CurItem
->Y2
= 0; // ???
1105 CurItem
->X2
= 0; // ???
1106 CurItem
->Y2
= Rect
.Bottom
;
1109 case DI_USERCONTROL
:
1110 CurItem
->X2
= Rect
.Right
;
1111 CurItem
->Y2
= Rect
.Bottom
;
1115 if (DialogMode
.Check(DMODE_SHOW
)) {
1116 ShowDialog((unsigned)-1);
1123 BOOL
Dialog::GetItemRect(unsigned I
, SMALL_RECT
&Rect
)
1125 CriticalSectionLock
Lock(CS
);
1130 DialogItemEx
*CurItem
= Item
[I
];
1131 DWORD ItemFlags
= CurItem
->Flags
;
1132 int Type
= CurItem
->Type
;
1134 Rect
.Left
= CurItem
->X1
;
1135 Rect
.Top
= CurItem
->Y1
;
1136 Rect
.Right
= CurItem
->X2
;
1137 Rect
.Bottom
= CurItem
->Y2
;
1148 Len
= ((ItemFlags
& DIF_SHOWAMPERSAND
)
1149 ? (int)CurItem
->strData
.CellsCount()
1150 : HiStrCellsCount(CurItem
->strData
));
1157 if (CurItem
->X1
== -1)
1158 Rect
.Left
= (X2
- X1
+ 1 - Len
) / 2;
1163 if (CurItem
->Y1
== -1)
1164 Rect
.Top
= (Y2
- Y1
+ 1) / 2;
1169 Rect
.Bottom
= Rect
.Top
;
1171 if (!Rect
.Right
|| Rect
.Right
== Rect
.Left
)
1172 Rect
.Right
= Rect
.Left
+ Len
- (Len
? 1 : 0);
1174 if (ItemFlags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
1175 Rect
.Bottom
= Rect
.Top
;
1176 Rect
.Left
= (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 3 : 0); //???
1177 Rect
.Right
= X2
- X1
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 5 : 0); //???
1183 if (CurItem
->X1
== -1)
1184 Rect
.Left
= (X2
- X1
+ 1) / 2;
1189 if (CurItem
->Y1
== -1)
1190 Rect
.Top
= (Y2
- Y1
+ 1 - Len
) / 2;
1195 Rect
.Right
= Rect
.Left
;
1197 // Rect.bottom=Rect.top+Len;
1198 if (!Rect
.Bottom
|| Rect
.Bottom
== Rect
.Top
)
1199 Rect
.Bottom
= Rect
.Top
+ Len
- (Len
? 1 : 0);
1201 #if defined(VTEXT_ADN_SEPARATORS)
1203 if (ItemFlags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
1204 Rect
.Right
= Rect
.Left
;
1205 Rect
.Top
= (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 1 : 0); //???
1206 Rect
.Bottom
= Y2
- Y1
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 3 : 0); //???
1213 Rect
.Bottom
= Rect
.Top
;
1214 Rect
.Right
= Rect
.Left
+ Len
;
1217 case DI_RADIOBUTTON
:
1218 Rect
.Bottom
= Rect
.Top
;
1219 Rect
.Right
= Rect
.Left
+ Len
+ ((Type
== DI_CHECKBOX
) ? 4 : (ItemFlags
& DIF_MOVESELECT
? 3 : 4));
1225 Rect
.Bottom
= Rect
.Top
;
1232 bool Dialog::ItemHasDropDownArrow(const DialogItemEx
*Item
)
1234 return ((!Item
->strHistory
.IsEmpty() && (Item
->Flags
& DIF_HISTORY
) && Opt
.Dialogs
.EditHistory
)
1235 || (Item
->Type
== DI_COMBOBOX
&& Item
->ListPtr
&& Item
->ListPtr
->GetItemCount() > 0));
1238 //////////////////////////////////////////////////////////////////////////
1241 Получение данных и удаление "редакторов"
1243 void Dialog::DeleteDialogObjects()
1245 CriticalSectionLock
Lock(CS
);
1246 DialogItemEx
*CurItem
;
1248 for (unsigned I
= 0; I
< ItemCount
; I
++) {
1251 switch (CurItem
->Type
) {
1258 if (CurItem
->ObjPtr
)
1259 delete (DlgEdit
*)(CurItem
->ObjPtr
);
1263 if ((CurItem
->Type
== DI_COMBOBOX
|| CurItem
->Type
== DI_LISTBOX
) && CurItem
->ListPtr
)
1264 delete CurItem
->ListPtr
;
1267 case DI_USERCONTROL
:
1269 if (CurItem
->UCData
)
1270 delete CurItem
->UCData
;
1275 if (CurItem
->Flags
& DIF_AUTOMATION
)
1276 if (CurItem
->AutoPtr
)
1277 free(CurItem
->AutoPtr
);
1281 //////////////////////////////////////////////////////////////////////////
1284 Сохраняет значение из полей редактирования.
1285 При установленном флаге DIF_HISTORY, сохраняет данные в реестре.
1287 void Dialog::GetDialogObjectsData()
1289 CriticalSectionLock
Lock(CS
);
1291 DialogItemEx
*CurItem
;
1293 for (unsigned I
= 0; I
< ItemCount
; I
++) {
1295 DWORD IFlags
= CurItem
->Flags
;
1297 switch (Type
= CurItem
->Type
) {
1304 if (CurItem
->ObjPtr
) {
1306 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
1312 EditPtr
->GetString(strData
);
1314 if (ExitCode
>= 0 && (IFlags
& DIF_HISTORY
) && !(IFlags
& DIF_MANUALADDHISTORY
) && // при мануале не добавляем
1315 !CurItem
->strHistory
.IsEmpty() && Opt
.Dialogs
.EditHistory
) {
1316 AddToEditHistory(strData
, CurItem
->strHistory
);
1321 ! В History должно заносится значение (для DIF_EXPAND...) перед
1327 Проверка - этот элемент предполагает расширение переменных среды?
1328 т.к. функция GetDialogObjectsData() может вызываться самостоятельно
1334 ! Для DI_PSWEDIT и DI_FIXEDIT обработка DIF_EDITEXPAND не нужна
1335 (DI_FIXEDIT допускается для случая если нету маски)
1338 if ((IFlags
& DIF_EDITEXPAND
) && Type
!= DI_PSWEDIT
&& Type
!= DI_FIXEDIT
) {
1339 apiExpandEnvironmentStrings(strData
, strData
);
1340 // как бы грязный хак, нам нужно обновить строку чтоб отдавалась правильная строка
1341 // для различных DM_* после закрытия диалога, но ни в коем случае нельзя чтоб
1342 // высылался DN_EDITCHANGE для этого изменения, ибо диалог уже закрыт.
1343 EditPtr
->SetCallbackState(false);
1344 EditPtr
->SetString(strData
);
1345 EditPtr
->SetCallbackState(true);
1348 CurItem
->strData
= strData
;
1355 if(CurItem->ListPtr)
1357 CurItem->ListPos=CurItem->ListPtr->GetSelectPos();
1366 if ((Type
== DI_COMBOBOX
|| Type
== DI_LISTBOX
) && CurItem
->ListPtr
&& CurItem
->ListItems
&& DlgProc
== DefDlgProc
)
1368 int ListPos
=CurItem
->ListPtr
->GetSelectPos();
1370 if (ListPos
< CurItem
->ListItems
->ItemsNumber
)
1372 for (int J
=0; J
< CurItem
->ListItems
->ItemsNumber
; ++J
)
1373 CurItem
->ListItems
->Items
[J
].Flags
&=~LIF_SELECTED
;
1375 CurItem
->ListItems
->Items
[ListPos
].Flags
|=LIF_SELECTED
;
1381 if ((Type
== DI_COMBOBOX
|| Type
== DI_LISTBOX
)) {
1382 CurItem
->ListPos
= CurItem
->ListPtr
? CurItem
->ListPtr
->GetSelectPos() : 0;
1389 // Функция формирования и запроса цветов.
1390 DWORD
Dialog::CtlColorDlgItem(int ItemPos
, const DialogItemEx
*CurItem
)
1392 CriticalSectionLock
Lock(CS
);
1393 const int Type
= CurItem
->Type
;
1394 const int Focus
= CurItem
->Focus
;
1395 const int Default
= CurItem
->DefaultButton
;
1396 const DWORD Flags
= CurItem
->Flags
;
1398 const bool DisabledItem
= (Flags
& DIF_DISABLE
) != 0;
1403 case DI_DOUBLEBOX
: {
1404 if (Flags
& DIF_SETCOLOR
)
1405 Attr
= Flags
& DIF_COLORMASK
;
1407 Attr
= DialogMode
.Check(DMODE_WARNINGSTYLE
)
1408 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGBOX
)
1409 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGBOX
);
1412 Attr
= MAKELONG(MAKEWORD(FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1413 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGBOXTITLE
)
1414 : (DisabledItem
? COL_DIALOGDISABLED
1415 : COL_DIALOGBOXTITLE
)), // Title LOBYTE
1416 FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1417 ? (DisabledItem
? COL_WARNDIALOGDISABLED
1418 : COL_WARNDIALOGHIGHLIGHTBOXTITLE
)
1419 : (DisabledItem
? COL_DIALOGDISABLED
1420 : COL_DIALOGHIGHLIGHTBOXTITLE
))), // HiText HIBYTE
1421 MAKEWORD(FarColorToReal(Attr
), // Box LOBYTE
1426 #if defined(VTEXT_ADN_SEPARATORS)
1430 if (Flags
& DIF_SETCOLOR
)
1431 Attr
= Flags
& DIF_COLORMASK
;
1433 if (Flags
& DIF_BOXCOLOR
)
1434 Attr
= DialogMode
.Check(DMODE_WARNINGSTYLE
)
1435 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGBOX
)
1436 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGBOX
);
1438 Attr
= DialogMode
.Check(DMODE_WARNINGSTYLE
)
1439 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
)
1440 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
);
1443 Attr
= MAKELONG(MAKEWORD(FarColorToReal(Attr
),
1444 FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1445 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGHIGHLIGHTTEXT
)
1446 : (DisabledItem
? COL_DIALOGDISABLED
1447 : COL_DIALOGHIGHLIGHTTEXT
) // HIBYTE HiText
1449 ((Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
)) ? (
1450 MAKEWORD(FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1451 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGBOX
)
1452 : (DisabledItem
? COL_DIALOGDISABLED
1453 : COL_DIALOGBOX
) // Box LOBYTE
1459 #if !defined(VTEXT_ADN_SEPARATORS)
1461 if (Flags
& DIF_BOXCOLOR
)
1462 Attr
= DialogMode
.Check(DMODE_WARNINGSTYLE
)
1463 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGBOX
)
1464 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGBOX
);
1465 else if (Flags
& DIF_SETCOLOR
)
1466 Attr
= (Flags
& DIF_COLORMASK
);
1468 Attr
= (DialogMode
.Check(DMODE_WARNINGSTYLE
)
1469 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
)
1470 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
));
1472 Attr
= MAKEWORD(MAKEWORD(FarColorToReal(Attr
), 0), MAKEWORD(0, 0));
1477 case DI_RADIOBUTTON
: {
1478 if (Flags
& DIF_SETCOLOR
)
1479 Attr
= (Flags
& DIF_COLORMASK
);
1481 Attr
= (DialogMode
.Check(DMODE_WARNINGSTYLE
)
1482 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
)
1483 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
));
1485 Attr
= MAKEWORD(FarColorToReal(Attr
),
1486 FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1487 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGHIGHLIGHTTEXT
)
1488 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGHIGHLIGHTTEXT
))); // HiText
1493 SetCursorType(0, 10);
1494 Attr
= MAKEWORD((Flags
& DIF_SETCOLOR
)
1495 ? (Flags
& DIF_COLORMASK
)
1496 : FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1497 ? (DisabledItem
? COL_WARNDIALOGDISABLED
1498 : (Default
? COL_WARNDIALOGSELECTEDDEFAULTBUTTON
1499 : COL_WARNDIALOGSELECTEDBUTTON
))
1500 : (DisabledItem
? COL_DIALOGDISABLED
1501 : (Default
? COL_DIALOGSELECTEDDEFAULTBUTTON
1502 : COL_DIALOGSELECTEDBUTTON
))), // TEXT
1503 FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1504 ? (DisabledItem
? COL_WARNDIALOGDISABLED
1505 : (Default
? COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON
1506 : COL_WARNDIALOGHIGHLIGHTSELECTEDBUTTON
))
1507 : (DisabledItem
? COL_DIALOGDISABLED
1508 : (Default
? COL_DIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON
1509 : COL_DIALOGHIGHLIGHTSELECTEDBUTTON
)))); // HiText
1511 Attr
= MAKEWORD((Flags
& DIF_SETCOLOR
)
1512 ? (Flags
& DIF_COLORMASK
)
1513 : FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1514 ? (DisabledItem
? COL_WARNDIALOGDISABLED
1515 : (Default
? COL_WARNDIALOGDEFAULTBUTTON
1516 : COL_WARNDIALOGBUTTON
))
1517 : (DisabledItem
? COL_DIALOGDISABLED
1518 : (Default
? COL_DIALOGDEFAULTBUTTON
1519 : COL_DIALOGBUTTON
))), // TEXT
1520 FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
)
1521 ? (DisabledItem
? COL_WARNDIALOGDISABLED
1522 : (Default
? COL_WARNDIALOGHIGHLIGHTDEFAULTBUTTON
1523 : COL_WARNDIALOGHIGHLIGHTBUTTON
))
1524 : (DisabledItem
? COL_DIALOGDISABLED
1525 : (Default
? COL_DIALOGHIGHLIGHTDEFAULTBUTTON
1526 : COL_DIALOGHIGHLIGHTBUTTON
)))); // HiText
1536 if (Type
== DI_COMBOBOX
&& (Flags
& DIF_DROPDOWNLIST
)) {
1537 if (DialogMode
.Check(DMODE_WARNINGSTYLE
))
1538 Attr
= MAKELONG(MAKEWORD( // LOWORD
1540 FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
1541 : COL_WARNDIALOGEDIT
),
1543 FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
1544 : COL_DIALOGEDITSELECTED
)),
1547 FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
1548 : COL_DIALOGEDITUNCHANGED
), //???
1551 DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
)));
1553 Attr
= MAKELONG(MAKEWORD( // LOWORD
1555 FarColorToReal(DisabledItem
1556 ? COL_DIALOGEDITDISABLED
1557 : (!Focus
? COL_DIALOGEDIT
1558 : COL_DIALOGEDITSELECTED
)),
1560 FarColorToReal(DisabledItem
1561 ? COL_DIALOGEDITDISABLED
1562 : (!Focus
? COL_DIALOGEDIT
1563 : COL_DIALOGEDITSELECTED
))),
1566 FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
1567 : COL_DIALOGEDITUNCHANGED
), //???
1569 FarColorToReal(DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
)));
1571 if (DialogMode
.Check(DMODE_WARNINGSTYLE
))
1572 Attr
= MAKELONG(MAKEWORD( // LOWORD
1574 FarColorToReal(DisabledItem
1575 ? COL_WARNDIALOGEDITDISABLED
1576 : (Flags
& DIF_NOFOCUS
? COL_DIALOGEDITUNCHANGED
1577 : COL_WARNDIALOGEDIT
)),
1579 FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
1580 : COL_DIALOGEDITSELECTED
)),
1583 FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
1584 : COL_DIALOGEDITUNCHANGED
), //???
1587 DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
)));
1589 Attr
= MAKELONG(MAKEWORD( // LOWORD
1591 FarColorToReal(DisabledItem
1592 ? COL_DIALOGEDITDISABLED
1593 : (Flags
& DIF_NOFOCUS
? COL_DIALOGEDITUNCHANGED
1596 FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
1597 : COL_DIALOGEDITSELECTED
)),
1600 FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
1601 : COL_DIALOGEDITUNCHANGED
), //???
1603 FarColorToReal(DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
)));
1609 Item
[ItemPos
]->ListPtr
->SetColors(nullptr);
1617 ++InCtlColorDlgItem
;
1618 DWORD out
= DlgProc((HANDLE
)this, DN_CTLCOLORDLGITEM
, ItemPos
, Attr
);
1619 --InCtlColorDlgItem
;
1623 static void SetColorNormal(DWORD Attr
, const std::unique_ptr
<DialogItemTrueColors
> &TrueColors
)
1625 ComposeAndSetColor(Attr
& 0xff, TrueColors
? &TrueColors
->Normal
: nullptr);
1628 static void SetColorFrame(DWORD Attr
, const std::unique_ptr
<DialogItemTrueColors
> &TrueColors
)
1630 ComposeAndSetColor(LOBYTE(HIWORD(Attr
)), TrueColors
? &TrueColors
->Frame
: nullptr);
1634 //////////////////////////////////////////////////////////////////////////
1637 Отрисовка элементов диалога на экране.
1639 void Dialog::ShowDialog(unsigned ID
)
1641 CriticalSectionLock
Lock(CS
);
1647 DialogItemEx
*CurItem
;
1649 unsigned I
, DrawItemCount
;
1652 // Если не разрешена отрисовка, то вываливаем.
1653 if (IsEnableRedraw
|| // разрешена прорисовка ?
1654 (ID
+ 1 > ItemCount
) || // а номер в рамках дозволенного?
1655 DialogMode
.Check(DMODE_DRAWING
) || // диалог рисуется?
1656 !DialogMode
.Check(DMODE_SHOW
) || // если не видим, то и не отрисовываем.
1657 !DialogMode
.Check(DMODE_INITOBJECTS
))
1660 DialogMode
.Set(DMODE_DRAWING
); // диалог рисуется!!!
1661 ChangePriority
ChPriority(ChangePriority::NORMAL
);
1663 if (ID
== (unsigned)-1) // рисуем все?
1665 // Перед прорисовкой диалога посылаем сообщение в обработчик
1666 if (!DlgProc((HANDLE
)this, DN_DRAWDIALOG
, 0, 0)) {
1667 DialogMode
.Clear(DMODE_DRAWING
); // конец отрисовки диалога!!!
1671 // перед прорисовкой подложки окна диалога
1672 if (!DialogMode
.Check(DMODE_NODRAWSHADOW
))
1673 Shadow(DialogMode
.Check(DMODE_FULLSHADOW
) != FALSE
); // "наводим" тень
1675 if (!DialogMode
.Check(DMODE_NODRAWPANEL
)) {
1676 Attr
= (DWORD
)DlgProc((HANDLE
)this, DN_CTLCOLORDIALOG
, 0,
1677 DialogMode
.Check(DMODE_WARNINGSTYLE
) ? COL_WARNDIALOGTEXT
: COL_DIALOGTEXT
);
1678 SetScreen(X1
, Y1
, X2
, Y2
, L
' ', Attr
);
1682 DrawItemCount
= ItemCount
;
1684 DrawItemCount
= ID
+ 1;
1688 IFlags.Set(DIMODE_REDRAW)
1690 если рисуется контрол и по Z-order`у он пересекается с
1691 другим контролом (по координатам), то для "позднего"
1692 контрола тоже нужна прорисовка.
1695 bool CursorVisible
= false;
1696 DWORD CursorSize
= 0;
1698 if (ID
!= (unsigned)-1 && FocusPos
!= ID
) {
1699 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
&& Item
[FocusPos
]->UCData
->CursorPos
.X
!= -1
1700 && Item
[FocusPos
]->UCData
->CursorPos
.Y
!= -1) {
1701 CursorVisible
= Item
[FocusPos
]->UCData
->CursorVisible
;
1702 CursorSize
= Item
[FocusPos
]->UCData
->CursorSize
;
1706 SetCursorType(CursorVisible
, CursorSize
);
1709 for (I
= ID
; I
< DrawItemCount
; I
++) {
1712 if (CurItem
->Flags
& DIF_HIDDEN
)
1717 Перед прорисовкой каждого элемента посылаем сообщение
1718 посредством функции SendDlgMessage - в ней делается все!
1720 if (!SendDlgMessage((HANDLE
)this, DN_DRAWDLGITEM
, I
, 0))
1724 short CX1
= CurItem
->X1
;
1725 short CY1
= CurItem
->Y1
;
1726 short CX2
= CurItem
->X2
;
1727 short CY2
= CurItem
->Y2
;
1735 short CW
= CX2
- CX1
+ 1;
1736 short CH
= CY2
- CY1
+ 1;
1737 Attr
= CtlColorDlgItem(I
, CurItem
);
1740 // TODO: прежде чем эту строку применять... нужно проверить _ВСЕ_ диалоги на предмет X2, Y2. !!!
1741 if (((CX1
> -1) && (CX2
> 0) && (CX2
> CX1
)) &&
1742 ((CY1
> -1) && (CY2
> 0) && (CY2
> CY1
)))
1743 SetScreen(X1
+CX1
,Y1
+CY1
,X1
+CX2
,Y1
+CY2
,' ',Attr
&0xFF);
1747 switch (CurItem
->Type
) {
1748 /* ***************************************************************** */
1750 case DI_DOUBLEBOX
: {
1751 BOOL IsDrawTitle
= TRUE
;
1752 GotoXY(X1
+ CX1
, Y1
+ CY1
);
1753 SetColorFrame(Attr
, CurItem
->TrueColors
);
1756 DrawLine(CX2
- CX1
+ 1, CurItem
->Type
== DI_SINGLEBOX
? 8 : 9); //???
1757 } else if (CX1
== CX2
) {
1758 DrawLine(CY2
- CY1
+ 1, CurItem
->Type
== DI_SINGLEBOX
? 10 : 11);
1759 IsDrawTitle
= FALSE
;
1761 Box(X1
+ CX1
, Y1
+ CY1
, X1
+ CX2
, Y1
+ CY2
, LOBYTE(HIWORD(Attr
)),
1762 (CurItem
->Type
== DI_SINGLEBOX
) ? SINGLE_BOX
: DOUBLE_BOX
);
1765 if (!CurItem
->strData
.IsEmpty() && IsDrawTitle
) {
1766 // ! Пусть диалог сам заботится о ширине собственного заголовка.
1767 strStr
= CurItem
->strData
;
1768 TruncStrFromEnd(strStr
, CW
- 2); // 5 ???
1769 LenText
= LenStrItem(I
, strStr
);
1771 if (LenText
< CW
- 2 && !strStr
.Begins(L
' ') ) {
1772 strStr
.Insert(0, L
' ');
1773 LenText
= LenStrItem(I
, strStr
);
1776 if (LenText
< CW
- 2 && !strStr
.Ends(L
' ') ) { // пробел после текста заголовка и рамкой
1777 strStr
.Append(L
' ');
1778 LenText
= LenStrItem(I
, strStr
);
1781 X
= X1
+ CX1
+ (CW
- LenText
) / 2;
1783 if ((CurItem
->Flags
& DIF_LEFTTEXT
) && X1
+ CX1
+ 1 < X
)
1786 SetColorNormal(Attr
, CurItem
->TrueColors
);
1787 GotoXY(X
, Y1
+ CY1
);
1789 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
1791 else if (CurItem
->TrueColors
)
1792 HiText(strStr
, ComposeColor(HIBYTE(LOWORD(Attr
)), &CurItem
->TrueColors
->Hilighted
));
1794 HiText(strStr
, HIBYTE(LOWORD(Attr
)));
1799 /* ***************************************************************** */
1801 strStr
= CurItem
->strData
;
1802 LenText
= LenStrItem(I
, strStr
);
1804 if (!(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))
1805 && (CurItem
->Flags
& DIF_CENTERTEXT
) && CX1
!= -1)
1806 LenText
= LenStrItem(I
, CenterStr(strStr
, strStr
, CX2
- CX1
+ 1));
1808 X
= (CX1
== -1 || (CurItem
->Flags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)))
1809 ? (X2
- X1
+ 1 - LenText
) / 2
1811 Y
= (CY1
== -1) ? (Y2
- Y1
+ 1) / 2 : CY1
;
1816 if ((CX2
<= 0) || (CX2
< CX1
))
1819 if (X1
+ X
+ LenText
> X2
) {
1820 int tmpCW
= ObjWidth
;
1825 strStr
.TruncateByCells(tmpCW
- 1);
1829 // SetScreen(X1+CX1,Y1+CY1,X1+CX2,Y1+CY2,' ',Attr&0xFF);
1831 if (CX1
> -1 && CX2
> CX1
1832 && !(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))) { // половинчатое решение
1834 int CntChr
= CX2
- CX1
+ 1;
1835 SetColorNormal(Attr
, CurItem
->TrueColors
);
1836 GotoXY(X1
+ X
, Y1
+ Y
);
1838 if (X1
+ X
+ CntChr
- 1 > X2
)
1839 CntChr
= X2
- (X1
+ X
) + 1;
1841 FS
<< fmt::Cells() << fmt::Expand(CntChr
) << L
"";
1843 if (CntChr
< LenText
)
1844 strStr
.TruncateByCells(CntChr
);
1847 if (CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
1848 SetColorFrame(Attr
, CurItem
->TrueColors
);
1850 + ((CurItem
->Flags
& DIF_SEPARATORUSER
)
1852 : (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 3 : 0)),
1854 ShowUserSeparator((CurItem
->Flags
& DIF_SEPARATORUSER
)
1856 : RealWidth
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 6 : 0 /* -1 */),
1857 (CurItem
->Flags
& DIF_SEPARATORUSER
)
1859 : (CurItem
->Flags
& DIF_SEPARATOR2
? 3 : 1),
1863 SetColorNormal(Attr
, CurItem
->TrueColors
);
1864 GotoXY(X1
+ X
, Y1
+ Y
);
1866 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
) {
1867 // MessageBox(0, strStr, strStr, MB_OK);
1870 // MessageBox(0, strStr, strStr, MB_OK);
1871 HiText(strStr
, HIBYTE(LOWORD(Attr
)));
1876 /* ***************************************************************** */
1878 strStr
= CurItem
->strData
;
1879 LenText
= LenStrItem(I
, strStr
);
1881 if (!(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))
1882 && (CurItem
->Flags
& DIF_CENTERTEXT
) && CY1
!= -1)
1883 LenText
= StrLength(CenterStr(strStr
, strStr
, CY2
- CY1
+ 1));
1885 X
= (CX1
== -1) ? (X2
- X1
+ 1) / 2 : CX1
;
1886 Y
= (CY1
== -1 || (CurItem
->Flags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)))
1887 ? (Y2
- Y1
+ 1 - LenText
) / 2
1893 if ((CY2
<= 0) || (CY2
< CY1
))
1894 CH
= LenStrItem(I
, strStr
);
1896 if (Y1
+ Y
+ LenText
> Y2
) {
1897 int tmpCH
= ObjHeight
;
1902 strStr
.TruncateByCells(tmpCH
- 1);
1906 // SetScreen(X1+CX1,Y1+CY1,X1+CX2,Y1+CY2,' ',Attr&0xFF);
1908 if (CY1
> -1 && CY2
> 0 && CY2
> CY1
1909 && !(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))) { // половинчатое решение
1911 int CntChr
= CY2
- CY1
+ 1;
1912 SetColorNormal(Attr
, CurItem
->TrueColors
);
1913 GotoXY(X1
+ X
, Y1
+ Y
);
1915 if (Y1
+ Y
+ CntChr
- 1 > Y2
)
1916 CntChr
= Y2
- (Y1
+ Y
) + 1;
1918 vmprintf(L
"%*ls", CntChr
, L
"");
1921 #if defined(VTEXT_ADN_SEPARATORS)
1923 if (CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
1924 SetColorFrame(Attr
, CurItem
->TrueColors
);
1927 + ((CurItem
->Flags
& DIF_SEPARATORUSER
)
1929 : (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 1 : 0))); //????
1930 ShowUserSeparator((CurItem
->Flags
& DIF_SEPARATORUSER
)
1932 : RealHeight
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 2 : 0),
1933 (CurItem
->Flags
& DIF_SEPARATORUSER
)
1935 : (CurItem
->Flags
& DIF_SEPARATOR2
? 7 : 5),
1940 SetColorNormal(Attr
, CurItem
->TrueColors
);
1941 GotoXY(X1
+ X
, Y1
+ Y
);
1943 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
1946 HiText(strStr
, HIBYTE(LOWORD(Attr
)), TRUE
);
1950 /* ***************************************************************** */
1952 case DI_RADIOBUTTON
: {
1953 SetColorNormal(Attr
, CurItem
->TrueColors
);
1954 GotoXY(X1
+ CX1
, Y1
+ CY1
);
1956 if (CurItem
->Type
== DI_CHECKBOX
) {
1957 const wchar_t Check
[] = {L
'[',
1958 (CurItem
->Selected
? (((CurItem
->Flags
& DIF_3STATE
) && CurItem
->Selected
== 2)
1959 ? *Msg::CheckBox2State
1965 if (CurItem
->strData
.GetLength())
1968 wchar_t Dot
[] = {L
' ', CurItem
->Selected
? L
'\x2022' : L
' ', L
' ', L
'\0'};
1970 if (CurItem
->Flags
& DIF_MOVESELECT
) {
1977 if (CurItem
->strData
.GetLength())
1982 strStr
+= CurItem
->strData
;
1983 LenText
= LenStrItem(I
, strStr
);
1985 if (X1
+ CX1
+ LenText
> X2
)
1986 strStr
.TruncateByCells(ObjWidth
- 1);
1988 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
1991 HiText(strStr
, HIBYTE(LOWORD(Attr
)));
1993 if (CurItem
->Focus
) {
1994 // Отключение мигающего курсора при перемещении диалога
1995 if (!DialogMode
.Check(DMODE_DRAGGED
))
1996 SetCursorType(1, -1);
1998 MoveCursor(X1
+ CX1
+ 1, Y1
+ CY1
);
2003 /* ***************************************************************** */
2005 strStr
= CurItem
->strData
;
2006 SetColorNormal(Attr
, CurItem
->TrueColors
);
2007 GotoXY(X1
+ CX1
, Y1
+ CY1
);
2009 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
2012 HiText(strStr
, HIBYTE(LOWORD(Attr
)));
2014 if (CurItem
->Flags
& DIF_SETSHIELD
) {
2015 int startx
= X1
+ CX1
+ (CurItem
->Flags
& DIF_NOBRACKETS
? 0 : 2);
2016 ScrBuf
.ApplyColor(startx
, Y1
+ CY1
, startx
+ 1, Y1
+ CY1
, 0xE9);
2020 /* ***************************************************************** */
2026 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
2031 EditPtr
->SetObjectColor(Attr
& 0xFF, HIBYTE(LOWORD(Attr
)), LOBYTE(HIWORD(Attr
)));
2033 if (CurItem
->Focus
) {
2034 // Отключение мигающего курсора при перемещении диалога
2035 if (!DialogMode
.Check(DMODE_DRAGGED
))
2036 SetCursorType(1, -1);
2040 EditPtr
->FastShow();
2041 EditPtr
->SetLeftPos(0);
2044 // Отключение мигающего курсора при перемещении диалога
2045 if (DialogMode
.Check(DMODE_DRAGGED
))
2046 SetCursorType(0, 0);
2048 if (ItemHasDropDownArrow(CurItem
)) {
2049 int EditX1
, EditY1
, EditX2
, EditY2
;
2050 EditPtr
->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
2051 // Text((CurItem->Type == DI_COMBOBOX?"\x1F":"\x19"));
2052 Text(EditX2
+ 1, EditY1
, HIBYTE(HIWORD(Attr
)), L
"\x2193");
2055 if (CurItem
->Type
== DI_COMBOBOX
&& GetDropDownOpened() && CurItem
->ListPtr
->IsVisible()) // need redraw VMenu?
2057 CurItem
->ListPtr
->Hide();
2058 CurItem
->ListPtr
->Show();
2063 /* ***************************************************************** */
2065 if (CurItem
->ListPtr
) {
2066 // Перед отрисовкой спросим об изменении цветовых атрибутов
2067 BYTE RealColors
[VMENU_COLOR_COUNT
];
2068 FarListColors ListColors
= {0};
2069 ListColors
.ColorCount
= VMENU_COLOR_COUNT
;
2070 ListColors
.Colors
= RealColors
;
2071 CurItem
->ListPtr
->GetColors(&ListColors
);
2073 if (DlgProc((HANDLE
)this, DN_CTLCOLORDLGLIST
, I
, (LONG_PTR
)&ListColors
))
2074 CurItem
->ListPtr
->SetColors(&ListColors
);
2076 // Курсор запоминаем...
2077 bool CursorVisible
= false;
2078 DWORD CursorSize
= 0;
2079 GetCursorType(CursorVisible
, CursorSize
);
2080 CurItem
->ListPtr
->Show();
2082 // .. а теперь восстановим!
2084 SetCursorType(CursorVisible
, CursorSize
);
2089 /* 01.08.2000 SVS $ */
2090 /* ***************************************************************** */
2091 case DI_USERCONTROL
:
2093 if (CurItem
->VBuf
) {
2094 PutText(X1
+ CX1
, Y1
+ CY1
, X1
+ CX2
, Y1
+ CY2
, CurItem
->VBuf
);
2096 // не забудем переместить курсор, если он позиционирован.
2097 if (FocusPos
== I
) {
2098 if (CurItem
->UCData
->CursorPos
.X
!= -1 && CurItem
->UCData
->CursorPos
.Y
!= -1) {
2099 MoveCursor(CurItem
->UCData
->CursorPos
.X
+ CX1
+ X1
,
2100 CurItem
->UCData
->CursorPos
.Y
+ CY1
+ Y1
);
2101 SetCursorType(CurItem
->UCData
->CursorVisible
, CurItem
->UCData
->CursorSize
);
2103 SetCursorType(0, -1);
2107 break; // уже наприсовали :-)))
2108 /* ***************************************************************** */
2115 for (I
= 0; I
< ItemCount
; I
++) {
2118 if (CurItem
->ListPtr
&& GetDropDownOpened() && CurItem
->ListPtr
->IsVisible()) {
2119 if ((CurItem
->Type
== DI_COMBOBOX
)
2120 || ((CurItem
->Type
== DI_EDIT
|| CurItem
->Type
== DI_FIXEDIT
)
2121 && !(CurItem
->Flags
& DIF_HIDDEN
) && (CurItem
->Flags
& DIF_HISTORY
))) {
2122 CurItem
->ListPtr
->Show();
2127 // Включим индикатор перемещения...
2128 if (!DialogMode
.Check(DMODE_DRAGGED
)) // если диалог таскается
2132 + При каждой перерисовке диалога, кроме режима перемещения, устанавливаем
2133 заголовок консоли, в противном случае он не всегда восстанавливался.
2135 if (!DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
2136 ConsoleTitle::SetFarTitle(GetDialogTitle());
2139 DialogMode
.Clear(DMODE_DRAWING
); // конец отрисовки диалога!!!
2140 DialogMode
.Set(DMODE_SHOW
); // диалог на экране!
2142 if (DialogMode
.Check(DMODE_DRAGGED
)) {
2144 - BugZ#813 - DM_RESIZEDIALOG в DN_DRAWDIALOG -> проблема: Ctrl-F5 - отрисовка только полозьев.
2145 Убираем вызов плагиновго обработчика.
2147 // DlgProc((HANDLE)this,DN_DRAWDIALOGDONE,1,0);
2148 DefDlgProc((HANDLE
)this, DN_DRAWDIALOGDONE
, 1, 0);
2150 DlgProc((HANDLE
)this, DN_DRAWDIALOGDONE
, 0, 0);
2153 int Dialog::LenStrItem(int ID
, const wchar_t *lpwszStr
)
2155 CriticalSectionLock
Lock(CS
);
2158 lpwszStr
= Item
[ID
]->strData
;
2160 return (Item
[ID
]->Flags
& DIF_SHOWAMPERSAND
) ? StrZCellsCount(lpwszStr
) : HiStrCellsCount(lpwszStr
);
2163 int Dialog::ProcessMoveDialog(DWORD Key
)
2165 CriticalSectionLock
Lock(CS
);
2167 if (DialogMode
.Check(DMODE_DRAGGED
)) // если диалог таскается
2170 TODO: Здесь проверить "уже здесь" и не делать лишних движений
2171 Т.е., если нажали End, то при следующем End ненужно ничего делать! - сравнить координаты !!!
2175 // При перемещении диалога повторяем поведение "бормандовых" сред.
2178 case KEY_CTRLNUMPAD4
:
2180 case KEY_CTRLNUMPAD7
:
2183 rr
= Key
== KEY_CTRLLEFT
|| Key
== KEY_CTRLNUMPAD4
? 10 : X1
;
2188 for (int i
= 0; i
< rr
; i
++)
2192 AdjustEditPos(-1, 0);
2195 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2200 case KEY_CTRLNUMPAD6
:
2202 case KEY_CTRLNUMPAD1
:
2205 rr
= Key
== KEY_CTRLRIGHT
|| Key
== KEY_CTRLNUMPAD6
? 10 : Max(0, ScrX
- X2
);
2210 for (int i
= 0; i
< rr
; i
++)
2214 AdjustEditPos(1, 0);
2217 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2224 case KEY_CTRLNUMPAD9
:
2226 case KEY_CTRLNUMPAD8
:
2227 rr
= Key
== KEY_CTRLUP
|| Key
== KEY_CTRLNUMPAD8
? 5 : Y1
;
2232 for (int i
= 0; i
< rr
; i
++)
2236 AdjustEditPos(0, -1);
2239 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2244 case KEY_CTRLNUMPAD2
:
2246 case KEY_CTRLNUMPAD3
:
2249 rr
= Key
== KEY_CTRLDOWN
|| Key
== KEY_CTRLNUMPAD2
? 5 : Max(0, ScrY
- Y2
);
2254 for (int i
= 0; i
< rr
; i
++)
2258 AdjustEditPos(0, 1);
2261 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2268 DialogMode
.Clear(DMODE_DRAGGED
); // закончим движение!
2270 if (!DialogMode
.Check(DMODE_ALTDRAGGED
)) {
2271 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, 0);
2278 AdjustEditPos(OldX1
- X1
, OldY1
- Y1
);
2283 DialogMode
.Clear(DMODE_DRAGGED
);
2285 if (!DialogMode
.Check(DMODE_ALTDRAGGED
)) {
2286 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, TRUE
);
2293 if (DialogMode
.Check(DMODE_ALTDRAGGED
)) {
2294 DialogMode
.Clear(DMODE_DRAGGED
| DMODE_ALTDRAGGED
);
2295 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, 0);
2302 if (Key
== KEY_CTRLF5
&& DialogMode
.Check(DMODE_ISCANMOVE
)) {
2303 if (DlgProc((HANDLE
)this, DN_DRAGGED
, 0, 0)) // если разрешили перемещать!
2305 // включаем флаг и запоминаем координаты
2306 DialogMode
.Set(DMODE_DRAGGED
);
2311 // # GetText(0,0,3,0,LV);
2321 int64_t Dialog::VMProcess(MacroOpcode OpCode
, void *vParam
, int64_t iParam
)
2324 case MCODE_F_MENU_CHECKHOTKEY
:
2325 case MCODE_F_MENU_GETHOTKEY
:
2326 case MCODE_F_MENU_SELECT
:
2327 case MCODE_F_MENU_GETVALUE
:
2328 case MCODE_F_MENU_ITEMSTATUS
:
2329 case MCODE_V_MENU_VALUE
: {
2330 const wchar_t *str
= (const wchar_t *)vParam
;
2332 if (GetDropDownOpened() || Item
[FocusPos
]->Type
== DI_LISTBOX
) {
2333 if (Item
[FocusPos
]->ListPtr
)
2334 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2335 } else if (OpCode
== MCODE_F_MENU_CHECKHOTKEY
)
2336 return (int64_t)(CheckHighlights(*str
, (int)iParam
) + 1);
2345 case MCODE_C_SELECTED
:
2346 case MCODE_C_EMPTY
: {
2347 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2348 if (Item
[FocusPos
]->Type
== DI_COMBOBOX
&& GetDropDownOpened())
2349 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2351 return ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->VMProcess(OpCode
, vParam
, iParam
);
2352 } else if (Item
[FocusPos
]->Type
== DI_LISTBOX
&& OpCode
!= MCODE_C_SELECTED
)
2353 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2357 case MCODE_V_DLGITEMTYPE
: {
2358 switch (Item
[FocusPos
]->Type
) {
2360 return 7; // Кнопка (Push Button).
2362 return 8; // Контрольный переключатель (Check Box).
2364 return (DropDownOpened
? 0x800A : 10); // Комбинированный список.
2366 return 3; // Двойная рамка.
2368 return DropDownOpened
? 0x8004 : 4; // Поле ввода.
2370 return 6; // Поле ввода фиксированного размера.
2372 return 11; // Окно списка.
2374 return 5; // Поле ввода пароля.
2375 case DI_RADIOBUTTON
:
2376 return 9; // Селекторная кнопка (Radio Button).
2378 return 2; // Одиночная рамка.
2380 return 0; // Текстовая строка.
2381 case DI_USERCONTROL
:
2382 return 255; // Элемент управления, определяемый программистом.
2384 return 1; // Вертикальная текстовая строка.
2389 case MCODE_V_DLGITEMCOUNT
: // Dlg.ItemCount
2393 case MCODE_V_DLGCURPOS
: // Dlg.CurPos
2395 return FocusPos
+ 1;
2397 case MCODE_V_DLGINFOID
: // Dlg.Info.Id
2399 static FARString strId
;
2400 strId
.Format(L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", Id
.Data1
, Id
.Data2
, Id
.Data3
,
2401 Id
.Data4
[0], Id
.Data4
[1], Id
.Data4
[2], Id
.Data4
[3], Id
.Data4
[4], Id
.Data4
[5], Id
.Data4
[6],
2403 return reinterpret_cast<INT64
>(strId
.CPtr());
2405 case MCODE_V_ITEMCOUNT
:
2406 case MCODE_V_CURPOS
: {
2407 switch (Item
[FocusPos
]->Type
) {
2410 if (DropDownOpened
|| (Item
[FocusPos
]->Flags
& DIF_DROPDOWNLIST
))
2411 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2416 return ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->VMProcess(OpCode
, vParam
, iParam
);
2418 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2419 case DI_USERCONTROL
:
2421 if (OpCode
== MCODE_V_CURPOS
)
2422 return Item
[FocusPos
]->UCData
->CursorPos
.X
;
2426 case DI_RADIOBUTTON
:
2432 case MCODE_F_EDITOR_SEL
: {
2433 if (FarIsEdit(Item
[FocusPos
]->Type
)
2434 || (Item
[FocusPos
]->Type
== DI_COMBOBOX
2435 && !(DropDownOpened
|| (Item
[FocusPos
]->Flags
& DIF_DROPDOWNLIST
)))) {
2436 return ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->VMProcess(OpCode
, vParam
, iParam
);
2446 //////////////////////////////////////////////////////////////////////////
2449 Обработка данных от клавиатуры.
2450 Перекрывает BaseInput::ProcessKey.
2452 int Dialog::ProcessKey(FarKey Key
)
2454 CriticalSectionLock
Lock(CS
);
2455 _DIALOG(CleverSysLog
CL(L
"Dialog::ProcessKey"));
2456 _DIALOG(SysLog(L
"Param: Key=%ls", _FARKEY_ToName(Key
)));
2460 if (Key
== KEY_NONE
|| Key
== KEY_IDLE
) {
2461 DlgProc((HANDLE
)this, DN_ENTERIDLE
, 0, 0); // $ 28.07.2000 SVS Передадим этот факт в обработчик :-)
2465 if (Key
== KEY_KILLFOCUS
|| Key
== KEY_GOTFOCUS
) {
2466 DlgProc((HANDLE
)this, DN_ACTIVATEAPP
, Key
== KEY_KILLFOCUS
? FALSE
: TRUE
, 0);
2470 if (ProcessMoveDialog(Key
))
2473 // BugZ#488 - Shift=enter
2474 if (ShiftPressed
&& (Key
== KEY_ENTER
|| Key
== KEY_NUMENTER
) && !CtrlObject
->Macro
.IsExecuting()
2475 && Item
[FocusPos
]->Type
!= DI_BUTTON
) {
2476 Key
= Key
== KEY_ENTER
? KEY_SHIFTENTER
: KEY_SHIFTNUMENTER
;
2480 /*(Key>=KEY_MACRO_BASE && Key <=KEY_MACRO_ENDBASE) ||*/
2481 ((unsigned int)Key
>= KEY_OP_BASE
&& (unsigned int)Key
<= KEY_OP_ENDBASE
))
2482 && !DialogMode
.Check(DMODE_KEY
))
2483 if (DlgProc((HANDLE
)this, DN_KEY
, FocusPos
, Key
))
2486 if (!DialogMode
.Check(DMODE_SHOW
))
2489 // А ХЗ, может в этот момент изменилось состояние элемента!
2490 if (Item
[FocusPos
]->Flags
& DIF_HIDDEN
)
2493 // небольшая оптимизация
2494 if (Item
[FocusPos
]->Type
== DI_CHECKBOX
) {
2495 if (!(Item
[FocusPos
]->Flags
& DIF_3STATE
)) {
2496 if (Key
== KEY_MULTIPLY
) // в CheckBox 2-state Gray* не работает!
2499 if ((Key
== KEY_ADD
&& !Item
[FocusPos
]->Selected
)
2500 || (Key
== KEY_SUBTRACT
&& Item
[FocusPos
]->Selected
))
2504 // блок else не нужен, т.к. ниже клавиши будут обработаны...
2505 } else if (Key
== KEY_ADD
)
2507 else if (Key
== KEY_SUBTRACT
)
2509 else if (Key
== KEY_MULTIPLY
)
2512 if (Item
[FocusPos
]->Type
== DI_BUTTON
&& Key
== KEY_SPACE
)
2515 if (Item
[FocusPos
]->Type
== DI_LISTBOX
) {
2533 case KEY_MSWHEEL_UP
:
2534 case KEY_MSWHEEL_DOWN
:
2535 case KEY_MSWHEEL_LEFT
:
2536 case KEY_MSWHEEL_RIGHT
:
2539 VMenu
*List
= Item
[FocusPos
]->ListPtr
;
2540 int CurListPos
= List
->GetSelectPos();
2541 auto CheckedListItem
= List
->GetCheck(-1);
2542 List
->ProcessKey(Key
);
2543 int NewListPos
= List
->GetSelectPos();
2545 if (NewListPos
!= CurListPos
&& !DlgProc((HANDLE
)this, DN_LISTCHANGE
, FocusPos
, NewListPos
)) {
2546 if (!DialogMode
.Check(DMODE_SHOW
))
2549 List
->SetCheck(CheckedListItem
, CurListPos
);
2551 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[FocusPos
]->Flags
& DIF_HIDDEN
))
2552 ShowDialog(FocusPos
); // FocusPos
2555 if (!(Key
== KEY_ENTER
|| Key
== KEY_NUMENTER
) || (Item
[FocusPos
]->Flags
& DIF_LISTNOCLOSE
))
2564 Перед выводом диалога посылаем сообщение в обработчик
2565 и если вернули что надо, то выводим подсказку
2567 if (!Help::MkTopic(PluginNumber
,
2568 (const wchar_t *)DlgProc((HANDLE
)this, DN_HELP
, FocusPos
,
2569 (HelpTopic
? (LONG_PTR
)HelpTopic
: 0)),
2572 Help::Present(strStr
);
2579 ExitCode
= (Key
== KEY_BREAK
) ? -2 : -1;
2585 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2588 return Do_ProcessFirstCtrl();
2591 return Do_ProcessTab(Key
== KEY_TAB
);
2593 return Do_ProcessSpace();
2594 case KEY_CTRLNUMENTER
:
2595 case KEY_CTRLENTER
: {
2596 for (I
= 0; I
< ItemCount
; I
++)
2597 if (Item
[I
]->DefaultButton
) {
2598 if (Item
[I
]->Flags
& DIF_DISABLE
) {
2599 // ProcessKey(KEY_DOWN); // на твой вкус :-)
2603 if (!FarIsEdit(Item
[I
]->Type
))
2604 Item
[I
]->Selected
= 1;
2607 /* $ 18.05.2001 DJ */
2613 if (!DialogMode
.Check(DMODE_OLDSTYLE
)) {
2614 DialogMode
.Clear(DMODE_ENDLOOP
); // только если есть
2615 return TRUE
; // делать больше не чего
2620 if (Item
[FocusPos
]->Type
!= DI_COMBOBOX
&& FarIsEdit(Item
[FocusPos
]->Type
)
2621 && (Item
[FocusPos
]->Flags
& DIF_EDITOR
) && !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
2622 unsigned EditorLastPos
;
2624 for (EditorLastPos
= I
= FocusPos
; I
< ItemCount
; I
++)
2625 if (FarIsEdit(Item
[I
]->Type
) && (Item
[I
]->Flags
& DIF_EDITOR
))
2630 if (((DlgEdit
*)(Item
[EditorLastPos
]->ObjPtr
))->GetLength())
2633 for (I
= EditorLastPos
; I
> FocusPos
; I
--) {
2636 if (I
== FocusPos
+ 1)
2637 CurPos
= ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->GetCurPos();
2641 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->GetString(strStr
);
2642 int Length
= (int)strStr
.GetLength();
2643 ((DlgEdit
*)(Item
[I
]->ObjPtr
))
2644 ->SetString(CurPos
>= Length
? L
"" : strStr
.CPtr() + CurPos
);
2646 if (CurPos
< Length
)
2647 strStr
.Truncate(CurPos
);
2649 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetCurPos(0);
2650 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(strStr
);
2653 if (EditorLastPos
> FocusPos
) {
2654 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->SetCurPos(0);
2655 Do_ProcessNextCtrl(FALSE
, FALSE
);
2660 } else if (Item
[FocusPos
]->Type
== DI_BUTTON
) {
2661 Item
[FocusPos
]->Selected
= 1;
2663 // сообщение - "Кнокна кликнута"
2664 if (SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, FocusPos
, 0))
2667 if (Item
[FocusPos
]->Flags
& DIF_BTNNOCLOSE
)
2670 ExitCode
= FocusPos
;
2676 for (I
= 0; I
< ItemCount
; I
++) {
2677 if (Item
[I
]->DefaultButton
&& !(Item
[I
]->Flags
& DIF_BTNNOCLOSE
)) {
2678 if (Item
[I
]->Flags
& DIF_DISABLE
) {
2679 // ProcessKey(KEY_DOWN); // на твой вкус :-)
2683 // if (!(FarIsEdit(Item[I].Type) || Item[I].Type == DI_CHECKBOX || Item[I].Type == DI_RADIOBUTTON))
2684 // Item[I].Selected=1;
2692 ExitCode
= FocusPos
;
2698 3-х уровневое состояние
2699 Для чекбокса сюда попадем только в случае, если контрол
2700 имеет флаг DIF_3STATE
2706 if (Item
[FocusPos
]->Type
== DI_CHECKBOX
) {
2707 unsigned int CHKState
= (Key
== KEY_ADD
2709 : (Key
== KEY_SUBTRACT
2711 : ((Key
== KEY_MULTIPLY
) ? 2 : Item
[FocusPos
]->Selected
)));
2713 if (Item
[FocusPos
]->Selected
!= (int)CHKState
)
2714 if (SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, FocusPos
, CHKState
)) {
2715 Item
[FocusPos
]->Selected
= CHKState
;
2723 case KEY_SHIFTNUMPAD4
:
2724 case KEY_MSWHEEL_LEFT
:
2727 case KEY_SHIFTNUMPAD6
:
2728 case KEY_MSWHEEL_RIGHT
: {
2729 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2732 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2733 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(Key
);
2736 return MoveToCtrlHorizontal(Key
== KEY_RIGHT
|| Key
== KEY_NUMPAD6
);
2743 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2746 return MoveToCtrlVertical(Key
== KEY_UP
|| Key
== KEY_NUMPAD8
);
2748 // $ 27.04.2001 VVM - Обработка колеса мышки
2749 case KEY_MSWHEEL_UP
:
2750 case KEY_MSWHEEL_DOWN
:
2752 case KEY_CTRLNUMPAD8
:
2754 case KEY_CTRLNUMPAD2
:
2755 return ProcessOpenComboBox(Item
[FocusPos
]->Type
, Item
[FocusPos
], FocusPos
);
2756 // ЭТО перед default предпоследний!!!
2760 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2763 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2764 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(Key
);
2769 // ЭТО перед default последний!!!
2773 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2776 if (!(Item
[FocusPos
]->Flags
& DIF_EDITOR
)) {
2777 for (I
= 0; I
< ItemCount
; I
++)
2778 if (Item
[I
]->DefaultButton
) {
2789 if (!CheckDialogMode(DMODE_NOPLUGINS
)) {
2790 return FrameManager
->ProcessKey(Key
);
2794 // для DIF_EDITOR будет обработано ниже
2796 // if(Item[FocusPos].Type == DI_USERCONTROL) // для user-типа вываливаем
2798 if (Item
[FocusPos
]->Type
== DI_LISTBOX
) {
2799 VMenu
*List
= Item
[FocusPos
]->ListPtr
;
2800 int CurListPos
= List
->GetSelectPos();
2801 auto CheckedListItem
= List
->GetCheck(-1);
2802 List
->ProcessKey(Key
);
2803 int NewListPos
= List
->GetSelectPos();
2805 if (NewListPos
!= CurListPos
&& !DlgProc((HANDLE
)this, DN_LISTCHANGE
, FocusPos
, NewListPos
)) {
2806 if (!DialogMode
.Check(DMODE_SHOW
))
2809 List
->SetCheck(CheckedListItem
, CurListPos
);
2811 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[FocusPos
]->Flags
& DIF_HIDDEN
))
2812 ShowDialog(FocusPos
); // FocusPos
2818 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2819 DlgEdit
*edt
= (DlgEdit
*)Item
[FocusPos
]->ObjPtr
;
2821 if (Key
== KEY_CTRLL
) // исключим смену режима RO для поля ввода с клавиатуры
2824 } else if (Key
== KEY_CTRLU
) {
2825 edt
->SetClearFlag(0);
2829 } else if ((Item
[FocusPos
]->Flags
& DIF_EDITOR
) && !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
2832 int CurPos
= edt
->GetCurPos();
2834 // В начале строки????
2835 if (!edt
->GetCurPos()) {
2836 // а "выше" тоже DIF_EDITOR?
2837 if (FocusPos
> 0 && (Item
[FocusPos
- 1]->Flags
& DIF_EDITOR
)) {
2838 // добавляем к предыдущему и...
2839 DlgEdit
*edt_1
= (DlgEdit
*)Item
[FocusPos
- 1]->ObjPtr
;
2840 edt_1
->GetString(strStr
);
2841 CurPos
= static_cast<int>(strStr
.GetLength());
2843 edt
->GetString(strAdd
);
2845 edt_1
->SetString(strStr
);
2847 for (I
= FocusPos
+ 1; I
< ItemCount
; I
++) {
2848 if (Item
[I
]->Flags
& DIF_EDITOR
) {
2850 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->GetString(strStr
);
2851 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(strStr
);
2854 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetString(L
"");
2855 } else // ага, значит FocusPos это есть последний из DIF_EDITOR
2857 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(L
"");
2862 Do_ProcessNextCtrl(TRUE
);
2863 edt_1
->SetCurPos(CurPos
);
2866 edt
->ProcessKey(Key
);
2873 for (I
= FocusPos
; I
< ItemCount
; I
++)
2874 if (Item
[I
]->Flags
& DIF_EDITOR
) {
2876 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->GetString(strStr
);
2877 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(strStr
);
2880 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetString(L
"");
2891 ! "...В редакторе команд меню нажмите home shift+end del
2892 блок не удаляется..."
2893 DEL у итемов, имеющих DIF_EDITOR, работал без учета
2896 if (FocusPos
< ItemCount
+ 1 && (Item
[FocusPos
+ 1]->Flags
& DIF_EDITOR
)) {
2897 int CurPos
= edt
->GetCurPos();
2898 int Length
= edt
->GetLength();
2899 int SelStart
, SelEnd
;
2900 edt
->GetSelection(SelStart
, SelEnd
);
2901 edt
->GetString(strStr
);
2903 if (SelStart
> -1) {
2904 FARString strEnd
= strStr
.CPtr() + SelEnd
;
2905 strStr
.Truncate(SelStart
);
2907 edt
->SetString(strStr
);
2908 edt
->SetCurPos(SelStart
);
2911 } else if (CurPos
>= Length
) {
2912 DlgEdit
*edt_1
= (DlgEdit
*)Item
[FocusPos
+ 1]->ObjPtr
;
2916 Решаем проблему, если Del нажали в позиции
2917 большей, чем длина строки
2919 if (CurPos
> Length
) {
2920 strStr
.Append(L
' ', CurPos
- Length
);
2924 edt_1
->GetString(strAdd
);
2925 edt_1
->SetString(strStr
+ strAdd
);
2926 ProcessKey(KEY_CTRLY
);
2927 edt
->SetCurPos(CurPos
);
2941 while (Item
[I
]->Flags
& DIF_EDITOR
)
2942 I
= ChangeFocus(I
, (Key
== KEY_PGUP
|| Key
== KEY_NUMPAD9
) ? -1 : 1, FALSE
);
2944 if (!(Item
[I
]->Flags
& DIF_EDITOR
))
2945 I
= ChangeFocus(I
, (Key
== KEY_PGUP
|| Key
== KEY_NUMPAD9
) ? 1 : -1, FALSE
);
2955 if (Key
== KEY_OP_XLAT
&& !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
2956 edt
->SetClearFlag(0);
2959 // иначе неправильно работает ctrl-end
2960 edt
->strLastStr
= edt
->GetStringAddr();
2961 edt
->LastPartLength
= static_cast<int>(edt
->strLastStr
.GetLength());
2963 Redraw(); // Перерисовка должна идти после DN_EDITCHANGE (imho)
2967 if (!(Item
[FocusPos
]->Flags
& DIF_READONLY
) || IsNavKey(Key
)) {
2968 // "только что ломанулись и начинать выделение с нуля"?
2969 if ((Opt
.Dialogs
.EditLine
& DLGEDITLINE_NEWSELONGOTFOCUS
) && Item
[FocusPos
]->SelStart
!= -1
2970 && PrevFocusPos
!= FocusPos
) { // && Item[FocusPos].SelEnd)
2972 edt
->Flags().Clear(FEDITLINE_MARKINGBLOCK
);
2973 PrevFocusPos
= FocusPos
;
2976 if (edt
->ProcessKey(Key
)) {
2977 if (Item
[FocusPos
]->Flags
& DIF_READONLY
)
2980 if ((Key
== KEY_CTRLEND
|| Key
== KEY_CTRLNUMPAD1
)
2981 && edt
->GetCurPos() == edt
->GetLength()) {
2982 if (edt
->LastPartLength
== -1)
2983 edt
->strLastStr
= edt
->GetStringAddr();
2985 strStr
= edt
->strLastStr
;
2986 int CurCmdPartLength
= static_cast<int>(strStr
.GetLength());
2987 edt
->HistoryGetSimilar(strStr
, edt
->LastPartLength
);
2989 if (edt
->LastPartLength
== -1) {
2990 edt
->strLastStr
= edt
->GetStringAddr();
2991 edt
->LastPartLength
= CurCmdPartLength
;
2994 edt
->SetString(strStr
);
2995 edt
->Select(edt
->LastPartLength
, static_cast<int>(strStr
.GetLength()));
3001 edt
->LastPartLength
= -1;
3003 if (Key
== KEY_CTRLSHIFTEND
|| Key
== KEY_CTRLSHIFTNUMPAD1
) {
3005 edt
->AutoComplete(true, false);
3009 Redraw(); // Перерисовка должна идти после DN_EDITCHANGE (imho)
3012 } else if (!(Key
& (KEY_ALT
| KEY_RALT
)))
3016 if (ProcessHighlighting(Key
, FocusPos
, FALSE
))
3019 return (Opt
.XLat
.EnableForDialogs
&& ProcessHighlighting(Key
, FocusPos
, TRUE
));
3025 void Dialog::ProcessKey(FarKey Key
, unsigned ItemPos
)
3027 unsigned SavedFocusPos
= FocusPos
;
3030 if (FocusPos
== ItemPos
)
3031 FocusPos
= SavedFocusPos
;
3034 //////////////////////////////////////////////////////////////////////////
3037 Обработка данных от "мыши".
3038 Перекрывает BaseInput::ProcessMouse.
3044 int Dialog::ProcessMouse(MOUSE_EVENT_RECORD
*MouseEvent
)
3046 CriticalSectionLock
Lock(CS
);
3052 if (!DialogMode
.Check(DMODE_SHOW
))
3055 if (DialogMode
.Check(DMODE_MOUSEEVENT
)) {
3056 if (!DlgProc((HANDLE
)this, DN_MOUSEEVENT
, 0, (LONG_PTR
)MouseEvent
))
3060 if (!DialogMode
.Check(DMODE_SHOW
))
3063 MsX
= MouseEvent
->dwMousePosition
.X
;
3064 MsY
= MouseEvent
->dwMousePosition
.Y
;
3066 // for (I=0;I<ItemCount;I++)
3067 for (I
= ItemCount
- 1; I
!= (unsigned)-1; I
--) {
3068 if (Item
[I
]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))
3071 Type
= Item
[I
]->Type
;
3073 if (Type
== DI_LISTBOX
&& MsY
>= Y1
+ Item
[I
]->Y1
&& MsY
<= Y1
+ Item
[I
]->Y2
3074 && MsX
>= X1
+ Item
[I
]->X1
&& MsX
<= X1
+ Item
[I
]->X2
) {
3075 VMenu
*List
= Item
[I
]->ListPtr
;
3076 int Pos
= List
->GetSelectPos();
3077 auto CheckedListItem
= List
->GetCheck(-1);
3079 if ((MouseEvent
->dwButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)) {
3080 if (FocusPos
!= I
) {
3085 if (MouseEvent
->dwEventFlags
!= DOUBLE_CLICK
3086 && !(Item
[I
]->IFlags
.Flags
3087 & (DLGIIF_LISTREACTIONFOCUS
| DLGIIF_LISTREACTIONNOFOCUS
))) {
3089 List
->ProcessMouse(MouseEvent
);
3090 int NewListPos
= List
->GetSelectPos();
3092 if (NewListPos
!= Pos
3093 && !SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)NewListPos
)) {
3094 List
->SetCheck(CheckedListItem
, Pos
);
3096 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[I
]->Flags
& DIF_HIDDEN
))
3097 ShowDialog(I
); // FocusPos
3101 } else if (!SendDlgMessage((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
)) {
3103 List
->ProcessMouse(MouseEvent
);
3104 int NewListPos
= List
->GetSelectPos();
3106 (MsX
== X1
+ Item
[I
]->X2
&& MsY
>= Y1
+ Item
[I
]->Y1
&& MsY
<= Y1
+ Item
[I
]->Y2
)
3107 && (List
->CheckFlags(VMENU_LISTBOX
| VMENU_ALWAYSSCROLLBAR
)
3108 || Opt
.ShowMenuScrollbar
);
3110 if (!InScroolBar
&& // вне скроллбара и
3111 NewListPos
!= Pos
&& // позиция изменилась и
3112 !SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)NewListPos
)) // и плагин сказал в морг
3114 List
->SetCheck(CheckedListItem
, Pos
);
3116 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[I
]->Flags
& DIF_HIDDEN
))
3117 ShowDialog(I
); // FocusPos
3121 if (!InScroolBar
&& !(Item
[I
]->Flags
& DIF_LISTNOCLOSE
)) {
3130 if (SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)Pos
)) {
3131 if (MsX
== X1
+ Item
[I
]->X2
&& MsY
>= Y1
+ Item
[I
]->Y1
&& MsY
<= Y1
+ Item
[I
]->Y2
)
3132 List
->ProcessMouse(MouseEvent
); // забыл проверить на клик на скролбар (KM)
3134 ProcessKey(KEY_ENTER
, I
);
3142 if (!MouseEvent
->dwButtonState
3143 || SendDlgMessage((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
)) {
3144 if ((I
== FocusPos
&& (Item
[I
]->IFlags
.Flags
& DLGIIF_LISTREACTIONFOCUS
))
3145 || (I
!= FocusPos
&& (Item
[I
]->IFlags
.Flags
& DLGIIF_LISTREACTIONNOFOCUS
))) {
3146 List
->ProcessMouse(MouseEvent
);
3147 int NewListPos
= List
->GetSelectPos();
3149 if (NewListPos
!= Pos
3150 && !SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)NewListPos
)) {
3151 List
->SetCheck(CheckedListItem
, Pos
);
3153 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[I
]->Flags
& DIF_HIDDEN
))
3154 ShowDialog(I
); // FocusPos
3165 if (MsX
< X1
|| MsY
< Y1
|| MsX
> X2
|| MsY
> Y2
) {
3166 if (DialogMode
.Check(DMODE_CLICKOUTSIDE
)
3167 && !DlgProc((HANDLE
)this, DN_MOUSECLICK
, -1, (LONG_PTR
)MouseEvent
)) {
3168 if (!DialogMode
.Check(DMODE_SHOW
))
3171 // if (!(MouseEvent->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) && PrevLButtonPressed && ScreenObject::CaptureMouseObject)
3172 if (!(MouseEvent
->dwButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)
3173 && (PrevMouseButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)
3174 && (Opt
.Dialogs
.MouseButton
& DMOUSEBUTTON_LEFT
))
3175 ProcessKey(KEY_ESC
);
3176 // else if (!(MouseEvent->dwButtonState & RIGHTMOST_BUTTON_PRESSED) && PrevRButtonPressed && ScreenObject::CaptureMouseObject)
3177 else if (!(MouseEvent
->dwButtonState
& RIGHTMOST_BUTTON_PRESSED
)
3178 && (PrevMouseButtonState
& RIGHTMOST_BUTTON_PRESSED
)
3179 && (Opt
.Dialogs
.MouseButton
& DMOUSEBUTTON_RIGHT
))
3180 ProcessKey(KEY_ENTER
);
3183 if (MouseEvent
->dwButtonState
)
3184 DialogMode
.Set(DMODE_CLICKOUTSIDE
);
3186 // ScreenObject::SetCapture(this);
3190 if (!MouseEvent
->dwButtonState
) {
3191 DialogMode
.Clear(DMODE_CLICKOUTSIDE
);
3192 // ScreenObject::SetCapture(nullptr);
3196 if (!MouseEvent
->dwEventFlags
|| MouseEvent
->dwEventFlags
== DOUBLE_CLICK
) {
3197 // первый цикл - все за исключением рамок.
3198 // for (I=0; I < ItemCount;I++)
3199 for (I
= ItemCount
- 1; I
!= (unsigned)-1; I
--) {
3200 if (Item
[I
]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))
3203 GetItemRect(I
, Rect
);
3208 //_D(SysLog(L"? %2d) Rect (%2d,%2d) (%2d,%2d) '%ls'",I,Rect.left,Rect.top,Rect.right,Rect.bottom,Item[I].Data));
3210 if (MsX
>= Rect
.Left
&& MsY
>= Rect
.Top
&& MsX
<= Rect
.Right
&& MsY
<= Rect
.Bottom
) {
3211 // для прозрачных :-)
3212 if (Item
[I
]->Type
== DI_SINGLEBOX
|| Item
[I
]->Type
== DI_DOUBLEBOX
) {
3213 // если на рамке, то...
3214 if (((MsX
== Rect
.Left
|| MsX
== Rect
.Right
) && MsY
>= Rect
.Top
&& MsY
<= Rect
.Bottom
)
3216 ((MsY
== Rect
.Top
|| MsY
== Rect
.Bottom
) && MsX
>= Rect
.Left
3217 && MsX
<= Rect
.Right
)) // hor
3219 if (DlgProc((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
))
3222 if (!DialogMode
.Check(DMODE_SHOW
))
3228 if (Item
[I
]->Type
== DI_USERCONTROL
) {
3229 // для user-типа подготовим координаты мыши
3230 MouseEvent
->dwMousePosition
.X
-= Rect
.Left
;
3231 MouseEvent
->dwMousePosition
.Y
-= Rect
.Top
;
3234 //_SVS(SysLog(L"+ %2d) Rect (%2d,%2d) (%2d,%2d) '%ls' Dbl=%d",I,Rect.left,Rect.top,Rect.right,Rect.bottom,Item[I].Data,MouseEvent->dwEventFlags==DOUBLE_CLICK));
3235 if (DlgProc((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
))
3238 if (!DialogMode
.Check(DMODE_SHOW
))
3241 if (Item
[I
]->Type
== DI_USERCONTROL
) {
3251 if ((MouseEvent
->dwButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)) {
3252 // for (I=0;I<ItemCount;I++)
3254 for (I
= ItemCount
- 1; I
!= (unsigned)-1; I
--) {
3255 // Исключаем из списка оповещаемых о мыши недоступные элементы
3256 if (Item
[I
]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))
3259 Type
= Item
[I
]->Type
;
3261 GetItemRect(I
, Rect
);
3266 if (ItemHasDropDownArrow(Item
[I
]))
3269 if (MsX
>= Rect
.Left
&& MsY
>= Rect
.Top
&& MsX
<= Rect
.Right
&& MsY
<= Rect
.Bottom
) {
3270 /* ********************************************************** */
3271 if (FarIsEdit(Type
)) {
3274 + Сделаем так, чтобы ткнув мышкой в DropDownList
3275 список раскрывался сам.
3276 Есть некоторая глюкавость - когда список раскрыт и мы
3277 мышой переваливаем на другой элемент, то список закрывается
3278 но перехода реального на указанный элемент диалога не происходит
3280 int EditX1
, EditY1
, EditX2
, EditY2
;
3281 DlgEdit
*EditLine
= (DlgEdit
*)(Item
[I
]->ObjPtr
);
3282 EditLine
->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
3284 if (MsY
== EditY1
&& Type
== DI_COMBOBOX
&& (Item
[I
]->Flags
& DIF_DROPDOWNLIST
)
3285 && MsX
>= EditX1
&& MsX
<= EditX2
+ 1) {
3286 EditLine
->SetClearFlag(0);
3291 ProcessOpenComboBox(Item
[I
]->Type
, Item
[I
], I
);
3298 if (EditLine
->ProcessMouse(MouseEvent
)) {
3299 EditLine
->SetClearFlag(0); // а может это делать в самом edit?
3303 ! Оказалось нужно перерисовывать весь диалог иначе
3304 не снимался признак активности с комбобокса с которго уходим.
3306 ShowDialog(); // нужен ли только один контрол или весь диалог?
3309 // Проверка на DI_COMBOBOX здесь лишняя. Убрана (KM).
3310 if (MsX
== EditX2
+ 1 && MsY
== EditY1
&& ItemHasDropDownArrow(Item
[I
])) {
3311 EditLine
->SetClearFlag(0); // раз уж покусились на, то и...
3315 if (!(Item
[I
]->Flags
& DIF_HIDDEN
))
3318 ProcessOpenComboBox(Item
[I
]->Type
, Item
[I
], I
);
3325 /* ********************************************************** */
3326 if (Type
== DI_BUTTON
&& MsY
== Y1
+ Item
[I
]->Y1
3327 && MsX
< X1
+ Item
[I
]->X1
+ HiStrCellsCount(Item
[I
]->strData
)) {
3331 while (IsMouseButtonPressed())
3334 if (MouseX
< X1
|| MouseX
> X1
+ Item
[I
]->X1
+ HiStrCellsCount(Item
[I
]->strData
) + 4
3335 || MouseY
!= Y1
+ Item
[I
]->Y1
) {
3342 ProcessKey(KEY_ENTER
, I
);
3346 /* ********************************************************** */
3347 if ((Type
== DI_CHECKBOX
|| Type
== DI_RADIOBUTTON
) && MsY
== Y1
+ Item
[I
]->Y1
3348 && MsX
< (X1
+ Item
[I
]->X1
+ HiStrCellsCount(Item
[I
]->strData
) + 4
3349 - ((Item
[I
]->Flags
& DIF_MOVESELECT
) != 0))) {
3351 ProcessKey(KEY_SPACE
, I
);
3355 } // for (I=0;I<ItemCount;I++)
3357 // ДЛЯ MOUSE-Перемещалки:
3358 // Сюда попадаем в том случае, если мышь не попала на активные элементы
3361 if (DialogMode
.Check(DMODE_ISCANMOVE
)) {
3362 // DialogMode.Set(DMODE_DRAGGED);
3367 // запомним delta места хватания и Left-Top диалогового окна
3368 MsX
= abs(X1
- MouseX
);
3369 MsY
= abs(Y1
- MouseY
);
3370 int NeedSendMsg
= 0;
3373 DWORD Mb
= IsMouseButtonPressed();
3376 if (Mb
== FROM_LEFT_1ST_BUTTON_PRESSED
) // still dragging
3378 int AdjX
= 0, AdjY
= 0;
3386 if (MouseX
== PrevMouseX
)
3391 if (MouseY
== PrevMouseY
)
3396 NX2
= mx
+ (X2
- X1
);
3399 NY2
= my
+ (Y2
- Y1
);
3403 // "А был ли мальчик?" (про холостой ход)
3404 if (OX1
!= NX1
|| OY1
!= NY1
) {
3405 if (!NeedSendMsg
) // тыкс, а уже посылку делали в диалоговую процедуру?
3409 if (!DlgProc((HANDLE
)this, DN_DRAGGED
, 0, 0)) // а может нас обломали?
3410 break; // валим отсель...плагин сказал - в морг перемещения
3412 if (!DialogMode
.Check(DMODE_SHOW
))
3416 // Да, мальчик был. Зачнем...
3426 AdjustEditPos(AdjX
, AdjY
); //?
3431 } else if (Mb
== RIGHTMOST_BUTTON_PRESSED
) // abort
3435 AdjustEditPos(OldX1
- X1
, OldY1
- Y1
);
3440 DialogMode
.Clear(DMODE_DRAGGED
);
3441 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, TRUE
);
3443 if (DialogMode
.Check(DMODE_SHOW
))
3447 } else // release key, drop dialog
3449 if (OldX1
!= X1
|| OldX2
!= X2
|| OldY1
!= Y1
|| OldY2
!= Y2
) {
3451 DialogMode
.Clear(DMODE_DRAGGED
);
3452 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, 0);
3454 if (DialogMode
.Check(DMODE_SHOW
))
3468 int Dialog::ProcessOpenComboBox(int Type
, DialogItemEx
*CurItem
, unsigned CurFocusPos
)
3470 CriticalSectionLock
Lock(CS
);
3472 DlgEdit
*CurEditLine
;
3474 // для user-типа вываливаем
3475 if (Type
== DI_USERCONTROL
)
3478 CurEditLine
= ((DlgEdit
*)(CurItem
->ObjPtr
));
3480 if (FarIsEdit(Type
) && (CurItem
->Flags
& DIF_HISTORY
) && Opt
.Dialogs
.EditHistory
3481 && !CurItem
->strHistory
.IsEmpty() && !(CurItem
->Flags
& DIF_READONLY
)) {
3482 // Передаем то, что в строке ввода в функцию выбора из истории для выделения нужного пункта в истории.
3483 CurEditLine
->GetString(strStr
);
3484 SelectFromEditHistory(CurItem
, CurEditLine
, CurItem
->strHistory
, strStr
);
3486 // $ 18.07.2000 SVS: +обработка DI_COMBOBOX - выбор из списка!
3487 else if (Type
== DI_COMBOBOX
&& CurItem
->ListPtr
&& !(CurItem
->Flags
& DIF_READONLY
)
3488 && CurItem
->ListPtr
->GetItemCount() > 0) //??
3490 SelectFromComboBox(CurItem
, CurEditLine
, CurItem
->ListPtr
);
3496 unsigned Dialog::ProcessRadioButton(unsigned CurRB
)
3498 CriticalSectionLock
Lock(CS
);
3499 unsigned PrevRB
= CurRB
, J
;
3502 for (I
= CurRB
;; I
--) {
3506 if (Item
[I
]->Type
== DI_RADIOBUTTON
&& (Item
[I
]->Flags
& DIF_GROUP
))
3509 if (Item
[I
- 1]->Type
!= DI_RADIOBUTTON
)
3516 При изменении состояния каждого элемента посылаем сообщение
3517 посредством функции SendDlgMessage - в ней делается все!
3519 J
= Item
[I
]->Selected
;
3520 Item
[I
]->Selected
= 0;
3527 } while (I
< ItemCount
&& Item
[I
]->Type
== DI_RADIOBUTTON
&& !(Item
[I
]->Flags
& DIF_GROUP
));
3529 Item
[CurRB
]->Selected
= 1;
3533 При изменении состояния каждого элемента посылаем сообщение
3534 посредством функции SendDlgMessage - в ней делается все!
3536 if (!SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, PrevRB
, 0)
3537 || !SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, CurRB
, 1)) {
3538 // вернем назад, если пользователь не захотел...
3539 Item
[CurRB
]->Selected
= 0;
3540 Item
[PrevRB
]->Selected
= 1;
3547 int Dialog::Do_ProcessFirstCtrl()
3549 CriticalSectionLock
Lock(CS
);
3551 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
3552 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(KEY_HOME
);
3555 for (unsigned I
= 0; I
< ItemCount
; I
++)
3556 if (CanGetFocus(Item
[I
]->Type
)) {
3566 int Dialog::Do_ProcessNextCtrl(int Up
, BOOL IsRedraw
)
3568 CriticalSectionLock
Lock(CS
);
3569 unsigned OldPos
= FocusPos
;
3570 unsigned PrevPos
= 0;
3572 if (FarIsEdit(Item
[FocusPos
]->Type
) && (Item
[FocusPos
]->Flags
& DIF_EDITOR
))
3573 PrevPos
= ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->GetCurPos();
3575 unsigned I
= ChangeFocus(FocusPos
, Up
? -1 : 1, FALSE
);
3576 Item
[FocusPos
]->Focus
= 0;
3580 if (FarIsEdit(Item
[I
]->Type
) && (Item
[I
]->Flags
& DIF_EDITOR
))
3581 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetCurPos(PrevPos
);
3583 if (Item
[FocusPos
]->Type
== DI_RADIOBUTTON
&& (Item
[I
]->Flags
& DIF_MOVESELECT
))
3584 ProcessKey(KEY_SPACE
);
3585 else if (IsRedraw
) {
3587 ShowDialog(FocusPos
);
3593 int Dialog::MoveToCtrlHorizontal(int right
)
3595 int MinDist
= 1000, MinPos
= 0;
3597 for (unsigned int I
= 0; I
< ItemCount
; I
++) {
3598 if (I
!= FocusPos
&& (!(Item
[I
]->Flags
& (DIF_NOFOCUS
| DIF_DISABLE
| DIF_HIDDEN
)))
3599 && (FarIsEdit(Item
[I
]->Type
) || Item
[I
]->Type
== DI_CHECKBOX
3600 || Item
[I
]->Type
== DI_RADIOBUTTON
)
3601 && Item
[I
]->Y1
== Item
[FocusPos
]->Y1
)
3603 int Dist
= Item
[I
]->X1
- Item
[FocusPos
]->X1
;
3605 if ((!right
&& Dist
< 0) || (right
&& Dist
> 0)) {
3606 if (abs(Dist
) < MinDist
) {
3607 MinDist
= abs(Dist
);
3614 if (MinDist
< 1000) {
3615 ChangeFocus2(MinPos
);
3617 if (Item
[MinPos
]->Flags
& DIF_MOVESELECT
) {
3623 return Do_ProcessNextCtrl(!right
);
3630 int Dialog::MoveToCtrlVertical(int up
)
3632 int MinDist
= 1000, MinPos
= 0;
3634 for (unsigned int I
= 0; I
< ItemCount
; I
++) {
3635 if (I
!= FocusPos
&& (!(Item
[I
]->Flags
& (DIF_NOFOCUS
| DIF_DISABLE
| DIF_HIDDEN
)))
3636 && (FarIsEdit(Item
[I
]->Type
) || Item
[I
]->Type
== DI_CHECKBOX
3637 || Item
[I
]->Type
== DI_RADIOBUTTON
)
3638 && Item
[I
]->X1
== Item
[FocusPos
]->X1
)
3640 int Dist
= Item
[I
]->Y1
- Item
[FocusPos
]->Y1
;
3642 if ((up
&& Dist
< 0) || (!up
&& Dist
> 0)) {
3643 if (abs(Dist
) < MinDist
) {
3644 MinDist
= abs(Dist
);
3651 if (MinDist
< 1000) {
3652 ChangeFocus2(MinPos
);
3654 if (Item
[MinPos
]->Flags
& DIF_MOVESELECT
) {
3660 return Do_ProcessNextCtrl(up
);
3666 int Dialog::Do_ProcessTab(int Next
)
3668 CriticalSectionLock
Lock(CS
);
3671 if (ItemCount
> 1) {
3672 // Must check for DI_EDIT since DIF_EDITOR and DIF_LISTNOAMPERSAND are equal
3673 if (Item
[FocusPos
]->Type
==DI_EDIT
&& (Item
[FocusPos
]->Flags
& DIF_EDITOR
)) {
3676 while (Item
[I
]->Type
==DI_EDIT
&& (Item
[I
]->Flags
& DIF_EDITOR
))
3677 I
= ChangeFocus(I
, Next
? 1 : -1, TRUE
);
3679 I
= ChangeFocus(FocusPos
, Next
? 1 : -1, TRUE
);
3683 && Item
[I
]->Type
== DI_EDIT
&& Item
[I
- 1]->Type
== DI_EDIT
3684 && (Item
[I
]->Flags
& DIF_EDITOR
) && (Item
[I
- 1]->Flags
& DIF_EDITOR
)
3685 && !((DlgEdit
*)Item
[I
]->ObjPtr
)->GetLength())
3697 int Dialog::Do_ProcessSpace()
3699 CriticalSectionLock
Lock(CS
);
3702 if (Item
[FocusPos
]->Type
== DI_CHECKBOX
) {
3703 int OldSelected
= Item
[FocusPos
]->Selected
;
3705 if (Item
[FocusPos
]->Flags
& DIF_3STATE
) {
3706 Item
[FocusPos
]->Selected
= (Item
[FocusPos
]->Selected
+ 1) % 3;
3708 Item
[FocusPos
]->Selected
= !Item
[FocusPos
]->Selected
;
3710 OldFocusPos
= FocusPos
;
3712 if (!SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, FocusPos
, Item
[FocusPos
]->Selected
))
3713 Item
[OldFocusPos
]->Selected
= OldSelected
;
3717 } else if (Item
[FocusPos
]->Type
== DI_RADIOBUTTON
) {
3718 FocusPos
= ProcessRadioButton(FocusPos
);
3721 } else if (FarIsEdit(Item
[FocusPos
]->Type
) && !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
3722 if (((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(KEY_SPACE
)) {
3723 Redraw(); // Перерисовка должна идти после DN_EDITCHANGE (imho)
3732 //////////////////////////////////////////////////////////////////////////
3735 Изменяет фокус ввода (воздействие клавишами
3736 KEY_TAB, KEY_SHIFTTAB, KEY_UP, KEY_DOWN,
3737 а так же Alt-HotKey)
3741 Довесок для сообщений DN_KILLFOCUS & DN_SETFOCUS
3745 Добавка для DI_USERCONTROL
3747 unsigned Dialog::ChangeFocus(unsigned CurFocusPos
, int Step
, int SkipGroup
)
3749 CriticalSectionLock
Lock(CS
);
3751 unsigned OrigFocusPos
= CurFocusPos
;
3752 // int FucusPosNeed=-1;
3753 // В функцию обработки диалога здесь передаем сообщение,
3754 // что элемент - LostFocus() - теряет фокус ввода.
3755 // if(DialogMode.Check(DMODE_INITOBJECTS))
3756 // FucusPosNeed=DlgProc((HANDLE)this,DN_KILLFOCUS,FocusPos,0);
3757 // if(FucusPosNeed != -1 && CanGetFocus(Item[FucusPosNeed].Type))
3758 // FocusPos=FucusPosNeed;
3764 if ((int)CurFocusPos
< 0)
3765 CurFocusPos
= ItemCount
- 1;
3767 if (CurFocusPos
>= ItemCount
)
3770 Type
= Item
[CurFocusPos
]->Type
;
3772 if (!(Item
[CurFocusPos
]->Flags
& (DIF_NOFOCUS
| DIF_DISABLE
| DIF_HIDDEN
))) {
3773 if (Type
== DI_LISTBOX
|| Type
== DI_BUTTON
|| Type
== DI_CHECKBOX
|| FarIsEdit(Type
)
3774 || Type
== DI_USERCONTROL
)
3777 if (Type
== DI_RADIOBUTTON
&& (!SkipGroup
|| Item
[CurFocusPos
]->Selected
))
3781 // убираем зацикливание с последующим подвисанием :-)
3782 if (OrigFocusPos
== CurFocusPos
)
3786 // Dialog::FocusPos=FocusPos;
3787 // В функцию обработки диалога здесь передаем сообщение,
3788 // что элемент GotFocus() - получил фокус ввода.
3789 // Игнорируем возвращаемое функцией диалога значение
3790 // if(DialogMode.Check(DMODE_INITOBJECTS))
3791 // DlgProc((HANDLE)this,DN_GOTFOCUS,FocusPos,0);
3792 return (CurFocusPos
);
3795 //////////////////////////////////////////////////////////////////////////
3798 Изменяет фокус ввода между двумя элементами.
3799 Вынесен отдельно с тем, чтобы обработать DN_KILLFOCUS & DM_SETFOCUS
3801 void Dialog::ChangeFocus2(unsigned SetFocusPos
)
3803 CriticalSectionLock
Lock(CS
);
3804 int FocusPosNeed
= -1;
3806 if (!(Item
[SetFocusPos
]->Flags
& (DIF_NOFOCUS
| DIF_DISABLE
| DIF_HIDDEN
))) {
3807 if (DialogMode
.Check(DMODE_INITOBJECTS
)) {
3808 FocusPosNeed
= (int)DlgProc((HANDLE
)this, DN_KILLFOCUS
, FocusPos
, 0);
3810 if (!DialogMode
.Check(DMODE_SHOW
))
3814 if (FocusPosNeed
!= -1 && CanGetFocus(Item
[FocusPosNeed
]->Type
))
3815 SetFocusPos
= FocusPosNeed
;
3817 Item
[FocusPos
]->Focus
= 0;
3819 // "снимать выделение при потере фокуса?"
3820 if (FarIsEdit(Item
[FocusPos
]->Type
)
3821 && !(Item
[FocusPos
]->Type
== DI_COMBOBOX
&& (Item
[FocusPos
]->Flags
& DIF_DROPDOWNLIST
))) {
3822 DlgEdit
*EditPtr
= (DlgEdit
*)Item
[FocusPos
]->ObjPtr
;
3823 EditPtr
->GetSelection(Item
[FocusPos
]->SelStart
, Item
[FocusPos
]->SelEnd
);
3825 if ((Opt
.Dialogs
.EditLine
& DLGEDITLINE_CLEARSELONKILLFOCUS
)) {
3826 EditPtr
->Select(-1, 0);
3830 Item
[SetFocusPos
]->Focus
= 1;
3832 // "не восстанавливать выделение при получении фокуса?"
3833 if (FarIsEdit(Item
[SetFocusPos
]->Type
)
3834 && !(Item
[SetFocusPos
]->Type
== DI_COMBOBOX
3835 && (Item
[SetFocusPos
]->Flags
& DIF_DROPDOWNLIST
))) {
3836 DlgEdit
*EditPtr
= (DlgEdit
*)Item
[SetFocusPos
]->ObjPtr
;
3838 if (!(Opt
.Dialogs
.EditLine
& DLGEDITLINE_NOTSELONGOTFOCUS
)) {
3839 if (Opt
.Dialogs
.EditLine
& DLGEDITLINE_SELALLGOTFOCUS
)
3840 EditPtr
->Select(0, EditPtr
->GetStrSize());
3842 EditPtr
->Select(Item
[SetFocusPos
]->SelStart
, Item
[SetFocusPos
]->SelEnd
);
3844 EditPtr
->Select(-1, 0);
3847 // при получении фокуса ввода переместить курсор в конец строки?
3848 if (Opt
.Dialogs
.EditLine
& DLGEDITLINE_GOTOEOLGOTFOCUS
) {
3849 EditPtr
->SetCurPos(EditPtr
->GetStrSize());
3853 // проинформируем листбокс, есть ли у него фокус
3854 if (Item
[FocusPos
]->Type
== DI_LISTBOX
)
3855 Item
[FocusPos
]->ListPtr
->ClearFlags(VMENU_LISTHASFOCUS
);
3857 if (Item
[SetFocusPos
]->Type
== DI_LISTBOX
)
3858 Item
[SetFocusPos
]->ListPtr
->SetFlags(VMENU_LISTHASFOCUS
);
3860 SelectOnEntry(FocusPos
, FALSE
);
3861 SelectOnEntry(SetFocusPos
, TRUE
);
3863 PrevFocusPos
= FocusPos
;
3864 FocusPos
= SetFocusPos
;
3866 if (DialogMode
.Check(DMODE_INITOBJECTS
))
3867 DlgProc((HANDLE
)this, DN_GOTFOCUS
, FocusPos
, 0);
3872 Функция SelectOnEntry - выделение строки редактирования
3873 Обработка флага DIF_SELECTONENTRY
3875 void Dialog::SelectOnEntry(unsigned Pos
, BOOL Selected
)
3877 // if(!DialogMode.Check(DMODE_SHOW))
3879 if (FarIsEdit(Item
[Pos
]->Type
) && (Item
[Pos
]->Flags
& DIF_SELECTONENTRY
)
3880 // && PrevFocusPos != -1 && PrevFocusPos != Pos
3882 DlgEdit
*edt
= (DlgEdit
*)Item
[Pos
]->ObjPtr
;
3886 edt
->Select(0, edt
->GetLength());
3890 //_SVS(SysLog(L"Selected=%d edt->GetLength()=%d",Selected,edt->GetLength()));
3895 int Dialog::SetAutomation(WORD IDParent
, WORD id
, FarDialogItemFlags UncheckedSet
,
3896 FarDialogItemFlags UncheckedSkip
, FarDialogItemFlags CheckedSet
, FarDialogItemFlags CheckedSkip
,
3897 FarDialogItemFlags Checked3Set
, FarDialogItemFlags Checked3Skip
)
3899 CriticalSectionLock
Lock(CS
);
3902 if (IDParent
< ItemCount
&& (Item
[IDParent
]->Flags
& DIF_AUTOMATION
) && id
< ItemCount
3903 && IDParent
!= id
) // Сами себя не юзаем!
3905 Ret
= Item
[IDParent
]->AddAutomation(id
, UncheckedSet
, UncheckedSkip
, CheckedSet
, CheckedSkip
,
3906 Checked3Set
, Checked3Skip
);
3912 //////////////////////////////////////////////////////////////////////////
3915 Заполняем выпадающий список для ComboBox
3917 int Dialog::SelectFromComboBox(DialogItemEx
*CurItem
,
3918 DlgEdit
*EditLine
, // строка редактирования
3919 VMenu
*ComboBox
) // список строк
3921 CriticalSectionLock
Lock(CS
);
3924 int EditX1
, EditY1
, EditX2
, EditY2
;
3925 int I
, Dest
, OriginalPos
;
3926 unsigned CurFocusPos
= FocusPos
;
3927 // if((Str=(char*)malloc(MaxLen)) )
3929 EditLine
->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
3931 if (EditX2
- EditX1
< 20)
3932 EditX2
= EditX1
+ 20;
3934 SetDropDownOpened(TRUE
); // Установим флаг "открытия" комбобокса.
3935 SetComboBoxPos(CurItem
);
3936 // Перед отрисовкой спросим об изменении цветовых атрибутов
3937 BYTE RealColors
[VMENU_COLOR_COUNT
];
3938 FarListColors ListColors
= {0};
3939 ListColors
.ColorCount
= VMENU_COLOR_COUNT
;
3940 ListColors
.Colors
= RealColors
;
3941 ComboBox
->SetColors(nullptr);
3942 ComboBox
->GetColors(&ListColors
);
3944 if (DlgProc((HANDLE
)this, DN_CTLCOLORDLGLIST
, CurItem
->ID
, (LONG_PTR
)&ListColors
))
3945 ComboBox
->SetColors(&ListColors
);
3947 // Выставим то, что есть в строке ввода!
3948 // if(EditLine->GetDropDownBox()) //???
3949 EditLine
->GetString(strStr
);
3951 if (CurItem
->Flags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
))
3952 HiText2Str(strStr
, strStr
);
3954 ComboBox
->SetSelectPos(ComboBox
->FindItem(0, strStr
, LIFIND_EXACTMATCH
), 1);
3956 OriginalPos
= Dest
= ComboBox
->GetSelectPos();
3957 CurItem
->IFlags
.Set(DLGIIF_COMBOBOXNOREDRAWEDIT
);
3959 while (!ComboBox
->Done()) {
3960 if (!GetDropDownOpened()) {
3961 ComboBox
->ProcessKey(KEY_ESC
);
3965 INPUT_RECORD ReadRec
;
3966 FarKey Key
= ComboBox
->ReadInput(&ReadRec
);
3968 if (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTKEY
) && ReadRec
.EventType
== KEY_EVENT
) {
3969 if (DlgProc((HANDLE
)this, DN_KEY
, FocusPos
, Key
))
3971 } else if (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTMOUSE
) && ReadRec
.EventType
== MOUSE_EVENT
)
3972 if (!DlgProc((HANDLE
)this, DN_MOUSEEVENT
, 0, (LONG_PTR
)&ReadRec
.Event
.MouseEvent
))
3975 // здесь можно добавить что-то свое, например,
3976 I
= ComboBox
->GetSelectPos();
3978 if (Key
== KEY_TAB
) // Tab в списке - аналог Enter
3980 ComboBox
->ProcessKey(KEY_ENTER
);
3985 if (!DlgProc((HANDLE
)this, DN_LISTCHANGE
, CurFocusPos
, I
))
3986 ComboBox
->SetSelectPos(Dest
, Dest
< I
? -1 : 1); //????
3992 // во время навигации по DropDown листу - отобразим ЭТО дело в
3995 // Очень медленная реакция!
3996 if (EditLine
->GetDropDownBox())
3998 MenuItem
*CurCBItem
=ComboBox
->GetItemPtr();
3999 EditLine
->SetString(CurCBItem
->Name
);
4001 //EditLine->FastShow();
4007 // обработку multiselect ComboBox
4009 ComboBox
->ProcessInput();
4012 CurItem
->IFlags
.Clear(DLGIIF_COMBOBOXNOREDRAWEDIT
);
4013 ComboBox
->ClearDone();
4016 if (GetDropDownOpened()) // Закрылся не программным путём?
4017 Dest
= ComboBox
->Modal::GetExitCode();
4022 ComboBox
->SetSelectPos(OriginalPos
, 0); //????
4024 SetDropDownOpened(FALSE
); // Установим флаг "закрытия" комбобокса.
4032 // ComboBox->GetUserData(Str,MaxLen,Dest);
4033 MenuItemEx
*ItemPtr
= ComboBox
->GetItemPtr(Dest
);
4035 if (CurItem
->Flags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
)) {
4036 HiText2Str(strStr
, ItemPtr
->strName
);
4037 EditLine
->SetString(strStr
);
4039 EditLine
->SetString(ItemPtr
->strName
);
4041 EditLine
->SetLeftPos(0);
4049 //////////////////////////////////////////////////////////////////////////
4052 Заполняем выпадающий список из истории
4054 BOOL
Dialog::SelectFromEditHistory(DialogItemEx
*CurItem
, DlgEdit
*EditLine
, const wchar_t *HistoryName
,
4057 CriticalSectionLock
Lock(CS
);
4064 FARString strRegKey
= fmtSavedDialogHistory
;
4065 strRegKey
+= HistoryName
;
4066 History
DlgHist(HISTORYTYPE_DIALOG
, Opt
.DialogsHistoryCount
, strRegKey
.GetMB(), &Opt
.Dialogs
.EditHistory
,
4068 DlgHist
.ResetPosition();
4070 // создание пустого вертикального меню
4071 VMenu
HistoryMenu(L
"", nullptr, 0, Opt
.Dialogs
.CBoxMaxHeight
,
4072 VMENU_ALWAYSSCROLLBAR
| VMENU_COMBOBOX
| VMENU_NOTCHANGE
);
4073 HistoryMenu
.SetFlags(VMENU_SHOWAMPERSAND
);
4074 HistoryMenu
.SetBoxType(SHORT_SINGLE_BOX
);
4075 SetDropDownOpened(TRUE
); // Установим флаг "открытия" комбобокса.
4076 // запомним (для прорисовки)
4077 CurItem
->ListPtr
= &HistoryMenu
;
4078 ret
= DlgHist
.Select(HistoryMenu
, Opt
.Dialogs
.CBoxMaxHeight
, this, strStr
);
4079 // забудим (не нужен)
4080 CurItem
->ListPtr
= nullptr;
4081 SetDropDownOpened(FALSE
); // Установим флаг "закрытия" комбобокса.
4085 EditLine
->SetString(strStr
);
4086 EditLine
->SetLeftPos(0);
4087 EditLine
->SetClearFlag(0);
4095 //////////////////////////////////////////////////////////////////////////
4098 Работа с историей - добавление и reorder списка
4100 int Dialog::AddToEditHistory(const wchar_t *AddStr
, const wchar_t *HistoryName
)
4102 CriticalSectionLock
Lock(CS
);
4108 FARString strRegKey
= fmtSavedDialogHistory
;
4109 strRegKey
+= HistoryName
;
4110 History
DlgHist(HISTORYTYPE_DIALOG
, Opt
.DialogsHistoryCount
, strRegKey
.GetMB(), &Opt
.Dialogs
.EditHistory
,
4112 DlgHist
.AddToHistory(AddStr
);
4116 int Dialog::CheckHighlights(WORD CheckSymbol
, int StartPos
)
4118 CriticalSectionLock
Lock(CS
);
4125 for (I
= StartPos
; I
< (int)ItemCount
; I
++) {
4126 Type
= Item
[I
]->Type
;
4127 Flags
= Item
[I
]->Flags
;
4129 if ((!FarIsEdit(Type
) || (Type
== DI_COMBOBOX
&& (Flags
& DIF_DROPDOWNLIST
)))
4130 && !(Flags
& (DIF_SHOWAMPERSAND
| DIF_DISABLE
| DIF_HIDDEN
))) {
4131 const wchar_t *ChPtr
= wcschr(Item
[I
]->strData
, L
'&');
4136 if (Ch
&& Upper(CheckSymbol
) == Upper(Ch
))
4138 } else if (!CheckSymbol
)
4146 //////////////////////////////////////////////////////////////////////////
4149 Если жмакнули Alt-???
4151 int Dialog::ProcessHighlighting(FarKey Key
, unsigned FocusPos
, int Translate
)
4153 CriticalSectionLock
Lock(CS
);
4157 for (unsigned I
= 0; I
< ItemCount
; I
++) {
4158 Type
= Item
[I
]->Type
;
4159 Flags
= Item
[I
]->Flags
;
4161 if ((!FarIsEdit(Type
) || (Type
== DI_COMBOBOX
&& (Flags
& DIF_DROPDOWNLIST
)))
4162 && !(Flags
& (DIF_SHOWAMPERSAND
| DIF_DISABLE
| DIF_HIDDEN
)))
4163 if (IsKeyHighlighted(Item
[I
]->strData
, Key
, Translate
)) {
4164 int DisableSelect
= FALSE
;
4166 // Если ЭТО: DlgEdit(пред контрол) и DI_TEXT в одну строку, то...
4167 if (I
> 0 && Type
== DI_TEXT
&& // DI_TEXT
4168 FarIsEdit(Item
[I
- 1]->Type
) && // и редактор
4169 Item
[I
]->Y1
== Item
[I
- 1]->Y1
&& // и оба в одну строку
4170 (I
+ 1 < ItemCount
&& Item
[I
]->Y1
!= Item
[I
+ 1]->Y1
)) // ...и следующий контрол в другой строке
4172 // Сначала сообщим о случившемся факте процедуре обработки диалога, а потом...
4173 if (!DlgProc((HANDLE
)this, DN_HOTKEY
, I
, Key
))
4174 break; // сказали не продолжать обработку...
4176 // ... если предыдущий контрол задизаблен или невидим, тогда выходим.
4177 if ((Item
[I
- 1]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))) // и не задисаблен
4180 I
= ChangeFocus(I
, -1, FALSE
);
4181 DisableSelect
= TRUE
;
4182 } else if (Item
[I
]->Type
== DI_TEXT
|| Item
[I
]->Type
== DI_VTEXT
4183 || Item
[I
]->Type
== DI_SINGLEBOX
|| Item
[I
]->Type
== DI_DOUBLEBOX
) {
4184 if (I
+ 1 < ItemCount
) // ...и следующий контрол
4186 // Сначала сообщим о случившемся факте процедуре обработки диалога, а потом...
4187 if (!DlgProc((HANDLE
)this, DN_HOTKEY
, I
, Key
))
4188 break; // сказали не продолжать обработку...
4190 // ... если следующий контрол задизаблен или невидим, тогда выходим.
4191 if ((Item
[I
+ 1]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))) // и не задисаблен
4194 I
= ChangeFocus(I
, 1, FALSE
);
4195 DisableSelect
= TRUE
;
4199 // Сообщим о случивщемся факте процедуре обработки диалога
4200 if (!DlgProc((HANDLE
)this, DN_HOTKEY
, I
, Key
))
4201 break; // сказали не продолжать обработку...
4206 if ((Item
[I
]->Type
== DI_CHECKBOX
|| Item
[I
]->Type
== DI_RADIOBUTTON
)
4207 && (!DisableSelect
|| (Item
[I
]->Flags
& DIF_MOVESELECT
))) {
4210 } else if (Item
[I
]->Type
== DI_BUTTON
) {
4211 ProcessKey(KEY_ENTER
, I
);
4214 // при ComboBox`е - "вываливаем" последний //????
4215 else if (Item
[I
]->Type
== DI_COMBOBOX
) {
4216 ProcessOpenComboBox(Item
[I
]->Type
, Item
[I
], I
);
4217 // ProcessKey(KEY_CTRLDOWN);
4228 //////////////////////////////////////////////////////////////////////////
4230 функция подравнивания координат edit классов
4232 void Dialog::AdjustEditPos(int dx
, int dy
)
4234 CriticalSectionLock
Lock(CS
);
4235 DialogItemEx
*CurItem
;
4238 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
))
4241 ScreenObject
*DialogScrObject
;
4243 for (unsigned I
= 0; I
< ItemCount
; I
++) {
4245 int Type
= CurItem
->Type
;
4247 if ((CurItem
->ObjPtr
&& FarIsEdit(Type
)) || (CurItem
->ListPtr
&& Type
== DI_LISTBOX
)) {
4248 if (Type
== DI_LISTBOX
)
4249 DialogScrObject
= (ScreenObject
*)CurItem
->ListPtr
;
4251 DialogScrObject
= (ScreenObject
*)CurItem
->ObjPtr
;
4253 DialogScrObject
->GetPosition(x1
, y1
, x2
, y2
);
4258 DialogScrObject
->SetPosition(x1
, y1
, x2
, y2
);
4262 ProcessCenterGroup();
4265 //////////////////////////////////////////////////////////////////////////
4267 Работа с доп. данными экземпляра диалога
4268 Пока простое копирование (присвоение)
4270 void Dialog::SetDialogData(LONG_PTR NewDataDialog
)
4272 DataDialog
= NewDataDialog
;
4275 //////////////////////////////////////////////////////////////////////////
4278 При расчётах времён копирования проще/надёжнее учитывать время ожидания
4279 пользовательских ответов в одном месте (здесь).
4280 Сброс этой переменной должен осуществляться перед общим началом операции
4286 + Для того, чтобы послать DM_CLOSE нужно переопределить Process
4288 static std::atomic
<int> s_in_dialog
{0};
4290 void Dialog::Process()
4292 // if(DialogMode.Check(DMODE_SMALLDIALOG))
4293 SetRestoreScreenMode(TRUE
);
4297 if (ExitCode
== -1) {
4300 DialogMode
.Set(DMODE_BEGINLOOP
);
4302 if (1 == ++s_in_dialog
) {
4303 btm
= GetProcessUptimeMSec();
4304 save
= WaitUserTime
;
4308 FrameManager
->ExecuteModal(this);
4309 save
+= (GetProcessUptimeMSec() - btm
);
4311 if (0 == --s_in_dialog
)
4312 WaitUserTime
= save
;
4316 for (unsigned i
= 0; i
< ItemCount
; i
++)
4317 DialogItemExToDialogItemEx(Item
[i
], &pSaveItemEx
[i
]);
4320 void Dialog::CloseDialog()
4322 CriticalSectionLock
Lock(CS
);
4323 GetDialogObjectsData();
4325 if (DlgProc((HANDLE
)this, DN_CLOSE
, ExitCode
, 0)) {
4326 DialogMode
.Set(DMODE_ENDLOOP
);
4329 if (DialogMode
.Check(DMODE_BEGINLOOP
)
4330 && (DialogMode
.Check(DMODE_MSGINTERNAL
) || FrameManager
->ManagerStarted())) {
4331 DialogMode
.Clear(DMODE_BEGINLOOP
);
4332 FrameManager
->DeleteFrame(this);
4335 _DIALOG(CleverSysLog
CL(L
"Close Dialog"));
4341 установка help topic'а и прочие радости, временно перетащенные сюда
4344 void Dialog::SetHelp(const wchar_t *Topic
)
4346 CriticalSectionLock
Lock(CS
);
4351 HelpTopic
= nullptr;
4353 if (Topic
&& *Topic
) {
4354 HelpTopic
= new (std::nothrow
) wchar_t[wcslen(Topic
) + 1];
4357 wcscpy(HelpTopic
, Topic
);
4361 void Dialog::ShowHelp()
4363 CriticalSectionLock
Lock(CS
);
4365 if (HelpTopic
&& *HelpTopic
) {
4366 Help::Present(HelpTopic
);
4370 void Dialog::ClearDone()
4372 CriticalSectionLock
Lock(CS
);
4374 DialogMode
.Clear(DMODE_ENDLOOP
);
4377 void Dialog::SetExitCode(int Code
)
4379 CriticalSectionLock
Lock(CS
);
4381 DialogMode
.Set(DMODE_ENDLOOP
);
4387 возвращаем наше название для меню по F12
4389 int Dialog::GetTypeAndName(FARString
&strType
, FARString
&strName
)
4391 CriticalSectionLock
Lock(CS
);
4392 strType
= Msg::DialogType
;
4394 const wchar_t *lpwszTitle
= GetDialogTitle();
4397 strName
= lpwszTitle
;
4399 return MODALTYPE_DIALOG
;
4402 int Dialog::GetMacroMode()
4404 return MACRO_DIALOG
;
4407 int Dialog::FastHide()
4409 return Opt
.AllCtrlAltShiftRule
& CASR_DIALOG
;
4412 void Dialog::ResizeConsole()
4414 CriticalSectionLock
Lock(CS
);
4416 DialogMode
.Set(DMODE_RESIZED
);
4422 COORD c
= {(SHORT
)(ScrX
+ 1), (SHORT
)(ScrY
+ 1)};
4423 SendDlgMessage(reinterpret_cast<HANDLE
>(this), DN_RESIZECONSOLE
, 0, reinterpret_cast<LONG_PTR
>(&c
));
4426 GetPosition(x1
, y1
, x2
, y2
);
4427 c
.X
= Min(x1
, ScrX
- 1);
4428 c
.Y
= Min(y1
, ScrY
- 1);
4429 if (c
.X
!= x1
|| c
.Y
!= y1
) {
4432 SendDlgMessage(reinterpret_cast<HANDLE
>(this), DM_MOVEDIALOG
, TRUE
, reinterpret_cast<LONG_PTR
>(&c
));
4433 Dialog::SetComboBoxPos();
4437 // void Dialog::OnDestroy()
4441 // Эта функция потеряла своё значение при текущем менеджере
4442 // и системе создания и уничтожения фреймов.
4444 // if(DialogMode.Check(DMODE_RESIZED))
4446 // Frame *BFrame=FrameManager->GetBottomFrame();
4448 // BFrame->UnlockRefresh();
4451 // А вот этот DM_KILLSAVESCREEN здесь только вредит. Удаление
4452 // диалога происходит без восстановления ShadowSaveScr и вот
4453 // они: "артефакты" непрорисовки.
4455 // SendDlgMessage((HANDLE)this,DM_KILLSAVESCREEN,0,0);
4459 LONG_PTR WINAPI
Dialog::DlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
4461 if (DialogMode
.Check(DMODE_ENDLOOP
))
4465 FarDialogEvent de
= {hDlg
, Msg
, Param1
, Param2
, 0};
4467 if (!reinterpret_cast<Dialog
*>(hDlg
)->CheckDialogMode(DMODE_NOPLUGINS
)) {
4468 if (CtrlObject
->Plugins
.ProcessDialogEvent(DE_DLGPROCINIT
, &de
))
4471 Result
= RealDlgProc(hDlg
, Msg
, Param1
, Param2
);
4472 if (!reinterpret_cast<Dialog
*>(hDlg
)->CheckDialogMode(DMODE_NOPLUGINS
)) {
4474 if (CtrlObject
->Plugins
.ProcessDialogEvent(DE_DLGPROCEND
, &de
))
4480 //////////////////////////////////////////////////////////////////////////
4483 функция обработки диалога (по умолчанию)
4484 Вот именно эта функция и является последним рубежом обработки диалога.
4485 Т.е. здесь должна быть ВСЯ обработка ВСЕХ сообщений!!!
4487 LONG_PTR WINAPI
DefDlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
4489 _DIALOG(CleverSysLog
CL(L
"Dialog.DefDlgProc()"));
4490 _DIALOG(SysLog(L
"hDlg=%p, Msg=%ls, Param1=%d (0x%08X), Param2=%d (0x%08X)", hDlg
, _DLGMSG_ToName(Msg
),
4491 Param1
, Param1
, Param2
, Param2
));
4493 if (!hDlg
|| hDlg
== INVALID_HANDLE_VALUE
)
4496 FarDialogEvent de
= {hDlg
, Msg
, Param1
, Param2
, 0};
4498 if (!reinterpret_cast<Dialog
*>(hDlg
)->CheckDialogMode(DMODE_NOPLUGINS
)) {
4499 if (CtrlObject
->Plugins
.ProcessDialogEvent(DE_DEFDLGPROCINIT
, &de
)) {
4503 Dialog
*Dlg
= (Dialog
*)hDlg
;
4504 CriticalSectionLock
Lock(Dlg
->CS
);
4505 DialogItemEx
*CurItem
= nullptr;
4510 return FALSE
; // изменений не было!
4512 return TRUE
; // согласен с закрытием
4514 return -1; // "Согласен с потерей фокуса"
4516 return 0; // always 0
4518 return Param2
; // что передали, то и...
4520 return TRUE
; // согласен с перемещалкой.
4521 case DN_DRAWDIALOGDONE
: {
4522 if (Param1
== 1) // Нужно отрисовать "салазки"?
4526 вывод текста в углу может приводить к ошибкам изображения
4527 1) когда диалог перемещается в угол
4528 2) когда диалог перемещается из угла
4529 сделал вывод красных палочек по углам
4531 Text(Dlg
->X1
, Dlg
->Y1
, 0xCE, L
"\\");
4532 Text(Dlg
->X1
, Dlg
->Y2
, 0xCE, L
"/");
4533 Text(Dlg
->X2
, Dlg
->Y1
, 0xCE, L
"/");
4534 Text(Dlg
->X2
, Dlg
->Y2
, 0xCE, L
"\\");
4539 case DN_DRAWDIALOG
: {
4542 case DN_CTLCOLORDIALOG
:
4544 case DN_CTLCOLORDLGITEM
:
4546 case DN_CTLCOLORDLGLIST
:
4549 return 0; // always 0
4550 case DM_GETDIALOGINFO
: {
4551 bool Result
= false;
4555 DialogInfo
*di
= reinterpret_cast<DialogInfo
*>(Param2
);
4557 if (static_cast<size_t>(di
->StructSize
) >= offsetof(DialogInfo
, Id
) + sizeof(di
->Id
)) {
4568 // предварительно проверим...
4569 if (Param1
< 0 || (unsigned)Param1
>= Dlg
->ItemCount
|| !Dlg
->Item
)
4572 CurItem
= Dlg
->Item
[Param1
];
4573 Type
= CurItem
->Type
;
4578 case DN_DRAWDLGITEM
:
4585 return ((Type
== DI_BUTTON
&& !(CurItem
->Flags
& DIF_BTNNOCLOSE
)) ? FALSE
: TRUE
);
4592 case DM_GETSELECTION
: // Msg=DM_GETSELECTION, Param1=ID, Param2=*EditorSelect
4594 case DM_SETSELECTION
:
4601 LONG_PTR
Dialog::CallDlgProc(int nMsg
, int nParam1
, LONG_PTR nParam2
)
4603 CriticalSectionLock
Lock(CS
);
4604 return Dialog::DlgProc((HANDLE
)this, nMsg
, nParam1
, nParam2
);
4607 //////////////////////////////////////////////////////////////////////////
4608 LONG_PTR
SendDlgMessageSynched(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
4610 Dialog
*Dlg
= (Dialog
*)hDlg
;
4611 CriticalSectionLock
Lock(Dlg
->CS
);
4612 _DIALOG(CleverSysLog
CL(L
"Dialog.SendDlgMessage()"));
4613 _DIALOG(SysLog(L
"hDlg=%p, Msg=%ls, Param1=%d (0x%08X), Param2=%d (0x%08X)", hDlg
, _DLGMSG_ToName(Msg
),
4614 Param1
, Param1
, Param2
, Param2
));
4616 // Сообщения, касаемые только диалога и не затрагивающие элементы
4618 /*****************************************************************/
4619 case DM_RESIZEDIALOG
:
4620 // изменим вызов RESIZE.
4622 /*****************************************************************/
4623 case DM_MOVEDIALOG
: {
4625 W1
= Dlg
->X2
- Dlg
->X1
+ 1;
4626 H1
= Dlg
->Y2
- Dlg
->Y1
+ 1;
4627 Dlg
->OldX1
= Dlg
->X1
;
4628 Dlg
->OldY1
= Dlg
->Y1
;
4629 Dlg
->OldX2
= Dlg
->X2
;
4630 Dlg
->OldY2
= Dlg
->Y2
;
4633 if (Param1
> 0) // абсолютно?
4635 Dlg
->X1
= ((COORD
*)Param2
)->X
;
4636 Dlg
->Y1
= ((COORD
*)Param2
)->Y
;
4639 Dlg
->CheckDialogCoord();
4640 } else if (!Param1
) // значит относительно
4642 Dlg
->X1
+= ((COORD
*)Param2
)->X
;
4643 Dlg
->Y1
+= ((COORD
*)Param2
)->Y
;
4644 } else // Resize, Param2=width/height
4649 W1
= ((COORD
*)Param2
)->X
;
4650 H1
= ((COORD
*)Param2
)->Y
;
4651 Dlg
->RealWidth
= W1
;
4652 Dlg
->RealHeight
= H1
;
4654 if (W1
< OldW1
|| H1
< OldH1
) {
4655 Dlg
->DialogMode
.Set(DMODE_DRAWING
);
4659 for (unsigned int I
= 0; I
< Dlg
->ItemCount
; I
++) {
4660 Item
= Dlg
->Item
[I
];
4662 if (Item
->Flags
& DIF_HIDDEN
)
4665 Rect
.Left
= Item
->X1
;
4666 Rect
.Top
= Item
->Y1
;
4668 if (Item
->X2
>= W1
) {
4669 Rect
.Right
= Item
->X2
- (OldW1
- W1
);
4670 Rect
.Bottom
= Item
->Y2
;
4671 Dlg
->SetItemRect(I
, &Rect
);
4674 if (Item
->Y2
>= H1
) {
4675 Rect
.Right
= Item
->X2
;
4676 Rect
.Bottom
= Item
->Y2
- (OldH1
- H1
);
4677 Dlg
->SetItemRect(I
, &Rect
);
4681 Dlg
->DialogMode
.Clear(DMODE_DRAWING
);
4685 // проверили и скорректировали
4686 if (Dlg
->X1
+ W1
< 0)
4689 if (Dlg
->Y1
+ H1
< 0)
4698 Dlg
->X2
= Dlg
->X1
+ W1
- 1;
4699 Dlg
->Y2
= Dlg
->Y1
+ H1
- 1;
4701 if (Param1
> 0) // абсолютно?
4703 Dlg
->CheckDialogCoord();
4706 if (Param1
< 0) // размер?
4708 ((COORD
*)Param2
)->X
= Dlg
->X2
- Dlg
->X1
+ 1;
4709 ((COORD
*)Param2
)->Y
= Dlg
->Y2
- Dlg
->Y1
+ 1;
4711 ((COORD
*)Param2
)->X
= Dlg
->X1
;
4712 ((COORD
*)Param2
)->Y
= Dlg
->Y1
;
4715 int I
= Dlg
->IsVisible(); // && Dlg->DialogMode.Check(DMODE_INITOBJECTS);
4721 Dlg
->AdjustEditPos(Dlg
->X1
- Dlg
->OldX1
, Dlg
->Y1
- Dlg
->OldY1
);
4724 Dlg
->Show(); // только если диалог был виден
4728 /*****************************************************************/
4730 if (Dlg
->DialogMode
.Check(DMODE_INITOBJECTS
))
4735 /*****************************************************************/
4736 case DM_ENABLEREDRAW
: {
4737 int Prev
= Dlg
->IsEnableRedraw
;
4740 Dlg
->IsEnableRedraw
++;
4741 else if (Param1
== FALSE
)
4742 Dlg
->IsEnableRedraw
--;
4744 // Edit::DisableEditOut(!Dlg->IsEnableRedraw?FALSE:TRUE);
4746 if (!Dlg
->IsEnableRedraw
&& Prev
!= Dlg
->IsEnableRedraw
)
4747 if (Dlg
->DialogMode
.Check(DMODE_INITOBJECTS
)) {
4756 case DM_ENABLEREDRAW:
4759 Dlg->IsEnableRedraw++;
4761 Dlg->IsEnableRedraw--;
4763 if(!Dlg->IsEnableRedraw)
4764 if(Dlg->DialogMode.Check(DMODE_INITOBJECTS))
4773 /*****************************************************************/
4774 case DM_SHOWDIALOG
: {
4775 // if(!Dlg->IsEnableRedraw)
4780 Залочим прорисовку при прятании диалога, в противном
4781 случае ОТКУДА менеджер узнает, что отрисовывать
4784 if (!Dlg
->IsVisible()) {
4789 if (Dlg
->IsVisible()) {
4797 /*****************************************************************/
4798 case DM_SETDLGDATA
: {
4799 LONG_PTR PrewDataDialog
= Dlg
->DataDialog
;
4800 Dlg
->DataDialog
= Param2
;
4801 return PrewDataDialog
;
4803 /*****************************************************************/
4804 case DM_GETDLGDATA
: {
4805 return Dlg
->DataDialog
;
4807 /*****************************************************************/
4809 int *KeyArray
= (int *)Param2
;
4810 Dlg
->DialogMode
.Set(DMODE_KEY
);
4812 for (unsigned int I
= 0; I
< (unsigned)Param1
; ++I
)
4813 Dlg
->ProcessKey(KeyArray
[I
]);
4815 Dlg
->DialogMode
.Clear(DMODE_KEY
);
4818 /*****************************************************************/
4821 Dlg
->ExitCode
= Dlg
->FocusPos
;
4823 Dlg
->ExitCode
= Param1
;
4826 return TRUE
; // согласен с закрытием
4828 /*****************************************************************/
4829 case DM_GETDLGRECT
: {
4832 Dlg
->GetPosition(x1
, y1
, x2
, y2
);
4833 ((SMALL_RECT
*)Param2
)->Left
= x1
;
4834 ((SMALL_RECT
*)Param2
)->Top
= y1
;
4835 ((SMALL_RECT
*)Param2
)->Right
= x2
;
4836 ((SMALL_RECT
*)Param2
)->Bottom
= y2
;
4842 /*****************************************************************/
4843 case DM_GETDROPDOWNOPENED
: // Param1=0; Param2=0
4845 return Dlg
->GetDropDownOpened();
4847 /*****************************************************************/
4848 case DM_KILLSAVESCREEN
: {
4850 Dlg
->SaveScr
->Discard();
4852 if (Dlg
->ShadowSaveScr
)
4853 Dlg
->ShadowSaveScr
->Discard();
4857 /*****************************************************************/
4861 =-1 - получить состояние
4866 case DM_ALLKEYMODE
: {
4868 return IsProcessAssignMacroKey
;
4870 BOOL OldIsProcessAssignMacroKey
= IsProcessAssignMacroKey
;
4871 IsProcessAssignMacroKey
= Param1
;
4872 return OldIsProcessAssignMacroKey
;
4874 /*****************************************************************/
4875 case DM_SETMOUSEEVENTNOTIFY
: // Param1 = 1 on, 0 off, -1 - get
4877 int State
= Dlg
->DialogMode
.Check(DMODE_MOUSEEVENT
) ? TRUE
: FALSE
;
4881 Dlg
->DialogMode
.Clear(DMODE_MOUSEEVENT
);
4883 Dlg
->DialogMode
.Set(DMODE_MOUSEEVENT
);
4888 /*****************************************************************/
4889 case DN_RESIZECONSOLE
: {
4890 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
4892 case DM_GETDIALOGINFO
: {
4893 return DefDlgProc(hDlg
, DM_GETDIALOGINFO
, Param1
, Param2
);
4897 /*****************************************************************/
4898 if (Msg
>= DM_USER
) {
4899 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
4902 /*****************************************************************/
4903 DialogItemEx
*CurItem
= nullptr;
4908 предварительно проверим...
4910 для DM_USER проверять _не_надо_!
4912 if ((unsigned)Param1
>= Dlg
->ItemCount
|| !Dlg
->Item
)
4915 // CurItem=&Dlg->Item[Param1];
4916 CurItem
= Dlg
->Item
[Param1
];
4917 Type
= CurItem
->Type
;
4918 const wchar_t *Ptr
= CurItem
->strData
;
4920 if (FarIsEdit(Type
) && CurItem
->ObjPtr
)
4921 Ptr
= const_cast<const wchar_t *>(((DlgEdit
*)(CurItem
->ObjPtr
))->GetStringAddr());
4924 /*****************************************************************/
4925 case DM_LISTSORT
: // Param1=ID Param=Direct {0|1}
4926 case DM_LISTADD
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
4927 case DM_LISTADDSTR
: // Param1=ID Param2=String
4928 case DM_LISTDELETE
: // Param1=ID Param2=FarListDelete: StartIndex=BeginIndex, Count=количество (<=0 - все!)
4929 case DM_LISTGETITEM
: // Param1=ID Param2=FarListGetItem: ItemsNumber=Index, Items=Dest
4930 case DM_LISTSET
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
4931 case DM_LISTGETCURPOS
: // Param1=ID Param2=FarListPos
4932 case DM_LISTSETCURPOS
: // Param1=ID Param2=FarListPos Ret: RealPos
4933 case DM_LISTUPDATE
: // Param1=ID Param2=FarList: ItemsNumber=Index, Items=Src
4934 case DM_LISTINFO
: // Param1=ID Param2=FarListInfo
4935 case DM_LISTFINDSTRING
: // Param1=ID Param2=FarListFind
4936 case DM_LISTINSERT
: // Param1=ID Param2=FarListInsert
4937 case DM_LISTGETDATA
: // Param1=ID Param2=Index
4938 case DM_LISTSETDATA
: // Param1=ID Param2=FarListItemData
4939 case DM_LISTSETTITLES
: // Param1=ID Param2=FarListTitles: TitleLen=strlen(Title), BottomLen=strlen(Bottom)
4940 case DM_LISTGETTITLES
: // Param1=ID Param2=FarListTitles: TitleLen=strlen(Title), BottomLen=strlen(Bottom)
4941 case DM_LISTGETDATASIZE
: // Param1=ID Param2=Index
4942 case DM_LISTSETMOUSEREACTION
: // Param1=ID Param2=FARLISTMOUSEREACTIONTYPE Ret=OldSets
4943 case DM_SETCOMBOBOXEVENT
: // Param1=ID Param2=FARCOMBOBOXEVENTTYPE Ret=OldSets
4944 case DM_GETCOMBOBOXEVENT
: // Param1=ID Param2=0 Ret=Sets
4946 if (Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) {
4947 VMenu
*ListBox
= CurItem
->ListPtr
;
4953 case DM_LISTINFO
: // Param1=ID Param2=FarListInfo
4955 return ListBox
->GetVMenuInfo((FarListInfo
*)Param2
);
4957 case DM_LISTSORT
: // Param1=ID Param=Direct {0|1}
4959 ListBox
->SortItems((int)Param2
);
4962 case DM_LISTFINDSTRING
: // Param1=ID Param2=FarListFind
4964 FarListFind
*lf
= reinterpret_cast<FarListFind
*>(Param2
);
4965 return ListBox
->FindItem(lf
->StartIndex
, lf
->Pattern
, lf
->Flags
);
4967 case DM_LISTADDSTR
: // Param1=ID Param2=String
4969 Ret
= ListBox
->AddItem((wchar_t *)Param2
);
4972 case DM_LISTADD
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
4974 FarList
*ListItems
= (FarList
*)Param2
;
4979 Ret
= ListBox
->AddItem(ListItems
);
4982 case DM_LISTDELETE
: // Param1=ID Param2=FarListDelete: StartIndex=BeginIndex, Count=количество (<=0 - все!)
4985 FarListDelete
*ListItems
= (FarListDelete
*)Param2
;
4987 if (!ListItems
|| (Count
= ListItems
->Count
) <= 0)
4988 ListBox
->DeleteItems();
4990 ListBox
->DeleteItem(ListItems
->StartIndex
, Count
);
4994 case DM_LISTINSERT
: // Param1=ID Param2=FarListInsert
4996 if ((Ret
= ListBox
->InsertItem((FarListInsert
*)Param2
)) == -1)
5001 case DM_LISTUPDATE
: // Param1=ID Param2=FarListUpdate: Index=Index, Items=Src
5003 if (Param2
&& ListBox
->UpdateItem((FarListUpdate
*)Param2
))
5008 case DM_LISTGETITEM
: // Param1=ID Param2=FarListGetItem: ItemsNumber=Index, Items=Dest
5010 FarListGetItem
*ListItems
= (FarListGetItem
*)Param2
;
5015 MenuItemEx
*ListMenuItem
;
5017 if ((ListMenuItem
= ListBox
->GetItemPtr(ListItems
->ItemIndex
))) {
5018 // ListItems->ItemIndex=1;
5019 FarListItem
*Item
= &ListItems
->Item
;
5020 memset(Item
, 0, sizeof(FarListItem
));
5021 Item
->Flags
= ListMenuItem
->Flags
;
5022 Item
->Text
= ListMenuItem
->strName
;
5024 if(ListMenuItem->UserDataSize <= sizeof(DWORD)) //???
5025 Item->UserData=ListMenuItem->UserData;
5032 case DM_LISTGETDATA
: // Param1=ID Param2=Index
5034 if (Param2
< ListBox
->GetItemCount())
5035 return (LONG_PTR
)ListBox
->GetUserData(nullptr, 0, (int)Param2
);
5039 case DM_LISTGETDATASIZE
: // Param1=ID Param2=Index
5041 if (Param2
< ListBox
->GetItemCount())
5042 return ListBox
->GetUserDataSize((int)Param2
);
5046 case DM_LISTSETDATA
: // Param1=ID Param2=FarListItemData
5048 FarListItemData
*ListItems
= (FarListItemData
*)Param2
;
5050 if (ListItems
&& ListItems
->Index
< ListBox
->GetItemCount()) {
5051 Ret
= ListBox
->SetUserData(ListItems
->Data
, ListItems
->DataSize
,
5054 if (!Ret
&& ListBox
->GetUserData(nullptr, 0, ListItems
->Index
))
5055 Ret
= sizeof(DWORD
);
5064 + Сообщение для добавления в список строк, с удалением
5065 уже существующих, т.с. "чистая" установка
5067 case DM_LISTSET
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
5069 FarList
*ListItems
= (FarList
*)Param2
;
5074 ListBox
->DeleteItems();
5075 Ret
= ListBox
->AddItem(ListItems
);
5078 // case DM_LISTINS: // Param1=ID Param2=FarList: ItemsNumber=Index, Items=Dest
5079 case DM_LISTSETTITLES
: // Param1=ID Param2=FarListTitles
5081 FarListTitles
*ListTitle
= (FarListTitles
*)Param2
;
5082 ListBox
->SetTitle(ListTitle
->Title
);
5083 ListBox
->SetBottomTitle(ListTitle
->Bottom
);
5084 break; // return TRUE;
5086 case DM_LISTGETTITLES
: // Param1=ID Param2=FarListTitles
5089 FarListTitles
*ListTitle
= (FarListTitles
*)Param2
;
5090 FARString strTitle
, strBottomTitle
;
5091 ListBox
->GetTitle(strTitle
);
5092 ListBox
->GetBottomTitle(strBottomTitle
);
5094 if (!strTitle
.IsEmpty() || !strBottomTitle
.IsEmpty()) {
5095 if (ListTitle
->Title
&& ListTitle
->TitleLen
)
5096 far_wcsncpy((wchar_t *)ListTitle
->Title
, strTitle
,
5097 ListTitle
->TitleLen
);
5099 ListTitle
->TitleLen
= (int)strTitle
.GetLength() + 1;
5101 if (ListTitle
->Bottom
&& ListTitle
->BottomLen
)
5102 far_wcsncpy((wchar_t *)ListTitle
->Bottom
, strBottomTitle
,
5103 ListTitle
->BottomLen
);
5105 ListTitle
->BottomLen
= (int)strBottomTitle
.GetLength() + 1;
5113 case DM_LISTGETCURPOS
: // Param1=ID Param2=FarListPos
5115 return Param2
? ListBox
->GetSelectPos((FarListPos
*)Param2
)
5116 : ListBox
->GetSelectPos();
5118 case DM_LISTSETCURPOS
: // Param1=ID Param2=FarListPos Ret: RealPos
5120 /* 26.06.2001 KM Подадим перед изменением позиции об этом сообщение */
5121 int CurListPos
= ListBox
->GetSelectPos();
5122 Ret
= ListBox
->SetSelectPos((FarListPos
*)Param2
);
5124 if (Ret
!= CurListPos
)
5125 if (!Dlg
->CallDlgProc(DN_LISTCHANGE
, Param1
, Ret
))
5126 Ret
= ListBox
->SetSelectPos(CurListPos
, 1);
5128 break; // т.к. нужно перерисовать!
5130 case DM_LISTSETMOUSEREACTION
: // Param1=ID Param2=FARLISTMOUSEREACTIONTYPE Ret=OldSets
5132 int OldSets
= CurItem
->IFlags
.Flags
;
5134 if (Param2
== LMRT_ONLYFOCUS
) {
5135 CurItem
->IFlags
.Clear(DLGIIF_LISTREACTIONNOFOCUS
);
5136 CurItem
->IFlags
.Set(DLGIIF_LISTREACTIONFOCUS
);
5137 } else if (Param2
== LMRT_NEVER
) {
5138 CurItem
->IFlags
.Clear(DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
);
5139 // ListBox->ClearFlags(VMENU_MOUSEREACTION);
5141 CurItem
->IFlags
.Set(DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
);
5142 // ListBox->SetFlags(VMENU_MOUSEREACTION);
5145 if ((OldSets
& (DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
))
5146 == (DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
))
5147 OldSets
= LMRT_ALWAYS
;
5148 else if (!(OldSets
& (DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
)))
5149 OldSets
= LMRT_NEVER
;
5151 OldSets
= LMRT_ONLYFOCUS
;
5155 case DM_GETCOMBOBOXEVENT
: // Param1=ID Param2=0 Ret=Sets
5157 return (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTKEY
) ? CBET_KEY
: 0)
5158 | (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTMOUSE
) ? CBET_MOUSE
: 0);
5160 case DM_SETCOMBOBOXEVENT
: // Param1=ID Param2=FARCOMBOBOXEVENTTYPE Ret=OldSets
5162 int OldSets
= CurItem
->IFlags
.Flags
;
5163 CurItem
->IFlags
.Clear(DLGIIF_COMBOBOXEVENTKEY
| DLGIIF_COMBOBOXEVENTMOUSE
);
5165 if (Param2
& CBET_KEY
)
5166 CurItem
->IFlags
.Set(DLGIIF_COMBOBOXEVENTKEY
);
5168 if (Param2
& CBET_MOUSE
)
5169 CurItem
->IFlags
.Set(DLGIIF_COMBOBOXEVENTMOUSE
);
5175 // уточнение для DI_COMBOBOX - здесь еще и DlgEdit нужно корректно заполнить
5176 if (!CurItem
->IFlags
.Check(DLGIIF_COMBOBOXNOREDRAWEDIT
) && Type
== DI_COMBOBOX
5177 && CurItem
->ObjPtr
) {
5178 MenuItemEx
*ListMenuItem
;
5180 if ((ListMenuItem
= ListBox
->GetItemPtr(ListBox
->GetSelectPos()))) {
5181 if (CurItem
->Flags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
))
5182 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetHiString(ListMenuItem
->strName
);
5184 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetString(ListMenuItem
->strName
);
5186 ((DlgEdit
*)(CurItem
->ObjPtr
))->Select(-1, -1); // снимаем выделение
5190 if (Dlg
->DialogMode
.Check(DMODE_SHOW
) && ListBox
->UpdateRequired()) {
5191 Dlg
->ShowDialog(Param1
);
5201 /*****************************************************************/
5202 case DM_SETHISTORY
: // Param1 = ID, Param2 = LPSTR HistoryName
5204 if (Type
== DI_EDIT
|| Type
== DI_FIXEDIT
) {
5205 if (Param2
&& *(const wchar_t *)Param2
) {
5206 CurItem
->Flags
|= DIF_HISTORY
;
5207 CurItem
->strHistory
= (const wchar_t *)Param2
;
5209 if (Type
== DI_EDIT
&& (CurItem
->Flags
& DIF_USELASTHISTORY
)) {
5210 Dlg
->ProcessLastHistory(CurItem
, Param1
);
5213 CurItem
->Flags
&= ~DIF_HISTORY
;
5214 CurItem
->strHistory
.Clear();
5217 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5218 Dlg
->ShowDialog(Param1
);
5227 /*****************************************************************/
5228 case DM_ADDHISTORY
: {
5229 if (Param2
&& (Type
== DI_EDIT
|| Type
== DI_FIXEDIT
) && (CurItem
->Flags
& DIF_HISTORY
)) {
5230 return Dlg
->AddToEditHistory((const wchar_t *)Param2
, CurItem
->strHistory
);
5235 /*****************************************************************/
5236 case DM_GETCURSORPOS
: {
5240 if (FarIsEdit(Type
) && CurItem
->ObjPtr
) {
5241 ((COORD
*)Param2
)->X
= ((DlgEdit
*)(CurItem
->ObjPtr
))->GetCurPos();
5242 ((COORD
*)Param2
)->Y
= 0;
5244 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5245 ((COORD
*)Param2
)->X
= CurItem
->UCData
->CursorPos
.X
;
5246 ((COORD
*)Param2
)->Y
= CurItem
->UCData
->CursorPos
.Y
;
5252 /*****************************************************************/
5253 case DM_SETCURSORPOS
: {
5254 if (FarIsEdit(Type
) && CurItem
->ObjPtr
&& ((COORD
*)Param2
)->X
>= 0) {
5255 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
5256 EditPtr
->SetCurPos(((COORD
*)Param2
)->X
);
5258 Dlg
->ShowDialog(Param1
);
5260 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5262 учтем, что координаты для этого элемента всегда относительные!
5265 COORD Coord
= *(COORD
*)Param2
;
5266 Coord
.X
+= CurItem
->X1
;
5268 if (Coord
.X
> CurItem
->X2
)
5269 Coord
.X
= CurItem
->X2
;
5271 Coord
.Y
+= CurItem
->Y1
;
5273 if (Coord
.Y
> CurItem
->Y2
)
5274 Coord
.Y
= CurItem
->Y2
;
5277 CurItem
->UCData
->CursorPos
.X
= Coord
.X
- CurItem
->X1
;
5278 CurItem
->UCData
->CursorPos
.Y
= Coord
.Y
- CurItem
->Y1
;
5280 // переместим если надо
5281 if (Dlg
->DialogMode
.Check(DMODE_SHOW
) && Dlg
->FocusPos
== (unsigned)Param1
) {
5282 // что-то одно надо убрать :-)
5283 MoveCursor(Coord
.X
+ Dlg
->X1
, Coord
.Y
+ Dlg
->Y1
); // ???
5284 Dlg
->ShowDialog(Param1
); // ???
5292 /*****************************************************************/
5293 case DM_GETEDITPOSITION
: {
5294 if (Param2
&& FarIsEdit(Type
)) {
5295 if (Type
== DI_MEMOEDIT
) {
5296 // EditorControl(ECTL_GETINFO,(EditorSetPosition *)Param2);
5299 EditorSetPosition
*esp
= (EditorSetPosition
*)Param2
;
5300 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
5302 esp
->CurPos
= EditPtr
->GetCurPos();
5303 esp
->CurTabPos
= EditPtr
->GetCellCurPos();
5304 esp
->TopScreenLine
= 0;
5305 esp
->LeftPos
= EditPtr
->GetLeftPos();
5306 esp
->Overtype
= EditPtr
->GetOvertypeMode();
5313 /*****************************************************************/
5314 case DM_SETEDITPOSITION
: {
5315 if (Param2
&& FarIsEdit(Type
)) {
5316 if (Type
== DI_MEMOEDIT
) {
5317 // EditorControl(ECTL_SETPOSITION,(EditorSetPosition *)Param2);
5320 EditorSetPosition
*esp
= (EditorSetPosition
*)Param2
;
5321 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
5322 EditPtr
->SetCurPos(esp
->CurPos
);
5323 EditPtr
->SetCellCurPos(esp
->CurTabPos
);
5324 EditPtr
->SetLeftPos(esp
->LeftPos
);
5325 EditPtr
->SetOvertypeMode(esp
->Overtype
);
5326 Dlg
->ShowDialog(Param1
);
5334 /*****************************************************************/
5336 // Return MAKELONG(Visible,Size)
5337 case DM_GETCURSORSIZE
: {
5338 if (FarIsEdit(Type
) && CurItem
->ObjPtr
) {
5341 ((DlgEdit
*)(CurItem
->ObjPtr
))->GetCursorType(Visible
, Size
);
5342 return MAKELONG(Visible
, Size
);
5343 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5344 return MAKELONG(CurItem
->UCData
->CursorVisible
, CurItem
->UCData
->CursorSize
);
5349 /*****************************************************************/
5350 // Param2=MAKELONG(Visible,Size)
5351 // Return MAKELONG(OldVisible,OldSize)
5352 case DM_SETCURSORSIZE
: {
5353 bool Visible
= false;
5356 if (FarIsEdit(Type
) && CurItem
->ObjPtr
) {
5357 ((DlgEdit
*)(CurItem
->ObjPtr
))->GetCursorType(Visible
, Size
);
5358 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetCursorType(LOWORD(Param2
) != 0, HIWORD(Param2
));
5359 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5360 Visible
= CurItem
->UCData
->CursorVisible
;
5361 Size
= CurItem
->UCData
->CursorSize
;
5362 CurItem
->UCData
->CursorVisible
= LOWORD(Param2
) != 0;
5363 CurItem
->UCData
->CursorSize
= HIWORD(Param2
);
5364 int CCX
= CurItem
->UCData
->CursorPos
.X
;
5365 int CCY
= CurItem
->UCData
->CursorPos
.Y
;
5367 if (Dlg
->DialogMode
.Check(DMODE_SHOW
) && Dlg
->FocusPos
== (unsigned)Param1
&& CCX
!= -1
5369 SetCursorType(CurItem
->UCData
->CursorVisible
, CurItem
->UCData
->CursorSize
);
5372 return MAKELONG(Visible
, Size
);
5374 /*****************************************************************/
5375 case DN_LISTCHANGE
: {
5376 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
5378 /*****************************************************************/
5379 case DN_EDITCHANGE
: {
5382 if (!ConvertItemEx(CVTITEM_TOPLUGIN
, &Item
, CurItem
, 1))
5383 return FALSE
; // no memory TODO: may be needed diagnostic
5386 if (CurItem
->Type
== DI_EDIT
|| CurItem
->Type
== DI_COMBOBOX
|| CurItem
->Type
== DI_FIXEDIT
5387 || CurItem
->Type
== DI_PSWEDIT
) {
5388 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(false);
5389 const wchar_t *original_PtrData
= Item
.PtrData
;
5390 I
= Dlg
->CallDlgProc(DN_EDITCHANGE
, Param1
, (LONG_PTR
)&Item
);
5392 if (Type
== DI_COMBOBOX
&& CurItem
->ListPtr
)
5393 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
5395 if (original_PtrData
)
5396 free((void *)original_PtrData
);
5397 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(true);
5402 /*****************************************************************/
5404 LONG_PTR Ret
= Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
5406 if (Ret
&& (CurItem
->Flags
& DIF_AUTOMATION
) && CurItem
->AutoCount
&& CurItem
->AutoPtr
) {
5407 DialogItemAutomation
*Auto
= CurItem
->AutoPtr
;
5410 for (UINT I
= 0; I
< CurItem
->AutoCount
; ++I
, ++Auto
) {
5411 DWORD NewFlags
= Dlg
->Item
[Auto
->ID
]->Flags
;
5412 Dlg
->Item
[Auto
->ID
]->Flags
=
5413 (NewFlags
& (~Auto
->Flags
[Param2
][1])) | Auto
->Flags
[Param2
][0];
5414 // здесь намеренно в обработчик не посылаются эвенты об изменении
5421 /*****************************************************************/
5423 if (Type
== DI_CHECKBOX
|| Type
== DI_RADIOBUTTON
)
5424 return CurItem
->Selected
;
5428 /*****************************************************************/
5429 case DM_SET3STATE
: {
5430 if (Type
== DI_CHECKBOX
) {
5431 int OldState
= CurItem
->Flags
& DIF_3STATE
? TRUE
: FALSE
;
5434 CurItem
->Flags
|= DIF_3STATE
;
5436 CurItem
->Flags
&= ~DIF_3STATE
;
5443 /*****************************************************************/
5445 if (Type
== DI_CHECKBOX
) {
5446 int Selected
= CurItem
->Selected
;
5448 if (Param2
== BSTATE_TOGGLE
)
5449 Param2
= ++Selected
;
5451 if (CurItem
->Flags
& DIF_3STATE
)
5456 CurItem
->Selected
= (int)Param2
;
5458 if (Selected
!= (int)Param2
&& Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5460 if ((CurItem
->Flags
& DIF_AUTOMATION
) && CurItem
->AutoCount
&& CurItem
->AutoPtr
) {
5461 DialogItemAutomation
*Auto
= CurItem
->AutoPtr
;
5464 for (UINT I
= 0; I
< CurItem
->AutoCount
; ++I
, ++Auto
) {
5465 DWORD NewFlags
= Dlg
->Item
[Auto
->ID
]->Flags
;
5466 Dlg
->Item
[Auto
->ID
]->Flags
=
5467 (NewFlags
& (~Auto
->Flags
[Param2
][1])) | Auto
->Flags
[Param2
][0];
5468 // здесь намеренно в обработчик не посылаются эвенты об изменении
5475 Dlg
->ShowDialog(Param1
);
5480 } else if (Type
== DI_RADIOBUTTON
) {
5481 Param1
= Dlg
->ProcessRadioButton(Param1
);
5483 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5493 /*****************************************************************/
5494 case DN_DRAWDLGITEM
: {
5497 if (!ConvertItemEx(CVTITEM_TOPLUGIN
, &Item
, CurItem
, 1))
5498 return FALSE
; // no memory TODO: may be needed diagnostic
5500 INT_PTR I
= Dlg
->CallDlgProc(Msg
, Param1
, (LONG_PTR
)&Item
);
5502 if ((Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) && CurItem
->ListPtr
)
5503 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
5506 free((wchar_t *)Item
.PtrData
);
5510 /*****************************************************************/
5512 if (!CanGetFocus(Type
))
5515 if (Dlg
->FocusPos
== (unsigned)Param1
) // уже и так установлено все!
5518 Dlg
->ChangeFocus2(Param1
);
5520 if (Dlg
->FocusPos
== (unsigned)Param1
) {
5527 /*****************************************************************/
5528 case DM_GETFOCUS
: // Получить ID фокуса
5530 return Dlg
->FocusPos
;
5532 /*****************************************************************/
5533 case DM_GETCONSTTEXTPTR
: {
5534 return (LONG_PTR
)Ptr
;
5536 /*****************************************************************/
5540 FarDialogItemData IData
= {0, (wchar_t *)Param2
};
5541 return SendDlgMessage(hDlg
, DM_GETTEXT
, Param1
, (LONG_PTR
)&IData
);
5544 /*****************************************************************/
5547 if (Param2
) // если здесь nullptr, то это еще один способ получить размер
5549 FarDialogItemData
*did
= (FarDialogItemData
*)Param2
;
5560 if (!CurItem
->ObjPtr
)
5563 Ptr
= const_cast<const wchar_t *>(((DlgEdit
*)(CurItem
->ObjPtr
))->GetStringAddr());
5569 case DI_RADIOBUTTON
:
5571 Len
= StrLength(Ptr
) + 1;
5573 if (Type
== DI_BUTTON
) {
5574 if (!(CurItem
->Flags
& DIF_NOBRACKETS
)) {
5578 if (CurItem
->Flags
& DIF_SETSHIELD
) {
5583 if (!did
->PtrLength
)
5584 did
->PtrLength
= Len
;
5585 else if (Len
> did
->PtrLength
)
5586 Len
= did
->PtrLength
+ 1; // Прибавим 1, чтобы учесть нулевой байт.
5588 if (Len
> 0 && did
->PtrData
) {
5589 wmemmove(did
->PtrData
, Ptr
, Len
);
5590 did
->PtrData
[Len
- 1] = 0;
5594 case DI_USERCONTROL
:
5595 /*did->PtrLength=CurItem->Ptr.PtrLength; BUGBUG
5596 did->PtrData=(char*)CurItem->Ptr.PtrData;*/
5599 // if(!CurItem->ListPtr)
5601 // did->PtrLength=CurItem->ListPtr->GetUserData(did->PtrData,did->PtrLength,-1);
5604 default: // подразумеваем, что остались
5609 return Len
- (!Len
? 0 : 1);
5612 // здесь умышленно не ставим return, т.к. хотим получить размер
5613 // следовательно сразу должен идти "case DM_GETTEXTLENGTH"!!!
5614 /*****************************************************************/
5615 case DM_GETTEXTLENGTH
: {
5618 Len
= StrLength(Ptr
) + 1;
5620 if (!(CurItem
->Flags
& DIF_NOBRACKETS
))
5624 case DI_USERCONTROL
:
5625 // Len=CurItem->Ptr.PtrLength; BUGBUG
5632 case DI_RADIOBUTTON
:
5633 Len
= StrLength(Ptr
) + 1;
5641 if (CurItem
->ObjPtr
) {
5642 Len
= ((DlgEdit
*)(CurItem
->ObjPtr
))->GetLength() + 1;
5648 MenuItemEx
*ListMenuItem
;
5650 if ((ListMenuItem
= CurItem
->ListPtr
->GetItemPtr(-1))) {
5651 Len
= (int)ListMenuItem
->strName
.GetLength() + 1;
5661 return Len
- (!Len
? 0 : 1);
5663 /*****************************************************************/
5664 case DM_SETTEXTPTR
: {
5668 FarDialogItemData IData
= {(size_t)StrLength((wchar_t *)Param2
), (wchar_t *)Param2
};
5669 return SendDlgMessage(hDlg
, DM_SETTEXT
, Param1
, (LONG_PTR
)&IData
);
5672 case DM_SETTEXTPTRSILENT
: {
5676 if (CurItem
->Type
!= DI_FIXEDIT
&& CurItem
->Type
!= DI_EDIT
)
5679 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(false);
5680 FarDialogItemData IData
= {(size_t)StrLength((wchar_t *)Param2
), (wchar_t *)Param2
};
5681 intptr_t rv
= SendDlgMessage(hDlg
, DM_SETTEXT
, Param1
, (LONG_PTR
)&IData
);
5682 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(true);
5687 /*****************************************************************/
5690 int NeedInit
= TRUE
;
5691 FarDialogItemData
*did
= (FarDialogItemData
*)Param2
;
5704 case DI_RADIOBUTTON
:
5707 case DI_LISTBOX
: // меняет только текущий итем
5708 CurItem
->strData
= did
->PtrData
;
5709 Len
= (int)CurItem
->strData
.GetLength();
5717 case DI_USERCONTROL
:
5718 /*CurItem->Ptr.PtrLength=did->PtrLength;
5719 CurItem->Ptr.PtrData=did->PtrData;
5720 return CurItem->Ptr.PtrLength;*/
5727 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5728 if (!Dlg
->DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
5729 ConsoleTitle::SetFarTitle(Dlg
->GetDialogTitle());
5730 Dlg
->ShowDialog(Param1
);
5734 return Len
- (!Len
? 0 : 1);
5737 case DI_RADIOBUTTON
:
5747 if (CurItem
->ObjPtr
) {
5748 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
5749 int ReadOnly
= EditLine
->GetReadOnly();
5750 EditLine
->SetReadOnly(0);
5751 EditLine
->DisableAC();
5752 EditLine
->SetString(CurItem
->strData
);
5753 EditLine
->RevertAC();
5754 EditLine
->SetReadOnly(ReadOnly
);
5756 if (Dlg
->DialogMode
.Check(DMODE_INITOBJECTS
)) // не меняем клеар-флаг, пока не проиницализировались
5757 EditLine
->SetClearFlag(0);
5759 EditLine
->Select(-1, 0); // снимаем выделение
5760 // ...оно уже снимается в DlgEdit::SetString()
5764 case DI_LISTBOX
: // меняет только текущий итем
5766 VMenu
*ListBox
= CurItem
->ListPtr
;
5769 FarListUpdate LUpdate
;
5770 LUpdate
.Index
= ListBox
->GetSelectPos();
5771 MenuItemEx
*ListMenuItem
= ListBox
->GetItemPtr(LUpdate
.Index
);
5774 LUpdate
.Item
.Flags
= ListMenuItem
->Flags
;
5775 LUpdate
.Item
.Text
= Ptr
;
5776 SendDlgMessage(hDlg
, DM_LISTUPDATE
, Param1
, (LONG_PTR
)&LUpdate
);
5783 default: // подразумеваем, что остались
5788 Dlg
->InitDialogObjects(Param1
); // переинициализируем элементы диалога
5790 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) // достаточно ли этого????!!!!
5792 Dlg
->ShowDialog(Param1
);
5796 // CurItem->strData = did->PtrData;
5797 return CurItem
->strData
.GetLength(); //???
5802 /*****************************************************************/
5803 case DM_SETMAXTEXTLENGTH
: {
5804 if ((Type
== DI_EDIT
|| Type
== DI_PSWEDIT
5805 || (Type
== DI_COMBOBOX
&& !(CurItem
->Flags
& DIF_DROPDOWNLIST
)))
5806 && CurItem
->ObjPtr
) {
5807 int MaxLen
= ((DlgEdit
*)(CurItem
->ObjPtr
))->GetMaxLength();
5808 // BugZ#628 - Неправильная длина редактируемого текста.
5809 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetMaxLength((int)Param2
);
5810 // if (DialogMode.Check(DMODE_INITOBJECTS)) //???
5811 Dlg
->InitDialogObjects(Param1
); // переинициализируем элементы диалога
5812 if (!Dlg
->DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
5813 ConsoleTitle::SetFarTitle(Dlg
->GetDialogTitle());
5819 /*****************************************************************/
5820 case DM_GETDLGITEM
: {
5821 FarDialogItem
*Item
= (FarDialogItem
*)Param2
;
5822 return (LONG_PTR
)ConvertItemEx2(Item
, CurItem
);
5824 /*****************************************************************/
5825 case DM_GETDLGITEMSHORT
: {
5826 if (Param2
&& ConvertItemEx(CVTITEM_TOPLUGINSHORT
, (FarDialogItem
*)Param2
, CurItem
, 1))
5830 /*****************************************************************/
5832 case DM_SETDLGITEMSHORT
: {
5836 if (Type
!= ((FarDialogItem
*)Param2
)->Type
) // пока нефига менять тип
5840 if (!ConvertItemEx((Msg
== DM_SETDLGITEM
) ? CVTITEM_FROMPLUGIN
: CVTITEM_FROMPLUGINSHORT
,
5841 (FarDialogItem
*)Param2
, CurItem
, 1))
5842 return FALSE
; // invalid parameters
5844 CurItem
->Type
= Type
;
5846 if ((Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) && CurItem
->ListPtr
)
5847 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
5849 // еще разок, т.к. данные могли быть изменены
5850 Dlg
->InitDialogObjects(Param1
);
5851 if (!Dlg
->DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
5852 ConsoleTitle::SetFarTitle(Dlg
->GetDialogTitle());
5854 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5855 Dlg
->ShowDialog(Param1
);
5861 /*****************************************************************/
5864 + показать/скрыть элемент
5866 -1 - получить состояние
5869 Return: предыдущее состояние
5872 DWORD PrevFlags
= CurItem
->Flags
;
5876 CurItem
->Flags
&= ~DIF_HIDDEN
;
5878 CurItem
->Flags
|= DIF_HIDDEN
;
5880 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) // && (PrevFlags&DIF_HIDDEN) != (CurItem->Flags&DIF_HIDDEN))//!(CurItem->Flags&DIF_HIDDEN))
5882 if ((CurItem
->Flags
& DIF_HIDDEN
) && Dlg
->FocusPos
== (unsigned)Param1
) {
5883 Param2
= Dlg
->ChangeFocus(Param1
, 1, TRUE
);
5884 Dlg
->ChangeFocus2((int)Param2
);
5887 // Либо все, либо... только 1
5888 Dlg
->ShowDialog(Dlg
->GetDropDownOpened() || (CurItem
->Flags
& DIF_HIDDEN
) ? -1 : Param1
);
5893 return (PrevFlags
& DIF_HIDDEN
) ? FALSE
: TRUE
;
5895 /*****************************************************************/
5896 case DM_SETDROPDOWNOPENED
: // Param1=ID; Param2={TRUE|FALSE}
5898 if (!Param2
) // Закрываем любой открытый комбобокс или историю
5900 if (Dlg
->GetDropDownOpened()) {
5901 Dlg
->SetDropDownOpened(FALSE
);
5909 у DI_PSWEDIT не бывает хистори!
5912 && (Type
== DI_COMBOBOX
5913 || ((Type
== DI_EDIT
|| Type
== DI_FIXEDIT
) && (CurItem
->Flags
& DIF_HISTORY
)))) /* DJ $ */
5915 // Открываем заданный в Param1 комбобокс или историю
5916 if (Dlg
->GetDropDownOpened()) {
5917 Dlg
->SetDropDownOpened(FALSE
);
5921 if (SendDlgMessage(hDlg
, DM_SETFOCUS
, Param1
, 0)) {
5922 Dlg
->ProcessOpenComboBox(Type
, CurItem
, Param1
); //?? Param1 ??
5923 // Dlg->ProcessKey(KEY_CTRLDOWN);
5932 /*****************************************************************/
5933 case DM_SETITEMPOSITION
: // Param1 = ID; Param2 = SMALL_RECT
5935 return Dlg
->SetItemRect((int)Param1
, (SMALL_RECT
*)Param2
);
5937 /*****************************************************************/
5940 + переключение/получение состояния Enable/Disable элемента
5943 DWORD PrevFlags
= CurItem
->Flags
;
5947 CurItem
->Flags
&= ~DIF_DISABLE
;
5949 CurItem
->Flags
|= DIF_DISABLE
;
5951 if ((Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) && CurItem
->ListPtr
)
5952 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
5955 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) //???
5957 Dlg
->ShowDialog(Param1
);
5961 return (PrevFlags
& DIF_DISABLE
) ? FALSE
: TRUE
;
5965 *(DWORD
*)Param2
= (DWORD
)Dlg
->CtlColorDlgItem(Param1
, CurItem
);
5966 *(DWORD
*)Param2
|= (CurItem
->Flags
& DIF_SETCOLOR
);
5971 CurItem
->Flags
&= ~(DIF_SETCOLOR
| DIF_COLORMASK
);
5972 CurItem
->Flags
|= Param2
& (DIF_SETCOLOR
| DIF_COLORMASK
);
5974 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) { //???
5975 Dlg
->ShowDialog(Param1
);
5982 case DM_GETTRUECOLOR
: {
5983 if (!CurItem
->TrueColors
) {
5984 memset((DialogItemTrueColors
*)Param2
, 0, sizeof(DialogItemTrueColors
));
5986 *(DialogItemTrueColors
*)Param2
= *CurItem
->TrueColors
;
5991 case DM_SETTRUECOLOR
: {
5992 if (!CurItem
->TrueColors
) {
5993 CurItem
->TrueColors
.reset(new DialogItemTrueColors
);
5995 *CurItem
->TrueColors
= *(const DialogItemTrueColors
*)Param2
;
5996 if (Dlg
->InCtlColorDlgItem
== 0 && Dlg
->DialogMode
.Check(DMODE_SHOW
)) { //???
5997 Dlg
->ShowDialog(Param1
);
6003 case DM_SETREADONLY
: {
6005 CurItem
->Flags
|= DIF_READONLY
;
6007 CurItem
->Flags
&= ~DIF_READONLY
;
6009 if (FarIsEdit(Type
)) {
6010 DlgEdit
*CurItemEdit
= (DlgEdit
*)CurItem
->ObjPtr
;
6012 CurItemEdit
->SetReadOnly(Param2
? 1 : 0);
6016 "%s: DM_SETREADONLY invoked for non-edit item %u\n",
6017 __FUNCTION__
, Param1
);
6019 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) { //???
6020 Dlg
->ShowDialog(Param1
);
6026 /*****************************************************************/
6027 // получить позицию и размеры контрола
6028 case DM_GETITEMPOSITION
: // Param1=ID, Param2=*SMALL_RECT
6032 if (Dlg
->GetItemRect(Param1
, Rect
)) {
6033 *reinterpret_cast<PSMALL_RECT
>(Param2
) = Rect
;
6039 /*****************************************************************/
6040 case DM_SETITEMDATA
: {
6041 LONG_PTR PrewDataDialog
= CurItem
->UserData
;
6042 CurItem
->UserData
= Param2
;
6043 return PrewDataDialog
;
6045 /*****************************************************************/
6046 case DM_GETITEMDATA
: {
6047 return CurItem
->UserData
;
6049 /*****************************************************************/
6050 case DM_EDITUNCHANGEDFLAG
: // -1 Get, 0 - Skip, 1 - Set; Выделение блока снимается.
6052 if (FarIsEdit(Type
)) {
6053 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
6054 int ClearFlag
= EditLine
->GetClearFlag();
6057 EditLine
->SetClearFlag((int)Param2
);
6058 EditLine
->Select(-1, 0); // снимаем выделение
6060 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) //???
6062 Dlg
->ShowDialog(Param1
);
6072 /*****************************************************************/
6073 case DM_GETSELECTION
: // Msg=DM_GETSELECTION, Param1=ID, Param2=*EditorSelect
6074 case DM_SETSELECTION
: // Msg=DM_SETSELECTION, Param1=ID, Param2=*EditorSelect
6076 if (FarIsEdit(Type
) && Param2
) {
6077 if (Msg
== DM_GETSELECTION
) {
6078 EditorSelect
*EdSel
= (EditorSelect
*)Param2
;
6079 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
6080 EdSel
->BlockStartLine
= 0;
6081 EdSel
->BlockHeight
= 1;
6082 EditLine
->GetSelection(EdSel
->BlockStartPos
, EdSel
->BlockWidth
);
6084 if (EdSel
->BlockStartPos
== -1 && !EdSel
->BlockWidth
)
6085 EdSel
->BlockType
= BTYPE_NONE
;
6087 EdSel
->BlockType
= BTYPE_STREAM
;
6088 EdSel
->BlockWidth
-= EdSel
->BlockStartPos
;
6094 EditorSelect
*EdSel
= (EditorSelect
*)Param2
;
6095 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
6097 // EdSel->BlockType=BTYPE_STREAM;
6098 // EdSel->BlockStartLine=0;
6099 // EdSel->BlockHeight=1;
6100 if (EdSel
->BlockType
== BTYPE_NONE
)
6101 EditLine
->Select(-1, 0);
6103 EditLine
->Select(EdSel
->BlockStartPos
, EdSel
->BlockStartPos
+ EdSel
->BlockWidth
);
6105 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) //???
6107 Dlg
->ShowDialog(Param1
);
6120 // Все, что сами не отрабатываем - посылаем на обработку обработчику.
6121 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
6126 Посылка сообщения диалогу
6127 Некоторые сообщения эта функция обрабатывает сама, не передавая управление
6128 обработчику диалога.
6130 LONG_PTR WINAPI
SendDlgMessage(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
6135 return InterThreadCall
<LONG_PTR
, 0>(std::bind(SendDlgMessageSynched
, hDlg
, Msg
, Param1
, Param2
));
6138 void Dialog::SetPosition(int X1
, int Y1
, int X2
, int Y2
)
6140 CriticalSectionLock
Lock(CS
);
6143 RealWidth
= X2
- X1
+ 1;
6148 RealHeight
= Y2
- Y1
+ 1;
6152 ScreenObject::SetPosition(X1
, Y1
, X2
, Y2
);
6154 //////////////////////////////////////////////////////////////////////////
6155 BOOL
Dialog::IsInited()
6157 CriticalSectionLock
Lock(CS
);
6158 return DialogMode
.Check(DMODE_INITOBJECTS
);
6161 void Dialog::SetComboBoxPos(DialogItemEx
*CurItem
)
6163 if (GetDropDownOpened()) {
6165 CurItem
= Item
[FocusPos
];
6167 int EditX1
, EditY1
, EditX2
, EditY2
;
6168 ((DlgEdit
*)CurItem
->ObjPtr
)->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
6170 if (EditX2
- EditX1
< 20)
6171 EditX2
= EditX1
+ 20;
6173 if (ScrY
- EditY1
< Min(Opt
.Dialogs
.CBoxMaxHeight
, CurItem
->ListPtr
->GetItemCount()) + 2
6174 && EditY1
> ScrY
/ 2)
6175 CurItem
->ListPtr
->SetPosition(EditX1
,
6176 Max(0, EditY1
- 1 - Min(Opt
.Dialogs
.CBoxMaxHeight
, CurItem
->ListPtr
->GetItemCount()) - 1),
6177 EditX2
, EditY1
- 1);
6179 CurItem
->ListPtr
->SetPosition(EditX1
, EditY1
+ 1, EditX2
, 0);
6183 bool Dialog::ProcessEvents()
6185 return !DialogMode
.Check(DMODE_ENDLOOP
);
6188 void Dialog::SetId(const GUID
&Id
)