in reply to coloring text in RichEdit takes long time
Few comments. You need to use \b boundary condition to avoid higlighting say the "be" in because.
The problem per se is that ReplaceSel is very slow and you hit it a lot.
You can do the RTF formatting task very simply if you understand the format. Here is a sub that will highlight all the matches in a given text string and output RTF format data. It will only process TXT data, not existing RTF.
# RGB format a text document using a highlight colour. # RGB 0-255 like HTML 0x00-0xFF # Output should be valid RTF but YMMV sub RTFhighlight { my ($text, $highlight, $r, $g, $b, $font) = @_; $font ||= "Arial"; $text =~ s/([\\{}])/\\$1/g; # escape \ and { } $text =~ s/\n/\\par\n/g; # convert \n to \par $text =~ s/\b\Q$highlight\E\b/\\cf1 $highlight\\cf0 /g; my $header = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fon +ttbl{\\f0\\fswiss\\fcharset0 $font;}}\n"; $header .= "{\\colortbl ;\\red$r\\green$g\\blue$b;}\n"; return $header.$text; } print RTFhighlight("hello be seabe be because", "be", 0, 0, 0xFF);
To use it in your code just read in all the text in a single pass, highlight it, and set it. This is still a bit slow because of the ReplaceSel issue. You can get it to display chunks of the file by iterating over chunks of your file but the price is lots more calls to ReplaceSel so although you get the satisfaction of some output straight away it takes a lot longer to finish. This takes about 6 seconds to do 20,000 highlights in a 250k file on my el cheapo laptop. Creating the highlight text takes a few milliseconds, all the rest of the time we are waiting for ReplaceSel.
One final note. You should delay showing the window until you have finished adding widgets. That way it will render properly when it appears ie move Win->Show.
use Win32::GUI; use warnings; use strict; my $Win = new Win32::GUI::Window( -left => 3, -top => 5, -width => 640, -height => 480, -name => "Win", ); my $font = Win32::GUI::Font->new( -name => "Courier New", -size => 12, ); $Win->AddButton( -text => "Run", -name => "Button1", -left => 23, -top => 10, -width => 56, -height => 36, -foreground => 0, ); my $RichText = $Win->AddRichEdit( -text => "Click Run.....\n", -name => "RichText_Output", # OutPut Rich Text -left => 41, -top => 91, -width => 580, -height => 313, -multiline => 1, -vscroll => 1, ); $RichText->SetLimitText(4194304); $Win->Show(); Win32::GUI::Dialog(); sub Win_Terminate { return -1; } sub Button1_Click { my $file = "bigfile.txt"; my $PATTERN = "be"; $RichText->Select(0,-1); $RichText->ReplaceSel("Loading and highlighting.....\n"); $Win->Update; open FILE, $file or die "Can't open $file because $!\n"; local $/; my $text = <FILE>; close FILE; $text = RTFhighlight($text, $PATTERN, 0xFF, 0, 0, "Courier New" ); $RichText->Select(0,-1); $RichText->ReplaceSel($text); } # rft format a document using a highlight colour. RGB 0-255 like HTML. sub RTFhighlight { my ($text, $highlight, $r, $g, $b, $font) = @_; $font ||= "Arial"; $text =~ s/([\\{}])/\\$1/g; # escape \ and { } $text =~ s/\n/\\par\n/g; # convert \n to \par $text =~ s/\b\Q$highlight\E\b/\\cf1 $highlight\\cf0 /g; my $header = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fon +ttbl{\\f0\\fswiss\\fcharset0 $font;}}\n"; $header .= "{\\colortbl ;\\red$r\\green$g\\blue$b;}\n"; return $header.$text; }
|
|---|