PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: Richard Marchessault on January 15, 2013, 01:53:51 PM

Title: Custom Control - How To
Post by: Richard Marchessault on January 15, 2013, 01:53:51 PM
I have a custom control (OCX) that I want to evaluate. The control is successfully registered with Windows. A demo application supplied with the control works fine. I have used the PB COM browser. I can see all the methods, etc. I have created an include file with this information for my evaluation project.

I have tried something simple like calling the "About" method but nothing happens. Although the program compiles and runs and I do not get any error messages, it is not clear to me that I am successfully passing information to and from the control.

What exactly are the steps I need to take to succeed in my evaluation of this control?

Any help you can give me would be appreciated.
Title: Re: Custom Control - How To
Post by: Wilko Verweij on January 15, 2013, 05:06:34 PM
Hi, if you open the FireFly-helpfile, then browse to "User Reference Guide", you will find an item on "Working with OCX/ActiveX Controls". Was sufficient even for me to get things working ;-)
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 15, 2013, 05:44:58 PM
Thanks. That helps and it is what I was doing. I believe my problem is with the OCX and and not Firefly. I'm working with the author.
Title: Re: Custom Control - How To
Post by: Rolf Brandt on January 16, 2013, 05:15:31 AM
Maybe you should try Jose's com browser. Jose probably could be of help.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 16, 2013, 05:07:08 PM
Thanks for the recommendation. I did try Jose's COM browser. Unfortunately it did not help me to get the OCX working. Waiting for a reply from the OCX author.

What do you do if you find what appears to be a really useful DLL that does not have a Type Library?
Title: Re: Custom Control - How To
Post by: José Roca on January 16, 2013, 05:14:40 PM
Standard DLLs don't have type libraries. You need to translate the headers to PowerBASIC.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 16, 2013, 05:20:08 PM
Quote from: Jose Roca on January 16, 2013, 05:14:40 PM
Standard DLLs don't have type libraries. You need to translate the headers to PowerBASIC.

Can you point me in the right direction on how to get started on translating headers to PowerBASIC?
Title: Re: Custom Control - How To
Post by: José Roca on January 16, 2013, 09:07:55 PM
You can browse my headers or the PowerBASIC headers. Not an easy task unless you know parameter passing and calling conventions very well.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 17, 2013, 10:08:49 AM
I am attaching a zip file with the control, the help file for it, and the include file created based on the COM browser to this message. Any help you or anyone in the forum can give me on getting this to work would be appreciated. The examples given in the help file are all for Visual Basic. No matter what I try to do with the control, I seem to get an error code 99. A key event seems to be assigning a bitmap image to the control and it's not clear to me how this can be done. Thanks.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 18, 2013, 04:45:26 PM
I'm trying to figure out how to render the following two lines of Visual Basic code in Firefly.

Picture1.Picture = LoadPicture(“Image.jpg”)
Control.Picture = Picture1.Image

Any recommedations?
Title: Re: Custom Control - How To
Post by: Haakon Birkeland on January 19, 2013, 05:12:31 AM
On the top of my head before I leap out of the house, you're looking for using the SendMessage API with the %STM_SETIMAGE constant.
I've usually used it with the picture loaded in the Image Library of FireFly, but it should also work fine with a picture fetched straight from the disk.
Title: Re: Custom Control - How To
Post by: Paul Squires on January 19, 2013, 11:23:48 PM
If you are to display a JPEG image then you should use the FireImage control. Check out this post:
http://www.planetsquires.com/protect/forum/index.php?topic=2063.msg16600#msg16600
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 20, 2013, 03:58:43 PM
Quote from: TechSupport on January 19, 2013, 11:23:48 PM
If you are to display a JPEG image then you should use the FireImage control. Check out this post:
http://www.planetsquires.com/protect/forum/index.php?topic=2063.msg16600#msg16600

My problem is not how to load an image into a FireImage control. It is how to transfer that image into the custom control.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 21, 2013, 11:19:52 AM
The code below was provided on the PB Forums by Chris Holbrook. (Thanks Chris) With this code run in Powerbasic the control does load and show its "About" box. When I try to implement this code in Firefly the object is created but the about box never shows. Why would that be?

#COMPILE EXE
#DIM ALL
'#include "win32api.inc"

%UNICODE = 1

' // Include files for external files
%USEOLECON = 1                ' // Use OLE container
#INCLUDE ONCE "CWindow.inc"   ' // CWindow class

