Real Software Forums

The forum for Real Studio and other Real Software products.
[ REAL Software Website | Board Index ]
It is currently Mon Dec 09, 2019 6:48 pm
xojo

All times are UTC - 5 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: OCX question
PostPosted: Mon Sep 05, 2011 8:46 pm 
Offline

Joined: Mon Sep 05, 2011 7:45 pm
Posts: 26
Hi all experts,
I'm totally new in RealBasic , I would like to ask a question for OCX object , I have to use realbasic and communicate with the "MIFARE" card reader and I found that the realbasic could succesfully reference the "MIFARE" card reader OCX , but there are some convertion issues happened during the time I was compiling the program, I'm not sure whether the method that I using is the correct way or not. Anyone could help me on that?

( i just referenced the ocx as below and builded the program , but the error returned as below.)

Errors : Structures cannot contain Date fields.
dt as Date


Besides that , I also found that there are some functions inside the OCX are not working properly due to the wrong datatype conversion by realbasic.


OCX file download link : http://www.box.net/shared/yie34f46go173i3h2qth

Thanks in advance.

regards
william


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Mon Sep 05, 2011 9:40 pm 
Offline
User avatar

Joined: Fri Jan 12, 2007 10:59 am
Posts: 136
Location: Victoriaville, QC, Canada
Hi William,

you cannot have a date field in a structure. You'll have to decode it yourself manually. If you have more info on how the date is stored, I can help with code to convert it to a RB date object.

_________________
Bruno Fréchette
PJJ Productions inc.
RealStudio Web & Desktop on OSX


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Mon Sep 05, 2011 11:45 pm 
Offline

Joined: Mon Sep 05, 2011 7:45 pm
Posts: 26
Hi BrunoFrechette ,

