home *** CD-ROM | disk | FTP | other *** search
- // baseview.cpp
- //
- // Created 10/07/98
- //
- // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
- //
-
- #include "pch.hpp"
- #pragma hdrstop
-
- #include "baseview.hpp"
- #include "hpmonmgr.hpp"
-
-
- //static
- LRESULT CALLBACK BasicClient::BaseWndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- BasicClient *bc;
- MDICREATESTRUCT *pmdics;
-
- case WM_CREATE:
-
- pmdics = (MDICREATESTRUCT*)((CREATESTRUCT*)lParam)->lpCreateParams;
- bc = (BasicClient*)pmdics->lParam;
-
- // See WM_CLOSE for explanation of why this store can't be AddRef'd.
- SetWindowLong(wnd, GWL_USERDATA, (LONG)bc);
-
- bc->m_hwnd = wnd;
- if (bc->OnCreateWindow())
- {
- bc->AddRef();
- }
- else
- {
- bc->m_hwnd = NULL;
-
- DestroyWindow(wnd);
- }
-
- return 0;
-
- case WM_CLOSE:
-
- bc = (BasicClient*)GetWindowLong(wnd, GWL_USERDATA);
-
- bc->m_mgr->UnregisterClient(bc);
-
- // Do NOT call DestroyWindow here. See
- // HeapMonitorManager::IterateClients. Because it cannot be holding
- // locks while sending messages to the UI thread, it may
- // simultaneously be sending a message to this window, so our HWND
- // needs to remain valid until the refcount reaches 0.
-
- // We must release the window's reference to the client now (was
- // AddRef'd above for GWL_USERDATA). If there are no other references
- // to the window (99.99% case), this is effectively calling
- // DestroyWindow. If not, some other thread is keeping the client
- // live, and we'll leave the GWL_USERDATA intact so that pending
- // messages can actually be processed.
- bc->Release();
-
- // TODO: switch to hourglass or something
-
- return 0;
-
- case WM_DESTROY:
-
- bc = (BasicClient*)GetWindowLong(wnd, GWL_USERDATA);
- ASSERT(bc);
-
- // REMIND: this may occur inside the manager's critical section.
-
- bc->m_hwnd = NULL;
- SetWindowLong(wnd, GWL_USERDATA, NULL);
-
- break;
-
- case WM_BC_DESTROY_NOW:
-
- bc = (BasicClient*)GetWindowLong(wnd, GWL_USERDATA);
- ASSERT(bc);
-
- // REMIND: this may occur inside the manager's critical section.
-
- SendMessage(bc->m_mgr->GetMDIClientWindow(), WM_MDIDESTROY, (WPARAM)wnd, 0);
- DestroyWindow(wnd);
-
- delete(bc);
- bc = NULL;
-
- return 0;
- }
-
- // REMIND: WM_CHILDACTIVATE, WM_GETMINMAXINFO, WM_MENUCHAR, WM_MOVE,
- // WM_SETFOCUS, WM_SIZE, and WM_SYSCOMMAND must be passed to the mdi proc.
-
- return DefMDIChildProc(wnd, msg, wParam, lParam);
- }
-
-
- BasicClient::BasicClient ()
- {
- m_RefCount = 1;
- m_mgr = NULL;
- }
-
- BasicClient::~BasicClient ()
- {
- ASSERT(!m_RefCount);
-
- // REMIND: this may occur inside the manager's critical section.
-
- if (m_mgr != NULL)
- {
- m_mgr->Release();
- }
- }
-
- BOOL BasicClient::BasePreInitialize (HeapMonitorManager *mgr, PCSTR wndclsname, PCSTR wndtitle)
- {
- BOOL result;
-
- (m_mgr = mgr)->AddRef();
-
- result = CreateMDIWindow(
- (PSTR)wndclsname,
- (PSTR)wndtitle,
- 0,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- mgr->GetMDIClientWindow(),
- mgr->GetInstance(),
- (LPARAM)this) != NULL;
-
- return result;
- }
-
- BOOL BasicClient::BasePostInitialize (HeapMonitorClientRegistrationInfo *preginfo)
- {
- BOOL result;
-
- result = m_mgr->RegisterClient(this, preginfo);
-
- if (!result)
- SendMessage(m_hwnd, WM_CLOSE, 0, 0);
-
- return result;
- }
-
-
- ULONG STDMETHODCALLTYPE BasicClient::AddRef (VOID)
- {
- ASSERT(m_RefCount && m_RefCount < ULONG_MAX);
-
- return InterlockedIncrement((LONG*)&m_RefCount);
- }
-
-
- ULONG STDMETHODCALLTYPE BasicClient::Release (VOID)
- {
- ASSERT(m_RefCount);
-
- ULONG NewRefCount = (ULONG)InterlockedDecrement((LONG*)&m_RefCount);
- if (NewRefCount)
- return NewRefCount;
-
- // REMIND: this may occur inside the manager's critical section.
-
- if (m_hwnd)
- SendNotifyMessage(m_hwnd, WM_BC_DESTROY_NOW, 0, 0);
- else
- delete(this);
-
- return 0;
-
- }
-
-
- STDMETHODIMP BasicClient::QueryInterface (REFIID riid, PVOID *ppvObj)
- {
- HRESULT hr = S_OK;
-
- if (riid == IID_IUnknown || riid == IID_IHeapMonitorClient)
- {
- *ppvObj = (IHeapMonitorClient*)this;
- AddRef();
- }
- else
- {
- *ppvObj = NULL;
- hr = E_NOINTERFACE;
- }
-
- return hr;
- }
-
-