Click here to Skip to main content
Click here to Skip to main content

OEM Branding

By , 1 Nov 2006
Rate this:
Please Sign up or sign in to vote.

Introduction

I find that OEM 'branding' is still a lot of trouble. I needed a simple way to produce OEM versions of multi-module products. Resources like graphics and icons are easy enough to deal with but the VERSIONINFO structures and embedded strings like the 'product name' are a hassle. Following is a simple method I have used for years to help ease things.

This method uses three header files (build.h, company.h, and product.h) and an object called CBrandingUtils that is defined in brandingutils.h and brandingutils.cpp.

(build.h)

#define BUILD_NUMBER "1"

(company.h)

#define LEGAL_COPYRIGHT                "Copyright © 2006"
#define LEGAL_COMPANY_NAME             "PlanetHarrington, Inc."
#define LEGAL_RIGHTS                   "All rights reserved."
#define LEGAL_FULL_COPYRIGHT           "Copyright © 2006 PlanetHarrington, Inc. 
                                        All rights reserved."
#define SIMPLE_COMPANY_NAME            "PlanetHarrington"
#define COMPANY_CONTACT_URL            "http://www.planetharrington.com"

(product.h)

#define PRODUCT_NAME                   "BrandingDemo"
#define PRODUCT_VERSION                "1.0"
#define PRODUCT_TRADEMARKS             "BrandingDemo is a trademark of PlanetHarrington."
#define PRODUCT_VSTRUCT_VERSION        "1,0,0,0"
#define PRODUCT_VSTRUCT_VERSION_PART1   1
#define PRODUCT_VSTRUCT_VERSION_PART2   0
#define PRODUCT_VSTRUCT_VERSION_PART3   0
#define PRODUCT_VSTRUCT_VERSION_PART4   0

(brandingutils.h)

#pragma once

#include <span class="code-keyword"><string></span>
using namespace std;
#include <span class="code-string">"build.h"</span>
#include <span class="code-string">"company.h"</span>
#include <span class="code-string">"product.h"</span>

/*
 * CBrandingUtils provides methods that work in conjunction with the
 * definitions from the 'build.h', 'company.h', and 'product.h' files.
 */
class CBrandingUtils
{
public:
    CBrandingUtils(){};
    virtual ~CBrandingUtils(){};

    HRESULT Put_COMPANY_NAME_InControl(HWND, UINT);
    HRESULT Put_PRODUCT_NAME_InControl(HWND, UINT);
    HRESULT Put_PRODUCT_VERSION_InControl(HWND, UINT);
    HRESULT Put_BUILD_NUMBER_InControl(HWND, UINT);
    HRESULT Put_COPYRIGHT_InControl(HWND, UINT);
    HRESULT Put_COMPANY_CONTACT_URL_InControl(HWND, UINT);
    HRESULT Put_RIGHTS_InControl(HWND, UINT);
    HRESULT Put_FULL_COPYRIGHT_InControl(HWND, UINT);
    HRESULT Put_FULL_COMPANY_NAME_InControl(HWND, UINT);
    HRESULT Put_PRODUCT_NAME_InTitle(HWND, bool bPropPage = false);
    HRESULT ReplaceStringWithString(wstring&, LPCTSTR, LPCTSTR);
    HRESULT ReplaceStringWithStringInCtrl(LPCTSTR, LPCTSTR, HWND, UINT);
};

Most developers will want to modify the CBrandingUtils methods and constants to suit their particular needs.

Using

