diff --git a/components/richmemo/samples/testsimple/project1.lpi b/components/richmemo/samples/testsimple/project1.lpi index f43b24e80..04f617c3c 100644 --- a/components/richmemo/samples/testsimple/project1.lpi +++ b/components/richmemo/samples/testsimple/project1.lpi @@ -6,7 +6,7 @@ - + @@ -32,14 +32,14 @@ - + - + @@ -47,10 +47,10 @@ - - + + - + @@ -58,84 +58,84 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -146,7 +146,7 @@ - + @@ -157,98 +157,98 @@ - + - + - + - + - + - + - + - + - + - + - + - + - - - - + + + + - - - - + + + + @@ -256,7 +256,7 @@ - + @@ -266,25 +266,25 @@ - + - + - + - + @@ -292,167 +292,207 @@ - + - + - + - + - - - - + + + + - - - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - + - + - + - + - - + + - - + + - - + + - + - - + + - - + + - - + + - + - + - + - + - + - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + @@ -460,13 +500,6 @@ - - - - - - - diff --git a/components/richmemo/samples/testsimple/unit1.lfm b/components/richmemo/samples/testsimple/unit1.lfm index b2b78a40a..90070bc92 100644 --- a/components/richmemo/samples/testsimple/unit1.lfm +++ b/components/richmemo/samples/testsimple/unit1.lfm @@ -10,9 +10,9 @@ object Form1: TForm1 OnCreate = FormCreate LCLVersion = '0.9.27' object RichMemo1: TRichMemo - Left = 8 + Left = 16 Height = 366 - Top = 8 + Top = 16 Width = 619 Anchors = [akTop, akLeft, akRight, akBottom] Font.Height = -13 @@ -22,9 +22,8 @@ object Form1: TForm1 'RichMemo1' ) ParentFont = False - ScrollBars = ssBoth + ScrollBars = ssVertical TabOrder = 0 - WordWrap = False end object Button1: TButton Left = 24 @@ -62,7 +61,7 @@ object Form1: TForm1 Top = 382 Width = 75 Anchors = [akLeft, akBottom] - Caption = 'Export' + Caption = 'Save RTF' OnClick = Button4Click TabOrder = 4 end @@ -72,7 +71,7 @@ object Form1: TForm1 Top = 382 Width = 75 Anchors = [akLeft, akBottom] - Caption = 'Import' + Caption = 'Load RTF' OnClick = Button5Click TabOrder = 5 end diff --git a/components/richmemo/samples/testsimple/unit1.lrs b/components/richmemo/samples/testsimple/unit1.lrs index 77916e5a7..31459c3ed 100644 --- a/components/richmemo/samples/testsimple/unit1.lrs +++ b/components/richmemo/samples/testsimple/unit1.lrs @@ -4,31 +4,31 @@ LazarusResources.Add('TForm1','FORMDATA',[ 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3#196#0#6'Height'#3#201#1#3'Top'#3#181#0#5 +'Width'#3'z'#2#13'ActiveControl'#7#9'RichMemo1'#7'Caption'#6#5'Form1'#12'Cli' +'entHeight'#3#201#1#11'ClientWidth'#3'z'#2#8'OnCreate'#7#10'FormCreate'#10'L' - +'CLVersion'#6#6'0.9.27'#0#9'TRichMemo'#9'RichMemo1'#4'Left'#2#8#6'Height'#3 - +'n'#1#3'Top'#2#8#5'Width'#3'k'#2#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight' + +'CLVersion'#6#6'0.9.27'#0#9'TRichMemo'#9'RichMemo1'#4'Left'#2#16#6'Height'#3 + +'n'#1#3'Top'#2#16#5'Width'#3'k'#2#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight' +#8'akBottom'#0#11'Font.Height'#2#243#9'Font.Name'#6#6'Tahoma'#13'HideSelecti' +'on'#8#13'Lines.Strings'#1#6#9'RichMemo1'#0#10'ParentFont'#8#10'ScrollBars'#7 - +#6'ssBoth'#8'TabOrder'#2#0#8'WordWrap'#8#0#0#7'TButton'#7'Button1'#4'Left'#2 - +#24#6'Height'#2#25#3'Top'#3'~'#1#5'Width'#3#160#0#7'Anchors'#11#6'akLeft'#8 - +'akBottom'#0#7'Caption'#6#17'Make Bold and Red'#7'OnClick'#7#12'Button1Click' - +#8'TabOrder'#2#1#0#0#7'TButton'#7'Button2'#4'Left'#3#192#0#6'Height'#2#25#3 - +'Top'#3'~'#1#5'Width'#2'a'#7'Anchors'#11#6'akLeft'#8'akBottom'#0#7'Caption'#6 - +#11'Get Attribs'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#2#0#0#7'TButton' - +#7'Button3'#4'Left'#3'0'#1#6'Height'#2#25#3'Top'#3'~'#1#5'Width'#2'`'#7'Anch' - +'ors'#11#6'akLeft'#8'akBottom'#0#7'Caption'#6#11'Select Font'#7'OnClick'#7#12 - +'Button3Click'#8'TabOrder'#2#3#0#0#7'TButton'#7'Button4'#4'Left'#3#16#2#6'He' - +'ight'#2#25#3'Top'#3'~'#1#5'Width'#2'K'#7'Anchors'#11#6'akLeft'#8'akBottom'#0 - +#7'Caption'#6#6'Export'#7'OnClick'#7#12'Button4Click'#8'TabOrder'#2#4#0#0#7 - +'TButton'#7'Button5'#4'Left'#3#184#1#6'Height'#2#25#3'Top'#3'~'#1#5'Width'#2 - +'K'#7'Anchors'#11#6'akLeft'#8'akBottom'#0#7'Caption'#6#6'Import'#7'OnClick'#7 - +#12'Button5Click'#8'TabOrder'#2#5#0#0#7'TButton'#7'Button6'#4'Left'#2#24#6'H' - +'eight'#2#25#3'Top'#3#159#1#5'Width'#3#160#0#7'Anchors'#11#6'akLeft'#8'akBot' - +'tom'#0#7'Caption'#6#16'Next Style Range'#7'OnClick'#7#12'Button6Click'#8'Ta' - +'bOrder'#2#6#0#0#11'TFontDialog'#11'FontDialog1'#11'MinFontSize'#2#0#11'MaxF' - +'ontSize'#2#0#4'left'#3'`'#1#3'top'#3'('#2#0#0#11'TSaveDialog'#11'SaveDialog' - +'1'#10'DefaultExt'#6#4'.rtf'#6'Filter'#6#27'RichText file (*.rtf)|*.rtf'#7'O' - +'ptions'#11#17'ofOverwritePrompt'#14'ofEnableSizing'#12'ofViewDetail'#0#4'le' - +'ft'#3#24#1#3'top'#3'('#2#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt' - +#6#4'.rtf'#6'Filter'#6#27'RichText file (*.rtf)|*.rtf'#4'left'#3#208#0#3'top' - +#3'('#2#0#0#0 + +#10'ssVertical'#8'TabOrder'#2#0#0#0#7'TButton'#7'Button1'#4'Left'#2#24#6'Hei' + +'ght'#2#25#3'Top'#3'~'#1#5'Width'#3#160#0#7'Anchors'#11#6'akLeft'#8'akBottom' + +#0#7'Caption'#6#17'Make Bold and Red'#7'OnClick'#7#12'Button1Click'#8'TabOrd' + +'er'#2#1#0#0#7'TButton'#7'Button2'#4'Left'#3#192#0#6'Height'#2#25#3'Top'#3'~' + +#1#5'Width'#2'a'#7'Anchors'#11#6'akLeft'#8'akBottom'#0#7'Caption'#6#11'Get A' + +'ttribs'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#2#0#0#7'TButton'#7'Butt' + +'on3'#4'Left'#3'0'#1#6'Height'#2#25#3'Top'#3'~'#1#5'Width'#2'`'#7'Anchors'#11 + +#6'akLeft'#8'akBottom'#0#7'Caption'#6#11'Select Font'#7'OnClick'#7#12'Button' + +'3Click'#8'TabOrder'#2#3#0#0#7'TButton'#7'Button4'#4'Left'#3#16#2#6'Height'#2 + +#25#3'Top'#3'~'#1#5'Width'#2'K'#7'Anchors'#11#6'akLeft'#8'akBottom'#0#7'Capt' + +'ion'#6#8'Save RTF'#7'OnClick'#7#12'Button4Click'#8'TabOrder'#2#4#0#0#7'TBut' + +'ton'#7'Button5'#4'Left'#3#184#1#6'Height'#2#25#3'Top'#3'~'#1#5'Width'#2'K'#7 + +'Anchors'#11#6'akLeft'#8'akBottom'#0#7'Caption'#6#8'Load RTF'#7'OnClick'#7#12 + +'Button5Click'#8'TabOrder'#2#5#0#0#7'TButton'#7'Button6'#4'Left'#2#24#6'Heig' + +'ht'#2#25#3'Top'#3#159#1#5'Width'#3#160#0#7'Anchors'#11#6'akLeft'#8'akBottom' + +#0#7'Caption'#6#16'Next Style Range'#7'OnClick'#7#12'Button6Click'#8'TabOrde' + +'r'#2#6#0#0#11'TFontDialog'#11'FontDialog1'#11'MinFontSize'#2#0#11'MaxFontSi' + +'ze'#2#0#4'left'#3'`'#1#3'top'#3'('#2#0#0#11'TSaveDialog'#11'SaveDialog1'#10 + +'DefaultExt'#6#4'.rtf'#6'Filter'#6#27'RichText file (*.rtf)|*.rtf'#7'Options' + +#11#17'ofOverwritePrompt'#14'ofEnableSizing'#12'ofViewDetail'#0#4'left'#3#24 + +#1#3'top'#3'('#2#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt'#6#4'.rtf' + +#6'Filter'#6#27'RichText file (*.rtf)|*.rtf'#4'left'#3#208#0#3'top'#3'('#2#0 + +#0#0 ]); diff --git a/components/richmemo/samples/testsimple/unit1.pas b/components/richmemo/samples/testsimple/unit1.pas index 1fb8513b9..c34fdcf3f 100644 --- a/components/richmemo/samples/testsimple/unit1.pas +++ b/components/richmemo/samples/testsimple/unit1.pas @@ -36,7 +36,7 @@ type public { public declarations } end; - + var Form1: TForm1; @@ -83,7 +83,7 @@ begin if OpenDialog1.Execute then begin fs := nil; try - fs := TFileStream.Create(OpenDialog1.FileName, fmCreate); + fs := TFileStream.Create( Utf8ToAnsi(OpenDialog1.FileName), fmCreate); RichMemo1.SaveRichText(fs); except end; @@ -98,7 +98,8 @@ begin if OpenDialog1.Execute then begin fs := nil; try - fs := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone); + // Utf8ToAnsi is required for windows + fs := TFileStream.Create(Utf8ToAnsi(OpenDialog1.FileName), fmOpenRead or fmShareDenyNone); RichMemo1.LoadRichText(fs); except end; diff --git a/components/richmemo/win32/win32richmemo.pas b/components/richmemo/win32/win32richmemo.pas index e2c6394a6..1f902270b 100644 --- a/components/richmemo/win32/win32richmemo.pas +++ b/components/richmemo/win32/win32richmemo.pas @@ -30,6 +30,8 @@ type const Params: TIntFontParams); override; class procedure SetHideSelection(const AWinControl: TWinControl; AHideSelection: Boolean); override; class function GetStyleRange(const AWinControl: TWinControl; TextStart: Integer; var RangeStart, RangeLen: Integer): Boolean; override; + class function LoadRichText(const AWinControl: TWinControl; Source: TStream): Boolean; override; + class function SaveRichText(const AWinControl: TWinControl; Dst: TStream): Boolean; override; end; implementation @@ -179,6 +181,26 @@ class function TWin32WSCustomRichMemo.GetStyleRange( begin Result:=inherited GetStyleRange(AWinControl, TextStart, RangeStart, RangeLen); end; + +class function TWin32WSCustomRichMemo.LoadRichText( + const AWinControl: TWinControl; Source: TStream): Boolean; +begin + Result := false; + if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin + writeln('failed!'); + Exit; + end; + writeln('loading rich edit text'); + Result := RichEditManager.LoadRichText(AWinControl.Handle, Source); +end; + +class function TWin32WSCustomRichMemo.SaveRichText( + const AWinControl: TWinControl; Dst: TStream): Boolean; +begin + Result := false; + if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit; + Result := RichEditManager.SaveRichText(AWinControl.Handle, Dst); +end; end. diff --git a/components/richmemo/win32/win32richmemoproc.pas b/components/richmemo/win32/win32richmemoproc.pas index 1fd73ce82..4009d73b5 100644 --- a/components/richmemo/win32/win32richmemoproc.pas +++ b/components/richmemo/win32/win32richmemoproc.pas @@ -27,6 +27,9 @@ type class procedure GetSelection(RichEditWnd: Handle; var TextStart, TextLen: Integer); virtual; class procedure SetSelection(RichEditWnd: Handle; TextStart, TextLen: Integer); virtual; class procedure SetHideSelection(RichEditWnd: Handle; AValue: Boolean); virtual; + class function LoadRichText(RichEditWnd: Handle; ASrc: TStream): Boolean; virtual; + class function SaveRichText(RichEditWnd: Handle; ADst: TStream): Boolean; virtual; + end; TRichManagerClass = class of TRichEditManager; @@ -188,5 +191,60 @@ begin SendMessage(RichEditWnd, EM_SETOPTIONS, ECOOP_OR, ECO_NOHIDESEL); end; +type + TEditStream_ = record + dwCookie : PDWORD; + dwError : DWORD; + pfnCallback : EDITSTREAMCALLBACK; + end; + +function RTFLoadCallback(dwCookie:PDWORD; pbBuff:LPBYTE; cb:LONG; var pcb:LONG):DWORD; stdcall; +var + s : TStream; +begin + try + s := TStream(dwCookie); + pcb := s.Read(pbBuff^, cb); + Result := 0; + except + Result := 1; + end; +end; + +class function TRichEditManager.LoadRichText(RichEditWnd: Handle; ASrc: TStream): Boolean; +var + cbs : TEditStream_; +begin + cbs.dwCookie := PDWORD(ASrc); + cbs.dwError := 0; + cbs.pfnCallback := @RTFLoadCallback; + SendMessage(RichEditWnd, EM_STREAMIN, SF_RTF, LPARAM(@cbs) ); + Result := cbs.dwError = 0; +end; + +function RTFSaveCallback(dwCookie:PDWORD; pbBuff:LPBYTE; cb:LONG; var pcb:LONG):DWORD; stdcall; +var + s : TStream; +begin + try + s := TStream(dwCookie); + pcb := s.Write(pbBuff^, cb); + Result := 0; + except + Result := 1; + end; +end; + +class function TRichEditManager.SaveRichText(RichEditWnd: Handle; ADst: TStream): Boolean; +var + cbs : TEditStream_; +begin + cbs.dwCookie := PDWORD(ADst); + cbs.dwError := 0; + cbs.pfnCallback := @RTFSaveCallback; + SendMessage(RichEditWnd, EM_STREAMOUT, SF_RTF, LPARAM(@cbs) ); + Result := cbs.dwError = 0; +end; + end.