OEM Branding






4.30/5 (9 votes)
A simple way to produce OEM versions of multi-module products
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 string
s 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 <string>
using namespace std;
#include "build.h"
#include "company.h"
#include "product.h"
/*
* 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
-
Add the three
include
files to your project. -
Add the
include
files to the *.rc file:#define APSTUDIO_READONLY_SYMBOLS //////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" #include "..\include\company.h" #include "..\include\product.h" #include "..\include\build.h" #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
-
Move the entire
VERSIONINFO
section to the *.rc2 file. -
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
-
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
-
Add the brandingutils.h and brandingutils.cpp files to your project. Turn off precompiled headers for the CPP file.
-
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 theCBrandingUtils
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 }
-
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!
