home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * 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 *************************/
-