/*
Module : PUSHPINFRAME.CPP
Purpose: Implementation of a push pin property dialog similar
to the ones seen in VC 4/5
Created: PJN / 24-11-1997
History: PJN / 16-04-1998 window now only closes if the window which is
going active is owned by the same parent as
the pushpin frame
PJN / 01-06-1999 1. Now supports changing the attached property sheet
through the new ChangeAttachPropertySheet function.
2. Did a bit of a tidy up of the source code
PJN / 02-06-1999 1. Updated code to work with the new v1.12 release
of CPushPinButton
2. Removed a number of unnecessary comments in the code.
3. Renamed a number of project files and workspace files
to be more descriptive.
4. Update a number of bugs / errors in this help file.
5. Fixed a small clipping bug where the push pin was being
clipped by the edge of the property sheet
Copyright (c) 1997 - 1999 by PJ Naughter.
All rights reserved.
*/
///////////////////////////////// Includes //////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "PushPinFrame.h"
////////////////////////////////// Macros ///////////////////////////////////
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
const int PUSHPIN_SHEET_EDGE = 24; //the horizontal offset of the property sheet
//from the edge of the frame window
////////////////////////////////// Implementation /////////////////////////////
IMPLEMENT_DYNCREATE(CPushPinFrame, CFrameWnd)
CPushPinFrame::CPushPinFrame()
{
m_pModelessPropSheet = NULL;
m_pRuntimeModelessPropSheet = NULL;
}
CPushPinFrame::~CPushPinFrame()
{
}
BEGIN_MESSAGE_MAP(CPushPinFrame, CFrameWnd)
//{{AFX_MSG_MAP(CPushPinFrame)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_ACTIVATE()
ON_WM_PAINT()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CPushPinFrame::SetAttachedPropertySheet(CRuntimeClass* pRuntimeModelessPropSheet)
{
//Validate our parameters
ASSERT(pRuntimeModelessPropSheet);
ASSERT(pRuntimeModelessPropSheet->IsDerivedFrom(RUNTIME_CLASS(CPropertySheet)));
m_pRuntimeModelessPropSheet = pRuntimeModelessPropSheet;
}
BOOL CPushPinFrame::ChangeAttachedPropertySheet(CRuntimeClass* pRuntimePropSheet)
{
//Close and delete the old property sheet
ASSERT(m_pModelessPropSheet); //Must have been created to change it
m_pModelessPropSheet->SendMessage(WM_CLOSE);
delete m_pModelessPropSheet;
m_pModelessPropSheet = NULL;
//Hive away the runtime class
SetAttachedPropertySheet(pRuntimePropSheet);
//Create the new property sheet
m_pModelessPropSheet = (CPropertySheet*) pRuntimePropSheet->CreateObject();
ASSERT(m_pModelessPropSheet); //Your class is probably not DECLARE_DYNCREATE
ASSERT(m_pModelessPropSheet->IsKindOf(RUNTIME_CLASS(CPropertySheet)));
if (!m_pModelessPropSheet->Create(this, WS_CHILD | WS_VISIBLE,0))
{
delete m_pModelessPropSheet;
m_pModelessPropSheet = NULL;
SetRedraw(TRUE);
return FALSE;
}
//Move the property sheet into the same place as the first propery sheet
m_pModelessPropSheet->SetWindowPos(NULL, m_RectPropSheet.left, m_RectPropSheet.top, m_RectPropSheet.Width(),
m_RectPropSheet.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
return TRUE;
}
int CPushPinFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//Let the parent class do its thing
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//Validate our variables
ASSERT(m_pModelessPropSheet == NULL);
ASSERT(m_pRuntimeModelessPropSheet); //You forgot to call SetAttachedPropertySheet before creation !!
//create the property page as a child of this frame window
m_pModelessPropSheet = (CPropertySheet*) m_pRuntimeModelessPropSheet->CreateObject();
ASSERT(m_pModelessPropSheet); //Your class is probably not DECLARE_DYNCREATE
ASSERT(m_pModelessPropSheet->IsKindOf(RUNTIME_CLASS(CPropertySheet)));
if (!m_pModelessPropSheet->Create(this, WS_CHILD | WS_VISIBLE, 0))
{
delete m_pModelessPropSheet;
m_pModelessPropSheet = NULL;
return -1;
}
// Resize the mini frame so that it fits around the child property
// sheet with space for the push pin in top left hand corner
CRect rectClient;
m_pModelessPropSheet->GetWindowRect(rectClient);
rectClient.right += PUSHPIN_SHEET_EDGE;
m_RectPropSheet = rectClient;
// CFrameWnd::CalcWindowRect adds the extra width and height needed from the mini frame.
CalcWindowRect(m_RectPropSheet);
//Resize this window to suit the property sheet
SetWindowPos(NULL, m_RectPropSheet.left, m_RectPropSheet.top, m_RectPropSheet.Width(),
m_RectPropSheet.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
//Move the property sheet into place
m_RectPropSheet.left += PUSHPIN_SHEET_EDGE;
m_pModelessPropSheet->SetWindowPos(NULL, m_RectPropSheet.left, m_RectPropSheet.top, m_RectPropSheet.Width(),
m_RectPropSheet.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
//Create the push pin in the top left hand corner of the frame window
m_PushPin.Create(_T(""), BS_OWNERDRAW | WS_CHILD | WS_VISIBLE, CRect(2, 8, 0, 0), this, 100);
m_PushPin.SetPinned(TRUE);
m_PushPin.SetUseEdgeBitmap(TRUE);
return 0;
}
void CPushPinFrame::OnClose()
{
// Instead of closing the modeless property sheet, just hide it.
ShowWindow(SW_HIDE);
}
void CPushPinFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
//Let the parent class do its thing
CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
// Forward any WM_ACTIVATEs to the property sheet...
// Like the dialog manager itself, it needs them to save/restore the focus.
ASSERT_VALID(m_pModelessPropSheet);
// Use GetCurrentMessage to get unmodified message data.
const MSG* pMsg = GetCurrentMessage();
ASSERT(pMsg->message == WM_ACTIVATE);
m_pModelessPropSheet->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
//if we lose activation and we are not pinned and
//the other window is an owned by the same toplevel window
//then close this window
if (nState == WA_INACTIVE && !m_PushPin.IsPinned() && OwnedBySameParent(pWndOther))
PostMessage(WM_CLOSE);
}
BOOL CPushPinFrame::OwnedBySameParent(CWnd* pWnd)
{
if (!pWnd)
return FALSE;
return (GetTopLevelOwner()->GetSafeHwnd() == pWnd->GetTopLevelOwner()->GetSafeHwnd());
}
void CPushPinFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
//Paint the client area of the frame window with
//the 3d color to make it look like a modal
//propery sheet
CRect r;
GetClientRect(&r);
dc.FillSolidRect(r, GetSysColor(COLOR_3DFACE));
}
BOOL CPushPinFrame::PreCreateWindow(CREATESTRUCT& cs)
{
//modify the styles to make the frame window
//like a modal property sheet
// WS_4THICKFRAME and MFS_THICKFRAME imply WS_THICKFRAME
if (cs.style & (MFS_4THICKFRAME | MFS_THICKFRAME))
cs.style |= WS_THICKFRAME;
// WS_CAPTION implies WS_EX_TOOLWINDOW
if (cs.style & WS_CAPTION)
cs.dwExStyle |= WS_EX_TOOLWINDOW;
//Let the parent class do its thing
BOOL bSuccess = CFrameWnd::PreCreateWindow(cs);
VERIFY(bSuccess);
cs.dwExStyle &= ~(WS_EX_CLIENTEDGE);
return bSuccess;
}
void CPushPinFrame::OnDestroy()
{
//Ensure the property sheet has been cleaned up
ASSERT(m_pModelessPropSheet != NULL);
m_pModelessPropSheet->SendMessage(WM_CLOSE);
delete m_pModelessPropSheet;
m_pModelessPropSheet = NULL;
//Let the parent do its thing
CFrameWnd::OnDestroy();
}
A Freeware MFC PushPin property page dialog class.(19KB)
需积分: 50 30 浏览量
2006-02-23
09:05:59
上传
评论
收藏 18KB ZIP 举报
评论0
最新资源