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

Вниз

Как подогнать размеры TRichEdit под текст в нем   Найти похожие ветки 

 
@!!ex ©   (2010-01-19 23:52) [0]

Нужно чтобы TRichEdit занимал ровно столько места, сколько нужно чтобы отобразить весь текст без скролла и без лишней пустоты.


 
Игорь Шевченко ©   (2010-01-20 00:12) [1]

вывести текст в ричедит, настроить шрифт и атрибуты, растягивая, найти приемлемый вид, записать размеры.


 
@!!ex ©   (2010-01-20 00:22) [2]

Это жесть...


 
Игорь Шевченко ©   (2010-01-20 00:28) [3]

@!!ex ©   (20.01.10 00:22) [2]

Я наверное не понял твой вопрос - ты хочешь, чтобы ричедит сам менял свои размеры, в зависимости от текста в нем ?


 
Игорь Шевченко ©   (2010-01-20 00:29) [4]

В любом случае загляни в Dialogs.pas, посмотри, как они размеры в CreateMessageDialog подгоняют под текст.


 
@!!ex ©   (2010-01-20 00:40) [5]

> Я наверное не понял твой вопрос - ты хочешь, чтобы ричедит
> сам менял свои размеры, в зависимости от текста в нем ?

Да. Я ExtendedHintWindow пишу на базе RichEdit.
В принципе пофиг, я действительно проще сам буду размеры окна указывать. В принципе не такая уж проблема.


> [4] Игорь Шевченко ©   (20.01.10 00:29)

У меня так еще и картинки...
Просто размер текста относительно не сложно выяснить через Canvas.TextWidth/TextHeight
А вот что с картинками делать - не понятно.
Так что действительно вручную буду указывать.


 
Игорь Шевченко ©   (2010-01-20 00:48) [6]


> Да. Я ExtendedHintWindow пишу на базе RichEdit.


Я бы писал на базе обыкновенного окна, без фокуса с клавиатуры и возможности модификации содержимого. Для компоновки текста с картинками советую, опять же, посмотреть на TFlowPanel в Delphi, начиная с 2005 (по-моему) в ExtCtrls.pas


 
@!!ex ©   (2010-01-20 01:00) [7]

RichEdit позволяет просто загружать rtf документ и не парится. Что очень удобно, т.к. позволяет дополнять и изменять описание не трогая кода проги.


 
Anatoly Podgoretsky ©   (2010-01-20 11:40) [8]

> @!!ex  (19.01.2010 23:52:00)  [0]

Даже 100 мегабайт?


 
Anatoly Podgoretsky ©   (2010-01-20 11:41) [9]

> @!!ex  (20.01.2010 00:40:05)  [5]

Именно так, какая проблема с заведомо известными текстами.


 
@!!ex ©   (2010-01-20 13:09) [10]

Кажется нашел решение с подгоном текста:
http://www.codeproject.com/KB/edit/richeditsize.aspx
http://support.microsoft.com/kb/257849

Но никак не получается это на дельфи сделать...


 
MBo ©   (2010-01-20 13:11) [11]

У RichEdit есть событие специально обученное ....


 
@!!ex ©   (2010-01-20 13:12) [12]

> [11] MBo ©   (20.01.10 13:11)

Я так и понял... Но никак не могу понять как это использовать...


 
@!!ex ©   (2010-01-20 13:57) [13]

Что я делаю не так:

var
 RichEdit:TRxRichEdit;

Function MyWndProc(hwnd:integer; Msg:integer; wParam:integer; lParam:integer):integer; stdcall;
var
 rResize:TREQSIZE;
 MaskHdr:Tnmhdr;
begin
  case Msg of
    WM_NOTIFY:begin
        CopyMemory(@MaskHdr, Pointer(lParam), sizeof(MaskHdr));

        if MaskHdr.code = EN_REQUESTRESIZE then begin
           CopyMemory(@rResize, Pointer(lParam), sizeof(rResize));
           RichEdit.Height:=rResize.rect.Bottom;
           RichEdit.Width:=rResize.rect.Right;
        end;
      end;
  end;

  Result := CallWindowProc(Pointer(OldWndProc), hwnd, Msg, wParam, lParam);
end;

Procedure NewWindowProc();
begin
  OldWndProc := SetWindowLong(RichEdit.Handle, GWL_WNDPROC, Integer(@MyWndProc))
end;

Procedure ResetWindProc();
begin
  SetWindowLong(RichEdit.Handle, GWL_WNDPROC, OldWndProc)
end;

Procedure Form.LoadFromFile();
begin
 FRichEdit.Lines.LoadFromFile(FileName);

 CurrentMask :=SendMessage( FRichEdit.Handle,EM_GETEVENTMASK, 0, 0);
 SendMessage( FRichEdit.Handle,EM_SETEVENTMASK, 0, (CurrentMask or ENM_REQUESTRESIZE));
 SendMessage( FRichEdit.Handle,EM_REQUESTRESIZE, 0, 0);
