C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: RichEdit  (Прочитано 2884 раз)
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


RichEdit
« : 27 Март 2015, 15:57:27 »

Подскажите, как запомнить позицию курсора в RichEdit?
В RichEdit постоянно программно добавляются записи. Если пользователь щелкнул на какой то записи, или перешел на запись клавишами, то курсор должен оставаться на этой записи 2 минуты или до того момента когда пользователь снова сам не выбрал запись самостоятельно. Просто программа добавляет записи, и курсор автоматически смещается на последнюю. Как можно зафиксировать курсор для выше описанной ситуации?
Записан
OVE
Участник


Сказали спасибо: +67/-0
Offline

Сообщений: 72


Re: RichEdit
« Ответ #1 : 27 Март 2015, 19:07:03 »

Попробуйте вставку записи сделать так
Код:
    int iPos=RichEdit1->SelStart;
    Form1->ActiveControl=NULL;
    RichEdit1->Lines->Add("Очередная запись");
    RichEdit1->SelStart=iPos;
    RichEdit1->SetFocus();
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: RichEdit
« Ответ #2 : 28 Март 2015, 15:30:18 »

только на всякий случай надо еще сохранять SelLength.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: RichEdit
« Ответ #3 : 30 Март 2015, 19:11:45 »

Я не совсем понимаю куда этот код надо добавить?
Строки добавляться в RichEdit1 когда от устройства приходит сигнал в порт.
Выглядит это так:
Код
//класс для записи в RichEdit из потока 
class TUpdateRichEdit : public TIdNotify
{
protected:
String sText;
void __fastcall DoNotify();
public:
__fastcall TUpdateRichEdit( const String &sMessage );
};
 

Код
__fastcall TUpdateRichEdit::TUpdateRichEdit( const String &sMessage )
: TIdNotify(), sText(sMessage)
{
}
 
void __fastcall TUpdateRichEdit::DoNotify()
{
if (sText.IsEmpty()) return;
 
 
if ((Form1Main) && (Form1Main->RichEditProtocol) && (Form1Main->CheckBox1))
if(Form1Main->CheckBox1->Checked == true)
Form1Main->RichEditProtocol->Lines->Add(sText);//добавление
 
}
//******************
 
void ZapisVRichEditWindow(String zapis)
{
//экземпляр класса class TUpdateRichEdit : public TIdNotify
TUpdateRichEdit *updateLB = new TUpdateRichEdit(zapis);
try
{
updateLB->Notify();
}
catch (const Exception &)
 {
delete updateLB;
throw;
 }
 
}
 
 
//**** вызов функции для записи строки в RichEdit
ZapisVRichEditWindow(mis);//вызывается из потока IdTCPServer1Execute
 

Как в эту конструкцию добавить таймер на две минуты для запоминания курсора если пользователь щелкнул в RichEdit мышкой? А если пользователь снова кликнул, то начать новый отсчет двух минут запоминания нового места курсора. А если пользователь две минуты не кликал, то курсор снова должен уйти на последнию запись.

Так написать?
Код
if ((Form1Main) && (Form1Main->RichEditProtocol) && (Form1Main->CheckBox1))
if(Form1Main->CheckBox1->Checked == true)
                       {
                        int iPos = RichEditProtocol->SelStart;
                        Form1Main->ActiveControl=NULL;
Form1Main->RichEditProtocol->Lines->Add(sText);//добавление
                        Form1Main->RichEditProtocol->SelStart=iPos;
                        Form1Main->RichEditProtocol->SetFocus();
                       }
 
 

Но так не отслеживается курсор при клике пользователя и таймера нет...
Записан
OVE
Участник


Сказали спасибо: +67/-0
Offline

Сообщений: 72


Re: RichEdit
« Ответ #4 : 30 Март 2015, 22:58:58 »

Я думаю, нужно добавить таймер с интервалом срабатывания 1сек. Завести глобальную переменную iCnt, которая будет увеличиваться на 1 при каждом срабатывании таймера. При клике мышкой или клавиатурой по RichEdit нужно обнулять этот счетчик.
Код:
int iCnt=0; //если нужно, чтобы при старте в конец добавлялись строки, проинициализировать iCnt=121
//---------------------------------------------------------------------------
void __fastcall Form1Main::RichEditProtocolKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
   iCnt=0;
}
//---------------------------------------------------------------------------

void __fastcall Form1Main::RichEditProtocolMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
   iCnt=0;
}
//---------------------------------------------------------------------------
void __fastcall Form1Main::Timer1Timer(TObject *Sender)
{
   iCnt++;
}

