12 April 2012

Ocx background color

Not all OCX controls support a .BackColor property to change the background color, although the control itself allows changing it. Here GB32 conforms to VB too much. Rather than adding a property to the implementation – which would require another patch in executable code – we can use a different approach.

All OCX controls share a user-defined structure to store the current settings of the wrapped control. Setting and getting property values is sometimes nothing more than changing and setting a member of the structure. Setting and obtaining the background value is one of them. The BackColor property stores its value in the member at offset $B8 of the start of object’s data block. The following code changes the background of a StatusBar Ocx.

Form frm1
Ocx StatusBar sb1
Trace SetBkColorControl(sb1, RGB(23, 56, 229))
Do
  Sleep
Until Me Is Nothing

Function SetBkColorControl(Ctrl As Control, Color As Long) As Long
  Const OffBackColor = $B8
  Local Long ObjPtr  = Long{*Ctrl}
  SetBkColorControl  = Long{ObjPtr + OffBackColor}
  {ObjPtr + OffBackColor} = Color
  ~InvalidateRect(Ctrl.hwnd, 0, 1)

  ' Notes
  ' 1 Using the IDispatch interface does not work
  '   when the GetTypeInfo doesn't support the
  '   the .BackColor property.
  ' BackColor is not a property of StatusBar
  If 0 Then Ctrl.BackColor = Color

  ' 2 When using XP Visual Themes the Visual Style
  '   theme takes over and gets precedence over
  '   GB OCX propery settings.
EndFunc

Note – Not all controls let their background set this way. Just experiment. 

03 April 2012

ImageList error signals missing manifest

When an application adds an Ocx ImageList to a Form using the Form-Editor an error might occur after compilation to EXE.

When the EXE is started the application stops executing displaying an ImageList loading error. This error occurs when the application is developed using a GfaWin32.Exe.manifest file. The manifest file forces the executable (named in its file name) to use the newer comctl32.dll version 6.x to apply more appealing visual styles. This DLL contains an updated load and save function for Image List common controls. When your application is compiled to a stand-alone the ImageList data is saved within the EXE using the ImageList_Write() API from the comctl32.dll version 6. Now when you launch the stand-alone EXE without a reference to the newer common control DLL, the ImageList_Read() from the older DLL is used. And, well… these functions are not compatible.

After compiling an application to a stand-alone EXE, a manifest file for the stand-alone EXE must be included, otherwise the executable will start without using the newer comctl32.dll. So, if you name your application “myapp.exe” you must include a “myapp.exe.manifest” file along with the EXE. You can easily copy the GfaWin32.exe.manifest file to the application’s directory and rename it by replacing the first part to the name of your application. A GB32 project would then include the following files:

myapp.g32
myapp.exe
myapp.exe.manifest

Note - It doesn’t hurt to include a manifest file for systems that don’t support comctl32 version 6.