Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

490 lines
11 KiB

// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFXCTL_PAGE_SEG
#pragma code_seg(AFXCTL_PAGE_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// CPicturePropPage implementation
BEGIN_MESSAGE_MAP(CPicturePropPage, CStockPropPage)
//{{AFX_MSG_MAP(CPicturePropPage)
ON_CBN_SELCHANGE(AFX_IDC_PROPNAME, OnSelchangePictProp)
ON_WM_PAINT()
ON_BN_CLICKED(AFX_IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(AFX_IDC_CLEAR, OnClear)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CPicturePropPage::CPicturePropPage() :
CStockPropPage(IDD, AFX_IDS_PICTURE_PPG_CAPTION),
m_pPictDisp(NULL)
{
//{{AFX_DATA_INIT(CPicturePropPage)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
CPicturePropPage::~CPicturePropPage()
{
// Release picture, if any
if (m_pPictDisp != NULL)
{
m_pPictDisp->Release();
m_pPictDisp = NULL;
}
}
BOOL CPicturePropPage::OnInitDialog()
{
m_pPictDisp = NULL;
SetModifiedFlag(FALSE);
CStockPropPage::OnInitDialog();
OnObjectsChanged();
IgnoreApply(AFX_IDC_BROWSE);
IgnoreApply(AFX_IDC_PROPNAME);
OnSelchangePictProp();
return TRUE;
}
void CPicturePropPage::DoDataExchange(CDataExchange* pDX)
{
//{{AFX_DATA_MAP(CPicturePropPage)
DDX_Control(pDX, AFX_IDC_PROPNAME, m_PropName);
DDX_Control(pDX, AFX_IDC_PICTURE, m_Static);
//}}AFX_DATA_MAP
if (pDX->m_bSaveAndValidate)
{
if (IsModified())
if (!SetPictureProp(pDX, m_pPictDisp, m_strPropName))
GetPictureProp(pDX, &m_pPictDisp, m_strPropName);
}
else
{
GetPictureProp(pDX, &m_pPictDisp, m_strPropName);
SetModifiedFlag(FALSE);
}
}
BOOL CPicturePropPage::SetPictureProp(CDataExchange*, LPPICTUREDISP pPictDisp, LPCTSTR pszPropName)
{
USES_CONVERSION;
COleDispatchDriver PropDispDriver;
// Set the properties for all the objects
ULONG nObjects;
LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
BOOL bSuccess = TRUE;
for (ULONG i = 0; bSuccess && (i < nObjects); i++)
{
DISPID dwDispID;
// Get the Dispatch ID for the property and if successful set the value of the property
LPCOLESTR lpOleStr = T2COLE(pszPropName);
if (SUCCEEDED(ppDisp[i]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr, 1, 0, &dwDispID)))
{
// Set property
PropDispDriver.AttachDispatch(ppDisp[i], FALSE);
TRY
{
PropDispDriver.SetProperty(dwDispID, VT_DISPATCH, pPictDisp);
}
CATCH(COleDispatchException, e)
{
// Display message box for dispatch exceptions.
e->ReportError(MB_ICONEXCLAMATION | MB_OK);
DELETE_EXCEPTION(e);
bSuccess = FALSE;
}
AND_CATCH_ALL(e)
{
// Ignore other exceptions.
DELETE_EXCEPTION(e);
}
END_CATCH_ALL
PropDispDriver.DetachDispatch();
}
}
return bSuccess;
}
BOOL CPicturePropPage::GetPictureProp(CDataExchange*, LPPICTUREDISP* ppPictDisp, LPCTSTR pszPropName)
{
USES_CONVERSION;
// Release previous picture, if any.
if (*ppPictDisp != NULL)
{
(*ppPictDisp)->Release();
*ppPictDisp = NULL;
}
COleDispatchDriver PropDispDriver;
ULONG nObjects;
LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
for (ULONG i = 0; i < nObjects; i++)
{
DISPID dwDispID;
// Get the Dispatch ID for the property and if successful set the value of the property
LPCOLESTR lpOleStr = T2COLE(pszPropName);
if (SUCCEEDED(ppDisp[i]->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr, 1, 0, &dwDispID)))
{
// Get property
LPPICTUREDISP pPictDisp = NULL;
PropDispDriver.AttachDispatch(ppDisp[i], FALSE);
TRY
PropDispDriver.GetProperty(dwDispID, VT_DISPATCH, &pPictDisp);
END_TRY
PropDispDriver.DetachDispatch();
// If more than one object, all pictures must be the same.
if ((i != 0) && (pPictDisp != *ppPictDisp))
{
if (*ppPictDisp != NULL)
(*ppPictDisp)->Release();
*ppPictDisp = NULL;
}
else
{
*ppPictDisp = pPictDisp;
}
// Don't keep multiple references to the picture.
if ((i != 0) && (pPictDisp != NULL))
pPictDisp->Release();
}
}
InvalidateRect(NULL);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CPicturePropPage message handlers
void CPicturePropPage::OnPaint()
{
CPaintDC dc(this); // device context for painting
// Determine rectangle for drawing picture
CRect rc;
m_Static.GetWindowRect(&rc);
rc.InflateRect(-::GetSystemMetrics(SM_CXBORDER) * 2,
-::GetSystemMetrics(SM_CYBORDER) * 2);
ScreenToClient(&rc);
LPPICTURE pPict = NULL;
if ((m_pPictDisp != NULL) &&
SUCCEEDED(m_pPictDisp->QueryInterface(IID_IPicture, (LPVOID*)&pPict)))
{
ASSERT(pPict != NULL);
// Draw it
OLE_XSIZE_HIMETRIC hmWidth;
OLE_YSIZE_HIMETRIC hmHeight;
pPict->get_Width(&hmWidth);
pPict->get_Height(&hmHeight);
int cxRect = rc.Width();
int cyRect = rc.Height();
if ((hmWidth != 0) && (hmHeight != 0) && (cxRect != 0) && (cyRect != 0))
{
// Adjust aspect ratio of rectangle to match picture.
int nPictureRatio = hmWidth * 1000 / hmHeight;
int nRectRatio = cxRect * 1000 / cyRect;
if (nPictureRatio > nRectRatio)
{
int dy = (cyRect - (cxRect * 1000 / nPictureRatio) + 1) / 2;
rc.InflateRect(0, -dy);
}
else
{
int dx = (cxRect - (cyRect * nPictureRatio / 1000) + 1) / 2;
rc.InflateRect(-dx, 0);
}
}
pPict->Render(dc.m_hDC, rc.left, rc.top, rc.Width(), rc.Height(),
0, hmHeight-1, hmWidth, -hmHeight, &rc);
pPict->Release();
}
}
HRESULT _AfxCreateStreamOnFile(LPCTSTR pszPath, LPSTREAM* ppstm,
LONG* plSize)
{
ASSERT(pszPath != NULL);
ASSERT(ppstm != NULL);
*ppstm = NULL;
if (plSize != NULL)
*plSize = 0;
CFileStatus fstatus;
CFile file;
HRESULT hr = E_FAIL;
LONG cb;
if (file.Open(pszPath, CFile::modeRead) &&
file.GetStatus(pszPath, fstatus) &&
((cb = fstatus.m_size) != -1))
{
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
BOOL bRead = (file.ReadHuge(pvData, cb) == (ULONG)cb);
GlobalUnlock(hGlobal);
if (bRead &&
SUCCEEDED(hr = CreateStreamOnHGlobal(hGlobal, TRUE, ppstm)))
{
ASSERT(*ppstm != NULL);
if (plSize != NULL)
*plSize = fstatus.m_size;
hr = S_OK;
}
}
if (FAILED(hr))
GlobalFree(hGlobal);
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_ACCESSDENIED;
}
return hr;
}
void CPicturePropPage::OnBrowse()
{
CString strFilter;
strFilter.LoadString(AFX_IDS_PICTUREFILTER);
CString strTitle;
strTitle.LoadString(AFX_IDS_PICTUREBROWSETITLE);
CFileDialog fdlg(TRUE, NULL, NULL,
OFN_FILEMUSTEXIST |
OFN_HIDEREADONLY |
OFN_PATHMUSTEXIST,
strFilter);
fdlg.m_ofn.lpstrTitle = strTitle;
int nResult = fdlg.DoModal();
SetFocus();
if (nResult != IDOK)
return;
CString strPath = fdlg.GetPathName();
LPSTREAM pstm = NULL;
LONG lSize;
HRESULT hr;
if (FAILED(hr = _AfxCreateStreamOnFile(strPath, &pstm, &lSize)))
{
UINT idsText;
CString strText;
CString strCaption;
switch (GetScode(hr))
{
case E_OUTOFMEMORY:
idsText = AFX_IDP_PICTURETOOLARGE;
break;
case E_ACCESSDENIED:
idsText = AFX_IDP_PICTURECANTOPEN;
break;
default:
idsText = AFX_IDP_PICTUREREADFAILED;
break;
}
AfxFormatString1(strText, idsText, strPath);
strCaption.LoadString(AFX_IDS_PICTURE_PPG_CAPTION);
MessageBox(strText, strCaption, MB_OK | MB_ICONEXCLAMATION);
SetFocus();
return;
}
ASSERT(pstm != NULL);
LPPICTURE pPict;
if (SUCCEEDED(OleLoadPicture(pstm, lSize, FALSE, IID_IPicture, (LPVOID *)&pPict)))
{
ChangePicture(pPict);
}
else
{
CString strText;
CString strCaption;
AfxFormatString1(strText, AFX_IDP_PICTURECANTLOAD, strPath);
strCaption.LoadString(AFX_IDS_PICTURE_PPG_CAPTION);
MessageBox(strText, strCaption, MB_OK | MB_ICONEXCLAMATION);
SetFocus();
}
pstm->Release();
}
static PICTDESC _pictDescEmpty =
{
sizeof(PICTDESC),
PICTYPE_NONE,
};
void CPicturePropPage::OnClear()
{
LPPICTURE pPict;
if (SUCCEEDED(OleCreatePictureIndirect(&_pictDescEmpty, IID_IPicture, TRUE,
(LPVOID *)&pPict)))
{
ChangePicture(pPict);
}
else
{
ASSERT(FALSE); // This should never happen!
}
}
void CPicturePropPage::ChangePicture(LPPICTURE pPict)
{
ASSERT(pPict != NULL);
LPPICTUREDISP pPictDisp = NULL;
if (SUCCEEDED(pPict->QueryInterface(IID_IPictureDisp,
(LPVOID*)&pPictDisp)))
{
ASSERT(pPictDisp != NULL);
if (m_pPictDisp != NULL)
m_pPictDisp->Release();
m_pPictDisp = pPictDisp;
SetModifiedFlag();
LPPROPERTYPAGESITE pPageSite = GetPageSite();
if (pPageSite != NULL)
pPageSite->OnStatusChange(
PROPPAGESTATUS_VALIDATE | PROPPAGESTATUS_DIRTY);
InvalidateRect(NULL);
}
pPict->Release();
}
void CPicturePropPage::OnSelchangePictProp()
{
OnSelchangePropname(m_PropName);
// disable Browse button if no property selected
CComboBox* pPropName = (CComboBox*)GetDlgItem(AFX_IDC_PROPNAME);
CWnd* pBrowse = GetDlgItem(AFX_IDC_BROWSE);
pBrowse->EnableWindow(pPropName->GetCurSel() != CB_ERR);
// redraw bitmap for new picture property
CRect rect;
m_Static.GetWindowRect(rect);
rect.InflateRect(-::GetSystemMetrics(SM_CXBORDER),
-::GetSystemMetrics(SM_CYBORDER));
ScreenToClient(rect);
InvalidateRect(rect);
}
BOOL CPicturePropPage::OnEditProperty(DISPID dispid)
{
return CStockPropPage::OnEditProperty(dispid, m_PropName);
}
void CPicturePropPage::OnObjectsChanged()
{
ULONG nObjects;
if (GetObjectArray(&nObjects) != NULL && m_hWnd != NULL)
FillPropnameList(IID_IPictureDisp, 1, m_PropName);
if (m_hWnd != NULL)
OnSelchangePictProp();
}
/////////////////////////////////////////////////////////////////////////////
// Class factory for Picture property page
#ifdef AFXCTL_FACT_SEG
#pragma code_seg(AFXCTL_FACT_SEG)
#endif
IMPLEMENT_OLECREATE_EX(CPicturePropPage, "OCxx.CPicturePropPage",
0x0be35202,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51)
BOOL CPicturePropPage::CPicturePropPageFactory::UpdateRegistry(BOOL bRegister)
{
if (bRegister)
return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),
m_clsid, AFX_IDS_PICTURE_PPG);
else
return AfxOleUnregisterClass(m_clsid, NULL);
}
/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNCREATE(CPicturePropPage, CStockPropPage)