[bmx] Search Text in files by Bobysait [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:40

Previous topic - Next topic

BlitzBot

Title : Search Text in files
Author : Bobysait
Posted : 1+ years ago

Description : Create a window with some gadgets :
- a textfield for the directory and a button to "requestDir"
- a textfield for text to search
- a textfieldK (you'll find the code source in the code archive - miscellaneous) to set the recursivity
- a button to launch the search

result happens in a textarea
(it could be replaced with a listbox which would be better)

source of the mdt.uisdk is below this post
-> copy/paste the code and save it to "uisdk.bmx" then put it in your mod folder with this path
$blitzmax_path/mod/mdt.mod/uisdk.mod/

($blitzmax_path is your blitzmax path ... obvious enough)


Code :
Code (blitzmax) Select
Framework maxgui.drivers
Import mdt.uisdk

Global _window:TGadget = CreateWindow("search", 10,10,800,600,,WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CLIENTCOORDS | WINDOW_CENTER | WINDOW_STATUS );
Local txtDir:TGadget = CreateTextField(5,5,ClientWidth(_window)-10-40, 20, _window )
txtDir.SetLayout(EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, 0);
Local BtnDir:TGadget = CreateButton("...", 5+ClientWidth(_window)-10-40, 5, 40, 20, _window);
btnDir.SetLayout(0, EDGE_ALIGNED, EDGE_ALIGNED, 0);
Local txtSearch:TGadget = CreateTextField(5,30,ClientWidth(_window)-10-40-80, 20, _window )
txtSearch.SetLayout(EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, 0);
Local sldLevel:TGadget = CreateTextFieldK( 5+ClientWidth(_window)-10-40-80, 30, 70, 20, _window, TEXTFIELDK_INT | TEXTFIELDK_CLAMP )
sldLevel.SetLayout(0, EDGE_ALIGNED, EDGE_ALIGNED, 0);
TTextFieldK(sldLevel).setClamp(-1,100, 1);
sldLevel.SetValue(-1);
Local btnSearch:TGadget = CreateButton("GO !", 5+ClientWidth(_window)-10-40, 30, 40, 20, _window);
btnSearch.SetLayout(0, EDGE_ALIGNED, EDGE_ALIGNED, 0);

Global txtOut:TGadget = CreateTextArea(5, 55, ClientWidth(_window), ClientHeight(_window)-60, _window );
txtOut.SetLayout (EDGE_ALIGNED,EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED);

Global _g_CurDir:String;

Repeat
WaitEvent()
Select EventID()
Case EVENT_APPTERMINATE
End
Case EVENT_WINDOWCLOSE
End
Case EVENT_GADGETACTION
Select EventSource()
Case BtnDir
Local dir:String = RequestDir("directory to search", CurrentDir())
If FileType(dir)=2
ChangeDir(dir)
txtDir.SetText(dir);
EndIf;
Case btnSearch
txtOut.SetText("");
_g_CurDir = txtDir.GetText()
SearchTxt(_g_CurDir, txtSearch.GetText(), TTextFieldK(sldLevel).GetValueI())
SetStatusText(_window, "done");
End Select
End Select
Until AppTerminate()
End;

Function SearchTxt(d:String, keywords:String, pRecursive:Int=20)

d = d.Replace("","/");
If Right(d,1) = "/" Then d = Left(d,d.length-1);

Local dir:Int = ReadDir(d)
If Not(dir) Then Return;

d :+ "/"
SetStatusText(_window, "DIR : '"+RSet(d,30)+"'")
Repeat

Local f:String = NextFile(dir)
Select f
Case "" ; Exit;
Case ".",".."
Default
Select FileType(d+f)
Case 1
searchTxtFile(d+f, keywords)
Case 2
If pRecursive<>0 Then SearchTxt(d+f, keywords, pRecursive-1)
End Select
End Select

Forever

CloseDir(dir)

End Function


Function searchTxtFile(url:String, keywords:String)

Local bank:TBank = LoadBank(url)
If bank=Null Then Return;

Local kw:Byte ptr = keywords.ToCString();
Local kl:Int = keywords.length;

Local offset:Int = 0
Local Size:Int = bank.Size();
Local Buf:Byte ptr = bank.Buf();

For offset = 0 Until Size-kl

Local found:Byte = True;
For Local a:Int = 0 Until kl
If Buf[offset+a] <> kw[a] Then found = False; Exit;
Next
If found Then AddTextAreaText(txtOut, "* url="+Right(url,url.length-_g_CurDir.length).Replace("/","")+"' pos='"+offset+"'"+Chr(13)+Chr(10) );
Next;

bank.Resize(0);
bank = Null

Delay 10;

End Function


Comments :


Bobysait(Posted 1+ years ago)

 here is the TextFieldK class and sdk
SuperStrict

module mdt.uisdk

Import maxgui.drivers


'#region TextField K
Const TEXTFIELDK_INT:Int = 512;
Const TEXTFIELDK_CLAMP:Int = 1024;
Const TEXTFIELDK_EXPONENT:Int = 2048;

Type TTextFieldK Extends TProxyGadget

Global _textFieldK_symbol_pixmap:TPixmap;

Global _arrows_width:Int = 15;
Global _arrows_height:Int = 19;

Field core:TGadget;
Field exponent:TGadget;
Field textField:TGadget;
Field arrows:TGadget;
Field btUp:TGadget;
Field btDn:TGadget;

Field _style:Int;
Field _autoExponentialIncrement:Byte = False;
Field _autoExponentialIncrementValue:Float=0.1;
Field _increment:Float;
Field _value:Float;
Field _valueI:Int;
Field _valueMin:Float;
Field _valueMax:Float;
Field _nbDigits:Int;

Function InTriangle2:Byte ( x0:Float,y0:Float, x1:Float,y1:Float, x2:Float,y2:Float, x3:Float,y3:Float )
If ( (x2-x1) * (y3-y1) - (x3-x1) * (y2-y1) > 0 )
If ( ( (x2-x0) * (y3-y0) - (x3-x0) * (y2-y0) ) < 0) Then Return False;
If ( ( (x3-x0) * (y1-y0) - (x1-x0) * (y3-y0) ) < 0) Then Return False;
Return ( ( (x1-x0) * (y2-y0) - (x2-x0) * (y1-y0) ) >= 0)
EndIf;
If ( ( ((x2-x0) * (y3-y0) - (x3-x0) * (y2-y0)) ) > 0) Then Return False;
If ( ( ((x3-x0) * (y1-y0) - (x1-x0) * (y3-y0)) ) > 0) Then Return False;
Return ( ( ((x1-x0) * (y2-y0) - (x2-x0) * (y1-y0)) ) <= 0)
End Function

Function WritePixmapTriangle(pix:TPixmap, x0:Int,y0:Int,x1:Int,y1:Int,x2:Int,y2:Int, rgba:Int)
Local l_w:Int = pix.width;
Local l_h:Int = pix.Height;
Local l_x:Int, l_y:Int
For l_y = 0 Until l_h
For l_x = 0 Until l_w
If InTriangle2(l_x,l_y, x0,y0,x1,y1,x2,y2)
pix.WritePixel(l_x,l_y, rgba);
End If
Next;
Next;
End Function

Method Init:TTextFieldK(pX:Int,pY:Int,pW:Int,pH:Int,pGroup:TGadget,pStyle:Int=0)

If _textFieldK_symbol_pixmap = Null

Local pix_w:Int = _arrows_width;
Local pix_h:Int = _arrows_height;

Local pix:TPixmap= CreatePixmap(pix_w,pix_h, PF_RGB888)
pix.ClearPixels($FF707070);

Local l_x0:Int = Floor(pix_w*0.5);
Local l_x1:Int = 2;
Local l_x2:Int = pix_w-3;

Local l_ym:Int = Floor(pix_h*0.5);
Local l_y0:Int = 2;
Local l_y1:Int = l_ym-2;
Local l_y2:Int = l_ym+2;
Local l_y3:Int = pix_h-3;

Local pix_i:Int
For pix_i = 0 Until pix_w
pix.WritePixel(pix_i,0,$FF010101);
pix.WritePixel(pix_i,pix_h-1,$FF010101);
pix.WritePixel(pix_i,l_ym   ,$FF010101);
Next;

WritePixmapTriangle(pix, l_x0, l_y0 , l_x1, l_y1 , l_x2, l_y1 ,$FF010101);
WritePixmapTriangle(pix, l_x1, l_y2 , l_x2, l_y2 , l_x0, l_y3 ,$FF010101);
For pix_i = 1 Until pix_h-1
pix.WritePixel(0,pix_i,$FF010101);
pix.WritePixel(pix_w-1,pix_i,$FF010101);
Next;
_textFieldK_symbol_pixmap = pix;
EndIf;

Self._value = 0.0;
Self._increment = 1.0;
Self._autoExponentialIncrement = False;
Self._autoExponentialIncrementValue = 0.1;
Self._nbDigits = 12;

pH = max(pH,_arrows_height);
Self.core = CreatePanel ( pX,pY,pW, pH, pGroup, 0);
Self._style = pStyle;

Self.exponent= CreateButton ( "", 2,2, 12, 16, Self.core, BUTTON_CHECKBOX );
Self.exponent.SetLayout(EDGE_ALIGNED,0,EDGE_ALIGNED,0);
If ( (pStyle & TEXTFIELDK_EXPONENT) > 0 )
Self.textField= CreateTextField ( 16,0,pW-_arrows_width-1-16,pH, Self.core, pStyle);
Else
HideGadget(Self.exponent);
Self.textField= CreateTextField ( 0,0,pW-_arrows_width-1,pH, Self.core, pStyle);
EndIf;

Self.textField .SetLayout ( EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED );
Self.arrows = CreatePanel ( pW-_arrows_width, 0, _arrows_width,_arrows_height, Self.core, PANEL_ACTIVE );

Self.arrows .SetLayout ( 0, EDGE_ALIGNED, EDGE_ALIGNED, 0 );
Self.arrows .SetPixmap ( _textFieldK_symbol_pixmap, PANELPIXMAP_CENTER );
Self.arrows .SetSensitivity ( SENSITIZE_ALL );
Self.textField .SetSensitivity ( SENSITIZE_ALL );

SetGadgetFilter ( Self.textField , TTextFieldK.filterNum, Self );

AddHook ( EmitEventHook, hook, Self );

Self.enableExpIncrement(Self._autoExponentialIncrement);

Self.SetProxy ( Self.core );

Return Self;
End Method

Method enableClamp:TTextFieldK(pEnable:Byte=True)
If pEnable
Self._style = Self._style | TEXTFIELDK_CLAMP;
Else
If ( (Self._style & TEXTFIELDK_CLAMP) > 0 )
Self._style = Self._style - TEXTFIELDK_CLAMP;
EndIf;
EndIf;
Return Self;
End Method

Method setClamp:TTextFieldK(pMinValue:Float, pMaxValue:Float, pEnableClamp:Int=-1)
Self._valueMin = min(pMinValue, pMaxValue);
Self._valueMax = max(pMinValue, pMaxValue);
If (pEnableClamp=1)
Self.enableClamp(True);
ElseIf (pEnableClamp=0)
Self.enableClamp(False);
EndIf;
Return Self;
End Method

Method enableExpIncrement:TTextFieldK(pEnable:Byte=True)
Self._autoExponentialIncrement = pEnable;
If (Self.exponent<>Null) Then SetButtonState(Self.exponent, pEnable);
Return Self;
End Method

Method setExpIncrement:TTextFieldK(pIncrement:Float)
Self._autoExponentialIncrementValue = pIncrement;
Return Self;
End Method

Function setTextFormatFloat:String(f:Float, pDigits:Int)
Local l_sgn:String="" ; If (f<0) Then  l_sgn="-"; f = Abs(f);
Local v:String = String.FromFloat(f);
Local locate:Int = Instr(v, "e",1);
If locate
Local locateDot:Int = Instr(v,".")
Local pow:Int = Right(v, v.length-locate).ToInt()
Local num:String;
If locateDot
num = Left(v,locateDot-1)
num :+ Mid(v, locateDot+1, locate-locateDot-1);
Else
num = Left(v,locate-1)
EndIf;
Local val:String = "0."+RSet( num, Abs(pow)+num.length-1 ).Replace(" ","0");
v = l_sgn+val;
Else
v = l_sgn+v;
EndIf
If v.length>pDigits
Local v2:String = Left(v,pDigits); If Abs(v2.ToFloat()-v.ToFloat())<0.1 Then Return v2;
EndIf;
Return v;
End Function

Method setDigits:TTextFieldK(pDigits:Int)
Self._nbDigits = pDigits;
Self.SetValue(Self._value);
Return Self;
End Method

Method getDigits:Int()
Return Self._nbDigits;
End Method

Method Increment:TTextFieldK(pValue:Int)

If ( pValue = 0 ) Then Return Self;

Self._checkNumString();

If ( (Self._style & TEXTFIELDK_INT) > 0 )

Local inc:Int = max(Self._increment,1);
pValue :* inc;

If Self._autoExponentialIncrement

If Self._valueI = 0

Self.SetValueI( pValue );

Else

If ( pValue>0 )

' increment Up -> increment |Self._valueI|
If ( Self._valueI > 10 )
Self.SetValueI( Self._valueI * (1 + Self._autoExponentialIncrementValue * pValue) );
ElseIf ( Self._valueI>-10 )
Self.SetValueI( Self._valueI + pValue );
Else
Self.SetValueI( Self._valueI / (1 + Self._autoExponentialIncrementValue * pValue) );
EndIf;

Else
' increment Down -> Decrement |self._valueI|
If ( Self._valueI > 10 )
Self.SetValueI( Self._valueI / (1 + Self._autoExponentialIncrementValue * Abs(pValue)) );
ElseIf ( Self._valueI>-10 )
Self.SetValueI( Self._valueI + pValue );
Else
Self.SetValueI( Self._valueI * (1 + Self._autoExponentialIncrementValue * Abs(pValue)) );
EndIf;

EndIf;

EndIf;
Else

Self.SetValueI( Self._valueI + pValue );

EndIf;

Else

If Self._autoExponentialIncrement
If pValue>0
Self.SetValue(Self._value * (1 + (Self._autoExponentialIncrementValue * pValue)) );
Else
Self.SetValue(Self._value / (1 + (Self._autoExponentialIncrementValue * Abs(pValue) )) );
EndIf;
Else
Self.SetValue(Self._value + pValue);
EndIf;

EndIf;

Return Self;

End Method

Method SetValueI:TTextFieldK(pValue:Int)

If ( (Self._style & TEXTFIELDK_CLAMP) > 0 )
If ( (Self._style & TEXTFIELDK_INT) > 0 )
pValue = min(max(pValue, Self._valueMin),Self._valueMax);
Else
pValue = min(max(pValue, Self._valueMin),Self._valueMax);
EndIf;
EndIf

Self._checkNumString();

If ( (Self._style & TEXTFIELDK_INT) > 0 )
Self._valueI = pValue;
Self.textField.SetText(Self._valueI);
Else
Self._value = pValue;
'If Self._autoExponentialIncrement Then Self._increment = Abs(Self._value)*Self._autoExponentialIncrementValue;
Self.textField.SetText(setTextFormatFloat(Self._value,Self._nbDigits));
EndIf;

Self._checkNumString();

Return Self;

End Method

Method SetValue (pValue:Float)

If ( (Self._style & TEXTFIELDK_CLAMP) > 0 )
If ( (Self._style & TEXTFIELDK_INT) > 0 )
pValue = min(max(pValue, Self._valueMin),Self._valueMax);
Else
pValue = min(max(pValue, Self._valueMin),Self._valueMax);
EndIf;
EndIf

Self._checkNumString();

If ( (Self._style & TEXTFIELDK_INT) > 0 )
Self._valueI = pValue;
Self.textField.SetText(Self._valueI);
Else
Self._value = pValue;
'If Self._autoExponentialIncrement Then Self._increment = Abs(Self._value)*Self._autoExponentialIncrementValue;
Self.textField.SetText(setTextFormatFloat(Self._value,Self._nbDigits));
EndIf;

Self._checkNumString();

End Method

Method _readValue()
If ( (Self._style & TEXTFIELDK_INT) > 0 )
Self._valueI = Self.textField.GetText().ToInt();
If ( (Self._style & TEXTFIELDK_CLAMP) > 0 )
Local l_valI:Int = Self._valueI;
Self._valueI = min(max(l_valI, Self._valueMin),Self._valueMax);
If l_valI<>Self._valueI Then Self.textField.SetText(String.FromInt(Self._valueI));
EndIf;
Else
Self._value = Self.textField.GetText().ToFloat();
If ( (Self._style & TEXTFIELDK_CLAMP) > 0 )
Local l_valF:Float = Self._value;
Self._value = min(max(l_valF, Self._valueMin),Self._valueMax);
If Abs(l_valF-Self._value)>0.0001 Then Self.textField.SetText(String.FromFloat(Self._value)); Self._checkNumString()
EndIf;
EndIf
End Method

Method GetValue:Float()
If ( (Self._style & TEXTFIELDK_INT) > 0 )
Return Self._valueI;
Else
Return Self._value;
EndIf;
End Method

Method GetValueI:Int()
If ( (Self._style & TEXTFIELDK_INT) > 0 )
Return Self._valueI;
Else
Return Self._value;
EndIf;
End Method

Method SetLayout( lft:Int, rht:Int, top:Int, bot:Int )
Self.core.SetLayout(lft,rht,top,bot);
End Method

Method _checkNumString()
Local l_s:String = Self.textField.GetText();
Local l_Len:Int = l_s.length;
Local c:Int;
Local out:String="";
Local countDots:Int = 0; If ( (Self._style & TEXTFIELDK_INT) > 0 ) Then countDots=1;
For c = 0 Until l_Len
Select l_s[c]
Case "-"[0],"+"[0]
If c=0
out :+ Chr(l_s[c]);
EndIf;
Case "."[0]
If countDots=0
out :+ Chr(l_s[c]);
countDots :+ 1;
EndIf;
Case "0"[0],"1"[0],"2"[0],"3"[0],"4"[0],"5"[0],"6"[0],"7"[0],"8"[0],"9"[0]
out :+ Chr(l_s[c]);
Default
End Select
Next;

If out<>l_s Then Self.textField.SetText(out);

Self._readValue();

End Method

Method postEv(pX:Int, pY:Int)
Self._readValue();
If ( (Self._style & TEXTFIELDK_INT) > 0 )
EmitEvent ( CreateEvent ( EVENT_GADGETACTION, Self, KEY_ENTER,0, pX,pY, String.FromInt(Self._value) ) );
Else
EmitEvent ( CreateEvent ( EVENT_GADGETACTION, Self, KEY_ENTER,0, pX,pY, String.FromFloat(Self._value) ) );
EndIf
End Method

Method GetText:String()
Return String.FromFloat(Self.GetValue());
End Method

Method SetText(text:String)
Self.SetValue(text.ToFloat());
End Method

Global last_ev_y:Int=0;
Function hook:Object (id:Int,data:Object,context:Object)

Local ev:TEvent = TEvent(data);
If ev = Null Then Return data;

Local tf:TTextFieldK = TTextFieldK(context);
If (tf<>Null)

If ev.id=EVENT_MOUSEENTER
Select ev.source
Case tf.arrows
Select ActiveGadget()
Case tf.textfield, tf.exponent
ActivateGadget(tf.arrows)
Return Null;
End Select
Case tf.textfield
Select ActiveGadget()
Case tf.arrows, tf.exponent
ActivateGadget(tf.textfield)
Return Null;
End Select
End Select
Return data;
EndIf;

Select ev.source

Case tf.arrows

Select ev.id

Case EVENT_MOUSEDOWN
If ev.data=1
tf.Increment( 1 - 2 * (ev.y>_arrows_height/2) );
tf.postEv(ev.x,ev.y);
EndIf;

Case EVENT_MOUSEWHEEL
tf.Increment( ev.data );
tf.postEv(ev.x,ev.y);

Case EVENT_KEYDOWN
Select ev.data
Case KEY_UP ; tf.Increment( +1 ); tf.postEv(ev.x,ev.y);
Case KEY_DOWN ; tf.Increment( -1 ); tf.postEv(ev.x,ev.y);
Case KEY_PAGEUP ; tf.Increment( +5 ); tf.postEv(ev.x,ev.y);
Case KEY_PAGEDOWN;tf.Increment( -5 ); tf.postEv(ev.x,ev.y);
End Select
End Select

Return Null;

Case tf.exponent
If ev.id=EVENT_GADGETACTION
tf.enableExpIncrement(ButtonState(tf.exponent));
EndIf;
Return Null;

Case tf.textField

Select ev.id

Case EVENT_KEYCHAR
Select ev.data
Case KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,"."[0], KEY_BACKSPACE
Return data;
Default
Return Null;
End Select;

Case EVENT_GADGETLOSTFOCUS

tf._checkNumString();
tf.postEv(ev.x,ev.y);

Case EVENT_GADGETACTION

tf._checkNumString();

End Select;

Return Null;

End Select;

EndIf;

Return data;

End Function

Function filterNum:Int(event:TEvent, context:Object)

Local tf:TTextFieldK = TTextFieldK(context); If (tf = Null) Then Return 1;
If (event.source <> tf.textField) Then Return 1;

Select event.id

Case EVENT_KEYCHAR

If (tf.Style  & TEXTFIELDK_INT)
Select event.data
Case "-"[0], "+"[0], KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9, KEY_BACKSPACE
' tf._checkNumString();
Return 1;
End Select
Else
Select event.data
Case "-"[0], "+"[0], KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,"."[0], KEY_BACKSPACE
' tf._checkNumString();
Return 1;
End Select
EndIf

Return 0;

Case EVENT_KEYDOWN

Select event.data
Case KEY_UP ; tf.Increment( +1 ); Return 0;
Case KEY_DOWN ; tf.Increment( -1 ); Return 0;
Case KEY_PAGEUP ; tf.Increment( +5 ); Return 0;
Case KEY_PAGEDOWN;tf.Increment( -5 ); Return 0;
End Select;
Return 1;

Case EVENT_GADGETACTION

tf._checkNumString();
Return 1;

Case EVENT_GADGETLOSTFOCUS

tf._checkNumString();
Return 1;

End Select

Return 1;

End Function

End Type

Function CreateTextFieldK:TTextFieldK(pX:Int,pY:Int,pW:Int,pH:Int,pGroup:TGadget=Null,pStyle:Int=0)
Return New TTextFieldK.Init(pX,pY,pW,pH,pGroup,pStyle);
End Function
'#end region



Function TextFieldK_Demo()

Local Win:TGadget = CreateWindow("window", 10,10,400,200,, WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CLIENTCOORDS | WINDOW_CENTER );
Local backpan:TGadget = CreatePanel(0,0,ClientWidth(Win), ClientHeight(Win), Win);
backpan.SetLayout(EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED );
backpan.SetColor($10,$10,$10);

Local txt1:TTextFieldK=CreateTextFieldK(10,10,100,20, backpan, TEXTFIELDK_EXPONENT | TEXTFIELDK_INT | TEXTFIELDK_CLAMP);
txt1.SetLayout(EDGE_ALIGNED, 0, EDGE_ALIGNED, 0 )
txt1.SetColor($50,$50,$50);
txt1.setClamp(1,255);

Local txt2:TTextFieldK=CreateTextFieldK(120,10,130,20, backpan, TEXTFIELDK_EXPONENT | TEXTFIELDK_CLAMP);
txt2.SetLayout(EDGE_ALIGNED, 0, EDGE_ALIGNED, 0 )
txt2.SetColor($50,$50,$50);
txt2.setClamp(-50,50000);

Local txt3:TTextFieldK=CreateTextFieldK(260,10,130,20, backpan);
txt3.SetLayout(EDGE_ALIGNED, 0, EDGE_ALIGNED, 0 )
txt3.SetColor($50,$50,$50);

Repeat

While PollEvent()
Select EventID()
Case EVENT_WINDOWCLOSE
End
Case EVENT_GADGETACTION
Select EventSource()
Case txt1, txt2, txt3
Print "data="+EventData()
Print CurrentEvent.ToString()
End Select
End Select
Wend

Forever

End Function