C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[39985] Re:TWebBrowser 에서 에디팅이 가능한가요?
황경록 [mpbox] 3653 읽음    2005-04-29 10:51
http://www.cpcug.org/user/clemenzi/technical/Languages/RichEdit.htm

즐빌하세요...


RichEdit
The Windows supplied RichEdit component can be used to display formatted text, i.e. text where each character can be formatted independent of all the others.
As of 12-2003, I know of several versions of this control

Riched.dll  236Kb 98  This is identified as a Windows 95 version, but it is not on my Windows 95 system. It is on a Windows 98 system, has the same date, time, and version as one of the Riched32.dll files, but not the same size. 
Riched32.dll  174Kb 95
184Kb 98
    4Kb XP  This is identified as a Windows 95 version. The Windows XP version is just a wrapper for Riched20.dll. 
Riched20.dll  288Kb 95
422Kb 98
417Kb XP  288Kb is version 2; 422Kb and 417Kb are version 3 

Because Windows 2000 and Windows XP replace Riched32.dll with a wrapper to Riched20.dll, some applications (in particular, one that I wrote) will work perfectly on one operating system and fail on another. This behavior is known as DLL Hell.
Visual Basic | Delphi | Windows XP Problems | References


--------------------------------------------------------------------------------

Visual Basic 6.0
Basically, the RichEdit control is not documented. Only a small number of the ActiveX parameters and functions are available to the user unless you want to use Windows Messages.
The built-in help is completely worthless ... except for the sections on how to manipulate selected text.

Scrollbar control is very responsive.

There is no obvious way to disable word wrap!! (give me a break!)
It appears that the RightMargin property controls this. 0 (the default) forces word wrap. Since the value is in twips, use a large value (like 500000) to disable word wrap.
A related example from some c-code supplied with VB

  SendMessage(predoc->hwndRE, EM_SETTARGETDEVICE,
    (WPARAM) predoc->hdcTarget, (LPARAM) xWidth);


--------------------------------------------------------------------------------

Parameters
Parameters and functions related to selecting text, modifying its font, and copying it to the clipboard seem to work ok.
 
SelStart  Current insertion point. Setting this forces SelLength=0, must be >=0 
SelLength  Returns or sets the number of characters selected, must be >=0 
SelText  Currently selected text 
SelColor  Changes (or returns) the color of the selected text. If no text is selected, it sets the color of any new text entered at the insertion point. 
Scrollbars  Controls whether the scrollbars are horizontal or vertical. Read only at run time. 
DisableNoScroll    Enables/disables scrollbars. 
AutoVerbMenu  Controls the display of the automatic Cut, Copy, Paste pop-up menu. 

Use SelFontName, SelFontSize, and SelFontColor to Set Font Attributes
The help says to use SelFontColor in one section and SelColor in another section.



--------------------------------------------------------------------------------

Related Windows Messages
In order to use these, you need to include the SendMessage function prototype and related constants in your program. Basically, this is fairly simple, except that most of the documented capabilities don't work. In general, the Borland C++ RichText Control help is much better than the VB help because it actually explains things. However, the help on the constants is identical.
Search the help for EM_ (Windows messages) and ES_ (Edit Styles)


