OleAutoObject

Deutschsprachiges X#-Forum – German language forum

Moderator: wriedmann

g.bunzel@domonet.de
Posts: 97
Joined: Tue Mar 01, 2016 11:50 am
Location: Germany

Re: OleAutoObject

Post by g.bunzel@domonet.de »

Franz,

wenn für den Laufbalken oDlg:SetMarquee(TRUE, 1) eingeschalten wird, macht die Aktualisierung des Balkens durch

DIBSetProgressControl( oDlg:oDCProgressBar:Handle() )

doch eigentlich gar keinen Sinn.
Aus der Funktionsbeschreibung von DIBSetProgressControl():
//d With this function you can set a Progress Control, wich Range is 1..100, then start to read a file with
//d any of DIBCreatexxx() function. For each step, the control will receive a notification to show the current reading.

Wozu diese Funktion aufrufen?

Gerhard
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: OleAutoObject

Post by Chris »

Hi Franz,

1. OK, but where is the function defined and how? If you right click on "DIBSetProgressControl" in the VO editor, where does it get you to?

2. In this case you need an intermediate GC handle to pass and retrieve that object to the windows callback. Here's how to do it:

Code: Select all

USING System.Runtime.InteropServices // top of prg
....
DELEGATE OGS_EnumAddItemToArray_delegate(ptrWnd AS PTR , lParam AS INT) AS WORD 
STATIC FUNCTION OGS_EnumAddItemToArray(ptrWnd AS PTR , lParam AS INT) AS WORD CALLBACK
	LOCAL aWindows AS ARRAY
	LOCAL oArrayHandle AS GCHandle
	oArrayHandle := GCHandle.FromIntPtr(lParam)
	aWindows := (ARRAY) oArrayHandle:Target

	IF aWindows[1] <= aWindows[2]				// number of elements <= max elements?
		aWindows[++aWindows[3]] := ptrWnd		// save handle
		aWindows[1] := ++aWindows[1]			// raise number of elements
	ELSE									// array zu small?
		aWindows[1] := -1					// return error
		RETURN 0
	ENDIF
		
	RETURN 1

FUNCTION OGS_EnumWindows() AS ARRAY PASCAL
	LOCAL aWindows AS ARRAY
	LOCAL loFaktor	AS DWORD
	
	aWindows := ArrayCreate(1024)
	aWindows[1] := 0				// Number of elements
	loFaktor := 1
	
	DO WHILE aWindows[1] = 0
		
		// max number of elements
		aWindows[2] := 1024*loFaktor
		// starting element-1
		aWindows[3] := 3

//		#warning Callback function modified to use a DELEGATE by xPorter. Please review.
//		EnumWindows(@OGS_EnumAddItemToArray(),LONGINT(_CAST,aWindows))
		STATIC LOCAL oOGS_EnumAddItemToArrayDelegate := OGS_EnumAddItemToArray AS OGS_EnumAddItemToArray_Delegate
		LOCAL oArrayHandle AS GCHandle
		oArrayHandle := GCHandle.Alloc(aWindows)
		EnumWindows(Marshal.GetFunctionPointerForDelegate(oOGS_EnumAddItemToArrayDelegate) , GCHandle.ToIntPtr(oArrayHandle))
		oArrayHandle:Free()

		IF aWindows[1] = -1
			
			aWindows := ArrayCreate(1024*(++loFaktor))	// too less elements
			aWindows[1] := 0
			aWindows[2] := 1024*loFaktor
			aWindows[3] := 3

		ELSE
			
			EXIT
		
		ENDIF
		
	ENDDO

	loFaktor := aWindows[1]
	aWindows := ADel(aWindows,1)                 		// delete element 1,2,3
	aWindows := ADel(aWindows,1)
	aWindows := ADel(aWindows,1)
	aWindows := ASize(aWindows,loFaktor)			// running windows

	RETURN aWindows
3. Then it should work. Are you sure that the error message points to that line of code? Can you zip and send me the project to have a look?
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Re: OleAutoObject

Post by lagraf »

Hi Chris,
1) I commented DIBSetProgressControl like Gerhard said -> Ok
2) I corrected code as you wrote -> maybe Ok not tested

