Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.09.05;
Скачать: CL | DM;

Вниз

Последний штришок в программу.   Найти похожие ветки 

 
Германн ©   (2010-06-12 02:18) [0]

В главном окне программы есть RichEdit, в который записывается "протокол" общения с внешним железом. Т.е. >"послано что-то", <" принято то-то".
Желательно всегда видеть самую нижнюю строку в этом RichEdit. Когда работа ведется из этого окна, то никаких проблем. SelStart и SetFocus дают результат. Но вот если при этом модально открыто (может модальность и ни при чём, не проверял) другое окно программы, то SelStart и SetFocus не срабатывают. Очевидно из-за того, что SetFocus не отрабатывает, что в общем понятно.
Так и вопрос. Как и что можно предпринять в данном случае?


 
turbouser ©   (2010-06-12 02:22) [1]

OnActivate для формы с ричедитом - в там SelStart и SetFocus


 
Германн ©   (2010-06-12 02:41) [2]


> turbouser ©   (12.06.10 02:22) [1]
>
> OnActivate для формы с ричедитом - в там SelStart и SetFocus

Ты не понял.
В окне главной формы (там где ричэдит) нажимается кнопка, по которой вызывается модально другая форма. В ней создаются и посылаются команды (запросы) к внешнему железу. И пока эту другую форму не закроешь первая (она же главная) не доступна в части SetFocus какому-то своему контроллу.

P.S. Этот ричэдит видим (хоть частично), но всегда видим. И это требование заказчика. И я его понимаю.


 
turbouser ©   (2010-06-12 02:44) [3]


> Германн ©   (12.06.10 02:41) [2]


> Ты не понял.
Ээммм.. то есть, надо пока отображается модальная форма, рисовать что-то на главной форме? А смысл?


 
Германн ©   (2010-06-12 03:02) [4]

На главной форме в RichEdit"е всегда ведётся лог. Сей лог порой весьма полезен для анализа.
Но и немало важно, чтоб сей лог можно было видеть (хоть частично) .
Те самые модальные формы - небольшие по размеру. Они закрывают только небольшую часть экрана.
Привычка у заказчика уже выработалась. Этой привычке пожалуй уже лет 10.
Не, если нет простых решений, то так тому и быть! Без вопросов.
Объяснить данному заказчику я смогу.


 
Eraser ©   (2010-06-12 03:11) [5]

RichEdit.SelStart := Length(RichEdit.Text);
или
RichEdit.SelStart := RichEdit.Perform(WM_GETTEXTLENGTH, 0, 0);
должно спасти.


 
Eraser ©   (2010-06-12 03:16) [6]

PS попробуйте в паре с выключенным hideselection.


 
Германн ©   (2010-06-12 03:42) [7]


> Eraser ©   (12.06.10 03:16) [6]

Попробую.
Спасибо, Лёха!


 
KilkennyCat ©   (2010-06-12 12:39) [8]

void RichTextAppend(char *cText)
{
   CHARRANGE   cr;

   cr.cpMin = -1;cr.cpMax = -1;
SendMessage(hChatLog,EM_EXSETSEL,0,(LPARAM)&cr);
SendMessage(hChatLog,EM_REPLACESEL, 0, (LPARAM)cText);
   SendMessage(hChatLog,WM_VSCROLL, /*SB_LINEDOWN*/ SB_BOTTOM, (LPARAM)NULL);
   return;
}

надено, грят, работает.


 
Германн ©   (2010-06-13 00:38) [9]


>  SendMessage(hChatLog,WM_VSCROLL, SB_BOTTOM,  (LPARAM)NULL);

Эта строчка помогла.Предыдущие мне не нужны.
Спасибо, Костя!


 
Германн ©   (2010-06-13 03:11) [10]

Теперь решил воплотить в жизнь свои старые идеи, ради которых выбрал для вывода лога RichEdit (ну не могу ничего не делать! А непосредственный заказчик в лучшем случае хоть как-то озаботится проверкой прошивки контроллера и программой тестирования только во вторник, в лучшем случае).
Алгоритм таков:
При посылке команды устанавливаю:
 RELog.SelStart:=Length(RELog.Text);
 RELog.SelAttributes.Color:=clBlack;
 RELog.Lines.Add(FormatDateTime("dd/mm/yy hh:nn:ss",Now)+">"+IntToHex(SEAddr.Value,2)+
IntToHex(StrToInt(ELength.Text),2)+St+Copy(ECRC.Text,1,Length(ECRC.Text)-1));
 RELog.SelStart:=Length(RELog.Text);
 RELog.SelAttributes.Color:=clRed;
 RELog.Lines.Add("<");