1. Using with a VERSIONINFO Resource

  1. Add the three include files to your project.

  2. Add the include files to the *.rc file:

    #define APSTUDIO_READONLY_SYMBOLS
    ////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include <span class="code-string">"afxres.h"</span>
    #include <span class="code-string">"..\include\company.h"</span>
    #include <span class="code-string">"..\include\product.h"</span>
    #include <span class="code-string">"..\include\build.h"</span>
            
    #ifdef APSTUDIO_INVOKED
    ////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "#include ""..\\include\\company.h""\r\n"
        "#include ""..\\include\\product.h""\r\n"
        "#include ""..\\include\\build.h""\r\n"
        "\0"
    END
  3. Move the entire VERSIONINFO section to the *.rc2 file.

  4. Use the desired macros:

      VS_VERSION_INFO VERSIONINFO
      FILEVERSION 1,0,0,1
      PRODUCTVERSION PRODUCT_VSTRUCT_VERSION_PART1,PRODUCT_VSTRUCT_VERSION_PART2,
          PRODUCT_VSTRUCT_VERSION_PART3,PRODUCT_VSTRUCT_VERSION_PART4
      FILEFLAGSMASK 0x3fL
     #ifdef _DEBUG
      FILEFLAGS 0x1L
     #else
      FILEFLAGS 0x0L
     #endif
      FILEOS 0x4L
      FILETYPE 0x1L
      FILESUBTYPE 0x0L
     BEGIN
         BLOCK "StringFileInfo"
         BEGIN
             BLOCK "040904e4"
             BEGIN
             VALUE "CompanyName", LEGAL_COMPANY_NAME
             VALUE "FileDescription", "Branding Demonstration"
             VALUE "FileVersion", "1.0.0.1"
             VALUE "InternalName", "brandingdemo.exe"
             VALUE "LegalCopyright", LEGAL_FULL_COPYRIGHT
             VALUE "OriginalFilename", "brandingdemo.exe"
             VALUE "ProductName", PRODUCT_NAME
             VALUE "ProductVersion", PRODUCT_VSTRUCT_VERSION
             VALUE "SpecialBuild", BUILD_NUMBER
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1252
     END
    END
  5. Check the results after building by opening the 'Properties' dialog for the deliverable using Explorer, selecting the "Version" tab, and confirming that the information displayed is correct.

2. Using with Code in a Dialog Object

  1. Add the brandingutils.h and brandingutils.cpp files to your project. Turn off precompiled headers for the CPP file.

  2. Include the CBrandingUtils.h file in your source file and declare an instance of a CBrandingUtils object. Use the definitions in the three header files along with the methods in the CBrandingUtils to replace the embedded keywords with the desired text.

    BOOL CBrandingDemoDlg::OnInitDialog() {
        CDialog::OnInitDialog();
    
        // Add "About..." menu item to system menu.
        
        // IDM_ABOUTBOX must be in the system command range.
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL) {
            CString strAboutMenu;
            strAboutMenu.LoadString(IDS_ABOUTBOX);
            wstring strReplace = strAboutMenu;
            if(SUCCEEDED(m_brandingUtils.ReplaceStringWithString
                (strReplace, TEXT("_PRODUCT_NAME_"), TEXT(PRODUCT_NAME)))) {
            strAboutMenu = strReplace.c_str();
        }
                        
        if (!strAboutMenu.IsEmpty()) {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }
    
        // Set the icon for this dialog.  The Framework does this automatically
        //  when the application's main window is not a dialog
        SetIcon(m_hIcon, TRUE);         // Set big icon
        SetIcon(m_hIcon, FALSE);        // Set small icon
        m_brandingUtils.Put_PRODUCT_NAME_InTitle(GetSafeHwnd());
    
        return TRUE;  // return TRUE  unless you set the focus to a control
    }
  3. Check out brandingdemDlg.h and BrandingdemDlg.cpp for a complete example.

Demo Project

The demo project download includes all the required files and a Visual Studio 7 project. The project output is both a branded application and a test harness for the CBrandingUtils object. Run the application and note the application title and About Box information. Change the definitions in the three header files, recompile, and run again and check for your changes. Add another module to the solution and implement the branding in it to see how easy it is to change version information for both of the modules.

Summary

If I left out any details you think should be mentioned in the article, please let me know.

If you could take one last second to rate this article or even leave a comment, it would be much appreciated.

Thanks for reading!

Shaun Harrington

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shaun Harrington
Web Developer
United States United States
16yrs of GUI programming experience gained at: (most recent first) BlackBall, Veritas, Seagate Software, Arcada, Stac, Mountain, and Emerald Systems.
 
Languages/Scripting: C, C++, JAVA, BASIC, JAVASCRIPT, HTML, XML, PHP, and SQL
 
Tools: MS Visual Studio, MS Visual SourceSafe, CVS, PVCS, Bounds Checker, VMWare, ToDoList, InstallShield, and Office Applications
 
Libraries and API: RTL, STL, WIN32, MFC, ATL, .NET, ActiveX, DirectX, COM, DCOM, Shell Extensions, and Shell Namespaces
 
Strengths: Honest, communicative, keen eye for usability, good at estimating workload and completion dates, ready to take on grunt work, team player, experienced working with QA, localization, Tech Pubs, Sales, and Marketing teams.

Comments and Discussions

 
GeneralMinor issue PinmemberWes Aday3-Nov-06 7:43 
GeneralRe: Minor issue PinmemberShaun Harrington3-Nov-06 9:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140421.2 | Last Updated 1 Nov 2006
Article Copyright 2006 by Shaun Harrington
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid