Results 1 to 4 of 4

Thread: How I migrated my project to VBCCR

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jul 2016

    How I migrated my project to VBCCR

    I have a large, several year old project with many forms and thousands of widgets. I wanted to use Kr00l's VB Common Controls Replacement, so I looked for the quickest solution, and came up with one. This article explains how I did it, so that you can easily do the same. Essentially, it explains not only how to install and use VBCCR, but also how to convert an existing project to use it.

    I do my VB6 development from a Windows XP virtual machine running in a Linux host.

    My source code lies a git repository on the Linux host (so I don't have to worry about Windows XP causing file corruption when it crashes). The repo folder structure looks like this:
    The source-code version of VBCCR ("StdEXE") requires being compiled, the same as any other code, which takes time as it's a big project. Since I as a developer compile my program hundreds of times a day as I code and test, I want to avoid this overhead. Therefore, I want to use the ActiveX (OCX) version, because it's pre-compiled. The run-time dependency is only 1 file, VBCCR16.OCX, which needs to be placed alongside your program's executable on the user's machine - something easily done in the installer (I use NSIS).

    For the purpose of this document, we will assume that your project resides in ~/repo/

    The first few steps deal with "installing" VBCCR, applicable to everyone. The last few steps deal with migrating your existing project from MS to VBCCR. This is dangerous and carries a high risk of death, so let's get started.

    To start using VBCCR in an existing project:
    1. Get VBCCR, and optionally VBFLXGRD. Just clone these git repositories to anywhere outside of your own project's repo:
      git clone ~/code-vbccr
      git clone ~/code-vbflxgrd
    2. Copy the required VBCCR (and VBFLXGRD) files into your project's repository, into the dependencies folder, so that you and other developers working on your project can just clone your repo and have all the required files without needing to download and figure out the confusing VBCCR structure:
      cp ~/code-vbccr/"ActiveX Control Version"/Bin/VBCCR16.OCX ~/repo/src/deps/
      cp ~/code-vbccr/"ActiveX Control Version"/Common/Common.bas ~/repo/src/deps/
      cp ~/code-vbccr/"ActiveX Control Version"/OLEGuids/OLEGuids.tlb ~/repo/src/deps/
      cp ~/code-vbflxgrd/"ActiveX Control Version"/Bin/VBFLXGRD13.OCX ~/repo/src/deps/
    3. To enable your program to find the OCX file alongside the executable when you ship it to users, you need to use a manifest file. A "resource" file which includes the manifest file is available in the first post of the "[VB6] ActiveX CommonControls (Replacement of the MS common controls)" thread:
      Download VBCCR16SideBySideAndVisualStyles.res and add it to your repo:
      cp VBCCR16SideBySideAndVisualStyles.res ~/repo/src/res/
      Open your project in the VB6 IDE, go to Project > Add File (shortcut Ctrl+D), and browse for VBCCR16SideBySideAndVisualStyles.res.
    4. Go to Project > Components (shortcut Ctrl+T) and browse for VBCCR16.OCX. "VB Common Controls Replacement 1.6 Library" appears.
      Done, VBCCR16 is "installed". Now you're ready to start using VBCCR widgets. But you still need to migrate the controls in your project from the MS stuff to VBCCR stuff, so read on.
    5. Optional. The source-code "StdEXE" version requires that you, the programmer, register OLEGuids.tlb on your system. This is only needed by you the programmer, not by the user. You don't need it at all for the ActiveX version. Should you wish to use the StdEXE version at some point, just copy ~/repo/src/deps/OLEGuids.tlb to c:\windows\system32 and register it (using regtlib):
      cd windows\system32
      regtlib OLEGuids.tlb
      Then in the VB6 IDE and go to Project > References and browse for c:\windows\system32\OLEGuids.tlb
    6. Add new files and commit outstanding changes, or backup if you don't use a version-control system like git (you should).
      git add -A
      git commit -a -m "Preparing for VBCCR"
    7. Now you will migrate your existing widgets (controls) from Microsoft Windows Common Controls(-2) 6.0 to VBCCR. This will be done by using sed to replace every occurrence of an MS class with its VBCCR counterpart, in every form. Through trial-and-error I found that some properties in the form code need to be blasted otherwise you won't be able to open the form in the IDE afterwards. In my case, these properties didn't matter - e.g. a few TextBoxes referenced text in the .frx binary blob, and I couldn't care less about blasting it as this was just some lorem ipsum placeholder text - the real text in my program is set at run-time.
      Close the VB6 IDE. Open a terminal, navigate to your repo, and run this sed script:
      sed -i -E \
          -e "s/(Begin[[:blank:]]+)MSComCtl2.DTPicker([[:blank:]]+)/\1VBCCR16.DTPicker\2/" \
          -e "s/(Begin[[:blank:]]+)MSComCtl2.MonthView([[:blank:]]+)/\1VBCCR16.MonthView\2/" \
          -e "s/(Begin[[:blank:]]+)MSComCtl2.UpDown([[:blank:]]+)/\1VBCCR16.UpDown\2/" \
          -e "s/(Begin[[:blank:]]+)MSComctlLib.ListView([[:blank:]]+)/\1VBCCR16.ListView\2/" \
          -e "s/(Begin[[:blank:]]+)MSComctlLib.ProgressBar([[:blank:]]+)/\1VBCCR16.ProgressBar\2/" \
          -e "s/(Begin[[:blank:]]+)MSComctlLib.Slider([[:blank:]]+)/\1VBCCR16.Slider\2/" \
          -e "s/(Begin[[:blank:]]+)MSComctlLib.TreeView([[:blank:]]+)/\1VBCCR16.TreeView\2/" \
          -e "s/(Begin[[:blank:]]+)RichTextLib.RichTextBox([[:blank:]]+)/\1VBCCR16.RichTextBox\2/" \
          -e "s/(Begin[[:blank:]]+)VB.CheckBox([[:blank:]]+)/\1VBCCR16.CheckBoxW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.ComboBox([[:blank:]]+)/\1VBCCR16.ComboBoxW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.CommandButton([[:blank:]]+)/\1VBCCR16.CommandButtonW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.Frame([[:blank:]]+)/\1VBCCR16.FrameW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.Label([[:blank:]]+)/\1VBCCR16.LabelW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.ListBox([[:blank:]]+)/\1VBCCR16.ListBoxW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.OptionButton([[:blank:]]+)/\1VBCCR16.OptionButtonW\2/" \
          -e "s/(Begin[[:blank:]]+)VB.TextBox([[:blank:]]+)/\1VBCCR16.TextBoxW\2/" \
          -e "s/BeginProperty Font.*/BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}\r/" \
          -e "/[[:blank:]]+StartOfWeek[[:blank:]]+=[[:blank:]]+[[:digit:]]+/d" \
          -e "/[[:blank:]]+Text[[:blank:]]+=.*\.frx/d" \
    8. Open your project in the VB6 IDE, and open each form to make sure it works. In my large project, the above steps work, and the forms open correctly using VBCCR.
      But your code is different, and you might be using controls I wasn't. If there is a problematic left-over in a .frm file, it will cause errors like this when you try to open the form:
      Run-time error '713':
      Class not registered.
      Name:  screenshot_20200113_190329.png
Views: 414
Size:  4.7 KB
      In typical Microsoft fashion, the error message tells us nothing.
      If you try to re-open the form, you could get this:
      Run-time error '429':
      ActiveX component can't create object
      Name:  screenshot_20200113_190431.png
Views: 404
Size:  5.3 KB
      If that's the case, revert to your previous commit (git reset --hard HEAD) (or backup) and have fun going through the .frm code looking for what might be the problem. Notice that something as innocent-looking as StartOfWeek = 16187393 was one of the culprits, that's why the sed script deleted all instances of that.
      Note: I did not need to delete any .frx files, and I did not lose any pictures/images in graphical controls in the process.
    9. Before you can compile your code, you will also need to update every control object which uses MS classes to the VBCCR16 class, for example:
      -    Dim n As Node
      +    Dim n As VBCCR16.TvwNode
      The following sed script does just that:
      sed -i -E \
          -e "s/InitVisualStyles/InitVisualStylesFixes/" \
          -e "s/ As Frame([,|\r])/ As VBCCR16.FrameW\1/" \
          -e "s/ As Label/ As VBCCR16.LabelW/" \
          -e "s/ As TextBox/ As VBCCR16.TextBoxW/" \
          -e "s/ As CheckBox/ As VBCCR16.CheckBoxW/" \
          -e "s/ As ComboBox/ As VBCCR16.ComboBoxW/" \
          -e "s/(TreeView_NodeClick.*)( As MSComctlLib.Node\))/\1 As VBCCR16.TvwNode, ByVal Button As Integer)/" \
          -e "s/ As (MSComctlLib.)?Node/ As VBCCR16.TvwNode/" \
          -e "s/ As ListView/ As VBCCR16.ListView/" \
          -e "s/(ListView_ItemClick.*)( As MSComctlLib.ListItem\))/\1 As VBCCR16.LvwListItem, ByVal Button As Integer)/" \
          -e "s/(ListView_ItemCheck.*)( As MSComctlLib.ListItem\))/\1 As VBCCR16.LvwListItem, ByVal Checked As Boolean)/" \
          -e "s/(ListView_[[:alnum:]]+LabelEdit.*)Cancel As Integer/\1Cancel As Boolean/" \
          -e "s/ As (MSComctlLib.)?ListItem/ As VBCCR16.LvwListItem/" \
          -e "s/ As ListSubItem/ As VBCCR16.LvwListSubItem/" \
          -e "s/\.FontBold /.Font.Bold /" \
          -e "s/\.FontSize /.Font.Size /" \
          -e "s/ As MSComctlLib.ColumnHeader/ As VBCCR16.LvwColumnHeader/" \
          -e "s/lvwAutomatic/LvwLabelEditAutomatic/" \
          -e "s/lvwColumn/LvwColumnHeaderAlignment/" \
          -e "s/rtfRTF/RtfLoadSaveFormatRTF/" \
          -e "s/rtfLeft/RtfSelAlignmentLeft/" \
          -e "s/rtfRight/RtfSelAlignmentRight/" \
          -e "s/rtfCenter/RtfSelAlignmentCenter/" \
          -e "s/lvwAscending/LvwSortOrderAscending/g" \
          -e "s/lvwDescending/LvwSortOrderDescending/g" \
          -e "s/tvwChild/TvwNodeRelationshipChild/g" \
          src/forms/*.frm src/modules/*.bas
      I wrote the above script based on the controls, properties and methods used in my project - your project might use ones than mine did not, so you may have to make some code changes from within the VB6 IDE. After running the script, open your project in the VB6 IDE, run it with a full compile (shortcut Ctrl+F5), and see if anything fails - some things might fail while compiling, while other things might fail only once you run the program and use a feature which calls that specific bit of code. If something fails, you can fix it using Ctrl+H in the IDE, e.g. to replace ".FontItalic " with ".Font.Italic ".
    10. If every form opens correctly and your project compiles and runs successfully, then fire up Project > Components and remove those wretched Microsoft Windows Common Controls(-2) 6.0.
      Ahh, just look at that diff:
      -Object={3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0; richtx32.ocx
      -Object={831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0; mscomctl.ocx
      -Object={86CF1D34-0C5F-11D2-A9FC-0000F8754DA1}#2.0#0; mscomct2.ocx
      For reference, your final .vbp file should contain:
      Object={0DF5D14C-08DD-4806-8BE2-B59CB924CFC9}#1.7#0; VBCCR16.OCX
      Module=Common; deps\Common.bas
      Module=VisualStyles; deps\VisualStyles.bas
    Last edited by OldClock; Jan 27th, 2020 at 08:39 AM.

  2. #2
    Addicted Member
    Join Date
    Feb 2015
    Colorado USA

    Re: How I migrated my project to VBCCR

    Did you know that the documentation/update utility will do the last step for you and remove the dependency on the .OCX from your final .EXE file and make it smaller because it only uses VBCCR controls in your project that you actually use? Take a look at here on vbForums. You've done the hard part by converting your project away from MS controls and now you can remove that final dependency.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jul 2016

    Re: How I migrated my project to VBCCR

    I updated step 9 in my first post with the bit about changing references in the code to use VBCCR, e.g. replacing all instances of " As Label" with " As VBCCR16.LabelW".

    Anyone interested in learning more should read MountainMan's documentation.
    Last edited by OldClock; Jan 20th, 2020 at 09:53 AM.

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Jul 2016

    Re: How I migrated my project to VBCCR

    Updating your project from VBCCR16 to VBCCR17:

    1. Update your clone of VBCCR:
      cd ~/code-vbccr
      git pull
    2. Copy the new VBCCR17 files into your project's repository:
      cp ~/code-vbccr/"ActiveX Control Version"/Bin/VBCCR17.OCX ~/repo/src/deps/
      cp ~/code-vbccr/"ActiveX Control Version"/Common/Common.bas ~/repo/src/deps/
    3. Go to the "[VB6] ActiveX CommonControls (Replacement of the MS common controls)" thread:
      Download VBCCR17SideBySideAndVisualStyles.res and add it to your repo:
      cp VBCCR17SideBySideAndVisualStyles.res ~/repo/src/resources/
      Open your project in the VB6 IDE and delete VBCCR16SideBySideAndVisualStyles.res from the Project Explorer (shortcut Ctrl+R). Also delete that file from your resources folder. Then go to Project > Add File (shortcut Ctrl+D), and add VBCCR17SideBySideAndVisualStyles.res.
    4. Go to Project > Components (shortcut Ctrl+T) and browse for VBCCR17.OCX to add "VB Common Controls Replacement 1.7 Library".
    5. Before running sed commands in the next step, commit progress so that you can revert in case things go wrong:
      git add -A
      git commit -a -m "Updating to VBCCR17 WIP"
    6. Now you will update references and GUIDs to the new ones used by VBCCR17:
      sed -i -E \
          -e "s/\{0DF5D14C-08DD-4806-8BE2-B59CB924CFC9\}#1.7#0/\{7020C36F-09FC-41FE-B822-CDE6FBB321EB\}#1.0#0/" \
          -e "s/VBCCR16/VBCCR17/g" \
          src/*.vbp src/forms/*.frm src/modules/*.bas src/usercontrols/*.ctl
    7. Review changes:
      git diff
    8. Test that everything works. Compile the project and run it. If everything seems correct then delete ~/repo/src/deps/VBCCR16.OCX.
    9. If all is good, commit:
      git add -A
      git commit -a -m "Updated to VBCCR17"

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