%IDC_OCX = 101
#INCLUDE "EymBarcodeReader.inc" '
GLOBAL ordr AS Int__DEymBarcodeReader
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
    LOCAL hCtl AS DWORD

   ' // Create the dialog
   LOCAL hDlg AS DWORD
   DIALOG NEW PIXELS, 0, "test", , , 300, 300, %WS_OVERLAPPEDWINDOW TO hDlg

   ' // Create an instance of the class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Add EYMBARCODERREADER control
   LOCAL nWide, nHigh AS LONG
   DIALOG GET CLIENT hDlg TO nWide, nHigh
   hCtl = pWindow.AddOCX(hDlg, %IDC_OCX, "EYMBARCODEREADER.EymBarcodeReaderCtrl.1" , "", 0, 0, nWide, nHigh)
   IF hCtl = 0 THEN MSGBOX "failed to add OCX" ELSE MSGBOX "added OCX" : EXIT FUNCTION
   CONTROL SET FOCUS hDlg, %IDC_OCX

   ' // Get the IDispatch of the control
   oRdr = OC_GetDispatch(hCtl)
   IF ISOBJECT(oRdr) THEN

       OBJECT CALL oRdr.aboutbox
       MSGBOX "object created"
   ELSE
       MSGBOX "Reader object not created"
   END IF

   ' // Display and activate the dialog
   DIALOG SHOW MODELESS hDlg, CALL DlgProc

   ' // Message handler loop
   ' // We need to forward the messages to this control to have keyboard navigation
   LOCAL uMsg AS tagMsg
   WHILE GetMessage(uMsg, %NULL, 0, 0)
      IF ISFALSE OC_ForwardMessage(GetFocus, uMsg) THEN
         IF IsDialogMessage(hDlg, uMsg) = 0 THEN
            TranslateMessage uMsg
            DispatchMessage uMsg
         END IF
      END IF
   WEND

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   SELECT CASE CBMSG

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
         MSGBOX "Test"
         ' ...
            ' ...
         END SELECT

      CASE %WM_SIZE
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            ' // Resize the control
            LOCAL nWide, nHigh AS LONG
            DIALOG GET CLIENT CB.HNDL TO nWide, nHigh
            CONTROL SET SIZE CB.HNDL, %IDC_OCX, nWide, nHigh
         END IF

      CASE %WM_DESTROY
         ' // End the application
         ' // Use this method instead of DIALOG END with modeless dialogs
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

END FUNCTION
' ===========================           
Title: Re: Custom Control - How To
Post by: José Roca on January 21, 2013, 11:31:48 AM
Quote
When I try to implement this code in Firefly the object is created but the about box never shows. Why would that be?

If you don't show the code you are using, we have no clue.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 21, 2013, 11:47:42 AM
Here is my code in Firefly. When run the message pops up indicating that the object has been created but the About box never shows.

Function FORM1_WM_CREATE ( _
                         hWndForm As Dword, _      ' handle of Form
                         ByVal UserData As Long _  ' optional user defined Long value
                         ) As Long

    Dim BCR As EYMBARCODEREADERLibEymBarcodeReader
    BCR = OC_GetDispatch(HWND_FORM1_OCXCONTROL1)
    BCR = NewCom $PROGID_EYMBARCODEREADEREYMBARCODEREADERCTRL1
    If IsObject(BCR) Then MsgBox "Object" Else MsgBox "Not object"
    FF_Control_SetFocus(HWND_FORM1_OCXCONTROL1)
    Object Call BCR.AboutBox     
End Function
Title: Re: Custom Control - How To
Post by: José Roca on January 21, 2013, 12:46:48 PM
Remove BCR = NewCom $PROGID_EYMBARCODEREADEREYMBARCODEREADERCTRL1
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 21, 2013, 01:33:15 PM
I removed that line but now the program indicates that an object has not been created and the about box still does not show up.
Title: Re: Custom Control - How To
Post by: José Roca on January 21, 2013, 02:58:06 PM
Do you have introduced EYMBARCODEREADER.EymBarcodeReaderCtrl.1 in the ProgID field of the properties of the control?
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 21, 2013, 03:02:48 PM
Yes. See the attachment.
Title: Re: Custom Control - How To
Post by: José Roca on January 21, 2013, 04:28:33 PM
The probably the control has not yet been created and HWND_FORM1_OCXCONTROL1 must be 0 (check it). Add a button for testing, move the code to the WM_COMMAND message and test it there.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 21, 2013, 08:33:00 PM
Unfortunately putting the code in the Command section for a button produces the same result as was obtained with the code in the Create section for the form. The same result is obtained each time the button is clicked. In all cases HWND_FORM1_OCXCONTROL1 comes up with a value of zero.
Title: Re: Custom Control - How To
Post by: José Roca on January 21, 2013, 11:39:38 PM
Then the control is not being created for some reason. Try removing the trial key; it doesn't look like a key for licensed controls, that usually is a GUID.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 22, 2013, 06:55:31 AM
I removed the trial key and that made a difference. The control now appears on the form and the handle is not zero. I still have the code in the command section for a button on the form. However, the about box does not display when the following code is executed.

Object Call BCR.AboutBox
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 23, 2013, 02:38:50 PM
The following code in the Command code for a button on the form works in that the About box appears and I can read values from parameters of the OCX control. Now if I can figure out how to load a bitmap into the control I should be well on my way to fully evaluating this control before I purchase it. Thanks to all for your assistance.

    Dim BCR As EYMBARCODEREADERLibEymBarcodeReader
    Dim X As Single, LL As Long     
    BCR = OC_GetDispatch(HWND_FORM1_OCXCONTROL1)
    Object Get BCR.Confidence To X
    MsgBox Str$(X)
    Object Get BCR.ExpectedDpi To X
    MsgBox Str$(X)
    Object Call BCR.AboutBox To LL
    MsgBox Str$(LL) & " " & Hex$(LL)