При добавлении новой строки добавить проверку, превышает ли значение iCnt число 120 (2 минуты бездействия оператора)
Если превышает, то добавляем по простому варианту(со скролом в конец списка), если нет - по сложному.
Код:
if ((Form1Main) && (Form1Main->RichEditProtocol) && (Form1Main->CheckBox1))
if(Form1Main->CheckBox1->Checked == true)
                        {
                         if(iCnt>120)
                               {  int iPos = RichEditProtocol->SelStart;
                                   Form1Main->ActiveControl=NULL;
           Form1Main->RichEditProtocol->Lines->Add(sText);//добавление
                                   Form1Main->RichEditProtocol->SelStart=iPos;
                                   Form1Main->RichEditProtocol->SetFocus();
                                }
                         else
                             Form1Main->RichEditProtocol->Lines->Add(sText);
                        }
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: RichEdit
« Ответ #5 : 31 Март 2015, 10:34:12 »

Большое спасибо!
Есть пару вопросов.
При попытке уйти с вкладки PageControl где находиться RichEdit, возникает AV не возможности поставить фокус на невидимый компонент.
Правильно ли мое решение?
1.
Код
int iCnt = 41; //тестовое значение
 
if ((Form1Main) && (Form1Main->RichEditProtocol) && (Form1Main->CheckBox1))
if(Form1Main->CheckBox1->Checked == true)
{
 if(iCnt 40)
  {
                                      //правильный порядок? Добавляем в двух местах ActivePageIndex
                                       int iPos = Form1Main->RichEditProtocol->SelStart;
if(Form1Main->PageControl1->ActivePageIndex == 3)
Form1Main->ActiveControl = NULL;
 
Form1Main->RichEditProtocol->Lines->Add(sText);//добавление
Form1Main->RichEditProtocol->SelStart = iPos;
 
if(Form1Main->PageControl1->ActivePageIndex == 3)
Form1Main->RichEditProtocol->SetFocus();
  }
  else
 {
  Form1Main->RichEditProtocol->Lines->Add(sText);
  iCnt = 0;
  Form1Main->Timer1->Enabled = false;
 }
           }
 

Код
void __fastcall TForm1Main::RichEditProtocolMouseDown(TObject *Sender, TMouseButton Button,
 TShiftState Shift, int X, int Y)
{
iCnt = 0;
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1Main::Timer1Timer(TObject *Sender)
{
iCnt++;
}
//---------------------------------------------------------------------------
void __fastcall TForm1Main::RichEditProtocolKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
 
{
iCnt = 0;
Timer1->Enabled = true;
}
 

2. На сколько я понимаю переполнения int iCnt не будет так как у меня есть else с отключением таймера?

3. Может добавить объявление int iCnt в раздел public: формы и обращаться Form1Main->iCnt или без разницы?


Записан
OVE
Участник


Сказали спасибо: +67/-0
Offline

Сообщений: 72


Re: RichEdit
« Ответ #6 : 31 Март 2015, 10:47:51 »

1. Если AV не возникает, то решение правильное. Смущает, только обнуление iCnt в ветке else. В этом случае и таймер отключится и значение обнулится. Мне кажется, эту строку нужно закоментировать.
2. Переполнения в данном случае бояться не надо, ибо оно наступит лет через 90 непрерывной работы программы (да еще при условии, что оператор ни разу к RichEdit не притронется)
3. как ни объяви iCnt (членом класса или как глобальную переменную) в данном случае результат не изменится.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: RichEdit
« Ответ #7 : 31 Март 2015, 11:28:04 »

Цитировать
Смущает, только обнуление iCnt в ветке else.

Может тогда так?:
Код
if(iCnt  40)
{
//курсор установлен на том месте где щелкнул пользователь
//если пользователь еще раз щелкнет начнется новый период времени
//тут вроде все нормально
}
else
{
//пользователь ничего не делал нет дополнительных щелчков мыши
//период времени истек
//вернем все параметры таймера и  iCnt в состояние по дефолту как при старте программы
//запись будет добавлена и курсор уйдет на последнию
}
//и поэтому else таким надо сделать:
Form1Main->RichEditProtocol->Lines->Add(sText);
iCnt = 41;//по дефолту
Form1Main->Timer1->Enabled = false;//по дефолту
 
 
Записан
OVE
Участник


Сказали спасибо: +67/-0
Offline

Сообщений: 72


Re: RichEdit
« Ответ #8 : 31 Март 2015, 12:04:37 »

Можно и так. Только внесите код в тело else
Код:
if(iCnt {
//курсор установлен на том месте где щелкнул пользователь
//если пользователь еще раз щелкнет начнется новый период времени
//тут вроде все нормально
}
else
{
//пользователь ничего не делал нет дополнительных щелчков мыши
//период времени истек
//вернем все параметры таймера и  iCnt в состояние по дефолту как при старте программы
//запись будет добавлена и курсор уйдет на последнию
//и поэтому else таким надо сделать:
Form1Main->RichEditProtocol->Lines->Add(sText);
iCnt = 41;//по дефолту
Form1Main->Timer1->Enabled = false;//по дефолту
}
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #9 : 31 Март 2015, 12:34:40 »

Цитировать
Только внесите код в тело else
Да, конечно.
Большое спасибо!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.063 секунд. Запросов: 19.