mirror of https://github.com/lianthony/NT4.0
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.
2116 lines
81 KiB
2116 lines
81 KiB
// thumbctl.cpp : Implementation of the CThumbCtrl OLE control class.
|
|
// This file contains Construction/Destruction,
|
|
// WM_ command handlers, Control Drawing, and other
|
|
// miscellanious routines...
|
|
//
|
|
// Property handlers can be found in THUMBCT1.CPP
|
|
// Method handlers can be found in THUMBCT1.CPP
|
|
// Event handlers can be found in THUMBCT1.CPP
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT NOTE: Alex McLeod (4/12/95)
|
|
//
|
|
// This file has been populated with Control-Ls which act like
|
|
// page break characters. These have been added before function
|
|
// headers to make printouts more readable.
|
|
//
|
|
// MSVC and its compiler seem to treat these characters as
|
|
// white space and simply ignore them. If these cause a problem
|
|
// please remove them carefully!!
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "limits.h"
|
|
#include "thumnail.h"
|
|
#include "thumbctl.h"
|
|
#include "thumbppg.h"
|
|
#include "dlgsize.h"
|
|
#include "transbmp.h"
|
|
#include "norvarnt.h"
|
|
#include "norermap.h"
|
|
#include "disphids.h"
|
|
|
|
/*
|
|
Other miscellanious includes...
|
|
*/
|
|
extern "C" // The following are the required Open/image headers
|
|
{ // .
|
|
#include <oierror.h> // .
|
|
#include <oifile.h> // .
|
|
#include <oiadm.h> // .
|
|
#include <oidisp.h> // .
|
|
} // .
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNCREATE(CThumbCtrl, COleControl)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message map
|
|
|
|
BEGIN_MESSAGE_MAP(CThumbCtrl, COleControl)
|
|
//{{AFX_MSG_MAP(CThumbCtrl)
|
|
ON_WM_SIZE()
|
|
ON_WM_VSCROLL()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_MBUTTONDOWN()
|
|
ON_WM_MBUTTONUP()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
ON_WM_DESTROY()
|
|
ON_WM_HSCROLL()
|
|
ON_WM_CREATE()
|
|
ON_WM_MOUSEMOVE()
|
|
// 9603.05 jar added cursor processing for [NT]
|
|
ON_WM_SETCURSOR()
|
|
//}}AFX_MSG_MAP
|
|
ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit)
|
|
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Dispatch map
|
|
|
|
BEGIN_DISPATCH_MAP(CThumbCtrl, COleControl)
|
|
//{{AFX_DISPATCH_MAP(CThumbCtrl)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbCount", GetThumbCount, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbWidth", GetThumbWidth, SetThumbWidth, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbHeight", GetThumbHeight, SetThumbHeight, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ScrollDirection", GetScrollDirection, SetScrollDirection, VT_I2)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbCaptionStyle", GetThumbCaptionStyle, SetThumbCaptionStyle, VT_I2)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbCaptionColor", GetThumbCaptionColor, SetThumbCaptionColor, VT_COLOR)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbCaptionFont", GetThumbCaptionFont, SetThumbCaptionFont, VT_FONT)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "HighlightSelectedThumbs", GetHilightSelectedThumbs, SetHilightSelectedThumbs, VT_BOOL)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "SelectedThumbCount", GetSelectedThumbCount, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "FirstSelectedThumb", GetFirstSelectedThumb, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "LastSelectedThumb", GetLastSelectedThumb, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbCaption", GetThumbCaption, SetThumbCaption, VT_BSTR)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "HighlightColor", GetHighlightColor, SetHighlightColor, VT_COLOR)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "ThumbBackColor", GetThumbBackColor, SetThumbBackColor, VT_COLOR)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "StatusCode", GetStatusCode, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "Image", GetImage, SetImage, VT_BSTR)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "MousePointer", GetMousePointer, SetMousePointer, VT_I2)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "MouseIcon", GetMouseIcon, SetMouseIcon, VT_PICTURE)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "FirstDisplayedThumb", GetFirstDisplayedThumb, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX(CThumbCtrl, "LastDisplayedThumb", GetLastDisplayedThumb, SetNotSupported, VT_I4)
|
|
DISP_PROPERTY_EX_ID(CThumbCtrl, "BackColor", DISPID_BACKCOLOR, GetBackColor, SetBackColor, VT_COLOR)
|
|
DISP_PROPERTY_EX_ID(CThumbCtrl, "BorderStyle", DISPID_BORDERSTYLE, GetBorderStyle, SetBorderStyle, VT_I2)
|
|
DISP_PROPERTY_EX_ID(CThumbCtrl, "Enabled", DISPID_ENABLED, GetEnabled, SetEnabled, VT_BOOL)
|
|
DISP_PROPERTY_EX_ID(CThumbCtrl, "hWnd", DISPID_HWND, GetHWnd, SetNotSupported, VT_HANDLE)
|
|
//}}AFX_DISPATCH_MAP
|
|
DISP_FUNCTION_ID(CThumbCtrl, "SelectAllThumbs", dispidSelectAllThumbs, SelectAllThumbs, VT_EMPTY, VTS_NONE)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "DeselectAllThumbs", dispidDeselectAllThumbs, DeselectAllThumbs, VT_EMPTY, VTS_NONE)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GetMinimumSize", dispidGetMinimumSize, GetMinimumSize, VT_I4, VTS_I4 VTS_BOOL)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GetMaximumSize", dispidGetMaximumSize, GetMaximumSize, VT_I4, VTS_I4 VTS_BOOL)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "ClearThumbs", dispidClearThumbs, ClearThumbs, VT_EMPTY, VTS_VARIANT)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "InsertThumbs", dispidInsertThumbs, InsertThumbs, VT_EMPTY, VTS_VARIANT VTS_VARIANT)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "DeleteThumbs", dispidDeleteThumbs, DeleteThumbs, VT_EMPTY, VTS_I4 VTS_VARIANT)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "DisplayThumbs", dispidDisplayThumbs, DisplayThumbs, VT_EMPTY, VTS_VARIANT VTS_VARIANT)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GenerateThumb", dispidGenerateThumb, GenerateThumb, VT_EMPTY, VTS_I2 VTS_VARIANT)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "ScrollThumbs", dispidScrollThumbs, ScrollThumbs, VT_BOOL, VTS_I2 VTS_I2)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "UISetThumbSize", dispidUISetThumbSize, UISetThumbSize, VT_BOOL, VTS_VARIANT VTS_VARIANT)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GetScrollDirectionSize", dispidGetScrollDirectionSize, GetScrollDirectionSize, VT_I4, VTS_I4 VTS_I4 VTS_I4 VTS_BOOL)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GetThumbPositionX", dispidGetThumbPositionX, GetThumbPositionX, VT_I4, VTS_I4)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GetThumbPositionY", dispidGetThumbPositionY, GetThumbPositionY, VT_I4, VTS_I4)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "GetVersion", dispidGetVersion, GetVersion, VT_BSTR, VTS_NONE)
|
|
DISP_PROPERTY_PARAM_ID(CThumbCtrl, "ThumbSelected", dispidThumbSelected, GetThumbSelected, SetThumbSelected, VT_BOOL, VTS_I4)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "Refresh", DISPID_REFRESH, Refresh, VT_EMPTY, VTS_NONE)
|
|
DISP_FUNCTION_ID(CThumbCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
|
|
END_DISPATCH_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event map
|
|
|
|
BEGIN_EVENT_MAP(CThumbCtrl, COleControl)
|
|
//{{AFX_EVENT_MAP(CThumbCtrl)
|
|
EVENT_CUSTOM("Click", FireMyClick, VTS_I4)
|
|
EVENT_CUSTOM("DblClick", FireMyDblClick, VTS_I4)
|
|
EVENT_CUSTOM("MouseDown", FireMyMouseDown, VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS VTS_I4)
|
|
EVENT_CUSTOM("MouseUp", FireMyMouseUp, VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS VTS_I4)
|
|
EVENT_CUSTOM("MouseMove", FireMyMouseMove, VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS VTS_I4)
|
|
EVENT_STOCK_KEYDOWN()
|
|
EVENT_STOCK_KEYUP()
|
|
//EVENT_CUSTOM_ID("Error", DISPID_ERROREVENT, FireError, VTS_I2 VTS_PBSTR VTS_SCODE VTS_BSTR VTS_BSTR VTS_I4 VTS_PBOOL)
|
|
EVENT_CUSTOM_ID("Error", DISPID_ERROREVENT, FireError, VTS_I2 VTS_PBSTR VTS_I4 VTS_BSTR VTS_BSTR VTS_I4 VTS_PBOOL)
|
|
//}}AFX_EVENT_MAP
|
|
END_EVENT_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Property pages
|
|
|
|
// TODO: Add more property pages as needed. Remember to increase the count!
|
|
BEGIN_PROPPAGEIDS(CThumbCtrl, 4)
|
|
PROPPAGEID(CThumbPropPage::guid)
|
|
PROPPAGEID(CLSID_CColorPropPage) // It was agreed that these
|
|
PROPPAGEID(CLSID_CFontPropPage) // should be in (english)
|
|
PROPPAGEID(CLSID_CPicturePropPage) // alphabetical order! (i.e., CFP)
|
|
END_PROPPAGEIDS(CThumbCtrl)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Initialize class factory and guid
|
|
|
|
IMPLEMENT_OLECREATE_EX(CThumbCtrl, "WangImage.ThumbnailCtrl.1",
|
|
0xe1a6b8a0, 0x3603, 0x101c, 0xac, 0x6e, 0x4, 0x2, 0x24, 0x0, 0x9c, 0x2)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Type library ID and version
|
|
|
|
IMPLEMENT_OLETYPELIB(CThumbCtrl, _tlid, _wVerMajor, _wVerMinor)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Interface IDs
|
|
|
|
const IID BASED_CODE IID_DThumb =
|
|
{ 0xe1a6b8a1, 0x3603, 0x101c, { 0xac, 0x6e, 0x4, 0x2, 0x24, 0x0, 0x9c, 0x2 } };
|
|
const IID BASED_CODE IID_DThumbEvents =
|
|
{ 0xe1a6b8a2, 0x3603, 0x101c, { 0xac, 0x6e, 0x4, 0x2, 0x24, 0x0, 0x9c, 0x2 } };
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Control type information
|
|
|
|
static const DWORD BASED_CODE _dwThumbOleMisc =
|
|
OLEMISC_ACTIVATEWHENVISIBLE |
|
|
OLEMISC_SETCLIENTSITEFIRST |
|
|
OLEMISC_INSIDEOUT |
|
|
OLEMISC_CANTLINKINSIDE |
|
|
OLEMISC_RECOMPOSEONRESIZE;
|
|
|
|
IMPLEMENT_OLECTLTYPE(CThumbCtrl, IDS_THUMB, _dwThumbOleMisc)
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL CHiddenWnd::CreateEx(long Width, long Height)
|
|
{
|
|
// Use the precreated MFC window class instead of registering our own...
|
|
return CWnd::CreateEx(0, NULL, "", WS_POPUP|WS_CHILD,
|
|
0, 0, (int)Width-2,(int)Height-2,
|
|
NULL,NULL);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::CThumbCtrlFactory::UpdateRegistry -
|
|
// Adds or removes system registry entries for CThumbCtrl
|
|
|
|
BOOL CThumbCtrl::CThumbCtrlFactory::UpdateRegistry(BOOL bRegister)
|
|
{
|
|
if (bRegister)
|
|
return AfxOleRegisterControlClass(
|
|
AfxGetInstanceHandle(),
|
|
m_clsid,
|
|
m_lpszProgID,
|
|
IDS_THUMB,
|
|
IDB_THUMB,
|
|
FALSE, // NOT Insertable
|
|
_dwThumbOleMisc,
|
|
_tlid,
|
|
_wVerMajor,
|
|
_wVerMinor);
|
|
else
|
|
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
|
|
}
|
|
|
|
/**********************************************
|
|
|
|
Removed as no license required...
|
|
(See .h file also)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Licensing strings
|
|
|
|
static const TCHAR BASED_CODE _szLicFileName[] = _T("THUMB.LIC");
|
|
|
|
static const TCHAR BASED_CODE _szLicString[] =
|
|
_T("Copyright (c) 1995 Wang Labs, Inc.");
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::CThumbCtrlFactory::VerifyUserLicense -
|
|
// Checks for existence of a user license
|
|
|
|
BOOL CThumbCtrl::CThumbCtrlFactory::VerifyUserLicense()
|
|
{
|
|
return AfxVerifyLicFile(AfxGetInstanceHandle(),
|
|
_szLicFileName, _szLicString);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::CThumbCtrlFactory::GetLicenseKey -
|
|
// Returns a runtime licensing key
|
|
|
|
BOOL CThumbCtrl::CThumbCtrlFactory::GetLicenseKey(DWORD dwReserved,
|
|
BSTR FAR* pbstrKey)
|
|
{
|
|
if (pbstrKey == NULL)
|
|
return FALSE;
|
|
|
|
*pbstrKey = SysAllocString(_szLicString);
|
|
return (*pbstrKey != NULL);
|
|
}
|
|
*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::CThumbCtrl - Constructor
|
|
|
|
CThumbCtrl::CThumbCtrl() : m_ThumbCaptionFont (&m_xFontNotification )
|
|
{
|
|
InitializeIIDs(&IID_DThumb, &IID_DThumbEvents);
|
|
|
|
// Initialize control's instance data...
|
|
m_ThumbMinSpacing = -20; // min % of thumbsize
|
|
m_ThumbsX = 0; // need to calc X &
|
|
m_ThumbsY = 0; // Y thumbs
|
|
|
|
m_ThumbCount = 0; // No thumbs
|
|
m_SelThumbCount = 0; // .
|
|
m_FirstSelThumb = 0; // .
|
|
m_LastSelThumb = 0; // .
|
|
|
|
// 16may96 paj Bug#6428,MSBug#310 Get correct defaults for locale
|
|
// Default width & height of thumb box
|
|
InitHeightWidth(m_ThumbHeight, m_ThumbWidth);
|
|
|
|
// The adjusted thumb width and height takes into account
|
|
// the selection box surrounding the thumbnail box...
|
|
m_AdjThumbWidth = m_ThumbWidth +
|
|
2*(THUMBSELOFFSET_X+THUMBSELWIDTH);
|
|
|
|
m_AdjThumbHeight = m_ThumbHeight +
|
|
2*(THUMBSELOFFSET_Y+THUMBSELWIDTH);
|
|
|
|
m_ScrollDirection = CTL_THUMB_VERTICAL; // vertical scroll
|
|
m_ScrollRange = 0; //
|
|
m_ScrollOffset = 0; //
|
|
m_ThumbCaptionStyle = CTL_THUMB_NONE; // NO caption
|
|
|
|
m_ThumbCaptionColor = RGB(0x00, 0x00, 0x00); // BLACK
|
|
m_ThumbBackColor = RGB(0x80, 0x80, 0x80); // GREY
|
|
m_HighlightColor = RGB(0x00, 0x00, 0x00); // BLACK
|
|
|
|
m_bHilightSelectedThumbs = TRUE; // DO hilight sel'd thumbs
|
|
m_bAutoRefresh = TRUE; // DO auto Refresh
|
|
|
|
m_ThumbStart[0] = 0; // ThumbStart array empty
|
|
m_LastButtonDown = LASTDOWN_NONE; // No mouse downs yet...
|
|
m_StatusCode = 0; // No errors
|
|
|
|
m_IHphWndHidden = NULL; // No hidden wnd created...
|
|
m_bIHThumbToTPageDirty = FALSE; // array NOT dirty
|
|
m_IHNextAvailablePage = 1; // Save to tfile at pg1
|
|
|
|
m_FirstDisplayedThumb = 0; // No thumbs displayed
|
|
m_LastDisplayedThumb = 0; // ...
|
|
|
|
m_NextWindowID = 1000; // Next ID for created wnd
|
|
|
|
// Clear all of our strings
|
|
m_Image.Empty(); // No image to display
|
|
m_ImageOIFileType = FIO_UNKNOWN; // No type
|
|
m_Caption.Empty(); // No caption
|
|
m_IHTempFile.Empty(); // No temp file
|
|
|
|
// Empty all of our arrays
|
|
m_IHThumbToTPage.RemoveAll(); // No thumb->Page mappings
|
|
m_IWDisplayedPage.RemoveAll(); // No thumbnails displayed
|
|
m_IWWindow.RemoveAll(); // No thumbnail wnds created
|
|
|
|
m_bDrawThumbImages = TRUE; // Draw thumbimg in OnDraw?
|
|
|
|
m_TextHeight = 0;
|
|
m_TextAscent = 0;
|
|
|
|
m_hCursor = NULL; // No initial custom cursor
|
|
|
|
m_NeedDrawFrom = 0;
|
|
|
|
m_szThrowString.Empty(); // For thrown & fired errors
|
|
m_ThrowHelpID = 0; // ...
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::~CThumbCtrl - Destructor
|
|
|
|
CThumbCtrl::~CThumbCtrl()
|
|
{
|
|
// Deregister and delete our hidden window if we had gotten one
|
|
// (in SetImage). This is done here in the destructor as the hidden
|
|
// window MAY be created even if the control's window is NEVER
|
|
// created and thus cannot be done in the OnDestroy handler...
|
|
if ( m_IHphWndHidden != NULL )
|
|
{
|
|
m_StatusCode = IMGDeRegWndw(m_IHphWndHidden->GetSafeHwnd());
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
TRACE1("Dest'r: DeRegWndw of hidden window returned 0x%lx.\n\r", m_StatusCode);
|
|
}
|
|
|
|
m_IHphWndHidden->DestroyWindow();
|
|
delete m_IHphWndHidden;
|
|
}
|
|
}
|
|
|
|
// BEGIN FONT STUFF
|
|
// From CDK Online documentation re: Custom font property notifications.
|
|
// (Only the names have been changed to protect the innocent!)
|
|
STDMETHODIMP_(ULONG) CThumbCtrl::XFontNotification::AddRef( )
|
|
{
|
|
METHOD_MANAGE_STATE(CThumbCtrl, FontNotification)
|
|
return 1;
|
|
}
|
|
STDMETHODIMP_(ULONG) CThumbCtrl::XFontNotification::Release( )
|
|
{
|
|
METHOD_MANAGE_STATE(CThumbCtrl, FontNotification)
|
|
return 0;
|
|
}
|
|
|
|
STDMETHODIMP CThumbCtrl::XFontNotification::QueryInterface( REFIID iid, LPVOID FAR* ppvObj )
|
|
{
|
|
METHOD_MANAGE_STATE( CThumbCtrl, FontNotification )
|
|
if( IsEqualIID( iid, IID_IUnknown ) ||
|
|
IsEqualIID( iid, IID_IPropertyNotifySink))
|
|
{
|
|
*ppvObj= this;
|
|
AddRef( );
|
|
return NOERROR;
|
|
}
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
STDMETHODIMP CThumbCtrl::XFontNotification::OnChanged(DISPID)
|
|
{
|
|
METHOD_MANAGE_STATE( CThumbCtrl, FontNotification )
|
|
if ( pThis->m_bAutoRefresh ) // This SINGLE if has beed added!!!
|
|
pThis->InvalidateControl( );
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP CThumbCtrl::XFontNotification::OnRequestEdit(DISPID)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
// END FONT STUFF
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::OnDraw - Drawing function
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
|
|
{
|
|
//TRACE0("In draw...\n\r");
|
|
|
|
START_TIMER(m_TimeAllDraw);
|
|
ZERO_TIMER(m_TimeOiDraw);
|
|
|
|
// Paint the background using the BackColor property
|
|
CBrush bkBrush(TranslateColor(GetBackColor()));
|
|
pdc->FillRect(rcInvalid, &bkBrush);
|
|
|
|
// Never ever draw outside the bounds
|
|
pdc->SelectClipRgn(NULL);
|
|
pdc->IntersectClipRect(rcInvalid);
|
|
|
|
// Various ways to get out BEFORE any thumbnail
|
|
// boxes, or thumbnail images are drawn:
|
|
// If there are NO thumbnails to be drawn (ThumbCount == 0)...
|
|
// If we are in design mode do not draw thumbs...
|
|
if ( (m_ThumbCount == 0) || (AmbientUserMode() == 0) )
|
|
{
|
|
END_TIMER(m_TimeAllDraw);
|
|
|
|
#ifdef _DEBUG
|
|
TRACE3("Draw: O/i: %lu, Thumb: %lu, Total: %lu (milliseconds).\n\r", m_TimeOiDraw, m_TimeAllDraw - m_TimeOiDraw, m_TimeAllDraw);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
// Get control's Width & Height
|
|
int CtlWidth;
|
|
int CtlHeight;
|
|
GetControlSize( &CtlWidth, &CtlHeight );
|
|
|
|
// Set up for thumbnail boxes drawn with
|
|
//ThumbBackColor brush interior BLACK edge
|
|
CRect ThumbBox;
|
|
|
|
CBrush ThumbBrush(TranslateColor(m_ThumbBackColor));
|
|
CBrush* pOldBrush = pdc->SelectObject(&ThumbBrush);
|
|
|
|
CPen ThumbPen;
|
|
ThumbPen.CreateStockObject(BLACK_PEN);
|
|
CPen* pOldPen = pdc->SelectObject(&ThumbPen);
|
|
|
|
// Set up for the thumbnail box labels drawn w/ ThumbCaptionColor text...
|
|
CFont* pOldFont;
|
|
if ( m_ThumbCaptionStyle != CTL_THUMB_NONE )
|
|
{
|
|
pdc->SetTextColor(TranslateColor(m_ThumbCaptionColor));
|
|
pdc->SetBkColor(TranslateColor(GetBackColor()));
|
|
pOldFont = SelectFontObject(pdc, m_ThumbCaptionFont);
|
|
}
|
|
|
|
// Setup for drawing thumb backgrounds...
|
|
long Pos; // X|Y position in thumbs
|
|
long WR_Pos; // WINDOW RELATIVE position
|
|
long ThumbStartIx = 0; // Ix into ThumbStart array
|
|
long ThumbNum = 1; // Start @ thumb #1
|
|
m_FirstDisplayedThumb = 0; // Clear 1st disp thumb,
|
|
// 0 = NONE displayed
|
|
|
|
if ( m_ScrollDirection == CTL_THUMB_HORIZONTAL )
|
|
{ // Horizontal scrolling...
|
|
// Draw each column starting at the 1st thumb...
|
|
for ( int col = 0; col < m_ThumbsX; col++ )
|
|
{
|
|
// Calc col's X position (of left of selection indicator),
|
|
// (using floats to distribute spacing
|
|
// roundoffs between the thumbnail boxes...)
|
|
// and adjust to make it WINDOW RELATIVE
|
|
Pos = (long)(m_Spacing +
|
|
((float)col * ((float)m_AdjThumbWidth + m_Spacing)));
|
|
WR_Pos = Pos - m_ScrollOffset;
|
|
|
|
// Finished if left of thumb is right of window, or
|
|
// we've gone past the last thumb...
|
|
if ( (WR_Pos > (long)CtlWidth) || (ThumbNum > m_ThumbCount) )
|
|
break;
|
|
|
|
// If right of thumb is left of window skip this entire row...
|
|
if ( (WR_Pos + m_AdjThumbWidth) < 0 )
|
|
{
|
|
ThumbNum += m_ThumbsY;
|
|
continue;
|
|
}
|
|
|
|
// Draw this column...
|
|
// and save the left of the row/column an the ThumbStart
|
|
// and save the first thumb in the first row/column
|
|
m_ThumbStart[ThumbStartIx++]= WR_Pos+THUMBSELOFFSET_X+THUMBSELWIDTH;
|
|
|
|
if ( m_FirstDisplayedThumb == 0 )
|
|
m_FirstDisplayedThumb = ThumbNum;
|
|
|
|
for ( int row = 0; row < m_ThumbsY; row++ )
|
|
{
|
|
// Never ever draw outside the bounds
|
|
pdc->SelectClipRgn(NULL);
|
|
pdc->IntersectClipRect(rcInvalid);
|
|
|
|
// Draw a thumbnail box...
|
|
DrawThumbBackground(pdc, ThumbNum,
|
|
WR_Pos + rcBounds.left,
|
|
(long)(m_Spacing + rcBounds.top +
|
|
((float)row*((float)m_AdjThumbHeight +
|
|
(float)m_LabelSpacing +
|
|
m_Spacing))));
|
|
|
|
// Increment to next thumb in column, if done, break...
|
|
if ( ++ThumbNum > m_ThumbCount )
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ // Vertical scrolling...
|
|
// Draw each row starting at the 1st thumb...
|
|
for ( int row = 0; row < m_ThumbsY; row++ )
|
|
{
|
|
// Calc row's Y position (of top of selection indicator),
|
|
// (using floats to distribute spacing
|
|
// roundoffs between the thumbnail boxes...)
|
|
// and adjust to make it WINDOW RELATIVE
|
|
Pos = (long)(m_Spacing +
|
|
((float)row*((float)m_AdjThumbHeight +
|
|
(float)m_LabelSpacing +
|
|
m_Spacing)));
|
|
WR_Pos = Pos - m_ScrollOffset;
|
|
|
|
// Finished if top of thumb is below bottom of window, or
|
|
// we've gone past the last thumb...
|
|
if ( (WR_Pos > CtlHeight) || (ThumbNum > m_ThumbCount) )
|
|
break;
|
|
|
|
// If thumb bottom + label space is above the
|
|
// top of window we can skip this entire row...
|
|
if ( (WR_Pos + m_ThumbHeight + m_LabelSpacing) < 0 )
|
|
{
|
|
ThumbNum += m_ThumbsX;
|
|
continue;
|
|
}
|
|
|
|
// Draw this row...
|
|
// and save the top of the row/column an the ThumbStart
|
|
// and save the first thumb in the first row/column
|
|
m_ThumbStart[ThumbStartIx++]= WR_Pos+THUMBSELOFFSET_Y+THUMBSELWIDTH;
|
|
|
|
if ( m_FirstDisplayedThumb == 0 )
|
|
m_FirstDisplayedThumb = ThumbNum;
|
|
|
|
for ( int col = 0; col < m_ThumbsX; col++ )
|
|
{
|
|
// Never ever draw outside the bounds
|
|
pdc->SelectClipRgn(NULL);
|
|
pdc->IntersectClipRect(rcInvalid);
|
|
|
|
// Draw a thumbnail box...
|
|
DrawThumbBackground(pdc, ThumbNum,
|
|
(long)(m_Spacing + rcBounds.left +
|
|
((float)col * ((float)m_AdjThumbWidth + m_Spacing))),
|
|
WR_Pos + rcBounds.top);
|
|
|
|
// Increment to next thumb in column, if done, break...
|
|
if ( ++ThumbNum > m_ThumbCount )
|
|
break;
|
|
}
|
|
}
|
|
} // end Horizontal/Vertical
|
|
|
|
// Restore the brush, pen and font (if font was switched)...
|
|
pdc->SelectObject(pOldBrush);
|
|
pdc->SelectObject(pOldPen);
|
|
|
|
if ( m_ThumbCaptionStyle != CTL_THUMB_NONE )
|
|
{
|
|
pdc->SelectObject(pOldFont);
|
|
}
|
|
|
|
// Mark end of ThumbStart list...
|
|
m_ThumbStart[ThumbStartIx] = 0;
|
|
|
|
// If we should NOT draw the thumb images return now...
|
|
// I.e. if scroll from scroll bar (as opposed to scroll method)
|
|
if ( m_bDrawThumbImages == FALSE )
|
|
{
|
|
END_TIMER(m_TimeAllDraw);
|
|
|
|
#ifdef _DEBUG
|
|
TRACE3("Draw: O/i: %lu, Thumb: %lu, Total: %lu (milliseconds).\n\r", m_TimeOiDraw, m_TimeAllDraw - m_TimeOiDraw, m_TimeAllDraw);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
// Now that we have the First and Last thumbs calculated,
|
|
// hide any unused windows and iterate through the
|
|
// displayed thumbnails drawing their images...
|
|
HideUnusedWindows();
|
|
|
|
CRect TRect;
|
|
MSG Message;
|
|
|
|
// Fix bug#3435
|
|
// Ensure that there are thumbs displayed prior to drawing thumb images...
|
|
if ( m_FirstDisplayedThumb > 0 )
|
|
{
|
|
int maxcount = MAXTHUMBSTART;
|
|
for ( ThumbNum = m_FirstDisplayedThumb;
|
|
((ThumbNum <= m_LastDisplayedThumb) && (maxcount != 0));
|
|
ThumbNum++, maxcount-- )
|
|
{
|
|
// If there is a mouse message in the queue, stop drawing thumbnail
|
|
// images to allow the message to get throught QUICKLY...
|
|
// The event handlers for these events will invalidate any remaining
|
|
// thumbs such that they will be painted...
|
|
if ( ::PeekMessage(&Message, m_hWnd, WM_LBUTTONDOWN,
|
|
WM_MOUSELAST, PM_NOREMOVE) )
|
|
{
|
|
m_NeedDrawFrom = ThumbNum;
|
|
break;
|
|
}
|
|
|
|
GetThumbDisplayRect(ThumbNum, ThumbBox);
|
|
if ( TRect.IntersectRect(ThumbBox, rcInvalid) )
|
|
DrawThumbImage(ThumbNum, ThumbBox.left, ThumbBox.top);
|
|
}
|
|
}
|
|
|
|
// Validate entire window (this stops the flashing caused by
|
|
// O/i drawing to windows ON TOP OF our control's window...)
|
|
ValidateRect(NULL);
|
|
|
|
END_TIMER(m_TimeAllDraw);
|
|
|
|
#ifdef _DEBUG
|
|
TRACE3("Draw: O/i: %lu, Thumb: %lu, Total: %lu (milliseconds).\n\r", m_TimeOiDraw, m_TimeAllDraw - m_TimeOiDraw, m_TimeAllDraw);
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::OnDraw helper - Draw thumb background
|
|
//
|
|
// Left, Top is position of corner of thumbnail box's sel indicator...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::DrawThumbBackground(CDC* pdc, long ThumbNumber,
|
|
long Left, long Top)
|
|
{
|
|
//TRACE1("Draw thumb #%lu's background...\n\r", ThumbNumber);
|
|
|
|
Left += THUMBSELOFFSET_X + THUMBSELWIDTH;
|
|
Top += THUMBSELOFFSET_Y + THUMBSELWIDTH;
|
|
|
|
CRect Thumb((int)Left, (int)Top,
|
|
(int)Left+(int)m_ThumbWidth, (int)Top+(int)m_ThumbHeight);
|
|
pdc->Rectangle(Thumb);
|
|
|
|
/* If this is really what we want!!!
|
|
// At Microsoft's request the top/left edges of the thumbbox
|
|
// should be dark gray (& Dan further clarifies it by saying
|
|
// that the top/right and bottom/left corner pixels should
|
|
// be dark gray!)
|
|
CPen LinePen;
|
|
LinePen.CreatePen(PS_SOLID, 0, rgbDkGray);
|
|
CPen * pop = pdc->SelectObject(&LinePen);
|
|
|
|
POINT Pnts[3];
|
|
Pnts[0].x = (int)Left;
|
|
Pnts[0].y = (int)Top+(int)m_ThumbHeight-1;
|
|
Pnts[1].x = (int)Left;
|
|
Pnts[1].y = (int)Top;
|
|
Pnts[2].x = (int)Left+(int)m_ThumbWidth;
|
|
Pnts[2].y = (int)Top;
|
|
pdc->Polyline(Pnts, 3);
|
|
|
|
pdc->SelectObject(pop);
|
|
*/
|
|
|
|
// Keep track of what the last displayed thumbnail box is...
|
|
m_LastDisplayedThumb = ThumbNumber;
|
|
|
|
TCHAR szPageNum[64]; // (WAY) Big enough to hold a pagenumber...
|
|
|
|
// ...and the annotation presence indicator (if requested)...
|
|
int LableXOffset = 0;
|
|
if ( (m_ThumbCaptionStyle == CTL_THUMB_SIMPLEWITHANN) ||
|
|
(m_ThumbCaptionStyle == CTL_THUMB_CAPTIONWITHANN) )
|
|
{
|
|
// Check for annotations...
|
|
if ((m_bDrawThumbImages == TRUE) &&
|
|
(m_ImageOIFileType != FIO_AWD) &&
|
|
PageHasAnnotations(ThumbNumber) )
|
|
{
|
|
CTransBmp Indicator;
|
|
if ( FALSE != Indicator.LoadBitmap(IDB_ANNOTATIONINDICATOR) )
|
|
{
|
|
Indicator.DrawTrans(pdc, Thumb.left, Thumb.bottom +
|
|
m_TextAscent + m_TextPad -
|
|
Indicator.GetHeight());
|
|
LableXOffset = Indicator.GetWidth() + 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ...and its caption (if requested)...
|
|
if ( m_ThumbCaptionStyle != CTL_THUMB_NONE )
|
|
{
|
|
// Set text output to clip appropriatly
|
|
int ClipTop = (int)Top +
|
|
(int)m_ThumbHeight+THUMBSELOFFSET_Y+THUMBSELWIDTH;
|
|
|
|
CRect Clip;
|
|
Clip.SetRect((int)Left, ClipTop,
|
|
(int)Left+(int)m_ThumbWidth,
|
|
ClipTop+(int)m_LabelSpacing);
|
|
|
|
pdc->IntersectClipRect(Clip);
|
|
|
|
if ( (m_ThumbCaptionStyle == CTL_THUMB_SIMPLE) ||
|
|
(m_ThumbCaptionStyle == CTL_THUMB_SIMPLEWITHANN) )
|
|
{
|
|
_itot((int)ThumbNumber, szPageNum, 10);
|
|
|
|
pdc->TextOut(Thumb.left+LableXOffset, Thumb.bottom+m_TextPad,
|
|
szPageNum, lstrlen(szPageNum));
|
|
}
|
|
else if ( (m_ThumbCaptionStyle == CTL_THUMB_CAPTION) ||
|
|
(m_ThumbCaptionStyle == CTL_THUMB_CAPTIONWITHANN) )
|
|
{
|
|
CString szPlaceHolder;
|
|
|
|
CString szCaption = m_Caption;
|
|
|
|
// Replace the page number placeholder with the pagenumber...
|
|
szPlaceHolder.LoadString(IDS_PAGENUMBER);
|
|
ReplaceString(szCaption, szPlaceHolder, ThumbNumber);
|
|
|
|
// Replace the page count placeholder with the thumb count...
|
|
szPlaceHolder.LoadString(IDS_PAGECOUNT);
|
|
ReplaceString(szCaption, szPlaceHolder, m_ThumbCount);
|
|
|
|
pdc->TextOut(Thumb.left+LableXOffset, Thumb.bottom+m_TextPad,
|
|
szCaption, lstrlen(szCaption));
|
|
}
|
|
|
|
pdc->SelectClipRgn(NULL);
|
|
}
|
|
|
|
// ...and its selection indicator (if needed)...
|
|
if ( m_bHilightSelectedThumbs && (m_ThumbFlags[(int)ThumbNumber-1] & THUMBFLAGS_SELECTED) )
|
|
{
|
|
CRect SelRect;
|
|
|
|
SelRect = Thumb;
|
|
SelRect.InflateRect(THUMBSELOFFSET_X, THUMBSELOFFSET_Y);
|
|
SelRect.right++;
|
|
SelRect.bottom++;
|
|
|
|
CBrush ThumbSelBrush;
|
|
CPen ThumbSelPen;
|
|
|
|
ThumbSelBrush.CreateStockObject(NULL_BRUSH);
|
|
ThumbSelPen.CreatePen(PS_SOLID, THUMBSELWIDTH,
|
|
TranslateColor(m_HighlightColor));
|
|
|
|
CBrush* pob = pdc->SelectObject(&ThumbSelBrush);
|
|
CPen* pop = pdc->SelectObject(&ThumbSelPen);
|
|
pdc->Rectangle(SelRect);
|
|
|
|
pdc->SelectObject(pob);
|
|
pdc->SelectObject(pop);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::OnDraw helper - Draw thumb image
|
|
//
|
|
// Left, Top is position of corner of thumbnail box...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::DrawThumbImage(long ThumbNumber, long Left, long Top)
|
|
{
|
|
//TRACE1("Draw thumb #%lu's image...\n\r", ThumbNumber);
|
|
|
|
// Generate the thumb(s), if it hasn't already been generated,
|
|
// just before we need it for display...
|
|
if (GenerateThumbInternal(CTL_THUMB_GENERATEIFNEEDED, ThumbNumber) == FALSE)
|
|
return;
|
|
|
|
// Get the window for this thumbnail. Note that upon return the
|
|
// window's size and content are already set!
|
|
CWnd* pWnd = GetPageWindow(ThumbNumber);
|
|
|
|
if ( pWnd != NULL )
|
|
{
|
|
ResetStatus();
|
|
|
|
m_StatusCode = IMGRegWndw(pWnd->GetSafeHwnd());
|
|
|
|
BOOL bDeregWhenDone = TRUE;
|
|
if ( m_StatusCode == IMG_SSDUPLICATE )
|
|
{
|
|
m_StatusCode = 0;
|
|
bDeregWhenDone = FALSE;
|
|
}
|
|
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
//TRACE1("OnDraw: Reg new thumbwnd ret 0x%lx.\n\r", m_StatusCode);
|
|
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
}
|
|
else
|
|
{
|
|
UINT PalType = DISP_PALETTE_COMMON;
|
|
m_StatusCode = IMGSetParmsCgbw(pWnd->GetSafeHwnd(),
|
|
PARM_DISPLAY_PALETTE,
|
|
&PalType,
|
|
PARM_WINDOW_DEFAULT);
|
|
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
//TRACE1("OnDraw: SetParm COMPALETTE ret 0x%lx.\n\r", m_StatusCode);
|
|
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
|
|
// Let it go... (i.e., NOT fatal but...)
|
|
}
|
|
|
|
// Do first rendering (no display)
|
|
DisplayFitToWindow(pWnd, ThumbNumber);
|
|
|
|
// Move the window to the thumbbox...
|
|
// (Note that the window is fit to the image)
|
|
RECT WRect;
|
|
pWnd->GetWindowRect(&WRect);
|
|
int WHeight = WRect.bottom - WRect.top;
|
|
int WWidth = WRect.right - WRect.left;
|
|
|
|
// Center thumbnail in the thumbbox. Adjust window's
|
|
// Left/Top by 1 to place inside of thumbbox's border.
|
|
int WinLeft = (int)Left + 1;
|
|
int WinTop = (int)Top + 1;
|
|
|
|
// Subtract out the 1 pixel border around
|
|
// (i.e., on EACH side of) the thumbbox...
|
|
long TargetWidth = m_ThumbWidth-2;
|
|
long TargetHeight = m_ThumbHeight-2;
|
|
|
|
// Determine whether we should center vertically or horizontally...
|
|
if ( (TargetWidth - WWidth) < (TargetHeight - WHeight) )
|
|
WinTop += (((int)m_ThumbHeight - WHeight)/2)-1;
|
|
else
|
|
WinLeft += (((int)m_ThumbWidth - WWidth)/2)-1;
|
|
|
|
// Reposition the window and repaint...
|
|
pWnd->SetWindowPos(&wndTop, WinLeft, WinTop, 0, 0,
|
|
SWP_NOSIZE | SWP_SHOWWINDOW);
|
|
|
|
START_TIMER(m_TimeTemp);
|
|
|
|
if ( bDeregWhenDone )
|
|
{
|
|
m_StatusCode = IMGDeRegWndw(pWnd->GetSafeHwnd());
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
TRACE1("OnDraw: DeReg returned 0x%lx.\n\r", m_StatusCode);
|
|
|
|
// Translate the O/i error to an SCODE getting the associated
|
|
// string and helpID and fore this as an error condition...
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
}
|
|
}
|
|
}
|
|
|
|
INC_TIMER(m_TimeOiDraw, m_TimeTemp);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::OnDraw helper - Replace String
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::ReplaceString(CString& Str, CString& Repl, long Number)
|
|
{
|
|
CString szNumber;
|
|
|
|
_itot((int)Number, szNumber.GetBuffer(128), 10);
|
|
szNumber.ReleaseBuffer();
|
|
|
|
int Pos = Str.Find(Repl);
|
|
|
|
if ( Pos != -1 )
|
|
{
|
|
Str = Str.Left(Pos) +
|
|
szNumber +
|
|
Str.Right(Str.GetLength() - (Pos+Repl.GetLength()));
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::OnDraw helper - PageHasAnnotations
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CThumbCtrl::PageHasAnnotations(long ThumbNumber)
|
|
{
|
|
// Assume NO annotations... (i.e., in case we fail for any reason...)
|
|
BOOL bHasAnnotations = FALSE;
|
|
int Ix = (int)ThumbNumber - 1;
|
|
|
|
// See if we've already generated thumbnails...
|
|
if ( (long)(m_IHThumbToTPage[Ix]) > 0 )
|
|
{
|
|
// Since the thumbnail(s) for this page have already been generated
|
|
// we can QUICKLY check for the presence of annotations by seeing
|
|
// if the thumbnail's has annotations flag is set...
|
|
if ( ((long)(m_ThumbFlags[Ix]) & THUMBFLAGS_HASANNO) == THUMBFLAGS_HASANNO )
|
|
bHasAnnotations = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Thumbnails have NOT YET been generated... We have to check
|
|
// via O/i on the file itself...
|
|
FIO_INFORMATION Fio;
|
|
memset(&Fio, 0, sizeof(FIO_INFORMATION)); // memset
|
|
|
|
Fio.filename = (LPSTR)(const char *)m_Image;
|
|
Fio.page_number = (int)ThumbNumber;
|
|
|
|
FIO_INFO_CGBW FioCgbw;
|
|
memset(&FioCgbw, 0, sizeof(FIO_INFO_CGBW));
|
|
|
|
// Bug#3276: Must specify what information we want to get back!!!
|
|
FioCgbw.fio_flags = FIO_ANNO_DATA | FIO_IMAGE_DATA;
|
|
|
|
if (TRUE == CreateHiddenWindow() )
|
|
{
|
|
ResetStatus();
|
|
m_StatusCode = IMGFileGetInfo(NULL, m_IHphWndHidden->GetSafeHwnd(),
|
|
&Fio, &FioCgbw, NULL);
|
|
|
|
if ( m_StatusCode == 0 )
|
|
{
|
|
if ( (FioCgbw.fio_flags & FIO_ANNO_DATA) == FIO_ANNO_DATA )
|
|
bHasAnnotations = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Translate the O/i error to an SCODE getting the associated
|
|
// string and helpID and fore this as an error condition...
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString,
|
|
m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
}
|
|
}
|
|
}
|
|
|
|
return bHasAnnotations;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::OnResetState - Reset control to default state
|
|
|
|
void CThumbCtrl::OnResetState()
|
|
{
|
|
TRACE0("In ResetState...\n\r");
|
|
|
|
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
|
|
|
|
// TBD: Reset any other control state here.
|
|
// Just what does that mean???
|
|
// Do we reset ThumbCount and selection statuses???
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::RecalcThumbInfo - Recalculate thumbnail control layout info...
|
|
void CThumbCtrl::RecalcThumbInfo(BOOL bMaintainRelativeScroll /* = FALSE */)
|
|
{
|
|
// Calculates:
|
|
// Number of thumbs that can fit across the control (m_ThumbsX)
|
|
// Number of thumbs that can fit down the control (m_ThumbsY)
|
|
//
|
|
// Assuming:
|
|
// all thumbnail boxes are equal in size
|
|
// space between the thumbs is equal in size
|
|
// space around the thumbs (to the window's edge) is equal in size
|
|
//
|
|
// This picture demonstrates with vertical scroll but applies when it is
|
|
// horizontal also...
|
|
//
|
|
// |-------------------------------------| N = Number of thumbnail boxes
|
|
// | | W = Window's width
|
|
// | <sp> | sp = interthumb spacing
|
|
// | +-----+ +-----+ +-----+ | tx = xtra space for text label
|
|
// | | | | | | | | w = Thumb width
|
|
// |<sp>|<-w->|<sp>|<-w->|<sp>|<-w->|<sp>| h = Thumb height
|
|
// | | | | | | | |
|
|
// | +-----+ +-----+ +-----+ | N*w + (N+1)*sp = W, and thus
|
|
// | <tx> | N = (W-sp)/(w+sp)
|
|
// | <sp> |
|
|
// | +-----+ +-----+ +-----+ |
|
|
// | | | | | | | |
|
|
// |<sp>|<-w->|<sp>|<-w->|<sp>|<-w->|<sp>| Also note that:
|
|
// | | | | | | | | the control's height (H) is:
|
|
// | +-----+ +-----+ +-----+ |
|
|
// | <tx> | H = (num rows)*(h+sp+tx)
|
|
// | <sp> |
|
|
// | . | It is IMPORTANT to note that
|
|
// | . | in the NON_SCROLLING direction
|
|
// | . | the space is evenly distributed
|
|
// | +-----+ +-----+ +-----+ | on each side of all thumb boxes
|
|
// | | | | | | | |
|
|
// |<sp>|<-w->|<sp>|<-w->|<sp>|<-w->|<sp>|
|
|
// | | | | | | | |
|
|
// | +-----+ +-----+ +-----+ |
|
|
// | <tx> |
|
|
// +-------------------------------------+
|
|
//
|
|
// The calculated N will be an integer. However, N is actually not typically
|
|
// an integral value. Using the calculated integral value of N the value of
|
|
// W (control width) that FITS that value can be found and then the
|
|
// difference between the current control's width and the width that FITS
|
|
// N thumbnails can be evenly distributed between the interthumb spacings.
|
|
|
|
// Remember the current scroll range and position
|
|
// when all is done if we are asked to maintain range and position
|
|
// we will reset to the same RELATIVE position...
|
|
long OldScrollRange = m_ScrollRange;
|
|
long OldScrollOffset = m_ScrollOffset;
|
|
|
|
// Get control's Width & Height
|
|
int CtlWidth;
|
|
int CtlHeight;
|
|
GetControlSize( &CtlWidth, &CtlHeight );
|
|
|
|
// Calculate information needed for placing any labels beneath
|
|
// the thumbnail boxes...
|
|
// Save text info - Height and
|
|
// Ascent
|
|
TEXTMETRIC tm;
|
|
m_ThumbCaptionFont.QueryTextMetrics(&tm);
|
|
m_TextHeight = tm.tmHeight;
|
|
m_TextAscent = tm.tmAscent;
|
|
|
|
// Setup Textpad based upon presence of selection indicator...
|
|
m_TextPad = THUMBSELOFFSET_Y + THUMBSELWIDTH;
|
|
|
|
// Adjust TextPad to account for taller of label's text
|
|
// or annotation presence indicator...
|
|
if ( (m_ThumbCaptionStyle == CTL_THUMB_SIMPLEWITHANN ) ||
|
|
(m_ThumbCaptionStyle == CTL_THUMB_CAPTIONWITHANN) )
|
|
{
|
|
CBitmap Indicator;
|
|
if ( FALSE != Indicator.LoadBitmap(IDB_ANNOTATIONINDICATOR) )
|
|
{
|
|
BITMAP BitmapInfo;
|
|
Indicator.GetObject(sizeof(BITMAP), &BitmapInfo);
|
|
|
|
if ( m_TextHeight < BitmapInfo.bmHeight )
|
|
m_TextPad = THUMBSELOFFSET_Y + THUMBSELWIDTH +
|
|
BitmapInfo.bmHeight + 1 -
|
|
m_TextHeight;
|
|
}
|
|
}
|
|
|
|
// Setup LabelSpacing (which we use regardless of
|
|
// whether or not labels are to be drawn)...
|
|
if ( m_ThumbCaptionStyle != CTL_THUMB_NONE )
|
|
m_LabelSpacing = m_TextPad + m_TextHeight;
|
|
else
|
|
m_LabelSpacing = 0;
|
|
|
|
// moved this here (from the beginning of the function) to allow
|
|
// to be called from GetScrollDirectionSize to set m_LabelSpacing
|
|
if ( m_ThumbCount == 0 )
|
|
{
|
|
if ( GetSafeHwnd() != NULL )
|
|
{
|
|
ShowScrollBar(SB_HORZ, FALSE);
|
|
ShowScrollBar(SB_VERT, FALSE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Vars for calculation of actual spacing...
|
|
long MinCtlSize;
|
|
long ExtraSpacing;
|
|
|
|
// Minimum requested spacing is either: as specified or
|
|
// a percentage of thumbwidth
|
|
long MinSpacing = m_ThumbMinSpacing;
|
|
|
|
// Total scroll direction size of the control...
|
|
long ScrollSize;
|
|
|
|
if ( m_ScrollDirection == CTL_THUMB_HORIZONTAL )
|
|
{ // Horizontal scrolling...
|
|
// Hide any vertical scroll bar...
|
|
if ( GetSafeHwnd() != NULL )
|
|
ShowScrollBar(SB_VERT, FALSE);
|
|
|
|
// Minimum requested spacing is either: as specified or
|
|
// a percentage of thumbheight
|
|
if ( MinSpacing < 0 )
|
|
MinSpacing = -(MinSpacing * m_AdjThumbHeight) / 100;
|
|
else
|
|
MinSpacing += 2*(THUMBSELOFFSET_Y+THUMBSELWIDTH+2);
|
|
|
|
// Calculate number of thumb rows (N)... (Not less than 1...)
|
|
m_ThumbsY = __max(1, ((CtlHeight-MinSpacing) / (m_AdjThumbHeight +
|
|
MinSpacing +
|
|
m_LabelSpacing)));
|
|
|
|
// Calculate the actual spacing... (a float such that we can
|
|
// distribute any rounding errors between the thumbnail boxes)
|
|
MinCtlSize = (m_ThumbsY*(m_AdjThumbHeight + m_LabelSpacing)) +
|
|
((m_ThumbsY+1) * MinSpacing);
|
|
|
|
ExtraSpacing = __max(0, CtlHeight - MinCtlSize);
|
|
m_Spacing = (float)MinSpacing +
|
|
(float)ExtraSpacing/((float)(m_ThumbsY+1));
|
|
|
|
// Thumb columns...
|
|
m_ThumbsX = (m_ThumbCount / m_ThumbsY) +
|
|
( (m_ThumbCount%m_ThumbsY==0)? 0:1 );
|
|
|
|
// Total Scrolling direction size
|
|
// (add 1/2*spacing to make it look better!)
|
|
ScrollSize = (long)m_Spacing / 2 +
|
|
(long)((float)m_ThumbsX *
|
|
(m_Spacing+(float)m_AdjThumbWidth));
|
|
|
|
// Check to see if we need a scroll bar (i.e., more rows than will fit)
|
|
if ( ScrollSize > CtlWidth )
|
|
{
|
|
// Need a horizontal scroll bar... Recalculate everything after
|
|
// shrinking control height by the height of a scrollbar...
|
|
CtlHeight -= GetSystemMetrics(SM_CYHSCROLL);
|
|
|
|
// Calculate number of thumb rows (N)... (Not less than 1...)
|
|
m_ThumbsY = __max(1, ((CtlHeight-MinSpacing) / (m_AdjThumbHeight +
|
|
MinSpacing +
|
|
m_LabelSpacing)));
|
|
|
|
// Calculate the actual spacing... (a float such that we can
|
|
// distribute any rounding errors between the thumbnail boxes)
|
|
MinCtlSize = (m_ThumbsY*(m_AdjThumbHeight + m_LabelSpacing)) +
|
|
((m_ThumbsY+1) * MinSpacing);
|
|
|
|
ExtraSpacing = __max(0, CtlHeight - MinCtlSize);
|
|
m_Spacing = (float)MinSpacing +
|
|
(float)ExtraSpacing/((float)(m_ThumbsY+1));
|
|
|
|
// Thumb columns...
|
|
m_ThumbsX = (m_ThumbCount / m_ThumbsY) +
|
|
( (m_ThumbCount%m_ThumbsY==0)? 0:1 );
|
|
|
|
// Total Scrolling direction size
|
|
// (add 1/2*spacing to make it look better!)
|
|
ScrollSize = (long)m_Spacing / 2 +
|
|
(long)((float)m_ThumbsX *
|
|
(m_Spacing+(float)m_AdjThumbWidth));
|
|
|
|
m_ScrollRange = ScrollSize - CtlWidth;
|
|
|
|
// If we were asked to maintain the relative scroll position
|
|
// (i.e., position after is same as position before) calculate
|
|
// a new scroll offset that is the same relative to the new
|
|
// scrollrange...
|
|
if ( bMaintainRelativeScroll )
|
|
{
|
|
if ( OldScrollRange != 0 )
|
|
m_ScrollOffset = (long)(((float)OldScrollOffset *
|
|
(float)m_ScrollRange) /
|
|
(float)OldScrollRange);
|
|
}
|
|
|
|
if ( GetSafeHwnd() != NULL )
|
|
{
|
|
SCROLLINFO SInfo;
|
|
SInfo.cbSize = sizeof(SInfo);
|
|
SInfo.fMask = SIF_ALL;
|
|
SInfo.nMin = 0;
|
|
SInfo.nMax = (int)ScrollSize;
|
|
SInfo.nPage = CtlWidth;
|
|
SInfo.nPos = (int)m_ScrollOffset;
|
|
|
|
// Note: MUST repaint in order for changes to be displayed...
|
|
// (Redraw based upon AutoRefresh...)
|
|
::SetScrollInfo(m_hWnd, SB_HORZ, &SInfo, m_bAutoRefresh);
|
|
ShowScrollBar(SB_HORZ, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No scrolling needed, reset scroll info to 0...
|
|
m_ScrollRange = 0;
|
|
m_ScrollOffset = 0;
|
|
|
|
if ( GetSafeHwnd() != NULL )
|
|
ShowScrollBar(SB_HORZ, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{ // Vertical scrolling...
|
|
|
|
// Hide any horizontal scroll bar...
|
|
if ( GetSafeHwnd() != NULL )
|
|
ShowScrollBar(SB_HORZ, FALSE);
|
|
|
|
// Minimum requested spacing is either: as specified or
|
|
// a percentage of thumbwidth
|
|
if ( MinSpacing < 0 )
|
|
MinSpacing = -(MinSpacing * m_AdjThumbWidth) / 100;
|
|
else
|
|
MinSpacing += 2*(THUMBSELOFFSET_X+THUMBSELWIDTH+2);
|
|
|
|
// Calculate number of thumb columns (N)... (Not less than 1...)
|
|
m_ThumbsX = __max(1, (short)((CtlWidth - MinSpacing) /
|
|
(m_AdjThumbWidth + MinSpacing)));
|
|
|
|
// Calculate the actual spacing... (a float such that we can
|
|
// distribute any rounding errors across the thumbnail boxes)
|
|
MinCtlSize = m_ThumbsX*m_AdjThumbWidth + (m_ThumbsX+1)*MinSpacing;
|
|
|
|
ExtraSpacing = __max(0, CtlWidth - MinCtlSize);
|
|
m_Spacing = (float)MinSpacing +
|
|
(float)ExtraSpacing/((float)(m_ThumbsX+1));
|
|
|
|
// Thumb rows...
|
|
m_ThumbsY = (m_ThumbCount / m_ThumbsX) +
|
|
( (m_ThumbCount%m_ThumbsX==0)? 0:1 );
|
|
|
|
// Total Scrolling direction size
|
|
// (add 1/2*spacing to make it look better!)
|
|
ScrollSize = (long)m_Spacing/2 +
|
|
(long)((float)m_ThumbsY *
|
|
(float)((float)m_AdjThumbHeight +
|
|
(float)m_LabelSpacing +
|
|
m_Spacing));
|
|
|
|
// Check to see if we need a scroll bar (i.e., more rows than will fit)
|
|
if ( ScrollSize > CtlHeight )
|
|
{
|
|
// Need a vertical scroll bar... Recalculate everything after
|
|
// shrinking control width by the width of a scrollbar...
|
|
CtlWidth -= GetSystemMetrics(SM_CXVSCROLL);
|
|
|
|
// Calculate number of thumb columns (N)... (Not less than 1...)
|
|
m_ThumbsX = __max(1, (short)((CtlWidth - MinSpacing) /
|
|
(m_AdjThumbWidth + MinSpacing)));
|
|
|
|
// Calculate the actual spacing... (a float such that we can
|
|
// distribute any rounding errors across the thumbnail boxes)
|
|
MinCtlSize = m_ThumbsX*m_AdjThumbWidth + (m_ThumbsX+1)*MinSpacing;
|
|
|
|
ExtraSpacing = __max(0, CtlWidth - MinCtlSize);
|
|
m_Spacing = (float)MinSpacing +
|
|
(float)ExtraSpacing/((float)(m_ThumbsX+1));
|
|
|
|
// Thumb rows...
|
|
m_ThumbsY = (m_ThumbCount / m_ThumbsX) +
|
|
( (m_ThumbCount%m_ThumbsX==0)? 0:1 );
|
|
|
|
// Total Scrolling direction size
|
|
// (add 1/2*spacing to make it look better!)
|
|
ScrollSize = (long)m_Spacing/2 +
|
|
(long)((float)m_ThumbsY *
|
|
(float)((float)m_AdjThumbHeight +
|
|
(float)m_LabelSpacing +
|
|
m_Spacing));
|
|
|
|
m_ScrollRange = ScrollSize - CtlHeight;
|
|
|
|
// If we were asked to maintain the relative scroll position
|
|
// (i.e., position after is same as position before) calculate
|
|
// a new scroll offset that is the same relative to the new
|
|
// scrollrange...
|
|
if ( bMaintainRelativeScroll )
|
|
{
|
|
if ( OldScrollRange != 0 )
|
|
m_ScrollOffset = (long)(((float)OldScrollOffset *
|
|
(float)m_ScrollRange) /
|
|
(float)OldScrollRange);
|
|
}
|
|
|
|
if ( GetSafeHwnd() != NULL )
|
|
{
|
|
SCROLLINFO SInfo;
|
|
SInfo.cbSize = sizeof(SInfo);
|
|
SInfo.fMask = SIF_ALL;
|
|
SInfo.nMin = 0;
|
|
SInfo.nMax = (int)ScrollSize;
|
|
SInfo.nPage = CtlHeight;
|
|
SInfo.nPos = (int)m_ScrollOffset;
|
|
|
|
// Note: MUST repaint in order for changes to be displayed...
|
|
// (Redraw based upon AutoRefresh...)
|
|
::SetScrollInfo(m_hWnd, SB_VERT, &SInfo, m_bAutoRefresh);
|
|
ShowScrollBar(SB_VERT, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No scrolling needed, reset scroll info to 0...
|
|
m_ScrollRange = 0;
|
|
m_ScrollOffset = 0;
|
|
|
|
if ( GetSafeHwnd() != NULL )
|
|
ShowScrollBar(SB_VERT, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl::AboutBox - Display an "About" box to the user
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CThumbCtrl::AboutBox()
|
|
{
|
|
ResetStatus();
|
|
|
|
CDialog dlgAbout(IDD_ABOUTBOX_THUMB);
|
|
dlgAbout.DoModal();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CThumbCtrl message handlers
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message handler: WM_CREATE...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
int CThumbCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (COleControl::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
// Set the cursor now as if property was set BEFORE the window
|
|
// is created the set cursor at that time fails...
|
|
SetMousePointerInternal(m_MousePointer);
|
|
ModifyStyle(WS_CLIPCHILDREN, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message handler: WM_DESTROY...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnDestroy()
|
|
{
|
|
COleControl::OnDestroy();
|
|
|
|
ResetStatus();
|
|
|
|
// Clear up any thumbnail windows that we have created... This MUST be
|
|
// done here in the OnDestroy handler, as opposed to the destructor, as
|
|
// these windows are child windows of the control's window and are thus
|
|
// only created after the control's window is created. They MUST be
|
|
// unregistered BEFORE the control's window is itself destroyed.
|
|
for ( int Ix = 0; Ix < m_IWWindow.GetSize(); Ix++ )
|
|
{
|
|
((CWnd*)m_IWWindow[Ix])->DestroyWindow();
|
|
delete m_IWWindow[Ix];
|
|
}
|
|
|
|
// Delete our temp file...
|
|
if ( m_IHTempFile.IsEmpty() == FALSE )
|
|
{
|
|
OFSTRUCT FileInfo;
|
|
HFILE Err = ::OpenFile((LPSTR)(const char *)m_IHTempFile,
|
|
&FileInfo, OF_DELETE);
|
|
}
|
|
|
|
// Destroy any loaded cursor...
|
|
if (m_hCursor != NULL)
|
|
{
|
|
DestroyCursor(m_hCursor);
|
|
m_hCursor = NULL;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message handler: WM_SIZE...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
// Recalculate layout (maintaining our current relative scroll position)
|
|
// as size effects interthumb spacing...
|
|
RecalcThumbInfo(TRUE);
|
|
|
|
COleControl::OnSize(nType, cx, cy);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message handler: WM_VSCROLL...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnVScroll(UINT nSBCode, UINT uPos, CScrollBar* pScrollBar)
|
|
{
|
|
// The uPos value comes from the WM_VSCROLL message and can only
|
|
// be a maximum of an unsigned short. Currently it is being
|
|
// translated into a long and then unsigned so that the value comes
|
|
// out as 0xffff... instead of 0x0000... This will allow the
|
|
// maximum short value to be used.
|
|
USHORT nPos = (USHORT)uPos;
|
|
|
|
if ( nSBCode == SB_ENDSCROLL )
|
|
{
|
|
if ( m_bDrawThumbImages == FALSE )
|
|
{
|
|
// Set TO draw thumb images in OnDraw...
|
|
m_bDrawThumbImages = TRUE;
|
|
|
|
// TBD: Handle scrolling w/ bit-blits and a smaller invalidated region...
|
|
// (requires corresponding 'smarter' OnDraw function above!)
|
|
InvalidateControl();
|
|
}
|
|
return;
|
|
}
|
|
|
|
int Pos;
|
|
|
|
if ( (nSBCode != SB_THUMBPOSITION) && (nSBCode != SB_THUMBTRACK) )
|
|
Pos = (UINT)GetScrollPos(SB_VERT);
|
|
else
|
|
Pos = nPos;
|
|
|
|
int CtlWidth;
|
|
int CtlHeight;
|
|
GetControlSize( &CtlWidth, &CtlHeight );
|
|
|
|
int ScrollAmount = 0;
|
|
|
|
BOOL bScrolled = FALSE;
|
|
|
|
if ( nSBCode == SB_LINEUP )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = -CtlHeight/10;
|
|
bScrolled = TRUE;
|
|
//TRACE0("LineUP (-10%)\n\r");
|
|
}
|
|
else if ( nSBCode == SB_LINEDOWN )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = CtlHeight/10;
|
|
bScrolled = TRUE;
|
|
//TRACE0("LineDOWN (+10%)\n\r");
|
|
}
|
|
else if ( nSBCode == SB_PAGEUP )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = -(CtlHeight - CtlHeight/10);
|
|
bScrolled = TRUE;
|
|
//TRACE0("PageUP (-90%)\n\r");
|
|
}
|
|
else if ( nSBCode == SB_PAGEDOWN )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = (CtlHeight - CtlHeight/10);
|
|
bScrolled = TRUE;
|
|
//TRACE0("PageDOWN (+90%)\n\r");
|
|
}
|
|
else if ( nSBCode == SB_THUMBTRACK )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
}
|
|
|
|
Pos += ScrollAmount;
|
|
if ( Pos < 0 )
|
|
Pos = 0;
|
|
else if ( Pos > m_ScrollRange )
|
|
Pos = (UINT)m_ScrollRange;
|
|
|
|
// If we have a new scroll offset, update...
|
|
if ( m_ScrollOffset != Pos )
|
|
{
|
|
/* Attempt at blit-scrolling...
|
|
if ( ScrollAmount != 0 )
|
|
{
|
|
CRect UpdateRect;
|
|
CRect ScrollRect;
|
|
CRect ClipRect;
|
|
|
|
ScrollRect.left = 0;
|
|
ScrollRect.right = CtlWidth;
|
|
|
|
if ( ScrollAmount > 0 )
|
|
{
|
|
TRACE0("+ScrollAmount\n\r");
|
|
ScrollRect.top = ScrollAmount;
|
|
ScrollRect.bottom = CtlHeight;
|
|
}
|
|
else
|
|
{
|
|
TRACE0("-ScrollAmount\n\r");
|
|
ScrollRect.top = 0;
|
|
ScrollRect.bottom = CtlHeight+ScrollAmount;
|
|
}
|
|
TRACE2("Top: %u, Bottom: %u\n\r", ScrollRect.top, ScrollRect.bottom);
|
|
|
|
CDC* pdc = GetDC();
|
|
BOOL Ret = pdc->ScrollDC(0,-ScrollAmount,
|
|
ScrollRect, NULL, NULL, UpdateRect);
|
|
ReleaseDC(pdc);
|
|
|
|
TRACE1("Ret: %i\n\r", Ret);
|
|
|
|
m_ScrollOffset = Pos;
|
|
|
|
// TBD: Win95 use SetScrollInfo!!!
|
|
SetScrollPos(SB_VERT, Pos);
|
|
SetScrollRange(SB_VERT, 0, (UINT)m_ScrollRange);
|
|
|
|
// TBD: Handle scroll w/ bit-blits and a smaller invalidated region...
|
|
// (requires corresponding 'smarter' OnDraw function above!)
|
|
InvalidateControl(&UpdateRect);
|
|
|
|
TRACE2("Update: (%i,%i)\n\r", UpdateRect.left, UpdateRect.top);
|
|
TRACE2(" (%i,%i)\n\r", UpdateRect.right, UpdateRect.bottom);
|
|
}
|
|
else
|
|
{
|
|
m_ScrollOffset = Pos;
|
|
|
|
// TBD: Win95 use SetScrollInfo!!!
|
|
SetScrollPos(SB_VERT, Pos);
|
|
SetScrollRange(SB_VERT, 0, (UINT)m_ScrollRange);
|
|
|
|
// TBD: Handle scroll w/ bit-blits and a smaller invalidated region...
|
|
// (requires corresponding 'smarter' OnDraw function above!)
|
|
InvalidateControl();
|
|
}
|
|
*/
|
|
|
|
m_ScrollOffset = Pos;
|
|
|
|
SCROLLINFO SInfo;
|
|
SInfo.cbSize = sizeof(SInfo);
|
|
SInfo.fMask = SIF_POS;
|
|
SInfo.nPos = (int)m_ScrollOffset;
|
|
|
|
::SetScrollInfo(m_hWnd, SB_VERT, &SInfo, TRUE);
|
|
|
|
// TBD: Handle scroll w/ bit-blits and a smaller invalidated region...
|
|
// (requires corresponding 'smarter' OnDraw function above!)
|
|
InvalidateControl();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message handler: WM_HCROLL...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnHScroll(UINT nSBCode, UINT uPos, CScrollBar* pScrollBar)
|
|
{
|
|
// The uPos value comes from the WM_VSCROLL message and can only
|
|
// be a maximum of an unsigned short. Currently it is being
|
|
// translated into a long and then unsigned so that the value comes
|
|
// out as 0xffff... instead of 0x0000... This will allow the
|
|
// maximum short value to be used.
|
|
USHORT nPos = (USHORT)uPos;
|
|
|
|
if ( nSBCode == SB_ENDSCROLL )
|
|
{
|
|
// Set TO draw thumb images in OnDraw...
|
|
m_bDrawThumbImages = TRUE;
|
|
|
|
// TBD: Handle scrolling w/ bit-blits and a smaller invalidated region...
|
|
// (requires corresponding 'smarter' OnDraw function above!)
|
|
InvalidateControl();
|
|
return;
|
|
}
|
|
|
|
int Pos;
|
|
|
|
if ( (nSBCode != SB_THUMBPOSITION) && (nSBCode != SB_THUMBTRACK) )
|
|
Pos = (UINT)GetScrollPos(SB_HORZ);
|
|
else
|
|
Pos = nPos;
|
|
|
|
int CtlWidth;
|
|
int CtlHeight;
|
|
GetControlSize( &CtlWidth, &CtlHeight );
|
|
|
|
int ScrollAmount = 0;
|
|
|
|
BOOL bScrolled = FALSE;
|
|
|
|
if ( nSBCode == SB_LINEUP )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = -CtlWidth/10;
|
|
bScrolled = TRUE;
|
|
}
|
|
else if ( nSBCode == SB_LINEDOWN )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = CtlWidth/10;
|
|
bScrolled = TRUE;
|
|
}
|
|
else if ( nSBCode == SB_PAGEUP )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = -(CtlWidth - CtlWidth/10);
|
|
bScrolled = TRUE;
|
|
}
|
|
else if ( nSBCode == SB_PAGEDOWN )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
ScrollAmount = (CtlWidth - CtlWidth/10);
|
|
bScrolled = TRUE;
|
|
}
|
|
else if ( nSBCode == SB_THUMBTRACK )
|
|
{
|
|
// Set to NOT draw thumb images in OnDraw
|
|
m_bDrawThumbImages = FALSE;
|
|
}
|
|
|
|
Pos += ScrollAmount;
|
|
if ( Pos < 0 )
|
|
Pos = 0;
|
|
else if ( Pos > m_ScrollRange )
|
|
Pos = (UINT)m_ScrollRange;
|
|
|
|
// If we have a new scroll offset, update...
|
|
if ( m_ScrollOffset != Pos )
|
|
{
|
|
m_ScrollOffset = Pos;
|
|
|
|
SCROLLINFO SInfo;
|
|
SInfo.cbSize = sizeof(SInfo);
|
|
SInfo.fMask = SIF_POS;
|
|
SInfo.nPos = (int)m_ScrollOffset;
|
|
|
|
::SetScrollInfo(m_hWnd, SB_HORZ, &SInfo, TRUE);
|
|
|
|
// TBD: Handle scroll w/ bit-blits and a smaller invalidated region...
|
|
// (requires corresponding 'smarter' OnDraw function above!)
|
|
InvalidateControl();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Method Helper: Recalulate: Number of selected thumbs
|
|
// First selected thumb
|
|
// Last selected thumb
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::ResetSelectionInfo()
|
|
{
|
|
// Reset counts to zero. We will reset them as we go...
|
|
m_SelThumbCount = 0;
|
|
m_FirstSelThumb = 0;
|
|
m_LastSelThumb = 0;
|
|
|
|
// Walk through the ThumbFlags array...
|
|
int ArraySize = m_ThumbFlags.GetSize();
|
|
|
|
for ( int Ix = 0; Ix < ArraySize; Ix++ )
|
|
{
|
|
// If this page is selected...
|
|
// (Note: Page is 1 relative, index is 0 relative!)
|
|
if ( m_ThumbFlags[Ix] & THUMBFLAGS_SELECTED )
|
|
{
|
|
// Increment selected thumb count and
|
|
// remember this one as the last one...
|
|
m_SelThumbCount++;
|
|
m_LastSelThumb = Ix+1;
|
|
|
|
// If we haven't set the FirstSelThumb yet,
|
|
// this must be the First Selected Thumb!!!
|
|
if ( m_FirstSelThumb == 0 )
|
|
m_FirstSelThumb = Ix+1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Utility routine: BOOL GetThumbDisplayRect(long ThumbNumber, CRect& ThumbBox)
|
|
//
|
|
// Returns: TRUE if ThumbNumber is displayed, FALSE otherwise.
|
|
//
|
|
// If returns true also returns thumbbox.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CThumbCtrl::GetThumbDisplayRect(long ThumbNumber, CRect& ThumbBox)
|
|
{
|
|
int Ix; // Index into thumbstart array
|
|
|
|
// Determine if specified thumb is visible or not...
|
|
if ( (ThumbNumber >= m_FirstDisplayedThumb) &&
|
|
(ThumbNumber <= m_LastDisplayedThumb) )
|
|
{
|
|
if ( m_ScrollDirection == CTL_THUMB_HORIZONTAL )
|
|
{ // Horizontal scrolling...
|
|
Ix = (int)((ThumbNumber - m_FirstDisplayedThumb) / m_ThumbsY);
|
|
|
|
ThumbBox.left = (int)m_ThumbStart[Ix];
|
|
|
|
long row = (ThumbNumber-1) % m_ThumbsY;
|
|
|
|
ThumbBox.top = (int)(m_Spacing +
|
|
((float)row*((float)m_AdjThumbHeight +
|
|
(float)m_LabelSpacing +
|
|
m_Spacing)));
|
|
ThumbBox.top += THUMBSELOFFSET_Y + THUMBSELWIDTH;
|
|
|
|
}
|
|
else
|
|
{ // Vertical scrolling...
|
|
Ix = (int)((ThumbNumber - m_FirstDisplayedThumb) / m_ThumbsX);
|
|
|
|
ThumbBox.top = (int)m_ThumbStart[Ix];
|
|
|
|
long col = (ThumbNumber-1) % m_ThumbsX;
|
|
|
|
ThumbBox.left = (int)(m_Spacing +
|
|
((float)col * ((float)m_AdjThumbWidth + m_Spacing)));
|
|
ThumbBox.left += THUMBSELOFFSET_X + THUMBSELWIDTH;
|
|
}
|
|
|
|
ThumbBox.right = ThumbBox.left + (int)m_ThumbWidth;
|
|
ThumbBox.bottom = ThumbBox.top + (int)m_ThumbHeight;
|
|
// MFH - 10/13/95: Invalidate caption in case
|
|
// annotation bitmap will need to be drawn or removed
|
|
if ( (m_ThumbCaptionStyle == CTL_THUMB_SIMPLEWITHANN) ||
|
|
(m_ThumbCaptionStyle == CTL_THUMB_CAPTIONWITHANN) )
|
|
{
|
|
ThumbBox.bottom += m_LabelSpacing;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Method Helper: Create the hidden image window...
|
|
//
|
|
// Note: Sets m_StatusCode if returns FALSE
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CThumbCtrl::CreateHiddenWindow()
|
|
{
|
|
// If we have yet to get our hidden window, get it now...
|
|
if ( m_IHphWndHidden == NULL )
|
|
{
|
|
m_IHphWndHidden = new CHiddenWnd;
|
|
if ( m_IHphWndHidden != NULL )
|
|
{
|
|
//TRACE0("Creating hidden window...\n\r");
|
|
|
|
if (m_IHphWndHidden->CreateEx(m_ThumbWidth, m_ThumbHeight) == FALSE)
|
|
{
|
|
TRACE0("Create of hidden window failed...\n\r");
|
|
|
|
// Window create failed, delete and null the CWnd* we DID get...
|
|
m_StatusCode = CTL_E_OUTOFMEMORY;
|
|
delete m_IHphWndHidden;
|
|
m_IHphWndHidden = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
//TRACE0("Hidden display window created...\n\r");
|
|
|
|
// Register the hidden window with O/i...
|
|
m_StatusCode = IMGRegWndw(m_IHphWndHidden->GetSafeHwnd());
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
TRACE1("SetImage: RegWndw of hidden wnd ret 0x%lx.\n\r", m_StatusCode);
|
|
|
|
delete m_IHphWndHidden;
|
|
m_IHphWndHidden = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
//TRACE0("Hidden display window registered...\n\r");
|
|
|
|
// Set all displays to fit-to-window...
|
|
UINT Scale = SD_FIT_WINDOW;
|
|
m_StatusCode =IMGSetParmsCgbw(m_IHphWndHidden->GetSafeHwnd(),
|
|
PARM_SCALE, &Scale,
|
|
PARM_WINDOW_DEFAULT);
|
|
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
TRACE1("SetImg: SetParmsSCALE hidden wnd ret 0x%lx.\n\r", m_StatusCode);
|
|
|
|
delete m_IHphWndHidden;
|
|
m_IHphWndHidden = NULL;
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{ // Unable to allocate new CHiddenWnd
|
|
m_StatusCode = CTL_E_OUTOFMEMORY;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image Window helper function: DisplayFitToWindow...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::ResetStatus()
|
|
{
|
|
// Reset to no error status...
|
|
m_StatusCode = 0;
|
|
|
|
// Empty the error string...
|
|
m_szThrowString.Empty();
|
|
|
|
// Reset the Help context ID to 0...
|
|
m_ThrowHelpID = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IMAGE WINDOWS handling section
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image Window helper function: GetPageWindow...
|
|
//
|
|
// returns:
|
|
// CWnd pointer - if window for display exists
|
|
// NULL - if no window exists...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CWnd* CThumbCtrl::GetPageWindow(long Page)
|
|
{
|
|
//TRACE1("GetPageWnd: Page %lu.\n\r", Page);
|
|
|
|
// Search through the DisplayedPage array for the requested page...
|
|
int ArraySize = m_IWDisplayedPage.GetSize();
|
|
int Ix = ArraySize;
|
|
int AvailableIx = ArraySize;
|
|
|
|
for ( int i = 0; i < ArraySize; i++ )
|
|
{
|
|
if ( (long)m_IWDisplayedPage[i] == Page )
|
|
{ // If we have found the page, stop looking...
|
|
Ix = i;
|
|
break;
|
|
}
|
|
else if (AvailableIx == ArraySize)
|
|
{ // If this is not the page & we've not found an available index...
|
|
|
|
// if this index is available, remember it...
|
|
if ( m_IWDisplayedPage[i] == 0 )
|
|
AvailableIx = i;
|
|
}
|
|
}
|
|
|
|
if ( Ix == ArraySize )
|
|
{
|
|
// Page not found in DisplayedPage array,
|
|
// display and size page to a window...
|
|
//TRACE0("GetPageWnd: Page not found in window array.\n\r");
|
|
|
|
if ( AvailableIx == ArraySize )
|
|
{ // No available index found...
|
|
//TRACE1("GetPageWnd: No unused wnds, creating new one (#%u).\n\r", ArraySize);
|
|
|
|
// Create a NEW window and add it, and the page to the IW arrays.
|
|
// The window is created (and used) disabled such that
|
|
// its events go to the parent
|
|
CWnd* pWnd = new CWnd;
|
|
if ( pWnd != NULL )
|
|
{
|
|
CRect WinRect(0,0,m_ThumbWidth, m_ThumbHeight);
|
|
if ( pWnd->Create( NULL, "", WS_CHILD | WS_DISABLED,
|
|
WinRect, this, m_NextWindowID++) )
|
|
{
|
|
int FirstAdd = -1;
|
|
TRY
|
|
{
|
|
/*
|
|
#ifdef _DEBUG
|
|
if ( ::GetAsyncKeyState(VK_SHIFT) < 0 )
|
|
AfxThrowMemoryException();
|
|
#endif
|
|
*/
|
|
|
|
FirstAdd = m_IWDisplayedPage.Add(Page);
|
|
|
|
/*
|
|
#ifdef _DEBUG
|
|
if ( ::GetAsyncKeyState(VK_CONTROL) < 0 )
|
|
AfxThrowMemoryException();
|
|
#endif
|
|
*/
|
|
|
|
m_IWWindow.Add(pWnd);
|
|
}
|
|
CATCH(CMemoryException,e)
|
|
{
|
|
// If we get here with the 1st add having succeeded
|
|
// (i.e., FirstAdd != -1) and the 2nd fails
|
|
// remove what was added and return failure...
|
|
if ( FirstAdd != -1 )
|
|
m_IWDisplayedPage.RemoveAt(FirstAdd);
|
|
|
|
ResetStatus();
|
|
m_StatusCode = ErrMap::Xlate(CTL_E_OUTOFMEMORY, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
|
|
// Unable to continue...
|
|
delete pWnd;
|
|
pWnd = NULL;
|
|
return pWnd;
|
|
}
|
|
END_CATCH
|
|
}
|
|
else
|
|
{
|
|
delete pWnd;
|
|
pWnd = NULL;
|
|
}
|
|
}
|
|
|
|
return pWnd;
|
|
}
|
|
else
|
|
{ // An available index was found, recycle it's window...
|
|
//TRACE1("GetPageWnd: Found unused wnd (#%u), recycle it...\n\r", AvailableIx);
|
|
m_IWDisplayedPage[AvailableIx] = Page;
|
|
return ((CWnd*)m_IWWindow[AvailableIx]);
|
|
}
|
|
}
|
|
else
|
|
{ // Page found...
|
|
// No need to redisplay page into its associated window...
|
|
// return existing window from Window array...
|
|
//TRACE0("GetPageWnd: Page found in wnd array, already disp in wnd.\n\r");
|
|
|
|
return ((CWnd*)m_IWWindow[Ix]);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image Window helper function: ClearPageWindow...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::ClearPageWindow(long Page)
|
|
{
|
|
// Clear this page's DisplayedPage Array entry.
|
|
// This will force the next display of this page to
|
|
// re-display it's thumbnail image into a window...
|
|
int ArraySize = m_IWDisplayedPage.GetSize();
|
|
|
|
for ( int i = 0; i < ArraySize; i++ )
|
|
{
|
|
if ( (long)m_IWDisplayedPage[i] == Page )
|
|
{ // If we have found the page, stop looking...
|
|
// Array entry no longer in use...
|
|
m_IWDisplayedPage[i] = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image Window helper function: ClearAllPageWindows...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::ClearAllPageWindows()
|
|
{
|
|
// Clear the DisplayedPage Array... This will force the next
|
|
// display of a page to re-display it's thumbnail image into a window...
|
|
int ArraySize = m_IWDisplayedPage.GetSize();
|
|
|
|
for ( int i = 0; i < ArraySize; i++ )
|
|
{
|
|
//TRACE1("Clearing Page # %lu's Page entries...\n\r", Page);
|
|
|
|
// Array entry no longer in use...
|
|
m_IWDisplayedPage[i] = 0;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image Window helper function: HideUnusedWindows...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::HideUnusedWindows()
|
|
{
|
|
// Clear this page's DisplayedPage Array. This will force the next display
|
|
// of this page to re-display it's thumbnail image into a window...
|
|
int ArraySize = m_IWDisplayedPage.GetSize();
|
|
|
|
for ( int i = 0; i < ArraySize; i++ )
|
|
{
|
|
if ( ((long)m_IWDisplayedPage[i] < m_FirstDisplayedThumb) ||
|
|
((long)m_IWDisplayedPage[i] > m_LastDisplayedThumb) )
|
|
{ // Hide unused windows...
|
|
m_IWDisplayedPage[i] = 0;
|
|
((CWnd*)m_IWWindow[i])->ShowWindow(SW_HIDE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image Window helper function: DisplayFitToWindow...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::DisplayFitToWindow(CWnd* pWnd, long Page)
|
|
{
|
|
// Check if temp file was not generated
|
|
if (m_IHTempFile.IsEmpty())
|
|
{
|
|
TRACE0("DispFitWnd: No temp file to display!!\n\r");
|
|
m_StatusCode = CTL_E_PATHFILEACCESSERROR;
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
return;
|
|
}
|
|
//TRACE1("DispFitWnd: Display page #%lu.\n\r", Page);
|
|
|
|
// Index into the ThumbToTPage array...
|
|
int Ix = (int)Page-1;
|
|
|
|
Page = m_IHThumbToTPage[Ix];
|
|
|
|
//TRACE2("DispFitWnd: Display page %lu of %s.\n\r", Page, m_IHTempFile);
|
|
|
|
START_TIMER(m_TimeTemp);
|
|
m_StatusCode = IMGDisplayFile(pWnd->GetSafeHwnd(),
|
|
(LPSTR)(const char *)m_IHTempFile, (int)Page,
|
|
OI_NOSCROLL | OI_DISP_NO );
|
|
INC_TIMER(m_TimeOiDraw, m_TimeTemp);
|
|
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
TRACE1("DispFitWnd: DisplayFile returned 0x%lx.\n\r", m_StatusCode);
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
return;
|
|
}
|
|
|
|
// Get the size of the page (WxH) in the temp file and adjust the size
|
|
// of the display window such that the image fits it...
|
|
FIO_INFORMATION Fio;
|
|
memset(&Fio, 0, sizeof(FIO_INFORMATION));
|
|
|
|
Fio.filename = (LPSTR)(const char *)m_IHTempFile;
|
|
Fio.page_number = (int)Page;
|
|
|
|
START_TIMER(m_TimeTemp);
|
|
m_StatusCode = IMGFileGetInfo(NULL, pWnd->GetSafeHwnd(), &Fio, NULL, NULL);
|
|
INC_TIMER(m_TimeOiDraw, m_TimeTemp);
|
|
|
|
if ( m_StatusCode != 0 )
|
|
{
|
|
TRACE1("DispFitWnd: FileInfo to get file's WxH returned 0x%lx.\n\r", m_StatusCode);
|
|
m_StatusCode = ErrMap::Xlate(m_StatusCode, m_szThrowString, m_ThrowHelpID, __FILE__, __LINE__);
|
|
FireErrorThumb(m_StatusCode, m_szThrowString, m_ThrowHelpID);
|
|
return;
|
|
}
|
|
|
|
// Ensure that we NEVER make the thumbnail's
|
|
// window LARGER than the thumbnail box...
|
|
// ('- 2' to account for border around thumbnail)
|
|
// MFH - When the x res != the y res, the height of the image
|
|
// must be adjusted according to the x/y ratio.
|
|
// (Must do ratio as (X * Z) / Y NOT (X/Y)*Z to avoid X/Y -> 0)
|
|
UINT XRes = Fio.horizontal_dpi;
|
|
UINT YRes = Fio.vertical_dpi;
|
|
int Width;
|
|
int Height;
|
|
if (XRes > YRes)
|
|
{
|
|
Width = Fio.horizontal_pixels;
|
|
Height = (XRes * Fio.vertical_pixels) / YRes;
|
|
}
|
|
else
|
|
{
|
|
Width = (YRes * Fio.horizontal_pixels) / XRes;
|
|
Height = Fio.vertical_pixels;
|
|
}
|
|
|
|
if ( Width > m_ThumbWidth - 2 )
|
|
Width = m_ThumbWidth - 2 ;
|
|
|
|
if ( Height > m_ThumbHeight - 2 )
|
|
Height = m_ThumbHeight - 2;
|
|
|
|
pWnd->SetWindowPos(NULL, 0,0, Width, Height, SWP_NOZORDER | SWP_NOMOVE);
|
|
}
|
|
// 9603.05 jar added for cursor processing [NT]
|
|
//***************************************************************************
|
|
//
|
|
// OnSetCursor NT KLUDGE
|
|
//
|
|
//***************************************************************************
|
|
BOOL CThumbCtrl::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
::SetCursor( m_LittleOldCursor);
|
|
return TRUE;
|
|
}
|