op2_sdk:textdialogbox

In Game Text Dialog Box

The Outpost 2 SDK supports adding custom dialog boxes during single player scenarios. Often dialog boxes are used to provide mission briefings or background story for colony missions. Sierra's odasl library can format dialog boxes to match the Outpost 2 UI theme.

Creating an Outpost themed text dialog box requires the following steps:

  • Write up the briefing/backstory in rich text format (RTF).
  • Add a resource script (.rc) to the project detailing the design of the dialog box.
  • Add a resource header file (typically resource.h) to the project providing a link between the resource script file and the rest of the source code.
  • Include odasl in your project.
  • Add code to the scenario that formats and opens the dialog screen through the windows API.

Rich Text Format documents include metadata such as font and text color which are not available in text (.txt) format. Depending on the program used to open an RTF, the metadata may be hidden. Microsoft Word and Wordpad will default to showing just the text and the effect of the metadata on the text. Notepad or Notepad++ will show all of the metadata.

For campaign mission briefing screens, Outpost 2 uses Arial font size 10 with an RGB of red0\green255\blue0.

Typically, the RTF file is saved as briefing.rtf and added to the root directory of the scenario's project.

Note: Although Microsoft Word can create and save RTF documents, it is not recommended. Microsoft Word adds large amounts of metadata to the document that is not necessary for Outpost 2, typically increasing a small amount of text from about 3 kb to about 50 kb. This file size increase will carry into the compiled DLL.

Example RTF file

{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}}
{\colortbl ;\red0\green255\blue0;}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\cf1\lang9\f0\fs22 Commander,\par
\par
Resources on this planet can no longer support our operations. Our last chance for survival is 
launching a starship before the last resources are depleted. We have established our new base at 
the northern end of Haise Valley. Plymouth has taken control of a mineral rich area 120 kilometers 
outside of the valley and off your local map display. Plymouth also recently established a small, 
secondary mining outpost in the southern part of Haise valley.\par
\par
Both our colony and Plymouth\rquote s colony suffer from the lack of resources. However, 
Plymouth\rquote s colony still has better resource access than our new base. Your orders are to 
construct an evacuation starship for 200 colonists and if possible prevent open warfare with 
Plymouth. So far, we have avoided harsh combat. However, do whatever you must for our survival.\par
\par
Good Luck Commander,\par
Failure is not an option\par
\par
}

Resource script files are text documents describing resources associated with an executable or DLL. These include among other things Version Information, Icons, Cursors, Dialog box descriptions, and Menu Toolbars. Microsoft Visual Studio will auto-generate resource script files.

To add a resource script file and associated resource header:

  • Right click on your project in the solution explorer. → Add → New Item… → Visual C++ → Resource → Resource File (.rc) → Add. (Using the default filename is fine.)

By default resource Scripts are placed in the Resource Files filter in the Solution Explorer. Use the Solution Explorer (or your favorite text editor) to open the file file in text view. You can also access the Resource Script from the Visual Studio Resource View, which defaults to opening on the left side of Visual Studio. The Resource View allows graphical depiction of Dialog Boxes defined in the resource script file. Alternative programs like Resource Hacker can also load Resource Scripts.

Below is a sample resource script file that provides a dialog box before a scenario is initialized. The dialog box will include the contents of briefing.rtf in a rich text box.

For more information on TEXTINCLUDE, see: https://msdn.microsoft.com/en-us/library/6t3612sk.aspx.

Common Pre-processor Directives:

  • #ifdef identifier - If defined directive. Execute the code if the identifier is defined.
  • #ifndef identifier - If not defined directive. Execute the code if the identifier is not defined.
  • #undef identifier - Undefined directive. Removes the definition of an identifier.

Resource Script Sample

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
 
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
 
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
 
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
 
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
 
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
 
IDD_MISSIONINFO DIALOGEX 0, 0, 282, 250
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_POPUP | 
      WS_VISIBLE | WS_CAPTION
CAPTION "MISSION INFO"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
    DEFPUSHBUTTON   "&CONTINUE",IDOK,75,230,130,15
    CONTROL         "",IDC_TEXTAREA,"RICHEDIT",TCS_HOTTRACK | TCS_RAGGEDRIGHT | TCS_MULTISELECT | 
                    WS_BORDER | WS_VSCROLL | WS_TABSTOP,5,5,270,220
END
 
 
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
 
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_MISSIONINFO, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 275
        TOPMARGIN, 7
        BOTTOMMARGIN, 243
    END
END
#endif    // APSTUDIO_INVOKED
 
 
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
 
1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END
 
2 TEXTINCLUDE 
BEGIN
    "#include ""winres.h""\r\n"
    "\0"
END
 
3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END
 
#endif    // APSTUDIO_INVOKED
 
 
/////////////////////////////////////////////////////////////////////////////
//
// TEXT
//
 
IDR_MISSIONTEXT         TEXT                    "briefing.rtf"
 
 
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
 
IDD_MISSIONINFO AFX_DIALOG_LAYOUT
BEGIN
    0
END
 
 
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
 
VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,0
 PRODUCTVERSION 1,3,0,5
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x0L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "CompanyName", "Outpost Universe"
            VALUE "FileDescription", "Plymouth Colony Game Starting over"
            VALUE "FileVersion", "1.0.0.0"
            VALUE "InternalName", "cOver.dll"
            VALUE "LegalCopyright", "Copyright (C) 2016"
            VALUE "OriginalFilename", "cOver"
            VALUE "ProductName", "Outpost 2"
            VALUE "ProductVersion", "1.3.0.5"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END
 
#endif    // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
 
 
 
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
 
 
/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

Once the Resource Script is added, the project will not successfully compile until all required items are defined in the resource header. Visual Studio will automatically create a resource header when the resource script is created. Typically, 5 items are defined in resource script as shown in the sample below, IDRMISSIONTEXT, IDBPIC, IDDMISSIONINFO, IDCTEXTAREA, and IDC_PIC. These values are represented in the resource script.

Microsoft Resource Naming and Numbering Conventions can be reviewed here: https://msdn.microsoft.com/en-us/library/t2zechd4.aspx.

ID Prefix Naming Conventions

PrefixUseRecommended Range
IDBBitmap resource101 through 0x6FFF
IDCCommand identifier, cursor, or control101 through 0x6FFF
IDDDialog box resource101 through 0x6FFF
IDIIcon resource101 through 0x6FFF
IDRMultiple resource types, possibly common to an entire application or window101 through 0x6FFF
IDSString resource101 through 0x7FFF

Note: 0x prefix on a number indicates it is in hexadecimal form.

Resource Header Example

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Resource.rc
//
#define IDR_MISSIONTEXT                 102
#define IDB_PIC                         104
#define IDD_MISSIONINFO                 907
#define IDC_TEXTAREA                    1001
#define IDC_PIC                         -1
 
// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        105
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1005
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

Once the resource script and resource header have been included, the briefing screen must be initialized from the code. You will also have to include the Sierra library odasl in your project to ensure the dialog is formatted similar to other Outpost 2 menus.

  • Add a reference to the Outpost2Dialog project, which can be found with the rest of the APIs. odasl.h and odasl.lib are contained in this project and are required to skin the Dialog Window in the Outpost 2 theme.
  • Create a reference to the DLL instance from DllMain (HINSTANCE hInst).
  • Add code to initialize and open the window. Typically this code is placed in it's own cpp file named briefing.cpp.
  • Call code to initialize the window from InitiProc.

Defining a handle to the DLL instance from DllMain:

DllMain.cpp

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
 
// Used by the scenario briefing screen.
HINSTANCE hInst;
 
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	if (fdwReason == DLL_PROCESS_ATTACH)
	{
		DisableThreadLibraryCalls(hinstDLL);
		hInst = hinstDLL;
	}
 
	return TRUE;
}

Code used to initialize window. This also may be written without a header file.

briefing.h

#pragma once
 
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
 
#include <richedit.h>
#include "resource.h"
#include "odasl\odasl.h"
 
void ShowBriefing();
LRESULT CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

briefing.cpp

#include "Briefing.h"
 
extern HINSTANCE hInst;
 
// Briefing source code is pulled from Plymouth Cold War Scenario and was written by BlackBox.
void ShowBriefing()
{
	// OP2 turns off the skinning before the game loads.
	// We have to re-enable it (otherwise the briefing box will look ugly).
	wplEnable();
	// Show the dialog box, using the shell window as the parent
	HWND shellWnd = FindWindow("Outpost2Shell", NULL);
	DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MISSIONINFO), shellWnd, (DLGPROC)DialogProc, NULL);
	// Turn off the skinning again (probably not needed but a good idea to do it anyway)
	wplDisable();
}
 
LRESULT CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HRSRC txtRes = NULL;
	HWND richEdit = NULL;
	switch (msg)
	{
	case WM_INITDIALOG:
		// Make the BG black in the rich edit box
		richEdit = GetDlgItem(hWnd, IDC_TEXTAREA);
		SendMessage(richEdit, EM_SETBKGNDCOLOR, 0, 0);
 
		// Find the text resource
		txtRes = FindResource(hInst, MAKEINTRESOURCE(IDR_MISSIONTEXT), "TEXT");
		if (txtRes)
		{
			// Load it
			HGLOBAL resHdl = LoadResource(hInst, txtRes);
			if (resHdl)
			{
				// Lock it and set the text
				char *briefing = (char*)LockResource(resHdl);
				if (briefing)
				{
					SetDlgItemText(hWnd, IDC_TEXTAREA, briefing);
					return TRUE;
				}
			}
		}
		SetDlgItemText(hWnd, IDC_TEXTAREA, "Error: Mission text could not be loaded.");
		return TRUE;
	case WM_COMMAND:
		if (wParam == IDOK)
		{
			EndDialog(hWnd, IDOK);
			return TRUE;
		}
		return FALSE;
	}
	return FALSE;
}

- Go Back to Programming a Scenario
- Go Back to Outpost 2 Mapmaking
- Go Back to Outpost 2 Main page
- Go Back to Wiki Home Page

  • op2_sdk/textdialogbox.txt
  • Last modified: 2016/12/28 19:03
  • by vagabond