xsharp.eu • Array mit Prozessen - Page 2
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