Recent

Author Topic: TMaskEdit and TCanvas.Brush  (Read 31974 times)

gitspielen

  • New Member
  • *
  • Posts: 19
TMaskEdit and TCanvas.Brush
« on: May 17, 2011, 06:56:49 pm »
hi

there are two environments i'm working with, one is lazarus 0.9.30 on windows 7 and the other is gtk2 ide of the same version on ubuntu 11.04 and unity.

i had finished my project on windows and then i tried to make a linux version but it doesn't work well.

the biggest problem i face with is concerning tmaskedit.
i set its property 'EditMask' to 'aaaa.aa.aa. aa\:aa;1;_', run it, type characters in the field but only the one letter i put firstly appears and i cannot do anything with the component afterward.

i entered any mask to the property for some tests such as '0000;1;_' but the results were all the same. even it crashed sometimes.

secondly i wrote some texts on timage.canvas setting its brush.color for their background colors like this:

Code: [Select]
with Image1.Canvas do
begin
  Font.Color:=clRed;
  Brush.Color:=clYellow;
  Brush.Style:=bsSolid;
  TextOut(5, 5, 'blah blah');
end;

red texts on yellow displayed on windows box as i expected but only the text color changed on linux. what's wrong with that?


apology for my poor english as a korean, and it could be some clues for the errors above because of its unique character system.
« Last Edit: May 17, 2011, 07:04:09 pm by gitspielen »

danthorpe

  • New Member
  • *
  • Posts: 15
Re: TMaskEdit and TCanvas.Brush
« Reply #1 on: May 17, 2011, 08:43:37 pm »
I´m also having some problems in the MaskEdit component, running in the Ubuntu 11.04. I wonder if it has something to do with the GTK2 version (2.4.24 if I´m not mistaken) that comes with the OS.

Anyone ?

Bart

  • Hero Member
  • *****
  • Posts: 4723
    • Bart en Mariska's Webstek
Re: TMaskEdit and TCanvas.Brush
« Reply #2 on: May 17, 2011, 10:08:36 pm »
There haven't been any significant changes with TMaskEdit since > 1 year now.

TMaskEdit should work independently form the widgetset (there are no different incudes per widgetset).
The inner workings of TMaskEdit, however, rely heavily on the proper functioning of TCustomEdit.SelStart and TCustomEdit.SelLength, and the ability to change these within TCustomEdit.TextChanged.

Recently there have been issues with that on GTK2.
My guess it, that it's a widgetset issue.

When testing the mask you mentioned in your firts post, but under windows, it works just fine (Laz 0.9.31 r29641: this includes the latest maskedit.pp (latest revision = r29200)).

Also note that TMaskEdit currently only works with lower ASCII input, it will reject all other input.

I'll test on Linux/GTK2

Bart

Bart

  • Hero Member
  • *****
  • Posts: 4723
    • Bart en Mariska's Webstek
Re: TMaskEdit and TCanvas.Brush
« Reply #3 on: May 17, 2011, 10:17:03 pm »
Just tested with Lazarus 0.9.31 r29137 on Suse 10.0 GTK2 (gtk2-2.8.3-4), this seems to work without any problems.

Bart

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #4 on: May 17, 2011, 11:46:02 pm »
thanks bart

but it seems that your gtk2 is a little bit outdated. mine is 2.24.4-0, installed today.
would you mind if i ask you to test it again under the latest version?

Bart

  • Hero Member
  • *****
  • Posts: 4723
    • Bart en Mariska's Webstek
Re: TMaskEdit and TCanvas.Brush
« Reply #5 on: May 18, 2011, 11:25:27 am »
but it seems that your gtk2 is a little bit outdated. mine is 2.24.4-0, installed today.

Yeah, my computer now is > 10 years old ...

would you mind if i ask you to test it again under the latest version?

I don't mind, but as I said TMaskEdit hasn't been changed for a long time and it used to work correctly under win32, gtk, gtk2 at least (never received any feedback from mac or darwin).

The simple fact that it does work under win32 and the way it is constructed means that, if the LCL (and TCustomEdit in particularly) behaves the same on all widgetsets, then it should must also work in GTK2.

(Take a look at maskedit.pp and see that in essence the control checks for valid input and manipulates SelStart and SelLength and the text in the control.)

The fact that is does with my old GTK2 and not with your, suggests to me that there is a fault in the widgetset implementation.

This may, or may not, be related to issue #19220 in the bugtracker.

Bart

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #6 on: May 18, 2011, 05:44:52 pm »
Great advice, Bart.

I found a very probable clue on your comment in MaskEdit.pp:

