/* 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); }