- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
331 lines
7.9 KiB
C++
331 lines
7.9 KiB
C++
//----------------------------------------------------------------------------
|
|
// ObjectWindows
|
|
// (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
|
|
//
|
|
// Implementation of TComboBox & TComboBoxData.
|
|
//----------------------------------------------------------------------------
|
|
#pragma hdrignore SECTION
|
|
#include <owl/owlpch.h>
|
|
#include <owl/combobox.h>
|
|
#include <cstring.h>
|
|
|
|
#if !defined(SECTION) || SECTION == 1
|
|
|
|
//
|
|
// constructor for a TComboBoxData object
|
|
//
|
|
TComboBoxData::TComboBoxData()
|
|
:
|
|
Strings(10, 0, 10),
|
|
ItemDatas(10, 0, 10)
|
|
{
|
|
SelIndex = 0;
|
|
}
|
|
|
|
//
|
|
// destructor for TComboBoxData
|
|
//
|
|
TComboBoxData::~TComboBoxData()
|
|
{
|
|
}
|
|
|
|
//
|
|
// adds the supplied string to the "Strings" array and copies it into
|
|
// "Selection" if "isSelected" is true
|
|
//
|
|
void
|
|
TComboBoxData::AddString(const char* str, bool isSelected)
|
|
{
|
|
Strings.Add(str);
|
|
if (isSelected)
|
|
Select(Strings.GetItemsInContainer()-1);
|
|
}
|
|
|
|
void
|
|
TComboBoxData::AddStringItem(const char* str, uint32 itemData, bool isSelected)
|
|
{
|
|
ItemDatas.Add(itemData);
|
|
AddString(str, isSelected);
|
|
}
|
|
|
|
//
|
|
// selects an item at a given index.
|
|
//
|
|
void
|
|
TComboBoxData::Select(int index)
|
|
{
|
|
if (index != CB_ERR) {
|
|
SelIndex = index;
|
|
if (index < Strings.GetItemsInContainer())
|
|
Selection = Strings[index];
|
|
}
|
|
}
|
|
|
|
//
|
|
// selects "str", marking the matching String entry (if any) as selected
|
|
//
|
|
void
|
|
TComboBoxData::SelectString(const char far* str)
|
|
{
|
|
int numStrings = Strings.GetItemsInContainer();
|
|
SelIndex = CB_ERR;
|
|
for (int i = 0; i < numStrings; i++)
|
|
if (strcmp(Strings[i].c_str(), str) == 0) {
|
|
SelIndex = i;
|
|
break;
|
|
}
|
|
if (Selection != str)
|
|
Selection = str;
|
|
}
|
|
|
|
//
|
|
// returns the length of the selection string excluding the terminating 0
|
|
//
|
|
int
|
|
TComboBoxData::GetSelStringLength() const
|
|
{
|
|
return Selection.length();
|
|
}
|
|
|
|
//
|
|
// copies the selected string into Buffer. BufferSize includes the terminating 0
|
|
//
|
|
void
|
|
TComboBoxData::GetSelString(char far* buffer, int bufferSize) const
|
|
{
|
|
if (bufferSize > 0) {
|
|
strncpy(buffer, Selection.c_str(), bufferSize-1);
|
|
buffer[bufferSize - 1] = 0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
//
|
|
// constructor for a TComboBox object
|
|
//
|
|
// by default, an MS-Windows combobox associated with the TComboBox will have
|
|
// a vertical scrollbar and will maintain its entries in alphabetical order
|
|
//
|
|
TComboBox::TComboBox(TWindow* parent,
|
|
int id,
|
|
int x, int y, int w, int h,
|
|
uint32 style,
|
|
uint textLen,
|
|
TModule* module)
|
|
:
|
|
TListBox(parent, id, x, y, w, h, module)
|
|
{
|
|
TextLen = textLen;
|
|
Attr.Style = WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP |
|
|
CBS_SORT | CBS_AUTOHSCROLL | WS_VSCROLL | style;
|
|
}
|
|
|
|
TComboBox::TComboBox(TWindow* parent,
|
|
int resourceId,
|
|
uint textLen,
|
|
TModule* module)
|
|
:
|
|
TListBox(parent, resourceId, module)
|
|
{
|
|
TextLen = textLen;
|
|
}
|
|
|
|
//
|
|
// sets and selects the contents of the associated edit control to the
|
|
// supplied string
|
|
//
|
|
void
|
|
TComboBox::SetText(const char far* str)
|
|
{
|
|
//
|
|
// if str is 0, then use empty str
|
|
//
|
|
if (!str)
|
|
str = "";
|
|
|
|
//
|
|
// if not in listbox, then set the edit/static portion
|
|
//
|
|
if (SetSelString(str, -1) < 0) {
|
|
SetWindowText(str);
|
|
SetEditSel(0, strlen(str));
|
|
}
|
|
}
|
|
|
|
//
|
|
// returns, in the supplied reference parameters, the starting and
|
|
// ending positions of the text selected in the associated edit control
|
|
//
|
|
// returns CB_ERR is the combo box has no edit control
|
|
//
|
|
int
|
|
TComboBox::GetEditSel(int& startPos, int& endPos)
|
|
{
|
|
LRESULT retValue = HandleMessage(CB_GETEDITSEL);
|
|
|
|
startPos = LOWORD(retValue);
|
|
endPos = HIWORD(retValue);
|
|
|
|
return (int)retValue;
|
|
}
|
|
|
|
//
|
|
// shows or hides the drop-down list
|
|
//
|
|
void
|
|
TComboBox::ShowList(bool show)
|
|
{
|
|
if ((GetWindowLong(GWL_STYLE) & CBS_DROPDOWN) == CBS_DROPDOWN)
|
|
HandleMessage(CB_SHOWDROPDOWN, show);
|
|
}
|
|
|
|
static void
|
|
DoAddStringToCB(string& str, void* comboBox)
|
|
{
|
|
((TListBox*)comboBox)->AddString(str.c_str());
|
|
}
|
|
|
|
//
|
|
// transfers the items and selection of the combo box to or from a transfer
|
|
// buffer if tdSetData or tdGetData, respectively, is passed as the
|
|
// direction
|
|
//
|
|
// buffer should point to a TComboBoxData which points to the data to be
|
|
// transferred
|
|
//
|
|
// Transfer returns the size of TComboBoxData
|
|
//
|
|
// to retrieve the size without transferring data, pass tdSizeData as the
|
|
// direction
|
|
//
|
|
uint
|
|
TComboBox::Transfer(void* buffer, TTransferDirection direction)
|
|
{
|
|
TComboBoxData* comboBoxData = (TComboBoxData*)buffer;
|
|
|
|
if (direction == tdGetData) {
|
|
//
|
|
// Clear out Strings array and fill with contents of list box part
|
|
// Prescan for longest string to allow a single temp allocation
|
|
//
|
|
comboBoxData->Clear();
|
|
|
|
int count = GetCount();
|
|
int maxStringLen = 0;
|
|
for (int i = 0; i < count; i++) {
|
|
int stringLen = GetStringLen(i);
|
|
if (stringLen > maxStringLen)
|
|
maxStringLen = stringLen;
|
|
}
|
|
char* tmpString = new char[maxStringLen+1];
|
|
for (i = 0; i < count; i++) {
|
|
GetString(tmpString, i);
|
|
comboBoxData->AddString(tmpString, false);
|
|
comboBoxData->GetItemDatas()[i] = GetItemData(i);
|
|
}
|
|
delete tmpString;
|
|
|
|
//
|
|
// Get the sel string from the list by index, or if no index from the
|
|
// edit box
|
|
//
|
|
int selIndex = GetSelIndex();
|
|
if (selIndex >= 0) {
|
|
int stringLen = GetStringLen(selIndex);
|
|
if (stringLen > 0) {
|
|
char* str = new char[stringLen+1];
|
|
GetString(str, selIndex);
|
|
comboBoxData->SelectString(str);
|
|
delete str;
|
|
}
|
|
else
|
|
comboBoxData->SelectString("");
|
|
}
|
|
else {
|
|
int stringLen = GetWindowTextLength();
|
|
if (stringLen > 0) {
|
|
char* str = new char[stringLen+1];
|
|
GetWindowText(str, stringLen+1);
|
|
comboBoxData->SelectString(str);
|
|
delete str;
|
|
}
|
|
else
|
|
comboBoxData->SelectString("");
|
|
}
|
|
}
|
|
else if (direction == tdSetData) {
|
|
ClearList();
|
|
comboBoxData->GetStrings().ForEach(DoAddStringToCB, this);
|
|
for (int i = 0; i < comboBoxData->GetItemDatas().GetItemsInContainer(); i++)
|
|
SetItemData(i, comboBoxData->GetItemDatas()[i]);
|
|
|
|
SetWindowText(comboBoxData->GetSelection().c_str());
|
|
if (comboBoxData->GetSelIndex() >= 0)
|
|
SetSelString(comboBoxData->GetSelection().c_str(), 0);
|
|
}
|
|
|
|
return sizeof(TComboBoxData);
|
|
}
|
|
|
|
//
|
|
// Return name of predefined Windows combobox class
|
|
//
|
|
char far*
|
|
TComboBox::GetClassName()
|
|
{
|
|
return "COMBOBOX";
|
|
}
|
|
|
|
//
|
|
// limits the amount of text that the user can enter in the combo box's
|
|
// edit control to the value of TextLen minus 1
|
|
//
|
|
// creates aliases for the children in the combo box so that TWindow can
|
|
// handle kill focus messages for focus support.
|
|
//
|
|
void
|
|
TComboBox::SetupWindow()
|
|
{
|
|
TListBox::SetupWindow();
|
|
|
|
if (TextLen != 0)
|
|
HandleMessage(CB_LIMITTEXT, TextLen-1);
|
|
|
|
HWND hWnd = ::GetWindow(HWindow, GW_CHILD);
|
|
while (hWnd) {
|
|
if (!GetWindowPtr(hWnd))
|
|
new TWindow(hWnd);
|
|
hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
#if !defined(SECTION) || SECTION == 2
|
|
|
|
IMPLEMENT_STREAMABLE1(TComboBox, TListBox);
|
|
|
|
//
|
|
// reads an instance of TComboBox from the supplied ipstream
|
|
//
|
|
void*
|
|
TComboBox::Streamer::Read(ipstream& is, uint32 /*version*/) const
|
|
{
|
|
ReadBaseObject((TListBox*)GetObject(), is);
|
|
is >> GetObject()->TextLen;
|
|
return GetObject();
|
|
}
|
|
|
|
//
|
|
// writes the TComboBox to the supplied opstream
|
|
//
|
|
void
|
|
TComboBox::Streamer::Write(opstream& os) const
|
|
{
|
|
WriteBaseObject((TListBox*)GetObject(), os);
|
|
os << GetObject()->TextLen;
|
|
}
|
|
|
|
#endif
|
|
|