end;


 
@!!ex ©   (2010-01-20 14:30) [14]

Может я с константами накосячил??

WM_NOTIFY = $4E;
EM_GETEVENTMASK = WM_USER + 59;
EM_SETEVENTMASK = WM_USER + 69;
ENM_REQUESTRESIZE = $40000;
EN_REQUESTRESIZE = $701;


 
MBo ©   (2010-01-20 14:32) [15]

событие дельфийского компонента TRichEdit.OnResizeRequest, оно есть в инспекторе объектов, использовать нетрудно.


 
@!!ex ©   (2010-01-20 14:45) [16]

Сделал OnResizeRequest
приходит Rect размером 0,0,0,6900


 
@!!ex ©   (2010-01-20 14:58) [17]

Причем событие вызывается только при открытии файла.


 
MBo ©   (2010-01-20 15:34) [18]

ну вот я загрузил небольшой файл
событие вызвалось два раза
73  18  258  36
73  18  258  998

73  18 - это координаты левого угла RichEdit  на форме


 
@!!ex ©   (2010-01-20 15:46) [19]

> [18] MBo ©   (20.01.10 15:34)

Покажи код? Может я чего упустил.


 
MBo ©   (2010-01-20 16:07) [20]

richedit1.Lines.LoadFromFile("d:\a.txt");

procedure TForm2.RichEdit1ResizeRequest(Sender: TObject; Rect: TRect);
begin
 Memo1.Lines.Add(Format("%d  %d  %d  %d",[rect.Left, rect.Top, rect.Right, rect.Bottom]));
end;


 
@!!ex ©   (2010-01-20 16:25) [21]

Похоже это косяк TRxRichEdit.... Не хочет размер указывать...


 
MBo ©   (2010-01-20 16:31) [22]

TRxRichEdit выдал три события (ширина контрола другая, наверно, не следил):
50  35  247  1010
50  35  229  1023
50  35  229  1023


 
@!!ex ©   (2010-01-20 17:36) [23]

6900 - это из-за того, что ширина нулевая...
ширину он не хочет указывать...


 
@!!ex ©   (2010-01-20 18:46) [24]

Неожиданная проблема...
Решил написать с нуля и у меня не отображается TRichEdit на Hint"e.
В старом коде все работало, но я его по глупостью не сохранил когда переписывал...
Вроде бы восстановил, но видимо что-то упустил.
В первый момент TRichEdit виден, но сразу пропадает.

unit HintWindowEx;
interface
uses
 Windows, Classes, Controls, Forms, Messages, Graphics, rxRichEd, StdCtrls, ComCtrls,
 SysUtils;
type
 TddgHintWindow = class(THintWindow)
 private
   FRichEdit:TRichEdit;
   FHintPath:string;
   FAdvancedHint:boolean;
   Procedure SetHintFile(const Hint:string);
 public
   Constructor Create(AOwner:TComponent); override;
   destructor Destroy; override;
   procedure ActivateHint(Rect: TRect; const AHint: string); override;
   procedure Paint; override;
   procedure CreateParams(var Params: TCreateParams); override;
 end;

implementation
destructor TddgHintWindow.Destroy;
begin
 inherited Destroy;
end;

constructor TddgHintWindow.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);

 FRichEdit:=TRichEdit.Create(self);
 FRichEdit.Parent:=self;
 FRichEdit.ParentWindow:=self.Handle;
 FRichEdit.Left:=0;
 FRichEdit.Top:=0;
 FRichEdit.Width:=10;
 FRichEdit.Height:=10;
 FRichEdit.ScrollBars:=ssNone;
 FRichEdit.BorderStyle:=bsNone;
 FRichEdit.ReadOnly:=true;
 FRichEdit.Visible:=false;

 FHintPath:=ExtractFilePath(ParamStr(0))+"\HHelp\";
 FAdvancedHint:=false;
end;

procedure TddgHintWindow.Paint;
var
 R: TRect;
begin
 if FAdvancedHint then begin
   //Ничего не делаем, т.к. RichEdit сам нарисуется
 end
 else begin
   R := ClientRect; // get bounding rectangle
   Canvas.Font.Color := clInfoText; // set to proper color
   { paint string in the center of the round rect }
   DrawText(Canvas.Handle, PChar(Caption), Length(Caption), R, DT_NOPREFIX or DT_WORDBREAK or DT_CENTER or DT_VCENTER);
 end;
end;

procedure TddgHintWindow.SetHintFile(const Hint: string);
begin
{  if FileExists(FHintPath+Hint) then begin
   FRichEdit.Lines.LoadFromFile(FHintPath+Hint);
 end
 else begin   }
   FRichEdit.Lines.Clear();
   FRichEdit.Lines.Add("File not found "+Hint);
{ end;   }
   FRichEdit.Width:=500;
   FRichEdit.Height:=500;
   ClientWidth:=FRichEdit.Width;
   ClientHeight:=FRichEdit.Height;  