Title: Re: Custom Control - How To
Post by: José Roca on January 23, 2013, 03:30:18 PM

LOCAL oPicture  AS IDispatch
vPath = <path to picture>
IF OleLoadPictureFile(vPath, oPicture) = %S_OK THEN
  OBJECT SET BCR.Picture = oPicture 
END IF


You must have to add #INCLUDE "OleCtl.inc" to the list of include files to have access to the OleLoadPictureFile function.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 23, 2013, 11:58:26 PM
I added the include statement for OleCtl.inc and ran the code below for the button on the form. If I click the button once, the "Not OK" message comes up. If I click the button a second time the program crashes after the "Not OK" message appears and is cleared from the screen. If I uncomment the Exit Function line, I can click the button as many times as I like and there is no crash. In each case the About box for the OCX does popup. What might be causing the crash?

Local BCR As EYMBARCODEREADERLibEymBarcodeReader
    Local X As Single, LL As Long
    Local oPicture As IDispatch, vPath As Variant, Z$     
    BCR = OC_GetDispatch(HWND_FORM1_OCXCONTROL1)
    Object Call BCR.AboutBox To LL
    vPath = "C:\Temp\barcode.bmp"
    'Exit Function
    If OleLoadPictureFile(vPath, oPicture) = %S_OK Then
        Object Set BCR.Picture = oPicture
        Object Get BCR.RawData To Z$
        MsgBox Z$
    Else
        MsgBox "Not OK"
    End If

Using the following code eliminates the crash but produces the result of "Other = FFFFFFFF80020008" every time.

    Local BCR As EYMBARCODEREADERLibEymBarcodeReader
    Local X As Single, LL As Long
    Local oPicture As IDispatch, vPath As Variant, Z$, Y$     
    BCR = OC_GetDispatch(HWND_FORM1_OCXCONTROL1)
    Object Call BCR.AboutBox To LL
    vPath = "C:\Users\Dick\Documents\Temp\barcode.bmp"
    LL = OleLoadPictureFile(vPath, oPicture)
    Select Case LL
        Case %S_OK
            MsgBox "Picture OK"
            Object Set BCR.Picture = oPicture
            Object Get BCR.RawData To Z$
            MsgBox Z$
        Case %CTL_E_INVALIDPICTURE             
            MsgBox "Invalid Picture"
        Case Else
            MsgBox "Other = " & Hex$(LL)
    End Select
Title: Re: Custom Control - How To
Post by: José Roca on January 24, 2013, 02:30:02 AM
I think there is a mistake in the declare.

Change:


DECLARE FUNCTION OleLoadPictureFile IMPORT "OLEAUT32.DLL" ALIAS "OleLoadPictureFile" ( _
   BYREF varFileName AS ANY _                           ' __in  VARIANT varFileName
, BYREF lplpdispPicture AS IDispatch _                 ' __out LPDISPATCH *lplpdispPicture
) AS LONG                                              ' HRESULT


to.


DECLARE FUNCTION OleLoadPictureFile IMPORT "OLEAUT32.DLL" ALIAS "OleLoadPictureFile" ( _
   BYVAL varFileName AS VARIANT _                       ' __in  VARIANT varFileName
, BYREF lplpdispPicture AS IDispatch _                 ' __out LPDISPATCH *lplpdispPicture
) AS LONG                                              ' HRESULT


in OleCtl.inc.
Title: Re: Custom Control - How To
Post by: Richard Marchessault on January 24, 2013, 10:22:27 AM
I got it working. I entered the message below before I picked up the fact that not only was the change in the include function from "Any" to "Variant" but also from "ByRef" to "ByVal". Now that I made that change, the OCX is working just fine. Pictures are loading without a problem. Barcodes reading is working fine. Thanks for all your help.

If anyone is reading through this, you should note that the string value being picked up by the control is a unicode value and requires a wide string. The code below works best with Z$$ instead of Z$.




Okay. I made the change to variant in the include file. No crashing but the picture is still not being loaded. The return code from OleLoadPictureFile is "Other = 80020008". What else might be the problem?

    Local BCR As EYMBARCODEREADERLibEymBarcodeReader
    Local X As Single, LL As Dword
    Local oPicture As IDispatch, vPath As Variant, Z$, Y$     
    BCR = OC_GetDispatch(HWND_FORM1_OCXCONTROL1)
    Object Call BCR.AboutBox To LL
    vPath = "C:\Users\Dick\Documents\Temp\barcode.bmp"
    LL = OleLoadPictureFile(vPath, oPicture)
    Select Case LL
        Case %S_OK
            MsgBox "Picture OK"
            Object Set BCR.Picture = oPicture
            Object Get BCR.RawData To Z$
            MsgBox Z$
        Case %CTL_E_INVALIDPICTURE             
            MsgBox "Invalid Picture"
        Case Else
            MsgBox "Other = " & Hex$(LL)
    End Select