После получении "правильного" ответа
 if Answ = OK then begin
   RELog.SelStart:=Length(RELog.Text)-Length(St)-RELog.Lines.Count*2-1;
   RELog.SelLength:=Length(St)+2+RELog.Lines.Count*2;
   RELog.SelAttributes.Color:=clBlack;
 end;

но не работает сей код. То ли я не правильно задаю SelStsrt, то ли SelLength, то ли и то и другое.


 
_Юрий ©   (2010-06-13 11:22) [11]

а зачем именно РичЭдит для лога?
(я просто как то раз тоже решил так сделать, однако через некоторое время выяснилось, что идея нехороша, заменил на грид)


 
KilkennyCat ©   (2010-06-13 12:53) [12]

не работает как? цвет не меняет?
а правильный ответ меняет уже где-то там неправильный?


 
KilkennyCat ©   (2010-06-13 12:57) [13]

я вот лично полюбил нтмл...
простой listbox с поддержкой мини-html
вечером приду на работу, скину образец с компонентом.


 
KilkennyCat ©   (2010-06-13 16:00) [14]

//Поддержка мини-HTML,SelectionColor, SelectionFontColor, ShowFocusRect
//мини-HTML:
//, , <FONT color=>
//все теги должны иметь закрытие
//пример: Раздел A <FONT color="#CC0000">СЕЛЬСКОЕ ХОЗЯЙСТВО, ОХОТА И ЛЕСНОЕ ХОЗЯЙСТВО</FONT>

unit KimRobListBox;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls;

type
TKimRobListBox = class(TListBox)
private
  FSelectionColor: TColor;
  FSelectionFontColor: TColor;
  FShowFocusRect : Boolean;
  procedure SetSelectionColor(const Value: tcolor);
  procedure SetSelectionFontColor(const Value: tcolor);
  procedure SetShowFocusRect(const Value: Boolean);
  procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
protected
  procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
public
  constructor Create(AOwner:TComponent);Override;
  destructor Destroy;Override;
published
  property Style default lbOwnerDrawFixed;
  property SelectionColor: TColor read FSelectionColor write SetSelectionColor;
  property SelectionFontColor: TColor read FSelectionFontColor write SetSelectionFontColor;
  property ShowFocusRect: Boolean read FShowFocusRect write SetShowFocusRect;

end;

procedure Register;

implementation

constructor TKimRobListBox.Create(AOwner: TComponent);
begin
Inherited Create(AOwner);
Style := lbOwnerDrawFixed;
end;

procedure TKimRobListBox.SetSelectionColor(const Value: tcolor);
begin
 FSelectionColor := Value;
 Invalidate;
end;

procedure TKimRobListBox.SetShowFocusRect(const Value: Boolean);
begin
 FShowFocusRect := Value;
 Invalidate;
end;

procedure TKimRobListBox.SetSelectionFontColor(const Value: tcolor);
begin
 FSelectionFontColor := Value;
 Invalidate;
end;

procedure TKimRobListBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);
type
 THTML = record
   color : TColor;
   style : TFontStyles;
   text : string;
 end;
var
 Data: String;

 function colorh(s : string) : TColor;
 begin
   s := "$00" + s[5] + s[6] + s[3] + s[4] + s[1] + s[2];
   if not IdentToColor(S, Longint(Result)) then Result := TColor(StrToIntDef(S, $1FFFFFFF));
 end;

 procedure DrawParserHTML(data : string);
 var
   i, l, ml, x : integer;
   tagS, text : string;
   DataHTML : array of THTML;
   Flags: Longint;
 begin
   Flags := DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
   i := 0;
   l := length(data);
   tagS := "";
   text := "";
   ml := 1;
   setlength(datahtml, ml);
   datahtml[ml - 1].color := clNone;
   datahtml[ml - 1].style := [];
   datahtml[ml - 1].text := "";
   repeat
     inc(i);
     if data[i] = "<" then begin
       tags := data[i];
       repeat
         inc(i);
         tagS := tags + data[i];
       until (data[i] = ">") or (i = l);
       inc(ml);
       setlength(datahtml, ml);
       if tags[2] = "/" then begin
         if "</FONT>" = tags then datahtml[ml - 1].color := clNone;
         if "" = tags then datahtml[ml - 1].style := [];
         if "
