Checking changes in folder
- Marco Turco
- Posts: 858
- Joined: Fri Oct 07, 2005 12:00 pm
- Location: London
- Contact:
Checking changes in folder
Hi,
I need to check if the value of some controls (get, combobox..) in a folder has changed in order to request a confirm to the customer before exit.
Due the outlook interface I am using the customer can loose the data simply selecting another record so a confirm exit is needed.
See image at www.softwarexp.co.uk/beta/sample.jpg
I made the following routine to check it that providing the oFld as parameter will scan all GET controls inside and check the ::oGet:Changed() value.
Function CheckChanged(oFld)
local aArray,i,n,nPrompts,lChanged
lChanged:=.f.
nPrompts:=len(oFld:aPrompts)
for n:=1 to nPrompts
aArray:=oFld:aDialogs[n]:aControls
for i:=1 to len(aArray)
if oFld:aDialogs[n]:aControls:Classname="TGET"
if oFld:aDialogs[n]:aControls:oGet:Changed()
lChanged:=.t. && has changed
exit
endif
endif
next
next
return(lChanged)
The problem is that I only can check changes in GET controls but I need to check the combobox and tcbrowse also.
Any ideas to make this ? As I know the ::Changed() data is only applied on GET controls.
Thanks iin advance.
I need to check if the value of some controls (get, combobox..) in a folder has changed in order to request a confirm to the customer before exit.
Due the outlook interface I am using the customer can loose the data simply selecting another record so a confirm exit is needed.
See image at www.softwarexp.co.uk/beta/sample.jpg
I made the following routine to check it that providing the oFld as parameter will scan all GET controls inside and check the ::oGet:Changed() value.
Function CheckChanged(oFld)
local aArray,i,n,nPrompts,lChanged
lChanged:=.f.
nPrompts:=len(oFld:aPrompts)
for n:=1 to nPrompts
aArray:=oFld:aDialogs[n]:aControls
for i:=1 to len(aArray)
if oFld:aDialogs[n]:aControls:Classname="TGET"
if oFld:aDialogs[n]:aControls:oGet:Changed()
lChanged:=.t. && has changed
exit
endif
endif
next
next
return(lChanged)
The problem is that I only can check changes in GET controls but I need to check the combobox and tcbrowse also.
Any ideas to make this ? As I know the ::Changed() data is only applied on GET controls.
Thanks iin advance.
Best Regards,
Marco Turco
SOFTWARE XP LLP
Marco Turco
SOFTWARE XP LLP
Marco,
This is the way I do this check :
It doesn't matter what the kind of cFIELD1 or cFIELD2 is : a GET, a CHECKBOX, a RADIO BUTTON, ...
It always works.
Good luck
This is the way I do this check :
Code: Select all
LOCAL cFIELD1, oFIELD1
LOCAL cFIELD2, oFIELD2
....
cFIELD1 := oFIELD1 := FILE->FIELD1
cFIELD2 := oFIELD2 := FILE->FIELD2
....
DEFINE DIALOG ....
....
REDEFINE GET cFIELD1 ID 101 OF ....
REDEFINE CHECKBOX cFIELD2 ID 102 OF ....
....
ACTIVATE DIALOG ....
IF cFIELD1 = oFIELD1 .AND. cFIELD2 = oFIELD2
.... data has not been changed ....
ELSE
.... data has been changed ....
ENDIF
It always works.
Good luck
Regards,
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
- Marco Turco
- Posts: 858
- Joined: Fri Oct 07, 2005 12:00 pm
- Location: London
- Contact:
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Marco Turco
- Posts: 858
- Joined: Fri Oct 07, 2005 12:00 pm
- Location: London
- Contact:
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Marco,
If you use locals, then I am thinking that we could implement an easy and very powerfull solution
if you keep the locals together, then we could step through them and build an array from them, and later on, compare the original values with the array. Thats what Class TDataBase does basically.
There are some functions in [x]Harbour to step through the local variables by their position (order) and no by its name. So it can be done
If you use locals, then I am thinking that we could implement an easy and very powerfull solution
if you keep the locals together, then we could step through them and build an array from them, and later on, compare the original values with the array. Thats what Class TDataBase does basically.
There are some functions in [x]Harbour to step through the local variables by their position (order) and no by its name. So it can be done
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Marco,
Here you have a working sample. It can be very much simplified, as I have included some code so testers can understand the virtual machine stack structure. Also the "locals" checker code could be placed into an external function:
Here you have a working sample. It can be very much simplified, as I have included some code so testers can understand the virtual machine stack structure. Also the "locals" checker code could be placed into an external function:
Code: Select all
#include "FiveWin.ch"
function Main()
Test( "one", "two", "three" )
return nil
function Test( x, y, z )
local local1 := "first", local2 := "second", aBegin := HB_DBG_VMSTKLLIST(), aEnd, n
MsgInfo( "Name of the function: " + aBegin[ 1 ] )
MsgInfo( "Is this a function or a method ? " + If( aBegin[ 2 ] != nil, "Method", "function" ) )
for n = 1 to PCount()
MsgInfo( "parameter " + AllTrim( Str( n ) ) + ": " + cValToChar( aBegin[ 2 + n ] ) )
next
n++
while n < Len( aBegin ) - 1
MsgInfo( "local " + AllTrim( Str( n - PCount() - 1 ) ) + ": " + cValToChar( aBegin[ n + 1 ] ) )
n++
end
local2 := "changed!" // we change a local value
aEnd = HB_DBG_VMSTKLLIST()
for n = PCount() + 1 to Len( aEnd ) - 1
if aBegin[ n ] != aEnd[ n ]
MsgInfo( "local " + AllTrim( Str( n - PCount() - 2 ) ) + " has changed!" )
endif
next
return nil
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
A simplified version:
Code: Select all
#include "FiveWin.ch"
function Main()
Test( "one", "two", "three" )
return nil
function Test( x, y, z )
local local1 := "first", local2 := "second", aBegin := HB_DBG_VMSTKLLIST(), aEnd, n
// your code...
local2 := "changed!" // we change a local value
// Now we check for changes in locals variables
aEnd = HB_DBG_VMSTKLLIST()
for n = PCount() + 1 to Len( aEnd ) - 1
if aBegin[ n ] != aEnd[ n ]
MsgInfo( "local " + AllTrim( Str( n - PCount() - 2 ) ) + " has changed!" )
endif
next
return nil
-
- Posts: 167
- Joined: Thu Mar 22, 2007 11:24 am
Maybe this will work , also when folders are nested
Frank
Frank
Code: Select all
#include "FiveWin.ch"
#include "common.ch"
function Main()
local oDlg, oFld
LOCAL Num := 100
LOCAL MemInpVal[0]
LOCAL n := 1 , oRadMenu , oGet
DEFINE DIALOG oDlg RESOURCE "test"
REDEFINE FOLDER oFld ID 110 OF oDlg ;
DIALOGS "dlg1", "dlg2" PROMPTS "One", "Two"
REDEFINE GET oGet VAR Num OF oFld:aDialogs[1] ID 100
REDEFINE RADIO oRadMenu VAR n ID 110 , 120 OF oFld:aDialogs[2]
REDEFINE BUTTON ID 120 OF oDlg ACTION CompInputValue(oDlg , @MemInpVal )
ACTIVATE DIALOG oDlg CENTERED ;
ON INIT (SaveInputValue(oDlg , @MemInpVal))
return nil
PROC SaveInputValue(oDlg , Arr)
*************************
LOCAL el , elem , oRadMenu[0]
FOR EACH el IN oDlg:aControls
IF el:ClassName == "TFOLDER"
FOR EACH elem IN el:aDialogs
SaveInputValue(elem , @Arr)
NEXT
ELSE
IF el:ClassName = "TRADIO"
IF ASCAN(oRadMenu , {|j|j==el:oRadMenu}) == 0
AADD(oRadMenu , el:oRadMenu)
AADD(Arr,el:oRadMenu:nOption())
END
ELSEIF __ObjHasMethod(el,"VarGet")
// Maybe better : IF el:ClassName IN {"TGET","TCHECK", ......}
AADD(Arr,el:VarGet() )
END
END
NEXT
RETURN
**********************************************************************************************
FUNC CompInputValue(oDlg , MemInpVal )
***************************************
LOCAL Arr[0] , i
LOCAL lOk := .T.
SaveInputValue(oDlg,@Arr)
FOR i := 1 TO Len(MemInpVal)
IF Arr[i] <> MemInpVal[i]
lOk := .F.
EXIT
END
NEXT
RETURN lOk
************************************************************
Test DIALOG 19, 47, 233, 124
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "FiveWin Folders"
{
CONTROL "", 110, "SysTabControl32", 0 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 4, 5, 225, 99
PUSHBUTTON "&OK", 120, 98, 108, 37, 14
}
dlg1 DIALOG 18, 18, 205, 80
STYLE WS_CHILD | 4
{
LTEXT "Number : ", 90, 10 , 2 , 40 , 10 //, WS_BORDER | WS_TABSTOP
EDITTEXT 100, 37 , 2, 20 , 10, WS_BORDER | WS_TABSTOP
CONTROL "First", 110, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 37, 30, 28, 12
}
dlg2 DIALOG 18, 18, 205, 80
STYLE WS_CHILD | 4
{
CONTROL "Second", 110, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 37, 30, 28, 12
CONTROL "Third", 120, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 37, 43, 28, 12
}
-
- Posts: 167
- Joined: Thu Mar 22, 2007 11:24 am
Antonio
In many cases we are using arrays , or why not , nested arrays , or arrays are mixted with others.
In this case i suppose that this code is much more complicated and has to
be changed .
Frank
In many cases we are using arrays , or why not , nested arrays , or arrays are mixted with others.
In this case i suppose that this code is much more complicated and has to
be changed .
Frank
Antonio Linares wrote:A simplified version:Code: Select all
#include "FiveWin.ch" function Main() Test( "one", "two", "three" ) return nil function Test( x, y, z ) local local1 := "first", local2 := "second", aBegin := HB_DBG_VMSTKLLIST(), aEnd, n // your code... local2 := "changed!" // we change a local value // Now we check for changes in locals variables aEnd = HB_DBG_VMSTKLLIST() for n = PCount() + 1 to Len( aEnd ) - 1 if aBegin[ n ] != aEnd[ n ] MsgInfo( "local " + AllTrim( Str( n - PCount() - 2 ) ) + " has changed!" ) endif next return nil
- Marco Turco
- Posts: 858
- Joined: Fri Oct 07, 2005 12:00 pm
- Location: London
- Contact: