- 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>
1024 lines
23 KiB
C++
1024 lines
23 KiB
C++
//
|
|
//----------------------------------------------------------------------------
|
|
// ObjectComponents
|
|
// (C) Copyright 1994 by Borland International, All Rights Reserved
|
|
//
|
|
// Implementation of TOcView Class
|
|
//----------------------------------------------------------------------------
|
|
#include <ocf/ocfpch.h>
|
|
#include <ocf/ocstorag.h>
|
|
#include <ocf/ocview.h>
|
|
#include <ocf/ocremvie.h>
|
|
#include <ocf/ocapp.h>
|
|
#include <ocf/ocpart.h>
|
|
#include <ocf/ocdata.h>
|
|
#include <ocf/autodefs.h>
|
|
#include <osl/locale.h>
|
|
#include <osl/geometry.h>
|
|
|
|
DIAG_DECLARE_GROUP(OcRefCount);
|
|
|
|
const char DocContent[] = "All";
|
|
|
|
TOcView::TOcView(TOcDocument& doc, TRegList* regList, IUnknown* outer)
|
|
:
|
|
OcApp(doc.OcApp),
|
|
Win(0),
|
|
OcDocument(doc),
|
|
ActivePart(0),
|
|
LinkFormat(-1),
|
|
RegList(regList),
|
|
OcData(0),
|
|
Options(0),
|
|
#if defined(BI_DATA_NEAR)
|
|
WinTitle(*new string),
|
|
Origin(*new TPoint(0,0)),
|
|
Extent(*new TSize(0,0)),
|
|
FormatList(*new TOcFormatList),
|
|
OrgTitle(*new TString)
|
|
#else
|
|
Origin(0,0),
|
|
Extent(0,0)
|
|
#endif
|
|
{
|
|
BContainer = 0;
|
|
BDocumentI = 0;
|
|
BDocument = 0;
|
|
BLDocumentI = 0;
|
|
|
|
SetOuter(outer);
|
|
AddRef(); // TUnknown defaults to 0, we need 1
|
|
if (regList)
|
|
RegisterClipFormats(*regList);
|
|
|
|
// Necessary to initialize TOcPart for linking
|
|
//
|
|
OcDocument.SetActiveView(this);
|
|
|
|
if (SUCCEEDED(OcApp.BOleComponentCreate(&BDocument,
|
|
(IUnknown*)(IBContainer*)this, cidBOleDocument))) {
|
|
BDocument->QueryInterface(IID_IBDocument, &(LPVOID)BDocumentI);
|
|
Release();
|
|
}
|
|
|
|
if (SUCCEEDED(OcApp.BOleComponentCreate(&BContainer,
|
|
(IUnknown*)(IBContainer*)this, cidBOleContainer))) {
|
|
if (regList) {
|
|
const char* progid = regList->Lookup(OcApp.IsOptionSet(amDebug) ?
|
|
"debugprogid" : "progid");
|
|
if (progid &&
|
|
SUCCEEDED(BContainer->QueryInterface(IID_IBRootLinkable, &(LPVOID)BLDocumentI))) {
|
|
Release();
|
|
BLDocumentI->Init((TOcView*)this, OleStr(progid));
|
|
}
|
|
}
|
|
}
|
|
|
|
TRACEX(OcRefCount, 1, "TOcView() @" << (void*)this);
|
|
}
|
|
|
|
TOcView::~TOcView()
|
|
{
|
|
Shutdown();
|
|
#if defined(BI_DATA_NEAR)
|
|
delete &WinTitle;
|
|
delete &FormatList;
|
|
delete &Origin;
|
|
delete &Extent;
|
|
delete &OrgTitle;
|
|
#endif
|
|
}
|
|
|
|
//
|
|
// called from destructor of this class or of derived class to release helpers
|
|
//
|
|
void
|
|
TOcView::Shutdown()
|
|
{
|
|
if (BContainer) {
|
|
BContainer->Release();
|
|
BContainer = 0;
|
|
}
|
|
if (BDocument) {
|
|
BDocument->Release();
|
|
BDocument = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Should only be called by the owner/creator of this object
|
|
//
|
|
void
|
|
TOcView::ReleaseObject()
|
|
{
|
|
Release();
|
|
Win = 0;
|
|
}
|
|
|
|
//
|
|
// Callback from TUnknown's implementation of QueryInterface
|
|
//
|
|
HRESULT
|
|
TOcView::QueryObject(const IID far& iid, void far* far* iface)
|
|
{
|
|
PRECONDITION(iface);
|
|
HRESULT hr;
|
|
|
|
// interfaces
|
|
//
|
|
SUCCEEDED(hr = IBContainer_QueryInterface(this, iid, iface))
|
|
|| SUCCEEDED(hr = IBContains_QueryInterface(this, iid, iface))
|
|
|| SUCCEEDED(hr = IBDataConsumer_QueryInterface(this, iid, iface))
|
|
|| SUCCEEDED(hr = IBDropDest_QueryInterface(this, iid, iface))
|
|
|| SUCCEEDED(hr = IBDataNegotiator_QueryInterface(this, iid, iface))
|
|
|
|
// helpers (BContainer needed for embed/link from file)
|
|
//
|
|
|| (BContainer && SUCCEEDED(hr = BContainer->QueryInterface(iid, iface)))
|
|
|| (BDocument && SUCCEEDED(hr = BDocument->QueryInterface(iid, iface)))
|
|
;
|
|
|
|
// If the QueryInterface failed, try the TOcLinkView
|
|
//
|
|
|
|
if (hr == HR_NOINTERFACE && iid == IID_IDataObject) {
|
|
TOcLinkView* view = GetDocLink();
|
|
if (view)
|
|
hr = view->QueryInterface(iid, iface);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
void
|
|
TOcView::SetupWindow(HWND hWin, bool embedded)
|
|
{
|
|
// Don't register drag&drop target here since it will do QueryInterface
|
|
// in ComponentCreate before the outer is set up. RefCount will be messed
|
|
// up in this case. Keep Win==0 while initing BDocumentI. OcRemView will init
|
|
// later.
|
|
//
|
|
Win = embedded ? 0 : hWin;
|
|
|
|
// Make sure at least the BDocument gets its container & application ptrs
|
|
// setup
|
|
//
|
|
if (BDocumentI)
|
|
BDocumentI->Init(this);
|
|
|
|
if (Win)
|
|
Rename();
|
|
Win = hWin;
|
|
|
|
EvActivate(true); // default to being the active view on creation
|
|
}
|
|
|
|
// Obtain a TOcLinkView representing the whole document
|
|
//
|
|
TOcLinkView*
|
|
TOcView::GetDocLink()
|
|
{
|
|
// Ask the document whether an TOcLinkView corresponding to the item name
|
|
// already exists
|
|
//
|
|
TOcLinkView* ocLinkView = OcDocument.GetViews().Find(DocContent);
|
|
|
|
// If not, Create an TOcLinkView for the linked doc/item
|
|
// the TOcLinkView should remember the moniker
|
|
//
|
|
if (!ocLinkView) {
|
|
ocLinkView = new TOcLinkView(this, RegList);
|
|
OcDocument.GetViews().Add(ocLinkView);
|
|
ocLinkView->SetMoniker(OleStr(DocContent));
|
|
ocLinkView->GetLinkRect();
|
|
}
|
|
|
|
return ocLinkView;
|
|
}
|
|
|
|
void
|
|
TOcView::EvResize()
|
|
{
|
|
if (BDocumentI)
|
|
BDocumentI->OnResize();
|
|
}
|
|
|
|
//
|
|
// View is shuting down
|
|
//
|
|
void
|
|
TOcView::EvClose()
|
|
{
|
|
// Release the data provider object
|
|
//
|
|
if (OcData) {
|
|
OcData->Disconnect();
|
|
OcData = 0;
|
|
}
|
|
|
|
if (BContainer && BDocument && BDocumentI) {
|
|
// Unregisters drag target
|
|
//
|
|
BDocumentI->OnClose();
|
|
|
|
// Unregisters moniker for this container
|
|
//
|
|
if (BLDocumentI)
|
|
BLDocumentI->OnRename(0, 0);
|
|
}
|
|
}
|
|
|
|
//
|
|
// View is activated/deactivated
|
|
//
|
|
void
|
|
TOcView::EvActivate(bool activate)
|
|
{
|
|
// Set the current active document
|
|
//
|
|
if (BDocumentI)
|
|
BDocumentI->OnActivate(activate);
|
|
if (activate)
|
|
OcDocument.SetActiveView(this);
|
|
}
|
|
|
|
//
|
|
// Returns true if view keeps focus, false if the inplace server got it
|
|
//
|
|
bool
|
|
TOcView::EvSetFocus(bool set)
|
|
{
|
|
if (BDocumentI)
|
|
BDocumentI->OnSetFocus(set);
|
|
|
|
return OcApp.EvSetFocus(set);
|
|
}
|
|
|
|
bool
|
|
TOcView::EnumLinks(IBLinkInfo far* far* linkInfo)
|
|
{
|
|
PRECONDITION(linkInfo);
|
|
|
|
return BDocumentI ? HRSucceeded(BDocumentI->EnumLinks(linkInfo)) : false;
|
|
}
|
|
|
|
bool
|
|
TOcView::BrowseLinks()
|
|
{
|
|
return BDocumentI ? HRSucceeded(BDocumentI->BrowseLinks()) : false;
|
|
}
|
|
|
|
bool
|
|
TOcView::UpdateLinks()
|
|
{
|
|
return BDocumentI ? HRSucceeded(BDocumentI->UpdateLinks()) : false;
|
|
}
|
|
|
|
void
|
|
TOcView::Rename()
|
|
{
|
|
if (!BLDocumentI || OcDocument.GetName().is_null())
|
|
return;
|
|
|
|
// update the file moniker
|
|
//
|
|
BLDocumentI->OnRename(0, OleStr(OcDocument.GetName().c_str()));
|
|
|
|
OcDocument.RenameParts(BLDocumentI);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
//
|
|
// Return the client rect for the view window
|
|
//
|
|
TRect
|
|
TOcView::GetWindowRect() const
|
|
{
|
|
TRect r;
|
|
const_cast<TOcView*>(this)->GetWindowRect(&r);
|
|
return r;
|
|
}
|
|
|
|
//
|
|
// Scroll this container window a give dx,dy
|
|
//
|
|
void
|
|
TOcView::ScrollWindow(int dx, int dy)
|
|
{
|
|
Origin += TPoint(dx, dy);
|
|
}
|
|
|
|
void
|
|
TOcView::InvalidatePart(TOcPartChangeInfo& changeInfo)
|
|
{
|
|
if (changeInfo.GetPart()) {
|
|
if (!ForwardEvent(OC_VIEWPARTINVALID, &changeInfo))
|
|
::InvalidateRect(GetWindow(), &(changeInfo.GetPart()->GetRect() - *(TSize*)&GetOrigin()), true);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Activate a given part
|
|
//
|
|
bool
|
|
TOcView::ActivatePart(TOcPart* part)
|
|
{
|
|
if (part == ActivePart)
|
|
return true;
|
|
|
|
if (ActivePart && ActivePart->IsActive()) {
|
|
ActivePart->Activate(false);
|
|
ActivePart = 0;
|
|
}
|
|
if (part) {
|
|
if (!part->IsActive() && !part->Activate(true))
|
|
return false;
|
|
ActivePart = part;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
uint32
|
|
TOcView::ForwardEvent(int eventId, const void far* param)
|
|
{
|
|
return ::SendMessage(GetWindow(), WM_OCEVENT, eventId, (LPARAM)param);
|
|
}
|
|
|
|
uint32
|
|
TOcView::ForwardEvent(int eventId, uint32 param)
|
|
{
|
|
return ::SendMessage(GetWindow(), WM_OCEVENT, eventId, param);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IBContains implementation
|
|
|
|
//
|
|
// Ask the container to load document named
|
|
//
|
|
HRESULT _IFUNC
|
|
TOcView::Init(LPCOLESTR path)
|
|
{
|
|
bool result = (bool)ForwardEvent(OC_VIEWOPENDOC, (const char far*)OleStr(path));
|
|
if (result) {
|
|
// register this document in running object table
|
|
//
|
|
|
|
OcDocument.SetName(string(OleStr(path)));
|
|
Rename();
|
|
}
|
|
|
|
return HRFailIfZero(result);
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::GetPart(IBPart far* far* bpart, LPCOLESTR name)
|
|
{
|
|
PRECONDITION(bpart);
|
|
|
|
for (TOcPartCollectionIter i(OcDocument.GetParts()); i; i++) {
|
|
TOcPart* ocPart = (TOcPart*)i.Current();
|
|
if (ocPart && strcmp(ocPart->GetName(), OleStr(name)) == 0) {
|
|
ocPart->FinishLoading(); // In case the part hasn't been loaded
|
|
if (SUCCEEDED(ocPart->QueryInterface(IID_IBPart, (LPVOID*)bpart))) {
|
|
return HR_NOERROR; // now there is one more refcount on ocPart
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ask the document whether an TOcLinkView corresponding to the item name
|
|
// already exists
|
|
//
|
|
TOcLinkView* ocLinkView = OcDocument.GetViews().Find(name);
|
|
if (ocLinkView) {
|
|
if (SUCCEEDED(ocLinkView->QueryInterface(IID_IBPart, (LPVOID*)bpart))) {
|
|
return HR_NOERROR; // now there is one more refcount on ocRemView
|
|
}
|
|
else
|
|
return HR_FAIL;
|
|
}
|
|
|
|
// If not, Create an TOcLinkView for the linked doc/item
|
|
// the TOcLinkView should remember the moniker
|
|
//
|
|
if (!ocLinkView) {
|
|
ocLinkView = new TOcLinkView(this, RegList);
|
|
OcDocument.GetViews().Add(ocLinkView);
|
|
}
|
|
|
|
ocLinkView->SetMoniker(OleStr(name));
|
|
ocLinkView->GetLinkRect();
|
|
if (SUCCEEDED(ocLinkView->QueryInterface(IID_IBPart, (LPVOID*)bpart)) &&
|
|
ForwardEvent(OC_VIEWSETLINK, ocLinkView)) {
|
|
return HR_NOERROR; // now there is one more refcount on ocRemView
|
|
}
|
|
|
|
return HR_FAIL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IBDataNegotiator implementation
|
|
|
|
//
|
|
// Format count
|
|
//
|
|
uint _IFUNC
|
|
TOcView::CountFormats()
|
|
{
|
|
return FormatList.Count();
|
|
}
|
|
|
|
//
|
|
// Format retrieval
|
|
//
|
|
HRESULT _IFUNC
|
|
TOcView::GetFormat(uint index, TOcFormatInfo far* fmt)
|
|
{
|
|
PRECONDITION(fmt);
|
|
|
|
// Link source is FormatList[0]
|
|
// Link source will be the first format returned if Link is 0
|
|
// Link source will be the last format returned if Link is -1
|
|
//
|
|
index = (index - LinkFormat) % CountFormats();
|
|
FormatList[index]->GetFormatInfo(*fmt);
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IBWindow implementation
|
|
|
|
HWND _IFUNC
|
|
TOcView::GetWindow()
|
|
{
|
|
return Win;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::GetWindowRect(TRect far* r)
|
|
{
|
|
PRECONDITION(r);
|
|
|
|
::GetClientRect(GetWindow(), r);
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
LPCOLESTR _IFUNC
|
|
TOcView::GetWindowTitle()
|
|
{
|
|
// Delegate to app's view window to get its title
|
|
//
|
|
OrgTitle = (const char far*)ForwardEvent(OC_VIEWTITLE);
|
|
return (LPCOLESTR)OrgTitle;
|
|
}
|
|
|
|
//
|
|
// Append server's doc title info to our view's window title
|
|
//
|
|
void _IFUNC
|
|
TOcView::AppendWindowTitle(LPCOLESTR title)
|
|
{
|
|
WinTitle = (const char far*)OleStr(GetWindowTitle());
|
|
char in[32];
|
|
::LoadString(_hInstance, IDS_IN, in, sizeof in);
|
|
|
|
string newTitle = (const char far*)OleStr(title);
|
|
newTitle += in;
|
|
newTitle += WinTitle;
|
|
ForwardEvent(OC_VIEWSETTITLE, newTitle.c_str());
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::SetStatusText(LPCOLESTR /*text*/)
|
|
{
|
|
return HR_FAIL;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::RequestBorderSpace(const TRect far* space)
|
|
{
|
|
PRECONDITION(space);
|
|
|
|
// Let individual views decide this
|
|
//
|
|
return HRFailIfZero((bool)ForwardEvent(OC_VIEWBORDERSPACEREQ, space));
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::SetBorderSpace(const TRect far* space)
|
|
{
|
|
PRECONDITION(space);
|
|
|
|
// Let individual views do this
|
|
//
|
|
return HRFailIfZero((bool)ForwardEvent(OC_VIEWBORDERSPACESET, space));
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::InsertContainerMenus(HMENU, TOcMenuWidths far*)
|
|
{
|
|
return HR_FAIL;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::SetFrameMenu(HMENU)
|
|
{
|
|
return HR_FAIL;
|
|
}
|
|
|
|
//
|
|
// The in-place server is done. Tell the container to restore its normal UI.
|
|
//
|
|
void _IFUNC
|
|
TOcView::RestoreUI()
|
|
{
|
|
ForwardEvent(OC_VIEWSETTITLE, WinTitle.c_str());
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::Accelerator(MSG far*)
|
|
{
|
|
return HR_FAIL;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::GetAccelerators(HACCEL far*, int far*)
|
|
{
|
|
return HR_FAIL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IBDropDest implementation
|
|
|
|
//
|
|
// Drop a part onto this view. Creates the part based on initInfo, activating
|
|
// it as appropriate
|
|
//
|
|
HRESULT _IFUNC
|
|
TOcView::Drop(TOcInitInfo far* initInfo, TPoint far* where, const TRect far* objPos)
|
|
{
|
|
PRECONDITION(initInfo && where && objPos);
|
|
|
|
initInfo->Container = this;
|
|
TPoint awhere(*where);
|
|
TRect aobjPos(*objPos);
|
|
TOcDragDrop dd = {
|
|
(TOcInitInfo far*)initInfo, &awhere, &aobjPos
|
|
};
|
|
|
|
if (PasteNative((TOcInitInfo&)*initInfo, where))
|
|
return HR_NOERROR;
|
|
|
|
// Make sure that the view will accept this drop
|
|
//
|
|
if (!ForwardEvent(OC_VIEWDROP, &dd))
|
|
return HR_FAIL;
|
|
|
|
// Create part now that view approved. BDocument calls AddSite on all views.
|
|
//
|
|
try {
|
|
new TOcPart(OcDocument, *dd.InitInfo, aobjPos);
|
|
}
|
|
catch (...) {
|
|
return HR_FAIL;
|
|
}
|
|
|
|
Rename();
|
|
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
//
|
|
// Provide feedback to the users drag action in our container window
|
|
//
|
|
void _IFUNC
|
|
TOcView::DragFeedback(TPoint far* where, const TRect far* objPos, TOcMouseAction /*action*/, uint, HRESULT& hr)
|
|
{
|
|
PRECONDITION(where && objPos);
|
|
|
|
TPoint awhere(*where);
|
|
TRect aobjPos(*objPos);
|
|
TOcDragDrop dd = { 0, &awhere, &aobjPos };
|
|
hr = HRFailIfZero((int)ForwardEvent(OC_VIEWDRAG, &dd));
|
|
}
|
|
|
|
//
|
|
// Ask the container view window to scroll itself in a given direction. Asked
|
|
// by the server when dragging or working in a clipped site.
|
|
//
|
|
HRESULT _IFUNC
|
|
TOcView::Scroll(TOcScrollDir scrollDir)
|
|
{
|
|
// Have the real view do the work here.
|
|
//
|
|
if (!ForwardEvent(OC_VIEWSCROLL, scrollDir))
|
|
return HR_FALSE;
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::GetScrollRect(TRect far*)
|
|
{
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IBContainer implementation
|
|
|
|
//
|
|
// Locate the drop destination object. For default OC, it is just this view.
|
|
// Other extensions might have subtargets within the view.
|
|
//
|
|
HRESULT _IFUNC
|
|
TOcView::FindDropDest(TPoint far*, IBDropDest far* far* dropDest)
|
|
{
|
|
*dropDest = this;
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::BringToFront()
|
|
{
|
|
// See if we are in an MDI child & if so activate it
|
|
//
|
|
HWND hMdiChild = ::GetParent(GetWindow());
|
|
if (hMdiChild) {
|
|
HWND hMdiClient = ::GetParent(hMdiChild);
|
|
if (hMdiClient) {
|
|
HWND hMdiFrame = ::GetParent(hMdiClient);
|
|
while (::GetParent(hMdiFrame)) {
|
|
hMdiChild = hMdiClient;
|
|
hMdiClient = hMdiFrame;
|
|
hMdiFrame = ::GetParent(hMdiFrame);
|
|
}
|
|
::SendMessage(hMdiClient, WM_MDIACTIVATE, (WPARAM)hMdiChild, 0);
|
|
}
|
|
}
|
|
|
|
// Bring our app frame to the top, show it & give it focus. Also make sure
|
|
// that this view is on top & visible
|
|
//
|
|
::SetWindowPos(OcApp.GetWindow(), HWND_TOP, 0, 0, 0, 0,
|
|
SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
|
|
::SetFocus(OcApp.GetWindow());
|
|
::ShowWindow(GetWindow(), SW_SHOWNORMAL);
|
|
::SetWindowPos(GetWindow(), HWND_TOP, 0, 0, 0, 0,
|
|
SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
|
|
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
HRESULT _IFUNC
|
|
TOcView::AllowInPlace()
|
|
{
|
|
if (IsOptionSet(voNoInPlace))
|
|
return HR_FALSE;
|
|
else
|
|
return HR_NOERROR;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Clipboard related
|
|
|
|
//
|
|
// Register the clipboard formats supported
|
|
//
|
|
bool
|
|
TOcView::RegisterClipFormats(TRegList& regList)
|
|
{
|
|
// Register link source first
|
|
//
|
|
uint cfLinkSource = ::RegisterClipboardFormat("Link Source");
|
|
if (cfLinkSource)
|
|
FormatList.Add(new TOcFormat(cfLinkSource, "%s", "%s",
|
|
4 /*BOLE_MED_STREAM*/, true));
|
|
|
|
char key[32];
|
|
char val[128];
|
|
char* buf;
|
|
uint i = 0;
|
|
bool succ = true;
|
|
|
|
while (true) {
|
|
wsprintf(key, "format%d", i);
|
|
buf = const_cast<char*>(regList[key]);
|
|
if (!buf)
|
|
break;
|
|
else {
|
|
// parse the value string
|
|
//
|
|
strcpy(val, buf);
|
|
buf = val;
|
|
|
|
TOcFormat* format = new TOcFormat;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
char* current = strchr(buf, ',');
|
|
if (!current) {
|
|
succ = false;
|
|
break; // error
|
|
}
|
|
|
|
*current = 0;
|
|
switch (i) {
|
|
case 0: // Format id or name
|
|
if (isdigit(*buf)) {
|
|
uint id = atoi(buf);
|
|
format->SetFormatId(id);
|
|
format->SetFormatName(id - 1, OcApp);
|
|
}
|
|
else { // register the user defined clipboard format
|
|
uint cf = ::RegisterClipboardFormat(buf);
|
|
if (cf == cfLinkSource)
|
|
format->SetLinkable();
|
|
|
|
format->SetFormatId(cf);
|
|
format->SetFormatName(buf, OcApp);
|
|
}
|
|
break;
|
|
|
|
case 1: // Aspect
|
|
format->SetAspect((uint)atoi(buf));
|
|
break;
|
|
|
|
case 2:
|
|
format->SetMedium((uint)atoi(buf)); // Storage medium
|
|
format->SetDirection((uint)atoi(current+1)); // Direction
|
|
break;
|
|
} // switch
|
|
|
|
buf = current + 1;
|
|
} // for
|
|
|
|
if (succ)
|
|
FormatList.Add(format); // Add to the format list
|
|
else
|
|
delete format;
|
|
} // else
|
|
|
|
i++;
|
|
} // while
|
|
|
|
return succ;
|
|
}
|
|
|
|
bool
|
|
TOcView::BrowseClipboard(TOcInitInfo& initInfo)
|
|
{
|
|
return OcApp.BrowseClipboard(initInfo);
|
|
}
|
|
|
|
//
|
|
// Paste native data into the container
|
|
//
|
|
bool
|
|
TOcView::PasteNative(TOcInitInfo& init, TPoint far* where)
|
|
{
|
|
bool result = false;
|
|
if ((init.Where == iwHandle) && (init.How == ihEmbed)) { // could be native data
|
|
TOcFormat* format = FormatList.Find(init.Handle.DataFormat);
|
|
if (!format) {
|
|
return false; // not my native data
|
|
}
|
|
|
|
TOcFormatData formatData(*format, 0, init.Handle.Data, true, where);
|
|
result = (bool)ForwardEvent(OC_VIEWCLIPDATA, &formatData);
|
|
if (result)
|
|
init.ReleaseDataObject();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool
|
|
TOcView::Paste(bool linking)
|
|
{
|
|
LinkFormat = linking ? 0 : -1;
|
|
TOcInitInfo init(this);
|
|
bool result = OcApp.Paste(init);
|
|
|
|
if (result) {
|
|
result = PasteNative(init);
|
|
if (!result)
|
|
result = (bool)ForwardEvent(OC_VIEWPASTEOBJECT, &init);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// TOcFormat
|
|
//
|
|
|
|
TOcFormat::TOcFormat()
|
|
{
|
|
char fstr[] = "%s";
|
|
|
|
Id = 0;
|
|
RegName[0] = 0;
|
|
strcpy(Name, fstr);
|
|
strcpy(ResultName, fstr);
|
|
Medium = ocrNull;
|
|
IsLinkable = false;
|
|
Aspect = 1; // content
|
|
Direction = 1; // get
|
|
}
|
|
|
|
TOcFormat::TOcFormat(uint id, char far* name, char far* resultName,
|
|
uint medium, bool isLinkable,
|
|
uint aspect, uint direction)
|
|
{
|
|
Id = (WORD)id;
|
|
Medium = (ocrMedium)medium;
|
|
IsLinkable = isLinkable;
|
|
Aspect = aspect;
|
|
Direction = direction;
|
|
|
|
RegName[0] = 0;
|
|
strcpy(Name, name);
|
|
strcpy(ResultName, resultName);
|
|
}
|
|
|
|
void
|
|
TOcFormat::operator =(const TOcFormatInfo& f)
|
|
{
|
|
Id = f.Id;
|
|
strcpy(Name, OleStr(f.Name));
|
|
strcpy(ResultName, OleStr(f.ResultName));
|
|
Medium = f.Medium;
|
|
IsLinkable = f.IsLinkable;
|
|
}
|
|
|
|
void
|
|
TOcFormat::GetFormatInfo(TOcFormatInfo far& f)
|
|
{
|
|
f.Id = uint16(Id);
|
|
#if defined(BI_OLECHAR_WIDE)
|
|
// lstrcpyW(f.Name, OleStr(Name));
|
|
memcpy(f.Name, (LPCWSTR)OleStr(Name), (strlen(Name)+1)*2);
|
|
// lstrcpyW(f.ResultName, OleStr(ResultName));
|
|
memcpy(f.ResultName, (LPCWSTR)OleStr(ResultName), (strlen(ResultName)+1)*2);
|
|
#else
|
|
strncpy(f.Name, Name, sizeof Name);
|
|
strncpy(f.ResultName, ResultName, sizeof ResultName);
|
|
#endif
|
|
f.Medium = (ocrMedium)Medium;
|
|
f.IsLinkable = (BOOL)IsLinkable;
|
|
}
|
|
|
|
void
|
|
TOcFormat::SetFormatName(char far* name, TOcApp& ocApp)
|
|
{
|
|
TOcFormatName* formatName = ocApp.GetNameList()[name];
|
|
if (!formatName)
|
|
return;
|
|
|
|
strcpy(RegName, name);
|
|
strcpy(Name, formatName->GetName());
|
|
strcpy(ResultName, formatName->GetResultName());
|
|
}
|
|
|
|
void
|
|
TOcFormat::SetFormatName(uint id, TOcApp& ocApp)
|
|
{
|
|
TOcFormatName* formatName = ocApp.GetNameList()[id];
|
|
if (!formatName)
|
|
return;
|
|
|
|
strcpy(Name, formatName->GetName());
|
|
strcpy(ResultName, formatName->GetResultName());
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// TOcFormatList
|
|
//
|
|
|
|
TOcFormatList::TOcFormatList()
|
|
: TICVectorImp<TOcFormat>(10, 0)
|
|
{
|
|
}
|
|
|
|
TOcFormatList::~TOcFormatList()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
TOcFormat*
|
|
TOcFormatList::Find(uint const id) const
|
|
{
|
|
for (TOcFormatListIter j(*this); j; j++) {
|
|
TOcFormat* format = (TOcFormat*)j.Current();
|
|
if (format && (format->GetFormatId() == id)) {
|
|
return format;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// TOcScaleFactor
|
|
//
|
|
|
|
TOcScaleFactor::TOcScaleFactor()
|
|
:
|
|
SiteSize(1, 1),
|
|
PartSize(1, 1)
|
|
{
|
|
}
|
|
|
|
TOcScaleFactor::TOcScaleFactor(const TRect& siteRect, const TSize& partSize)
|
|
{
|
|
SiteSize.cx = siteRect.Width();
|
|
SiteSize.cy = siteRect.Height();
|
|
|
|
PartSize = partSize;
|
|
}
|
|
|
|
TOcScaleFactor::TOcScaleFactor(const TOcScaleInfo far& scale)
|
|
{
|
|
*this = scale;
|
|
}
|
|
|
|
//
|
|
// Assign a BOle structure to this scale factor
|
|
//
|
|
TOcScaleFactor&
|
|
TOcScaleFactor::operator =(const TOcScaleInfo far& scaleInfo)
|
|
{
|
|
SiteSize.cx = (int)scaleInfo.xN;
|
|
SiteSize.cy = (int)scaleInfo.yN;
|
|
PartSize.cx = (int)scaleInfo.xD;
|
|
PartSize.cy = (int)scaleInfo.yD;
|
|
|
|
return *this;
|
|
}
|
|
|
|
//
|
|
// Assign one TOcScaleFactor to another
|
|
//
|
|
TOcScaleFactor&
|
|
TOcScaleFactor::operator =(const TOcScaleFactor& scaleFactor)
|
|
{
|
|
SiteSize = scaleFactor.SiteSize;
|
|
PartSize = scaleFactor.PartSize;
|
|
|
|
return *this;
|
|
}
|
|
|
|
//
|
|
// Copy a BOle scale factor structure
|
|
//
|
|
void
|
|
TOcScaleFactor::GetScaleFactor(TOcScaleInfo far& scaleInfo) const
|
|
{
|
|
scaleInfo.xN = SiteSize.cx;
|
|
scaleInfo.yN = SiteSize.cy;
|
|
scaleInfo.xD = PartSize.cx;
|
|
scaleInfo.yD = PartSize.cy;
|
|
}
|
|
|
|
//
|
|
// Whether there is zoom factor
|
|
//
|
|
bool
|
|
TOcScaleFactor::IsZoomed()
|
|
{
|
|
return SiteSize != PartSize;
|
|
}
|
|
|
|
//
|
|
// Change the scaling factor
|
|
//
|
|
void
|
|
TOcScaleFactor::SetScale(uint16 percent)
|
|
{
|
|
PartSize.cx = PartSize.cy = 100;
|
|
SiteSize.cx = SiteSize.cy = percent;
|
|
}
|
|
|
|
//
|
|
// Get the scale percentage
|
|
//
|
|
uint16
|
|
TOcScaleFactor::GetScale()
|
|
{
|
|
return (uint16)(((uint32)SiteSize.cx * 100 + (PartSize.cx >> 1)) / PartSize.cx);
|
|
}
|
|
|
|
//
|
|
// Set scaling factor to 1
|
|
//
|
|
void
|
|
TOcScaleFactor::Reset()
|
|
{
|
|
PartSize.cx = PartSize.cy = 1;
|
|
SiteSize.cx = SiteSize.cy = 1;
|
|
}
|
|
|