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.
375 lines
13 KiB
375 lines
13 KiB
// thumbct3.cpp : Implementation of the CThumbCtrl OLE control class's
|
|
// Event handlers.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT NOTE: Alex McLeod
|
|
//
|
|
// 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 "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
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// EVENT handlers and EVENT helper functions... (events)
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Left mouse button down...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
m_LastButtonDown = LASTDOWN_LEFT;
|
|
FireMyMouseDown(LEFT_BUTTON, ShiftState(), point.x, point.y, PointOnThumb(point));
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Middle mouse button down...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnMButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
m_LastButtonDown = LASTDOWN_MIDDLE;
|
|
FireMyMouseDown(MIDDLE_BUTTON, ShiftState(), point.x, point.y, PointOnThumb(point));
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Right mouse button down...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
m_LastButtonDown = LASTDOWN_RIGHT;
|
|
FireMyMouseDown(RIGHT_BUTTON, ShiftState(), point.x, point.y, PointOnThumb(point));
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Left mouse button up...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
long ThumbNumber = PointOnThumb(point);
|
|
FireMyMouseUp(LEFT_BUTTON, ShiftState(), point.x, point.y, ThumbNumber);
|
|
|
|
if ( m_LastButtonDown == LASTDOWN_LEFT )
|
|
{
|
|
// ACM 3/20/95
|
|
// A double click results in the following message stream:
|
|
//
|
|
// DOWN - UP - DOUBLECLICK - UP
|
|
//
|
|
// And all that seems to be required to get a click is that:
|
|
// 1) The up is NOT the result of a double click
|
|
// 2) The up is from the same button that generated the DOWN
|
|
// 3) The up must occur in the window
|
|
//
|
|
// But time and distance from the DOWN do not matter...
|
|
// (I tried all of this in a test control's implementation of the
|
|
// standard CLICK handlers and this seems to be how it works...)
|
|
//
|
|
CRect ClientRect;
|
|
GetClientRect(&ClientRect);
|
|
if (ClientRect.PtInRect(point))
|
|
FireMyClick(PointOnThumb(point));
|
|
}
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Left mouse button up...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnMButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
FireMyMouseUp(MIDDLE_BUTTON, ShiftState(), point.x, point.y, PointOnThumb(point));
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Left mouse button up...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnRButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
FireMyMouseUp(RIGHT_BUTTON, ShiftState(), point.x, point.y, PointOnThumb(point));
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Left mouse button double click...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
m_LastButtonDown = LASTDOWN_NONE;
|
|
FireMyDblClick(PointOnThumb(point));
|
|
|
|
// If drawing was interrupted, force it to resume...
|
|
ResumeDraw();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler: Mouse move...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
// Reset to no error status...
|
|
ResetStatus();
|
|
|
|
long ThumbNumber = PointOnThumb(point);
|
|
|
|
// Mask off any keystate information...
|
|
nFlags = nFlags & ( MK_LBUTTON | MK_MBUTTON | MK_RBUTTON);
|
|
|
|
// Fire with nFlags to indicate what buttons are CURRENTLY down...
|
|
FireMyMouseMove(nFlags, ShiftState(), point.x, point.y, ThumbNumber);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler helper function: ResumeDraw...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::ResumeDraw()
|
|
{
|
|
if ( m_NeedDrawFrom != 0 )
|
|
{
|
|
CRect ThumbRect;
|
|
|
|
for ( long i = m_NeedDrawFrom; i <= m_LastDisplayedThumb; i++ )
|
|
{
|
|
if ( GetThumbDisplayRect(i, ThumbRect) )
|
|
{
|
|
ThumbRect.InflateRect(THUMBSELOFFSET_X + THUMBSELWIDTH,
|
|
THUMBSELOFFSET_Y + THUMBSELWIDTH);
|
|
InvalidateControl(ThumbRect);
|
|
}
|
|
}
|
|
m_NeedDrawFrom = 0;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler helper function: ShiftState...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
short CThumbCtrl::ShiftState()
|
|
{
|
|
// Helper function copied from MSVC OLE16 source's CTLEVENT.CPP
|
|
BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
|
|
BOOL bCtrl = (GetKeyState(VK_CONTROL) < 0);
|
|
BOOL bAlt = (GetKeyState(VK_MENU) < 0);
|
|
|
|
return (short)(bShift + (bCtrl << 1) + (bAlt << 2));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event handler helper function: PointOnThumb...
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
long CThumbCtrl::PointOnThumb(CPoint Pnt)
|
|
{
|
|
// Determine if the click was on a thumb...
|
|
int Ix = 0;
|
|
long ThumbNum = m_FirstDisplayedThumb;
|
|
|
|
if ( m_ScrollDirection == CTL_THUMB_HORIZONTAL )
|
|
{ // Horizontal scrolling...
|
|
|
|
// m_ThumbStart holds the lefts of the visible columns
|
|
// of thumbnail boxes. See if we are in a column...
|
|
long Top;
|
|
long Bottom;
|
|
|
|
while ( (m_ThumbStart[Ix] != 0) && (ThumbNum <= m_ThumbCount) )
|
|
{
|
|
if ( (Pnt.x >= m_ThumbStart[Ix]) &&
|
|
(Pnt.x <= (m_ThumbStart[Ix]+ m_ThumbWidth)) )
|
|
{
|
|
// Found the column that we are in, see if we are in a thumb...
|
|
for ( int row = 0; row < m_ThumbsY; row++ )
|
|
{
|
|
// Top (Note: Formula copied from OnDraw's
|
|
// Vertical DrawThumbnail image calculation!)
|
|
Top = (long)(m_Spacing +
|
|
((float)row*((float)m_AdjThumbHeight +
|
|
(float)m_LabelSpacing +
|
|
m_Spacing)));
|
|
Top += THUMBSELOFFSET_Y + THUMBSELWIDTH;
|
|
|
|
Bottom = Top + m_ThumbHeight;
|
|
|
|
if ( (Pnt.y >= (int)Top) && (Pnt.y <= (int)Bottom) )
|
|
return ThumbNum;
|
|
|
|
// Off to the next thumb, but don't go too far...
|
|
if ( ++ThumbNum > m_ThumbCount )
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Skipped an entire row...
|
|
ThumbNum += m_ThumbsY;
|
|
}
|
|
|
|
// Off to the next row...
|
|
Ix++;
|
|
}
|
|
}
|
|
else
|
|
{ // Vertical scrolling...
|
|
|
|
// m_ThumbStart holds the tops of the visible rows
|
|
// of thumbnail boxes. See if we are in a row...
|
|
long Left;
|
|
long Right;
|
|
|
|
while ( (m_ThumbStart[Ix] != 0) && (ThumbNum <= m_ThumbCount) )
|
|
{
|
|
if ( (Pnt.y >= m_ThumbStart[Ix]) &&
|
|
(Pnt.y <= (m_ThumbStart[Ix]+ m_ThumbHeight)) )
|
|
{
|
|
// Found the row that we are in, see if we are in a thumb...
|
|
for ( int col = 0; col < m_ThumbsX; col++ )
|
|
{
|
|
// Left (Note: Formula copied from OnDraw's
|
|
// Horizontal DrawThumbnail image calculation!)
|
|
Left = (long)(m_Spacing +
|
|
((float)col * ((float)m_AdjThumbWidth + m_Spacing)));
|
|
|
|
Left += THUMBSELOFFSET_X + THUMBSELWIDTH;
|
|
|
|
Right = Left + (int)m_ThumbWidth;
|
|
|
|
if ( (Pnt.x >= (int)Left) && (Pnt.x <= (int)Right) )
|
|
return ThumbNum;
|
|
|
|
// Off to the next thumb, but don't go too far...
|
|
if ( ++ThumbNum > m_ThumbCount )
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Skipped an entire row...
|
|
ThumbNum += m_ThumbsX;
|
|
}
|
|
|
|
// Off to the next row...
|
|
Ix++;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Custom FIREERROR event handler for the ImgThumb control
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::FireErrorThumb(SCODE scode, LPCTSTR lpszDescription, UINT nHelpID)
|
|
{
|
|
ExternalAddRef(); // "Insurance" addref -- keeps control alive.
|
|
|
|
BSTR bstrDescription = ::SysAllocString((BSTR)lpszDescription);
|
|
LPCTSTR lpszSource = AfxGetAppName();
|
|
LPCTSTR lpszHelpFile = _T("");
|
|
|
|
if (nHelpID != 0)
|
|
lpszHelpFile = AfxGetApp()->m_pszHelpFilePath;
|
|
|
|
if (lpszHelpFile == NULL)
|
|
lpszHelpFile = _T("");
|
|
|
|
|
|
// 9602.23 jar fire drill du jour
|
|
//BOOL bCancelDisplay = FALSE;
|
|
int bCancelDisplay = (int)FALSE;
|
|
|
|
FireError((WORD)SCODE_CODE(scode), &bstrDescription, scode,
|
|
lpszSource, lpszHelpFile, (DWORD)nHelpID, &bCancelDisplay);
|
|
|
|
if (! (BOOL)bCancelDisplay)
|
|
{
|
|
DisplayError(scode, (LPCTSTR)bstrDescription, lpszSource, lpszHelpFile, nHelpID);
|
|
}
|
|
|
|
::SysFreeString(bstrDescription);
|
|
|
|
ExternalRelease();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event Helper: DisplayError
|
|
//
|
|
// This function is used by the COleControl class to provide
|
|
// default display behavior when an error is fired. The default
|
|
// implementation puts up a message box. We don't want that
|
|
// so I'm overriding to avoid it.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CThumbCtrl::DisplayError( SCODE scode, LPCTSTR lpszDescription, LPCTSTR lpszSource, LPCTSTR lpszHelpFile, UINT nHelpID )
|
|
{
|
|
AfxLockTempMaps();
|
|
CWnd *pParentWnd = GetParent();
|
|
if (pParentWnd == NULL)
|
|
pParentWnd = this;
|
|
pParentWnd->MessageBox(lpszDescription, lpszSource);
|
|
AfxUnlockTempMaps();
|
|
}
|