home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
TOOLKIT
/
PM
/
PORTING
/
IMG_SIZE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
20KB
|
617 lines
/**************************************************************************
* File name : img_size.c
*
* Description: This module contains the code for sizing the main window,
* and scrolling the image inside the window.
* Functions contained here:
*
* SizeMainWindow()
* SizeCalculateMaxWindow(prclBound)
* SizePositionImage(mp2)
* SizeVScroll(mp2, rcl, ptl)
* SizeHScroll(mp2, rcl, ptl)
* ScrollBars(usWidth, usHeight)
* Scroll(lThmbpos, lDeltaSc, sScrollType, prclInvalid)
*
* Concepts : sizable windows
*
* API's : WinSetWindowPos
* WinQueryWindowRect
* GpiSetCurrentPosition
* WinSendMsg
* WinWindowFromID
* WinScrollWindow
* WinInvalidateRect
* GpiQueryCurrentPosition
*
* Required
* Files : OS2.H, STRING.H, STDLIB.H, IMG_MAIN.H, IMG_XTRN.H
*
* Copyright (C) 1991 IBM Corporation
*
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is
* sample code created by IBM Corporation. This sample code is not
* part of any standard or IBM product and is provided to you solely
* for the purpose of assisting you in the development of your
* applications. The code is provided "AS IS", without
* warranty of any kind. IBM shall not be liable for any damages
* arising out of your use of the sample code, even if they have been
* advised of the possibility of such damages. *
*************************************************************************/
/*
* Include files, macros, defined constants, and externs
*/
#define INCL_WINSCROLLBARS
#define INCL_WINFRAMEMGR
#define INCL_WINSTDFILE
#define INCL_GPIPRIMITIVES
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include "img_main.h"
#include "img_xtrn.h"
/*
* Static variables
*/
ULONG ulScrollXPage;
ULONG ulScrollYPage;
ULONG ulScrollYLine = LINESCROLL;
ULONG ulScrollXLine = LINESCROLL;
/*
* Entry point declarations
*/
VOID ScrollBars(USHORT usWidth, USHORT usHeight);
VOID Scroll(LONG lThmbpos, LONG lDeltaSc, SHORT sScrollType,
PRECTL prclInvalid);
/**************************************************************************
*
* Name : SizeMainWindow()
*
* Description: Maximizes the amount of the image that is
* visible . This can only be done after the image
* has been loaded, as the size of the window is
* directly related to the size of the image.
*
* Concepts : Routine is called whenever a WM_COMMAND message
* is posted to the main window as a result of
* selecting the 'Detail' item on the 'View'
* pulldown.
*
* Sets the size and position of the main window
* whenever 'Detail' mode is selected.
*
* API's : WinSetWindowPos
* WinQueryWindowRect
* GpiSetCurrentPosition
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID SizeMainWindow(void)
{
RECTL rcl, rclCWM;
/* limit the window size */
SizeCalculateMaxWindow(&rclCWM);
WinSetWindowPos(vhwndFrame, (HWND)NULL,
(SHORT)rclCWM.xLeft,
(SHORT)rclCWM.yBottom,
(SHORT)(rclCWM.xRight - rclCWM.xLeft),
(SHORT)(rclCWM.yTop - rclCWM.yBottom),
SWP_MOVE | SWP_SIZE);
/*
* The position of the top-left corner of the window rectangle is
* recorded and selected as the current position before the image is
* drawn.
*/
WinQueryWindowRect(vhwndClient, &rcl);
vptlSave.x = rcl.xLeft;
vptlSave.y = rcl.yTop;
GpiSetCurrentPosition(vhps, &vptlSave);
/*
* set the scroll-bar range and slider position and size
*/
ScrollBars((USHORT)(rcl.xRight - rcl.xLeft),
(USHORT)(rcl.yTop - rcl.yBottom));
} /* End of SizeMainWindow */
/**************************************************************************
*
* Name : Scroll()
*
* Description: Scrolls the window contents horizontally or
* vertically.
*
* Concepts : Routine is called from SizeVScroll() and
* SizeHScroll()
* - reposition slider
* - scroll the window contents in the required
* direction by the required amount.
*
* API's : WinSendMsg
* WinWindowFromID
* WinScrollWindow
*
* Parameters : lThmbPos = new thumb position
* lDeltaSc = scrolled amount
* sScrollType = horizontal/vertical scroll ?
* prclInvalid) = invalidated area
*
* Return : [none]
*
*************************************************************************/
VOID Scroll(
LONG lThmbPos, /* new thumb position */
LONG lDeltaSc, /* scrolled amount */
SHORT sScrollType, /* horizontal/vertical scroll ? */
PRECTL prclInvalid) /* invalidated area */
{
unsigned Fid;
/* determine type of scroll operation */
Fid = sScrollType == VERTSCROLL ? FID_VERTSCROLL : FID_HORZSCROLL;
/*
* reposition the slider
*/
WinSendMsg(WinWindowFromID(vhwndFrame, Fid),
SBM_SETPOS,
MPFROMLONG(lThmbPos),
(MPARAM)NULL);
/*
* scroll the window contents
*/
if (sScrollType == VERTSCROLL)
/* vertical scroll */
WinScrollWindow(vhwndClient,
0,
(SHORT)lDeltaSc,
(PRECTL)NULL,
(PRECTL)NULL,
(HRGN)NULL,
(PRECTL)prclInvalid,
0);
else
/* horizontal scroll */
WinScrollWindow(vhwndClient,
(SHORT)lDeltaSc,
0,
(PRECTL)NULL,
(PRECTL)NULL,
(HRGN)NULL,
(PRECTL)prclInvalid,
0);
} /* End of Scroll */
/**************************************************************************
*
* Name : ScrollBars()
*
* Description: Prepares the main window for scrolling (i.e.
* set up the scrollbars appropriately)
*
* Concepts : Routine is called from WndSize() and SizeMain()
* - set scrollbar ranges
* - set slider size relative to the current window
* size
*
* API's : WinSendMsg
* GpiQueryCurrentPosition
*
* Parameters : usWidth = width
* usHeight = height
*
* Return : [none]
*
*************************************************************************/
VOID ScrollBars(USHORT usWidth, USHORT usHeight)
{
POINTL ptlCur;
/*
* calculate the full scrolling range
*/
vulScrollXMax = vsizlImg.cx - usWidth;
vulScrollYMax = vsizlImg.cy - usHeight;
/*
* The page-scrolling action scrolls the image by half of the window
* extent in both axes.
*/
ulScrollXPage = usWidth / 2;
ulScrollYPage = usHeight / 2;
/*
* get current position, which is at the top-left of the image
*/
GpiQueryCurrentPosition(vhps, &ptlCur);
/*
* The scroll-bar slider is positioned according to the position
* of the image in the newly-sized window.
*/
WinSendMsg(vhwndHScroll,
SBM_SETSCROLLBAR,
MPFROMLONG(-ptlCur.x), /* slider position */
MPFROM2SHORT(0, (SHORT)vulScrollXMax)); /* range */
WinSendMsg(vhwndVScroll,
SBM_SETSCROLLBAR,
MPFROMLONG(ptlCur.y - usHeight), /* slider position */
MPFROM2SHORT(0, (SHORT)vulScrollYMax)); /* range */
WinSendMsg(vhwndHScroll,
SBM_SETTHUMBSIZE,
MPFROM2SHORT(usWidth, (SHORT)(vsizlImg.cx)),
(MPARAM)0L);
WinSendMsg(vhwndVScroll,
SBM_SETTHUMBSIZE,
MPFROM2SHORT(usHeight, (SHORT)(vsizlImg.cy)),
(MPARAM)0L);
} /* End of ScrollBars */
/**************************************************************************
*
* Name : SizeCalculateMaxWindow()
*
* Description: Calculates the maximized window size, which
* must not exceed the size of the loaded image.
*
* Concepts : Routine is called from SizeMain(), LoadImage(),
* MainWndProc() and FrameWndProc()
*
* max_window_size = min(screen_size, image_size)
*
* API's : [none]
*
* Parameters : prclBound = points to the bounding rectangle
*
* Return : TRUE - if image loaded and in 'Detail' mode
* FALSE - if either the image isn't loaded or
* the application is not in 'Detail' mode
*
*************************************************************************/
BOOL SizeCalculateMaxWindow(prclBound)
PRECTL prclBound;
{
/*
* Calculate the maximized window size. If an image has been loaded
* in 'Detail' mode, the maximized window is the smaller of the
* screen and the image.
*/
if (vfImgLoaded && vfDetail)
{
if (vsizlImg.cx > (vlYScreen - vlcxVScroll))
{
prclBound->xLeft = -vlcxBorder;
prclBound->xRight = prclBound->xLeft + vlYScreen +
(2*vlcxBorder);
}
else
{
prclBound->xLeft = 0;
prclBound->xRight = prclBound->xLeft +
vsizlImg.cx + vlcxVScroll +
(2*vlcxBorder);
}
if (vsizlImg.cy >
(vlYScreen - vlcyHScroll - vlcyMenu - vlcyTitle))
{
prclBound->yBottom = -vlcyBorder;
prclBound->yTop = prclBound->yBottom + vlYScreen +
(2*vlcyBorder);
}
else
{
prclBound->yTop = vlYScreen;
prclBound->yBottom = prclBound->yTop -
(vsizlImg.cy + vlcyTitle + vlcyMenu +
vlcyHScroll + (2*vlcyBorder));
}
return TRUE;
}
else
/* error if not in 'Detail' mode */
return FALSE;
} /* End of SizeCalculateMaxWindow */
/**************************************************************************
*
* Name : SizeVScroll(mp2, rcl, ptl)
*
* Description: Implements vertical scrolling in 'Detail' mode
*
* Concepts : Routine is called MainWndProc() and it invokes
* Scroll().
*
* -adjust current position
* -redraw image at new position
*
* API's : GpiSetCurrentPosition
* WinInvalidateRect
*
* Parameters : mp2 = second message parameter
* rcl = rectangle
* ptl = new position
*
* Return : [none]
*
*************************************************************************/
VOID SizeVScroll(MPARAM mp2, RECTL rcl, POINTL ptl)
{
LONG lDeltaScr;
/* act on the type of vertical scroll message */
switch (SHORT2FROMMP(mp2))
{
case SB_LINEDOWN:
/*
* line-down processing
*/
if ((ULONG)(ptl.y - rcl.yTop) < vulScrollYMax)
{
lDeltaScr = ptl.y;
ptl.y +=
((ULONG)(ptl.y - rcl.yTop) + ulScrollYLine < vulScrollYMax) ?
ulScrollYLine : vulScrollYMax - (ptl.y - rcl.yTop);
lDeltaScr = ptl.y - lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll((ptl.y-rcl.yTop), lDeltaScr, VERTSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_LINEUP:
/*
* line-up processing
*/
if (ptl.y > rcl.yTop)
{
lDeltaScr = ptl.y;
ptl.y -= (ptl.y > rcl.yTop + ulScrollYLine) ?
ulScrollYLine : ptl.y - rcl.yTop;
lDeltaScr = ptl.y - lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll((ptl.y-rcl.yTop), lDeltaScr, VERTSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_PAGEDOWN:
/*
* page-down processing
*/
if ((ULONG)(ptl.y - rcl.yTop) < vulScrollYMax)
{
lDeltaScr =
((ULONG)(ptl.y - rcl.yTop) + ulScrollYPage < vulScrollYMax) ?
ulScrollYPage : vulScrollYMax -
(SHORT)(ptl.y - rcl.yTop);
ptl.y += lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll((ptl.y-rcl.yTop), lDeltaScr, VERTSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_PAGEUP:
/*
* page-up processing
*/
if (ptl.y > rcl.yTop)
{
lDeltaScr = (ptl.y > rcl.yTop + ulScrollYPage) ?
ulScrollYPage : (SHORT)(ptl.y - rcl.yTop);
ptl.y -= lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll((ptl.y-rcl.yTop), -lDeltaScr, VERTSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_SLIDERPOSITION:
/*
* adjust the slider position
*/
lDeltaScr = ptl.y;
ptl.y = rcl.yTop + SHORT1FROMMP(mp2);
lDeltaScr = ptl.y - lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll((LONG)(SHORT1FROMMP(mp2)), lDeltaScr, VERTSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
break;
}
} /* End of SizeVScroll() */
/**************************************************************************
*
* Name : SizeHScroll(mp2, rcl, ptl)
*
* Description: Implements horizontal scrolling in 'Detail' mode
*
* Concepts : Routine is called MainWndProc() and it invokes
* Scroll().
*
* -adjust current position
* -redraw image at new position
*
* API's : GpiSetCurrentPosition
* WinInvalidateRect
*
* Parameters : mp2 = second message parameter
* rcl = rectangle
* ptl = new position
*
* Return : [none]
*
*************************************************************************/
VOID SizeHScroll(MPARAM mp2, RECTL rcl, POINTL ptl)
{
LONG lDeltaScr;
/* act on the type of horizontal scroll message */
switch(SHORT2FROMMP(mp2))
{
case SB_LINERIGHT:
/*
* line-right processing
*/
if ((vsizlImg.cx + ptl.x) > rcl.xRight)
{
lDeltaScr = ptl.x;
ptl.x -=
((vsizlImg.cx + ptl.x) > rcl.xRight+ulScrollXLine) ?
ulScrollXLine : ptl.x + vsizlImg.cx - rcl.xRight;
lDeltaScr = ptl.x - lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll(-ptl.x, lDeltaScr, HORZSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_LINELEFT:
/*
* line-left processing
*/
if (ptl.x < rcl.xLeft)
{
lDeltaScr = ptl.x;
ptl.x += ((ULONG)(rcl.xLeft - ptl.x) > ulScrollXLine) ?
ulScrollXLine : rcl.xLeft - ptl.x;
lDeltaScr = ptl.x - lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll(-ptl.x, lDeltaScr, HORZSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_PAGERIGHT:
/*
* page-right processing
*/
if ((vsizlImg.cx + ptl.x) > rcl.xRight)
{
lDeltaScr =
((vsizlImg.cx+(LONG)ptl.x) > rcl.xRight+ulScrollXPage) ?
ulScrollXPage : (vsizlImg.cx + ptl.x - rcl.xRight);
ptl.x -= (LONG)lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll(-ptl.x, -lDeltaScr, HORZSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_PAGELEFT:
/*
* page-left processing
*/
if (ptl.x < rcl.xLeft)
{
lDeltaScr = ((ULONG)(rcl.xLeft - ptl.x) > ulScrollXPage) ?
ulScrollXPage : (SHORT)(rcl.xLeft - ptl.x);
ptl.x += lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll(-ptl.x, lDeltaScr, HORZSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
}
break;
case SB_SLIDERPOSITION:
/*
* adjust the slider position
*/
lDeltaScr = ptl.x;
ptl.x = (LONG)rcl.xLeft - (LONG)SHORT1FROMMP(mp2);
lDeltaScr = ptl.x - lDeltaScr;
GpiSetCurrentPosition(vhps, &ptl);
Scroll((LONG)(SHORT1FROMMP(mp2)), lDeltaScr, HORZSCROLL, &rcl);
WinInvalidateRect(vhwndClient, &rcl, FALSE);
break;
default:
break;
}
} /* End of SizeHScroll */
/**************************************************************************
*
* Name : SizePositionImage(mp2)
*
* Description: Positions the image correctly within a sized window.
* Concepts : Routine is called MainWndProc() and it invokes
* ScrollBars().
*
* - adjust current position of image
* - adjust range & position of scrollbars
*
* API's : GpiSetCurrentPosition
* WinQueryWindowRect
* GpiQueryCurrentPosition
*
* Parameters : mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID SizePositionImage(MPARAM mp2)
{
RECTL rcl; /* new window rectangle */
POINTL ptl; /* new current position */
WinQueryWindowRect(vhwndClient, &rcl);
GpiQueryCurrentPosition(vhps, &ptl);
/*
* The WM_QUERYTRACKINFO processing ensures that window size never
* exceeds image size. Here, however, image position in relation to
* window limits is checked.
*
* Set current position such that the image top and right edges are
* at least at the window limits.
*/
ptl.y = (ptl.y < rcl.yTop) ? rcl.yTop : ptl.y;
ptl.x = ((ptl.x + vsizlImg.cx) < rcl.xRight) ?
(rcl.xRight - rcl.xLeft) - vsizlImg.cx : ptl.x;
GpiSetCurrentPosition(vhps, &ptl);
/*
* adjust scroll-bar positioning and range to new window size
*/
ScrollBars(SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
} /* End of SizePositionImage() */
/*************************** End of img_size.c *************************/