Firstly , thank you for replying my "First post" . I have tried changing the "Date" datatype to integer and it seems like working fine now ( i'm not using the mf_record class) .The second question is the function inside the OCX ( mfReadHex)

This function allows us to read the value from the "MIFARE" card block, typically , If I want to retrieve the value from the card block by using VB6 , I just need to set the block of the card in integer format and put a "blank string variable" on "SzData" then the card block value will be returned to the "Blank variable" , but I not sure why Realbasic converted the "Szdata" in Ptr(pointer) , May I know how could this happened and how we retrieve the actual value from that?


VB6
Function mfReadHex(nBlock As Integer, szData As String) As Boolean

RealBasic
Function mfReadHex(nBlock_Param As Int16, szData_Param As Ptr) As Boolean

Million thanks!
regards,
william


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Tue Sep 06, 2011 8:23 am 
Offline
User avatar

Joined: Fri Jan 12, 2007 10:59 am
Posts: 136
Location: Victoriaville, QC, Canada
Hey William.

What VB was doing is passing a variable that was modified by the function. It can be done in RB but in a slightly different way.

When you pass a scalar value to a function (integer, string, boolean, etc.) the function actually gets a copy of the data and thus the original variable is isolated from what the function would be doing to the data. It makes sens to me and I like it this way (it's just my opinion though :) )

What the conversion did is to actually pass a pointer to the function. The pointer is the address of a memory block. This way, the function can modify the memory block at will and when the function returns, your pointer it still referring to the same block now containing whatever new data has been put there by the function.

I haven't user the memory blocks much but I have a good idea of how they work. You can check the documentation:
Ptr: http://docs.realsoftware.com/index.php/Ptr
MemoryBlock: http://docs.realsoftware.com/index.php/MemoryBlock

Now there's another way to go that does what you're looking for: pass the parameter by adding "byRef". The ByRef keyword tells RB that you don't want to pass a copy of the data but the variable itself, making it possible for the function to modify the variable and for the caller to access the modified data when the function returns. Your function call would be:

Function mfReadHex(nBlock_Param As Int16, byRef szData_Param As string) As Boolean


I'm not sure if that will work with external functions though, but you can give it a try.
ByRef: http://docs.realsoftware.com/index.php/ByRef

Otherwise, you'll have to define a memoryblock of sufficient size (in bytes) to hold whatever data the function needs to store and pass it as the string argument. Your function would remain as it was translated by RB:
Function mfReadHex(nBlock_Param As Int16, szData_Param As Ptr) As Boolean

To call it, you would do:
dim mbPtr as MemoryBlock // this defines mbPtr as a pointer to a memory block. The block doesn't exist yet.

// replace theSize with the length in bytes that you need the memoryblock to be
// I don't know if the function will adjust the size of the memoryblock or not, but to be safe, I would try with a large enough block.
// once you get it working, you can experiment with passing an empty block and see if your function does adjust the size
mbPtr = new MemoryBlock(theSize)

if mfReadHex(nBlock,mbPtr) then
// the memoryblock now contains the data
// if you know it's a string, you can access it as such with the getString method
// note that you might have to convert the encoding
msgBox mbPtr.getString
end if


I haven't tested anything, but I guess it'll get you starting in the right direction.

_________________
Bruno Fréchette
PJJ Productions inc.
RealStudio Web & Desktop on OSX


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Thu Sep 08, 2011 2:20 am 
Offline

Joined: Mon Sep 05, 2011 7:45 pm
Posts: 26
Hi BrunoFrechette,

Sorry for late replying your post and thank you for your detail explanations . I have tried to use both suggestions that you mentioned previously , but that 2 ways are not working too :( .

For first method , I just modified the external function header "mfReadHex" by adding a "byref" to the szData_Param parameter and changing the datatype from Ptr to string, , but realbasic still referring the original function parameter .

For second method, I just declared a memory block and set it to the "mfReadHex" , but there is an error "Failed on mfReadHex" popped up from the OCX's function (mfReadHex).
dim mbPtr as MemoryBlock

mbptr=new MemoryBlock(80)

if mf5x1.mfReadHex(2,mbptr)=false then
msgbox "Reading failed."
exit sub
end if


May I know whether I missed out some of the steps or made some mistakes for that ?

Thank you in advance.
regards
william


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Thu Sep 08, 2011 11:01 am 
Offline
User avatar

Joined: Fri Jan 12, 2007 10:59 am
Posts: 136
Location: Victoriaville, QC, Canada
Hi again Will. The byref can't work ... my bad, I didn't understand you question correctly. :oops:

The second way with the memory block should work. Can you post the original declare and how RB translated it?

_________________
Bruno Fréchette
PJJ Productions inc.
RealStudio Web & Desktop on OSX


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Fri Sep 09, 2011 12:51 am 
Offline

Joined: Mon Sep 05, 2011 7:45 pm
Posts: 26
Hi BrunoFrechette,

I'm sorry for the unclear explanations :( , however, thank you for answering my post patiently. :) here are the codes that copied from the external OCX.

Function mfReadHex(nBlock_Param As Int16, szData_Param As Ptr) As Boolean

If mThis = Nil Then Raise New NilObjectException
Dim disp As New COM.IDispatch(mThis)
Call disp.AddRef
Dim memID As Integer = 29
If memID = -1Then Raise New COM.COMException("Failed on mfReadHex", -1)
Dim params As COM.DISPPARAMS
Dim Local_nBlock_Param As MemoryBlock = COM.RBVariantToVARIANT(nBlock_Param)
params.cArgs = params.cArgs + 1
Dim Local_szData_Param As MemoryBlock = COM.RBVariantToVARIANT(szData_Param)
params.cArgs = params.cArgs + 1
Dim mbParams As New MemoryBlock(params.cArgs * COM.SIZEOF_VARIANT)
params.rgvarg = mbParams
If Local_nBlock_Param <> Nil Then mbParams.StringValue(1 * COM.SIZEOF_VARIANT, COM.SIZEOF_VARIANT) = Local_nBlock_Param.StringValue(0, COM.SIZEOF_VARIANT)
If Local_szData_Param <> Nil Then mbParams.StringValue(0 * COM.SIZEOF_VARIANT, COM.SIZEOF_VARIANT) = Local_szData_Param.StringValue(0, COM.SIZEOF_VARIANT)
Dim resultCode As Integer
Dim result As New MemoryBlock(COM.SIZEOF_VARIANT)
Dim err As UInt32
Dim mb As New MemoryBlock(params.Size)
mb.LittleEndian = True
mb.StringValue(0,params.Size) = params.StringValue(True)
resultCode = disp.Invoke(memID, COM.IID_NULL, COM.LOCALE_USER_DEFAULT, COM.DISPATCH_METHOD + COM.DISPATCH_PROPERTYGET, mb, result, nil, err)
COM.FreeVARIANT(Local_nBlock_Param)
COM.FreeVARIANT(Local_szData_Param)
If resultCode = COM.S_OK Then
Dim retVal As Variant = COM.VARIANTToRBVariant(result)
COM.FreeVARIANT(result)
Return retVal
Else // Throw Exception
Raise New COM.COMException("Failed on mfReadHex", resultCode)
End If


Once again thank you for your help.

regards
william


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Fri Sep 09, 2011 9:10 pm 
Offline
User avatar

Joined: Fri Jan 12, 2007 10:59 am
Posts: 136
Location: Victoriaville, QC, Canada
Hey WIlliam.

Don't blame yourself for the explanation, there are lots of things I'm not expert with so it often takes me lots of time to grasp things!

From what I see, you do need to pass a memoryblock as szData_Param. However, I'm not sure how the data is put in this memory block. But we're not there yet. The error you get is from the disp.Invoke function. It returns false and that triggers the exception. So we'd have to know what this function doesn't like in order to understand why you get the error.

BTW, the code seems somewhat strange. For example, you have
Dim memID As Integer = 29
If memID = -1Then Raise New COM.COMException("Failed on mfReadHex", -1)

Besides the missing space which is probably a copy/paste error, it seems strange to test a variable that was just initialized... The test will never fail because memID will always be 29 at that point!

So maybe you can put a break point and trace the disp.invoke method to see what is causing it to return false.

_________________
Bruno Fréchette
PJJ Productions inc.
RealStudio Web & Desktop on OSX


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Mon Sep 12, 2011 10:08 pm 
Offline

Joined: Mon Sep 05, 2011 7:45 pm
Posts: 26
Hey BrunoFrechette,

It's me again, I have debugged the that function line by line and I finally found that the line of code below is the main cause to return the error.

resultCode = disp.Invoke(memID, COM.IID_NULL, COM.LOCALE_USER_DEFAULT, COM.DISPATCH_METHOD + COM.DISPATCH_PROPERTYGET, mb, result, nil, err)


the resultcode is error code (-2147352571).

may I know is there any way to make it works?

thanks
regards
william


Top
 Profile  
Reply with quote  
 Post subject: Re: OCX question
PostPosted: Mon Sep 12, 2011 11:09 pm 
Offline
User avatar

Joined: Fri Jan 12, 2007 10:59 am
Posts: 136
Location: Victoriaville, QC, Canada
Hi William.

I had figured that the disp.Invoke was returning an error code. The question is why. :wink: You should try and trace inside that function. Moreover, you'll have to understand what the function is supposed to do and why it doesn't do it.

I'll have a hard time guiding you remotely to the exact part that doesn't work as several classes and objects seem to be involved, like the COM class which looks like it contains several properties and methods. Again, looking at the logic, it seems like a big endeavour to diagnose remotely, so you'll have to do some work yourself...

Let me know if you have other specific questions.

Good luck.

_________________
Bruno Fréchette
PJJ Productions inc.
RealStudio Web & Desktop on OSX


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 5 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group