" = tags then datahtml[ml - 1].style := [];
       end else begin
         x := pos("<FONT color=", tagS);
         if x > 0 then datahtml[ml - 1].color := colorh(copy(tagS,x + 14, 6)) else datahtml[ml - 1].color := datahtml[ml - 2].color;
         if "" = tags then datahtml[ml - 1].style := [fsBold] else //datahtml[ml - 1].style := datahtml[ml - 2].style;
         if "" = tags then datahtml[ml - 1].style := [fsItalic] else datahtml[ml - 1].style := datahtml[ml - 2].style;
       end;
       datahtml[ml - 2].text := text;
       datahtml[ml - 1].text := "";
       text := "";
     end else text := text + data[i];
   until i = l;
   if ml = 1 then datahtml[ml - 1].text := text;
   for i := 0 to high(datahtml) do if datahtml[i].text <> "" then begin
     canvas.Font.Color := datahtml[i].color;
     canvas.Font.Style := datahtml[i].style;
     DrawText(Canvas.Handle, PChar(datahtml[i].text), Length(datahtml[i].text), Rect, Flags);
     rect.Left := rect.Left + canvas.TextWidth(datahtml[i].text);
   end;
   setlength(datahtml, 0);
 end;

begin
 begin
   Canvas.FillRect(Rect);
   if Index < Count then begin
     if not UseRightToLeftAlignment then Inc(Rect.Left, 2) else Dec(Rect.Right, 2);
     if (Style in [lbVirtual, lbVirtualOwnerDraw]) then Data := DoGetData(Index) else Data := Items[Index];
     DrawParserHTML(data);
   end;
 end;
end;

procedure TKimRobListBox.CNDrawItem(var Message: TWMDrawItem);
var
 State: TOwnerDrawState;
begin
 with Message.DrawItemStruct^ do begin
   State := TOwnerDrawState(LoWord(itemState));
   Canvas.Handle := hDC;
   Canvas.Font := Font;
   Canvas.Brush := Brush;
   if (Integer(itemID) >= 0) and (odSelected in State) then begin
     Canvas.Brush.Color := clRed;
     Canvas.Font.Color := clBlue;
   end;
   if Integer(itemID) >= 0 then DrawItem(itemID, rcItem, State) else Canvas.FillRect(rcItem);
   if (odFocused in State) and FShowFocusRect then DrawFocusRect(hDC, rcItem);
   Canvas.Handle := 0;
 end;
end;

destructor TKimRobListBox.Destroy;
begin
  Inherited;
end;

procedure Register;
begin
 RegisterComponents("KimRob", [TKimRobListBox]);
end;

end.


 
KilkennyCat ©   (2010-06-13 16:01) [15]

жуть какая...


 
Германн ©   (2010-06-13 20:38) [16]


> KilkennyCat ©   (13.06.10 12:53) [12]
>
> не работает как? цвет не меняет?

Меняет.Только то начало выделения куда-то съезжает, то конец.


 
Германн ©   (2010-06-13 20:39) [17]


> Юрий ©   (13.06.10 11:22) [11]
>
> а зачем именно РичЭдит для лога?

Только для выделения цветом ошибок обмена с железякой.


 
KilkennyCat ©   (2010-06-13 23:16) [18]

тогда не проще ли ListBox? Переписать DrawItem, ну можно добавить массив хранения "ошибок" и все. полчаса возни всего.


 
Германн ©   (2010-06-13 23:38) [19]


> KilkennyCat ©   (13.06.10 23:16) [18]
>
> тогда не проще ли ListBox?

У ричэдита есть встроенная запись в rtf-формате. Таким образом выделение сохраняется в файле, который можно просмотреть в любое время любым человеком.
Так и не понял как можно вычислить начало выделения зная RELog.Text. Такое впечатление, что при моих вычислениях есть какой-то неучтенный байт в каждой строке RELog.
Пошел другим путем.
   RELog.SelStart:=RELog.SelStart-Length(St);
   RELog.SelLength:=Length(St);

Заработало.



Страницы: 1 вся ветка

Текущий архив: 2010.09.05;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.007 c
15-1276107937
da4
2010-06-09 22:25
2010.09.05
Онлайн музыка


4-1239772550
SPeller
2009-04-15 09:15
2010.09.05
Как достоверно определить что программа запущена как сервис?


15-1276201773
Юрий
2010-06-11 00:29
2010.09.05
С днем рождения ! 11 июня 2010 пятница


4-1239652712
Unlocker
2009-04-13 23:58
2010.09.05
Запуск под админом


15-1276064997
12
2010-06-09 10:29
2010.09.05
Какой умный человек поместил русскую "C" и латинскую "C" на одну