- 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>
534 lines
12 KiB
C++
534 lines
12 KiB
C++
//----------------------------------------------------------------------------
|
|
// ObjectWindows
|
|
// (C) Copyright 1994 by Borland International, All Rights Reserved
|
|
//
|
|
// Implementation of TOleView. Doc/View view derived from TOleWindow that
|
|
// supports Ole2 using OCF TOcView & TOcRemView
|
|
//----------------------------------------------------------------------------
|
|
#define INC_OLE2
|
|
#include <owl/owlpch.h>
|
|
#include <owl/window.h>
|
|
#include <owl/gdiobjec.h>
|
|
#include <owl/scroller.h>
|
|
#include <owl/docmanag.h>
|
|
#include <owl/docview.rh>
|
|
#include <owl/oleview.rh>
|
|
#include <owl/oleframe.h>
|
|
#include <owl/oleview.h>
|
|
#include <owl/oledoc.h>
|
|
|
|
//----------------------------------------------------------------------------
|
|
// TOleView
|
|
//
|
|
|
|
DEFINE_RESPONSE_TABLE1(TOleView, TOleWindow)
|
|
EV_VN_ISWINDOW,
|
|
|
|
// Container specific messages
|
|
//
|
|
EV_VN_INVALIDATE,
|
|
EV_VN_DOCOPENED,
|
|
EV_VN_DOCCLOSED,
|
|
EV_OC_VIEWPARTINVALID,
|
|
|
|
// Server specific messages
|
|
//
|
|
EV_OC_VIEWSAVEPART,
|
|
EV_OC_VIEWLOADPART,
|
|
EV_OC_VIEWINSMENUS,
|
|
EV_OC_VIEWCLOSE,
|
|
EV_OC_VIEWOPENDOC,
|
|
EV_OC_VIEWATTACHWINDOW,
|
|
EV_OC_VIEWSETLINK,
|
|
EV_OC_VIEWBREAKLINK,
|
|
EV_OC_VIEWGETITEMNAME,
|
|
END_RESPONSE_TABLE;
|
|
|
|
TOleView::TOleView(TDocument& doc, TWindow* parent)
|
|
:
|
|
TView(doc),
|
|
TOleWindow(parent, doc.GetDocManager().GetApplication())
|
|
{
|
|
Destroying = false;
|
|
TOleDocument* oleDoc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
|
|
CHECK(oleDoc);
|
|
OcDoc = oleDoc->GetOcDoc(); // Let OleWindow member point to it for accessor
|
|
}
|
|
|
|
TOleView::~TOleView()
|
|
{
|
|
Destroying = true;
|
|
if (IsRemote())
|
|
Destroy(); // make sure that derived TWindow shutdown virtuals get called
|
|
OcDoc = 0; // we don't own it, don't let TOleWindow delete it
|
|
}
|
|
|
|
//
|
|
// Override TOleWindow's version to pass info to TOleDocument & provide a
|
|
// second chance to find the RegLink.
|
|
//
|
|
TOcView*
|
|
TOleView::CreateOcView(TRegLink* link, bool isRemote, IUnknown* outer)
|
|
{
|
|
// Assume an embedded document until we find out later if we are a link
|
|
// or a load-from-file
|
|
//
|
|
if (isRemote)
|
|
GetDocument().SetEmbedded(true);
|
|
|
|
return TOleWindow::CreateOcView(link ? link : GetDocument().GetTemplate(),
|
|
isRemote, outer);
|
|
}
|
|
|
|
//
|
|
// Override TView's GetViewMenu to make an on-the-fly decision about which
|
|
// menu to use: normal, or embedded.
|
|
//
|
|
TMenuDescr*
|
|
TOleView::GetViewMenu()
|
|
{
|
|
if (TView::GetViewMenu())
|
|
return TView::GetViewMenu();
|
|
|
|
//!CQ && not a link!
|
|
if (IsRemote() && GetModule()->FindResource(IDM_OLEVIEWEMBED, RT_MENU))
|
|
SetViewMenu(new TMenuDescr(IDM_OLEVIEWEMBED, GetModule()));
|
|
else
|
|
SetViewMenu(new TMenuDescr(IDM_OLEVIEW, GetModule()));
|
|
|
|
return TView::GetViewMenu();
|
|
}
|
|
|
|
//
|
|
// Does a given HWND belong to this view? Yes if it is us, or a child of us
|
|
//
|
|
bool
|
|
TOleView::VnIsWindow(HWND hWnd)
|
|
{
|
|
return hWnd == HWindow || IsChild(hWnd);
|
|
}
|
|
|
|
//
|
|
// Intercept CanClose() to interpose OpenEdit semantics
|
|
// Bypasses TOleWindow in order to get Doc query involved
|
|
//
|
|
bool
|
|
TOleView::CanClose()
|
|
{
|
|
// We don't want to close the view for DLL servers
|
|
//
|
|
if (IsOpenEditing() && !OcApp->IsOptionSet(amExeMode)) {
|
|
TOleFrame* olefr = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(), TOleFrame);
|
|
CHECK(olefr);
|
|
olefr->ShowWindow(SW_HIDE);
|
|
TOleWindow::OleShutDown();
|
|
return false;
|
|
}
|
|
|
|
// say yes if there are more than one TOleView's attached to the document
|
|
//
|
|
if (OtherViewExists() || GetOcRemView())
|
|
return true;
|
|
|
|
if (Doc->CanClose())
|
|
{
|
|
if (OcDoc)
|
|
OcDoc->Close();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
//
|
|
// Check if other TOleView already exists
|
|
//
|
|
bool
|
|
TOleView::OtherViewExists()
|
|
{
|
|
TView* curView = GetDocument().GetViewList();
|
|
while (curView) {
|
|
TOleLinkView* oleLinkView = TYPESAFE_DOWNCAST(curView, TOleLinkView);
|
|
if (!oleLinkView && curView != this)
|
|
return true;
|
|
|
|
curView = curView->GetNextView();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Perform normal CleanupWindow, plus let the OcView object know we have closed
|
|
//
|
|
void
|
|
TOleView::CleanupWindow()
|
|
{
|
|
if (!OtherViewExists()) {
|
|
|
|
TOleWindow::CleanupWindow();
|
|
|
|
// Delete the TOleView now rather wait until ~TOleFrame if its parent
|
|
// is TRemViewBucket
|
|
//
|
|
TOleFrame* mainWindow = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(),
|
|
TOleFrame);
|
|
if (mainWindow && mainWindow->GetRemViewBucket() == Parent && !Destroying)
|
|
GetApplication()->Condemn(this);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Shut down the associated OCF partners if possible
|
|
//
|
|
bool
|
|
TOleView::OleShutDown()
|
|
{
|
|
TOleWindow::OleShutDown();
|
|
if (OcDoc && !OtherViewExists())
|
|
OcDoc->Close();
|
|
return true;
|
|
}
|
|
|
|
|
|
//
|
|
// Invalidate the view region specified by rect
|
|
//
|
|
bool
|
|
TOleView::VnInvalidate(TRect& rect)
|
|
{
|
|
InvalidateRect(rect, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// The associated doc is opened
|
|
//
|
|
bool
|
|
TOleView::VnDocOpened(int /*omode*/)
|
|
{
|
|
DragPart = 0;
|
|
Pos.SetNull();
|
|
Scale.Reset();
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// The associated doc is closed
|
|
//
|
|
bool
|
|
TOleView::VnDocClosed(int /*omode*/)
|
|
{
|
|
OcDoc = 0;
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// TOcRemView is going away, disconnect TOleWindow with it so we don't use it
|
|
// later. In some cases we also need to delete the document.
|
|
//
|
|
bool
|
|
TOleView::EvOcViewClose()
|
|
{
|
|
TOcRemView* ocRemView = GetOcRemView();
|
|
|
|
// When TOcRemView gets shut down in the Embed From File case,
|
|
// we need to cleanup the document and view right away. Otherwise,
|
|
// the document and view will be shut down as part of the frame shut down
|
|
// process.
|
|
//
|
|
if (ocRemView && ocRemView->GetKind() == TOcRemView::LoadFromFile) {
|
|
OcView = 0; // OcView is going away, so don't mess with it
|
|
OcDoc = 0; // OleDoc will delete OcDoc, so don't mess with it
|
|
delete &GetDocument();
|
|
}
|
|
else {
|
|
TOleWindow::EvOcViewClose();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Ask server to save itself in the IStorage
|
|
//
|
|
bool
|
|
TOleView::EvOcViewSavePart(TOcSaveLoad far& ocSave)
|
|
{
|
|
PRECONDITION(ocSave.StorageI);
|
|
|
|
TOleDocument* doc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
|
|
if (!doc)
|
|
return false;
|
|
|
|
doc->SetStorage(ocSave.StorageI, (ocSave.SameAsLoad || ocSave.Remember));
|
|
|
|
bool status;
|
|
if (ocSave.SaveSelection) {
|
|
status = doc->CommitSelection(*this, ocSave.UserData);
|
|
}
|
|
else {
|
|
// Save view remote view info such as origin and extent
|
|
//
|
|
TOcRemView* ocRemView = GetOcRemView();
|
|
if (ocRemView)
|
|
ocRemView->Save(ocSave.StorageI);
|
|
|
|
status = doc->Commit(true);
|
|
}
|
|
|
|
// Restore the original storage
|
|
//
|
|
if (!ocSave.SameAsLoad && !ocSave.Remember)
|
|
doc->RestoreStorage();
|
|
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Ask server to load itself from the IStorage
|
|
//
|
|
bool
|
|
TOleView::EvOcViewLoadPart(TOcSaveLoad far& ocLoad)
|
|
{
|
|
PRECONDITION(ocLoad.StorageI);
|
|
|
|
TOleDocument* doc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
|
|
doc->SetStorage(ocLoad.StorageI);
|
|
|
|
// Load view remote view info such as origin and extent
|
|
//
|
|
CHECK(GetOcRemView());
|
|
GetOcRemView()->Load(ocLoad.StorageI);
|
|
|
|
bool status = GetDocument().Open(doc->GetOpenMode());
|
|
|
|
if (!ocLoad.Remember)
|
|
doc->SetStorage(0);
|
|
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Ask container to open an existing document
|
|
// Used for linking from embedding
|
|
//
|
|
bool
|
|
TOleView::EvOcViewOpenDoc(const char far* path)
|
|
{
|
|
TOleDocument* oleDoc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
|
|
CHECK(oleDoc && GetOcDoc());
|
|
|
|
oleDoc->SetEmbedded(false); // must really be a link or load-from-file
|
|
oleDoc->SetStorage(0); // release the current storage
|
|
oleDoc->SetDocPath(path);
|
|
oleDoc->InitDoc();
|
|
oleDoc->Open(ofRead, path);
|
|
|
|
string newName(oleDoc->GetDocPath());
|
|
GetOcDoc()->SetName(newName);
|
|
Invalidate();
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Insert server menu into the composite one
|
|
//
|
|
bool
|
|
TOleView::EvOcViewInsMenus(TOcMenuDescr far& sharedMenu)
|
|
{
|
|
// Recreate a temporary composite menu for frame and child
|
|
//
|
|
TMenuDescr compMenuDesc; // empty menudescr
|
|
if (GetViewMenu()) {
|
|
compMenuDesc.Merge(*GetViewMenu());
|
|
compMenuDesc.Merge(TMenuDescr(0, -1, 0, -1, 0, -1, 0));
|
|
}
|
|
|
|
TMenuDescr shMenuDescr(sharedMenu.HMenu,
|
|
sharedMenu.Width[0],
|
|
sharedMenu.Width[1],
|
|
sharedMenu.Width[2],
|
|
sharedMenu.Width[3],
|
|
sharedMenu.Width[4],
|
|
sharedMenu.Width[5]);
|
|
shMenuDescr.Merge(compMenuDesc);
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
sharedMenu.Width[i] = shMenuDescr.GetGroupCount(i);
|
|
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Notify the active view of part data changes
|
|
//
|
|
bool
|
|
TOleView::EvOcViewPartInvalid(TOcPartChangeInfo& changeInfo)
|
|
{
|
|
if (changeInfo.IsDataChange())
|
|
GetDocument().SetDirty(true);
|
|
|
|
// Reflect the change in part in other (non-active) views
|
|
//
|
|
TRect rect(changeInfo.GetPart()->GetRect());
|
|
rect.right++;
|
|
rect.bottom++;
|
|
TOleClientDC dc(*this);
|
|
dc.LPtoDP((TPoint*)&rect, 2);
|
|
|
|
GetDocument().NotifyViews(vnInvalidate, (long)&rect, 0);
|
|
|
|
// Notify container if this is an intermediate container
|
|
//
|
|
InvalidatePart((TOcInvalidate)changeInfo.GetType());
|
|
|
|
return true; // stop further processing by OCF
|
|
}
|
|
|
|
//
|
|
// Attach this view back to its owl parent for either open editing, or
|
|
// mearly inplace de-activating
|
|
//
|
|
bool
|
|
TOleView::EvOcViewAttachWindow(bool attach)
|
|
{
|
|
TOleFrame* mainWindow = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(),
|
|
TOleFrame);
|
|
if (!mainWindow)
|
|
return false; // server app is shutting down
|
|
|
|
// There won't be any TOcRemView if we're reestablishing the link
|
|
//
|
|
if (attach) {
|
|
if (IsOpenEditing()) {
|
|
// Get the normal app notify handler to set up the parent for us
|
|
// knowing that we are now open editing
|
|
//
|
|
if (mainWindow->GetRemViewBucket() == Parent) {
|
|
GetDocument().GetDocManager().PostEvent(dnCreate, *this);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (IsOpenEditing() && Parent != mainWindow)
|
|
Parent->PostMessage(WM_CLOSE);
|
|
SetParent(mainWindow->GetRemViewBucket()); // simple reparent
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Find the item name for whole doc or selection
|
|
//
|
|
bool
|
|
TOleView::EvOcViewGetItemName(TOcItemName& item)
|
|
{
|
|
if (item.Selection) {
|
|
if (DragPart) {
|
|
item.Name = DragPart->GetName();
|
|
return true;
|
|
}
|
|
}
|
|
else {
|
|
item.Name = "Content"; // item name representing the whole document
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Linking Spport
|
|
//
|
|
|
|
//
|
|
// Establish link with whole doc or selection
|
|
//
|
|
bool
|
|
TOleView::EvOcViewSetLink(TOcLinkView& /*view*/)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Break link with whole doc or selection
|
|
//
|
|
bool
|
|
TOleView::EvOcViewBreakLink(TOcLinkView& view)
|
|
{
|
|
// Find the link view with the moniker
|
|
//
|
|
TView* target = GetDocument().QueryViews(vnLinkView, (long)&view, this);
|
|
|
|
// Delete a linked view to this document
|
|
//
|
|
delete target;
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// TOleLinkView
|
|
//
|
|
|
|
DEFINE_RESPONSE_TABLE(TOleLinkView)
|
|
EV_VN_LINKVIEW,
|
|
EV_VN_LINKMONIKER,
|
|
END_RESPONSE_TABLE;
|
|
|
|
TOleLinkView::TOleLinkView(TDocument& doc, TOcLinkView& view)
|
|
:
|
|
TView(doc),
|
|
OcLinkView(view)
|
|
{
|
|
}
|
|
|
|
TOleLinkView::~TOleLinkView()
|
|
{
|
|
OcLinkView.Release();
|
|
}
|
|
|
|
//
|
|
// See if a TOleLinkView is associated with this TOcRemView
|
|
//
|
|
bool
|
|
TOleLinkView::VnLinkView(TOcLinkView& view)
|
|
{
|
|
if (&OcLinkView == &view)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// See if a TOleLinkView is associated with this TOcRemView
|
|
//
|
|
bool
|
|
TOleLinkView::VnLinkMoniker(TString& moniker)
|
|
{
|
|
if ((char*)OcLinkView.GetMoniker() == (char*)moniker)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Update all links to this view
|
|
//
|
|
bool
|
|
TOleLinkView::UpdateLinks()
|
|
{
|
|
OcLinkView.Invalidate(invView);
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Get the moniker corresponding to this view
|
|
//
|
|
TString&
|
|
TOleLinkView::GetMoniker()
|
|
{
|
|
return OcLinkView.GetMoniker();
|
|
}
|