' Edit Control Messages - from WIN32API.TXT
Const EM_GETSEL              = &HB0
Const EM_SETSEL              = &HB1  ' Selects all text
Const EM_GETRECT             = &HB2
Const EM_SETRECT             = &HB3
Const EM_SETRECTNP           = &HB4
Const EM_SCROLL              = &HB5  ' Scrolls one page or one line up or down
Const EM_LINESCROLL          = &HB6  ' Goes to end of file only
Const EM_SCROLLCARET         = &HB7  ' Seems ok
Const EM_GETMODIFY           = &HB8
Const EM_SETMODIFY           = &HB9
Const EM_GETLINECOUNT        = &HBA  ' Works
Const EM_LINEINDEX           = &HBB
Const EM_SETHANDLE           = &HBC
Const EM_GETHANDLE           = &HBD  ' Fails - the Borland help explains why
Const EM_GETTHUMB            = &HBE  ' Fails
Const EM_LINELENGTH          = &HC1
Const EM_REPLACESEL          = &HC2
Const EM_GETLINE             = &HC4  '
Const EM_LIMITTEXT           = &HC5
Const EM_CANUNDO             = &HC6
Const EM_UNDO                = &HC7
Const EM_FMTLINES            = &HC8
Const EM_LINEFROMCHAR        = &HC9
Const EM_SETTABSTOPS         = &HCB
Const EM_SETPASSWORDCHAR     = &HCC
Const EM_EMPTYUNDOBUFFER     = &HCD
Const EM_GETFIRSTVISIBLELINE = &HCE  ' Works
Const EM_SETREADONLY         = &HCF
Const EM_SETWORDBREAKPROC    = &HD0
Const EM_GETWORDBREAKPROC    = &HD1
Const EM_GETPASSWORDCHAR     = &HD2

EM_GETTHUMB - to retrieve the position of the scroll box (thumb) - Fails
EM_SCROLL - to scroll the text vertically - up or down one page or line
EM_LINESCROLL - to scroll the text vertically or horizontally - Fails

The following always returns zero
tt = SendMessage(RichTextBox1.hwnd, EM_GETTHUMB, 0, 0)
The EM_SCROLL messages only uses 4 of the 17 ScrollBar constants
(yes, I tried all 8 unique codes).

Const SB_LINEUP   = 0  ' Scrolls  up  one line
Const SB_LINEDOWN = 1  ' Scrolls down one line
Const SB_PAGEUP   = 2  ' Scrolls  up  one page
Const SB_PAGEDOWN = 3  ' Scrolls down one page




--------------------------------------------------------------------------------

Delphi
This Delphi 5 code fragment is from comctrls.pas
procedure TCustomRichEdit.CreateParams(var Params: TCreateParams);
const
  RichEditModuleName = 'RICHED32.DLL';
begin
    FRichEditModule := LoadLibrary(RichEditModuleName);

The LoadLibrary function explains why Depends does NOT list either Riched32.dll or Riched20.dll as one of the required modules.

Notice that this actually selects different controls depending on which operating system is used. Specifically,

In Windows 98, Riched32.dll and Riched20.dll are separate programs
In Windows XP, Riched32.dll is just a wrapper for Riched20.dll
This is one of the reasons why some programs that work perfectly under Windows 98 crash under Windows XP (and others).
Basic Examples | Paste From Clipboard | Other | Windows XP Problems


--------------------------------------------------------------------------------

Some Basic Examples
  UIRichEdit.SelAttributes.color := clGreen;
  UIRichEdit.WordWrap := false;
  BoldButton.Down := fsBold in RichEdit1.SelAttributes.Style;
    (in is not in the regular help index, search delphi.hlp
      This example is from the SelAttributes example)
  Memo1.Font.Style := [fsBold]; // Style is a set
                                // The square bracket syntax is not explained
                                //  but it is required for sets

  RichEdit1.Perform(EM_SCROLLCARET, 0, 0); // Directly send a Windows message

   procedure TWinControl.DefaultHandler(var Message);
        Result := CallWindowProc(FDefWndProc, FHandle, Msg, WParam, LParam);



  property WordWrap: Boolean;
  procedure ScrollBy(DeltaX, DeltaY: Integer); // Values are in pixels

   // Set the selection to the beginning of a line
  with RichEdit1 do begin
    SelStart := perform(em_LineIndex, spinedit1.value, 0);



--------------------------------------------------------------------------------

Paste From Clipboard
When you copy text to the clipboard, several different formats may be saved.

When you paste from the clipboard, TRichEdit decides which format to use and how to render it.

The default functionality can be observed by simply placing a TRichEdit component on a blank form and running the application.

Highlight some text on a web page
Copy it to the clipboard
Paste it in your TRichEdit component
Bold, underline, and hyperlinks are rendered - even if TRichEdit.PlainText = true (unfortunately, this property only affects streaming, not pasting).
I have one web page that actually displays html tags (which I use to copy and paste to pages I write using notepad). When these are pasted, the tags are interpreted (kind of defeats the purpose).

The problem is that I just want the clipboard pasted as text with bold, italic and other crap removed. (In this case, I am using TRichEdit as a replacement for TMemo which has a size limitation - ~32K)

While I was not able to find any obvious way to control this (the ability to set a preferred clipboard format would have been nice), I was able to develop a work around. Simply deriving a new component based on TRichEdit does not work because most of the functionality is based on RICHED32.DLL (that is why copy and paste work without adding any additional code.) Instead, I used 2 menu selections and the TEditPaste action to capture the Paste keystrokes and to paste the clipboard data as text.

The following code shows how the TEditPaste action normally works - WM_PASTE instructs the dll to do whatever it wants.

procedure TEditPaste.ExecuteTarget(Target: TObject);
begin
   GetControl(Target).PasteFromClipboard;
end;

procedure TCustomEdit.PasteFromClipboard;
begin
  SendMessage(Handle, WM_PASTE, 0, 0);
end;

The solution is to

Create 2 menu items (one for each shortcut key)
Connect each menu item to the same TEditPaste action
Set the menu shortcut keys to Ctrl-V and Shift-Ins
Hide one of the menu items - the shortcut key will still work
Set the action's OnExecute to the following
procedure TForm1.EditPaste1Execute(Sender: TObject);
begin
  SendMessage(RichEdit1.Handle, EM_PASTESPECIAL, CF_TEXT, 0);
end;

Normally, Actions are written to determine their targets at runtime. However, since that is not possible when code is attached to OnExecute, RichEdit1.Handle is used instead. If you need that functionality, then derive a new action from TEditPaste.
I tried several other approaches, but these did not work. For instance

I told the form to capture WM_PASTE messages - but the break point was never hit
Notes: When copying from notepad or a TMemo, the clipboard contained 3 formats (1, 16, 7). When pasting these, html code was not interpreted. When copying from Internet Explorer, the clipboard contained 8 formats (51906, 1, 13, 53478, 52434, 51949, 16, 7), 4 of them not defined. When pasting these, html code was interpreted.



--------------------------------------------------------------------------------

Other
When you save to a file, and wordwrap is on, the new linebreaks are saved (have not "recently" verifed this)
****

Use this to search the text

TCustomRichEdit.FindText
From EM_FINDTEXTEX in the Windows SDK help

fuFlags

FT_MATCHCASE
FT_WHOLEWORD

FR_DOWN is new to version 2, It must be added for a version 2 search
        to be the same as a version 1 search

Microsoft SDK

****

Copying rtf text from one RichEdit control to another works fine in Windows 98, but causes a "resource error" in Windows XP because it converts the rtf codes and does not place them in the Text property. XP RichEdit Design Problem presents a solution using streams.
How to insert a Smiley image into a TRxRichEdit? shows how to do this with streams and a callback function.



--------------------------------------------------------------------------------

Windows XP Problems
Windows XP is a complete disaster - the RichEdit control was rewritten.
This is unbelievable - I wrote a program using Delphi 5 that used the Microsoft RichEdit control (via TRichEdit).

It runs perfectly under Windows 98.
It is completely hosed under Windows XP
These are the problems I currently know about. They are all related to the fact that the default changed from treating an rtf input as plain text to processing the tags and displaying formatted text.
If I read an *.rtf file into a TRichEdit, all the rtf codes are automatically removed.
When the PlainText property is true, Windows 98 shows all the text in the file - just like opening the file in notepad. In Windows XP, the rtf codes are removed.

When I try to write an rtf file to disk, all the rtf codes are removed.
When the PlainText property is false, both Windows 98 and Windows XP show the text formatted (colors, fonts, underline, and the like are displayed) - just like opening the file in MS Word. However, when you try to save the file, Windows XP removes the rtf codes and Windows 98 does not.

