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 <string>
using namespace std;
#include "build.h"
#include "company.h"
#include "product.h"
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
#include "afxres.h"
#include "..\include\company.h"
#include "..\include\product.h"
#include "..\include\build.h"
#ifdef APSTUDIO_INVOKED
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 the CBrandingUtils to replace the embedded keywords with the desired text.
BOOL CBrandingDemoDlg::OnInitDialog() {
CDialog::OnInitDialog();
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);
}
}
SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE); m_brandingUtils.Put_PRODUCT_NAME_InTitle(GetSafeHwnd());
return TRUE; }
-
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
Web Developer
United States
Member
|
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.
|