Quote
So, as a horrible hack I decided  to only allow changing of the text if we coded
 this change ourself. This is done by setting the FChangeAllowed field to True before any
 write action (in SetInherited Text() ).
 We try to intercept the messages for cut/paste/copy/clear and perform the appropriate
 actions instead.
 If this fails, then in TextChanged we check and will see that FChangeAllowed = False
 and we will undo the changes made.

Unfortunately, it seems that the way your job about FChangedAllowed works makes the problem here on the latest GTK2 Widgetset.

I made breakpoints at TCustomMaskEdit.TextChanged and Keydown procedure, put a character in the field, and noticed that SetInheritedText procedure set FChangedAllowed to False.

As far, the process above was just as you intended but the problem is following. I typed another letter anticipating Keydown event but the widget just called TextChanged and that's all!

I'm not a professional programmer nor informed of low level programming so hardly can I touch anything from now on. :-(

Thanks.
« Last Edit: May 18, 2011, 05:56:59 pm by gitspielen »

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #7 on: May 18, 2011, 05:51:28 pm »
And I'm still curious about my next question, background color of text on TImage.Canvas.

Is there anyone who can help me?
« Last Edit: May 18, 2011, 05:54:44 pm by gitspielen »

Bart

  • Hero Member
  • *****
  • Posts: 4723
    • Bart en Mariska's Webstek
Re: TMaskEdit and TCanvas.Brush
« Reply #8 on: May 18, 2011, 11:42:46 pm »
Quote from: gitspielen
I made breakpoints at TCustomMaskEdit.TextChanged and Keydown procedure, put a character in the field, and noticed that SetInheritedText procedure set FChangedAllowed to False

I'ld say you didn't get it right.

When you press a (printable) key then the follwing happens:

TCustomMaskedit.KeyPress (not KeyDown) b.t.w. calls TCustomMaskedit.InsertChar, which calls TCustomMaskedit.SetInheritedText (if TCustomMaskedit.CanInsertChar returns true).
TCustomMaskedit.SetInheritedText then first sets the flag FChangeAllowed to true, then sets the text in the control.
This then triggers the TextChanged event to be called, which checks wether FChangeAllowed = True (which it is), and allows the change.
After this we return to TCustomMaskedit.SetInheritedtext, and at this point we set FChangeAllowed to False.

This should be completely independant of the widgetset.

I just tested my MaskEdit program (Lazarus 0.9.31 r29137) using Ububtu 11.02 (GTK2 2.20), and it works like a charm.

What you can do is open maskedit.pp and replace TCustomMaskEdit.InsertChar with the following code

Code: [Select]
procedure TCustomMaskEdit.InsertChar(Ch : Char);
Var
  S    : ShortString;
  i, SelectionStart, SelectionStop: Integer;
begin
  if CanInsertChar(FCursorPos + 1, Ch) then
  begin
    S := Inherited Text;
    debugln('TCustomMaskEdit.InsertChar: Ch = ',Ch,' CanInsertChar = True');
    if HasSelection then
    begin
      //replace slection with blank chars
      //don't do this via DeleteChars(True), since it will do an unneccesary
      //update of the control and 2 TextChanged's are triggerd for every char we enter
      GetSel(SelectionStart, SelectionStop);
      for i := SelectionStart + 1 to SelectionStop do S[i] := ClearChar(i);
    end;
    S[FCursorPos + 1] := Ch;
    debugln('TCustomMaskedit.InsertChar: calling SeInheritedText(',S,')');
    SetInheritedText(S);
    SelectNextChar;
  end
  else
  begin
    debugln('TCustomMaskedit.InsertChar: CanInsertChar = False');
    //If we have a selection > 1 (and cannot insert) then Delete the selected text: Delphi compatibility
    if HasExtSelection then DeleteSelected;
  end;
end;

Then rebuild the LCL (clean), build the program and then start it from a console.
Use 'ccccccccccc;1;_' as the EditMask (this should allow you to type any (lower ASCII) char in the control).

Select the control and try to type in it and report the debug output on the console.

(Please also make sure that you did not accidentally set ReadOnly to True for the MaskEdit component...)

Bart

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #9 on: May 19, 2011, 12:20:24 am »
It is quite interesting I could know the fact by chance to build LCL that the control works well with root permission!

This is debug output:

Code: [Select]
user@ubuntu:~/jmds$ ./jmds
TCustomMaskEdit.InsertChar: Ch = 1 CanInsertChar = True
TCustomMaskedit.InsertChar: calling SeInheritedText(1011.05.19. 07:10)

/// I kept trying to put other numbers but failed.

user@ubuntu:~/jmds$ sudo ./jmds
TCustomMaskEdit.InsertChar: Ch = 1 CanInsertChar = True
TCustomMaskedit.InsertChar: calling SeInheritedText(1011.05.19. 07:10)
TCustomMaskEdit.InsertChar: Ch = 2 CanInsertChar = True
TCustomMaskedit.InsertChar: calling SeInheritedText(1211.05.19. 07:10)
TCustomMaskEdit.InsertChar: Ch = 3 CanInsertChar = True
TCustomMaskedit.InsertChar: calling SeInheritedText(1231.05.19. 07:10)
TCustomMaskEdit.InsertChar: Ch = 4 CanInsertChar = True
TCustomMaskedit.InsertChar: calling SeInheritedText(1234.05.19. 07:10)

/// It works!
user@ubuntu:~/jmds$

What's the difference?
« Last Edit: May 19, 2011, 12:22:04 am by gitspielen »

Bart

  • Hero Member
  • *****
  • Posts: 4723
    • Bart en Mariska's Webstek
Re: TMaskEdit and TCanvas.Brush
« Reply #10 on: May 19, 2011, 10:02:19 am »
It (the working of TMaskEdit) should make no difference whatsoever wether you are root or not.

Bart

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #11 on: May 19, 2011, 10:32:41 am »
It (the working of TMaskEdit) should make no difference whatsoever wether you are root or not.

Yes, truly. Maybe the bug is related to widgetset implementation or peculiar reaction of the system though almost I didn't make personalization.  %)

Thanks anyhow.

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #12 on: May 19, 2011, 10:41:17 am »
I made breakpoints at TCustomMaskEdit.TextChanged and Keydown procedure, put a character in the field, and noticed that SetInheritedText procedure set FChangedAllowed to False.

As far, the process above was just as you intended but the problem is following. I typed another letter anticipating Keydown event but the widget just called TextChanged and that's all!

What do you think of my suggestion? I also made a breakpoint at KeyPress procedure at that time and found without root permission, the debugger just passed it too :(

Quote
I'ld say you didn't get it right.

When you press a (printable) key then the follwing happens:

TCustomMaskedit.KeyPress (not KeyDown) b.t.w. calls TCustomMaskedit.InsertChar, which calls TCustomMaskedit.SetInheritedText (if TCustomMaskedit.CanInsertChar returns true).
TCustomMaskedit.SetInheritedText then first sets the flag FChangeAllowed to true, then sets the text in the control.
This then triggers the TextChanged event to be called, which checks wether FChangeAllowed = True (which it is), and allows the change.
After this we return to TCustomMaskedit.SetInheritedtext, and at this point we set FChangeAllowed to False.

This should be completely independant of the widgetset.

Ah, I've already noticed the process by trace. I just said it simply in terms of the result.


Here is my another example with a new form:
Code: [Select]

// I allocated a new event to MaskEdit1

procedure TForm1.MaskEdit1KeyPress(Sender: TObject; var Key: char);
begin
  Edit1.Text:=Edit1.Text + Key;
end;

The text of Edit1 changes only one time.


Too much mysterious!
« Last Edit: May 19, 2011, 11:34:09 am by gitspielen »

Bart

  • Hero Member
  • *****
  • Posts: 4723
    • Bart en Mariska's Webstek
Re: TMaskEdit and TCanvas.Brush
« Reply #13 on: May 19, 2011, 11:49:46 am »
In TMaskEdit.KeyPress (in maskedit.pp) place as the frits line (after begin)

Code: [Select]
  DebugLn('TCustomMaskdit.KeyPress: Key = ',Key);

In ObjectInspector set EditMask to 'cccccccc;1;_'
Also set Text to '' (empty)

Rebuild LCL clean, rebuild app, run from console (as normal user).

Set focus to Maskedit, then type '12345' and show me the debugoutput (only the debug output from within KeyPress please).


If this also fails then install a snapshot or install trunk version using svn (see the wiki).
If the problem remains, then file a bugreport in Mantis (see link in menu on the left here).

Bart

gitspielen

  • New Member
  • *
  • Posts: 19
Re: TMaskEdit and TCanvas.Brush
« Reply #14 on: May 20, 2011, 02:40:29 am »
OK.

Set focus to Maskedit, then type '12345' and show me the debugoutput (only the debug output from within KeyPress please).

Result:
Code: [Select]
user@ubuntu:~/test$ ./project1
TCustomMaskdit.KeyPress: Key = 1
user@ubuntu:~/test$
Failed.


If this also fails then install a snapshot or install trunk version using svn (see the wiki).

Code: [Select]
user@ubuntu:/media/home/src/lazarus$ ~/maskedit/project1
TCustomMaskdit.KeyPress: Key = 1
user@ubuntu:/media/home/src/lazarus$
Failed again.

If the problem remains, then file a bugreport in Mantis (see link in menu on the left here).

I'll try.
By the way, I really appreciate your concern over my thread.

 

TinyPortal © 2005-2018