![](https://en.delphipraxis.net/uploads/set_resources_2/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
![](https://en.delphipraxis.net/uploads/monthly_2018_11/M_member_476.png)
Mahdi Safsafi
-
Content Count
383 -
Joined
-
Last visited
-
Days Won
10
Posts posted by Mahdi Safsafi
-
-
Quoteif i type the string as example abcdefgÄ the result returned True and i did not specfiy Ä in the regex pattern
You need to match EOS "$":
if Regexs.IsMatch(astr, '^[ء-ي-A-Z-a-z-0-9 ]+$') then // match fro the begining to the end of astr
-
Is that what you want ?
procedure TForm1.FormCreate(Sender: TObject); type TControlHack = type TControl; begin TControlHack(pgc1).Color := clWindow; end;
-
@Mike Torrettinni I don't know if this going to help. A while ago I wrote a regular expression to match the following pattern ""%" [index ":"] ["-"] [width] ["." prec] type" for format
%((\d+|\*)\:)?[\-]?(\d+|\*)?(\.(\d+|\*))?[duefgnmpsx]
The regex was used with Perl but I believe its still compatible with PCRE like.
-
1
-
-
QuoteMahdi - again: calm down now. This is not the first time I have to tell you to calm down.
And that's not your first time when you show un-professionalism behavior(remember last time) !
QuoteYou must stop personal attacks against other members.
I believe that I never showed disrespect for anyone here. All what I did is argumenting. So I really don't know why you think that disagree with someone is an attack !
And telling someone that he is not a judge, I think that's not an attack ... is it ?
Quoteif you feel unable to have a focused discussion on a topic, just don’t do it.
But there is a consensus that some(!) of your posts tend to be personal against other members.Go on all those posts, I challenge you to prove that its me who started a discussion !
For this post, I gave an explanation to the bug, as well as an answer, I was argumenting with some people peacefully ... until some people started provocating me!
So please don't be driven by your subjectivity and try to view things neutrally.
Peace.
-
1
-
-
QuoteI think the point is that you are violating the API contract ... blablabla....
Prove it ! FYI, the vcl core is calling CM_RECREATEWND directly.
Quoteit seems you are doing so just because you can, because you don't know better or because you are stubborn.
You're not the judge here !
QuoteThere are multiple definitions of perverse. In this case I think David meant obstinate in opposing what is right, reasonable, or accepted (from Merriam-Webster).
Don't speak on his name. He is definitely able/free to explain what he means !
David tell your friends there is no need to interfere ... I really started thinking you guys are making a kind of gang here.
-
QuoteYou said, "I'd understand if the logic was implemented in RecreateWnd but that's not the case here". You literally talk about making a choice based on the implementation details.
Yes, I make a lot of choice based on implementation details ! don't you ?
QuoteI still can't see why you are set against calling RecreateWnd.
Simply you didn't convince me (it requires more than words to convince someone) !
QuoteThat seems perverse to me.
Do you use "perverse" each time you disagree with someone ?
-
QuoteAs a broad principle, you should not be looking to work with Windows messages when consuming VCL controls. Sometimes one is forced into it because the control provides no official mechanism. But when we do that, it is brittle, and subject to future implementation detail changes.
I wish if you were right ... but things are much much more complex than that. E.g : sometimes there is an official mechanism but you choose message instead because you don't want the official mechanism to perform a paint for example ... there is a lot of those examples.
QuoteAnd there it is. There's the point where you take a dependency on on implementation details.
I didn't take any dependency (please read my example again) !
QuoteRecreateWnd is useful when creating dynamic controls as you don't know when there would be the handle available.
When you know that the handle is allocated, its just pointless to call RecreateWnd instead of CM_RECREATEWND.
procedure Main.StyleChanged; begin // I won't be here if handle is empty. // Perform(CM_RECREATEWND, ...); // VCL core is using the same Principle too ... take a look at Vcl.Forms,... (there are call to Perform(CM_RECREATEWND) instead of RecreateWnd). end;
-
1 hour ago, David Heffernan said:This doesn't make sense to me. I don't see the argument for sending a private implementation specific message rather than calling the RecreateWnd method.
We have plenty of
private implementation specific message(CM_XX) should we make XX() for each ?FYI, there is no concept of private/protected for messages. Messages are public !
I'd understand if the logic was implemented in RecreateWnd but that's not the case here !
-
2 hours ago, Remy Lebeau said:Just FYI, you should call the form's RecreateWnd() method instead of issuing the CM_RECREATEWND message manually.
For Main form that's not necessary. RecreateWnd is useful when creating dynamic controls as you don't know when there would be the handle available.
-
-
QuoteI am confused here. If I don't have to free TJSONValue why is there this line in the code you propose?
Obviously its a typos (read again Remy explanation). I believe he means :
LJSONValueObj := TJSONObject.ParseJSONValue(IdHTTP.Post(URL_LOGIN, sList)); try if LJSONValueObj is TJSONObject then begin LJSONObject := TJSONObject(LJSONValueObj); {$IFDEF VER230} LJSONPair := LJSONObject.Get('token'); if LJSONPair <> nil then LJSONValue := LJSONPair.JsonValue else LJSONValue := nil; {$ELSE} LJSONValue := LJSONObject.Values['token']; {$ENDIF} if LJSONValue <> nil then FToken := LJSONValue.Value; end; finally LJSONValueObj.Free; end;
-
The problem is that TFormStyleHook uses a cached version of Icon(See TFormStyleHook .GetIconFast ). Once the StyleHook is attached to a form it makes a cached copy of its icon. However it does not update the cache when you change the icon.
QuoteIs this function disabled while custom styles is used?
This is a bug !
Until we have a fix, you may need to recreate the window handle in order to change the icon.
main_form.Icon.LoadFromFile(ico_file); main_form.Perform(CM_RECREATEWND, 0, 0);
-
I made a quick test that uses buttons with hints and empty hints ... and it worked just fine on Delphi 10.3. Perhaps the issue is on your Delphi (can you give more details about your version, are you using vcl-style ?,...).
QuoteWhat I'd like to know is - is there a quick and easy way to go through all the properties in an application and check if there is text in all the Hint property where the ShowHint is checked, or vice versa see if there is text whenever the ShowHint is not checked? Going through every form and every component would take forever...
Something like this ?
procedure CheckEmptyHint(AComponent: TComponent); var LComponent: TComponent; LControl: TControl; begin if (AComponent is TControl) then begin LControl := TControl(AComponent); if LControl.ShowHint and (LControl.Hint = EmptyStr) then Main.Memo1.Lines.Add(Format('%s has empty hint property.', [AComponent.Name])); end; for LComponent in AComponent do CheckEmptyHint(LComponent); end; // CheckEmptyHint(Application);
-
1
-
-
@Attila Kovacs do it like this "(PWord(P + i)^ xor PWord(fc + i)^) = 0"
this is better than (P + i)^ = (fc + i)^
-
QuoteNice catch, I was comparing against the RTL code 😉
Seems to be even faster as the RTL #13#10 code.
-- command line
QuoteThat did not work out well. I'll let the case out, less implementation detail on PChar.
It should work after all its just a two-byte type.
-
I use pyscripter version.
FYI guys, pyscripter is one of the best developers that knows how to correctly maintain/extend 3rd party library.
-
2
-
-
QuoteCan you give me a test case for the incorrect handling of the trailing? This would be important to know.
Your new version rocks ! it passed all the cases, except this:
LineBreak = '--'; Text = LineBreak; LIST.COUNT= EXPECT(0) GOT(1)
QuoteIt's also faster than yours by the way, and your implementation fails on 7 test-cases of mine.
Great job 🙂
Perhaps you can use xor operator to handle LinebreakLength when its in [1,2,3,4]:
case length (linebreak) of 1: b := (PWord(P + i)^ xor PWord(fc + i)^) = 0; 2,3,4:... else for ...
-
39 minutes ago, Stefan Glienke said:What you describe is exactly what traits are in Scala. Well minus the fact that traits can even declare fields but when they always implemented by objects that would work as well - hence I would not call them anything like "so and so interface" - because while they might be similar they would be a completely different beast and not to be mixed with them.
I'm not aware about Scala but is this like what java does with default implementation for interface ?
-
1
-
-
QuoteI would suggest try to remove one conditional jump more from your last version ... is cheaper that comparing and jumping
@Kas Ob
Performance is not always related to conditional jump.
I made a quick optimization on SetTextStr, bellow is my implementation and it uses jcc heavy but outperforms original/Attila algo.
You can use jcc to make your own prediction (cheat and step):
// this algo can be optimized further // requires length(LineBreak) > 1 procedure TStringList2.SetTextStr(const Value: string); label Again; var P, PStart, PEnd: PChar; s: string; FirstLineBreakChar: Char; LastLineBreakChar: Char; LineBreakLength: integer; TextLength: integer; PMax: PChar; function IsBreak(PC: PChar): Boolean; var P: PChar; begin P := PChar(LineBreak); while (P^ <> #00) do begin if P^ <> PC^ then Exit(False); inc(P); inc(PC); end; Result := True; end; begin LineBreakLength := Length(LineBreak); if (LineBreakLength = 1) or (LineBreak = sLineBreak) then begin // this algo does not handle LineBreakLength = 1 inherited end else begin BeginUpdate(); try Clear(); FirstLineBreakChar := LineBreak[1]; LastLineBreakChar := LineBreak[LineBreakLength]; TextLength := Length(Value); P := PChar(Value); PStart := P; PEnd := P + TextLength; if P^ <> #00 then begin Again: // skip all non important char: while (P^ <> FirstLineBreakChar) and (P^ <> #00) do inc(P); PMax := P + LineBreakLength; // either null or FirstLineBreakChar. if (PMax < PEnd) then begin // current char = FirstLineBreakChar ... could be a line break ! if (P[LineBreakLength - 1] = LastLineBreakChar) then begin // there is a hight chance that its a linebreak ! if IsBreak(P) then begin // this is a linebreak. SetString(s, PStart, P - PStart); Add(s); PStart := P + LineBreakLength; end; end; inc(P, LineBreakLength); // eat all processed chars... goto Again; end else begin if (P > PStart) then begin SetString(s, PStart, P - PStart); Add(s); end else if (P = PStart) then begin // didn't move. if (PMax <> PEnd) then begin SetString(s, PStart, PEnd - PStart); Add(s); end; end; end; end; finally EndUpdate(); end; end; end;
@Attila Kovacs Note that the original implementation and yours do not handle correctly trailing.
-
@Attila Kovacs
QuoteI was struggling to write this down or not, poor dummzeuch's thread is hijacked as hell, but I can't stand, sorry.
He is really a good guy ... I'd understand if he kicked us.
QuoteIt's interesting, how tiny things can affect the speed. Originally I was starting from 320ms and it was a replacement for the RTL which was using 10's of seconds to do the same thing.
Indeed !
BTW, AChar is de-referenced twice ! try to declare a local CH that holds AChar^ "var Ch: Char := AChar^", this may improve a little bit your function.
QuoteBut I barely think that anybody could/would get used to it to write "if then else begin <actual code> end;" just because the most likely branch would be to do nothing.
You're right ! that's some how difficult to cover all your logic.
-
9 minutes ago, Dave Novo said:I wanted to modify the top record of the stack, without removing the record from the stack. Seems like with the way records work (copies all the time) that may not be possible with the current TStack implementation, given the intermediate records that are along the way. With our own structures, in situations that require it, we do take the effort to ensure there are no intermediate records and we get direct access to the address of the record we want to modify. I had not considered that the result of Peek would actually be a copy of the record at the top of the stack.
My bad, I didn't understood you correctly.
As I mentioned before, you can still use @stk.List[value] to get a pointer of your record without copying the data.
-
4 minutes ago, David Heffernan said:What value of xxx is to be used?
Hmmm that depends on him e.g : stk.count - 1 ; 0 ; 1 ....
-
3 minutes ago, David Heffernan said:"may" is rather weak. A more detailed clarification may be useful to the asker, to make it clear that the code you offered does not prevent a copy, and in fact just adds obfuscation.
However, it's also possible that there is premature optimisation going on here.
He wrote "@stk.Peek" and I understood that he wanted the address of the peeked value.
-
Regex Validate string
in VCL
Posted
For curiosity, why are you mixing arabic with latin letters. Does such ArabicLatin word make sense for you?