Results 1 to 17 of 17

Thread: VB6 Cairo-Widgets Tutorial

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    VB6 Cairo-Widgets Tutorial

    This is the "logical second step", after one got more familiar with Cairo-Drawing -
    in the preceding Tutorial here: https://www.vbforums.com/showthread....cs-using-Cairo

    This Widget-Tutorial will show, how you can put your gathered knowledge with the Drawing-Methods
    (behind the usually named CC As cCairoContext) - to good use, when writing your own Cairo-based Controls.

    A self-implemented "UserControl" (with the helper-classes from RC6, using cairo-drawing) - is called "a Widget".

    A Widget is like a WindowLess-UserControl in VB6 - but not implemented in a *.ctl - but a normal *.cls.

    Due to that (everything sitting in a "normal Class"), I recommend to use the same ClassName-prefixing as you find in the Demos:
    - cSomeNormalClass (a normal Class is prefixed with a small c)
    - cfSomeRC6Form (an RC6-Form-Class is prefixed with cf)
    - cwSomeWidget (an RC6-Widget-Class is prefixed with cw)

    This will allow one, to keep the different type of Classes apart (the cf-prefixed ones are like *.frm, and the cw-ones like *.ctl).

    Ok, on the inside of a cwSomeWidget-Class, you will see basically the same principle, as when implementing something in a MyCtl.ctl:
    - an internal Helper-Variable, which provides you with all kind of Events inside of this "Control-Class"
    - in VB6 this Helper-Variable is named UserControl (automatically provided by the IDE, you don't have to define it)
    - and for RC6-WidgetClasses the same thing is usually named W, but you have to define it yourself:
    Private WithEvents W As cWidgetBase

    Other than that, the implementation is similar to what you do in a VB6-UserControl-Module:
    - you get Resize, Focus, Keyboard, Mouse- and Paint-Events from your internal UserControl-Variable
    - and in the same way, you get the same Events (plus a few more) in your Widget-Class from the W-Variable

    The largest difference to VB6-Usercontrols is this:
    - We now have a fully Alpha-Capable Vector-engine behind it (which supports even nested Alpha)
    - And the Widget is "by default" always "fully transparent"

    The latter part meaning:
    If you don't render anything in the W_Paint()-Event via explicite Cairo-methods, you will "not see anything"
    (the Container-Background of the Parent-Widget or Parent-Form will "remain as it is" below the area, your Widget occupies).

    Please note, that the only way to "render a given Widget properly", is via the W_Paint()-Event.
    If you change state on a given Widget (e.g. a Caption-Prop or an ImageKey-Property), you will have to ensure:
    - either a W.Refresh (if you are on the inside of your own implementing WidgetClass)
    - or a MyCtl.Widget.Refresh call on the outside of your WidgetClass-implementation
    to finally trigger the W_Paint-Event on the given Widget, which then dutifully re-renders its contents, according to the new "state".

    Ok, the Tutorial here has the same "Folder-structured approach" (from simple to more difficult),
    as the Cairo-Drawing-Tutorial which came before it...

    Folder-Contents:
    - 0 Hello World in VBScript
    - 1 Hello Widgets (simple)
    - 2 Widgets (Moveable-Prop and Zooming)
    - 3 Widgets (Events and Nesting)
    - 4 Widgets (MouseCursors and ImageKeys)
    - 5 SliderWidget (demonstrating visual inheritance)

    Here a ScreenShot of the "Folder #4 Demo" (Drag-Drop + MouseCursor-Handling)


    Here a ScreenShot of "Folder #5" (a Slider Widget + Visual Inheritance)


    Here the Demo-Zip:
    RC6WidgetTutorial.zip

    Happy "Widgeting"...

    Olaf
    Last edited by Schmidt; May 13th, 2021 at 10:36 AM.

  2. #2
    Fanatic Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    548

    Re: VB6 Cairo-Widgets Tutorial

    Never, I have been given the visual aspect.
    But this tutorial is very good.
    I will study it later


    very good work

  3. #3
    Banned
    Join Date
    May 2021
    Posts
    40

    Re: VB6 Cairo-Widgets Tutorial

    Dear Olaf,
    The RC5/6 Widget is so powerful that I'm able to use it to simulate a little graph canvas to create a group of objects as a desired mixed object, my question is how to save the single object and whole canvas , especially like microsoft excel's insert shapes and grouping them and save them. Thanks.

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    Re: VB6 Cairo-Widgets Tutorial

    RC5/6 Widgets are based on a "State-Machine"...
    (based on a bunch of Widget-Props, which hold that State,...
    and "all that State" is finally influencing the rendering in the internal W_Paint-Event, when triggered by the .Refresh-Method).

    So, if you want to save Widgets (a Widget-Hierarchy, starting from some "Root-, or Parent-Widget"), you will have to:
    - Enumerate all Widgets recursively (starting from a Root-Widget)
    - build (serialize) "a XML- or JSON-Node"-string out of the "internal State" of the currently enumerated Widget
    adding that "String-Result-Node", to a StringBuilder-Object, you pass along in that recursive Enumeration

    And as for the serialization itself, you basically have to do that (in a single, given Widget) -
    for all the Private Vars within that Widget, starting with the one which is "always there" -> W As cWidgetBase.

    1) serialize all "Default-Props" of 'W' (Left, Top, Width, Height, FontName, FontSize, ForeColor,BackColor etc.)
    2) and finally serialize all "selfdefined Private Vars" which you used, to hold additional state

    -----------------------------------------

    That said... the RC5/6 already contains an "Auto-Serializer", based on XML -
    which can be triggered behind any .Widgets-Prop via e.g.: strXML = MyRC6Form.Widgets.SerializeToXML(..., ...)

    The only requirement for that to work properly, is that all of your own Widget-Classes are contained Public in an AX-Dll
    (and not as Private Classes in your Main-Project).

    If that requirement is a problem for you, then you can always "roll your own" serialization,
    as outlined at the beginning of this post.

    Olaf

  5. #5
    Banned
    Join Date
    May 2021
    Posts
    40

    Re: VB6 Cairo-Widgets Tutorial

    Desr Olaf, Thank you very much, As per your guide above, I define sth my self in every obj class, so far the object can be moved, zoomimg , coped and saved as png ,also with the help of imagemagicK command line it can be copy as tranparent bg object similar to MS excel insert graph. It works fine。

    My another3 questions are:
    1)how to lock any one object but allow other objects to move and zoom in the same panel?
    2) Is it possible to group some objects together like excel insert graph?
    3) when I make one object rotate as your post example in vbforums, it can work at first time, then memory problem occured ,how can I do ?

    thanks .
    Last edited by JT870; Jan 4th, 2022 at 12:50 PM.

  6. #6
    Banned
    Join Date
    May 2021
    Posts
    40

    Re: VB6 Cairo-Widgets Tutorial


  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    Re: VB6 Cairo-Widgets Tutorial

    Cannot see (or download) your attachment.

    As for your other questions:
    1) Move-Locks could be done by simply setting MyShape.Widget.Moveable = False
    2) Grouping (using the Widget-Engine) one can do, by placing the grouped Widgets within their own (transparent) Parent-Widget
    3) A link to some code (or your own uploaded Zip-File) would be good

    Olaf

  8. #8
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: VB6 Cairo-Widgets Tutorial

    Hi all, I can't believe I missed this tutorial(?) somehow. As I'm reading it currently, just wondering, since Olaf has updated Cairo so much, it appears that some of the programing is no longer requires a lot of the setouts of the old stuff. Is this same situtation for Widgets too? Like for example, one doesn't need to type this in anymore to make Cairo work. (Great)
    "Public New_c As New cConstructor, Cairo As cCairo"
    I'd like learn more if possible, but I feel like I'm reading something that seems out of date. Does anyone have any updated Widget samples/examples they could share with us plebs?
    Have a Cairo-Random-Auto-Generated Facemaker Maiden for your trouble.
    Name:  Emi Small.jpg
