windows-nt/Source/XPSP1/NT/shell/osshell/accesory/mspaint/pbrusfrm.cpp
2020-09-26 16:20:57 +08:00

557 lines
14 KiB
C++

// pbrusfrm.cpp : implementation of the CPBFrame class
//
#include "stdafx.h"
#include "resource.h"
#include "global.h"
#include "pbrusfrm.h"
#include "pbrusvw.h"
#include "pbrush.h"
#include "pbrusdoc.h"
#include "bmobject.h"
#include "docking.h"
#include "minifwnd.h"
#include "imgwnd.h"
#include "imgwell.h"
#include "imgtools.h"
#include "imgdlgs.h"
#include "cmpmsg.h"
#include "props.h"
#include "colorsrc.h"
#include <htmlhelp.h>
#include "imaging.h"
#ifdef _DEBUG
#undef THIS_FILE
static CHAR BASED_CODE THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE( CPBFrame, CFrameWnd )
#include "memtrace.h"
#define UM_FILE_ERROR WM_USER + 1001
/*************************** CPBFrame **************************************/
BEGIN_MESSAGE_MAP( CPBFrame, CFrameWnd )
//{{AFX_MSG_MAP(CPBFrame)
ON_WM_ACTIVATEAPP()
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_PALETTECHANGED()
ON_WM_QUERYNEWPALETTE()
ON_WM_GETMINMAXINFO()
ON_WM_MOVE()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
ON_WM_DEVMODECHANGE()
ON_WM_WININICHANGE()
ON_COMMAND(ID_HELP, OnHelp)
ON_WM_SYSCOLORCHANGE()
ON_WM_CLOSE()
ON_UPDATE_COMMAND_UI(ID_FILE_SCAN_NEW, OnUpdateAcquire)
ON_COMMAND(ID_FILE_SCAN_NEW, OnAcquire)
ON_UPDATE_COMMAND_UI(ID_FILE_SELECT_SOURCE, OnUpdateSelectSource)
ON_COMMAND(ID_FILE_SELECT_SOURCE, OnSelectSource)
//}}AFX_MSG_MAP
ON_MESSAGE(UM_FILE_ERROR, OnFileError)
// Global help commands
ON_COMMAND(ID_HELP_INDEX, CFrameWnd::OnHelpIndex)
ON_COMMAND(ID_HELP_USING, CFrameWnd::OnHelpUsing)
ON_COMMAND(ID_CONTEXT_HELP, CFrameWnd::OnContextHelp)
ON_COMMAND(ID_DEFAULT_HELP, CFrameWnd::OnHelpIndex)
ON_UPDATE_COMMAND_UI(ID_VIEW_TOOL_BOX, CFrameWnd::OnUpdateControlBarMenu)
ON_COMMAND_EX(ID_VIEW_TOOL_BOX, CFrameWnd::OnBarCheck)
ON_UPDATE_COMMAND_UI(ID_VIEW_COLOR_BOX, CFrameWnd::OnUpdateControlBarMenu)
ON_COMMAND_EX(ID_VIEW_COLOR_BOX, CFrameWnd::OnBarCheck)
END_MESSAGE_MAP()
/***************************************************************************/
/*********************** CPBFrame construction/destruction *****************/
CPBFrame::CPBFrame()
{
// Just small enough so that the control bars fit
m_szFrameMin = CSize( 275, 410 );
m_pMgr = new CWIAMgr;
#ifdef USE_TWAIN
if (!m_pMgr || !m_pMgr->IsAvailable())
{
delete m_pMgr;
m_pMgr = new CTwainMgr;
}
#endif //USE_TWAIN
}
/***************************************************************************/
CPBFrame::~CPBFrame()
{
// also can't delete objects derived from class cframewnd, must destroy their
// window => deletion indirectly
delete m_pMgr;
}
/*************************** CPBFrame diagnostics **************************/
#ifdef _DEBUG
void CPBFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
/***************************************************************************/
void CPBFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/***************************************************************************/
TCHAR mszMSPaintClass[] = TEXT("MSPaintApp");
BOOL CPBFrame::PreCreateWindow( CREATESTRUCT& cs )
{
cs.dwExStyle |= WS_EX_WINDOWEDGE;
cs.style |= WS_CLIPCHILDREN;
BOOL bResult = CFrameWnd::PreCreateWindow( cs );
if (bResult)
{
WINDOWPLACEMENT& wpSaved = theApp.m_wpPlacement;
RECT& rcSaved = wpSaved.rcNormalPosition;
CPoint ptPBrush(rcSaved.left, rcSaved.top);
CSize sizePBrush(rcSaved.right - rcSaved.left, rcSaved.bottom - rcSaved.top);
CPoint pt = theApp.CheckWindowPosition( ptPBrush, sizePBrush );
if (pt.x || pt.y)
{
cs.x = pt.x;
cs.y = pt.y;
}
sizePBrush.cx = max(sizePBrush.cx, m_szFrameMin.cx);
sizePBrush.cy = max(sizePBrush.cy, m_szFrameMin.cy);
if (sizePBrush.cx && sizePBrush.cy)
{
cs.cx = sizePBrush.cx;
cs.cy = sizePBrush.cy;
}
rcSaved.left = cs.x;
rcSaved.top = cs.y;
rcSaved.right = rcSaved.left + cs.cx;
rcSaved.bottom = rcSaved.top + cs.cy;
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
// see if the class already exists
if (! ::GetClassInfo( hInst, mszMSPaintClass, &wndcls ))
{
// get default stuff
::GetClassInfo( hInst, cs.lpszClass, &wndcls );
// register a new class
wndcls.lpszClassName = mszMSPaintClass;
wndcls.hIcon = ::LoadIcon( hInst, MAKEINTRESOURCE( ID_MAINFRAME ) );
ASSERT( wndcls.hIcon != NULL );
if (! AfxRegisterClass( &wndcls ))
AfxThrowResourceException();
}
cs.lpszClass = mszMSPaintClass;
}
return bResult;
}
/***************************************************************************/
CWnd* CPBFrame::GetMessageBar()
{
if (m_statBar.m_hWnd != NULL)
return &m_statBar;
return NULL;
}
/***************************************************************************/
void CPBFrame::OnHelp()
{
if (m_dwPromptContext)
CFrameWnd::OnHelp();
else
::HtmlHelpA( ::GetDesktopWindow(), "mspaint.chm", HH_DISPLAY_TOPIC, 0L );
}
/***************************************************************************/
int CPBFrame::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
if (CFrameWnd::OnCreate( lpCreateStruct ) == -1)
return -1;
g_pStatBarWnd = &m_statBar;
g_pImgToolWnd = &m_toolBar;
g_pImgColorsWnd = &m_colorBar;
return 0;
}
/***************************************************************************/
void CPBFrame::OnDestroy()
{
CFrameWnd::OnDestroy();
theApp.m_wpPlacement.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(&theApp.m_wpPlacement);
theApp.SaveProfileSettings();
}
/***************************************************************************/
BOOL CPBFrame::OnEraseBkgnd(CDC* pDC)
{
if ( !m_pViewActive ) //fix gray background on screen while IME disappear problem
{
CRect cRectClient;
GetClientRect( &cRectClient );
pDC->FillRect( &cRectClient, GetSysBrush( COLOR_BTNFACE ) );
}
return CFrameWnd::OnEraseBkgnd( pDC );
}
/***************************************************************************/
void CPBFrame::OnActivateApp(BOOL bActive, HTASK hTask)
{
theApp.m_bActiveApp = bActive;
CFrameWnd::OnActivateApp(bActive, hTask);
}
/***************************************************************************/
void CPBFrame::OnMove( int x, int y )
{
CRect cRectWindow;
GetWindowRect( &cRectWindow );
m_ptPosition.x = cRectWindow.left;
m_ptPosition.y = cRectWindow.top;
CWnd::OnMove( x, y );
}
/***************************************************************************/
void CPBFrame::OnSize( UINT nType, int cx, int cy )
{
CFrameWnd::OnSize( nType, cx, cy );
CRect rect;
GetWindowRect( &rect );
m_szFrame = rect.Size();
}
/***************************************************************************/
void CPBFrame::OnSetFocus(CWnd* pOldWnd)
{
CFrameWnd::OnSetFocus( pOldWnd );
// We need to update the window here because the SetFocus below will update
// the image window, and then some async paints can come after that which
// will cause us to put the background color over parts of the window (see
// WIN95C bug #4080).
UpdateWindow();
CPBView* pView = (CPBView*)GetActiveView();
if (pView
&& pView->IsKindOf( RUNTIME_CLASS( CPBView ) )
&& pView->m_pImgWnd != NULL
&& ::IsWindow(pView->m_pImgWnd->m_hWnd) )
pView->m_pImgWnd->SetFocus();
}
/***************************************************************************/
void CPBFrame::OnPaletteChanged( CWnd* pFocusWnd )
{
CFrameWnd::OnPaletteChanged( pFocusWnd );
CPBView* pView = (CPBView*)GetActiveView();
if (pView != NULL && pView->IsKindOf( RUNTIME_CLASS( CPBView ) ))
{
pView->OnPaletteChanged( pFocusWnd );
}
}
/***************************************************************************/
BOOL CPBFrame::OnQueryNewPalette()
{
CPBView* pView = (CPBView*)GetActiveView();
if (pView != NULL && ::IsWindow(pView->m_hWnd) && pView->IsKindOf( RUNTIME_CLASS( CPBView ) ))
{
pView->OnQueryNewPalette();
}
return CFrameWnd::OnQueryNewPalette();
}
/***************************************************************************/
void CPBFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
lpMMI->ptMinTrackSize.x = m_szFrameMin.cx;
lpMMI->ptMinTrackSize.y = m_szFrameMin.cy;
CFrameWnd::OnGetMinMaxInfo(lpMMI);
}
/*****************************************************************************/
void CPBFrame::OnDevModeChange( LPTSTR lpDeviceName )
{
CClientDC dc( this );
if (dc.m_hDC != NULL)
theApp.GetSystemSettings( &dc );
CFrameWnd::OnDevModeChange( lpDeviceName );
}
/*****************************************************************************/
void CPBFrame::OnWinIniChange( LPCTSTR lpszSection )
{
CClientDC dc( this );
CDocument *pDoc;
if (dc.m_hDC != NULL)
theApp.GetSystemSettings( &dc );
if ( m_statBar.m_hWnd != NULL
&& theApp.m_fntStatus.m_hObject != NULL)
m_statBar.SetFont( &theApp.m_fntStatus, FALSE );
CFrameWnd::OnWinIniChange( lpszSection );
if (pDoc = GetActiveDocument())
{
pDoc->UpdateAllViews( NULL );
GetActiveView()->UpdateWindow();
}
}
/*****************************************************************************/
void CPBFrame::ActivateFrame( int nCmdShow )
{
WINDOWPLACEMENT& wpSaved = theApp.m_wpPlacement;
if (theApp.m_bPrintOnly)
{
nCmdShow = SW_HIDE;
}
else if (!IsWindowVisible())
{
switch (nCmdShow)
{
case SW_SHOW:
case SW_SHOWNORMAL:
switch (wpSaved.showCmd)
{
case SW_HIDE:
case SW_MINIMIZE:
case SW_SHOWMINIMIZED:
case SW_SHOWMINNOACTIVE:
break;
default:
nCmdShow = wpSaved.showCmd;
break;
}
break;
}
wpSaved.showCmd = nCmdShow;
wpSaved.length = sizeof(WINDOWPLACEMENT);
SetWindowPlacement(&wpSaved);
}
//
// We have to reassign the global toolbar pointers here, in case
// they were pointing to the inplace frame's toolbars and that window
// was deleted.
//
g_pStatBarWnd = &m_statBar;
g_pImgToolWnd = &m_toolBar;
g_pImgColorsWnd = &m_colorBar;
CFrameWnd::ActivateFrame( nCmdShow );
}
/*****************************************************************************/
#ifdef xyzzyz
void CPBFrame::OnUpdateFrameTitle( BOOL bAddToTitle )
{
if (theApp.m_bEmbedded && ! theApp.m_bLinked)
{
CFrameWnd::OnUpdateFrameTitle( bAddToTitle );
return;
}
// get old text for comparison against new text
CString sOld;
CString sText;
GetWindowText( sOld );
CPBDoc* pDocument = (CPBDoc*)GetActiveDocument();
if (bAddToTitle && pDocument != NULL)
{
const TCHAR* psTitle = pDocument->GetTitle();
if (psTitle != NULL)
{
sText += GetName( psTitle );
sText += TEXT(" - ");
sText.MakeLower();
}
}
sText += m_strTitle;
// set title if changed, but don't remove completely
if (sText != sOld)
SetWindowText( sText );
}
#endif
/*****************************************************************************/
LRESULT CPBFrame::OnFileError( WPARAM, LPARAM )
{
theApp.FileErrorMessageBox();
return 0;
}
/***************************************************************************/
void CPBFrame::OnSysColorChange()
{
CFrameWnd ::OnSysColorChange();
ResetSysBrushes();
}
void CPBFrame::OnClose()
{
SaveBarState(TEXT("General"));
CFrameWnd ::OnClose();
}
/***************************************************************************/
void CPBFrame::OnSelectSource()
{
CWaitCursor DisplayWaitCursor;
// if m_pMgr == 0, "Select Source" menu item will not be available anyway
ASSERT(m_pMgr != 0);
HRESULT hr = m_pMgr->SelectSource(
GetSafeHwnd(),
WIA_SELECT_DEVICE_NODEFAULT
);
if (!SUCCEEDED(hr))
{
CmpMessageBox(IDS_ERROR_SELECT_SCAN,
AFX_IDS_APP_TITLE, MB_OK | MB_ICONEXCLAMATION);
}
}
void CPBFrame::OnAcquire()
{
CWaitCursor DisplayWaitCursor;
// if m_pMgr == 0, "Scan New" menu item will not be available anyway
ASSERT(m_pMgr != 0);
// call the WIA interface to acquire the image
HGLOBAL hDib = 0;
HRESULT hr = m_pMgr->Acquire(GetSafeHwnd(), &hDib);
if (!SUCCEEDED(hr))
{
// if the interface has failed, display the generic error message
CmpMessageBox(IDS_ERROR_SCAN_NEW,
AFX_IDS_APP_TITLE, MB_OK | MB_ICONEXCLAMATION);
}
else if (hr == S_OK)
{
// if the user has not cancelled the operation, get the image
CPBView *pView = (CPBView*)GetActiveView();
if (pView)
{
CPBDoc *pDoc = (CPBDoc *)pView->GetDocument();
// prompt to save the current document if it was modified
if (pDoc && pDoc->SaveModified())
{
pDoc->SetModifiedFlag(FALSE);
// and set this as the new image
theApp.OnFileNew ();
pDoc->SetDibHandle (hDib);
pView->m_pImgWnd->Invalidate();
pView->m_pImgWnd->CheckScrollBars();
}
}
}
}
void CPBFrame::OnUpdateSelectSource(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pMgr && m_pMgr->NumDevices(GetSafeHwnd()) > 0);
}
void CPBFrame::OnUpdateAcquire(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pMgr && m_pMgr->NumDevices(GetSafeHwnd()) > 0);
}