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 * check if dialog element can be focused
99 static inline bool IsItemFocusable(const struct DialogItemEx
* item
)
113 return !(item
->Flags
& (DIF_NOFOCUS
| DIF_DISABLE
| DIF_HIDDEN
));
120 * check if dialog item is horizontal separator.
122 static inline bool IsItemHorizontalSeparator(const struct DialogItemEx
* item
)
124 return (item
->Type
== DI_SINGLEBOX
|| item
->Type
== DI_DOUBLEBOX
||
125 (item
->Type
== DI_TEXT
&& (item
->Flags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
| DIF_SEPARATORUSER
))));
129 * check if dialog item is vertical separator.
131 static inline bool IsItemVerticalSeparator(const struct DialogItemEx
* item
)
133 return (item
->Type
== DI_SINGLEBOX
|| item
->Type
== DI_DOUBLEBOX
||
134 (item
->Type
== DI_VTEXT
&& (item
->Flags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
| DIF_SEPARATORUSER
))));
137 bool IsKeyHighlighted(const wchar_t *Str
, FarKey Key
, int Translate
, int AmpPos
)
140 if (!(Str
= wcschr(Str
, L
'&')))
145 if (AmpPos
>= StrLength(Str
))
151 if (Str
[AmpPos
] == L
'&')
155 wchar_t UpperStrKey
= Upper(Str
[AmpPos
]);
157 if (WCHAR_IS_VALID(Key
)) {
158 return UpperStrKey
== Upper(Key
) || (Translate
&& KeyToKeyLayoutCompare(Upper(Key
), UpperStrKey
));
162 uint32_t AltKey
= Key
& (~KEY_ALT
);
164 if (WCHAR_IS_VALID(AltKey
)) {
165 if (iswdigit(AltKey
) != 0)
166 return (AltKey
== (uint32_t)UpperStrKey
);
169 // (AltKey=='-' || AltKey=='/' || AltKey==',' || AltKey=='.' ||
170 // AltKey=='\\' || AltKey=='=' || AltKey=='[' || AltKey==']' ||
171 // AltKey==':' || AltKey=='"' || AltKey=='~'))
173 return (UpperStrKey
== Upper(AltKey
)
174 || (Translate
&& KeyToKeyLayoutCompare(AltKey
, UpperStrKey
)));
182 void DialogItemExToDialogItemEx(DialogItemEx
*pSrc
, DialogItemEx
*pDest
)
184 pDest
->Type
= pSrc
->Type
;
185 pDest
->X1
= pSrc
->X1
;
186 pDest
->Y1
= pSrc
->Y1
;
187 pDest
->X2
= pSrc
->X2
;
188 pDest
->Y2
= pSrc
->Y2
;
189 pDest
->Focus
= pSrc
->Focus
;
190 pDest
->Reserved
= pSrc
->Reserved
;
191 pDest
->strHistory
= pSrc
->strHistory
;
192 pDest
->strMask
= pSrc
->strMask
;
193 pDest
->Flags
= pSrc
->Flags
;
194 pDest
->DefaultButton
= pSrc
->DefaultButton
;
195 pDest
->nMaxLength
= 0;
196 pDest
->strData
= pSrc
->strData
;
197 pDest
->ID
= pSrc
->ID
;
198 pDest
->IFlags
= pSrc
->IFlags
;
199 pDest
->AutoCount
= pSrc
->AutoCount
;
200 pDest
->AutoPtr
= pSrc
->AutoPtr
;
201 pDest
->UserData
= pSrc
->UserData
;
202 pDest
->ObjPtr
= pSrc
->ObjPtr
;
203 pDest
->ListPtr
= pSrc
->ListPtr
;
204 pDest
->UCData
= pSrc
->UCData
;
205 pDest
->SelStart
= pSrc
->SelStart
;
206 pDest
->SelEnd
= pSrc
->SelEnd
;
208 pDest
->customItemColor
[0] = pSrc
->customItemColor
[0];
209 pDest
->customItemColor
[1] = pSrc
->customItemColor
[1];
210 pDest
->customItemColor
[2] = pSrc
->customItemColor
[2];
211 pDest
->customItemColor
[3] = pSrc
->customItemColor
[3];
214 void ConvertItemSmall(FarDialogItem
*Item
, DialogItemEx
*Data
)
216 Item
->Type
= Data
->Type
;
221 Item
->Focus
= Data
->Focus
;
222 Item
->Flags
= Data
->Flags
;
223 Item
->DefaultButton
= Data
->DefaultButton
;
224 Item
->MaxLen
= Data
->nMaxLength
;
225 Item
->PtrData
= nullptr;
227 Item
->Param
.History
= nullptr;
228 if (Data
->Type
== DI_LISTBOX
|| Data
->Type
== DI_COMBOBOX
) {
229 Item
->Param
.ListPos
= Data
->ListPtr
? Data
->ListPtr
->GetSelectPos() : 0;
231 if ((Data
->Type
== DI_EDIT
|| Data
->Type
== DI_FIXEDIT
) && Data
->Flags
& DIF_HISTORY
) {
232 Item
->Param
.History
= Data
->strHistory
;
233 } else if (Data
->Type
== DI_FIXEDIT
&& Data
->Flags
& DIF_MASKEDIT
) {
234 Item
->Param
.Mask
= Data
->strMask
;
236 Item
->Param
.Reserved
= Data
->Reserved
;
240 size_t ItemStringAndSize(DialogItemEx
*Data
, FARString
&ItemString
)
243 if (FarIsEdit(Data
->Type
) && (EditPtr
= (DlgEdit
*)(Data
->ObjPtr
)) != nullptr)
244 EditPtr
->GetString(ItemString
);
246 ItemString
= Data
->strData
;
248 size_t sz
= ItemString
.GetLength();
250 if (sz
> Data
->nMaxLength
&& Data
->nMaxLength
> 0)
251 sz
= Data
->nMaxLength
;
256 bool ConvertItemEx(CVTITEMFLAGS FromPlugin
, FarDialogItem
*Item
, DialogItemEx
*Data
, unsigned Count
)
263 switch (FromPlugin
) {
264 case CVTITEM_TOPLUGIN
:
265 case CVTITEM_TOPLUGINSHORT
:
267 for (I
= 0; I
< Count
; I
++, ++Item
, ++Data
) {
268 ConvertItemSmall(Item
, Data
);
270 if (FromPlugin
== CVTITEM_TOPLUGIN
) {
272 size_t sz
= ItemStringAndSize(Data
, str
);
274 wchar_t *p
= (wchar_t *)malloc((sz
+ 1) * sizeof(wchar_t));
277 if (!p
) // TODO: may be needed message?
280 wmemcpy(p
, str
.CPtr(), sz
);
287 case CVTITEM_FROMPLUGIN
:
288 case CVTITEM_FROMPLUGINSHORT
:
290 for (I
= 0; I
< Count
; I
++, ++Item
, ++Data
) {
295 Data
->Focus
= Item
->Focus
;
297 if ((Item
->Type
== DI_EDIT
|| Item
->Type
== DI_FIXEDIT
) && Item
->Flags
& DIF_HISTORY
) {
298 Data
->strHistory
= Item
->Param
.History
;
299 } else if (Item
->Type
== DI_FIXEDIT
&& Item
->Flags
& DIF_MASKEDIT
) {
300 Data
->strMask
= Item
->Param
.Mask
;
302 Data
->Reserved
= Item
->Param
.Reserved
;
304 Data
->Flags
= Item
->Flags
;
305 Data
->DefaultButton
= Item
->DefaultButton
;
306 Data
->Type
= Item
->Type
;
308 if (FromPlugin
== CVTITEM_FROMPLUGIN
) {
309 Data
->strData
= Item
->PtrData
;
310 Data
->nMaxLength
= Item
->MaxLen
;
312 if (Data
->nMaxLength
> 0)
313 Data
->strData
.Truncate(Data
->nMaxLength
);
316 Data
->ListItems
= Item
->Param
.ListItems
;
318 if (Data
->X2
< Data
->X1
)
321 if (Data
->Y2
< Data
->Y1
)
324 if ((Data
->Type
== DI_COMBOBOX
|| Data
->Type
== DI_LISTBOX
) && !IsPtr(Item
->Param
.ListItems
))
325 Data
->ListItems
= nullptr;
334 size_t ConvertItemEx2(FarDialogItem
*Item
, DialogItemEx
*Data
)
336 size_t size
= sizeof(*Item
);
338 size_t sz
= ItemStringAndSize(Data
, str
);
339 size
+= (sz
+ 1) * sizeof(wchar_t);
342 ConvertItemSmall(Item
, Data
);
344 wchar_t *p
= (wchar_t *)(Item
+ 1);
346 wmemcpy(p
, str
.CPtr(), sz
);
353 void DataToItemEx(const DialogDataEx
*Data
, DialogItemEx
*Item
, int Count
)
358 for (int i
= 0; i
< Count
; i
++) {
360 Item
[i
].ID
= static_cast<WORD
>(i
);
361 Item
[i
].Type
= Data
[i
].Type
;
362 Item
[i
].X1
= Data
[i
].X1
;
363 Item
[i
].Y1
= Data
[i
].Y1
;
364 Item
[i
].X2
= Data
[i
].X2
;
365 Item
[i
].Y2
= Data
[i
].Y2
;
367 Item
[i
].customItemColor
[0] = 0;
368 Item
[i
].customItemColor
[1] = 0;
369 Item
[i
].customItemColor
[2] = 0;
370 Item
[i
].customItemColor
[3] = 0;
372 if (Item
[i
].X2
< Item
[i
].X1
)
373 Item
[i
].X2
= Item
[i
].X1
;
375 if (Item
[i
].Y2
< Item
[i
].Y1
)
376 Item
[i
].Y2
= Item
[i
].Y1
;
379 Item
[i
].Type
!= DI_SINGLEBOX
&& Item
[i
].Type
!= DI_DOUBLEBOX
&& (Data
[i
].Flags
& DIF_FOCUS
);
380 if ((Data
[i
].Type
== DI_EDIT
|| Data
[i
].Type
== DI_FIXEDIT
) && Data
[i
].Flags
& DIF_HISTORY
) {
381 Item
[i
].strHistory
= Data
[i
].History
;
382 } else if (Data
[i
].Type
== DI_FIXEDIT
&& Data
[i
].Flags
& DIF_MASKEDIT
) {
383 Item
[i
].strMask
= Data
[i
].Mask
;
385 Item
[i
].Reserved
= Data
[i
].Reserved
;
387 Item
[i
].Flags
= Data
[i
].Flags
;
388 Item
[i
].DefaultButton
=
389 Item
[i
].Type
!= DI_TEXT
&& Item
[i
].Type
!= DI_VTEXT
&& (Data
[i
].Flags
& DIF_DEFAULT
);
390 Item
[i
].SelStart
= -1;
392 if (!IsPtr(Data
[i
].Data
)) // awful
393 Item
[i
].strData
= FarLangMsg
{(int)(DWORD_PTR
)Data
[i
].Data
};
395 Item
[i
].strData
= Data
[i
].Data
;
399 Dialog::Dialog(DialogItemEx
*SrcItem
, // Набор элементов диалога
400 unsigned SrcItemCount
, // Количество элементов
401 FARWINDOWPROC DlgProc
, // Диалоговая процедура
402 LONG_PTR InitParam
) // Ассоцированные с диалогом данные
406 Dialog::Item
= (DialogItemEx
**)malloc(sizeof(DialogItemEx
*) * SrcItemCount
);
408 for (unsigned i
= 0; i
< SrcItemCount
; i
++) {
409 Dialog::Item
[i
] = new DialogItemEx
;
410 Dialog::Item
[i
]->Clear();
411 DialogItemExToDialogItemEx(&SrcItem
[i
], Dialog::Item
[i
]);
414 Dialog::ItemCount
= SrcItemCount
;
415 Dialog::pSaveItemEx
= SrcItem
;
416 Init(DlgProc
, InitParam
);
419 Dialog::Dialog(FarDialogItem
*SrcItem
, // Набор элементов диалога
420 unsigned SrcItemCount
, // Количество элементов
421 FARWINDOWPROC DlgProc
, // Диалоговая процедура
422 LONG_PTR InitParam
) // Ассоцированные с диалогом данные
426 Dialog::Item
= (DialogItemEx
**)malloc(sizeof(DialogItemEx
*) * SrcItemCount
);
428 for (unsigned i
= 0; i
< SrcItemCount
; i
++) {
429 Dialog::Item
[i
] = new DialogItemEx
;
430 Dialog::Item
[i
]->Clear();
431 // BUGBUG add error check
432 ConvertItemEx(CVTITEM_FROMPLUGIN
, &SrcItem
[i
], Dialog::Item
[i
], 1);
435 Dialog::ItemCount
= SrcItemCount
;
436 Dialog::pSaveItemEx
= nullptr;
437 Init(DlgProc
, InitParam
);
440 void Dialog::Init(FARWINDOWPROC DlgProc
, // Диалоговая процедура
441 LONG_PTR InitParam
) // Ассоцированные с диалогом данные
443 SetDynamicallyBorn(FALSE
); // $OT: По умолчанию все диалоги создаются статически
444 CanLoseFocus
= FALSE
;
446 // Номер плагина, вызвавшего диалог (-1 = Main)
448 Dialog::DataDialog
= InitParam
;
449 DialogMode
.Set(DMODE_ISCANMOVE
);
450 SetDropDownOpened(FALSE
);
452 InCtlColorDlgItem
= 0;
453 FocusPos
= (unsigned)-1;
454 PrevFocusPos
= (unsigned)-1;
456 if (!DlgProc
) // функция должна быть всегда!!!
458 DlgProc
= DefDlgProc
;
459 // знать диалог в старом стиле - учтем этот факт!
460 DialogMode
.Set(DMODE_OLDSTYLE
);
463 Dialog::RealDlgProc
= DlgProc
;
465 //_SVS(SysLog(L"Dialog =%d",CtrlObject->Macro.GetMode()));
466 // запоминаем предыдущий заголовок консоли
467 OldTitle
= new ConsoleTitle
;
469 memset(&Id
, 0, sizeof(Id
));
472 //////////////////////////////////////////////////////////////////////////
475 Деструктор класса Dialog
479 _tran(SysLog(L
"[%p] Dialog::~Dialog()", this));
481 DeleteDialogObjects();
489 for (unsigned i
= 0; i
< ItemCount
; i
++)
495 if (!WinPortTesting()) {
497 PeekInputRecord(&rec
);
500 _DIALOG(CleverSysLog
CL(L
"Destroy Dialog"));
503 void Dialog::CheckDialogCoord()
505 CriticalSectionLock
Lock(CS
);
507 if (X1
== -1) // задано центрирование диалога по горизонтали?
508 { // X2 при этом = ширине диалога.
509 X1
= (ScrX
- X2
+ 1) / 2;
511 if (X1
< 0) // ширина диалога больше ширины экрана?
519 if (Y1
== -1) // задано центрирование диалога по вертикали?
520 { // Y2 при этом = высоте диалога.
521 Y1
= (ScrY
- Y2
+ 1) / 2;
523 if (!DialogMode
.Check(DMODE_SMALLDIALOG
)) //????
535 void Dialog::InitDialog()
537 CriticalSectionLock
Lock(CS
);
539 if (!DialogMode
.Check(DMODE_INITOBJECTS
)) // самодостаточный вариант, когда
540 { // элементы инициализируются при первом вызове.
542 unsigned InitFocus
= InitDialogObjects();
543 int Result
= (int)DlgProc((HANDLE
)this, DN_INITDIALOG
, InitFocus
, DataDialog
);
545 if (ExitCode
== -1) {
547 // еще разок, т.к. данные могли быть изменены
548 InitFocus
= InitDialogObjects(); // InitFocus=????
551 if (!DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
552 ConsoleTitle::SetFarTitle(GetDialogTitle());
555 // все объекты проинициализированы!
556 DialogMode
.Set(DMODE_INITOBJECTS
);
557 DialogInfo di
= {sizeof(di
)};
559 if (DlgProc(reinterpret_cast<HANDLE
>(this), DN_GETDIALOGINFO
, 0, reinterpret_cast<LONG_PTR
>(&di
))) {
564 DlgProc((HANDLE
)this, DN_GOTFOCUS
, InitFocus
, 0);
568 //////////////////////////////////////////////////////////////////////////
571 Расчет значений координат окна диалога и вызов функции
572 ScreenObject::Show() для вывода диалога на экран.
576 CriticalSectionLock
Lock(CS
);
577 _tran(SysLog(L
"[%p] Dialog::Show()", this));
579 if (!DialogMode
.Check(DMODE_INITOBJECTS
))
582 if (!Locked() && DialogMode
.Check(DMODE_RESIZED
)) {
583 PreRedrawItem preRedrawItem
= PreRedraw
.Peek();
585 if (preRedrawItem
.PreRedrawFunc
)
586 preRedrawItem
.PreRedrawFunc();
589 DialogMode
.Clear(DMODE_RESIZED
);
594 DialogMode
.Set(DMODE_SHOW
);
595 ScreenObject::Show();
598 // Цель перехвата данной функции - управление видимостью...
601 CriticalSectionLock
Lock(CS
);
602 _tran(SysLog(L
"[%p] Dialog::Hide()", this));
604 if (!DialogMode
.Check(DMODE_INITOBJECTS
))
607 DialogMode
.Clear(DMODE_SHOW
);
608 ScreenObject::Hide();
611 //////////////////////////////////////////////////////////////////////////
614 Инициализация объектов и вывод диалога на экран.
616 void Dialog::DisplayObject()
618 CriticalSectionLock
Lock(CS
);
620 if (DialogMode
.Check(DMODE_SHOW
)) {
621 ChangePriority
ChPriority(ChangePriority::NORMAL
);
622 ShowDialog(); // "нарисуем" диалог
626 // пересчитать координаты для элементов с DIF_CENTERGROUP
627 void Dialog::ProcessCenterGroup()
629 CriticalSectionLock
Lock(CS
);
631 for (unsigned I
= 0; I
< ItemCount
; I
++) {
633 Последовательно объявленные элементы с флагом DIF_CENTERGROUP
634 и одинаковой вертикальной позицией будут отцентрированы в диалоге.
635 Их координаты X не важны. Удобно использовать для центрирования
638 if ((Item
[I
]->Flags
& DIF_CENTERGROUP
)
639 && (I
== 0 || (Item
[I
- 1]->Flags
& DIF_CENTERGROUP
) == 0
640 || Item
[I
- 1]->Y1
!= Item
[I
]->Y1
)) {
644 J
< ItemCount
&& (Item
[J
]->Flags
& DIF_CENTERGROUP
) && Item
[J
]->Y1
== Item
[I
]->Y1
; J
++) {
645 Length
+= LenStrItem(J
);
647 if (!Item
[J
]->strData
.IsEmpty())
648 switch (Item
[J
]->Type
) {
659 if (!Item
[I
]->strData
.IsEmpty())
660 switch (Item
[I
]->Type
) {
668 } // Бля, це ж ботва какая-то
670 int StartX
= Max(0, (X2
- X1
+ 1 - Length
) / 2);
673 J
< ItemCount
&& (Item
[J
]->Flags
& DIF_CENTERGROUP
) && Item
[J
]->Y1
== Item
[I
]->Y1
; J
++) {
674 Item
[J
]->X1
= StartX
;
675 StartX
+= LenStrItem(J
);
677 if (!Item
[J
]->strData
.IsEmpty())
678 switch (Item
[J
]->Type
) {
688 if (StartX
== Item
[J
]->X1
)
689 Item
[J
]->X2
= StartX
;
691 Item
[J
]->X2
= StartX
- 1;
697 //////////////////////////////////////////////////////////////////////////
700 Инициализация элементов диалога.
702 InitDialogObjects возвращает ID элемента с фокусом ввода
703 Параметр - для выборочной реинициализации элементов. ID = -1 - касаемо всех объектов
706 TODO: Необходимо применить ProcessRadioButton для исправления
707 кривых рук некоторых плагинописателей (а надо?)
709 unsigned Dialog::InitDialogObjects(unsigned ID
)
711 CriticalSectionLock
Lock(CS
);
714 DialogItemEx
*CurItem
;
715 unsigned InitItemCount
;
717 _DIALOG(CleverSysLog
CL(L
"Init Dialog"));
719 if (ID
== (unsigned)-1) // инициализируем все?
722 InitItemCount
= ItemCount
;
723 } else if (ID
+ 1 > ItemCount
) {
726 InitItemCount
= ID
+ 1;
729 // если FocusPos в пределах и элемент задисаблен, то ищем сначала
730 if (FocusPos
!= (unsigned)-1 && FocusPos
< ItemCount
&& !IsItemFocusable(Item
[FocusPos
]))
731 FocusPos
= (unsigned)-1; // будем искать сначала!
733 // предварительный цикл по поводу кнопок
734 for (I
= ID
; I
< InitItemCount
; I
++) {
736 ItemFlags
= CurItem
->Flags
;
737 Type
= CurItem
->Type
;
739 if (Type
== DI_BUTTON
&& ItemFlags
& DIF_SETSHIELD
) {
740 CurItem
->strData
= FARString(L
"\x2580\x2584 ") + CurItem
->strData
;
744 для кнопок не имеющи стиля "Показывает заголовок кнопки без скобок"
745 добавим энти самые скобки
747 if (Type
== DI_BUTTON
&& !(ItemFlags
& DIF_NOBRACKETS
)) {
748 LPCWSTR Brackets
[] = {L
"[ ", L
" ]", L
"{ ", L
" }"};
749 int Start
= (CurItem
->DefaultButton
? 2 : 0);
750 if (CurItem
->strData
.At(0) != *Brackets
[Start
]) {
751 CurItem
->strData
= Brackets
[Start
] + CurItem
->strData
+ Brackets
[Start
+ 1];
754 // предварительный поик фокуса
755 if (FocusPos
== (unsigned)-1 && IsItemFocusable(CurItem
) && CurItem
->Focus
)
756 FocusPos
= I
; // запомним первый фокусный элемент
758 CurItem
->Focus
= 0; // сбросим для всех, чтобы не оказалось,
759 // что фокусов - как у дурочка фантиков
761 // сбросим флаг DIF_CENTERGROUP для редакторов
767 case DI_VTEXT
: // ????
771 if (ItemFlags
& DIF_CENTERGROUP
)
772 CurItem
->Flags
&= ~DIF_CENTERGROUP
;
777 Опять про фокус ввода - теперь, если "чудо" забыло выставить
778 хотя бы один, то ставим на первый подходящий
780 if (FocusPos
== (unsigned)-1) {
781 for (I
= 0; I
< ItemCount
; I
++) // по всем!!!!
785 if (IsItemFocusable(CurItem
)) {
792 if (FocusPos
== (unsigned)-1) // ну ни хрена себе - нет ни одного
793 { // элемента с возможностью фокуса
794 FocusPos
= 0; // убится, блин
797 // ну вот и добрались до!
798 Item
[FocusPos
]->Focus
= 1;
799 // а теперь все сначала и по полной программе...
800 ProcessCenterGroup(); // сначала отцентрируем
802 for (I
= ID
; I
< InitItemCount
; I
++) {
804 Type
= CurItem
->Type
;
805 ItemFlags
= CurItem
->Flags
;
807 if (Type
== DI_LISTBOX
) {
808 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
809 CurItem
->ListPtr
= new VMenu(nullptr, nullptr, 0, CurItem
->Y2
- CurItem
->Y1
+ 1,
810 VMENU_ALWAYSSCROLLBAR
| VMENU_LISTBOX
, nullptr, this);
813 if (CurItem
->ListPtr
) {
814 VMenu
*ListPtr
= CurItem
->ListPtr
;
815 ListPtr
->SetVDialogItemID(I
);
818 + Флаг DIF_LISTNOAMPERSAND. По умолчанию для DI_LISTBOX &
819 DI_COMBOBOX выставляется флаг MENU_SHOWAMPERSAND. Этот флаг
820 подавляет такое поведение
822 CurItem
->IFlags
.Set(DLGIIF_LISTREACTIONFOCUS
| DLGIIF_LISTREACTIONNOFOCUS
); // всегда!
823 ListPtr
->ChangeFlags(VMENU_DISABLED
, ItemFlags
& DIF_DISABLE
);
824 ListPtr
->ChangeFlags(VMENU_SHOWAMPERSAND
, !(ItemFlags
& DIF_LISTNOAMPERSAND
));
825 ListPtr
->ChangeFlags(VMENU_SHOWNOBOX
, ItemFlags
& DIF_LISTNOBOX
);
826 ListPtr
->ChangeFlags(VMENU_WRAPMODE
, ItemFlags
& DIF_LISTWRAPMODE
);
827 ListPtr
->ChangeFlags(VMENU_AUTOHIGHLIGHT
, ItemFlags
& DIF_LISTAUTOHIGHLIGHT
);
829 if (ItemFlags
& DIF_LISTAUTOHIGHLIGHT
)
830 ListPtr
->AssignHighlights(FALSE
);
832 ListPtr
->SetDialogStyle(DialogMode
.Check(DMODE_WARNINGSTYLE
));
833 ListPtr
->SetPosition(X1
+ CurItem
->X1
, Y1
+ CurItem
->Y1
, X1
+ CurItem
->X2
, Y1
+ CurItem
->Y2
);
834 ListPtr
->SetBoxType(SHORT_SINGLE_BOX
);
836 // поле FarDialogItem.Data для DI_LISTBOX используется как верхний заголовок листа
837 if (!(ItemFlags
& DIF_LISTNOBOX
) && !DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
838 ListPtr
->SetTitle(CurItem
->strData
);
842 // ListBox->DeleteItems(); //???? А НАДО ЛИ ????
843 if (CurItem
->ListItems
&& !DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
844 ListPtr
->AddItem(CurItem
->ListItems
);
847 ListPtr
->ChangeFlags(VMENU_LISTHASFOCUS
, CurItem
->Focus
);
850 // "редакторы" - разговор особый...
851 else if (FarIsEdit(Type
)) {
853 сбросим флаг DIF_EDITOR для строки ввода, отличной от DI_EDIT,
854 DI_FIXEDIT и DI_PSWEDIT
856 if (Type
!= DI_COMBOBOX
)
857 if ((ItemFlags
& DIF_EDITOR
) && Type
!= DI_EDIT
&& Type
!= DI_FIXEDIT
&& Type
!= DI_PSWEDIT
)
858 ItemFlags
&= ~DIF_EDITOR
;
860 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
)) {
862 new DlgEdit(this, I
, Type
== DI_MEMOEDIT
? DLGEDIT_MULTILINE
: DLGEDIT_SINGLELINE
);
864 if (Type
== DI_COMBOBOX
) {
865 CurItem
->ListPtr
= new VMenu(L
"", nullptr, 0, Opt
.Dialogs
.CBoxMaxHeight
,
866 VMENU_ALWAYSSCROLLBAR
| VMENU_NOTCHANGE
, nullptr, this);
867 CurItem
->ListPtr
->SetVDialogItemID(I
);
870 CurItem
->SelStart
= -1;
873 DlgEdit
*DialogEdit
= (DlgEdit
*)CurItem
->ObjPtr
;
874 // Mantis#58 - символ-маска с кодом 0х0А - пропадает
875 // DialogEdit->SetDialogParent((Type != DI_COMBOBOX && (ItemFlags & DIF_EDITOR) || (CurItem->Type==DI_PSWEDIT || CurItem->Type==DI_FIXEDIT))?
876 // FEDITLINE_PARENT_SINGLELINE:FEDITLINE_PARENT_MULTILINE);
877 DialogEdit
->SetDialogParent(
878 Type
== DI_MEMOEDIT
? FEDITLINE_PARENT_MULTILINE
: FEDITLINE_PARENT_SINGLELINE
);
879 DialogEdit
->SetReadOnly(0);
881 if (Type
== DI_COMBOBOX
) {
882 if (CurItem
->ListPtr
) {
883 VMenu
*ListPtr
= CurItem
->ListPtr
;
884 ListPtr
->SetBoxType(SHORT_SINGLE_BOX
);
885 DialogEdit
->SetDropDownBox(ItemFlags
& DIF_DROPDOWNLIST
);
886 ListPtr
->ChangeFlags(VMENU_WRAPMODE
, ItemFlags
& DIF_LISTWRAPMODE
);
887 ListPtr
->ChangeFlags(VMENU_DISABLED
, ItemFlags
& DIF_DISABLE
);
888 ListPtr
->ChangeFlags(VMENU_SHOWAMPERSAND
, !(ItemFlags
& DIF_LISTNOAMPERSAND
));
889 ListPtr
->ChangeFlags(VMENU_AUTOHIGHLIGHT
, ItemFlags
& DIF_LISTAUTOHIGHLIGHT
);
891 if (ItemFlags
& DIF_LISTAUTOHIGHLIGHT
)
892 ListPtr
->AssignHighlights(FALSE
);
894 if (CurItem
->ListItems
&& !DialogMode
.Check(DMODE_CREATEOBJECTS
))
895 ListPtr
->AddItem(CurItem
->ListItems
);
897 ListPtr
->SetFlags(VMENU_COMBOBOX
);
898 ListPtr
->SetDialogStyle(DialogMode
.Check(DMODE_WARNINGSTYLE
));
904 строка редакторирование должна иметь максимум в 511 символов
905 выставляем максимальный размер в том случае, если он еще не выставлен
909 if (DialogEdit
->GetMaxLength() == -1)
910 DialogEdit
->SetMaxLength(CurItem
->nMaxLength
? (int)CurItem
->nMaxLength
: -1);
912 DialogEdit
->SetPosition(X1
+ CurItem
->X1
, Y1
+ CurItem
->Y1
, X1
+ CurItem
->X2
, Y1
+ CurItem
->Y2
);
915 DialogEdit->SetObjectColor(
916 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE) ?
917 ((ItemFlags&DIF_DISABLE)?COL_WARNDIALOGEDITDISABLED:COL_WARNDIALOGEDIT):
918 ((ItemFlags&DIF_DISABLE)?COL_DIALOGEDITDISABLED:COL_DIALOGEDIT)),
919 FarColorToReal((ItemFlags&DIF_DISABLE)?COL_DIALOGEDITDISABLED:COL_DIALOGEDITSELECTED)
922 if (CurItem
->Type
== DI_PSWEDIT
) {
923 DialogEdit
->SetPasswordMode(TRUE
);
924 // ...Что бы небыло повадно... и для повыщения защиты, т.с.
925 ItemFlags
&= ~DIF_HISTORY
;
928 if (Type
== DI_FIXEDIT
) {
929 // DIF_HISTORY имеет более высокий приоритет, чем DIF_MASKEDIT
930 if (ItemFlags
& DIF_HISTORY
)
931 ItemFlags
&= ~DIF_MASKEDIT
;
934 если DI_FIXEDIT, то курсор сразу ставится на замену...
935 ай-ай - было недокументированно :-)
937 DialogEdit
->SetMaxLength(CurItem
->X2
- CurItem
->X1
+ 1
938 + (CurItem
->X2
== CurItem
->X1
|| !(ItemFlags
& DIF_HISTORY
) ? 0 : 1));
939 DialogEdit
->SetOvertypeMode(TRUE
);
942 Если тип строки ввода DI_FIXEDIT и установлен флаг DIF_MASKEDIT
943 и непустой параметр CurItem->Mask, то вызываем новую функцию
944 для установки маски в объект DlgEdit.
947 // Маска не должна быть пустой (строка из пробелов не учитывается)!
948 if ((ItemFlags
& DIF_MASKEDIT
) && !CurItem
->strMask
.IsEmpty()) {
949 RemoveExternalSpaces(CurItem
->strMask
);
950 if (!CurItem
->strMask
.IsEmpty()) {
951 DialogEdit
->SetInputMask(CurItem
->strMask
);
953 ItemFlags
&= ~DIF_MASKEDIT
;
960 Последовательно определенные поля ввода (edit controls),
961 имеющие этот флаг группируются в редактор с возможностью
962 вставки и удаления строк
964 if (!(ItemFlags
& DIF_EDITOR
) && CurItem
->Type
!= DI_COMBOBOX
) {
965 DialogEdit
->SetEditBeyondEnd(FALSE
);
967 if (!DialogMode
.Check(DMODE_INITOBJECTS
))
968 DialogEdit
->SetClearFlag(1);
971 if (CurItem
->Type
== DI_COMBOBOX
)
972 DialogEdit
->SetClearFlag(1);
976 Еже ли стоит флаг DIF_USELASTHISTORY и непустая строка ввода,
977 то подстанавливаем первое значение из History
979 if (CurItem
->Type
== DI_EDIT
980 && (ItemFlags
& (DIF_HISTORY
| DIF_USELASTHISTORY
))
981 == (DIF_HISTORY
| DIF_USELASTHISTORY
)) {
982 ProcessLastHistory(CurItem
, -1);
985 if ((ItemFlags
& DIF_MANUALADDHISTORY
) && !(ItemFlags
& DIF_HISTORY
))
986 ItemFlags
&= ~DIF_MANUALADDHISTORY
; // сбросим нафиг.
990 Если это ComBoBox и данные не установлены, то берем из списка
991 при условии, что хоть один из пунктов имеет Selected
994 if (Type
== DI_COMBOBOX
&& CurItem
->strData
.IsEmpty() && CurItem
->ListItems
) {
995 FarListItem
*ListItems
= CurItem
->ListItems
->Items
;
996 unsigned Length
= CurItem
->ListItems
->ItemsNumber
;
997 // CurItem->ListPtr->AddItem(CurItem->ListItems);
999 for (J
= 0; J
< Length
; J
++) {
1000 if (ListItems
[J
].Flags
& LIF_SELECTED
) {
1001 if (ItemFlags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
))
1002 HiText2Str(CurItem
->strData
, ListItems
[J
].Text
);
1004 CurItem
->strData
= ListItems
[J
].Text
;
1011 DialogEdit
->SetCallbackState(false);
1012 DialogEdit
->SetString(CurItem
->strData
);
1013 DialogEdit
->SetCallbackState(true);
1015 if (Type
== DI_FIXEDIT
)
1016 DialogEdit
->SetCurPos(0);
1018 // Для обычных строк отрубим постоянные блоки
1019 if (!(ItemFlags
& DIF_EDITOR
))
1020 DialogEdit
->SetPersistentBlocks(Opt
.Dialogs
.EditBlock
);
1022 DialogEdit
->SetDelRemovesBlocks(Opt
.Dialogs
.DelRemovesBlocks
);
1024 if (ItemFlags
& DIF_READONLY
)
1025 DialogEdit
->SetReadOnly(1);
1026 } else if (Type
== DI_USERCONTROL
) {
1027 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
))
1028 CurItem
->UCData
= new DlgUserControl
;
1031 CurItem
->Flags
= ItemFlags
;
1034 // если будет редактор, то обязательно будет выделен.
1035 SelectOnEntry(FocusPos
, TRUE
);
1036 // все объекты созданы!
1037 DialogMode
.Set(DMODE_CREATEOBJECTS
);
1041 const wchar_t *Dialog::GetDialogTitle()
1043 CriticalSectionLock
Lock(CS
);
1044 DialogItemEx
*CurItem
, *CurItemList
= nullptr;
1046 for (unsigned I
= 0; I
< ItemCount
; I
++) {
1049 // по первому попавшемуся "тексту" установим заголовок консоли!
1050 if ((CurItem
->Type
== DI_TEXT
|| CurItem
->Type
== DI_DOUBLEBOX
|| CurItem
->Type
== DI_SINGLEBOX
)) {
1051 const wchar_t *Ptr
= CurItem
->strData
;
1054 if (IsAlpha(*Ptr
) || iswdigit(*Ptr
))
1056 } else if (CurItem
->Type
== DI_LISTBOX
&& !I
)
1057 CurItemList
= CurItem
;
1061 return CurItemList
->ListPtr
->GetPtrTitle();
1064 return nullptr; //""
1067 void Dialog::ProcessLastHistory(DialogItemEx
*CurItem
, int MsgIndex
)
1069 CriticalSectionLock
Lock(CS
);
1070 FARString
&strData
= CurItem
->strData
;
1072 if (strData
.IsEmpty()) {
1073 FARString strRegKey
= fmtSavedDialogHistory
;
1074 strRegKey
+= CurItem
->strHistory
;
1075 History::ReadLastItem(strRegKey
.GetMB().c_str(), strData
);
1077 if (MsgIndex
!= -1) {
1078 // обработка DM_SETHISTORY => надо пропустить изменение текста через
1079 // диалоговую функцию
1080 FarDialogItemData IData
;
1081 IData
.PtrData
= const_cast<wchar_t *>(strData
.CPtr());
1082 IData
.PtrLength
= (int)strData
.GetLength();
1083 SendDlgMessage(this, DM_SETTEXT
, MsgIndex
, (LONG_PTR
)&IData
);
1089 static int ToRange(int Val
, int Min
, int Max
)
1091 return std::min(std::max(Val
, Min
), Max
);
1094 // Изменение координат и/или размеров итема диалога.
1095 BOOL
Dialog::SetItemRect(unsigned ID
, SMALL_RECT
*aRect
)
1097 CriticalSectionLock
Lock(CS
);
1099 if (ID
>= ItemCount
)
1104 Rect
.Left
= ToRange(Rect
.Left
, 0, X2
-X1
);
1105 Rect
.Top
= ToRange(Rect
.Top
, 0, Y2
-Y1
);
1106 Rect
.Right
= ToRange(Rect
.Right
, Rect
.Left
, X2
-X1
);
1107 Rect
.Bottom
= ToRange(Rect
.Bottom
, Rect
.Top
, Y2
-Y1
);
1109 DialogItemEx
*CurItem
= Item
[ID
];
1110 int Type
= CurItem
->Type
;
1111 CurItem
->X1
= Rect
.Left
;
1112 CurItem
->Y1
= (Rect
.Top
< 0) ? 0 : Rect
.Top
;
1114 if (FarIsEdit(Type
)) {
1115 DlgEdit
*DialogEdit
= (DlgEdit
*)CurItem
->ObjPtr
;
1116 CurItem
->X2
= Rect
.Right
;
1117 CurItem
->Y2
= (Type
== DI_MEMOEDIT
? Rect
.Bottom
: 0);
1118 DialogEdit
->SetPosition(X1
+ Rect
.Left
, Y1
+ Rect
.Top
, X1
+ Rect
.Right
, Y1
+ Rect
.Top
);
1119 } else if (Type
== DI_LISTBOX
) {
1120 CurItem
->X2
= Rect
.Right
;
1121 CurItem
->Y2
= Rect
.Bottom
;
1122 CurItem
->ListPtr
->SetPosition(X1
+ Rect
.Left
, Y1
+ Rect
.Top
, X1
+ Rect
.Right
, Y1
+ Rect
.Bottom
);
1123 CurItem
->ListPtr
->SetMaxHeight(CurItem
->Y2
- CurItem
->Y1
+ 1);
1128 CurItem
->X2
= Rect
.Right
;
1129 CurItem
->Y2
= 0; // ???
1132 CurItem
->X2
= 0; // ???
1133 CurItem
->Y2
= Rect
.Bottom
;
1136 case DI_USERCONTROL
:
1137 CurItem
->X2
= Rect
.Right
;
1138 CurItem
->Y2
= Rect
.Bottom
;
1142 if (DialogMode
.Check(DMODE_SHOW
)) {
1143 ShowDialog((unsigned)-1);
1150 BOOL
Dialog::GetItemRect(unsigned I
, SMALL_RECT
&Rect
)
1152 CriticalSectionLock
Lock(CS
);
1157 DialogItemEx
*CurItem
= Item
[I
];
1158 DWORD ItemFlags
= CurItem
->Flags
;
1159 int Type
= CurItem
->Type
;
1161 Rect
.Left
= CurItem
->X1
;
1162 Rect
.Top
= CurItem
->Y1
;
1163 Rect
.Right
= CurItem
->X2
;
1164 Rect
.Bottom
= CurItem
->Y2
;
1175 Len
= ((ItemFlags
& DIF_SHOWAMPERSAND
)
1176 ? (int)CurItem
->strData
.CellsCount()
1177 : HiStrCellsCount(CurItem
->strData
));
1184 if (CurItem
->X1
== -1)
1185 Rect
.Left
= (X2
- X1
+ 1 - Len
) / 2;
1190 if (CurItem
->Y1
== -1)
1191 Rect
.Top
= (Y2
- Y1
+ 1) / 2;
1196 Rect
.Bottom
= Rect
.Top
;
1198 if (!Rect
.Right
|| Rect
.Right
== Rect
.Left
)
1199 Rect
.Right
= Rect
.Left
+ Len
- (Len
? 1 : 0);
1201 if (ItemFlags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
1202 Rect
.Bottom
= Rect
.Top
;
1203 Rect
.Left
= (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 3 : 0); //???
1204 Rect
.Right
= X2
- X1
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 5 : 0); //???
1210 if (CurItem
->X1
== -1)
1211 Rect
.Left
= (X2
- X1
+ 1) / 2;
1216 if (CurItem
->Y1
== -1)
1217 Rect
.Top
= (Y2
- Y1
+ 1 - Len
) / 2;
1222 Rect
.Right
= Rect
.Left
;
1224 // Rect.bottom=Rect.top+Len;
1225 if (!Rect
.Bottom
|| Rect
.Bottom
== Rect
.Top
)
1226 Rect
.Bottom
= Rect
.Top
+ Len
- (Len
? 1 : 0);
1228 #if defined(VTEXT_ADN_SEPARATORS)
1230 if (ItemFlags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
1231 Rect
.Right
= Rect
.Left
;
1232 Rect
.Top
= (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 1 : 0); //???
1233 Rect
.Bottom
= Y2
- Y1
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 3 : 0); //???
1240 Rect
.Bottom
= Rect
.Top
;
1241 Rect
.Right
= Rect
.Left
+ Len
;
1244 case DI_RADIOBUTTON
:
1245 Rect
.Bottom
= Rect
.Top
;
1246 Rect
.Right
= Rect
.Left
+ Len
+ ((Type
== DI_CHECKBOX
) ? 4 : (ItemFlags
& DIF_MOVESELECT
? 3 : 4));
1252 Rect
.Bottom
= Rect
.Top
;
1259 bool Dialog::ItemHasDropDownArrow(const DialogItemEx
*Item
)
1261 return ((!Item
->strHistory
.IsEmpty() && (Item
->Flags
& DIF_HISTORY
) && Opt
.Dialogs
.EditHistory
)
1262 || (Item
->Type
== DI_COMBOBOX
&& Item
->ListPtr
&& Item
->ListPtr
->GetItemCount() > 0));
1265 //////////////////////////////////////////////////////////////////////////
1268 Получение данных и удаление "редакторов"
1270 void Dialog::DeleteDialogObjects()
1272 CriticalSectionLock
Lock(CS
);
1273 DialogItemEx
*CurItem
;
1275 for (unsigned I
= 0; I
< ItemCount
; I
++) {
1278 switch (CurItem
->Type
) {
1285 if (CurItem
->ObjPtr
)
1286 delete (DlgEdit
*)(CurItem
->ObjPtr
);
1290 if ((CurItem
->Type
== DI_COMBOBOX
|| CurItem
->Type
== DI_LISTBOX
) && CurItem
->ListPtr
)
1291 delete CurItem
->ListPtr
;
1294 case DI_USERCONTROL
:
1296 if (CurItem
->UCData
)
1297 delete CurItem
->UCData
;
1302 if (CurItem
->Flags
& DIF_AUTOMATION
)
1303 if (CurItem
->AutoPtr
)
1304 free(CurItem
->AutoPtr
);
1308 //////////////////////////////////////////////////////////////////////////
1311 Сохраняет значение из полей редактирования.
1312 При установленном флаге DIF_HISTORY, сохраняет данные в реестре.
1314 void Dialog::GetDialogObjectsData()
1316 CriticalSectionLock
Lock(CS
);
1318 DialogItemEx
*CurItem
;
1320 for (unsigned I
= 0; I
< ItemCount
; I
++) {
1322 DWORD IFlags
= CurItem
->Flags
;
1324 switch (Type
= CurItem
->Type
) {
1331 if (CurItem
->ObjPtr
) {
1333 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
1339 EditPtr
->GetString(strData
);
1341 if (ExitCode
>= 0 && (IFlags
& DIF_HISTORY
) && !(IFlags
& DIF_MANUALADDHISTORY
) && // при мануале не добавляем
1342 !CurItem
->strHistory
.IsEmpty() && Opt
.Dialogs
.EditHistory
) {
1343 AddToEditHistory(strData
, CurItem
->strHistory
);
1348 ! В History должно заносится значение (для DIF_EXPAND...) перед
1354 Проверка - этот элемент предполагает расширение переменных среды?
1355 т.к. функция GetDialogObjectsData() может вызываться самостоятельно
1361 ! Для DI_PSWEDIT и DI_FIXEDIT обработка DIF_EDITEXPAND не нужна
1362 (DI_FIXEDIT допускается для случая если нету маски)
1365 if ((IFlags
& DIF_EDITEXPAND
) && Type
!= DI_PSWEDIT
&& Type
!= DI_FIXEDIT
) {
1366 apiExpandEnvironmentStrings(strData
, strData
);
1367 // как бы грязный хак, нам нужно обновить строку чтоб отдавалась правильная строка
1368 // для различных DM_* после закрытия диалога, но ни в коем случае нельзя чтоб
1369 // высылался DN_EDITCHANGE для этого изменения, ибо диалог уже закрыт.
1370 EditPtr
->SetCallbackState(false);
1371 EditPtr
->SetString(strData
);
1372 EditPtr
->SetCallbackState(true);
1375 CurItem
->strData
= strData
;
1382 if(CurItem->ListPtr)
1384 CurItem->ListPos=CurItem->ListPtr->GetSelectPos();
1393 if ((Type
== DI_COMBOBOX
|| Type
== DI_LISTBOX
) && CurItem
->ListPtr
&& CurItem
->ListItems
&& DlgProc
== DefDlgProc
)
1395 int ListPos
=CurItem
->ListPtr
->GetSelectPos();
1397 if (ListPos
< CurItem
->ListItems
->ItemsNumber
)
1399 for (int J
=0; J
< CurItem
->ListItems
->ItemsNumber
; ++J
)
1400 CurItem
->ListItems
->Items
[J
].Flags
&=~LIF_SELECTED
;
1402 CurItem
->ListItems
->Items
[ListPos
].Flags
|=LIF_SELECTED
;
1408 if ((Type
== DI_COMBOBOX
|| Type
== DI_LISTBOX
)) {
1409 CurItem
->ListPos
= CurItem
->ListPtr
? CurItem
->ListPtr
->GetSelectPos() : 0;
1416 // Функция формирования и запроса цветов.
1417 DWORD
Dialog::CtlColorDlgItem(int ItemPos
, const DialogItemEx
*CurItem
, uint64_t *Color
)
1419 CriticalSectionLock
Lock(CS
);
1420 const int Type
= CurItem
->Type
;
1421 const int Focus
= CurItem
->Focus
;
1422 const int Default
= CurItem
->DefaultButton
;
1423 const DWORD Flags
= CurItem
->Flags
;
1425 const bool IsWarning
= DialogMode
.Check(DMODE_WARNINGSTYLE
);
1426 const bool DisabledItem
= (Flags
& DIF_DISABLE
) != 0;
1430 case DI_DOUBLEBOX
: {
1433 Color
[0] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGBOXTITLE
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGBOXTITLE
));
1435 Color
[1] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGHIGHLIGHTBOXTITLE
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGHIGHLIGHTBOXTITLE
));
1437 Color
[2] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGBOX
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGBOX
));
1441 if (Flags & DIF_SETCOLOR)
1442 Attr = Flags & DIF_COLORMASK;
1444 Attr = DialogMode.Check(DMODE_WARNINGSTYLE)
1445 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGBOX)
1446 : (DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGBOX);
1449 Attr = MAKELONG(MAKEWORD(FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1450 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGBOXTITLE)
1451 : (DisabledItem ? COL_DIALOGDISABLED
1452 : COL_DIALOGBOXTITLE)), // Title LOBYTE
1453 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1454 ? (DisabledItem ? COL_WARNDIALOGDISABLED
1455 : COL_WARNDIALOGHIGHLIGHTBOXTITLE)
1456 : (DisabledItem ? COL_DIALOGDISABLED
1457 : COL_DIALOGHIGHLIGHTBOXTITLE))), // HiText HIBYTE
1458 MAKEWORD(FarColorToReal(Attr), // Box LOBYTE
1464 #if defined(VTEXT_ADN_SEPARATORS)
1469 Color
[0] = FarColorToReal((Flags
& DIF_BOXCOLOR
)? (IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGBOX
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGBOX
)) : (IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGTEXT
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGTEXT
)));
1471 Color
[1] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGHIGHLIGHTTEXT
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGHIGHLIGHTTEXT
));
1472 if (Flags
& (DIF_SEPARATORUSER
|DIF_SEPARATOR
|DIF_SEPARATOR2
))
1475 Color
[2] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGBOX
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGBOX
));
1480 if (Flags & DIF_SETCOLOR)
1481 Attr = Flags & DIF_COLORMASK;
1483 if (Flags & DIF_BOXCOLOR)
1484 Attr = DialogMode.Check(DMODE_WARNINGSTYLE)
1485 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGBOX)
1486 : (DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGBOX);
1488 Attr = DialogMode.Check(DMODE_WARNINGSTYLE)
1489 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGTEXT)
1490 : (DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGTEXT);
1493 Attr = MAKELONG(MAKEWORD(FarColorToReal(Attr),
1494 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1495 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGHIGHLIGHTTEXT)
1496 : (DisabledItem ? COL_DIALOGDISABLED
1497 : COL_DIALOGHIGHLIGHTTEXT) // HIBYTE HiText
1499 ((Flags & (DIF_SEPARATORUSER | DIF_SEPARATOR | DIF_SEPARATOR2)) ? (
1500 MAKEWORD(FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1501 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGBOX)
1502 : (DisabledItem ? COL_DIALOGDISABLED
1503 : COL_DIALOGBOX) // Box LOBYTE
1511 #if !defined(VTEXT_ADN_SEPARATORS)
1513 if (Flags
& DIF_BOXCOLOR
)
1514 Attr
= DialogMode
.Check(DMODE_WARNINGSTYLE
)
1515 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGBOX
)
1516 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGBOX
);
1517 else if (Flags
& DIF_SETCOLOR
)
1518 Attr
= (Flags
& DIF_COLORMASK
);
1520 Attr
= (DialogMode
.Check(DMODE_WARNINGSTYLE
)
1521 ? (DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
)
1522 : (DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
));
1524 Attr
= MAKEWORD(MAKEWORD(FarColorToReal(Attr
), 0), MAKEWORD(0, 0));
1530 case DI_RADIOBUTTON
: {
1532 Color
[0] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGTEXT
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGTEXT
));
1534 Color
[1] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:COL_WARNDIALOGHIGHLIGHTTEXT
) : (DisabledItem
?COL_DIALOGDISABLED
:COL_DIALOGHIGHLIGHTTEXT
));
1537 if (Flags & DIF_SETCOLOR)
1538 Attr = (Flags & DIF_COLORMASK);
1540 Attr = (DialogMode.Check(DMODE_WARNINGSTYLE)
1541 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGTEXT)
1542 : (DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGTEXT));
1544 Attr = MAKEWORD(FarColorToReal(Attr),
1545 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1546 ? (DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGHIGHLIGHTTEXT)
1547 : (DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGHIGHLIGHTTEXT))); // HiText
1555 SetCursorType(0, 10);
1557 Color
[0] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:(Default
?COL_WARNDIALOGSELECTEDDEFAULTBUTTON
:COL_WARNDIALOGSELECTEDBUTTON
)) : (DisabledItem
?COL_DIALOGDISABLED
:(Default
?COL_DIALOGSELECTEDDEFAULTBUTTON
:COL_DIALOGSELECTEDBUTTON
)));
1559 Color
[1] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:(Default
?COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON
:COL_WARNDIALOGHIGHLIGHTSELECTEDBUTTON
)) : (DisabledItem
?COL_DIALOGDISABLED
:(Default
?COL_DIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON
:COL_DIALOGHIGHLIGHTSELECTEDBUTTON
)));
1564 Color
[0] = FarColorToReal(IsWarning
?
1565 (DisabledItem
?COL_WARNDIALOGDISABLED
:(Default
?COL_WARNDIALOGDEFAULTBUTTON
:COL_WARNDIALOGBUTTON
)):
1566 (DisabledItem
?COL_DIALOGDISABLED
:(Default
?COL_DIALOGDEFAULTBUTTON
:COL_DIALOGBUTTON
)));
1568 Color
[1] = FarColorToReal(IsWarning
? (DisabledItem
?COL_WARNDIALOGDISABLED
:(Default
?COL_WARNDIALOGHIGHLIGHTDEFAULTBUTTON
:COL_WARNDIALOGHIGHLIGHTBUTTON
)) : (DisabledItem
?COL_DIALOGDISABLED
:(Default
?COL_DIALOGHIGHLIGHTDEFAULTBUTTON
:COL_DIALOGHIGHLIGHTBUTTON
)));
1574 SetCursorType(0, 10);
1575 Attr = MAKEWORD((Flags & DIF_SETCOLOR)
1576 ? (Flags & DIF_COLORMASK)
1577 : FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1578 ? (DisabledItem ? COL_WARNDIALOGDISABLED
1579 : (Default ? COL_WARNDIALOGSELECTEDDEFAULTBUTTON
1580 : COL_WARNDIALOGSELECTEDBUTTON))
1581 : (DisabledItem ? COL_DIALOGDISABLED
1582 : (Default ? COL_DIALOGSELECTEDDEFAULTBUTTON
1583 : COL_DIALOGSELECTEDBUTTON))), // TEXT
1584 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1585 ? (DisabledItem ? COL_WARNDIALOGDISABLED
1586 : (Default ? COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON
1587 : COL_WARNDIALOGHIGHLIGHTSELECTEDBUTTON))
1588 : (DisabledItem ? COL_DIALOGDISABLED
1589 : (Default ? COL_DIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON
1590 : COL_DIALOGHIGHLIGHTSELECTEDBUTTON)))); // HiText
1592 Attr = MAKEWORD((Flags & DIF_SETCOLOR)
1593 ? (Flags & DIF_COLORMASK)
1594 : FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1595 ? (DisabledItem ? COL_WARNDIALOGDISABLED
1596 : (Default ? COL_WARNDIALOGDEFAULTBUTTON
1597 : COL_WARNDIALOGBUTTON))
1598 : (DisabledItem ? COL_DIALOGDISABLED
1599 : (Default ? COL_DIALOGDEFAULTBUTTON
1600 : COL_DIALOGBUTTON))), // TEXT
1601 FarColorToReal(DialogMode.Check(DMODE_WARNINGSTYLE)
1602 ? (DisabledItem ? COL_WARNDIALOGDISABLED
1603 : (Default ? COL_WARNDIALOGHIGHLIGHTDEFAULTBUTTON
1604 : COL_WARNDIALOGHIGHLIGHTBUTTON))
1605 : (DisabledItem ? COL_DIALOGDISABLED
1606 : (Default ? COL_DIALOGHIGHLIGHTDEFAULTBUTTON
1607 : COL_DIALOGHIGHLIGHTBUTTON)))); // HiText
1619 if (Type
== DI_COMBOBOX
&& (Flags
& DIF_DROPDOWNLIST
))
1624 Color
[0] = FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
: Focus
? COL_WARNDIALOGEDITSELECTED
: COL_WARNDIALOGEDIT
);
1626 Color
[1] = FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
: Focus
? COL_WARNDIALOGEDITSELECTED
: COL_WARNDIALOGEDIT
);
1628 Color
[2] = FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
: Focus
? COL_WARNDIALOGEDITSELECTED
: COL_WARNDIALOGEDITUNCHANGED
);
1630 Color
[3] = FarColorToReal(DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
);
1635 Color
[0] = FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
: Focus
? COL_DIALOGEDITSELECTED
: COL_DIALOGEDIT
);
1637 Color
[1] = FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
: Focus
? COL_DIALOGEDITSELECTED
: COL_DIALOGEDIT
);
1639 Color
[2] = FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
: Focus
? COL_DIALOGEDITSELECTED
: COL_DIALOGEDITUNCHANGED
);
1641 Color
[3] = FarColorToReal(DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
);
1649 Color
[0] = FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
: Flags
& DIF_NOFOCUS
? COL_WARNDIALOGEDITUNCHANGED
: COL_WARNDIALOGEDIT
);
1651 Color
[1] = FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
: COL_WARNDIALOGEDITSELECTED
);
1653 Color
[2] = FarColorToReal(DisabledItem
? COL_WARNDIALOGEDITDISABLED
: COL_WARNDIALOGEDITUNCHANGED
);
1655 Color
[3] = FarColorToReal(DisabledItem
? COL_WARNDIALOGDISABLED
: COL_WARNDIALOGTEXT
);
1660 Color
[0] = FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
: Flags
& DIF_NOFOCUS
? COL_DIALOGEDITUNCHANGED
: COL_DIALOGEDIT
);
1662 Color
[1] = FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
: COL_DIALOGEDITSELECTED
);
1664 Color
[2] = FarColorToReal(DisabledItem
? COL_DIALOGEDITDISABLED
: COL_DIALOGEDITUNCHANGED
);
1666 Color
[3] = FarColorToReal(DisabledItem
? COL_DIALOGDISABLED
: COL_DIALOGTEXT
);
1671 if (Type == DI_COMBOBOX && (Flags & DIF_DROPDOWNLIST)) {
1672 if (DialogMode.Check(DMODE_WARNINGSTYLE))
1673 Attr = MAKELONG(MAKEWORD( // LOWORD
1675 FarColorToReal(DisabledItem ? COL_WARNDIALOGEDITDISABLED
1676 : COL_WARNDIALOGEDIT),
1678 FarColorToReal(DisabledItem ? COL_DIALOGEDITDISABLED
1679 : COL_DIALOGEDITSELECTED)),
1682 FarColorToReal(DisabledItem ? COL_WARNDIALOGEDITDISABLED
1683 : COL_DIALOGEDITUNCHANGED), //???
1686 DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGTEXT)));
1688 Attr = MAKELONG(MAKEWORD( // LOWORD
1690 FarColorToReal(DisabledItem
1691 ? COL_DIALOGEDITDISABLED
1692 : (!Focus ? COL_DIALOGEDIT
1693 : COL_DIALOGEDITSELECTED)),
1695 FarColorToReal(DisabledItem
1696 ? COL_DIALOGEDITDISABLED
1697 : (!Focus ? COL_DIALOGEDIT
1698 : COL_DIALOGEDITSELECTED))),
1701 FarColorToReal(DisabledItem ? COL_DIALOGEDITDISABLED
1702 : COL_DIALOGEDITUNCHANGED), //???
1704 FarColorToReal(DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGTEXT)));
1706 if (DialogMode.Check(DMODE_WARNINGSTYLE))
1707 Attr = MAKELONG(MAKEWORD( // LOWORD
1709 FarColorToReal(DisabledItem
1710 ? COL_WARNDIALOGEDITDISABLED
1711 : (Flags & DIF_NOFOCUS ? COL_DIALOGEDITUNCHANGED
1712 : COL_WARNDIALOGEDIT)),
1714 FarColorToReal(DisabledItem ? COL_DIALOGEDITDISABLED
1715 : COL_DIALOGEDITSELECTED)),
1718 FarColorToReal(DisabledItem ? COL_WARNDIALOGEDITDISABLED
1719 : COL_DIALOGEDITUNCHANGED), //???
1722 DisabledItem ? COL_WARNDIALOGDISABLED : COL_WARNDIALOGTEXT)));
1724 Attr = MAKELONG(MAKEWORD( // LOWORD
1726 FarColorToReal(DisabledItem
1727 ? COL_DIALOGEDITDISABLED
1728 : (Flags & DIF_NOFOCUS ? COL_DIALOGEDITUNCHANGED
1731 FarColorToReal(DisabledItem ? COL_DIALOGEDITDISABLED
1732 : COL_DIALOGEDITSELECTED)),
1735 FarColorToReal(DisabledItem ? COL_DIALOGEDITDISABLED
1736 : COL_DIALOGEDITUNCHANGED), //???
1738 FarColorToReal(DisabledItem ? COL_DIALOGDISABLED : COL_DIALOGTEXT)));
1745 Item
[ItemPos
]->ListPtr
->SetColors(nullptr);
1753 ++InCtlColorDlgItem
;
1754 DWORD out
= DlgProc((HANDLE
)this, DN_CTLCOLORDLGITEM
, ItemPos
, (LONG_PTR
)Color
);
1755 --InCtlColorDlgItem
;
1760 static void SetColorNormal(DWORD Attr, const std::unique_ptr<DialogItemTrueColors> &TrueColors)
1762 ComposeAndSetColor(Attr & 0xff, TrueColors ? &TrueColors->Normal : nullptr);
1765 static void SetColorFrame(DWORD Attr, const std::unique_ptr<DialogItemTrueColors> &TrueColors)
1767 ComposeAndSetColor(LOBYTE(HIWORD(Attr)), TrueColors ? &TrueColors->Frame : nullptr);
1771 //////////////////////////////////////////////////////////////////////////
1774 Отрисовка элементов диалога на экране.
1776 void Dialog::ShowDialog(unsigned ID
)
1778 CriticalSectionLock
Lock(CS
);
1784 DialogItemEx
*CurItem
;
1786 // size_t I, DrawItemCount;
1787 unsigned I
, DrawItemCount
;
1788 uint64_t ItemColor
[4];
1790 // Если не разрешена отрисовка, то вываливаем.
1791 if (IsEnableRedraw
|| // разрешена прорисовка ?
1792 (ID
+ 1 > ItemCount
) || // а номер в рамках дозволенного?
1793 DialogMode
.Check(DMODE_DRAWING
) || // диалог рисуется?
1794 !DialogMode
.Check(DMODE_SHOW
) || // если не видим, то и не отрисовываем.
1795 !DialogMode
.Check(DMODE_INITOBJECTS
))
1798 DialogMode
.Set(DMODE_DRAWING
); // диалог рисуется!!!
1799 ChangePriority
ChPriority(ChangePriority::NORMAL
);
1801 if (ID
== (unsigned)-1) // рисуем все?
1803 // Перед прорисовкой диалога посылаем сообщение в обработчик
1804 if (!DlgProc((HANDLE
)this, DN_DRAWDIALOG
, 0, 0)) {
1805 DialogMode
.Clear(DMODE_DRAWING
); // конец отрисовки диалога!!!
1809 // перед прорисовкой подложки окна диалога
1810 if (!DialogMode
.Check(DMODE_NODRAWSHADOW
))
1811 Shadow(DialogMode
.Check(DMODE_FULLSHADOW
) != FALSE
); // "наводим" тень
1813 if (!DialogMode
.Check(DMODE_NODRAWPANEL
)) {
1817 Color
[0] = FarColorToReal(DialogMode
.Check(DMODE_WARNINGSTYLE
) ? COL_WARNDIALOGTEXT
:COL_DIALOGTEXT
);
1818 DlgProc((HANDLE
)this, DN_CTLCOLORDIALOG
, 0, (LONG_PTR
)Color
);
1819 SetScreen(X1
, Y1
, X2
, Y2
, L
' ', Color
[0]);
1823 DrawItemCount
= ItemCount
;
1825 DrawItemCount
= ID
+ 1;
1829 IFlags.Set(DIMODE_REDRAW)
1831 если рисуется контрол и по Z-order`у он пересекается с
1832 другим контролом (по координатам), то для "позднего"
1833 контрола тоже нужна прорисовка.
1836 bool CursorVisible
= false;
1837 DWORD CursorSize
= 0;
1839 if (ID
!= (unsigned)-1 && FocusPos
!= ID
) {
1840 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
&& Item
[FocusPos
]->UCData
->CursorPos
.X
!= -1
1841 && Item
[FocusPos
]->UCData
->CursorPos
.Y
!= -1) {
1842 CursorVisible
= Item
[FocusPos
]->UCData
->CursorVisible
;
1843 CursorSize
= Item
[FocusPos
]->UCData
->CursorSize
;
1847 SetCursorType(CursorVisible
, CursorSize
);
1850 for (I
= ID
; I
< DrawItemCount
; I
++) {
1853 if (CurItem
->Flags
& DIF_HIDDEN
)
1858 Перед прорисовкой каждого элемента посылаем сообщение
1859 посредством функции SendDlgMessage - в ней делается все!
1861 if (!SendDlgMessage((HANDLE
)this, DN_DRAWDLGITEM
, I
, 0))
1865 short CX1
= CurItem
->X1
;
1866 short CY1
= CurItem
->Y1
;
1867 short CX2
= CurItem
->X2
;
1868 short CY2
= CurItem
->Y2
;
1876 short CW
= CX2
- CX1
+ 1;
1877 short CH
= CY2
- CY1
+ 1;
1879 CtlColorDlgItem(I
, CurItem
, ItemColor
);
1881 for (size_t g
= 0; g
< 4; g
++)
1882 if (CurItem
->customItemColor
[g
])
1883 ItemColor
[g
] = CurItem
->customItemColor
[g
];
1887 // TODO: прежде чем эту строку применять... нужно проверить _ВСЕ_ диалоги на предмет X2, Y2. !!!
1888 if (((CX1
> -1) && (CX2
> 0) && (CX2
> CX1
)) &&
1889 ((CY1
> -1) && (CY2
> 0) && (CY2
> CY1
)))
1890 SetScreen(X1
+CX1
,Y1
+CY1
,X1
+CX2
,Y1
+CY2
,' ',Attr
&0xFF);
1894 switch (CurItem
->Type
) {
1895 /* ***************************************************************** */
1897 case DI_DOUBLEBOX
: {
1898 BOOL IsDrawTitle
= TRUE
;
1899 GotoXY(X1
+ CX1
, Y1
+ CY1
);
1900 // SetColorFrame(Attr, CurItem->TrueColors);
1901 SetColor(ItemColor
[2]);
1904 DrawLine(CX2
- CX1
+ 1, CurItem
->Type
== DI_SINGLEBOX
? 8 : 9); //???
1905 } else if (CX1
== CX2
) {
1906 DrawLine(CY2
- CY1
+ 1, CurItem
->Type
== DI_SINGLEBOX
? 10 : 11);
1907 IsDrawTitle
= FALSE
;
1909 Box(X1
+ CX1
, Y1
+ CY1
, X1
+ CX2
, Y1
+ CY2
, ItemColor
[2],
1910 (CurItem
->Type
== DI_SINGLEBOX
) ? SINGLE_BOX
: DOUBLE_BOX
);
1913 if (!CurItem
->strData
.IsEmpty() && IsDrawTitle
) {
1914 // ! Пусть диалог сам заботится о ширине собственного заголовка.
1915 strStr
= CurItem
->strData
;
1916 TruncStrFromEnd(strStr
, CW
- 2); // 5 ???
1917 LenText
= LenStrItem(I
, strStr
);
1919 if (LenText
< CW
- 2 && !strStr
.Begins(L
' ') ) {
1920 strStr
.Insert(0, L
' ');
1921 LenText
= LenStrItem(I
, strStr
);
1924 if (LenText
< CW
- 2 && !strStr
.Ends(L
' ') ) { // пробел после текста заголовка и рамкой
1925 strStr
.Append(L
' ');
1926 LenText
= LenStrItem(I
, strStr
);
1929 X
= X1
+ CX1
+ (CW
- LenText
) / 2;
1931 if ((CurItem
->Flags
& DIF_LEFTTEXT
) && X1
+ CX1
+ 1 < X
)
1934 // SetColorNormal(Attr, CurItem->TrueColors);
1935 SetColor(ItemColor
[0]);
1936 GotoXY(X
, Y1
+ CY1
);
1938 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
1941 HiText(strStr
, ItemColor
[1]);
1944 if (CurItem->Flags & DIF_SHOWAMPERSAND)
1946 else if (CurItem->TrueColors)
1947 HiText(strStr, ComposeColor(ItemColor[1] & 0xFF, &CurItem->TrueColors->Hilighted));
1949 HiText(strStr, ItemColor[1]);
1956 /* ***************************************************************** */
1958 strStr
= CurItem
->strData
;
1959 LenText
= LenStrItem(I
, strStr
);
1961 if (!(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))
1962 && (CurItem
->Flags
& DIF_CENTERTEXT
) && CX1
!= -1)
1963 LenText
= LenStrItem(I
, CenterStr(strStr
, strStr
, CX2
- CX1
+ 1));
1965 X
= (CX1
== -1 || (CurItem
->Flags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)))
1966 ? (X2
- X1
+ 1 - LenText
) / 2
1968 Y
= (CY1
== -1) ? (Y2
- Y1
+ 1) / 2 : CY1
;
1973 if ((CX2
<= 0) || (CX2
< CX1
))
1976 if (X1
+ X
+ LenText
> X2
) {
1977 int tmpCW
= ObjWidth
;
1982 strStr
.TruncateByCells(tmpCW
- 1);
1986 // SetScreen(X1+CX1,Y1+CY1,X1+CX2,Y1+CY2,' ',Attr&0xFF);
1988 if (CX1
> -1 && CX2
> CX1
1989 && !(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))) { // половинчатое решение
1991 int CntChr
= CX2
- CX1
+ 1;
1992 // SetColorNormal(Attr, CurItem->TrueColors);
1993 SetColor(ItemColor
[0]);
1994 GotoXY(X1
+ X
, Y1
+ Y
);
1996 if (X1
+ X
+ CntChr
- 1 > X2
)
1997 CntChr
= X2
- (X1
+ X
) + 1;
1999 FS
<< fmt::Cells() << fmt::Expand(CntChr
) << L
"";
2001 if (CntChr
< LenText
)
2002 strStr
.TruncateByCells(CntChr
);
2005 /// if (CX1 > -1 && CX2 > CX1 && !(Item.Flags & (DIF_SEPARATORUSER|DIF_SEPARATOR|DIF_SEPARATOR2))) //половинчатое решение
2007 /// SetScreen({ m_Where.left + CX1, m_Where.top + Y, m_Where.left + CX2, m_Where.top + Y }, L' ', ItemColor[0]);
2009 int CntChr=CX2-CX1+1;
2010 SetColor(ItemColor[0]);
2013 if (X1+X+CntChr-1 > X2)
2016 Text(string(CntChr, L' '));
2018 if (CntChr < LenText)
2019 strStr.SetLength(CntChr);
2023 if (CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
2024 // SetColorFrame(Attr, CurItem->TrueColors);
2025 SetColor(ItemColor
[2]);
2027 + ((CurItem
->Flags
& DIF_SEPARATORUSER
)
2029 : (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 3 : 0)),
2031 ShowUserSeparator((CurItem
->Flags
& DIF_SEPARATORUSER
)
2033 : RealWidth
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 6 : 0 /* -1 */),
2034 (CurItem
->Flags
& DIF_SEPARATORUSER
)
2036 : (CurItem
->Flags
& DIF_SEPARATOR2
? 3 : 1),
2040 // SetColorNormal(Attr, CurItem->TrueColors);
2041 SetColor(ItemColor
[0]);
2042 GotoXY(X1
+ X
, Y1
+ Y
);
2044 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
) {
2045 // MessageBox(0, strStr, strStr, MB_OK);
2048 // MessageBox(0, strStr, strStr, MB_OK);
2049 HiText(strStr
, ItemColor
[1]);
2054 /* ***************************************************************** */
2056 strStr
= CurItem
->strData
;
2057 LenText
= LenStrItem(I
, strStr
);
2059 if (!(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))
2060 && (CurItem
->Flags
& DIF_CENTERTEXT
) && CY1
!= -1)
2061 LenText
= StrLength(CenterStr(strStr
, strStr
, CY2
- CY1
+ 1));
2063 X
= (CX1
== -1) ? (X2
- X1
+ 1) / 2 : CX1
;
2064 Y
= (CY1
== -1 || (CurItem
->Flags
& (DIF_SEPARATOR
| DIF_SEPARATOR2
)))
2065 ? (Y2
- Y1
+ 1 - LenText
) / 2
2071 if ((CY2
<= 0) || (CY2
< CY1
))
2072 CH
= LenStrItem(I
, strStr
);
2074 if (Y1
+ Y
+ LenText
> Y2
) {
2075 int tmpCH
= ObjHeight
;
2080 strStr
.TruncateByCells(tmpCH
- 1);
2084 // SetScreen(X1+CX1,Y1+CY1,X1+CX2,Y1+CY2,' ',Attr&0xFF);
2086 if (CY1
> -1 && CY2
> 0 && CY2
> CY1
2087 && !(CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
))) { // половинчатое решение
2089 int CntChr
= CY2
- CY1
+ 1;
2090 SetColor(ItemColor
[0]);
2091 // SetColorNormal(Attr, CurItem->TrueColors);
2092 GotoXY(X1
+ X
, Y1
+ Y
);
2094 if (Y1
+ Y
+ CntChr
- 1 > Y2
)
2095 CntChr
= Y2
- (Y1
+ Y
) + 1;
2097 vmprintf(L
"%*ls", CntChr
, L
"");
2101 //SetScreen(X1+CX1,Y1+CY1,X1+CX2,Y1+CY2,' ',Attr&0xFF);
2103 /// if (CY1 > -1 && CY2 > CY1 && !(Item.Flags & (DIF_SEPARATORUSER|DIF_SEPARATOR|DIF_SEPARATOR2))) //половинчатое решение
2105 /// SetScreen({ m_Where.left + X, m_Where.top + CY1, m_Where.left + X, m_Where.top + CY2 }, L' ', ItemColor[0]);
2107 int CntChr=CY2-CY1+1;
2108 SetColor(ItemColor[0]);
2111 if (Y1+Y+CntChr-1 > Y2)
2114 vmprintf(L"%*s",CntChr,L"");
2121 #if defined(VTEXT_ADN_SEPARATORS)
2123 if (CurItem
->Flags
& (DIF_SEPARATORUSER
| DIF_SEPARATOR
| DIF_SEPARATOR2
)) {
2124 // SetColorFrame(Attr, CurItem->TrueColors);
2125 SetColor(ItemColor
[2]);
2128 + ((CurItem
->Flags
& DIF_SEPARATORUSER
)
2130 : (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 1 : 0))); //????
2131 ShowUserSeparator((CurItem
->Flags
& DIF_SEPARATORUSER
)
2133 : RealHeight
- (!DialogMode
.Check(DMODE_SMALLDIALOG
) ? 2 : 0),
2134 (CurItem
->Flags
& DIF_SEPARATORUSER
)
2136 : (CurItem
->Flags
& DIF_SEPARATOR2
? 7 : 5),
2141 SetColor(ItemColor
[0]);
2142 // SetColorNormal(Attr, CurItem->TrueColors);
2143 GotoXY(X1
+ X
, Y1
+ Y
);
2145 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
2148 HiText(strStr
, ItemColor
[1], TRUE
);
2152 /* ***************************************************************** */
2154 case DI_RADIOBUTTON
: {
2155 // SetColorNormal(Attr, CurItem->TrueColors);
2156 SetColor(ItemColor
[0]);
2157 GotoXY(X1
+ CX1
, Y1
+ CY1
);
2159 if (CurItem
->Type
== DI_CHECKBOX
) {
2160 const wchar_t Check
[] = {L
'[',
2161 (CurItem
->Selected
? (((CurItem
->Flags
& DIF_3STATE
) && CurItem
->Selected
== 2)
2162 ? *Msg::CheckBox2State
2168 if (CurItem
->strData
.GetLength())
2171 wchar_t Dot
[] = {L
' ', CurItem
->Selected
? L
'\x2022' : L
' ', L
' ', L
'\0'};
2173 if (CurItem
->Flags
& DIF_MOVESELECT
) {
2180 if (CurItem
->strData
.GetLength())
2185 strStr
+= CurItem
->strData
;
2186 LenText
= LenStrItem(I
, strStr
);
2188 if (X1
+ CX1
+ LenText
> X2
)
2189 strStr
.TruncateByCells(ObjWidth
- 1);
2191 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
2194 HiText(strStr
, ItemColor
[1]);
2196 if (CurItem
->Focus
) {
2197 // Отключение мигающего курсора при перемещении диалога
2198 if (!DialogMode
.Check(DMODE_DRAGGED
))
2199 SetCursorType(1, -1);
2201 MoveCursor(X1
+ CX1
+ 1, Y1
+ CY1
);
2206 /* ***************************************************************** */
2208 strStr
= CurItem
->strData
;
2209 SetColor(ItemColor
[0]);
2210 // SetColorNormal(Attr, CurItem->TrueColors);
2211 GotoXY(X1
+ CX1
, Y1
+ CY1
);
2213 if (CurItem
->Flags
& DIF_SHOWAMPERSAND
)
2216 HiText(strStr
,ItemColor
[1]);
2217 // HiText(strStr, HIBYTE(LOWORD(Attr)));
2219 if (CurItem
->Flags
& DIF_SETSHIELD
) {
2220 int startx
= X1
+ CX1
+ (CurItem
->Flags
& DIF_NOBRACKETS
? 0 : 2);
2221 ScrBuf
.ApplyColor(startx
, Y1
+ CY1
, startx
+ 1, Y1
+ CY1
, 0xE9);
2225 /* ***************************************************************** */
2231 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
2236 // EditPtr->SetObjectColor(Attr & 0xFF, HIBYTE(LOWORD(Attr)), LOBYTE(HIWORD(Attr)));
2237 EditPtr
->SetObjectColor(ItemColor
[0],ItemColor
[1],ItemColor
[2]);
2239 if (CurItem
->Focus
) {
2240 // Отключение мигающего курсора при перемещении диалога
2241 if (!DialogMode
.Check(DMODE_DRAGGED
))
2242 SetCursorType(1, -1);
2246 EditPtr
->FastShow();
2247 EditPtr
->SetLeftPos(0);
2250 // Отключение мигающего курсора при перемещении диалога
2251 if (DialogMode
.Check(DMODE_DRAGGED
))
2252 SetCursorType(0, 0);
2254 if (ItemHasDropDownArrow(CurItem
)) {
2255 int EditX1
, EditY1
, EditX2
, EditY2
;
2256 EditPtr
->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
2257 // Text((CurItem->Type == DI_COMBOBOX?"\x1F":"\x19"));
2258 Text(EditX2
+ 1, EditY1
, ItemColor
[3], L
"\x2193");
2261 if (CurItem
->Type
== DI_COMBOBOX
&& GetDropDownOpened() && CurItem
->ListPtr
->IsVisible()) // need redraw VMenu?
2263 CurItem
->ListPtr
->Hide();
2264 CurItem
->ListPtr
->Show();
2269 /* ***************************************************************** */
2271 if (CurItem
->ListPtr
) {
2272 // Перед отрисовкой спросим об изменении цветовых атрибутов
2273 uint64_t RealColors
[VMENU_COLOR_COUNT
];
2274 FarListColors ListColors
= {0};
2275 ListColors
.ColorCount
= VMENU_COLOR_COUNT
;
2276 ListColors
.Colors
= RealColors
;
2277 CurItem
->ListPtr
->GetColors(&ListColors
);
2279 if (DlgProc((HANDLE
)this, DN_CTLCOLORDLGLIST
, I
, (LONG_PTR
)&ListColors
))
2280 CurItem
->ListPtr
->SetColors(&ListColors
);
2282 // Курсор запоминаем...
2283 bool CursorVisible
= false;
2284 DWORD CursorSize
= 0;
2285 GetCursorType(CursorVisible
, CursorSize
);
2286 CurItem
->ListPtr
->Show();
2288 // .. а теперь восстановим!
2290 SetCursorType(CursorVisible
, CursorSize
);
2295 /* 01.08.2000 SVS $ */
2296 /* ***************************************************************** */
2297 case DI_USERCONTROL
:
2299 if (CurItem
->VBuf
) {
2300 PutText(X1
+ CX1
, Y1
+ CY1
, X1
+ CX2
, Y1
+ CY2
, CurItem
->VBuf
);
2302 // не забудем переместить курсор, если он позиционирован.
2303 if (FocusPos
== I
) {
2304 if (CurItem
->UCData
->CursorPos
.X
!= -1 && CurItem
->UCData
->CursorPos
.Y
!= -1) {
2305 MoveCursor(CurItem
->UCData
->CursorPos
.X
+ CX1
+ X1
,
2306 CurItem
->UCData
->CursorPos
.Y
+ CY1
+ Y1
);
2307 SetCursorType(CurItem
->UCData
->CursorVisible
, CurItem
->UCData
->CursorSize
);
2309 SetCursorType(0, -1);
2313 break; // уже наприсовали :-)))
2314 /* ***************************************************************** */
2321 for (I
= 0; I
< ItemCount
; I
++) {
2324 if (CurItem
->ListPtr
&& GetDropDownOpened() && CurItem
->ListPtr
->IsVisible()) {
2325 if ((CurItem
->Type
== DI_COMBOBOX
)
2326 || ((CurItem
->Type
== DI_EDIT
|| CurItem
->Type
== DI_FIXEDIT
)
2327 && !(CurItem
->Flags
& DIF_HIDDEN
) && (CurItem
->Flags
& DIF_HISTORY
))) {
2328 CurItem
->ListPtr
->Show();
2333 // Включим индикатор перемещения...
2334 if (!DialogMode
.Check(DMODE_DRAGGED
)) // если диалог таскается
2338 + При каждой перерисовке диалога, кроме режима перемещения, устанавливаем
2339 заголовок консоли, в противном случае он не всегда восстанавливался.
2341 if (!DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
2342 ConsoleTitle::SetFarTitle(GetDialogTitle());
2345 DialogMode
.Clear(DMODE_DRAWING
); // конец отрисовки диалога!!!
2346 DialogMode
.Set(DMODE_SHOW
); // диалог на экране!
2348 if (DialogMode
.Check(DMODE_DRAGGED
)) {
2350 - BugZ#813 - DM_RESIZEDIALOG в DN_DRAWDIALOG -> проблема: Ctrl-F5 - отрисовка только полозьев.
2351 Убираем вызов плагиновго обработчика.
2353 // DlgProc((HANDLE)this,DN_DRAWDIALOGDONE,1,0);
2354 DefDlgProc((HANDLE
)this, DN_DRAWDIALOGDONE
, 1, 0);
2356 DlgProc((HANDLE
)this, DN_DRAWDIALOGDONE
, 0, 0);
2359 int Dialog::LenStrItem(int ID
, const wchar_t *lpwszStr
)
2361 CriticalSectionLock
Lock(CS
);
2364 lpwszStr
= Item
[ID
]->strData
;
2366 return (Item
[ID
]->Flags
& DIF_SHOWAMPERSAND
) ? StrZCellsCount(lpwszStr
) : HiStrCellsCount(lpwszStr
);
2369 int Dialog::ProcessMoveDialog(DWORD Key
)
2371 CriticalSectionLock
Lock(CS
);
2373 if (DialogMode
.Check(DMODE_DRAGGED
)) // если диалог таскается
2376 TODO: Здесь проверить "уже здесь" и не делать лишних движений
2377 Т.е., если нажали End, то при следующем End ненужно ничего делать! - сравнить координаты !!!
2381 // При перемещении диалога повторяем поведение "бормандовых" сред.
2384 case KEY_CTRLNUMPAD4
:
2386 case KEY_CTRLNUMPAD7
:
2389 rr
= Key
== KEY_CTRLLEFT
|| Key
== KEY_CTRLNUMPAD4
? 10 : X1
;
2394 for (int i
= 0; i
< rr
; i
++)
2398 AdjustEditPos(-1, 0);
2401 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2406 case KEY_CTRLNUMPAD6
:
2408 case KEY_CTRLNUMPAD1
:
2411 rr
= Key
== KEY_CTRLRIGHT
|| Key
== KEY_CTRLNUMPAD6
? 10 : Max(0, ScrX
- X2
);
2416 for (int i
= 0; i
< rr
; i
++)
2420 AdjustEditPos(1, 0);
2423 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2430 case KEY_CTRLNUMPAD9
:
2432 case KEY_CTRLNUMPAD8
:
2433 rr
= Key
== KEY_CTRLUP
|| Key
== KEY_CTRLNUMPAD8
? 5 : Y1
;
2438 for (int i
= 0; i
< rr
; i
++)
2442 AdjustEditPos(0, -1);
2445 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2450 case KEY_CTRLNUMPAD2
:
2452 case KEY_CTRLNUMPAD3
:
2455 rr
= Key
== KEY_CTRLDOWN
|| Key
== KEY_CTRLNUMPAD2
? 5 : Max(0, ScrY
- Y2
);
2460 for (int i
= 0; i
< rr
; i
++)
2464 AdjustEditPos(0, 1);
2467 if (!DialogMode
.Check(DMODE_ALTDRAGGED
))
2474 DialogMode
.Clear(DMODE_DRAGGED
); // закончим движение!
2476 if (!DialogMode
.Check(DMODE_ALTDRAGGED
)) {
2477 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, 0);
2484 AdjustEditPos(OldX1
- X1
, OldY1
- Y1
);
2489 DialogMode
.Clear(DMODE_DRAGGED
);
2491 if (!DialogMode
.Check(DMODE_ALTDRAGGED
)) {
2492 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, TRUE
);
2499 if (DialogMode
.Check(DMODE_ALTDRAGGED
)) {
2500 DialogMode
.Clear(DMODE_DRAGGED
| DMODE_ALTDRAGGED
);
2501 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, 0);
2508 if (Key
== KEY_CTRLF5
&& DialogMode
.Check(DMODE_ISCANMOVE
)) {
2509 if (DlgProc((HANDLE
)this, DN_DRAGGED
, 0, 0)) // если разрешили перемещать!
2511 // включаем флаг и запоминаем координаты
2512 DialogMode
.Set(DMODE_DRAGGED
);
2517 // # GetText(0,0,3,0,LV);
2527 int64_t Dialog::VMProcess(MacroOpcode OpCode
, void *vParam
, int64_t iParam
)
2530 case MCODE_F_MENU_CHECKHOTKEY
:
2531 case MCODE_F_MENU_GETHOTKEY
:
2532 case MCODE_F_MENU_SELECT
:
2533 case MCODE_F_MENU_GETVALUE
:
2534 case MCODE_F_MENU_ITEMSTATUS
:
2535 case MCODE_V_MENU_VALUE
: {
2536 const wchar_t *str
= (const wchar_t *)vParam
;
2538 if (GetDropDownOpened() || Item
[FocusPos
]->Type
== DI_LISTBOX
) {
2539 if (Item
[FocusPos
]->ListPtr
)
2540 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2541 } else if (OpCode
== MCODE_F_MENU_CHECKHOTKEY
)
2542 return (int64_t)(CheckHighlights(*str
, (int)iParam
) + 1);
2551 case MCODE_C_SELECTED
:
2552 case MCODE_C_EMPTY
: {
2553 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2554 if (Item
[FocusPos
]->Type
== DI_COMBOBOX
&& GetDropDownOpened())
2555 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2557 return ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->VMProcess(OpCode
, vParam
, iParam
);
2558 } else if (Item
[FocusPos
]->Type
== DI_LISTBOX
&& OpCode
!= MCODE_C_SELECTED
)
2559 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2563 case MCODE_V_DLGITEMTYPE
: {
2564 switch (Item
[FocusPos
]->Type
) {
2566 return 7; // Кнопка (Push Button).
2568 return 8; // Контрольный переключатель (Check Box).
2570 return (DropDownOpened
? 0x800A : 10); // Комбинированный список.
2572 return 3; // Двойная рамка.
2574 return DropDownOpened
? 0x8004 : 4; // Поле ввода.
2576 return 6; // Поле ввода фиксированного размера.
2578 return 11; // Окно списка.
2580 return 5; // Поле ввода пароля.
2581 case DI_RADIOBUTTON
:
2582 return 9; // Селекторная кнопка (Radio Button).
2584 return 2; // Одиночная рамка.
2586 return 0; // Текстовая строка.
2587 case DI_USERCONTROL
:
2588 return 255; // Элемент управления, определяемый программистом.
2590 return 1; // Вертикальная текстовая строка.
2595 case MCODE_V_DLGITEMCOUNT
: // Dlg.ItemCount
2599 case MCODE_V_DLGCURPOS
: // Dlg.CurPos
2601 return FocusPos
+ 1;
2603 case MCODE_V_DLGINFOID
: // Dlg.Info.Id
2605 static FARString strId
;
2606 strId
.Format(L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", Id
.Data1
, Id
.Data2
, Id
.Data3
,
2607 Id
.Data4
[0], Id
.Data4
[1], Id
.Data4
[2], Id
.Data4
[3], Id
.Data4
[4], Id
.Data4
[5], Id
.Data4
[6],
2609 return reinterpret_cast<INT64
>(strId
.CPtr());
2611 case MCODE_V_ITEMCOUNT
:
2612 case MCODE_V_CURPOS
: {
2613 switch (Item
[FocusPos
]->Type
) {
2616 if (DropDownOpened
|| (Item
[FocusPos
]->Flags
& DIF_DROPDOWNLIST
))
2617 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2622 return ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->VMProcess(OpCode
, vParam
, iParam
);
2624 return Item
[FocusPos
]->ListPtr
->VMProcess(OpCode
, vParam
, iParam
);
2625 case DI_USERCONTROL
:
2627 if (OpCode
== MCODE_V_CURPOS
)
2628 return Item
[FocusPos
]->UCData
->CursorPos
.X
;
2632 case DI_RADIOBUTTON
:
2638 case MCODE_F_EDITOR_SEL
: {
2639 if (FarIsEdit(Item
[FocusPos
]->Type
)
2640 || (Item
[FocusPos
]->Type
== DI_COMBOBOX
2641 && !(DropDownOpened
|| (Item
[FocusPos
]->Flags
& DIF_DROPDOWNLIST
)))) {
2642 return ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->VMProcess(OpCode
, vParam
, iParam
);
2652 //////////////////////////////////////////////////////////////////////////
2655 Обработка данных от клавиатуры.
2656 Перекрывает BaseInput::ProcessKey.
2658 int Dialog::ProcessKey(FarKey Key
)
2660 CriticalSectionLock
Lock(CS
);
2661 _DIALOG(CleverSysLog
CL(L
"Dialog::ProcessKey"));
2662 _DIALOG(SysLog(L
"Param: Key=%ls", _FARKEY_ToName(Key
)));
2666 if (Key
== KEY_NONE
|| Key
== KEY_IDLE
) {
2667 DlgProc((HANDLE
)this, DN_ENTERIDLE
, 0, 0); // $ 28.07.2000 SVS Передадим этот факт в обработчик :-)
2671 if (Key
== KEY_KILLFOCUS
|| Key
== KEY_GOTFOCUS
) {
2672 DlgProc((HANDLE
)this, DN_ACTIVATEAPP
, Key
== KEY_KILLFOCUS
? FALSE
: TRUE
, 0);
2676 if (ProcessMoveDialog(Key
))
2679 // BugZ#488 - Shift=enter
2680 if (ShiftPressed
&& (Key
== KEY_ENTER
|| Key
== KEY_NUMENTER
) && !CtrlObject
->Macro
.IsExecuting()
2681 && Item
[FocusPos
]->Type
!= DI_BUTTON
) {
2682 Key
= Key
== KEY_ENTER
? KEY_SHIFTENTER
: KEY_SHIFTNUMENTER
;
2686 /*(Key>=KEY_MACRO_BASE && Key <=KEY_MACRO_ENDBASE) ||*/
2687 ((unsigned int)Key
>= KEY_OP_BASE
&& (unsigned int)Key
<= KEY_OP_ENDBASE
))
2688 && !DialogMode
.Check(DMODE_KEY
))
2689 if (DlgProc((HANDLE
)this, DN_KEY
, FocusPos
, Key
))
2692 if (!DialogMode
.Check(DMODE_SHOW
))
2695 // А ХЗ, может в этот момент изменилось состояние элемента!
2696 if (Item
[FocusPos
]->Flags
& DIF_HIDDEN
)
2699 // небольшая оптимизация
2700 if (Item
[FocusPos
]->Type
== DI_CHECKBOX
) {
2701 if (!(Item
[FocusPos
]->Flags
& DIF_3STATE
)) {
2702 if (Key
== KEY_MULTIPLY
) // в CheckBox 2-state Gray* не работает!
2705 if ((Key
== KEY_ADD
&& !Item
[FocusPos
]->Selected
)
2706 || (Key
== KEY_SUBTRACT
&& Item
[FocusPos
]->Selected
))
2710 // блок else не нужен, т.к. ниже клавиши будут обработаны...
2711 } else if (Key
== KEY_ADD
)
2713 else if (Key
== KEY_SUBTRACT
)
2715 else if (Key
== KEY_MULTIPLY
)
2718 if (Item
[FocusPos
]->Type
== DI_BUTTON
&& Key
== KEY_SPACE
)
2721 if (Item
[FocusPos
]->Type
== DI_LISTBOX
) {
2739 case KEY_MSWHEEL_UP
:
2740 case KEY_MSWHEEL_DOWN
:
2741 case KEY_MSWHEEL_LEFT
:
2742 case KEY_MSWHEEL_RIGHT
:
2745 VMenu
*List
= Item
[FocusPos
]->ListPtr
;
2746 int CurListPos
= List
->GetSelectPos();
2747 auto CheckedListItem
= List
->GetCheck(-1);
2748 List
->ProcessKey(Key
);
2749 int NewListPos
= List
->GetSelectPos();
2751 if (NewListPos
!= CurListPos
&& !DlgProc((HANDLE
)this, DN_LISTCHANGE
, FocusPos
, NewListPos
)) {
2752 if (!DialogMode
.Check(DMODE_SHOW
))
2755 List
->SetCheck(CheckedListItem
, CurListPos
);
2757 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[FocusPos
]->Flags
& DIF_HIDDEN
))
2758 ShowDialog(FocusPos
); // FocusPos
2761 if (!(Key
== KEY_ENTER
|| Key
== KEY_NUMENTER
) || (Item
[FocusPos
]->Flags
& DIF_LISTNOCLOSE
))
2770 Перед выводом диалога посылаем сообщение в обработчик
2771 и если вернули что надо, то выводим подсказку
2773 if (!Help::MkTopic(PluginNumber
,
2774 (const wchar_t *)DlgProc((HANDLE
)this, DN_HELP
, FocusPos
,
2775 (HelpTopic
? (LONG_PTR
)HelpTopic
: 0)),
2778 Help::Present(strStr
);
2785 ExitCode
= (Key
== KEY_BREAK
) ? -2 : -1;
2791 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2794 return Do_ProcessFirstCtrl();
2797 return Do_ProcessTab(Key
== KEY_TAB
);
2799 return Do_ProcessSpace();
2800 case KEY_CTRLNUMENTER
:
2801 case KEY_CTRLENTER
: {
2802 for (I
= 0; I
< ItemCount
; I
++)
2803 if (Item
[I
]->DefaultButton
) {
2804 if (Item
[I
]->Flags
& DIF_DISABLE
) {
2805 // ProcessKey(KEY_DOWN); // на твой вкус :-)
2809 if (!FarIsEdit(Item
[I
]->Type
))
2810 Item
[I
]->Selected
= 1;
2813 /* $ 18.05.2001 DJ */
2819 if (!DialogMode
.Check(DMODE_OLDSTYLE
)) {
2820 DialogMode
.Clear(DMODE_ENDLOOP
); // только если есть
2821 return TRUE
; // делать больше не чего
2826 if (Item
[FocusPos
]->Type
!= DI_COMBOBOX
&& FarIsEdit(Item
[FocusPos
]->Type
)
2827 && (Item
[FocusPos
]->Flags
& DIF_EDITOR
) && !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
2828 unsigned EditorLastPos
;
2830 for (EditorLastPos
= I
= FocusPos
; I
< ItemCount
; I
++)
2831 if (FarIsEdit(Item
[I
]->Type
) && (Item
[I
]->Flags
& DIF_EDITOR
))
2836 if (((DlgEdit
*)(Item
[EditorLastPos
]->ObjPtr
))->GetLength())
2839 for (I
= EditorLastPos
; I
> FocusPos
; I
--) {
2842 if (I
== FocusPos
+ 1)
2843 CurPos
= ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->GetCurPos();
2847 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->GetString(strStr
);
2848 int Length
= (int)strStr
.GetLength();
2849 ((DlgEdit
*)(Item
[I
]->ObjPtr
))
2850 ->SetString(CurPos
>= Length
? L
"" : strStr
.CPtr() + CurPos
);
2852 if (CurPos
< Length
)
2853 strStr
.Truncate(CurPos
);
2855 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetCurPos(0);
2856 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(strStr
);
2859 if (EditorLastPos
> FocusPos
) {
2860 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->SetCurPos(0);
2861 Do_ProcessNextCtrl(FALSE
, FALSE
);
2866 } else if (Item
[FocusPos
]->Type
== DI_BUTTON
) {
2867 Item
[FocusPos
]->Selected
= 1;
2869 // сообщение - "Кнокна кликнута"
2870 if (SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, FocusPos
, 0))
2873 if (Item
[FocusPos
]->Flags
& DIF_BTNNOCLOSE
)
2876 ExitCode
= FocusPos
;
2882 for (I
= 0; I
< ItemCount
; I
++) {
2883 if (Item
[I
]->DefaultButton
&& !(Item
[I
]->Flags
& DIF_BTNNOCLOSE
)) {
2884 if (Item
[I
]->Flags
& DIF_DISABLE
) {
2885 // ProcessKey(KEY_DOWN); // на твой вкус :-)
2889 // if (!(FarIsEdit(Item[I].Type) || Item[I].Type == DI_CHECKBOX || Item[I].Type == DI_RADIOBUTTON))
2890 // Item[I].Selected=1;
2898 ExitCode
= FocusPos
;
2904 3-х уровневое состояние
2905 Для чекбокса сюда попадем только в случае, если контрол
2906 имеет флаг DIF_3STATE
2912 if (Item
[FocusPos
]->Type
== DI_CHECKBOX
) {
2913 unsigned int CHKState
= (Key
== KEY_ADD
2915 : (Key
== KEY_SUBTRACT
2917 : ((Key
== KEY_MULTIPLY
) ? 2 : Item
[FocusPos
]->Selected
)));
2919 if (Item
[FocusPos
]->Selected
!= (int)CHKState
)
2920 if (SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, FocusPos
, CHKState
)) {
2921 Item
[FocusPos
]->Selected
= CHKState
;
2929 case KEY_SHIFTNUMPAD4
:
2930 case KEY_MSWHEEL_LEFT
:
2933 case KEY_SHIFTNUMPAD6
:
2934 case KEY_MSWHEEL_RIGHT
: {
2935 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2938 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2939 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(Key
);
2942 return MoveToCtrlHorizontal(Key
== KEY_RIGHT
|| Key
== KEY_NUMPAD6
);
2949 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2952 return MoveToCtrlVertical(Key
== KEY_UP
|| Key
== KEY_NUMPAD8
);
2954 // $ 27.04.2001 VVM - Обработка колеса мышки
2955 case KEY_MSWHEEL_UP
:
2956 case KEY_MSWHEEL_DOWN
:
2958 case KEY_CTRLNUMPAD8
:
2960 case KEY_CTRLNUMPAD2
:
2961 return ProcessOpenComboBox(Item
[FocusPos
]->Type
, Item
[FocusPos
], FocusPos
);
2962 // ЭТО перед default предпоследний!!!
2966 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2969 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
2970 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(Key
);
2975 // ЭТО перед default последний!!!
2979 if (Item
[FocusPos
]->Type
== DI_USERCONTROL
) // для user-типа вываливаем
2982 if (!(Item
[FocusPos
]->Flags
& DIF_EDITOR
)) {
2983 for (I
= 0; I
< ItemCount
; I
++)
2984 if (Item
[I
]->DefaultButton
) {
2995 if (!CheckDialogMode(DMODE_NOPLUGINS
)) {
2996 return FrameManager
->ProcessKey(Key
);
3000 // для DIF_EDITOR будет обработано ниже
3002 // if(Item[FocusPos].Type == DI_USERCONTROL) // для user-типа вываливаем
3004 if (Item
[FocusPos
]->Type
== DI_LISTBOX
) {
3005 VMenu
*List
= Item
[FocusPos
]->ListPtr
;
3006 int CurListPos
= List
->GetSelectPos();
3007 auto CheckedListItem
= List
->GetCheck(-1);
3008 List
->ProcessKey(Key
);
3009 int NewListPos
= List
->GetSelectPos();
3011 if (NewListPos
!= CurListPos
&& !DlgProc((HANDLE
)this, DN_LISTCHANGE
, FocusPos
, NewListPos
)) {
3012 if (!DialogMode
.Check(DMODE_SHOW
))
3015 List
->SetCheck(CheckedListItem
, CurListPos
);
3017 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[FocusPos
]->Flags
& DIF_HIDDEN
))
3018 ShowDialog(FocusPos
); // FocusPos
3024 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
3025 DlgEdit
*edt
= (DlgEdit
*)Item
[FocusPos
]->ObjPtr
;
3027 if (Key
== KEY_CTRLL
) // исключим смену режима RO для поля ввода с клавиатуры
3030 } else if (Key
== KEY_CTRLU
) {
3031 edt
->SetClearFlag(0);
3035 } else if ((Item
[FocusPos
]->Flags
& DIF_EDITOR
) && !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
3038 int CurPos
= edt
->GetCurPos();
3040 // В начале строки????
3041 if (!edt
->GetCurPos()) {
3042 // а "выше" тоже DIF_EDITOR?
3043 if (FocusPos
> 0 && (Item
[FocusPos
- 1]->Flags
& DIF_EDITOR
)) {
3044 // добавляем к предыдущему и...
3045 DlgEdit
*edt_1
= (DlgEdit
*)Item
[FocusPos
- 1]->ObjPtr
;
3046 edt_1
->GetString(strStr
);
3047 CurPos
= static_cast<int>(strStr
.GetLength());
3049 edt
->GetString(strAdd
);
3051 edt_1
->SetString(strStr
);
3053 for (I
= FocusPos
+ 1; I
< ItemCount
; I
++) {
3054 if (Item
[I
]->Flags
& DIF_EDITOR
) {
3056 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->GetString(strStr
);
3057 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(strStr
);
3060 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetString(L
"");
3061 } else // ага, значит FocusPos это есть последний из DIF_EDITOR
3063 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(L
"");
3068 Do_ProcessNextCtrl(TRUE
);
3069 edt_1
->SetCurPos(CurPos
);
3072 edt
->ProcessKey(Key
);
3079 for (I
= FocusPos
; I
< ItemCount
; I
++)
3080 if (Item
[I
]->Flags
& DIF_EDITOR
) {
3082 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->GetString(strStr
);
3083 ((DlgEdit
*)(Item
[I
- 1]->ObjPtr
))->SetString(strStr
);
3086 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetString(L
"");
3097 ! "...В редакторе команд меню нажмите home shift+end del
3098 блок не удаляется..."
3099 DEL у итемов, имеющих DIF_EDITOR, работал без учета
3102 if (FocusPos
< ItemCount
+ 1 && (Item
[FocusPos
+ 1]->Flags
& DIF_EDITOR
)) {
3103 int CurPos
= edt
->GetCurPos();
3104 int Length
= edt
->GetLength();
3105 int SelStart
, SelEnd
;
3106 edt
->GetSelection(SelStart
, SelEnd
);
3107 edt
->GetString(strStr
);
3109 if (SelStart
> -1) {
3110 FARString strEnd
= strStr
.CPtr() + SelEnd
;
3111 strStr
.Truncate(SelStart
);
3113 edt
->SetString(strStr
);
3114 edt
->SetCurPos(SelStart
);
3117 } else if (CurPos
>= Length
) {
3118 DlgEdit
*edt_1
= (DlgEdit
*)Item
[FocusPos
+ 1]->ObjPtr
;
3122 Решаем проблему, если Del нажали в позиции
3123 большей, чем длина строки
3125 if (CurPos
> Length
) {
3126 strStr
.Append(L
' ', CurPos
- Length
);
3130 edt_1
->GetString(strAdd
);
3131 edt_1
->SetString(strStr
+ strAdd
);
3132 ProcessKey(KEY_CTRLY
);
3133 edt
->SetCurPos(CurPos
);
3147 while (Item
[I
]->Flags
& DIF_EDITOR
)
3148 I
= ChangeFocus(I
, (Key
== KEY_PGUP
|| Key
== KEY_NUMPAD9
) ? -1 : 1, FALSE
);
3150 if (!(Item
[I
]->Flags
& DIF_EDITOR
))
3151 I
= ChangeFocus(I
, (Key
== KEY_PGUP
|| Key
== KEY_NUMPAD9
) ? 1 : -1, FALSE
);
3161 if (Key
== KEY_OP_XLAT
&& !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
3162 edt
->SetClearFlag(0);
3165 // иначе неправильно работает ctrl-end
3166 edt
->strLastStr
= edt
->GetStringAddr();
3167 edt
->LastPartLength
= static_cast<int>(edt
->strLastStr
.GetLength());
3169 Redraw(); // Перерисовка должна идти после DN_EDITCHANGE (imho)
3173 if (!(Item
[FocusPos
]->Flags
& DIF_READONLY
) || IsNavKey(Key
)) {
3174 // "только что ломанулись и начинать выделение с нуля"?
3175 if ((Opt
.Dialogs
.EditLine
& DLGEDITLINE_NEWSELONGOTFOCUS
) && Item
[FocusPos
]->SelStart
!= -1
3176 && PrevFocusPos
!= FocusPos
) { // && Item[FocusPos].SelEnd)
3178 edt
->Flags().Clear(FEDITLINE_MARKINGBLOCK
);
3179 PrevFocusPos
= FocusPos
;
3182 if (edt
->ProcessKey(Key
)) {
3183 if (Item
[FocusPos
]->Flags
& DIF_READONLY
)
3186 if ((Key
== KEY_CTRLEND
|| Key
== KEY_CTRLNUMPAD1
)
3187 && edt
->GetCurPos() == edt
->GetLength()) {
3188 if (edt
->LastPartLength
== -1)
3189 edt
->strLastStr
= edt
->GetStringAddr();
3191 strStr
= edt
->strLastStr
;
3192 int CurCmdPartLength
= static_cast<int>(strStr
.GetLength());
3193 edt
->HistoryGetSimilar(strStr
, edt
->LastPartLength
);
3195 if (edt
->LastPartLength
== -1) {
3196 edt
->strLastStr
= edt
->GetStringAddr();
3197 edt
->LastPartLength
= CurCmdPartLength
;
3200 edt
->SetString(strStr
);
3201 edt
->Select(edt
->LastPartLength
, static_cast<int>(strStr
.GetLength()));
3207 edt
->LastPartLength
= -1;
3209 if (Key
== KEY_CTRLSHIFTEND
|| Key
== KEY_CTRLSHIFTNUMPAD1
) {
3211 edt
->AutoComplete(true, false);
3215 Redraw(); // Перерисовка должна идти после DN_EDITCHANGE (imho)
3218 } else if (!(Key
& (KEY_ALT
| KEY_RALT
)))
3222 if (ProcessHighlighting(Key
, FocusPos
, FALSE
))
3225 return (Opt
.XLat
.EnableForDialogs
&& ProcessHighlighting(Key
, FocusPos
, TRUE
));
3231 void Dialog::ProcessKey(FarKey Key
, unsigned ItemPos
)
3233 unsigned SavedFocusPos
= FocusPos
;
3236 if (FocusPos
== ItemPos
)
3237 FocusPos
= SavedFocusPos
;
3240 //////////////////////////////////////////////////////////////////////////
3243 Обработка данных от "мыши".
3244 Перекрывает BaseInput::ProcessMouse.
3250 int Dialog::ProcessMouse(MOUSE_EVENT_RECORD
*MouseEvent
)
3252 CriticalSectionLock
Lock(CS
);
3258 if (!DialogMode
.Check(DMODE_SHOW
))
3261 if (DialogMode
.Check(DMODE_MOUSEEVENT
)) {
3262 if (!DlgProc((HANDLE
)this, DN_MOUSEEVENT
, 0, (LONG_PTR
)MouseEvent
))
3266 if (!DialogMode
.Check(DMODE_SHOW
))
3269 MsX
= MouseEvent
->dwMousePosition
.X
;
3270 MsY
= MouseEvent
->dwMousePosition
.Y
;
3272 // for (I=0;I<ItemCount;I++)
3273 for (I
= ItemCount
- 1; I
!= (unsigned)-1; I
--) {
3274 if (Item
[I
]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))
3277 Type
= Item
[I
]->Type
;
3279 if (Type
== DI_LISTBOX
&& MsY
>= Y1
+ Item
[I
]->Y1
&& MsY
<= Y1
+ Item
[I
]->Y2
3280 && MsX
>= X1
+ Item
[I
]->X1
&& MsX
<= X1
+ Item
[I
]->X2
) {
3281 VMenu
*List
= Item
[I
]->ListPtr
;
3282 int Pos
= List
->GetSelectPos();
3283 auto CheckedListItem
= List
->GetCheck(-1);
3285 if ((MouseEvent
->dwButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)) {
3286 if (FocusPos
!= I
) {
3291 if (MouseEvent
->dwEventFlags
!= DOUBLE_CLICK
3292 && !(Item
[I
]->IFlags
.Flags
3293 & (DLGIIF_LISTREACTIONFOCUS
| DLGIIF_LISTREACTIONNOFOCUS
))) {
3295 List
->ProcessMouse(MouseEvent
);
3296 int NewListPos
= List
->GetSelectPos();
3298 if (NewListPos
!= Pos
3299 && !SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)NewListPos
)) {
3300 List
->SetCheck(CheckedListItem
, Pos
);
3302 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[I
]->Flags
& DIF_HIDDEN
))
3303 ShowDialog(I
); // FocusPos
3307 } else if (!SendDlgMessage((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
)) {
3309 List
->ProcessMouse(MouseEvent
);
3310 int NewListPos
= List
->GetSelectPos();
3312 (MsX
== X1
+ Item
[I
]->X2
&& MsY
>= Y1
+ Item
[I
]->Y1
&& MsY
<= Y1
+ Item
[I
]->Y2
)
3313 && (List
->CheckFlags(VMENU_LISTBOX
| VMENU_ALWAYSSCROLLBAR
)
3314 || Opt
.ShowMenuScrollbar
);
3316 if (!InScroolBar
&& // вне скроллбара и
3317 NewListPos
!= Pos
&& // позиция изменилась и
3318 !SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)NewListPos
)) // и плагин сказал в морг
3320 List
->SetCheck(CheckedListItem
, Pos
);
3322 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[I
]->Flags
& DIF_HIDDEN
))
3323 ShowDialog(I
); // FocusPos
3327 if (!InScroolBar
&& !(Item
[I
]->Flags
& DIF_LISTNOCLOSE
)) {
3336 if (SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)Pos
)) {
3337 if (MsX
== X1
+ Item
[I
]->X2
&& MsY
>= Y1
+ Item
[I
]->Y1
&& MsY
<= Y1
+ Item
[I
]->Y2
)
3338 List
->ProcessMouse(MouseEvent
); // забыл проверить на клик на скролбар (KM)
3340 ProcessKey(KEY_ENTER
, I
);
3348 if (!MouseEvent
->dwButtonState
3349 || SendDlgMessage((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
)) {
3350 if ((I
== FocusPos
&& (Item
[I
]->IFlags
.Flags
& DLGIIF_LISTREACTIONFOCUS
))
3351 || (I
!= FocusPos
&& (Item
[I
]->IFlags
.Flags
& DLGIIF_LISTREACTIONNOFOCUS
))) {
3352 List
->ProcessMouse(MouseEvent
);
3353 int NewListPos
= List
->GetSelectPos();
3355 if (NewListPos
!= Pos
3356 && !SendDlgMessage((HANDLE
)this, DN_LISTCHANGE
, I
, (LONG_PTR
)NewListPos
)) {
3357 List
->SetCheck(CheckedListItem
, Pos
);
3359 if (DialogMode
.Check(DMODE_SHOW
) && !(Item
[I
]->Flags
& DIF_HIDDEN
))
3360 ShowDialog(I
); // FocusPos
3371 if (MsX
< X1
|| MsY
< Y1
|| MsX
> X2
|| MsY
> Y2
) {
3372 if (DialogMode
.Check(DMODE_CLICKOUTSIDE
)
3373 && !DlgProc((HANDLE
)this, DN_MOUSECLICK
, -1, (LONG_PTR
)MouseEvent
)) {
3374 if (!DialogMode
.Check(DMODE_SHOW
))
3377 // if (!(MouseEvent->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) && PrevLButtonPressed && ScreenObject::CaptureMouseObject)
3378 if (!(MouseEvent
->dwButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)
3379 && (PrevMouseButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)
3380 && (Opt
.Dialogs
.MouseButton
& DMOUSEBUTTON_LEFT
))
3381 ProcessKey(KEY_ESC
);
3382 // else if (!(MouseEvent->dwButtonState & RIGHTMOST_BUTTON_PRESSED) && PrevRButtonPressed && ScreenObject::CaptureMouseObject)
3383 else if (!(MouseEvent
->dwButtonState
& RIGHTMOST_BUTTON_PRESSED
)
3384 && (PrevMouseButtonState
& RIGHTMOST_BUTTON_PRESSED
)
3385 && (Opt
.Dialogs
.MouseButton
& DMOUSEBUTTON_RIGHT
))
3386 ProcessKey(KEY_ENTER
);
3389 if (MouseEvent
->dwButtonState
)
3390 DialogMode
.Set(DMODE_CLICKOUTSIDE
);
3392 // ScreenObject::SetCapture(this);
3396 if (!MouseEvent
->dwButtonState
) {
3397 DialogMode
.Clear(DMODE_CLICKOUTSIDE
);
3398 // ScreenObject::SetCapture(nullptr);
3402 if (!MouseEvent
->dwEventFlags
|| MouseEvent
->dwEventFlags
== DOUBLE_CLICK
) {
3403 // первый цикл - все за исключением рамок.
3404 // for (I=0; I < ItemCount;I++)
3405 for (I
= ItemCount
- 1; I
!= (unsigned)-1; I
--) {
3406 if (Item
[I
]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))
3409 GetItemRect(I
, Rect
);
3414 //_D(SysLog(L"? %2d) Rect (%2d,%2d) (%2d,%2d) '%ls'",I,Rect.left,Rect.top,Rect.right,Rect.bottom,Item[I].Data));
3416 if (MsX
>= Rect
.Left
&& MsY
>= Rect
.Top
&& MsX
<= Rect
.Right
&& MsY
<= Rect
.Bottom
) {
3417 // для прозрачных :-)
3418 if (Item
[I
]->Type
== DI_SINGLEBOX
|| Item
[I
]->Type
== DI_DOUBLEBOX
) {
3419 // если на рамке, то...
3420 if (((MsX
== Rect
.Left
|| MsX
== Rect
.Right
) && MsY
>= Rect
.Top
&& MsY
<= Rect
.Bottom
)
3422 ((MsY
== Rect
.Top
|| MsY
== Rect
.Bottom
) && MsX
>= Rect
.Left
3423 && MsX
<= Rect
.Right
)) // hor
3425 if (DlgProc((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
))
3428 if (!DialogMode
.Check(DMODE_SHOW
))
3434 if (Item
[I
]->Type
== DI_USERCONTROL
) {
3435 // для user-типа подготовим координаты мыши
3436 MouseEvent
->dwMousePosition
.X
-= Rect
.Left
;
3437 MouseEvent
->dwMousePosition
.Y
-= Rect
.Top
;
3440 //_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));
3441 if (DlgProc((HANDLE
)this, DN_MOUSECLICK
, I
, (LONG_PTR
)MouseEvent
))
3444 if (!DialogMode
.Check(DMODE_SHOW
))
3447 if (Item
[I
]->Type
== DI_USERCONTROL
) {
3457 if ((MouseEvent
->dwButtonState
& FROM_LEFT_1ST_BUTTON_PRESSED
)) {
3458 // for (I=0;I<ItemCount;I++)
3460 for (I
= ItemCount
- 1; I
!= (unsigned)-1; I
--) {
3461 // Исключаем из списка оповещаемых о мыши недоступные элементы
3462 if (Item
[I
]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))
3465 Type
= Item
[I
]->Type
;
3467 GetItemRect(I
, Rect
);
3472 if (ItemHasDropDownArrow(Item
[I
]))
3475 if (MsX
>= Rect
.Left
&& MsY
>= Rect
.Top
&& MsX
<= Rect
.Right
&& MsY
<= Rect
.Bottom
) {
3476 /* ********************************************************** */
3477 if (FarIsEdit(Type
)) {
3480 + Сделаем так, чтобы ткнув мышкой в DropDownList
3481 список раскрывался сам.
3482 Есть некоторая глюкавость - когда список раскрыт и мы
3483 мышой переваливаем на другой элемент, то список закрывается
3484 но перехода реального на указанный элемент диалога не происходит
3486 int EditX1
, EditY1
, EditX2
, EditY2
;
3487 DlgEdit
*EditLine
= (DlgEdit
*)(Item
[I
]->ObjPtr
);
3488 EditLine
->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
3490 if (MsY
== EditY1
&& Type
== DI_COMBOBOX
&& (Item
[I
]->Flags
& DIF_DROPDOWNLIST
)
3491 && MsX
>= EditX1
&& MsX
<= EditX2
+ 1) {
3492 EditLine
->SetClearFlag(0);
3497 ProcessOpenComboBox(Item
[I
]->Type
, Item
[I
], I
);
3504 if (EditLine
->ProcessMouse(MouseEvent
)) {
3505 EditLine
->SetClearFlag(0); // а может это делать в самом edit?
3509 ! Оказалось нужно перерисовывать весь диалог иначе
3510 не снимался признак активности с комбобокса с которго уходим.
3512 ShowDialog(); // нужен ли только один контрол или весь диалог?
3515 // Проверка на DI_COMBOBOX здесь лишняя. Убрана (KM).
3516 if (MsX
== EditX2
+ 1 && MsY
== EditY1
&& ItemHasDropDownArrow(Item
[I
])) {
3517 EditLine
->SetClearFlag(0); // раз уж покусились на, то и...
3521 if (!(Item
[I
]->Flags
& DIF_HIDDEN
))
3524 ProcessOpenComboBox(Item
[I
]->Type
, Item
[I
], I
);
3531 /* ********************************************************** */
3532 if (Type
== DI_BUTTON
&& MsY
== Y1
+ Item
[I
]->Y1
3533 && MsX
< X1
+ Item
[I
]->X1
+ HiStrCellsCount(Item
[I
]->strData
)) {
3537 while (IsMouseButtonPressed())
3540 if (MouseX
< X1
|| MouseX
> X1
+ Item
[I
]->X1
+ HiStrCellsCount(Item
[I
]->strData
) + 4
3541 || MouseY
!= Y1
+ Item
[I
]->Y1
) {
3548 ProcessKey(KEY_ENTER
, I
);
3552 /* ********************************************************** */
3553 if ((Type
== DI_CHECKBOX
|| Type
== DI_RADIOBUTTON
) && MsY
== Y1
+ Item
[I
]->Y1
3554 && MsX
< (X1
+ Item
[I
]->X1
+ HiStrCellsCount(Item
[I
]->strData
) + 4
3555 - ((Item
[I
]->Flags
& DIF_MOVESELECT
) != 0))) {
3557 ProcessKey(KEY_SPACE
, I
);
3561 } // for (I=0;I<ItemCount;I++)
3563 // ДЛЯ MOUSE-Перемещалки:
3564 // Сюда попадаем в том случае, если мышь не попала на активные элементы
3567 if (DialogMode
.Check(DMODE_ISCANMOVE
)) {
3568 // DialogMode.Set(DMODE_DRAGGED);
3573 // запомним delta места хватания и Left-Top диалогового окна
3574 MsX
= abs(X1
- MouseX
);
3575 MsY
= abs(Y1
- MouseY
);
3576 int NeedSendMsg
= 0;
3579 DWORD Mb
= IsMouseButtonPressed();
3582 if (Mb
== FROM_LEFT_1ST_BUTTON_PRESSED
) // still dragging
3584 int AdjX
= 0, AdjY
= 0;
3592 if (MouseX
== PrevMouseX
)
3597 if (MouseY
== PrevMouseY
)
3602 NX2
= mx
+ (X2
- X1
);
3605 NY2
= my
+ (Y2
- Y1
);
3609 // "А был ли мальчик?" (про холостой ход)
3610 if (OX1
!= NX1
|| OY1
!= NY1
) {
3611 if (!NeedSendMsg
) // тыкс, а уже посылку делали в диалоговую процедуру?
3615 if (!DlgProc((HANDLE
)this, DN_DRAGGED
, 0, 0)) // а может нас обломали?
3616 break; // валим отсель...плагин сказал - в морг перемещения
3618 if (!DialogMode
.Check(DMODE_SHOW
))
3622 // Да, мальчик был. Зачнем...
3632 AdjustEditPos(AdjX
, AdjY
); //?
3637 } else if (Mb
== RIGHTMOST_BUTTON_PRESSED
) // abort
3641 AdjustEditPos(OldX1
- X1
, OldY1
- Y1
);
3646 DialogMode
.Clear(DMODE_DRAGGED
);
3647 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, TRUE
);
3649 if (DialogMode
.Check(DMODE_SHOW
))
3653 } else // release key, drop dialog
3655 if (OldX1
!= X1
|| OldX2
!= X2
|| OldY1
!= Y1
|| OldY2
!= Y2
) {
3657 DialogMode
.Clear(DMODE_DRAGGED
);
3658 DlgProc((HANDLE
)this, DN_DRAGGED
, 1, 0);
3660 if (DialogMode
.Check(DMODE_SHOW
))
3674 int Dialog::ProcessOpenComboBox(int Type
, DialogItemEx
*CurItem
, unsigned CurFocusPos
)
3676 CriticalSectionLock
Lock(CS
);
3678 DlgEdit
*CurEditLine
;
3680 // для user-типа вываливаем
3681 if (Type
== DI_USERCONTROL
)
3684 CurEditLine
= ((DlgEdit
*)(CurItem
->ObjPtr
));
3686 if (FarIsEdit(Type
) && (CurItem
->Flags
& DIF_HISTORY
) && Opt
.Dialogs
.EditHistory
3687 && !CurItem
->strHistory
.IsEmpty() && !(CurItem
->Flags
& DIF_READONLY
)) {
3688 // Передаем то, что в строке ввода в функцию выбора из истории для выделения нужного пункта в истории.
3689 CurEditLine
->GetString(strStr
);
3690 SelectFromEditHistory(CurItem
, CurEditLine
, CurItem
->strHistory
, strStr
);
3692 // $ 18.07.2000 SVS: +обработка DI_COMBOBOX - выбор из списка!
3693 else if (Type
== DI_COMBOBOX
&& CurItem
->ListPtr
&& !(CurItem
->Flags
& DIF_READONLY
)
3694 && CurItem
->ListPtr
->GetItemCount() > 0) //??
3696 SelectFromComboBox(CurItem
, CurEditLine
, CurItem
->ListPtr
);
3702 unsigned Dialog::ProcessRadioButton(unsigned CurRB
)
3704 CriticalSectionLock
Lock(CS
);
3705 unsigned PrevRB
= CurRB
, J
;
3708 for (I
= CurRB
;; I
--) {
3712 if (Item
[I
]->Type
== DI_RADIOBUTTON
&& (Item
[I
]->Flags
& DIF_GROUP
))
3715 if (Item
[I
- 1]->Type
!= DI_RADIOBUTTON
)
3722 При изменении состояния каждого элемента посылаем сообщение
3723 посредством функции SendDlgMessage - в ней делается все!
3725 J
= Item
[I
]->Selected
;
3726 Item
[I
]->Selected
= 0;
3733 } while (I
< ItemCount
&& Item
[I
]->Type
== DI_RADIOBUTTON
&& !(Item
[I
]->Flags
& DIF_GROUP
));
3735 Item
[CurRB
]->Selected
= 1;
3739 При изменении состояния каждого элемента посылаем сообщение
3740 посредством функции SendDlgMessage - в ней делается все!
3742 if (!SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, PrevRB
, 0)
3743 || !SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, CurRB
, 1)) {
3744 // вернем назад, если пользователь не захотел...
3745 Item
[CurRB
]->Selected
= 0;
3746 Item
[PrevRB
]->Selected
= 1;
3753 int Dialog::Do_ProcessFirstCtrl()
3755 CriticalSectionLock
Lock(CS
);
3757 if (FarIsEdit(Item
[FocusPos
]->Type
)) {
3758 ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(KEY_HOME
);
3761 for (unsigned I
= 0; I
< ItemCount
; I
++)
3762 if (IsItemFocusable(Item
[I
])) {
3772 int Dialog::Do_ProcessNextCtrl(int Up
, BOOL IsRedraw
)
3774 CriticalSectionLock
Lock(CS
);
3775 unsigned OldPos
= FocusPos
;
3776 unsigned PrevPos
= 0;
3778 if (FarIsEdit(Item
[FocusPos
]->Type
) && (Item
[FocusPos
]->Flags
& DIF_EDITOR
))
3779 PrevPos
= ((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->GetCurPos();
3781 unsigned I
= ChangeFocus(FocusPos
, Up
? -1 : 1, FALSE
);
3782 Item
[FocusPos
]->Focus
= 0;
3786 if (FarIsEdit(Item
[I
]->Type
) && (Item
[I
]->Flags
& DIF_EDITOR
))
3787 ((DlgEdit
*)(Item
[I
]->ObjPtr
))->SetCurPos(PrevPos
);
3789 if (Item
[FocusPos
]->Type
== DI_RADIOBUTTON
&& (Item
[I
]->Flags
& DIF_MOVESELECT
))
3790 ProcessKey(KEY_SPACE
);
3791 else if (IsRedraw
) {
3793 ShowDialog(FocusPos
);
3799 int Dialog::MoveToCtrlHorizontal(int right
)
3801 int MinDist
= RealWidth
,
3803 RightBorder
= RealWidth
,
3807 for (unsigned int I
= 0; I
< ItemCount
; I
++) {
3808 //first, let's find nearest borders
3809 if (IsItemHorizontalSeparator(Item
[I
])) {
3810 if (Item
[I
]->X1
< Item
[FocusPos
]->X1
){
3811 if (LeftBorder
< Item
[I
]->X1
) {
3812 LeftBorder
= Item
[I
]->X1
;
3814 } else if (Item
[I
]->X1
> Item
[FocusPos
]->X1
) {
3815 if (RightBorder
> Item
[I
]->X1
) {
3816 RightBorder
= Item
[I
]->X1
;
3821 //find nearest item _inside_ nearest borders
3822 if (I
!= FocusPos
&& IsItemFocusable(Item
[I
]) && Item
[I
]->Y1
== Item
[FocusPos
]->Y1
) {
3823 Dist
= Item
[I
]->X1
- Item
[FocusPos
]->X1
;
3825 if ((!right
&& Dist
< 0 &&(Item
[I
]->X1
> LeftBorder
))
3826 || (right
&& Dist
> 0 &&(Item
[I
]->X1
< RightBorder
))
3828 if (abs(Dist
) < MinDist
) {
3829 MinDist
= abs(Dist
);
3836 //MinDist still equal to RealWidth,
3837 //it means current line inside block of items has no focusable controls
3838 //fallback to Do_ProcessNextCtrl
3839 if (MinDist
< RealWidth
) {
3840 ChangeFocus2(MinPos
);
3842 if (Item
[MinPos
]->Flags
& DIF_MOVESELECT
) {
3848 return Do_ProcessNextCtrl(!right
);
3855 int Dialog::MoveToCtrlVertical(int up
)
3857 int MinDist
= RealHeight
,
3859 BottomBorder
= RealHeight
,
3863 for (unsigned int I
= 0; I
< ItemCount
; I
++) {
3864 //first, let's find nearest borders
3865 if (IsItemVerticalSeparator(Item
[I
])) {
3866 if (Item
[I
]->Y1
< Item
[FocusPos
]->Y1
){
3867 if (UpperBorder
< Item
[I
]->Y1
) {
3868 UpperBorder
= Item
[I
]->Y1
;
3870 } else if (Item
[I
]->Y1
> Item
[FocusPos
]->Y1
) {
3871 if (BottomBorder
> Item
[I
]->Y1
) {
3872 BottomBorder
= Item
[I
]->Y1
;
3877 //find nearest item _inside_ nearest borders
3878 if (I
!= FocusPos
&& IsItemFocusable(Item
[I
]) && Item
[I
]->X1
== Item
[FocusPos
]->X1
) {
3879 Dist
= Item
[I
]->Y1
- Item
[FocusPos
]->Y1
;
3881 if ((up
&& Dist
< 0 && (Item
[I
]->Y1
> UpperBorder
))
3882 || (!up
&& Dist
> 0 && (Item
[I
]->Y1
< BottomBorder
))
3884 if (abs(Dist
) < MinDist
) {
3885 MinDist
= abs(Dist
);
3892 //current column inside block of items has no focusable controls
3893 //gap more than one line considered as "native" block separator
3894 //fallback to Do_ProcessNextCtrl
3896 ChangeFocus2(MinPos
);
3898 if (Item
[MinPos
]->Flags
& DIF_MOVESELECT
) {
3904 return Do_ProcessNextCtrl(up
);
3910 int Dialog::Do_ProcessTab(int Next
)
3912 CriticalSectionLock
Lock(CS
);
3915 if (ItemCount
> 1) {
3916 // Must check for DI_EDIT since DIF_EDITOR and DIF_LISTNOAMPERSAND are equal
3917 if (Item
[FocusPos
]->Type
==DI_EDIT
&& (Item
[FocusPos
]->Flags
& DIF_EDITOR
)) {
3920 while (Item
[I
]->Type
==DI_EDIT
&& (Item
[I
]->Flags
& DIF_EDITOR
))
3921 I
= ChangeFocus(I
, Next
? 1 : -1, TRUE
);
3923 I
= ChangeFocus(FocusPos
, Next
? 1 : -1, TRUE
);
3927 && Item
[I
]->Type
== DI_EDIT
&& Item
[I
- 1]->Type
== DI_EDIT
3928 && (Item
[I
]->Flags
& DIF_EDITOR
) && (Item
[I
- 1]->Flags
& DIF_EDITOR
)
3929 && !((DlgEdit
*)Item
[I
]->ObjPtr
)->GetLength())
3941 int Dialog::Do_ProcessSpace()
3943 CriticalSectionLock
Lock(CS
);
3946 if (Item
[FocusPos
]->Type
== DI_CHECKBOX
) {
3947 int OldSelected
= Item
[FocusPos
]->Selected
;
3949 if (Item
[FocusPos
]->Flags
& DIF_3STATE
) {
3950 Item
[FocusPos
]->Selected
= (Item
[FocusPos
]->Selected
+ 1) % 3;
3952 Item
[FocusPos
]->Selected
= !Item
[FocusPos
]->Selected
;
3954 OldFocusPos
= FocusPos
;
3956 if (!SendDlgMessage((HANDLE
)this, DN_BTNCLICK
, FocusPos
, Item
[FocusPos
]->Selected
))
3957 Item
[OldFocusPos
]->Selected
= OldSelected
;
3961 } else if (Item
[FocusPos
]->Type
== DI_RADIOBUTTON
) {
3962 FocusPos
= ProcessRadioButton(FocusPos
);
3965 } else if (FarIsEdit(Item
[FocusPos
]->Type
) && !(Item
[FocusPos
]->Flags
& DIF_READONLY
)) {
3966 if (((DlgEdit
*)(Item
[FocusPos
]->ObjPtr
))->ProcessKey(KEY_SPACE
)) {
3967 Redraw(); // Перерисовка должна идти после DN_EDITCHANGE (imho)
3976 //////////////////////////////////////////////////////////////////////////
3979 Изменяет фокус ввода (воздействие клавишами
3980 KEY_TAB, KEY_SHIFTTAB, KEY_UP, KEY_DOWN,
3981 а так же Alt-HotKey)
3985 Довесок для сообщений DN_KILLFOCUS & DN_SETFOCUS
3989 Добавка для DI_USERCONTROL
3991 unsigned Dialog::ChangeFocus(unsigned CurFocusPos
, int Step
, int SkipGroup
)
3993 CriticalSectionLock
Lock(CS
);
3994 unsigned OrigFocusPos
= CurFocusPos
;
3997 CurFocusPos
+= Step
;
3999 if ((int)CurFocusPos
< 0) {
4000 CurFocusPos
= ItemCount
- 1;
4003 if (CurFocusPos
>= ItemCount
) {
4007 if (IsItemFocusable(Item
[CurFocusPos
])) {
4008 //move straight to selected radio when SkipGroup is true
4009 if (Item
[CurFocusPos
]->Type
== DI_RADIOBUTTON
&& !(SkipGroup
&& Item
[CurFocusPos
]->Selected
)) {
4016 // убираем зацикливание с последующим подвисанием :-)
4017 if (OrigFocusPos
== CurFocusPos
) {
4022 return (CurFocusPos
);
4025 //////////////////////////////////////////////////////////////////////////
4028 Изменяет фокус ввода между двумя элементами.
4029 Вынесен отдельно с тем, чтобы обработать DN_KILLFOCUS & DM_SETFOCUS
4031 void Dialog::ChangeFocus2(unsigned SetFocusPos
)
4033 CriticalSectionLock
Lock(CS
);
4034 int FocusPosNeed
= -1;
4036 if (IsItemFocusable(Item
[SetFocusPos
])) {
4037 if (DialogMode
.Check(DMODE_INITOBJECTS
)) {
4038 FocusPosNeed
= (int)DlgProc((HANDLE
)this, DN_KILLFOCUS
, FocusPos
, 0);
4040 if (!DialogMode
.Check(DMODE_SHOW
))
4044 if (FocusPosNeed
>= 0 && FocusPosNeed
< (int)ItemCount
&& IsItemFocusable(Item
[FocusPosNeed
]))
4045 SetFocusPos
= FocusPosNeed
;
4047 Item
[FocusPos
]->Focus
= 0;
4049 // "снимать выделение при потере фокуса?"
4050 if (FarIsEdit(Item
[FocusPos
]->Type
)
4051 && !(Item
[FocusPos
]->Type
== DI_COMBOBOX
&& (Item
[FocusPos
]->Flags
& DIF_DROPDOWNLIST
))) {
4052 DlgEdit
*EditPtr
= (DlgEdit
*)Item
[FocusPos
]->ObjPtr
;
4053 EditPtr
->GetSelection(Item
[FocusPos
]->SelStart
, Item
[FocusPos
]->SelEnd
);
4055 if ((Opt
.Dialogs
.EditLine
& DLGEDITLINE_CLEARSELONKILLFOCUS
)) {
4056 EditPtr
->Select(-1, 0);
4060 Item
[SetFocusPos
]->Focus
= 1;
4062 // "не восстанавливать выделение при получении фокуса?"
4063 if (FarIsEdit(Item
[SetFocusPos
]->Type
)
4064 && !(Item
[SetFocusPos
]->Type
== DI_COMBOBOX
4065 && (Item
[SetFocusPos
]->Flags
& DIF_DROPDOWNLIST
))) {
4066 DlgEdit
*EditPtr
= (DlgEdit
*)Item
[SetFocusPos
]->ObjPtr
;
4068 if (!(Opt
.Dialogs
.EditLine
& DLGEDITLINE_NOTSELONGOTFOCUS
)) {
4069 if (Opt
.Dialogs
.EditLine
& DLGEDITLINE_SELALLGOTFOCUS
)
4070 EditPtr
->Select(0, EditPtr
->GetStrSize());
4072 EditPtr
->Select(Item
[SetFocusPos
]->SelStart
, Item
[SetFocusPos
]->SelEnd
);
4074 EditPtr
->Select(-1, 0);
4077 // при получении фокуса ввода переместить курсор в конец строки?
4078 if (Opt
.Dialogs
.EditLine
& DLGEDITLINE_GOTOEOLGOTFOCUS
) {
4079 EditPtr
->SetCurPos(EditPtr
->GetStrSize());
4083 // проинформируем листбокс, есть ли у него фокус
4084 if (Item
[FocusPos
]->Type
== DI_LISTBOX
)
4085 Item
[FocusPos
]->ListPtr
->ClearFlags(VMENU_LISTHASFOCUS
);
4087 if (Item
[SetFocusPos
]->Type
== DI_LISTBOX
)
4088 Item
[SetFocusPos
]->ListPtr
->SetFlags(VMENU_LISTHASFOCUS
);
4090 SelectOnEntry(FocusPos
, FALSE
);
4091 SelectOnEntry(SetFocusPos
, TRUE
);
4093 PrevFocusPos
= FocusPos
;
4094 FocusPos
= SetFocusPos
;
4096 if (DialogMode
.Check(DMODE_INITOBJECTS
))
4097 DlgProc((HANDLE
)this, DN_GOTFOCUS
, FocusPos
, 0);
4102 Функция SelectOnEntry - выделение строки редактирования
4103 Обработка флага DIF_SELECTONENTRY
4105 void Dialog::SelectOnEntry(unsigned Pos
, BOOL Selected
)
4107 // if(!DialogMode.Check(DMODE_SHOW))
4109 if (FarIsEdit(Item
[Pos
]->Type
) && (Item
[Pos
]->Flags
& DIF_SELECTONENTRY
)
4110 // && PrevFocusPos != -1 && PrevFocusPos != Pos
4112 DlgEdit
*edt
= (DlgEdit
*)Item
[Pos
]->ObjPtr
;
4116 edt
->Select(0, edt
->GetLength());
4120 //_SVS(SysLog(L"Selected=%d edt->GetLength()=%d",Selected,edt->GetLength()));
4125 int Dialog::SetAutomation(WORD IDParent
, WORD id
, FarDialogItemFlags UncheckedSet
,
4126 FarDialogItemFlags UncheckedSkip
, FarDialogItemFlags CheckedSet
, FarDialogItemFlags CheckedSkip
,
4127 FarDialogItemFlags Checked3Set
, FarDialogItemFlags Checked3Skip
)
4129 CriticalSectionLock
Lock(CS
);
4132 if (IDParent
< ItemCount
&& (Item
[IDParent
]->Flags
& DIF_AUTOMATION
) && id
< ItemCount
4133 && IDParent
!= id
) // Сами себя не юзаем!
4135 Ret
= Item
[IDParent
]->AddAutomation(id
, UncheckedSet
, UncheckedSkip
, CheckedSet
, CheckedSkip
,
4136 Checked3Set
, Checked3Skip
);
4142 //////////////////////////////////////////////////////////////////////////
4145 Заполняем выпадающий список для ComboBox
4147 int Dialog::SelectFromComboBox(DialogItemEx
*CurItem
,
4148 DlgEdit
*EditLine
, // строка редактирования
4149 VMenu
*ComboBox
) // список строк
4151 CriticalSectionLock
Lock(CS
);
4153 int I
, Dest
, OriginalPos
;
4154 unsigned CurFocusPos
= FocusPos
;
4156 // if (EditX2 - EditX1 < 20)
4157 // EditX2 = EditX1 + 20;
4159 SetDropDownOpened(TRUE
); // Установим флаг "открытия" комбобокса.
4160 SetComboBoxPos(CurItem
);
4161 // Перед отрисовкой спросим об изменении цветовых атрибутов
4162 uint64_t RealColors
[VMENU_COLOR_COUNT
];
4163 FarListColors ListColors
= {0};
4164 ListColors
.ColorCount
= VMENU_COLOR_COUNT
;
4165 ListColors
.Colors
= RealColors
;
4166 ComboBox
->SetColors(nullptr);
4167 ComboBox
->GetColors(&ListColors
);
4169 if (DlgProc((HANDLE
)this, DN_CTLCOLORDLGLIST
, CurItem
->ID
, (LONG_PTR
)&ListColors
))
4170 ComboBox
->SetColors(&ListColors
);
4172 // Выставим то, что есть в строке ввода!
4173 // if(EditLine->GetDropDownBox()) //???
4174 EditLine
->GetString(strStr
);
4176 if (CurItem
->Flags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
))
4177 HiText2Str(strStr
, strStr
);
4179 ComboBox
->SetSelectPos(ComboBox
->FindItem(0, strStr
, LIFIND_EXACTMATCH
), 1);
4181 OriginalPos
= Dest
= ComboBox
->GetSelectPos();
4182 CurItem
->IFlags
.Set(DLGIIF_COMBOBOXNOREDRAWEDIT
);
4184 while (!ComboBox
->Done()) {
4185 if (!GetDropDownOpened()) {
4186 ComboBox
->ProcessKey(KEY_ESC
);
4190 INPUT_RECORD ReadRec
;
4191 FarKey Key
= ComboBox
->ReadInput(&ReadRec
);
4193 if (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTKEY
) && ReadRec
.EventType
== KEY_EVENT
) {
4194 if (DlgProc((HANDLE
)this, DN_KEY
, FocusPos
, Key
))
4196 } else if (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTMOUSE
) && ReadRec
.EventType
== MOUSE_EVENT
)
4197 if (!DlgProc((HANDLE
)this, DN_MOUSEEVENT
, 0, (LONG_PTR
)&ReadRec
.Event
.MouseEvent
))
4200 // здесь можно добавить что-то свое, например,
4201 I
= ComboBox
->GetSelectPos();
4203 if (Key
== KEY_TAB
) // Tab в списке - аналог Enter
4205 ComboBox
->ProcessKey(KEY_ENTER
);
4210 if (!DlgProc((HANDLE
)this, DN_LISTCHANGE
, CurFocusPos
, I
))
4211 ComboBox
->SetSelectPos(Dest
, Dest
< I
? -1 : 1); //????
4217 // во время навигации по DropDown листу - отобразим ЭТО дело в
4220 // Очень медленная реакция!
4221 if (EditLine
->GetDropDownBox())
4223 MenuItem
*CurCBItem
=ComboBox
->GetItemPtr();
4224 EditLine
->SetString(CurCBItem
->Name
);
4226 //EditLine->FastShow();
4232 // обработку multiselect ComboBox
4234 ComboBox
->ProcessInput();
4237 CurItem
->IFlags
.Clear(DLGIIF_COMBOBOXNOREDRAWEDIT
);
4238 ComboBox
->ClearDone();
4241 if (GetDropDownOpened()) // Закрылся не программным путём?
4242 Dest
= ComboBox
->Modal::GetExitCode();
4247 ComboBox
->SetSelectPos(OriginalPos
, 0); //????
4249 SetDropDownOpened(FALSE
); // Установим флаг "закрытия" комбобокса.
4256 // ComboBox->GetUserData(Str,MaxLen,Dest);
4257 MenuItemEx
*ItemPtr
= ComboBox
->GetItemPtr(Dest
);
4259 if (CurItem
->Flags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
)) {
4260 HiText2Str(strStr
, ItemPtr
->strName
);
4261 EditLine
->SetString(strStr
);
4263 EditLine
->SetString(ItemPtr
->strName
);
4265 EditLine
->SetLeftPos(0);
4270 //////////////////////////////////////////////////////////////////////////
4273 Заполняем выпадающий список из истории
4275 BOOL
Dialog::SelectFromEditHistory(DialogItemEx
*CurItem
, DlgEdit
*EditLine
, const wchar_t *HistoryName
,
4278 CriticalSectionLock
Lock(CS
);
4285 FARString strRegKey
= fmtSavedDialogHistory
;
4286 strRegKey
+= HistoryName
;
4287 History
DlgHist(HISTORYTYPE_DIALOG
, Opt
.DialogsHistoryCount
, strRegKey
.GetMB(), &Opt
.Dialogs
.EditHistory
,
4289 DlgHist
.ResetPosition();
4291 // создание пустого вертикального меню
4292 VMenu
HistoryMenu(L
"", nullptr, 0, Opt
.Dialogs
.CBoxMaxHeight
,
4293 VMENU_ALWAYSSCROLLBAR
| VMENU_COMBOBOX
| VMENU_NOTCHANGE
);
4294 HistoryMenu
.SetFlags(VMENU_SHOWAMPERSAND
);
4295 HistoryMenu
.SetBoxType(SHORT_SINGLE_BOX
);
4296 SetDropDownOpened(TRUE
); // Установим флаг "открытия" комбобокса.
4297 // запомним (для прорисовки)
4298 CurItem
->ListPtr
= &HistoryMenu
;
4299 ret
= DlgHist
.Select(HistoryMenu
, Opt
.Dialogs
.CBoxMaxHeight
, this, strStr
);
4300 // забудим (не нужен)
4301 CurItem
->ListPtr
= nullptr;
4302 SetDropDownOpened(FALSE
); // Установим флаг "закрытия" комбобокса.
4306 EditLine
->SetString(strStr
);
4307 EditLine
->SetLeftPos(0);
4308 EditLine
->SetClearFlag(0);
4316 //////////////////////////////////////////////////////////////////////////
4319 Работа с историей - добавление и reorder списка
4321 int Dialog::AddToEditHistory(const wchar_t *AddStr
, const wchar_t *HistoryName
)
4323 CriticalSectionLock
Lock(CS
);
4329 FARString strRegKey
= fmtSavedDialogHistory
;
4330 strRegKey
+= HistoryName
;
4331 History
DlgHist(HISTORYTYPE_DIALOG
, Opt
.DialogsHistoryCount
, strRegKey
.GetMB(), &Opt
.Dialogs
.EditHistory
,
4333 DlgHist
.AddToHistory(AddStr
);
4337 int Dialog::CheckHighlights(WORD CheckSymbol
, int StartPos
)
4339 CriticalSectionLock
Lock(CS
);
4346 for (I
= StartPos
; I
< (int)ItemCount
; I
++) {
4347 Type
= Item
[I
]->Type
;
4348 Flags
= Item
[I
]->Flags
;
4350 if ((!FarIsEdit(Type
) || (Type
== DI_COMBOBOX
&& (Flags
& DIF_DROPDOWNLIST
)))
4351 && !(Flags
& (DIF_SHOWAMPERSAND
| DIF_DISABLE
| DIF_HIDDEN
))) {
4352 const wchar_t *ChPtr
= wcschr(Item
[I
]->strData
, L
'&');
4357 if (Ch
&& Upper(CheckSymbol
) == Upper(Ch
))
4359 } else if (!CheckSymbol
)
4367 //////////////////////////////////////////////////////////////////////////
4370 Если жмакнули Alt-???
4372 int Dialog::ProcessHighlighting(FarKey Key
, unsigned FocusPos
, int Translate
)
4374 CriticalSectionLock
Lock(CS
);
4378 for (unsigned I
= 0; I
< ItemCount
; I
++) {
4379 Type
= Item
[I
]->Type
;
4380 Flags
= Item
[I
]->Flags
;
4382 if ((!FarIsEdit(Type
) || (Type
== DI_COMBOBOX
&& (Flags
& DIF_DROPDOWNLIST
)))
4383 && !(Flags
& (DIF_SHOWAMPERSAND
| DIF_DISABLE
| DIF_HIDDEN
)))
4384 if (IsKeyHighlighted(Item
[I
]->strData
, Key
, Translate
)) {
4385 int DisableSelect
= FALSE
;
4387 // Если ЭТО: DlgEdit(пред контрол) и DI_TEXT в одну строку, то...
4388 if (I
> 0 && Type
== DI_TEXT
&& // DI_TEXT
4389 FarIsEdit(Item
[I
- 1]->Type
) && // и редактор
4390 Item
[I
]->Y1
== Item
[I
- 1]->Y1
&& // и оба в одну строку
4391 (I
+ 1 < ItemCount
&& Item
[I
]->Y1
!= Item
[I
+ 1]->Y1
)) // ...и следующий контрол в другой строке
4393 // Сначала сообщим о случившемся факте процедуре обработки диалога, а потом...
4394 if (!DlgProc((HANDLE
)this, DN_HOTKEY
, I
, Key
))
4395 break; // сказали не продолжать обработку...
4397 // ... если предыдущий контрол задизаблен или невидим, тогда выходим.
4398 if ((Item
[I
- 1]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))) // и не задисаблен
4401 I
= ChangeFocus(I
, -1, FALSE
);
4402 DisableSelect
= TRUE
;
4403 } else if (Item
[I
]->Type
== DI_TEXT
|| Item
[I
]->Type
== DI_VTEXT
4404 || Item
[I
]->Type
== DI_SINGLEBOX
|| Item
[I
]->Type
== DI_DOUBLEBOX
) {
4405 if (I
+ 1 < ItemCount
) // ...и следующий контрол
4407 // Сначала сообщим о случившемся факте процедуре обработки диалога, а потом...
4408 if (!DlgProc((HANDLE
)this, DN_HOTKEY
, I
, Key
))
4409 break; // сказали не продолжать обработку...
4411 // ... если следующий контрол задизаблен или невидим, тогда выходим.
4412 if ((Item
[I
+ 1]->Flags
& (DIF_DISABLE
| DIF_HIDDEN
))) // и не задисаблен
4415 I
= ChangeFocus(I
, 1, FALSE
);
4416 DisableSelect
= TRUE
;
4420 // Сообщим о случивщемся факте процедуре обработки диалога
4421 if (!DlgProc((HANDLE
)this, DN_HOTKEY
, I
, Key
))
4422 break; // сказали не продолжать обработку...
4427 if ((Item
[I
]->Type
== DI_CHECKBOX
|| Item
[I
]->Type
== DI_RADIOBUTTON
)
4428 && (!DisableSelect
|| (Item
[I
]->Flags
& DIF_MOVESELECT
))) {
4431 } else if (Item
[I
]->Type
== DI_BUTTON
) {
4432 ProcessKey(KEY_ENTER
, I
);
4435 // при ComboBox`е - "вываливаем" последний //????
4436 else if (Item
[I
]->Type
== DI_COMBOBOX
) {
4437 ProcessOpenComboBox(Item
[I
]->Type
, Item
[I
], I
);
4438 // ProcessKey(KEY_CTRLDOWN);
4449 //////////////////////////////////////////////////////////////////////////
4451 функция подравнивания координат edit классов
4453 void Dialog::AdjustEditPos(int dx
, int dy
)
4455 CriticalSectionLock
Lock(CS
);
4456 DialogItemEx
*CurItem
;
4459 if (!DialogMode
.Check(DMODE_CREATEOBJECTS
))
4462 ScreenObject
*DialogScrObject
;
4464 for (unsigned I
= 0; I
< ItemCount
; I
++) {
4466 int Type
= CurItem
->Type
;
4468 if ((CurItem
->ObjPtr
&& FarIsEdit(Type
)) || (CurItem
->ListPtr
&& Type
== DI_LISTBOX
)) {
4469 if (Type
== DI_LISTBOX
)
4470 DialogScrObject
= (ScreenObject
*)CurItem
->ListPtr
;
4472 DialogScrObject
= (ScreenObject
*)CurItem
->ObjPtr
;
4474 DialogScrObject
->GetPosition(x1
, y1
, x2
, y2
);
4479 DialogScrObject
->SetPosition(x1
, y1
, x2
, y2
);
4483 ProcessCenterGroup();
4486 //////////////////////////////////////////////////////////////////////////
4488 Работа с доп. данными экземпляра диалога
4489 Пока простое копирование (присвоение)
4491 void Dialog::SetDialogData(LONG_PTR NewDataDialog
)
4493 DataDialog
= NewDataDialog
;
4496 //////////////////////////////////////////////////////////////////////////
4499 При расчётах времён копирования проще/надёжнее учитывать время ожидания
4500 пользовательских ответов в одном месте (здесь).
4501 Сброс этой переменной должен осуществляться перед общим началом операции
4507 + Для того, чтобы послать DM_CLOSE нужно переопределить Process
4509 static std::atomic
<int> s_in_dialog
{0};
4511 void Dialog::Process()
4513 // if(DialogMode.Check(DMODE_SMALLDIALOG))
4514 SetRestoreScreenMode(TRUE
);
4518 if (ExitCode
== -1) {
4521 DialogMode
.Set(DMODE_BEGINLOOP
);
4523 if (1 == ++s_in_dialog
) {
4524 btm
= GetProcessUptimeMSec();
4525 save
= WaitUserTime
;
4529 FrameManager
->ExecuteModal(this);
4530 save
+= (GetProcessUptimeMSec() - btm
);
4532 if (0 == --s_in_dialog
)
4533 WaitUserTime
= save
;
4537 for (unsigned i
= 0; i
< ItemCount
; i
++)
4538 DialogItemExToDialogItemEx(Item
[i
], &pSaveItemEx
[i
]);
4541 void Dialog::CloseDialog()
4543 CriticalSectionLock
Lock(CS
);
4544 GetDialogObjectsData();
4546 if (DlgProc((HANDLE
)this, DN_CLOSE
, ExitCode
, 0)) {
4547 DialogMode
.Set(DMODE_ENDLOOP
);
4550 if (DialogMode
.Check(DMODE_BEGINLOOP
)
4551 && (DialogMode
.Check(DMODE_MSGINTERNAL
) || FrameManager
->ManagerStarted())) {
4552 DialogMode
.Clear(DMODE_BEGINLOOP
);
4553 FrameManager
->DeleteFrame(this);
4556 _DIALOG(CleverSysLog
CL(L
"Close Dialog"));
4562 установка help topic'а и прочие радости, временно перетащенные сюда
4565 void Dialog::SetHelp(const wchar_t *Topic
)
4567 CriticalSectionLock
Lock(CS
);
4572 HelpTopic
= nullptr;
4574 if (Topic
&& *Topic
) {
4575 HelpTopic
= new (std::nothrow
) wchar_t[wcslen(Topic
) + 1];
4578 wcscpy(HelpTopic
, Topic
);
4582 void Dialog::ShowHelp()
4584 CriticalSectionLock
Lock(CS
);
4586 if (HelpTopic
&& *HelpTopic
) {
4587 Help::Present(HelpTopic
);
4591 void Dialog::ClearDone()
4593 CriticalSectionLock
Lock(CS
);
4595 DialogMode
.Clear(DMODE_ENDLOOP
);
4598 void Dialog::SetExitCode(int Code
)
4600 CriticalSectionLock
Lock(CS
);
4602 DialogMode
.Set(DMODE_ENDLOOP
);
4608 возвращаем наше название для меню по F12
4610 int Dialog::GetTypeAndName(FARString
&strType
, FARString
&strName
)
4612 CriticalSectionLock
Lock(CS
);
4613 strType
= Msg::DialogType
;
4615 const wchar_t *lpwszTitle
= GetDialogTitle();
4618 strName
= lpwszTitle
;
4620 return MODALTYPE_DIALOG
;
4623 int Dialog::GetMacroMode()
4625 return MACRO_DIALOG
;
4628 int Dialog::FastHide()
4630 return Opt
.AllCtrlAltShiftRule
& CASR_DIALOG
;
4633 void Dialog::ResizeConsole()
4635 CriticalSectionLock
Lock(CS
);
4637 DialogMode
.Set(DMODE_RESIZED
);
4643 COORD c
= {(SHORT
)(ScrX
+ 1), (SHORT
)(ScrY
+ 1)};
4644 SendDlgMessage(reinterpret_cast<HANDLE
>(this), DN_RESIZECONSOLE
, 0, reinterpret_cast<LONG_PTR
>(&c
));
4647 GetPosition(x1
, y1
, x2
, y2
);
4648 c
.X
= Min(x1
, ScrX
- 1);
4649 c
.Y
= Min(y1
, ScrY
- 1);
4650 if (c
.X
!= x1
|| c
.Y
!= y1
) {
4653 SendDlgMessage(reinterpret_cast<HANDLE
>(this), DM_MOVEDIALOG
, TRUE
, reinterpret_cast<LONG_PTR
>(&c
));
4654 Dialog::SetComboBoxPos();
4658 // void Dialog::OnDestroy()
4662 // Эта функция потеряла своё значение при текущем менеджере
4663 // и системе создания и уничтожения фреймов.
4665 // if(DialogMode.Check(DMODE_RESIZED))
4667 // Frame *BFrame=FrameManager->GetBottomFrame();
4669 // BFrame->UnlockRefresh();
4672 // А вот этот DM_KILLSAVESCREEN здесь только вредит. Удаление
4673 // диалога происходит без восстановления ShadowSaveScr и вот
4674 // они: "артефакты" непрорисовки.
4676 // SendDlgMessage((HANDLE)this,DM_KILLSAVESCREEN,0,0);
4680 LONG_PTR WINAPI
Dialog::DlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
4682 if (DialogMode
.Check(DMODE_ENDLOOP
))
4686 FarDialogEvent de
= {hDlg
, Msg
, Param1
, Param2
, 0};
4688 if (!reinterpret_cast<Dialog
*>(hDlg
)->CheckDialogMode(DMODE_NOPLUGINS
)) {
4689 if (CtrlObject
->Plugins
.ProcessDialogEvent(DE_DLGPROCINIT
, &de
))
4692 Result
= RealDlgProc(hDlg
, Msg
, Param1
, Param2
);
4693 if (!reinterpret_cast<Dialog
*>(hDlg
)->CheckDialogMode(DMODE_NOPLUGINS
)) {
4695 if (CtrlObject
->Plugins
.ProcessDialogEvent(DE_DLGPROCEND
, &de
))
4701 //////////////////////////////////////////////////////////////////////////
4704 функция обработки диалога (по умолчанию)
4705 Вот именно эта функция и является последним рубежом обработки диалога.
4706 Т.е. здесь должна быть ВСЯ обработка ВСЕХ сообщений!!!
4708 LONG_PTR WINAPI
DefDlgProc(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
4710 _DIALOG(CleverSysLog
CL(L
"Dialog.DefDlgProc()"));
4711 _DIALOG(SysLog(L
"hDlg=%p, Msg=%ls, Param1=%d (0x%08X), Param2=%d (0x%08X)", hDlg
, _DLGMSG_ToName(Msg
),
4712 Param1
, Param1
, Param2
, Param2
));
4714 if (!hDlg
|| hDlg
== INVALID_HANDLE_VALUE
)
4717 FarDialogEvent de
= {hDlg
, Msg
, Param1
, Param2
, 0};
4719 if (!reinterpret_cast<Dialog
*>(hDlg
)->CheckDialogMode(DMODE_NOPLUGINS
)) {
4720 if (CtrlObject
->Plugins
.ProcessDialogEvent(DE_DEFDLGPROCINIT
, &de
)) {
4724 Dialog
*Dlg
= (Dialog
*)hDlg
;
4725 CriticalSectionLock
Lock(Dlg
->CS
);
4726 DialogItemEx
*CurItem
= nullptr;
4731 return FALSE
; // изменений не было!
4733 return TRUE
; // согласен с закрытием
4735 return -1; // "Согласен с потерей фокуса"
4737 return 0; // always 0
4739 return Param2
; // что передали, то и...
4741 return TRUE
; // согласен с перемещалкой.
4742 case DN_DRAWDIALOGDONE
: {
4743 if (Param1
== 1) // Нужно отрисовать "салазки"?
4747 вывод текста в углу может приводить к ошибкам изображения
4748 1) когда диалог перемещается в угол
4749 2) когда диалог перемещается из угла
4750 сделал вывод красных палочек по углам
4752 Text(Dlg
->X1
, Dlg
->Y1
, 0xCE, L
"\\");
4753 Text(Dlg
->X1
, Dlg
->Y2
, 0xCE, L
"/");
4754 Text(Dlg
->X2
, Dlg
->Y1
, 0xCE, L
"/");
4755 Text(Dlg
->X2
, Dlg
->Y2
, 0xCE, L
"\\");
4760 case DN_DRAWDIALOG
: {
4763 case DN_CTLCOLORDIALOG
:
4765 case DN_CTLCOLORDLGITEM
:
4767 case DN_CTLCOLORDLGLIST
:
4770 return 0; // always 0
4771 case DM_GETDIALOGINFO
: {
4772 bool Result
= false;
4776 DialogInfo
*di
= reinterpret_cast<DialogInfo
*>(Param2
);
4778 if (static_cast<size_t>(di
->StructSize
) >= offsetof(DialogInfo
, Id
) + sizeof(di
->Id
)) {
4789 // предварительно проверим...
4790 if (Param1
< 0 || (unsigned)Param1
>= Dlg
->ItemCount
|| !Dlg
->Item
)
4793 CurItem
= Dlg
->Item
[Param1
];
4794 Type
= CurItem
->Type
;
4799 case DN_DRAWDLGITEM
:
4806 return ((Type
== DI_BUTTON
&& !(CurItem
->Flags
& DIF_BTNNOCLOSE
)) ? FALSE
: TRUE
);
4813 case DM_GETSELECTION
: // Msg=DM_GETSELECTION, Param1=ID, Param2=*EditorSelect
4815 case DM_SETSELECTION
:
4822 LONG_PTR
Dialog::CallDlgProc(int nMsg
, int nParam1
, LONG_PTR nParam2
)
4824 CriticalSectionLock
Lock(CS
);
4825 return Dialog::DlgProc((HANDLE
)this, nMsg
, nParam1
, nParam2
);
4828 //////////////////////////////////////////////////////////////////////////
4829 LONG_PTR
SendDlgMessageSynched(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
4831 Dialog
*Dlg
= (Dialog
*)hDlg
;
4832 CriticalSectionLock
Lock(Dlg
->CS
);
4833 _DIALOG(CleverSysLog
CL(L
"Dialog.SendDlgMessage()"));
4834 _DIALOG(SysLog(L
"hDlg=%p, Msg=%ls, Param1=%d (0x%08X), Param2=%d (0x%08X)", hDlg
, _DLGMSG_ToName(Msg
),
4835 Param1
, Param1
, Param2
, Param2
));
4837 // Сообщения, касаемые только диалога и не затрагивающие элементы
4839 /*****************************************************************/
4840 case DM_RESIZEDIALOG
:
4841 // изменим вызов RESIZE.
4843 /*****************************************************************/
4844 case DM_MOVEDIALOG
: {
4846 W1
= Dlg
->X2
- Dlg
->X1
+ 1;
4847 H1
= Dlg
->Y2
- Dlg
->Y1
+ 1;
4848 Dlg
->OldX1
= Dlg
->X1
;
4849 Dlg
->OldY1
= Dlg
->Y1
;
4850 Dlg
->OldX2
= Dlg
->X2
;
4851 Dlg
->OldY2
= Dlg
->Y2
;
4854 if (Param1
> 0) // абсолютно?
4856 Dlg
->X1
= ((COORD
*)Param2
)->X
;
4857 Dlg
->Y1
= ((COORD
*)Param2
)->Y
;
4860 Dlg
->CheckDialogCoord();
4861 } else if (!Param1
) // значит относительно
4863 Dlg
->X1
+= ((COORD
*)Param2
)->X
;
4864 Dlg
->Y1
+= ((COORD
*)Param2
)->Y
;
4865 } else // Resize, Param2=width/height
4870 W1
= ((COORD
*)Param2
)->X
;
4871 H1
= ((COORD
*)Param2
)->Y
;
4872 Dlg
->RealWidth
= W1
;
4873 Dlg
->RealHeight
= H1
;
4875 if (W1
< OldW1
|| H1
< OldH1
) {
4876 Dlg
->DialogMode
.Set(DMODE_DRAWING
);
4880 for (unsigned int I
= 0; I
< Dlg
->ItemCount
; I
++) {
4881 Item
= Dlg
->Item
[I
];
4883 if (Item
->Flags
& DIF_HIDDEN
)
4886 Rect
.Left
= Item
->X1
;
4887 Rect
.Top
= Item
->Y1
;
4889 if (Item
->X2
>= W1
) {
4890 Rect
.Right
= Item
->X2
- (OldW1
- W1
);
4891 Rect
.Bottom
= Item
->Y2
;
4892 Dlg
->SetItemRect(I
, &Rect
);
4895 if (Item
->Y2
>= H1
) {
4896 Rect
.Right
= Item
->X2
;
4897 Rect
.Bottom
= Item
->Y2
- (OldH1
- H1
);
4898 Dlg
->SetItemRect(I
, &Rect
);
4902 Dlg
->DialogMode
.Clear(DMODE_DRAWING
);
4906 // проверили и скорректировали
4907 if (Dlg
->X1
+ W1
< 0)
4910 if (Dlg
->Y1
+ H1
< 0)
4919 Dlg
->X2
= Dlg
->X1
+ W1
- 1;
4920 Dlg
->Y2
= Dlg
->Y1
+ H1
- 1;
4922 if (Param1
> 0) // абсолютно?
4924 Dlg
->CheckDialogCoord();
4927 if (Param1
< 0) // размер?
4929 ((COORD
*)Param2
)->X
= Dlg
->X2
- Dlg
->X1
+ 1;
4930 ((COORD
*)Param2
)->Y
= Dlg
->Y2
- Dlg
->Y1
+ 1;
4932 ((COORD
*)Param2
)->X
= Dlg
->X1
;
4933 ((COORD
*)Param2
)->Y
= Dlg
->Y1
;
4936 int I
= Dlg
->IsVisible(); // && Dlg->DialogMode.Check(DMODE_INITOBJECTS);
4942 Dlg
->AdjustEditPos(Dlg
->X1
- Dlg
->OldX1
, Dlg
->Y1
- Dlg
->OldY1
);
4945 Dlg
->Show(); // только если диалог был виден
4949 /*****************************************************************/
4951 if (Dlg
->DialogMode
.Check(DMODE_INITOBJECTS
))
4956 /*****************************************************************/
4957 case DM_ENABLEREDRAW
: {
4958 int Prev
= Dlg
->IsEnableRedraw
;
4961 Dlg
->IsEnableRedraw
++;
4962 else if (Param1
== FALSE
)
4963 Dlg
->IsEnableRedraw
--;
4965 // Edit::DisableEditOut(!Dlg->IsEnableRedraw?FALSE:TRUE);
4967 if (!Dlg
->IsEnableRedraw
&& Prev
!= Dlg
->IsEnableRedraw
)
4968 if (Dlg
->DialogMode
.Check(DMODE_INITOBJECTS
)) {
4977 case DM_ENABLEREDRAW:
4980 Dlg->IsEnableRedraw++;
4982 Dlg->IsEnableRedraw--;
4984 if(!Dlg->IsEnableRedraw)
4985 if(Dlg->DialogMode.Check(DMODE_INITOBJECTS))
4994 /*****************************************************************/
4995 case DM_SHOWDIALOG
: {
4996 // if(!Dlg->IsEnableRedraw)
5001 Залочим прорисовку при прятании диалога, в противном
5002 случае ОТКУДА менеджер узнает, что отрисовывать
5005 if (!Dlg
->IsVisible()) {
5010 if (Dlg
->IsVisible()) {
5018 /*****************************************************************/
5019 case DM_SETDLGDATA
: {
5020 LONG_PTR PrewDataDialog
= Dlg
->DataDialog
;
5021 Dlg
->DataDialog
= Param2
;
5022 return PrewDataDialog
;
5024 /*****************************************************************/
5025 case DM_GETDLGDATA
: {
5026 return Dlg
->DataDialog
;
5028 /*****************************************************************/
5030 int *KeyArray
= (int *)Param2
;
5031 Dlg
->DialogMode
.Set(DMODE_KEY
);
5033 for (unsigned int I
= 0; I
< (unsigned)Param1
; ++I
)
5034 Dlg
->ProcessKey(KeyArray
[I
]);
5036 Dlg
->DialogMode
.Clear(DMODE_KEY
);
5039 /*****************************************************************/
5042 Dlg
->ExitCode
= Dlg
->FocusPos
;
5044 Dlg
->ExitCode
= Param1
;
5047 return TRUE
; // согласен с закрытием
5049 /*****************************************************************/
5050 case DM_GETDLGRECT
: {
5053 Dlg
->GetPosition(x1
, y1
, x2
, y2
);
5054 ((SMALL_RECT
*)Param2
)->Left
= x1
;
5055 ((SMALL_RECT
*)Param2
)->Top
= y1
;
5056 ((SMALL_RECT
*)Param2
)->Right
= x2
;
5057 ((SMALL_RECT
*)Param2
)->Bottom
= y2
;
5063 /*****************************************************************/
5064 case DM_GETDROPDOWNOPENED
: // Param1=0; Param2=0
5066 return Dlg
->GetDropDownOpened();
5068 /*****************************************************************/
5069 case DM_KILLSAVESCREEN
: {
5071 Dlg
->SaveScr
->Discard();
5073 if (Dlg
->ShadowSaveScr
)
5074 Dlg
->ShadowSaveScr
->Discard();
5078 /*****************************************************************/
5082 =-1 - получить состояние
5087 case DM_ALLKEYMODE
: {
5089 return IsProcessAssignMacroKey
;
5091 BOOL OldIsProcessAssignMacroKey
= IsProcessAssignMacroKey
;
5092 IsProcessAssignMacroKey
= Param1
;
5093 return OldIsProcessAssignMacroKey
;
5095 /*****************************************************************/
5096 case DM_SETMOUSEEVENTNOTIFY
: // Param1 = 1 on, 0 off, -1 - get
5098 int State
= Dlg
->DialogMode
.Check(DMODE_MOUSEEVENT
) ? TRUE
: FALSE
;
5102 Dlg
->DialogMode
.Clear(DMODE_MOUSEEVENT
);
5104 Dlg
->DialogMode
.Set(DMODE_MOUSEEVENT
);
5109 /*****************************************************************/
5110 case DN_RESIZECONSOLE
: {
5111 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
5113 case DM_GETDIALOGINFO
: {
5114 return DefDlgProc(hDlg
, DM_GETDIALOGINFO
, Param1
, Param2
);
5118 /*****************************************************************/
5119 if (Msg
>= DM_USER
) {
5120 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
5123 /*****************************************************************/
5124 DialogItemEx
*CurItem
= nullptr;
5129 предварительно проверим...
5131 для DM_USER проверять _не_надо_!
5133 if ((unsigned)Param1
>= Dlg
->ItemCount
|| !Dlg
->Item
)
5136 // CurItem=&Dlg->Item[Param1];
5137 CurItem
= Dlg
->Item
[Param1
];
5138 Type
= CurItem
->Type
;
5139 const wchar_t *Ptr
= CurItem
->strData
;
5141 if (FarIsEdit(Type
) && CurItem
->ObjPtr
)
5142 Ptr
= const_cast<const wchar_t *>(((DlgEdit
*)(CurItem
->ObjPtr
))->GetStringAddr());
5145 /*****************************************************************/
5146 case DM_LISTSORT
: // Param1=ID Param=Direct {0|1}
5147 case DM_LISTADD
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
5148 case DM_LISTADDSTR
: // Param1=ID Param2=String
5149 case DM_LISTDELETE
: // Param1=ID Param2=FarListDelete: StartIndex=BeginIndex, Count=количество (<=0 - все!)
5150 case DM_LISTGETITEM
: // Param1=ID Param2=FarListGetItem: ItemsNumber=Index, Items=Dest
5151 case DM_LISTSET
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
5152 case DM_LISTGETCURPOS
: // Param1=ID Param2=FarListPos
5153 case DM_LISTSETCURPOS
: // Param1=ID Param2=FarListPos Ret: RealPos
5154 case DM_LISTUPDATE
: // Param1=ID Param2=FarList: ItemsNumber=Index, Items=Src
5155 case DM_LISTINFO
: // Param1=ID Param2=FarListInfo
5156 case DM_LISTFINDSTRING
: // Param1=ID Param2=FarListFind
5157 case DM_LISTINSERT
: // Param1=ID Param2=FarListInsert
5158 case DM_LISTGETDATA
: // Param1=ID Param2=Index
5159 case DM_LISTSETDATA
: // Param1=ID Param2=FarListItemData
5160 case DM_LISTSETTITLES
: // Param1=ID Param2=FarListTitles: TitleLen=strlen(Title), BottomLen=strlen(Bottom)
5161 case DM_LISTGETTITLES
: // Param1=ID Param2=FarListTitles: TitleLen=strlen(Title), BottomLen=strlen(Bottom)
5162 case DM_LISTGETDATASIZE
: // Param1=ID Param2=Index
5163 case DM_LISTSETMOUSEREACTION
: // Param1=ID Param2=FARLISTMOUSEREACTIONTYPE Ret=OldSets
5164 case DM_SETCOMBOBOXEVENT
: // Param1=ID Param2=FARCOMBOBOXEVENTTYPE Ret=OldSets
5165 case DM_GETCOMBOBOXEVENT
: // Param1=ID Param2=0 Ret=Sets
5167 if (Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) {
5168 VMenu
*ListBox
= CurItem
->ListPtr
;
5174 case DM_LISTINFO
: // Param1=ID Param2=FarListInfo
5176 return ListBox
->GetVMenuInfo((FarListInfo
*)Param2
);
5178 case DM_LISTSORT
: // Param1=ID Param=Direct {0|1}
5180 ListBox
->SortItems((int)Param2
);
5183 case DM_LISTFINDSTRING
: // Param1=ID Param2=FarListFind
5185 FarListFind
*lf
= reinterpret_cast<FarListFind
*>(Param2
);
5186 return ListBox
->FindItem(lf
->StartIndex
, lf
->Pattern
, lf
->Flags
);
5188 case DM_LISTADDSTR
: // Param1=ID Param2=String
5190 Ret
= ListBox
->AddItem((wchar_t *)Param2
);
5193 case DM_LISTADD
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
5195 FarList
*ListItems
= (FarList
*)Param2
;
5200 Ret
= ListBox
->AddItem(ListItems
);
5203 case DM_LISTDELETE
: // Param1=ID Param2=FarListDelete: StartIndex=BeginIndex, Count=количество (<=0 - все!)
5206 FarListDelete
*ListItems
= (FarListDelete
*)Param2
;
5208 if (!ListItems
|| (Count
= ListItems
->Count
) <= 0)
5209 ListBox
->DeleteItems();
5211 ListBox
->DeleteItem(ListItems
->StartIndex
, Count
);
5215 case DM_LISTINSERT
: // Param1=ID Param2=FarListInsert
5217 if ((Ret
= ListBox
->InsertItem((FarListInsert
*)Param2
)) == -1)
5222 case DM_LISTUPDATE
: // Param1=ID Param2=FarListUpdate: Index=Index, Items=Src
5224 if (Param2
&& ListBox
->UpdateItem((FarListUpdate
*)Param2
))
5229 case DM_LISTGETITEM
: // Param1=ID Param2=FarListGetItem: ItemsNumber=Index, Items=Dest
5231 FarListGetItem
*ListItems
= (FarListGetItem
*)Param2
;
5236 MenuItemEx
*ListMenuItem
;
5238 if ((ListMenuItem
= ListBox
->GetItemPtr(ListItems
->ItemIndex
))) {
5239 // ListItems->ItemIndex=1;
5240 FarListItem
*Item
= &ListItems
->Item
;
5241 memset(Item
, 0, sizeof(FarListItem
));
5242 Item
->Flags
= ListMenuItem
->Flags
;
5243 Item
->Text
= ListMenuItem
->strName
;
5245 if(ListMenuItem->UserDataSize <= sizeof(DWORD)) //???
5246 Item->UserData=ListMenuItem->UserData;
5253 case DM_LISTGETDATA
: // Param1=ID Param2=Index
5255 if (Param2
< ListBox
->GetItemCount())
5256 return (LONG_PTR
)ListBox
->GetUserData(nullptr, 0, (int)Param2
);
5260 case DM_LISTGETDATASIZE
: // Param1=ID Param2=Index
5262 if (Param2
< ListBox
->GetItemCount())
5263 return ListBox
->GetUserDataSize((int)Param2
);
5267 case DM_LISTSETDATA
: // Param1=ID Param2=FarListItemData
5269 FarListItemData
*ListItems
= (FarListItemData
*)Param2
;
5271 if (ListItems
&& ListItems
->Index
< ListBox
->GetItemCount()) {
5272 Ret
= ListBox
->SetUserData(ListItems
->Data
, ListItems
->DataSize
,
5275 if (!Ret
&& ListBox
->GetUserData(nullptr, 0, ListItems
->Index
))
5276 Ret
= sizeof(DWORD
);
5285 + Сообщение для добавления в список строк, с удалением
5286 уже существующих, т.с. "чистая" установка
5288 case DM_LISTSET
: // Param1=ID Param2=FarList: ItemsNumber=Count, Items=Src
5290 FarList
*ListItems
= (FarList
*)Param2
;
5295 ListBox
->DeleteItems();
5296 Ret
= ListBox
->AddItem(ListItems
);
5299 // case DM_LISTINS: // Param1=ID Param2=FarList: ItemsNumber=Index, Items=Dest
5300 case DM_LISTSETTITLES
: // Param1=ID Param2=FarListTitles
5302 FarListTitles
*ListTitle
= (FarListTitles
*)Param2
;
5303 ListBox
->SetTitle(ListTitle
->Title
);
5304 ListBox
->SetBottomTitle(ListTitle
->Bottom
);
5305 break; // return TRUE;
5307 case DM_LISTGETTITLES
: // Param1=ID Param2=FarListTitles
5310 FarListTitles
*ListTitle
= (FarListTitles
*)Param2
;
5311 FARString strTitle
, strBottomTitle
;
5312 ListBox
->GetTitle(strTitle
);
5313 ListBox
->GetBottomTitle(strBottomTitle
);
5315 if (!strTitle
.IsEmpty() || !strBottomTitle
.IsEmpty()) {
5316 if (ListTitle
->Title
&& ListTitle
->TitleLen
)
5317 far_wcsncpy((wchar_t *)ListTitle
->Title
, strTitle
,
5318 ListTitle
->TitleLen
);
5320 ListTitle
->TitleLen
= (int)strTitle
.GetLength() + 1;
5322 if (ListTitle
->Bottom
&& ListTitle
->BottomLen
)
5323 far_wcsncpy((wchar_t *)ListTitle
->Bottom
, strBottomTitle
,
5324 ListTitle
->BottomLen
);
5326 ListTitle
->BottomLen
= (int)strBottomTitle
.GetLength() + 1;
5334 case DM_LISTGETCURPOS
: // Param1=ID Param2=FarListPos
5336 return Param2
? ListBox
->GetSelectPos((FarListPos
*)Param2
)
5337 : ListBox
->GetSelectPos();
5339 case DM_LISTSETCURPOS
: // Param1=ID Param2=FarListPos Ret: RealPos
5341 /* 26.06.2001 KM Подадим перед изменением позиции об этом сообщение */
5342 int CurListPos
= ListBox
->GetSelectPos();
5343 Ret
= ListBox
->SetSelectPos((FarListPos
*)Param2
);
5345 if (Ret
!= CurListPos
)
5346 if (!Dlg
->CallDlgProc(DN_LISTCHANGE
, Param1
, Ret
))
5347 Ret
= ListBox
->SetSelectPos(CurListPos
, 1);
5349 break; // т.к. нужно перерисовать!
5351 case DM_LISTSETMOUSEREACTION
: // Param1=ID Param2=FARLISTMOUSEREACTIONTYPE Ret=OldSets
5353 int OldSets
= CurItem
->IFlags
.Flags
;
5355 if (Param2
== LMRT_ONLYFOCUS
) {
5356 CurItem
->IFlags
.Clear(DLGIIF_LISTREACTIONNOFOCUS
);
5357 CurItem
->IFlags
.Set(DLGIIF_LISTREACTIONFOCUS
);
5358 } else if (Param2
== LMRT_NEVER
) {
5359 CurItem
->IFlags
.Clear(DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
);
5360 // ListBox->ClearFlags(VMENU_MOUSEREACTION);
5362 CurItem
->IFlags
.Set(DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
);
5363 // ListBox->SetFlags(VMENU_MOUSEREACTION);
5366 if ((OldSets
& (DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
))
5367 == (DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
))
5368 OldSets
= LMRT_ALWAYS
;
5369 else if (!(OldSets
& (DLGIIF_LISTREACTIONNOFOCUS
| DLGIIF_LISTREACTIONFOCUS
)))
5370 OldSets
= LMRT_NEVER
;
5372 OldSets
= LMRT_ONLYFOCUS
;
5376 case DM_GETCOMBOBOXEVENT
: // Param1=ID Param2=0 Ret=Sets
5378 return (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTKEY
) ? CBET_KEY
: 0)
5379 | (CurItem
->IFlags
.Check(DLGIIF_COMBOBOXEVENTMOUSE
) ? CBET_MOUSE
: 0);
5381 case DM_SETCOMBOBOXEVENT
: // Param1=ID Param2=FARCOMBOBOXEVENTTYPE Ret=OldSets
5383 int OldSets
= CurItem
->IFlags
.Flags
;
5384 CurItem
->IFlags
.Clear(DLGIIF_COMBOBOXEVENTKEY
| DLGIIF_COMBOBOXEVENTMOUSE
);
5386 if (Param2
& CBET_KEY
)
5387 CurItem
->IFlags
.Set(DLGIIF_COMBOBOXEVENTKEY
);
5389 if (Param2
& CBET_MOUSE
)
5390 CurItem
->IFlags
.Set(DLGIIF_COMBOBOXEVENTMOUSE
);
5396 // уточнение для DI_COMBOBOX - здесь еще и DlgEdit нужно корректно заполнить
5397 if (!CurItem
->IFlags
.Check(DLGIIF_COMBOBOXNOREDRAWEDIT
) && Type
== DI_COMBOBOX
5398 && CurItem
->ObjPtr
) {
5399 MenuItemEx
*ListMenuItem
;
5401 if ((ListMenuItem
= ListBox
->GetItemPtr(ListBox
->GetSelectPos()))) {
5402 if (CurItem
->Flags
& (DIF_DROPDOWNLIST
| DIF_LISTNOAMPERSAND
))
5403 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetHiString(ListMenuItem
->strName
);
5405 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetString(ListMenuItem
->strName
);
5407 ((DlgEdit
*)(CurItem
->ObjPtr
))->Select(-1, -1); // снимаем выделение
5411 if (Dlg
->DialogMode
.Check(DMODE_SHOW
) && ListBox
->UpdateRequired()) {
5412 Dlg
->ShowDialog(Param1
);
5422 /*****************************************************************/
5423 case DM_SETHISTORY
: // Param1 = ID, Param2 = LPSTR HistoryName
5425 if (Type
== DI_EDIT
|| Type
== DI_FIXEDIT
) {
5426 if (Param2
&& *(const wchar_t *)Param2
) {
5427 CurItem
->Flags
|= DIF_HISTORY
;
5428 CurItem
->strHistory
= (const wchar_t *)Param2
;
5430 if (Type
== DI_EDIT
&& (CurItem
->Flags
& DIF_USELASTHISTORY
)) {
5431 Dlg
->ProcessLastHistory(CurItem
, Param1
);
5434 CurItem
->Flags
&= ~DIF_HISTORY
;
5435 CurItem
->strHistory
.Clear();
5438 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5439 Dlg
->ShowDialog(Param1
);
5448 /*****************************************************************/
5449 case DM_ADDHISTORY
: {
5450 if (Param2
&& (Type
== DI_EDIT
|| Type
== DI_FIXEDIT
) && (CurItem
->Flags
& DIF_HISTORY
)) {
5451 return Dlg
->AddToEditHistory((const wchar_t *)Param2
, CurItem
->strHistory
);
5456 /*****************************************************************/
5457 case DM_GETCURSORPOS
: {
5461 if (FarIsEdit(Type
) && CurItem
->ObjPtr
) {
5462 ((COORD
*)Param2
)->X
= ((DlgEdit
*)(CurItem
->ObjPtr
))->GetCurPos();
5463 ((COORD
*)Param2
)->Y
= 0;
5465 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5466 ((COORD
*)Param2
)->X
= CurItem
->UCData
->CursorPos
.X
;
5467 ((COORD
*)Param2
)->Y
= CurItem
->UCData
->CursorPos
.Y
;
5473 /*****************************************************************/
5474 case DM_SETCURSORPOS
: {
5475 if (FarIsEdit(Type
) && CurItem
->ObjPtr
&& ((COORD
*)Param2
)->X
>= 0) {
5476 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
5477 EditPtr
->SetCurPos(((COORD
*)Param2
)->X
);
5479 Dlg
->ShowDialog(Param1
);
5481 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5483 учтем, что координаты для этого элемента всегда относительные!
5486 COORD Coord
= *(COORD
*)Param2
;
5487 Coord
.X
+= CurItem
->X1
;
5489 if (Coord
.X
> CurItem
->X2
)
5490 Coord
.X
= CurItem
->X2
;
5492 Coord
.Y
+= CurItem
->Y1
;
5494 if (Coord
.Y
> CurItem
->Y2
)
5495 Coord
.Y
= CurItem
->Y2
;
5498 CurItem
->UCData
->CursorPos
.X
= Coord
.X
- CurItem
->X1
;
5499 CurItem
->UCData
->CursorPos
.Y
= Coord
.Y
- CurItem
->Y1
;
5501 // переместим если надо
5502 if (Dlg
->DialogMode
.Check(DMODE_SHOW
) && Dlg
->FocusPos
== (unsigned)Param1
) {
5503 // что-то одно надо убрать :-)
5504 MoveCursor(Coord
.X
+ Dlg
->X1
, Coord
.Y
+ Dlg
->Y1
); // ???
5505 Dlg
->ShowDialog(Param1
); // ???
5513 /*****************************************************************/
5514 case DM_GETEDITPOSITION
: {
5515 if (Param2
&& FarIsEdit(Type
)) {
5516 if (Type
== DI_MEMOEDIT
) {
5517 // EditorControl(ECTL_GETINFO,(EditorSetPosition *)Param2);
5520 EditorSetPosition
*esp
= (EditorSetPosition
*)Param2
;
5521 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
5523 esp
->CurPos
= EditPtr
->GetCurPos();
5524 esp
->CurTabPos
= EditPtr
->GetCellCurPos();
5525 esp
->TopScreenLine
= 0;
5526 esp
->LeftPos
= EditPtr
->GetLeftPos();
5527 esp
->Overtype
= EditPtr
->GetOvertypeMode();
5534 /*****************************************************************/
5535 case DM_SETEDITPOSITION
: {
5536 if (Param2
&& FarIsEdit(Type
)) {
5537 if (Type
== DI_MEMOEDIT
) {
5538 // EditorControl(ECTL_SETPOSITION,(EditorSetPosition *)Param2);
5541 EditorSetPosition
*esp
= (EditorSetPosition
*)Param2
;
5542 DlgEdit
*EditPtr
= (DlgEdit
*)(CurItem
->ObjPtr
);
5543 EditPtr
->SetCurPos(esp
->CurPos
);
5544 EditPtr
->SetCellCurPos(esp
->CurTabPos
);
5545 EditPtr
->SetLeftPos(esp
->LeftPos
);
5546 EditPtr
->SetOvertypeMode(esp
->Overtype
);
5547 Dlg
->ShowDialog(Param1
);
5555 /*****************************************************************/
5557 // Return MAKELONG(Visible,Size)
5558 case DM_GETCURSORSIZE
: {
5559 if (FarIsEdit(Type
) && CurItem
->ObjPtr
) {
5562 ((DlgEdit
*)(CurItem
->ObjPtr
))->GetCursorType(Visible
, Size
);
5563 return MAKELONG(Visible
, Size
);
5564 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5565 return MAKELONG(CurItem
->UCData
->CursorVisible
, CurItem
->UCData
->CursorSize
);
5570 /*****************************************************************/
5571 // Param2=MAKELONG(Visible,Size)
5572 // Return MAKELONG(OldVisible,OldSize)
5573 case DM_SETCURSORSIZE
: {
5574 bool Visible
= false;
5577 if (FarIsEdit(Type
) && CurItem
->ObjPtr
) {
5578 ((DlgEdit
*)(CurItem
->ObjPtr
))->GetCursorType(Visible
, Size
);
5579 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetCursorType(LOWORD(Param2
) != 0, HIWORD(Param2
));
5580 } else if (Type
== DI_USERCONTROL
&& CurItem
->UCData
) {
5581 Visible
= CurItem
->UCData
->CursorVisible
;
5582 Size
= CurItem
->UCData
->CursorSize
;
5583 CurItem
->UCData
->CursorVisible
= LOWORD(Param2
) != 0;
5584 CurItem
->UCData
->CursorSize
= HIWORD(Param2
);
5585 int CCX
= CurItem
->UCData
->CursorPos
.X
;
5586 int CCY
= CurItem
->UCData
->CursorPos
.Y
;
5588 if (Dlg
->DialogMode
.Check(DMODE_SHOW
) && Dlg
->FocusPos
== (unsigned)Param1
&& CCX
!= -1
5590 SetCursorType(CurItem
->UCData
->CursorVisible
, CurItem
->UCData
->CursorSize
);
5593 return MAKELONG(Visible
, Size
);
5595 /*****************************************************************/
5596 case DN_LISTCHANGE
: {
5597 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
5599 /*****************************************************************/
5600 case DN_EDITCHANGE
: {
5603 if (!ConvertItemEx(CVTITEM_TOPLUGIN
, &Item
, CurItem
, 1))
5604 return FALSE
; // no memory TODO: may be needed diagnostic
5607 if (CurItem
->Type
== DI_EDIT
|| CurItem
->Type
== DI_COMBOBOX
|| CurItem
->Type
== DI_FIXEDIT
5608 || CurItem
->Type
== DI_PSWEDIT
) {
5609 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(false);
5610 const wchar_t *original_PtrData
= Item
.PtrData
;
5611 I
= Dlg
->CallDlgProc(DN_EDITCHANGE
, Param1
, (LONG_PTR
)&Item
);
5613 if (Type
== DI_COMBOBOX
&& CurItem
->ListPtr
)
5614 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
5616 if (original_PtrData
)
5617 free((void *)original_PtrData
);
5618 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(true);
5623 /*****************************************************************/
5625 LONG_PTR Ret
= Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
5627 if (Ret
&& (CurItem
->Flags
& DIF_AUTOMATION
) && CurItem
->AutoCount
&& CurItem
->AutoPtr
) {
5628 DialogItemAutomation
*Auto
= CurItem
->AutoPtr
;
5631 for (UINT I
= 0; I
< CurItem
->AutoCount
; ++I
, ++Auto
) {
5632 DWORD NewFlags
= Dlg
->Item
[Auto
->ID
]->Flags
;
5633 Dlg
->Item
[Auto
->ID
]->Flags
=
5634 (NewFlags
& (~Auto
->Flags
[Param2
][1])) | Auto
->Flags
[Param2
][0];
5635 // здесь намеренно в обработчик не посылаются эвенты об изменении
5642 /*****************************************************************/
5644 if (Type
== DI_CHECKBOX
|| Type
== DI_RADIOBUTTON
)
5645 return CurItem
->Selected
;
5649 /*****************************************************************/
5650 case DM_SET3STATE
: {
5651 if (Type
== DI_CHECKBOX
) {
5652 int OldState
= CurItem
->Flags
& DIF_3STATE
? TRUE
: FALSE
;
5655 CurItem
->Flags
|= DIF_3STATE
;
5657 CurItem
->Flags
&= ~DIF_3STATE
;
5664 /*****************************************************************/
5666 if (Type
== DI_CHECKBOX
) {
5667 int Selected
= CurItem
->Selected
;
5669 if (Param2
== BSTATE_TOGGLE
)
5670 Param2
= ++Selected
;
5672 if (CurItem
->Flags
& DIF_3STATE
)
5677 CurItem
->Selected
= (int)Param2
;
5679 if (Selected
!= (int)Param2
&& Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5681 if ((CurItem
->Flags
& DIF_AUTOMATION
) && CurItem
->AutoCount
&& CurItem
->AutoPtr
) {
5682 DialogItemAutomation
*Auto
= CurItem
->AutoPtr
;
5685 for (UINT I
= 0; I
< CurItem
->AutoCount
; ++I
, ++Auto
) {
5686 DWORD NewFlags
= Dlg
->Item
[Auto
->ID
]->Flags
;
5687 Dlg
->Item
[Auto
->ID
]->Flags
=
5688 (NewFlags
& (~Auto
->Flags
[Param2
][1])) | Auto
->Flags
[Param2
][0];
5689 // здесь намеренно в обработчик не посылаются эвенты об изменении
5696 Dlg
->ShowDialog(Param1
);
5701 } else if (Type
== DI_RADIOBUTTON
) {
5702 Param1
= Dlg
->ProcessRadioButton(Param1
);
5704 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5714 /*****************************************************************/
5715 case DN_DRAWDLGITEM
: {
5718 if (!ConvertItemEx(CVTITEM_TOPLUGIN
, &Item
, CurItem
, 1))
5719 return FALSE
; // no memory TODO: may be needed diagnostic
5721 INT_PTR I
= Dlg
->CallDlgProc(Msg
, Param1
, (LONG_PTR
)&Item
);
5723 if ((Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) && CurItem
->ListPtr
)
5724 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
5727 free((wchar_t *)Item
.PtrData
);
5731 /*****************************************************************/
5733 if (!IsItemFocusable(CurItem
))
5736 if (Dlg
->FocusPos
== (unsigned)Param1
) // уже и так установлено все!
5739 Dlg
->ChangeFocus2(Param1
);
5741 if (Dlg
->FocusPos
== (unsigned)Param1
) {
5748 /*****************************************************************/
5749 case DM_GETFOCUS
: // Получить ID фокуса
5751 return Dlg
->FocusPos
;
5753 /*****************************************************************/
5754 case DM_GETCONSTTEXTPTR
: {
5755 return (LONG_PTR
)Ptr
;
5757 /*****************************************************************/
5761 FarDialogItemData IData
= {0, (wchar_t *)Param2
};
5762 return SendDlgMessage(hDlg
, DM_GETTEXT
, Param1
, (LONG_PTR
)&IData
);
5765 /*****************************************************************/
5768 if (Param2
) // если здесь nullptr, то это еще один способ получить размер
5770 FarDialogItemData
*did
= (FarDialogItemData
*)Param2
;
5781 if (!CurItem
->ObjPtr
)
5784 Ptr
= const_cast<const wchar_t *>(((DlgEdit
*)(CurItem
->ObjPtr
))->GetStringAddr());
5790 case DI_RADIOBUTTON
:
5792 Len
= StrLength(Ptr
) + 1;
5794 if (Type
== DI_BUTTON
) {
5795 if (!(CurItem
->Flags
& DIF_NOBRACKETS
)) {
5799 if (CurItem
->Flags
& DIF_SETSHIELD
) {
5804 if (!did
->PtrLength
)
5805 did
->PtrLength
= Len
;
5806 else if (Len
> did
->PtrLength
)
5807 Len
= did
->PtrLength
+ 1; // Прибавим 1, чтобы учесть нулевой байт.
5809 if (Len
> 0 && did
->PtrData
) {
5810 wmemmove(did
->PtrData
, Ptr
, Len
);
5811 did
->PtrData
[Len
- 1] = 0;
5815 case DI_USERCONTROL
:
5816 /*did->PtrLength=CurItem->Ptr.PtrLength; BUGBUG
5817 did->PtrData=(char*)CurItem->Ptr.PtrData;*/
5820 // if(!CurItem->ListPtr)
5822 // did->PtrLength=CurItem->ListPtr->GetUserData(did->PtrData,did->PtrLength,-1);
5825 default: // подразумеваем, что остались
5830 return Len
- (!Len
? 0 : 1);
5833 // здесь умышленно не ставим return, т.к. хотим получить размер
5834 // следовательно сразу должен идти "case DM_GETTEXTLENGTH"!!!
5835 /*****************************************************************/
5836 case DM_GETTEXTLENGTH
: {
5839 Len
= StrLength(Ptr
) + 1;
5841 if (!(CurItem
->Flags
& DIF_NOBRACKETS
))
5845 case DI_USERCONTROL
:
5846 // Len=CurItem->Ptr.PtrLength; BUGBUG
5853 case DI_RADIOBUTTON
:
5854 Len
= StrLength(Ptr
) + 1;
5862 if (CurItem
->ObjPtr
) {
5863 Len
= ((DlgEdit
*)(CurItem
->ObjPtr
))->GetLength() + 1;
5869 MenuItemEx
*ListMenuItem
;
5871 if ((ListMenuItem
= CurItem
->ListPtr
->GetItemPtr(-1))) {
5872 Len
= (int)ListMenuItem
->strName
.GetLength() + 1;
5882 return Len
- (!Len
? 0 : 1);
5884 /*****************************************************************/
5885 case DM_SETTEXTPTR
: {
5889 FarDialogItemData IData
= {(size_t)StrLength((wchar_t *)Param2
), (wchar_t *)Param2
};
5890 return SendDlgMessage(hDlg
, DM_SETTEXT
, Param1
, (LONG_PTR
)&IData
);
5893 case DM_SETTEXTPTRSILENT
: {
5897 if (CurItem
->Type
!= DI_FIXEDIT
&& CurItem
->Type
!= DI_EDIT
)
5900 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(false);
5901 FarDialogItemData IData
= {(size_t)StrLength((wchar_t *)Param2
), (wchar_t *)Param2
};
5902 intptr_t rv
= SendDlgMessage(hDlg
, DM_SETTEXT
, Param1
, (LONG_PTR
)&IData
);
5903 reinterpret_cast<DlgEdit
*>(CurItem
->ObjPtr
)->SetCallbackState(true);
5908 /*****************************************************************/
5911 int NeedInit
= TRUE
;
5912 FarDialogItemData
*did
= (FarDialogItemData
*)Param2
;
5925 case DI_RADIOBUTTON
:
5928 case DI_LISTBOX
: // меняет только текущий итем
5929 CurItem
->strData
= did
->PtrData
;
5930 Len
= (int)CurItem
->strData
.GetLength();
5938 case DI_USERCONTROL
:
5939 /*CurItem->Ptr.PtrLength=did->PtrLength;
5940 CurItem->Ptr.PtrData=did->PtrData;
5941 return CurItem->Ptr.PtrLength;*/
5948 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
5949 if (!Dlg
->DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
5950 ConsoleTitle::SetFarTitle(Dlg
->GetDialogTitle());
5951 Dlg
->ShowDialog(Param1
);
5955 return Len
- (!Len
? 0 : 1);
5958 case DI_RADIOBUTTON
:
5968 if (CurItem
->ObjPtr
) {
5969 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
5970 int ReadOnly
= EditLine
->GetReadOnly();
5971 EditLine
->SetReadOnly(0);
5972 EditLine
->DisableAC();
5973 EditLine
->SetString(CurItem
->strData
);
5974 EditLine
->RevertAC();
5975 EditLine
->SetReadOnly(ReadOnly
);
5977 if (Dlg
->DialogMode
.Check(DMODE_INITOBJECTS
)) // не меняем клеар-флаг, пока не проиницализировались
5978 EditLine
->SetClearFlag(0);
5980 EditLine
->Select(-1, 0); // снимаем выделение
5981 // ...оно уже снимается в DlgEdit::SetString()
5985 case DI_LISTBOX
: // меняет только текущий итем
5987 VMenu
*ListBox
= CurItem
->ListPtr
;
5990 FarListUpdate LUpdate
;
5991 LUpdate
.Index
= ListBox
->GetSelectPos();
5992 MenuItemEx
*ListMenuItem
= ListBox
->GetItemPtr(LUpdate
.Index
);
5995 LUpdate
.Item
.Flags
= ListMenuItem
->Flags
;
5996 LUpdate
.Item
.Text
= Ptr
;
5997 SendDlgMessage(hDlg
, DM_LISTUPDATE
, Param1
, (LONG_PTR
)&LUpdate
);
6004 default: // подразумеваем, что остались
6009 Dlg
->InitDialogObjects(Param1
); // переинициализируем элементы диалога
6011 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) // достаточно ли этого????!!!!
6013 Dlg
->ShowDialog(Param1
);
6017 // CurItem->strData = did->PtrData;
6018 return CurItem
->strData
.GetLength(); //???
6023 /*****************************************************************/
6024 case DM_SETMAXTEXTLENGTH
: {
6025 if ((Type
== DI_EDIT
|| Type
== DI_PSWEDIT
6026 || (Type
== DI_COMBOBOX
&& !(CurItem
->Flags
& DIF_DROPDOWNLIST
)))
6027 && CurItem
->ObjPtr
) {
6028 int MaxLen
= ((DlgEdit
*)(CurItem
->ObjPtr
))->GetMaxLength();
6029 // BugZ#628 - Неправильная длина редактируемого текста.
6030 ((DlgEdit
*)(CurItem
->ObjPtr
))->SetMaxLength((int)Param2
);
6031 // if (DialogMode.Check(DMODE_INITOBJECTS)) //???
6032 Dlg
->InitDialogObjects(Param1
); // переинициализируем элементы диалога
6033 if (!Dlg
->DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
6034 ConsoleTitle::SetFarTitle(Dlg
->GetDialogTitle());
6040 /*****************************************************************/
6041 case DM_GETDLGITEM
: {
6042 FarDialogItem
*Item
= (FarDialogItem
*)Param2
;
6043 return (LONG_PTR
)ConvertItemEx2(Item
, CurItem
);
6045 /*****************************************************************/
6046 case DM_GETDLGITEMSHORT
: {
6047 if (Param2
&& ConvertItemEx(CVTITEM_TOPLUGINSHORT
, (FarDialogItem
*)Param2
, CurItem
, 1))
6051 /*****************************************************************/
6053 case DM_SETDLGITEMSHORT
: {
6057 if (Type
!= ((FarDialogItem
*)Param2
)->Type
) // пока нефига менять тип
6061 if (!ConvertItemEx((Msg
== DM_SETDLGITEM
) ? CVTITEM_FROMPLUGIN
: CVTITEM_FROMPLUGINSHORT
,
6062 (FarDialogItem
*)Param2
, CurItem
, 1))
6063 return FALSE
; // invalid parameters
6065 CurItem
->Type
= Type
;
6067 if ((Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) && CurItem
->ListPtr
)
6068 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
6070 // еще разок, т.к. данные могли быть изменены
6071 Dlg
->InitDialogObjects(Param1
);
6072 if (!Dlg
->DialogMode
.Check(DMODE_KEEPCONSOLETITLE
))
6073 ConsoleTitle::SetFarTitle(Dlg
->GetDialogTitle());
6075 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) {
6076 Dlg
->ShowDialog(Param1
);
6082 /*****************************************************************/
6085 + показать/скрыть элемент
6087 -1 - получить состояние
6090 Return: предыдущее состояние
6093 DWORD PrevFlags
= CurItem
->Flags
;
6097 CurItem
->Flags
&= ~DIF_HIDDEN
;
6099 CurItem
->Flags
|= DIF_HIDDEN
;
6101 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) // && (PrevFlags&DIF_HIDDEN) != (CurItem->Flags&DIF_HIDDEN))//!(CurItem->Flags&DIF_HIDDEN))
6103 if ((CurItem
->Flags
& DIF_HIDDEN
) && Dlg
->FocusPos
== (unsigned)Param1
) {
6104 Param2
= Dlg
->ChangeFocus(Param1
, 1, TRUE
);
6105 Dlg
->ChangeFocus2((int)Param2
);
6108 // Либо все, либо... только 1
6109 Dlg
->ShowDialog(Dlg
->GetDropDownOpened() || (CurItem
->Flags
& DIF_HIDDEN
) ? -1 : Param1
);
6114 return (PrevFlags
& DIF_HIDDEN
) ? FALSE
: TRUE
;
6116 /*****************************************************************/
6117 case DM_SETDROPDOWNOPENED
: // Param1=ID; Param2={TRUE|FALSE}
6119 if (!Param2
) // Закрываем любой открытый комбобокс или историю
6121 if (Dlg
->GetDropDownOpened()) {
6122 Dlg
->SetDropDownOpened(FALSE
);
6130 у DI_PSWEDIT не бывает хистори!
6133 && (Type
== DI_COMBOBOX
6134 || ((Type
== DI_EDIT
|| Type
== DI_FIXEDIT
) && (CurItem
->Flags
& DIF_HISTORY
)))) /* DJ $ */
6136 // Открываем заданный в Param1 комбобокс или историю
6137 if (Dlg
->GetDropDownOpened()) {
6138 Dlg
->SetDropDownOpened(FALSE
);
6142 if (SendDlgMessage(hDlg
, DM_SETFOCUS
, Param1
, 0)) {
6143 Dlg
->ProcessOpenComboBox(Type
, CurItem
, Param1
); //?? Param1 ??
6144 // Dlg->ProcessKey(KEY_CTRLDOWN);
6153 /*****************************************************************/
6154 case DM_SETITEMPOSITION
: // Param1 = ID; Param2 = SMALL_RECT
6156 return Dlg
->SetItemRect((int)Param1
, (SMALL_RECT
*)Param2
);
6158 /*****************************************************************/
6161 + переключение/получение состояния Enable/Disable элемента
6164 DWORD PrevFlags
= CurItem
->Flags
;
6168 CurItem
->Flags
&= ~DIF_DISABLE
;
6170 CurItem
->Flags
|= DIF_DISABLE
;
6172 if ((Type
== DI_LISTBOX
|| Type
== DI_COMBOBOX
) && CurItem
->ListPtr
)
6173 CurItem
->ListPtr
->ChangeFlags(VMENU_DISABLED
, CurItem
->Flags
& DIF_DISABLE
);
6176 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) //???
6178 Dlg
->ShowDialog(Param1
);
6182 return (PrevFlags
& DIF_DISABLE
) ? FALSE
: TRUE
;
6185 //* `DM_SETREADONLY` - changes readonly-ness of selected dialog edit control item
6186 //* `DM_GETCOLOR` - retrieves current color attributes of selected dialog item
6187 //* `DM_SETCOLOR` - changes current color attributes of selected dialog item
6188 //* `DM_SETTRUECOLOR` - sets 24-bit RGB colors to selected dialog item, can be used within DN_CTLCOLORDLGITEM handler to provide extra coloring.
6189 //* `DM_GETTRUECOLOR` - retrieves 24-bit RGB colors of selected dialog item, if they were set before by DM_SETTRUECOLOR.
6190 //* `ECTL_ADDTRUECOLOR` - applies coloring to editor like ECTL_ADDCOLOR does but allows to specify 24 RGB color using EditorTrueColor structure.
6191 //* `ECTL_GETTRUECOLOR` - retrieves coloring of editor like ECTL_GETCOLOR does but gets 24 RGB color using EditorTrueColor structure.
6194 // case DM_GETCOLOR: {
6195 // *(DWORD *)Param2 = (DWORD)Dlg->CtlColorDlgItem(Param1, CurItem);
6196 // *(DWORD *)Param2|= (CurItem->Flags & DIF_SETCOLOR);
6200 // case DM_SETCOLOR: {
6201 // CurItem->Flags&= ~(DIF_SETCOLOR | DIF_COLORMASK);
6202 // CurItem->Flags|= Param2 & (DIF_SETCOLOR | DIF_COLORMASK);
6203 // if (Dlg->DialogMode.Check(DMODE_SHOW)) { //???
6204 // Dlg->ShowDialog(Param1);
6210 case DM_GETDEFAULTCOLOR
: {
6212 Dlg
->CtlColorDlgItem(Param1
, CurItem
, (uint64_t *)Param2
);
6217 ///case DM_GETCOLOR:///
6218 case DM_GETTRUECOLOR
: {
6220 memcpy((uint64_t *)Param2
, CurItem
->customItemColor
, sizeof(uint64_t) * 4);
6221 // if (!CurItem->TrueColors) {
6222 // memset((uint64_t *)Param2, 0, sizeof(DialogItemTrueColors));
6224 // *(DialogItemTrueColors *)Param2 = *CurItem->TrueColors;
6226 // Param2 = CurItem->customItemColor
6231 ///case DM_SETCOLOR:///
6232 case DM_SETTRUECOLOR
: {
6234 memcpy(CurItem
->customItemColor
, (uint64_t *)Param2
, sizeof(uint64_t) * 4);
6236 // if (!CurItem->TrueColors) {
6237 // CurItem->TrueColors.reset(new DialogItemTrueColors);
6239 // *CurItem->TrueColors = *(const DialogItemTrueColors *)Param2;
6241 if (Dlg
->InCtlColorDlgItem
== 0 && Dlg
->DialogMode
.Check(DMODE_SHOW
)) { //???
6242 Dlg
->ShowDialog(Param1
);
6248 case DM_SETREADONLY
: {
6250 CurItem
->Flags
|= DIF_READONLY
;
6252 CurItem
->Flags
&= ~DIF_READONLY
;
6254 if (FarIsEdit(Type
)) {
6255 DlgEdit
*CurItemEdit
= (DlgEdit
*)CurItem
->ObjPtr
;
6257 CurItemEdit
->SetReadOnly(Param2
? 1 : 0);
6261 "%s: DM_SETREADONLY invoked for non-edit item %u\n",
6262 __FUNCTION__
, Param1
);
6264 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) { //???
6265 Dlg
->ShowDialog(Param1
);
6271 /*****************************************************************/
6272 // получить позицию и размеры контрола
6273 case DM_GETITEMPOSITION
: // Param1=ID, Param2=*SMALL_RECT
6277 if (Dlg
->GetItemRect(Param1
, Rect
)) {
6278 *reinterpret_cast<PSMALL_RECT
>(Param2
) = Rect
;
6284 /*****************************************************************/
6285 case DM_SETITEMDATA
: {
6286 LONG_PTR PrewDataDialog
= CurItem
->UserData
;
6287 CurItem
->UserData
= Param2
;
6288 return PrewDataDialog
;
6290 /*****************************************************************/
6291 case DM_GETITEMDATA
: {
6292 return CurItem
->UserData
;
6294 /*****************************************************************/
6295 case DM_EDITUNCHANGEDFLAG
: // -1 Get, 0 - Skip, 1 - Set; Выделение блока снимается.
6297 if (FarIsEdit(Type
)) {
6298 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
6299 int ClearFlag
= EditLine
->GetClearFlag();
6302 EditLine
->SetClearFlag((int)Param2
);
6303 EditLine
->Select(-1, 0); // снимаем выделение
6305 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) //???
6307 Dlg
->ShowDialog(Param1
);
6317 /*****************************************************************/
6318 case DM_GETSELECTION
: // Msg=DM_GETSELECTION, Param1=ID, Param2=*EditorSelect
6319 case DM_SETSELECTION
: // Msg=DM_SETSELECTION, Param1=ID, Param2=*EditorSelect
6321 if (FarIsEdit(Type
) && Param2
) {
6322 if (Msg
== DM_GETSELECTION
) {
6323 EditorSelect
*EdSel
= (EditorSelect
*)Param2
;
6324 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
6325 EdSel
->BlockStartLine
= 0;
6326 EdSel
->BlockHeight
= 1;
6327 EditLine
->GetSelection(EdSel
->BlockStartPos
, EdSel
->BlockWidth
);
6329 if (EdSel
->BlockStartPos
== -1 && !EdSel
->BlockWidth
)
6330 EdSel
->BlockType
= BTYPE_NONE
;
6332 EdSel
->BlockType
= BTYPE_STREAM
;
6333 EdSel
->BlockWidth
-= EdSel
->BlockStartPos
;
6339 EditorSelect
*EdSel
= (EditorSelect
*)Param2
;
6340 DlgEdit
*EditLine
= (DlgEdit
*)(CurItem
->ObjPtr
);
6342 // EdSel->BlockType=BTYPE_STREAM;
6343 // EdSel->BlockStartLine=0;
6344 // EdSel->BlockHeight=1;
6345 if (EdSel
->BlockType
== BTYPE_NONE
)
6346 EditLine
->Select(-1, 0);
6348 EditLine
->Select(EdSel
->BlockStartPos
, EdSel
->BlockStartPos
+ EdSel
->BlockWidth
);
6350 if (Dlg
->DialogMode
.Check(DMODE_SHOW
)) //???
6352 Dlg
->ShowDialog(Param1
);
6365 // Все, что сами не отрабатываем - посылаем на обработку обработчику.
6366 return Dlg
->CallDlgProc(Msg
, Param1
, Param2
);
6371 Посылка сообщения диалогу
6372 Некоторые сообщения эта функция обрабатывает сама, не передавая управление
6373 обработчику диалога.
6375 LONG_PTR WINAPI
SendDlgMessage(HANDLE hDlg
, int Msg
, int Param1
, LONG_PTR Param2
)
6380 return InterThreadCall
<LONG_PTR
, 0>(std::bind(SendDlgMessageSynched
, hDlg
, Msg
, Param1
, Param2
));
6383 void Dialog::SetPosition(int X1
, int Y1
, int X2
, int Y2
)
6385 CriticalSectionLock
Lock(CS
);
6388 RealWidth
= X2
- X1
+ 1;
6393 RealHeight
= Y2
- Y1
+ 1;
6397 ScreenObject::SetPosition(X1
, Y1
, X2
, Y2
);
6399 //////////////////////////////////////////////////////////////////////////
6400 BOOL
Dialog::IsInited()
6402 CriticalSectionLock
Lock(CS
);
6403 return DialogMode
.Check(DMODE_INITOBJECTS
);
6406 void Dialog::SetComboBoxPos(DialogItemEx
*CurItem
)
6408 if (GetDropDownOpened()) {
6410 CurItem
= Item
[FocusPos
];
6412 int EditX1
, EditY1
, EditX2
, EditY2
;
6413 ((DlgEdit
*)CurItem
->ObjPtr
)->GetPosition(EditX1
, EditY1
, EditX2
, EditY2
);
6415 if (EditX2
- EditX1
< 20)
6416 EditX2
= EditX1
+ 20;
6418 if (ScrY
- EditY1
< Min(Opt
.Dialogs
.CBoxMaxHeight
, CurItem
->ListPtr
->GetItemCount()) + 2
6419 && EditY1
> ScrY
/ 2)
6420 CurItem
->ListPtr
->SetPosition(EditX1
,
6421 Max(0, EditY1
- 1 - Min(Opt
.Dialogs
.CBoxMaxHeight
, CurItem
->ListPtr
->GetItemCount()) - 1),
6422 EditX2
, EditY1
- 1);
6424 CurItem
->ListPtr
->SetPosition(EditX1
, EditY1
+ 1, EditX2
, 0);
6428 bool Dialog::ProcessEvents()
6430 return !DialogMode
.Check(DMODE_ENDLOOP
);
6433 void Dialog::SetId(const GUID
&Id
)