Page 2 of 5
Delegates
Posted: Thu Dec 19, 2019 8:35 am
by lagraf
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?
Code: Select all
#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)
Delegates
Posted: Thu Dec 19, 2019 11:39 am
by wriedmann
Hi Franz,
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
Delegates
Posted: Thu Dec 19, 2019 1:45 pm
by lagraf
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 :
Code: Select all
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
Delegates
Posted: Thu Dec 19, 2019 2:11 pm
by FFF
You might also have a look here:
https://www.techcoil.com/blog/how-to-mo ... plication/
(despite the url it talks about c#, not c
)
doing a similiar task. There's a FileSystemWatcher Class for those jobs...
Delegates
Posted: Thu Dec 19, 2019 5:13 pm
by robert
Wolfgang,
One more thing:
Code: Select all
delegate EnumWindowsProc_delegate( hWnd as ptr, aWindows as array ) as word
function EnumWindowsProc(hwnd as ptr, lParam as IntPtr) as logic
The delegate returns a WORD, the function a LOGIC. I think they should both be defined as LOGIC
Robert
Delegates
Posted: Thu Dec 19, 2019 5:32 pm
by wriedmann
Hi Robert,
you are right again!
Thank you very much!
Wolfgang
P.S. I will change che code to use native :NET methods in the X# version.
Delegates
Posted: Thu Dec 19, 2019 5:56 pm
by George
Hi Wolfgang,
>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:
https://books.google.gr/books?id=WnMumn ... er&f=false
George
Delegates
Posted: Thu Dec 19, 2019 6:00 pm
by wriedmann
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
Delegates
Posted: Fri Dec 20, 2019 6:26 am
by lagraf
Hallo Wolfgang
wenn ich deinen XSGetWindowsArray() Code einbaue und compiliere bekomme ich die Fehlermeldung
XS0123: No overload for 'EnumWindowsProc' matches delegate 'EnumWindowsProc_delegate'
Delegates
Posted: Fri Dec 20, 2019 6:31 am
by wriedmann
Hallo Franz,
da hat mich gestern der Robert drauf hingewiesen, dass ich da noch einen Fehler drin hatte.
Das ist der korrekte Code:
Code: Select all
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