Copying rtf text from one RichEdit control to another works fine in Windows 98, but causes a resource error in Windows XP. XP RichEdit Design Problem presents a solution using streams.
One of the things that bothers me about this is that I was not able to find any information related to these problems by searching the internet.

This line of code works perfectly in Windows 98, but fails in Windows 2000 (and Windows XP).

  PlainText_UIRichEdit.Text := rtf_string;

It is executed in Controls.pas via
  Perform(WM_SETTEXT, 0, Longint(Buffer));
  Perform(CM_TEXTCHANGED, 0, 0);

Here is one way to work around the problem, this method converts the string to a stream and then loads the RichEdit control from the stream - when this is done the PlainText property controls the rtf conversion.
var
xx: TStringStream ;
begin
  xx := TStringStream.Create(rtf_string);

  PlainText_UIRichEdit.Lines.LoadFromStream(xx);

  xx.Free;
end;

Another option is to tell the RichEdit control not to interpret the text as rtf - this code should work with RichEdit v2 and is ignored by the old version. To use the constants, add richedit to your uses clause.
  SendMessage(PlainText_UIRichEdit.Handle, EM_SETTEXTMODE, TM_PLAINTEXT, 0);

  PlainText_UIRichEdit.Text := rtf_string;

Well, it doesn't exactly work - in Windows XP, it interprets the rtf codes and displays the formatted text ... except that the "hidden" text is not displayed and there is no documented method to display it. CFE_HIDDEN is defined in CHARFORMAT2 and implemeted in Rich Edit 3.0.
There is no difference using TM_PLAINTEXT or TM_RICHTEXT - though the help files say that there is supposed to be.

Do not confuse these

Perform simulates getting a message from Windows
SendMessage sends a message to the Windows API


--------------------------------------------------------------------------------

References
Yet Another Code Site
This has lots of information on TRichEdit - most (all) of the examples are written in Borland C++ Builder (BCB).
Faster rich edit syntax highlighting explains how to speed up a syntax highlighting algorithm - it was 3 minutes, now its 8 seconds. Basically, disable screen updates (with WM_SETREDRAW), disable OnChange messages (with EM_SETEVENTMASK), and use messages to modify the colors (instead of the TRichEdit properties).


SynEdit is a 32-bit syntax highlighting edit control, not based on Windows built-in controls. However, it does not support word wrapping.


--------------------------------------------------------------------------------

Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Languages / RichEdit.htm

utime.김성하 님이 쓰신 글 :
: 안녕하세요 utime.김성하 입니다.
: 네이트온이나 Msn 메신저의 에디터 기능을 구현하려 합니다.
:
: 지난번 이 관련되어 질문을 드렸는데 어느 분께서 TWebBrowser Compnent를 이용해서 html로 처리하는게 편하다고 하시더군요
:
: 그런데 살펴 보니 TWebBrowser 는 M$ IE를 이용해서 그냥 뷰어 정도 가능한 것 같은데 TWebBrowser에서 메신져 처럼 에디팅이 가능 한가요?
:
: 참고로 네이트 온은 SoftWeb_Control이란 클래스를, Msn은 RichEdit20W 라는 클래스를 쓰던데 이 클래스에 관련된 참고할 만한 자료가 있는지요...
:
: 답변 부탁 드립니다~ ^^;

+ -

관련 글 리스트
39981 TWebBrowser 에서 에디팅이 가능한가요? utime.김성하 2896 2005/04/29
39987     모든 길은 구글형님에게 있습니다..... (내용무) ^^:: 황경록 1359 2005/04/29
40044         오호~ 감샤합니다.~ 구굴이라... 이런 좋은 면이 있었군요~ (냉무) utime.김성하 1371 2005/05/03
39986     Re:TWebBrowser 에서 에디팅이 가능한가요? 황경록 1769 2005/04/29
39985     Re:TWebBrowser 에서 에디팅이 가능한가요? 황경록 3653 2005/04/29
39984     Re:TWebBrowser 에서 에디팅이 가능한가요? 황경록 1943 2005/04/29
39983     Re:TWebBrowser 에서 에디팅이 가능한가요? 황경록 2199 2005/04/29
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.