Microsoft-3D-Movie-Maker/kauai/SRC/GOBWIN.CPP
2022-05-03 16:31:19 -07:00

253 lines
6.3 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
Author: ShonK
Project: Kauai
Reviewed:
Copyright (c) Microsoft Corporation
Graphic object class.
***************************************************************************/
#include "frame.h"
ASSERTNAME
PGOB GOB::_pgobScreen;
/***************************************************************************
Create the screen gob. If fgobEnsureHwnd is set, ensures that the
screen gob has an OS window associated with it.
***************************************************************************/
bool GOB::FInitScreen(ulong grfgob, long ginDef)
{
PGOB pgob;
GCB gcb(khidScreen, pvNil);
switch (ginDef)
{
case kginDraw:
case kginMark:
case kginSysInval:
_ginDefGob = ginDef;
break;
}
if (pvNil == (pgob = NewObj GOB(&gcb)))
return fFalse;
Assert(pgob == _pgobScreen, 0);
if (!pgob->FAttachHwnd(vwig.hwndApp))
return fFalse;
return fTrue;
}
/***************************************************************************
Make the GOB a wrapper for the given system window.
***************************************************************************/
bool GOB::FAttachHwnd(HWND hwnd)
{
if (_hwnd != hNil)
{
ReleasePpo(&_pgpt);
//don't destroy the hwnd - the caller must do that
_hwnd = hNil;
}
if (hwnd != hNil)
{
if (pvNil == (_pgpt = GPT::PgptNewHwnd(hwnd)))
return fFalse;
_hwnd = hwnd;
SetRcFromHwnd();
}
return fTrue;
}
/***************************************************************************
Find the GOB associated with the given hwnd (if there is one).
***************************************************************************/
PGOB GOB::PgobFromHwnd(HWND hwnd)
{
//NOTE: we used to use SetProp and GetProp for this, but profiling
//indicated that GetProp is very slow.
Assert(hwnd != hNil, "nil hwnd");
GTE gte;
ulong grfgte;
PGOB pgob;
gte.Init(_pgobScreen, fgteNil);
while (gte.FNextGob(&pgob, &grfgte, fgteNil))
{
if (pgob->_hwnd == hwnd)
return pgob;
}
return pvNil;
}
/***************************************************************************
Return the active MDI window.
***************************************************************************/
HWND GOB::HwndMdiActive(void)
{
if (vwig.hwndClient == hNil)
return hNil;
return (HWND)SendMessage(vwig.hwndClient, WM_MDIGETACTIVE, 0, 0);
}
/***************************************************************************
Creates a new MDI window and returns it. This is normally then
attached to a gob.
***************************************************************************/
HWND GOB::_HwndNewMdi(PSTN pstnTitle)
{
AssertPo(pstnTitle, 0);
HWND hwnd, hwndT;
long lwStyle;
if (vwig.hwndClient == hNil)
{
//create the client first
CLIENTCREATESTRUCT ccs;
RCS rcs;
ccs.hWindowMenu = hNil;
ccs.idFirstChild = 1;
GetClientRect(vwig.hwndApp, &rcs);
Assert(rcs.left == 0 && rcs.top == 0, 0);
vwig.hwndClient = CreateWindow(PszLit("MDICLIENT"), NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
0, 0, rcs.right, rcs.bottom,
vwig.hwndApp, NULL, vwig.hinst, (LPVOID)&ccs);
if (vwig.hwndClient == hNil)
return hNil;
}
lwStyle = MDIS_ALLCHILDSTYLES | WS_CHILD | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
hwndT = HwndMdiActive();
if (hNil == hwndT || IsZoomed(hwndT))
lwStyle |= WS_MAXIMIZE;
hwnd = CreateMDIWindow(PszLit("MDI"), pstnTitle->Psz(), lwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
vwig.hwndClient, vwig.hinst, 0L);
if (hNil != hwnd && pvNil != vpmubCur)
vpmubCur->FAddListCid(cidChooseWnd, (long)hwnd, pstnTitle);
return hwnd;
}
/***************************************************************************
Destroy an hwnd.
***************************************************************************/
void GOB::_DestroyHwnd(HWND hwnd)
{
if (hwnd == vwig.hwndApp)
{
Bug("can't destroy app window");
return;
}
if (GetParent(hwnd) == vwig.hwndClient && vwig.hwndClient != hNil)
{
if (pvNil != vpmubCur)
vpmubCur->FRemoveListCid(cidChooseWnd, (long)hwnd);
SendMessage(vwig.hwndClient, WM_MDIDESTROY, (WPARAM)hwnd, 0);
}
else
DestroyWindow(hwnd);
}
/***************************************************************************
Gets the current mouse location in this gob's coordinates (if ppt is
not nil) and determines if the mouse button is down (if pfDown is
not nil).
***************************************************************************/
void GOB::GetPtMouse(PT *ppt, bool *pfDown)
{
AssertThis(0);
if (ppt != pvNil)
{
PTS pts;
long xp, yp;
PGOB pgob;
xp = yp = 0;
for (pgob = this; pgob != pvNil && pgob->_hwnd == hNil;
pgob = pgob->_pgobPar)
{
xp += pgob->_rcCur.xpLeft;
yp += pgob->_rcCur.ypTop;
}
GetCursorPos(&pts);
if (pgob != pvNil)
ScreenToClient(pgob->_hwnd, &pts);
*ppt = PT(pts);
ppt->xp -= xp;
ppt->yp -= yp;
}
if (pfDown != pvNil)
*pfDown = GetAsyncKeyState(VK_LBUTTON) < 0;
}
/***************************************************************************
Makes sure the GOB is clean (no update is pending).
***************************************************************************/
void GOB::Clean(void)
{
AssertThis(0);
HWND hwnd;
RC rc, rcT;
RCS rcs;
if (hNil == (hwnd = _HwndGetRc(&rc)))
return;
vpappb->InvalMarked(hwnd);
GetUpdateRect(hwnd, &rcs, fFalse);
rcT = RC(rcs);
if (rc.FIntersect(&rcT))
UpdateWindow(hwnd);
}
/***************************************************************************
Set the window name.
***************************************************************************/
void GOB::SetHwndName(PSTN pstn)
{
if (hNil == _hwnd)
{
Bug("GOB doesn't have an hwnd");
return;
}
if (pvNil != vpmubCur)
{
vpmubCur->FChangeListCid(cidChooseWnd, (long)_hwnd, pvNil,
(long)_hwnd, pstn);
}
SetWindowText(_hwnd, pstn->Psz());
}
/***************************************************************************
If this is one of our MDI windows, make it the active MDI window.
***************************************************************************/
void GOB::MakeHwndActive(HWND hwnd)
{
if (IsWindow(hwnd) && GetParent(hwnd) == vwig.hwndClient && vwig.hwndClient != hNil)
SendMessage(vwig.hwndClient, WM_MDIACTIVATE, (WPARAM)hwnd, 0);
}