Hi Wolfgang
thank you for translating FOREACH!
local aProcess as Process[] helps me for a better understanding!
But are you sure that alen() does not work? I get a value with alen() and I can do the loop!
A second warning is shown at RunMethodWaitForChanges, but the app works! Should I leave this XPorter code or is there a better way to do it to get no warning?
#warning Callback function modified to use a DELEGATE by xPorter. Please review.
// ptrCallBack := @RunMethodWaitForChanges()
STATIC LOCAL oRunMethodWaitForChangesDelegate := RunMethodWaitForChanges AS RunMethodWaitForChanges_Delegate
ptrCallBack := System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(oRunMethodWaitForChangesDelegate)
if ALen() works, thenm the development team has added something to make it work.
Please start using foreach - it is a lot better and, works also for collections where the index not always works.
Can you show me the VO code for the RunMethodWaitForChanges()?
If it works, the Xporter has done a good work, but maybe someone has a better solution for you.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Hi Wolfgang,
I already implemented FOREACH, its so much easier!
The RunMethodWaitForChangesDelegates from XPorter works, the app does what it should. I use it to monitor a dir for incoming files in an own thread :
GLOBAL oO AS ObserveEx
CLASS Main
METHOD StartObserve()
LOCAL ptrCallBack AS PTR
LOCAL dwParam, dwId AS DWORD
oO := ObServeEx{ _cDir,; // path
"*.PRN",; // file mask
FALSE,; // observe subtrees
FILE_NOTIFY_CHANGE_FILE_NAME; // watch creates and deletes
}
#warning Callback function modified to use a DELEGATE by xPorter. Please review.
// ptrCallBack := @RunMethodWaitForChanges()
STATIC LOCAL oRunMethodWaitForChangesDelegate := RunMethodWaitForChanges AS RunMethodWaitForChanges_Delegate
ptrCallBack := System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(oRunMethodWaitForChangesDelegate)
_ptrThread := CreateThread( NULL_PTR,;
0,;
ptrCallBack,;
@dwParam,;
0,;
@dwId;
)
IF _ptrThread = NULL_PTR
oO:Status := THREAD_CANT_CREATE_ERR
oO:Close(TRUE)
oO:Ok := FALSE
InfoBox{SELF, "Fehler", "Thread Observe konnte nicht gestartet werden"}:Show()
ENDIF
RETURN SELF
// Other Methods
END CLASS
FUNCTION RunMethodWaitForChanges() AS VOID PASCAL
oO:WaitForChanges()
RETURN
CLASS ObserveEx
PROTECT Z_cPath AS STRING
PROTECT Z_cMask AS STRING
PROTECT Z_loStatus AS DWORD
PROTECT Z_dwWaitStatus AS DWORD
PROTECT Z_dwWhat AS DWORD
PROTECT Z_bOK AS LOGIC
PROTECT Z_bWatchSubTree AS LOGIC
PROTECT Z_ptrChangeHandle AS PTR
METHOD WaitForChanges() AS VOID PASCAL
DO WHILE TRUE
SELF:Z_dwWaitStatus := WaitForSingleObject(; // number of Handle to wait
SELF:Z_ptrChangeHandle,; // Handle
INFINITE; // wait for ever
)
DO CASE
CASE SELF:Z_dwWaitStatus = WAIT_OBJECT_0
SELF:DoWhatMustBeDone() // a change in directory occurs!
IF !(FindNextChangeNotification(SELF:Z_ptrChangeHandle)) // start waiting next event
SELF:Z_loStatus := GetLastError() // Last Error
SELF:Z_bOk := FALSE // Status
SELF:Close(FALSE) // Close Object
EXIT
ENDIF
CASE TRUE
InfoBox{, "Fehler", "Wait For Changes bringt Otherwise"}:Show()
ENDCASE
ENDDO
RETURN
// Other Methods
END CLASS
>One of the latest things is that I'm using COM modules to access data from different SQL engines, from SQLite, MS SQL, MySQL to PostgreSQL
Another idea is instead using COM, to use a GenericFactoryHelper to write common code for: MSSQL, SqlCe, SQLite and MySQL etc.
The idea is to use DBConnection instead of SqlConnection (or...) and a Helper Class similar to this sample:
Hi George,
I use COM modules written in X# from my VO applications, and since .NET does not need installable drivers, I don't need them anymore.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Hallo Wolfgang
wenn ich deinen XSGetWindowsArray() Code einbaue und compiliere bekomme ich die Fehlermeldung
XS0123: No overload for 'EnumWindowsProc' matches delegate 'EnumWindowsProc_delegate'
function XSGetWindowsArray() as array pascal
local aWindows as array
local oGCHandle as System.Runtime.InteropServices.GCHandle
local oPtr as IntPtr
local oDelegate as EnumWindowsProc_delegate
static local oEnumWindowsProcDelegate := EnumWindowsProc as EnumWindowsProc_Delegate
aWindows := {}
oDelegate := EnumWindowsProc
oGCHandle := System.Runtime.InteropServices.GCHandle.Alloc( aWindows )
oPtr := System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate( oDelegate )
EnumWindows( oPtr, System.Runtime.InteropServices.GCHandle.ToIntPtr( oGCHandle ) )
oGCHandle:Free()
return aWindows
delegate EnumWindowsProc_delegate( hWnd as ptr, aWindows as array ) as logic
function EnumWindowsProc(hwnd as ptr, lParam as IntPtr) as logic
local aWindows as array
local gch as System.Runtime.InteropServices.GCHandle
gch := System.Runtime.InteropServices.GCHandle.FromIntPtr(LParam)
aWindows := (array)gch:Target
AAdd( aWindows, hwnd )
return true
Der Rückgabewert des Delegate muss "logic" sein, und nicht "word".
Keine Ahnung, warum mir das nicht aufgefallen ist....
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it