But I have problems testing the app:
When starting the app I read a binary license file (you know it from INTERN.PRG) with memoread. What I get is different between VO and X#:
VO: œœ¦R«œ ª˜¯i‘’“z…”q íÜÞçÂÝÕÊ‘Ä×êØÖàÎçÜìØ„³¢¯³´¿§¼Á²’Ø“ñÕãèÙéêêùÝëðáñòò²¾Ô×ÄÒÚ
X#: ££ªR½£á¬ÿ»iüæÆôzàöqáf_¦t-¦+-æ-+O++a+t_8+ä¦ó»¦¦+º+-¦Æ+ô±+pF+TOO·¦d=ß±==¦+++--+

Why this is different?

3) Here are the classes Mailing and Etikette in short and the error XS7036, oOwner in Constructor is a DialogWindow

Code: Select all

CLASS Mailing
METHOD Close() 
ASSIGN FilterExpression(cString AS STRING) AS STRING PASCAL 
CONSTRUCTOR(oOwner AS window, cName AS STRING) 
ACCESS IsValid AS LOGIC PASCAL 
METHOD PrintPreview() 
ASSIGN SeekExpression(cString AS STRING) AS STRING PASCAL 
METHOD SetIndex(cString1 AS STRING, cString2 AS STRING) 
METHOD SetSortOrder(cOrder AS STRING) 
METHOD SetVariableValue(cVar AS STRING, cStr AS STRING) 
ASSIGN WhileExpression(cString) 
END CLASS

CLASS Etikette INHERIT Mailing	// Line 570
METHOD PrintPreview() 
END CLASS

error XS7036: There is no argument given that corresponds to the required formal parameter 'oOwner' of 'Mailing.Mailing(VO.Window, string)'	570,1	dlgReports.prg	Etikette:Etikette
Regards, Franz
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Re: OleAutoObject

Post by lagraf »

When I read the file with FRead or FReadLine instead of MemoRead it is ok!
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Re: OleAutoObject

Post by wriedmann »

Hi Franz,
using Memoread for binary files in .NET is a bad idea.
In .NET strings are Unicode and not more ANSI/ASCII.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: OleAutoObject

Post by Chris »

Hi Franz,

2. As Wolfgang said, that's because strings in .Net (and X#) are unicode, in contrast to the 8-bit strings of VO and due to the ansi<->OEM conversions. I am a bit surprised that with FReadLine() it does work as expected, but in any case that's good!

3. OK, so the error is reported for the Etikette class itself, not for the object instantiation. You just need to define a constructor that calls the parent one like this:

Code: Select all

CLASS Etikette INHERIT Mailing
CONSTRUCTOR(oOwner AS window, cName AS STRING) 
SUPER(oOwner, cName)
There's an option in VOXporter to automatically add such missing constructors, but it's better if you add them manually (if they are not too many), so you can also use better parameter names (VOXporter uses generic ones) as in above.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Re: OleAutoObject

Post by lagraf »

Hi Chris,
3) ok, Class Etikette runs now!
VO automatically uses Init of super class when Init is missing, why X# doesn't do this with Constructor?
I already tried something like SUPER: ..., but now I know that this is VO style and does not run <g>!

Thank you very much for all your help!
Franz
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: OleAutoObject

Post by Chris »

Hi Franz,

The difference is that VO uses CLIPPER calling convention constructors only, while in your X# code the constructor is strongly typed. If it was not typed, then you could had used the vo17 (generate missing clipper constructors) compiler option (in the app properties, compiler page) so that the compiler would had created one automatically.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
lagraf
Posts: 450
Joined: Thu Jan 18, 2018 9:03 am
Location: A

Re: OleAutoObject

Post by lagraf »

Hi Chris,
as I only need a small part of the XML Parser, I wrote a small function to extract the needed part of the XML string.
So I do not need the XML Parser and OleAutoObject in this app.
Franz
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Re: OleAutoObject

Post by Chris »

Hi Franz,

OK, sounds good! Btw, in case you are not aware, .Net has a very sophisticated and powerful set of classes for handling Xml. You can use them by adding a reference to System.Xml and using the classes System.Xml.XmlDocument, System.Xml.XmlNode etc.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Post Reply