Page 1 of 1

Posted: 2 Oct 2007 7:02
by Chan Bok
Here are the codes for richControl.pro corresponding to richControl.cnt.
Use setText() and setStyle() to initialize the control.

Code: Select all

implement richControl         inherits window, controlSupport         open core, vpiDomains, gui_native   constants         className = "axon/rich/richControl".         classVersion = "".   clauses         classInfo(className, classVersion). %============================ % CONSTANTS %============================ constants         em_STREAMIN     = 1097.         em_STREAMOUT    = 1098.         % sf_text               = 0x0001.         sf_rtf          = 0x0002. %============================ % DOMAINS %============================ domains         editstream = editstream(unsigned32 Cookie,unsigned32 Error,stream_callback).         % Cookie domains can also be a string or cookie = cookie(unsigned).           stream_callback = (unsigned32 Cookie,string Buff,unsigned Cb,unsigned Pb) ->                 unsigned32 determ (i,i,i,o) language stdcall. %============================ % FACTS %============================ class facts         content_ : string := "".         % Not a good design to use class facts, but difficult otherwise. facts         hwnd_ : windowHandle := erroneous.         style_ : unsigned := 0. %============================ % NEW %============================ clauses         new(Parent):-                 new(),                 setContainer(Parent).           new():-                 window::new(),                 controlSupport::new(This),                 generatedInitialize(). %============================ % SETSTYLE  An interface %============================         setStyle(Style):- style_ := Style.              % Style is windows native style %============================ % SHOW %============================ clauses    show():-                 rich::richLoadDLL(DLL_class),                                   % - (o) Usually DLL_class = "RichEdit50W"              % Above loads "Msftedit.dll" at most once                 Container = getContainer(),                 _RichWin = vpi::createCustomControl(getEventHandler(), getRect(),                    u_dlgbase, "", Container:getVpiWindow(), getState(), getCtrlId()),   % Note - hardcoded for u_dlgbase only                 Style = ws_child + style_,                 % e.g.  style_ = ws_visible + ws_vscroll + es_multiline + es_autovscroll  + es_nohidesel + es_readonly,                 % Note - vscrollbar is created in hwnd_, not in RichWin                 getClientSize(Width, Height),                 hwnd_ := gui_native::createWindowEx(0,DLL_class,"",Style,                            0,0,Width,Height,getVpiWindow(),null,mainExe::getCurrentHinstance(),null),                 content_ := getText(),                 Cookie = convert(unsigned32,0+0),                               % Trick to avoid compiler warning "Superfluous conversion..."                 ESTREAM = editstream(Cookie,0,rich_callback),                 LPARAM = uncheckedConvert(integer,ESTREAM),                 _NoChar = vpi::winSendEvent(hwnd_,e_Native(em_STREAMIN,sf_rtf,LPARAM)).  % Access violation here if Cookie is a constant   %============================ % CALLBACK %============================ class predicates        % object predicate (i.e. std call) cannot be used as a value (gives privileged instruction error)         rich_callback : stream_callback.                                % - (i,i,i,o) clauses         rich_callback(_Cookie,Buff,Cb,Actual) = 0:-!,                 stream_in(Buff,Cb,Actual).                              % - (i,i,o)   class predicates         stream_in: (string Buff,unsigned Cb,unsigned Actual) procedure (i,i,o). clauses         stream_in(Buff,Cb,Cb):-                                         % Case(1) All but last Streams    (Observed Cb=4094)                 Len = string::length(content_),                 Cb < (Len+Len),!,                 string::front(content_,Cb div 2,Front,Rest),                 content_ := Rest,                 Source = uncheckedConvert(pointer,Front),                 Dest = uncheckedConvert(pointer,Buff),                 memory::copy(Dest,Source,convert(byteCount,Cb)).           stream_in(Buff,_Cb,ActualRead*2):-                      % Case(2) Last Stream                 ActualRead = string::length(content_),                 Source = uncheckedConvert(pointer,content_),                 Dest = uncheckedConvert(pointer,Buff),                 memory::copy(Dest,Source,ActualRead*2),                 content_ := "". %============================ % ONSIZE   Without this vscrollbar won't be resized %============================ predicates         onSize : window::sizeListener. clauses         onSize(_Source):-                 getClientSize(Width, Height),           % This is in pixel                 vpi::winMove(hwnd_,rct(0,0,Width,Height)). %============================ % AUTO CODES %============================ % This code is maintained automatically, do not update it manually. 14:05:40-1.10.2007 facts   predicates         generatedInitialize : (). clauses         generatedInitialize():-                 setText("richControl"),                 This:setSize(148, 74),                 addSizeListener(onSize). % end of automatic code   end implement richControl

Chan Bok
Axon Research

Posted: 2 Oct 2007 23:01
by Thomas Linder Puls
Nice, I couldn't resist updating the code somewhat:

Code: Select all

interface richEditCbObj     open core predicates    stream_in: (pointer Buffer, byteCount BufferSize) -> byteCount Actual. end interface richEditCbObj   implement richeditControl     inherits userControlSupport     supports richEditCbObj     open core, vpiDomains, gui_native   constants     className = "richeditControl/richeditControl".     classVersion = "$JustDate:  $$Revision:  $".   clauses     classInfo(className, classVersion).   class facts     loaded : boolean := false().   clauses     new(Parent):-         new(),         setContainer(Parent).   clauses     new():-         if loaded = false() then             _ = useDll::load("Msftedit.dll"),             loaded := true()         end if,         userControlSupport::new(),         generatedInitialize().   constants     em_streamIn = 1097.     em_streamOut = 1098.     sf_text = 0x0001.     sf_rtf = 0x0002.     sf_rtfnoobjs = 0x0003. % write only     sf_textized = 0x0004. % write only     sf_unicode = 0x0010. % unicode file (ucs2 little endian)     sf_usecodepage = 0x0020. % codepage given by high word     sf_ncrfornonascii = 0x40. % output /un for nonascii     sff_writextrapar = 0x80. % output \par at end     domains     stream_callback = (richEditCbObj Cookie, pointer Buff, byteCount BufferSize, byteCount Pb) -> unsigned determ (i,i,i,o) language stdcall.     editstream = editstream(richEditCbObj Cookie, unsigned Error, stream_callback CallBack).   facts     content : string := "".     hwnd : windowHandle := erroneous.     style : unsigned := ws_visible + ws_vscroll + es_multiline + es_autovscroll.     % e.g.   style = ws_visible + ws_vscroll + es_multiline + es_autovscroll  + es_nohidesel + es_readonly,   clauses    show():-         userControlSupport::show(),         Style = ws_child + style,         getClientSize(Width, Height),         hwnd := createWindowEx(0, "RichEdit50W", "", Style, 0, 0, Width, Height, getVpiWindow(), null, mainExe::getCurrentHinstance(), null),         content := getText(),         EStream = editstream(This, 0, rich_callback),         LParam = uncheckedConvert(integer, EStream),         _NoChar = vpi::winSendEvent(hwnd, e_Native(em_streamIn, sf_text+sf_unicode, LParam)).  % Access violation here if Cookie is a constant   class predicates     rich_callback : stream_callback. clauses     rich_callback(ThisCtrl, Buffer, BufferSize, Actual) = 0 :-         Actual = ThisCtrl:stream_in(Buffer, BufferSize).   clauses     stream_in(Buffer, BufferSize) = Read :-         Read = math::min(BufferSize, 2 * string::length(content)),         memory::copy(Buffer, content, Read),         content := uncheckedConvert(string, memory::pointerAdd(content, Read)).   predicates     onSize : window::sizeListener. clauses     onSize(_Source):-         getClientSize(Width, Height), % This is in pixel         vpi::winMove(hwnd, rct(0, 0, Width, Height)).   % This code is maintained automatically, do not update it manually. 21:21:34-2.10.2007 facts   predicates     generatedInitialize : (). clauses     generatedInitialize():-         setText("richeditControl"),         This:setSize(240, 120),         addSizeListener(onSize). % end of automatic code end implement richeditControl
The changes can be summarized as follows:
  • I have changed the control to receive text (Unicode) instead of rich text format (you can easily change it back; I just didn't have any RTF text to test with).
  • I have changed the types on the structs and callbacks to suite the usage better (byteCount instead of unsigned32, etc).
  • I use the control object itself as "Cookie" (in form of the privately supported richEditCbObj). That way I avoid using a class fact for holding the "contents" of the control
  • I inherit from userControlSupport simplifying some of the code
  • I have added the DLL load code directly to the class

Posted: 2 Oct 2007 23:31
by Thomas Linder Puls
It seems to be quite a lot easier to use the "EM_SETTEXTEX" mesage:

Code: Select all

implement richeditControl     inherits userControlSupport     open core, vpiDomains, gui_native   constants     className = "richeditControl/richeditControl".     classVersion = "$JustDate:  $$Revision:  $".   clauses     classInfo(className, classVersion).   class facts     loaded : boolean := false().   clauses     new(Parent):-         new(),         setContainer(Parent).   clauses     new():-         if loaded = false() then             _ = useDll::load("Msftedit.dll"),             loaded := true()         end if,         userControlSupport::new(),         generatedInitialize().   constants     wm_user = 1024.     em_streamIn = wm_user+73.     em_streamOut = wm_user+74.     em_setTextEx = wm_user+97.   constants     st_default = 0.     st_keepundo = 1.     st_selection = 2.     st_newchars = 4.   constants     unicode_codepage = 1200.   domains     setTextEx = setTextEx(unsigned Flags, unsigned Codepage).   facts     hwnd : windowHandle := erroneous.     style : unsigned := ws_visible + ws_vscroll + es_multiline + es_autovscroll.     % e.g.   style = ws_visible + ws_vscroll + es_multiline + es_autovscroll  + es_nohidesel + es_readonly,   clauses    show():-         userControlSupport::show(),         Style = ws_child + style,         getClientSize(Width, Height),         hwnd := createWindowEx(0, "RichEdit50W", "", Style, 0, 0, Width, Height, getVpiWindow(), null, mainExe::getCurrentHinstance(), null),         WParam = uncheckedConvert(unsigned, setTextEx(st_default, unicode_codepage)),         LParam = uncheckedConvert(integer, getText()),         _NoChar = vpi::winSendEvent(hwnd, e_Native(em_setTextEx, WParam, LParam)).  % Access violation here if Cookie is a constant   predicates     onSize : window::sizeListener. clauses     onSize(_Source):-         getClientSize(Width, Height), % This is in pixel         vpi::winMove(hwnd, rct(0, 0, Width, Height)).   % This code is maintained automatically, do not update it manually. 21:21:34-2.10.2007 facts   predicates     generatedInitialize : (). clauses     generatedInitialize():-         setText("richeditControl"),         This:setSize(240, 120),         addSizeListener(onSize). % end of automatic code end implement richeditControl
It should handle both RTF and plain text by examining the string.

Posted: 3 Oct 2007 2:03
by Chan Bok
Astonishing!

I tested with some rtf texts and it works fine.

Many thanks.

Chan Bok
Axon Research

Posted: 12 Nov 2007 19:50
by Thomas Linder Puls
I have added a wiki article with some of this content: RichEdit control.

Justification

Posted: 18 Oct 2010 7:56
by Ferenc Nagy
There was a RichEdit example in the version 5.2.
The justification of the paragraphs was missing from it.
Why?
Question to the same 5.2 RichEdit.
I'd like to edit Flip Album Vista Pro flp files. One file contains more

Code: Select all

<RTF> rich text </RTF>
blocks.
The above RICHEDIT.exe reads whole files. What should I do that it will be able to read blocks within files.

how to add table in the RichEdit example

Posted: 5 May 2011 5:02
by djh
HI,
how to add table in the RichEdit example ?
thk!

This RichEdit.exe does not insert picture,pls help me

Posted: 2 Sep 2012 16:30
by djh
This RichEdit.exe does not insert picture,why?what should I do?,pls help me