Views: 3354
Size:  83.9 KB

  9. #9
    Addicted Member
    Join Date
    Apr 2017
    Location
    India
    Posts
    235

    Re: VB6 Cairo-Widgets Tutorial

    Dear Olaf,


    Any sample code to tell me how using RC6 I can do the following:
    --
    1. Read the contents of a password protected zip file, in memory? In other words, I should not have the need to unzip the contents anywhere first into the system in order to read the contents. I should be able to do in-memory reading.


    2. On a similar note, how to do in-memory writing? i.e. read the contents of a password-protected in memory, make changes in it and write it back to the zip file. All this to be done without extracting the contents of the zip file anywhere into the system.
    --


    Note-1: I will be creating the password-protected zip file using 7-zip, just in case this info is significant


    Note-2: I searched the forum on 'olaf rc6 zip file', 'olaf rc6 cryptography', etc., etc., but I could not get the right thread where I could ask the above question. Hence, I decided to ask the above question here, in this thread. I will be mighty thankful to get to know one major thread (like the WebView2 thread) where I can ask all NON-webview2 questions (sqlite, cairo, zip/unzip, hash, encyrpt, etc.) in future. Thanks in advance.


    I take this opportunity to once again thank you like anything, Olaf, for all your contributions and wholehearted support at all times.


    Kind Regards.

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    Re: VB6 Cairo-Widgets Tutorial

    Quote Originally Posted by softv View Post
    Any sample code to tell me how using RC6 I can do the following:
    --
    1. Read the contents of a password protected zip file, in memory? In other words, I should not have the need to unzip the contents anywhere first into the system in order to read the contents. I should be able to do in-memory reading.


    2. On a similar note, how to do in-memory writing? i.e. read the contents of a password-protected in memory, make changes in it and write it back to the zip file. All this to be done without extracting the contents of the zip file anywhere into the system.
    --

    Note-1: I will be creating the password-protected zip file using 7-zip, just in case this info is significant
    The RC6-Zip support works in conjunction with the SQLite-Zip-module -
    (where Zip-ByteArrays or Zip-Files can be loaded into, as a "virtual table", which is then "SQL-queryable").

    Though "password-protected Zip-Files" are not supported by this module (but I think wqwetos Zip-class has support for it).

    What you can do though is, to encrypt a "normal Zip file" via your own Encryption-routine -
    (treating it like a "any other unencrypted ByteBuffer") - though then "only your App" will then be able to open an archive, encrypted in this way.

    Crypto- and Hash-support is all contained in the New_c.Crypt-class (e.g. AES and ArcFour Methods are available behind it).

    Quote Originally Posted by softv View Post
    Note-2: I searched the forum on 'olaf rc6 zip file', 'olaf rc6 cryptography', etc., etc., but I could not get the right thread where I could ask the above question. Hence, I decided to ask the above question here, in this thread.

    where I can ask all NON-webview2 questions (sqlite, cairo, zip/unzip, hash, encyrpt, etc.) in future. Thanks in advance.
    As for searches - I use google, along with the "site-modifier"-addition, as e.g.:
    [ site:vbForums.com New_c olaf zip file ]
    Note, that I used New_c instead of the terms RC5 or RC6 - to "catch all code-examples across both versions".

    Well, the above spits out (as the first found link): https://www.vbforums.com/showthread....ontainer-Files

    As for "the correct place, to ask questions"...

    RC5/RC6 is a "commonly used, free available ActiveX-helper" in the meantime -
    so "questions about it" should be treated like questions about "other larger ActiveX-helpers" like e.g. FlexGrid, ADO, DAO etc. -
    and are therefore welcome in the normal (big) VB6-Forum.

    Olaf

  11. #11
    Addicted Member
    Join Date
    Feb 2022
    Posts
    189

    Re: VB6 Cairo-Widgets Tutorial

    This is fantastic, Olaf. Thank you!
    My goal is to replace controls one at a time as time permits on my existing standard forms and VBCCR apps.
    Would you recommend using the ucPanel.ctl to draw widget replacements as I go?
    Cheers
    Last edited by taishan; Apr 26th, 2024 at 06:27 PM.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    Re: VB6 Cairo-Widgets Tutorial

    Quote Originally Posted by taishan View Post
    This is fantastic, Olaf. Thank you!
    My goal is to replace controls one at a time as time permits on my existing standard forms and VBCCR apps.
    Would you recommend using the ucPanel.ctl to draw widget replacements as I go?
    ucPanel.ctl (as a VB6-Control) integrates (as a Widget-Host) best with the VB6-Tab-and-Focus-Handling.

    Though - once you have replaced *all* VB6-Controls on a given VB6-Form with Widgets -
    then you don't need to host them on an "intermediate ucPanel" anymore -
    and can finally replace the VB6-Form with a cWidgetForm-Class
    (which contains a Public WithEvents Form As cWidgetForm - which contains all Widgets).

    Olaf

  13. #13
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    580

    Question Re: VB6 Cairo-Widgets Tutorial

    Hi!
    I love them, thank you.

    However, there is one problem which is extremely time taking:

    VB6 crashes when the IDE is being stopped.
    I have attached a minimalistic sample project.
    Once the timer in the attached sample project tries to divide by zero, and if I press Stop, VB6 freezes, and I need to kill it using the taskmanager.

    Pressing the Stop button is something that I can not avoid, it is an essential feature of an IDE to me.

    Is there a way to fix this?


    Thank you!
    Attached Files Attached Files
    Last edited by tmighty2; Sep 29th, 2024 at 11:19 AM.

  14. #14

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    Re: VB6 Cairo-Widgets Tutorial

    Quote Originally Posted by tmighty2 View Post
    Is there a way to fix this?
    The old ucPanel.ctl based approach is not as "debug-stable" -
    (due to relying on the somewhat "messed up" VBIDE-control-unloading mechanisms) -
    compared to using a cWidgetForm-based Panel (or TopLevel-Form).

    Here is code, which shows how to use the more modern and crash-resistant "Panel As cWidgetForm" approach:
    (also using a cTimer instead of a VB-TimerControl - to keep the hosting VB-Form free of any old Controls).

    Code:
    Option Explicit
    
    Private m_lX&
    Private m_lY&
    Private m_dblButtonWidth As Double
    Private m_dblButtonHeight As Double
    Private m_lBorder As Double
    
    Private WithEvents btnIdle As cwSimpleButton
    Private WithEvents btnWaitingToShrink As cwSimpleButton
    Private WithEvents btnTravel As cwSimpleButton
    Private WithEvents btnShrinking As cwSimpleButton
    Private WithEvents btnClicked As cwSimpleButton
    Private WithEvents btnUnableToShrinkHere As cwSimpleButton
    Private WithEvents btnEnlargingAfterClick As cwSimpleButton
    
    Private WithEvents Panel As cWidgetForm
    Private WithEvents Timer As cTimer
    
    Private Sub Form_Load()
        Set Panel = Cairo.WidgetForms.CreateChild(hWnd)
        Set Timer = New_c.Timer(2000, True)
        
        pCreateControls
    End Sub
    
    Private Sub Form_Resize()
      Panel.Move 0, 0, ScaleWidth, ScaleHeight 'let the panel cover the entire Form-area
    End Sub
    
    Private Sub pCreateControls()
        m_lBorder = 4
        m_dblButtonHeight = 80
        m_dblButtonWidth = 80
    
        Set btnIdle = pAddButton("btnIdle", "Toggle " & Quote("Idle"))
        Set btnWaitingToShrink = pAddButton("btnWaitingToShrink", "Toggle " & Quote("WaitingToShrink"))
        Set btnTravel = pAddButton("btnTravel", "Toggle " & Quote("Travel"))
        Set btnShrinking = pAddButton("btnShrinking", "Toggle " & Quote("Shrinking"))
        Set btnClicked = pAddButton("btnClicked", "Toggle " & Quote("Clicked"))
        Set btnUnableToShrinkHere = pAddButton("btnUnableToShrinkHere", "Toggle " & Quote("UnableToShrinkHere"))
        Set btnEnlargingAfterClick = pAddButton("btnEnlargingAfterClick", "Toggle " & Quote("EnlargingAfterClick"))
        
        Panel.WidgetRoot.LockRefresh = False
    End Sub
    
    Private Function pAddButton(ByVal uName As String, ByVal uText As String) As cwSimpleButton
        Set pAddButton = New cwSimpleButton
            pAddButton.Caption = uText
        
        Panel.Widgets.Add pAddButton, uName, m_lX, m_lY, m_dblButtonWidth, m_dblButtonHeight
        
        m_lX = m_lX + m_dblButtonWidth + m_lBorder
    End Function
    
    Public Function Quote(ByVal u As String) As String
        Quote = ChrW(34) & u & ChrW(34)
    End Function
    
    Private Sub Timer_Timer()
        Dim d As Double
        Dim d2 As Double
        d2 = d / 0
        
        Debug.Print d2
    End Sub
    The blue Lines above, show the changes to your former code...

    Olaf

  15. #15
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    580

    Re: VB6 Cairo-Widgets Tutorial

    Thank you.
    I am in the progress of making a PWA version of my VB6 application. I have now (apart from using this new Panel) completed the transition to RC6 graphics only.
    My app consist of a surface that has different "cells" which can be tapped.
    I am going to use this Panel as cWidgetForm for that, right?

    Is there any additional recommendation that you can share in this where somebody wants to use RC6 for a PWA?

    Thank you!

  16. #16
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    580

    Re: VB6 Cairo-Widgets Tutorial

    I have an anchor class that handles the form resizing.
    It is not absolutely necessary to have this property, but since all controls so far had a .Name property, I would use "Name" for debugging purposes in the class.
    Also, I was referring to objecfs to be anchored as "Control". Here is a link:
    https://www.vbforums.com/showthread....=1#post5654044
    AnchorEx v1.95.zip

    Now that I have switched from usercontrol to Widgetform Panel, I noticed that a WidgetForm does not have a name, and I have to treat it as Object in this anchor class.

    Most times when I notice that RC6 is different than I thought, I later discover that there is a different concept behind that.
    If you find the time to reply:

    Is there more to it than just the .Name property not being there?
    If I have to guess why there is no .Name property then I would say that - being runtime creatures - they would not have names as names are something to clearly identify something, and since the usual development-time checks like double names are not easily available at runtime, you did not implement this property. But that is just a guess.
    Last edited by tmighty2; Oct 3rd, 2024 at 11:24 AM.

  17. #17

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,416

    Re: VB6 Cairo-Widgets Tutorial

    Quote Originally Posted by tmighty2 View Post
    Most times when I notice that RC6 is different than I thought, I later discover that there is a different concept behind that.
    It's not that different as you might think...

    Regarding the "Name"-Prop of VB-Controls - every Widget has a "Key"-Property -
    accessible at runtime via: MyBtn.Widget.Key

    And with that Key(Name) you can go into its Parents Widgets-Collection, to retreive the instance via that Key directly:
    MyParent.Widgets("MyBtnKey")

    So it acts basically the same way as VB6-Ctls, which you can retrieve via the Controls-Collection (by Name).

    Olaf

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width