end;

procedure TddgHintWindow.CreateParams(var Params: TCreateParams);
begin
 inherited CreateParams(Params);
 Params.Style := Params.Style and not ws_Border;
end;

procedure TddgHintWindow.ActivateHint(Rect: TRect; const AHint: string);
begin
 FRichEdit.Visible:=false;
 inherited ActivateHint(Rect, AHint);
 FAdvancedHint:=(Length(AHint)>1) and (AHint[1]="*");

 if FAdvancedHint then begin
   SetHintFile(Copy(AHint,2,Length(AHint)));
   FRichEdit.Visible:=true;
 end;
end;

var
 OldHintClass: THintWindowClass;
function SetNewHintClass(AClass: THintWindowClass): THintWindowClass;
var
 DoShowHint: Boolean;
begin
 Result := HintWindowClass; // return value is old hint window
 DoShowHint := Application.ShowHint;
 if DoShowHint then
   Application.ShowHint := False; // destroy old hint window
 HintWindowClass := AClass; // assign new hint window
 if DoShowHint then
   Application.ShowHint := True; // create new hint window
end;

initialization
 OldHintClass := SetNewHintClass(TddgHintWindow);
finalization
 SetNewHintClass(OldHintClass);
end.


 
@!!ex ©   (2010-01-20 19:42) [25]

Это из-за консоли. Если {$APPTYPE CONSOLE} , то объекты на хинте не рисуются. почему? Я не знаю.


 
Anatoly Podgoretsky ©   (2010-01-21 09:34) [26]

Не вижу inherrited в TddgHintWindow.Paint;

Зачем в консоли Хинт? Вроде бы как ее назначение совсем другое, особенно чистая консоль.


 
@!!ex ©   (2010-01-21 10:15) [27]

> [26] Anatoly Podgoretsky ©   (21.01.10 09:34)

Зачем там inherited? У меня же полностью свой вывод...


> [26] Anatoly Podgoretsky ©   (21.01.10 09:34)
> Зачем в консоли Хинт? Вроде бы как ее назначение совсем
> другое, особенно чистая консоль.

Ну там же не только консоль, но и куча форм.


 
Anatoly Podgoretsky ©   (2010-01-21 10:32) [28]

> @!!ex  (21.01.2010 10:15:27)  [27]

Зачем inherited, на этот вопрос сложно ответить, не изучая глубоко код, но принято при наследование сначала вызывать код предка, а потом исполнять свой.
А с консолью разберись, не надо в этом случае указывать, что у тебя консольное приложение.


 
@!!ex ©   (2010-01-21 12:18) [29]

> [28] Anatoly Podgoretsky ©   (21.01.10 10:32)
Зачем inherited, на этот вопрос сложно ответить, не изучая глубоко код, но принято при наследование сначала вызывать код предка, а потом исполнять свой.

Оригинальный код рисует хинт по своему. Если делать inherited, то хинт начинает мелькать, т.к. сначала рисуется по старому, потому рисуется мной.


> А с консолью разберись, не надо в этом случае указывать,
> что у тебя консольное приложение.

Создать консоль вручную?


 
Anatoly Podgoretsky ©   (2010-01-21 12:55) [30]

> @!!ex  (21.01.2010 12:18:29)  [29]

Конечно вручную, раз у тебя комбо


 
Наиль ©   (2010-01-21 23:40) [31]

>[0]
Я бы попытался использовать скролы ричедита.
Они точно знают размер вписаного в ричедит текста.
К примеру создать дополнительный ричедит в отрицательных координатах относительно родительского окна (например, на главной форме) размером 100х100. Выводил бы в него свой текст, выяснял бы характеристики скролла GetScrollInfo и по формуле определял бы размер РичЕдита хинта.


 
Наиль ©   (2010-01-22 00:19) [32]

http://www.delphimaster.net/view/7-1072692942



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

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

Наверх




Память: 0.55 MB
Время: 0.011 c
2-1264058602
tipman
2010-01-21 10:23
2010.03.21
Запуск файла с любым расширением ( *.doc) в качестве исполняемого


2-1263762231
@!!ex
2010-01-18 00:03
2010.03.21
Как сделать форму не замерзающую при вызове диалогов.


2-1263838589
mpdasa
2010-01-18 21:16
2010.03.21
как написать: если A>2 и А<5 тогда


15-1262069352
БарЛог
2009-12-29 09:49
2010.03.21
пример.испытание


2-1263482392
Sunktor
2010-01-14 18:19
2010.03.21
Как в CodeGear Delphi 2009 запретить показ вкладки Welcome Page