Files
TeslaRel410/BORLAND/BC45/SOURCE/OWL/CHGICON.CPP
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- 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>
2026-07-19 07:33:26 -05:00

693 lines
15 KiB
C++

//----------------------------------------------------------------------------
// ObjectWindows
// (C) Copyright 1994 by Borland International, All Rights Reserved
//
// Defines TChangeIconDlg
//----------------------------------------------------------------------------
#define INC_OLE2
#include <owl/owlpch.h>
#include <owl/listbox.h>
#include <owl/radiobut.h>
#include <owl/edit.h>
#include <ocf/ocview.h>
#include <owl/oledlg.h>
#include <bwcc.h> // for IDHELP
//
// OWL OLE Dialog diagnostic group.
//
DIAG_DECLARE_GROUP(OwlOleDlg);
//
// Class TIconListBox
// ----- ------------
// OwnerDraw ListBox which displays icons [used by TChangeIconDlg]
//
class _OWLCLASS TIconListBox : public TListBox {
public:
TIconListBox(TWindow *parent, int resourceId, TModule* module=0):
TListBox(parent, resourceId, module){};
void DrawIcon(DRAWITEMSTRUCT far& drawInfo);
void ODADrawEntire(DRAWITEMSTRUCT far& drawInfo);
void ODAFocus(DRAWITEMSTRUCT far& drawInfo);
void ODASelect(DRAWITEMSTRUCT far& drawInfo);
void MeasureItem(MEASUREITEMSTRUCT far& measureInfo);
void DeleteItem(DELETEITEMSTRUCT far& deleteInfo);
int AddIcon(TIcon&);
uint AddIconsFromFile(const char far* fileName);
};
//
// Specifies each listbox entry's size as slightly bigger than
// the size of an icon
//
void
TIconListBox::MeasureItem(MEASUREITEMSTRUCT far& measureInfo)
{
measureInfo.itemWidth = GetSystemMetrics(SM_CXICON)+cxIconPad;
measureInfo.itemHeight= GetSystemMetrics(SM_CYICON)+cyIconPad;
}
//
// Adds an icon to the listbox
//
int
TIconListBox::AddIcon(TIcon &icon)
{
return (int)HandleMessage(LB_ADDSTRING, 0, (LPARAM)(HICON)icon);
}
//
// Extracts icons from the specified file and adds them to the listbox.
// NOTE: Performs no validation of the filename
// Returns number of icons added
//
uint
TIconListBox::AddIconsFromFile(const char far* filename)
{
int count = 0;
for(uint i=0; i<0xffff; i++) {
HICON hicon = ExtractIcon(*GetModule(), filename, i);
if ((UINT)hicon > 32) {
TIcon icon(hicon);
if (AddIcon(icon) != LB_ERR)
count++;
}
else {
break;
}
}
return count;
}
//
// Handles deletion of items from the listbox by cleaning up each
// icon inserted.
//
void
TIconListBox::DeleteItem(DELETEITEMSTRUCT far& deleteInfo)
{
DestroyIcon(HICON(deleteInfo.itemData));
}
//
// Draws a listbox entry by calling DrawIcon [the itemData field
// is really a HICON inserted earlier in the listbox].
//
void
TIconListBox::DrawIcon(DRAWITEMSTRUCT far& drawInfo)
{
if ((int)drawInfo.itemID < 0)
return;
TColor bkColor(GetSysColor(drawInfo.itemState & ODS_SELECTED ?
COLOR_HIGHLIGHT : COLOR_WINDOW));
TDC dc(drawInfo.hDC);
TColor oldBkColor = dc.GetBkColor();
dc.TextRect(drawInfo.rcItem, bkColor);
dc.DrawIcon(drawInfo.rcItem.left+(cxIconPad/2),
drawInfo.rcItem.top +(cyIconPad/2),
TIcon(HICON(drawInfo.itemData)));
dc.SetBkColor(oldBkColor);
if (drawInfo.itemState & ODS_FOCUS)
dc.DrawFocusRect(drawInfo.rcItem);
}
//
// Draws a Focus Rect - Called for the selected entry
//
void
TIconListBox::ODAFocus(DRAWITEMSTRUCT far& drawInfo)
{
TDC dc(drawInfo.hDC);
dc.DrawFocusRect(drawInfo.rcItem);
}
void
TIconListBox::ODADrawEntire(DRAWITEMSTRUCT far& drawInfo)
{
DrawIcon(drawInfo);
}
void
TIconListBox::ODASelect(DRAWITEMSTRUCT far& drawInfo)
{
DrawIcon(drawInfo);
}
//
// Initialize data members of structure used internally by TChangeIconDlg -
// The structure keeps track of the dialog's state.
//
TChangeIconDlg::THelper::THelper()
{
//
// Using memset since class is a private PODS.
//
memset(this, 0, sizeof(THelper));
}
DEFINE_RESPONSE_TABLE1(TChangeIconDlg, TOleDialog)
EV_BN_CLICKED(IDC_CURRENT, CurrentClicked),
EV_BN_CLICKED(IDC_DEFAULT, DefaultClicked),
EV_BN_CLICKED(IDC_FROMFILE, FromFileClicked),
EV_EN_KILLFOCUS(IDC_LABEL, LabelKillFocus),
EV_CHILD_NOTIFY_ALL_CODES(IDC_FILENAME, FileNameNotification),
EV_LBN_SETFOCUS(IDC_ICONLIST, IconListSetFocus),
EV_LBN_SELCHANGE(IDC_ICONLIST, IconListSelChange),
EV_LBN_DBLCLK(IDC_ICONLIST, IconListDblClk),
EV_BN_CLICKED(IDC_BROWSE, BrowseClicked),
EV_BN_CLICKED(IDCANCEL, CmCancel),
END_RESPONSE_TABLE;
//
// Creates C++ objects to wrap controls
//
TChangeIconDlg::TChangeIconDlg(TWindow* parent,
TData& data,
TResId templateId,
const char far* title,
TModule* module)
:TOleDialog(parent,
templateId ? templateId : TResId(DLG_CHANGEICON),
title,
module), Data(data), Helper(*new THelper)
{
CurrentIcon = new TStatic(this, IDC_CURRENTICON);
DefaultIcon = new TStatic(this, IDC_DEFAULTICON);
Label = new TEdit(this, IDC_LABEL, MaxLabelLen);
ResultIcon = new TStatic(this, IDC_RESULTICON);
ResultLabel = new TStatic(this, IDC_DOCUMENTNAME);
Current = new TRadioButton(this, IDC_CURRENT);
Default = new TRadioButton(this, IDC_DEFAULT);
FromFile = new TRadioButton(this, IDC_FROMFILE);
Help = new TButton(this, IDHELP);
Browse = new TButton(this, IDC_BROWSE);
IconList = new TIconListBox(this, IDC_ICONLIST);
FileName = new TEdit(this, IDC_FILENAME, MaxPathLen);
}
//
// Clean up dialog
//
TChangeIconDlg::~TChangeIconDlg()
{
delete &Helper;
}
//
// Initialize members of TData structure
//
TChangeIconDlg::TData::TData()
{
Flags = 0;
MetaPict = 0;
ClsId = CLSID_NULL;
IconExe[0] = 0;
}
//
// Wrapper to set a static control's icon
//
void
TChangeIconDlg::SetIcon(TStatic& win, HICON hIcon)
{
win.SendMessage(STM_SETICON, (WPARAM)hIcon);
}
//
// Executes dialog
//
int
TChangeIconDlg::DoExecute()
{
return TDialog::DoExecute();
}
//
// Performs initialization of ChangeIcon Dialog.
//
void
TChangeIconDlg::SetupWindow()
{
TOleDialog::SetupWindow();
TModule *module = GetModule();
//
// Copy Info from user
//
Helper.Flags = Data.Flags;
//
// Extract info about MetaFile icon
//
TOleMetaPict metaPict(Data.MetaPict);
metaPict.ExtractIconSource(Helper.File, Helper.IconIndex);
metaPict.ExtractLabel(Helper.Label);
Helper.CurIcon = metaPict.ExtractIcon(*GetModule());
//
// Set Control Font
//
if (Font)
ResultLabel->SetWindowFont(*Font, false);
//
// Handle Help button display
//
if (!(Helper.Flags & ciShowHelp))
Activate(Help, false);
//
// Init control displays
//
FileName->SetText(Helper.File);
Label->SetText(Helper.Label);
ResultLabel->SetText(Helper.Label);
//
// Use IconExe as IconFile if requested
//
Helper.DefIcon = 0;
if (Helper.Flags & ciUseIconExe) {
Helper.DefIcon = ExtractIcon(*module, Data.IconExe, 0);
if (Helper.DefIcon) {
strcpy(Helper.DefIconFile, Data.IconExe);
Helper.DefIconIndex = 0;
}
}
if (!Helper.DefIcon) {
HGLOBAL metaPict = GetIconFromClass(Data.ClsId, 0, TRUE);
if (metaPict) {
TOleMetaPict defMetaPict(metaPict, AutoDelete);
Helper.DefIcon = defMetaPict.ExtractIcon(*GetModule());
defMetaPict.ExtractIconSource(Helper.DefIconFile,
Helper.DefIconIndex);
}
}
//
// Init Icon Displays
//
SetIcon(*CurrentIcon, Helper.CurIcon);
SetIcon(*DefaultIcon, Helper.DefIcon);
SetIcon(*ResultIcon, Helper.CurIcon);
//
// Adjust listbox dimensions
//
int listHeight = GetSystemMetrics(SM_CYICON)+
GetSystemMetrics(SM_CYHSCROLL)+
GetSystemMetrics(SM_CYBORDER)*2+
cyIconPad;
TRect lRect;
IconList->GetClientRect(lRect);
IconList->SetWindowPos(0, 0, 0, lRect.right, listHeight,
SWP_NOMOVE|SWP_NOZORDER);
IconList->SetColumnWidth(GetSystemMetrics(SM_CXICON)+cxIconPad);
TRect gRect;
IconList->GetWindowRect(lRect);
//! BB Window may need resizing
//
// Select appropriate RadioButton
//
if (FillIconList(Helper.File)) {
IconList->SetSelIndex(Helper.IconIndex);
}
if (Helper.Flags & ciSelectCurrent) {
CheckRadioButton(IDC_CURRENT, IDC_FROMFILE, IDC_CURRENT);
}
else {
uint id = (Helper.Flags & ciSelectFromFile) ? IDC_FROMFILE : IDC_DEFAULT;
CheckRadioButton(IDC_CURRENT, IDC_FROMFILE, id);
}
}
//
// Called when user selects 'OK'
//
bool
TChangeIconDlg::OleDlgOk()
{
char file[MaxPathLen];
FileName->GetText(file, sizeof(file));
//
// If the file name has changed we'll simply update the listbox instead
// of closing the dialog
//
if (strcmpi(Helper.File, file)) {
strcpy(Helper.File, file);
FillIconList(Helper.File);
UpdateResultIcon(ciSelectFromFile);
return false;
}
//
// Validate filename if 'SelectFromFile'
//
if (Helper.Flags & ciSelectFromFile) {
OFSTRUCT ofs;
if (DoesFileExist(Helper.File, ofs)==HFILE_ERROR) {
OpenFileError(ofs.nErrCode, Helper.File);
FileName->SetFocus();
FileName->SetSelection(0, -1);
return false;
}
}
//
// Set Focus to OK button
//
if (GetFocus() != GetDlgItem(IDOK))
::SetFocus(GetDlgItem(IDOK));
//
//
//
HICON hIcon = (HICON)ResultIcon->SendMessage(STM_GETICON);
LPSTR lpsz = Helper.File;
//
// Retrieve default information (if Default)
//
if (Helper.Flags & ciSelectDefault) {
lpsz = Helper.DefIconFile;
Helper.IconIndex = Helper.DefIconIndex;
hIcon = Helper.DefIcon;
}
//
// Extract current icon source (if Current)
//
if (Helper.Flags & ciSelectCurrent) {
TOleMetaPict metaPict(Data.MetaPict);
metaPict.ExtractIconSource(lpsz, Helper.IconIndex);
}
//
// Retrieve filename and index (if FromFile)
//
if (Helper.Flags & ciSelectFromFile) {
FileName->GetText(lpsz, MaxPathLen);
Helper.IconIndex = IconList->GetSelIndex();
}
//
// Retrieve label to make new metafile
//
char label[MaxLabelLen];
Label->GetText(label, sizeof(label));
//
// Create new metafile
//
HGLOBAL hMetaPict = OleMetafilePictFromIconAndLabel(hIcon, label, lpsz,
Helper.IconIndex);
//
// Free metafile passed in
//
TOleMetaPict::Free(Data.MetaPict);
//
// Return new metafile to user along with flags
//
Data.MetaPict = hMetaPict;
Data.Flags = Helper.Flags;
return true;
}
//
//
//
void
TChangeIconDlg::CleanupWindow()
{
//
// Make sure that icons are properly destroyed
// (this takes care of destroying the [fromFile] icon)
//
IconList->ClearList();
//
// Destroy Current Icon
//
HICON hIcon = (HICON)CurrentIcon->SendMessage(STM_GETICON);
if (hIcon)
DestroyIcon(hIcon);
//
// Destroy the Default Icon
//
hIcon = (HICON)DefaultIcon->SendMessage(STM_GETICON);
if (hIcon)
DestroyIcon(hIcon);
TOleDialog::CleanupWindow();
}
//
// Fills the Icon ListBox with icons extracted from the specified filename
//
uint
TChangeIconDlg::FillIconList(const char *fileName)
{
uint numIcons = 0;
//
// Clear listbox (which destroys currently extracted icons)
//
IconList->ClearList();
//
// Check for !NULL filename
//
if (!fileName || strlen(fileName) == 0)
return 0;
//
// Enable Wait cursor and Clear List
//
HCURSOR oldCursor = HourGlassOn();
//
// Validate filename
//
OFSTRUCT ofs;
if (DoesFileExist(fileName, ofs) != HFILE_ERROR) {
//
// Check that indeed there are icons in the file
//
HICON hIcon = ExtractIcon(*GetModule(), fileName, 0);
if ((uint)hIcon > 32) {
//
// Clean up the extracted icon
//
DestroyIcon(hIcon);
//
// Pass name to listbox for grunt work and for listbox to update
//
IconList->SetRedraw(false);
numIcons = IconList->AddIconsFromFile(fileName);
IconList->SetRedraw(true);
IconList->Invalidate(true);
IconList->SetSelIndex(0);
}
else {
ErrorWithFile(IDS_CINOICONSINFILE, fileName);
}
}
else {
OpenFileError(ofs.nErrCode, fileName);
}
HourGlassOff(oldCursor);
return numIcons;
}
void
TChangeIconDlg::UpdateResultIcon(TChangeIconFlags flag)
{
PRECONDITION(flag == ciSelectCurrent ||
flag == ciSelectDefault ||
flag == ciSelectFromFile);
Helper.Flags &= ~(ciSelectCurrent | ciSelectDefault | ciSelectFromFile);
long lval = LB_ERR;
if (flag == ciSelectCurrent)
lval = CurrentIcon->SendMessage(STM_GETICON);
else if (flag == ciSelectDefault)
lval = DefaultIcon->SendMessage(STM_GETICON);
else if (flag == ciSelectFromFile) {
int index = IconList->GetSelIndex();
if (index != LB_ERR)
IconList->HandleMessage(LB_GETTEXT, index, (LPARAM)(LPLONG)&lval);
else
lval = DefaultIcon->SendMessage(STM_GETICON);
}
if (lval != LB_ERR)
SetIcon(*ResultIcon, (HICON)lval);
}
void
TChangeIconDlg::CurrentClicked()
{
UpdateResultIcon(ciSelectCurrent);
}
void
TChangeIconDlg::DefaultClicked()
{
UpdateResultIcon(ciSelectDefault);
}
void
TChangeIconDlg::FromFileClicked()
{
UpdateResultIcon(ciSelectFromFile);
}
void
TChangeIconDlg::LabelKillFocus()
{
char str[MaxPathLen];
Label->GetText(str, sizeof(str));
ResultLabel->SetText(str);
}
void
TChangeIconDlg::FileNameNotification(uint)
{
char str[MaxPathLen];
FileName->GetText(str, sizeof(str));
if (strcmpi(Helper.File, str)) {
IconList->SetSelIndex(-1);
CheckRadioButton(IDC_CURRENT, IDC_FROMFILE, IDC_FROMFILE);
}
}
//
// If the filename has changed when the IconListBox gains focus,
// the list is refilled and the result icon updated.
//
void
TChangeIconDlg::IconListSetFocus()
{
char str[MaxPathLen];
FileName->GetText(str, sizeof(str));
if (strcmpi(Helper.File, str)) {
strcpy(Helper.File, str);
FillIconList(Helper.File);
UpdateResultIcon(ciSelectFromFile);
}
}
//
// Updates result icon if listbox selection changes
//
void
TChangeIconDlg::IconListSelChange()
{
UpdateResultIcon(ciSelectFromFile);
}
//
// A double click on the IconListBox is treated as if the 'OK' button
// had been clicked
//
void
TChangeIconDlg::IconListDblClk()
{
SendNotification(IDOK, BN_CLICKED, GetDlgItem(IDOK));
}
//
// Allows user to browse for a file from which icons can be extracted
//
void
TChangeIconDlg::BrowseClicked()
{
//
// Save a copy of filename
//
char file[MaxPathLen];
FileName->GetText(file, sizeof(file));
//
// Build flags
//
DWORD flags = OFN_FILEMUSTEXIST;
if (Data.Flags & ciShowHelp)
flags |= OFN_SHOWHELP;
//
// Display OpenFile dialog
//
if (BrowseDlg(Helper.File, 0, IDS_ICONFILTERS, flags)) {
//
// If filename has changed, update display
//
if (strcmpi(file, Helper.File)) {
CheckRadioButton(IDC_CURRENT, IDC_FROMFILE, IDC_FROMFILE);
FileName->SetText(Helper.File);
FillIconList(Helper.File);
UpdateResultIcon(ciSelectFromFile);
}
}
}