www.pudn.com > helpview.zip > Hotspots.c, change:1997-10-15,size:11453b


/* 
  
Copyright 1997 Willows Software, Inc.  
 
This library is free software; you can redistribute it and/or 
modify it under the terms of the GNU Library General Public License as 
published by the Free Software Foundation; either version 2 of the 
License, or (at your option) any later version. 
 
This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
Library General Public License for more details. 
 
You should have received a copy of the GNU Library General Public 
License along with this library; see the file COPYING.LIB.  If 
not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
Cambridge, MA 02139, USA. 
 
*/ 
 
/************************************************************************* 
* 
* HOTSPOT.C 
* Hotspot information storage routines.      
* 
* Author: Paul E. Kissel 
* 
**************************************************************************/ 
 
/*********************************** 
** 
**  System Includes 
** 
***********************************/ 
 
/*********************************** 
** 
**  App. Includes 
** 
***********************************/ 
 
#include "hotspots.h" 
#include "winmem.h" 
 
 
/*********************************** 
** 
**  Private File Defines 
** 
***********************************/ 
 
/* Initial number of hotspots held in the buffer. */ 
#define NUM_HOTSPOTS  20 
 
/* Information stored for each hotspot. */ 
typedef struct tagHOTSPOTDATA 
{ 
  HOTSPOTREC Info;      /* Info. about the hotspot. */ 
  POSRECT PosRect;      /* Position of hotspot on the page. */ 
}  
HOTSPOTDATA; 
typedef HOTSPOTDATA * FPHOTSPOTDATA; 
 
/* Buffer of hotspot data. */ 
typedef struct tagHOTSPOTBUFFER 
{ 
  WORD    wNumRecords;      /* Number of used records in the list. */ 
  WORD    wMaxRecords;      /* Number of total (used and unused) records in the list. */ 
  HGLOBAL hRecordList;      /* List of records. */ 
}  
HOTSPOTBUFFER; 
typedef HOTSPOTBUFFER * FPHOTSPOTBUFFER; 
 
 
/*********************************** 
** 
**  Private functions 
** 
***********************************/ 
 
static BOOL PtInPosRect( FPPOSRECT fpPosRect, POSPOINT PosPoint ); 
 
 
/*********************************************************************************** 
** 
**                              Shared Functions 
** 
************************************************************************************/ 
 
 
/********************************************************* 
** 
**  Allocates the hotspot buffer's structure. 
** 
**  Initially, only the first slot is allocated. 
**  It will be used to hold a count of the number of hotspots 
**  in the buffer in the dwHotSpotContext variable.  
** 
**********************************************************/ 
HHOTSPOTBUFFER AllocHotSpotBuffer( HWND hWnd ) 
{ 
  HHOTSPOTBUFFER hHotSpotBuffer; 
  FPHOTSPOTBUFFER  fpHotSpotBuffer; 
   
  /* Allocate the hotspot buffer. */ 
  if( ! GlobalAllocMem( hWnd, &hHotSpotBuffer, sizeof(HOTSPOTBUFFER) ) ) 
  { 
    /* Failure. */ 
    return( NULL ); 
  } 
   
  /* Get pointer to the buffer. */ 
  fpHotSpotBuffer = ( FPHOTSPOTBUFFER ) GlobalLock( hHotSpotBuffer ); 
   
  /* Allocate space for initial number of records. */ 
  if( ! GlobalAllocMem( hWnd, &(fpHotSpotBuffer)->hRecordList, sizeof(HOTSPOTDATA) * NUM_HOTSPOTS ) ) 
  { 
    /* Unlock the buffer structure. */ 
    GlobalUnlock( hHotSpotBuffer ); 
 
    /* Free the buffer structure. */ 
    MyGlobalFree( hHotSpotBuffer ); 
 
    /* Failure. */ 
    return( NULL ); 
  } 
 
  /* Set max. number of hotspots used and avail. in the buffer. */ 
  fpHotSpotBuffer->wNumRecords = 0; 
  fpHotSpotBuffer->wMaxRecords = NUM_HOTSPOTS; 
   
  /* Unlock the buffer structure. */ 
  GlobalUnlock( hHotSpotBuffer ); 
 
  /* Success. */ 
  return( hHotSpotBuffer ); 
} 
 
 
 
/********************************************************* 
** 
**  Destroys the hotspots in the buffer and frees the 
**  memory associated with each hotspot record. 
** 
**********************************************************/ 
void  FreeHotSpotBuffer( HHOTSPOTBUFFER hHotSpotBuffer ) 
{ 
  FPHOTSPOTBUFFER  fpHotSpotBuffer; 
 
  /* No hotspot buffer.  */ 
  if( hHotSpotBuffer == NULL ) return; 
   
  /* Get pointer to the buffer. */ 
  fpHotSpotBuffer = ( FPHOTSPOTBUFFER ) GlobalLock( hHotSpotBuffer ); 
   
  /* Free hotspot data. */ 
  MyGlobalFree( fpHotSpotBuffer->hRecordList ); 
 
  /* Free the buffer structure. */ 
  GlobalUnlock( hHotSpotBuffer ); 
  MyGlobalFree( hHotSpotBuffer ); 
} 
 
 
 
/********************************************************* 
** 
**  Adds a new hotspot to the buffer. 
** 
**  If no space is available, the buffer size is 
**  increased. 
** 
**********************************************************/ 
BOOL AddHotSpot 
(  
  HWND hWnd,  
  HHOTSPOTBUFFER hHotSpotBuffer, 
  FPHOTSPOTREC fpHotSpotRec, 
  FPPOSRECT fpPosRect  
) 
{ 
  FPHOTSPOTBUFFER fpHotSpotBuffer; 
  FPHOTSPOTDATA   fpHotSpotData; 
       
 
  /* No hotspot buffer.  */ 
  if( hHotSpotBuffer == NULL ) return FALSE; 
   
  /* Get pointer to the buffer. */ 
  fpHotSpotBuffer = ( FPHOTSPOTBUFFER ) GlobalLock( hHotSpotBuffer ); 
   
  /*  
  ** If we have reached the buffer limit and must 
  ** allocate a bigger buffer before adding new 
  ** hotspot. 
  */ 
  if( fpHotSpotBuffer->wNumRecords == fpHotSpotBuffer->wMaxRecords ) 
  { 
    /*  
    ** wNumHotSpots is number of hotspots in the buffer. 
    ** We add one to size for the dummy 1st record that keeps our array count. 
    */ 
    if( ! GlobalReAllocMem( hWnd, &(fpHotSpotBuffer)->hRecordList,  
                            sizeof(HOTSPOTDATA) * (NUM_HOTSPOTS + fpHotSpotBuffer->wMaxRecords ) ) ) 
    { 
      return FALSE; 
    } 
 
    /*  
    ** Increment the count of how many hotspots are 
    ** in the hotspot buffer. 
    */ 
    fpHotSpotBuffer->wMaxRecords = fpHotSpotBuffer->wMaxRecords + NUM_HOTSPOTS; 
  } 
 
  /* Get pointer to the first hotspot info record. */ 
  fpHotSpotData = GlobalLock( fpHotSpotBuffer->hRecordList ); 
 
  /* Skip to the new record.*/ 
  fpHotSpotData = fpHotSpotData + fpHotSpotBuffer->wNumRecords; 
 
  /* Copy the data. */ 
  fpHotSpotData->Info     = *fpHotSpotRec; 
 
  fpHotSpotData->PosRect.left   = fpPosRect->left; 
  fpHotSpotData->PosRect.right  = fpPosRect->right; 
  fpHotSpotData->PosRect.top    = fpPosRect->top; 
  fpHotSpotData->PosRect.bottom = fpPosRect->bottom; 
 
  /*  
  ** Increment the number of hotspots in the buffer. 
  ** The data is stored in the first record.  
  */ 
  fpHotSpotBuffer->wNumRecords = fpHotSpotBuffer->wNumRecords + 1; 
 
  /* Unlock the records. */ 
  GlobalUnlock( fpHotSpotBuffer->hRecordList ); 
 
  /* Unlock the buffer structure. */ 
  GlobalUnlock( hHotSpotBuffer ); 
 
  /* Success. */ 
  return( TRUE ); 
} 
 
 
/********************************************************* 
** 
**  Is the given point (where cursor is) in a hotspot. 
** 
**  The point should be a relative to the entire topic page 
**  and not the display window. 
** 
**********************************************************/ 
BOOL  IsPointInHotSpot 
(  
  HHOTSPOTBUFFER hHotSpotBuffer,  
  POSPOINT PosPoint 
) 
{ 
  FPHOTSPOTBUFFER fpHotSpotBuffer; 
  FPHOTSPOTDATA   fpHotSpotData; 
  WORD            wIndex; 
 
   
  /* No hotspot buffer.  */ 
  if( hHotSpotBuffer == NULL ) return FALSE; 
   
  /* Get pointer to the buffer. */ 
  fpHotSpotBuffer = ( FPHOTSPOTBUFFER ) GlobalLock( hHotSpotBuffer ); 
   
  /* If there are hotspots in the buffer. */ 
  if( fpHotSpotBuffer->wNumRecords != 0 ) 
  { 
    /* Get pointer to the first hotspot info record. */ 
    fpHotSpotData = ( FPHOTSPOTDATA ) GlobalLock( fpHotSpotBuffer->hRecordList ); 
   
    /* For each hotspot in the buffer. */ 
    for( wIndex = 0; wIndex < fpHotSpotBuffer->wNumRecords; wIndex++ ) 
    { 
      /* Is point in hotspot */ 
      if( PtInPosRect( &(fpHotSpotData)->PosRect, PosPoint ) ) 
      { 
        /* Unlock hotspot info record. */ 
        GlobalUnlock( fpHotSpotBuffer->hRecordList ); 
       
        return( TRUE ); 
      } 
             
      /* Goto next record. */ 
      fpHotSpotData++; 
    } 
 
    /* Unlock hotspot info record. */ 
    GlobalUnlock( fpHotSpotBuffer->hRecordList ); 
  } 
   
  /* Unlock the hotspot buffer. */ 
  GlobalUnlock( hHotSpotBuffer ); 
 
  /* Point not in hotspot. */ 
  return( FALSE ); 
} 
 
 
/********************************************************* 
** 
**  Retrive a hotspot's information if the point is 
**  in a hotspot. 
** 
**  The point should be a relative to the entire topic page 
**  and not the display window. 
** 
**********************************************************/ 
BOOL  GetHotSpot 
(  
  HHOTSPOTBUFFER hHotSpotBuffer,   
  POSPOINT PosPoint,  
  FPHOTSPOTREC fpHotSpotRec, 
  FPPOSRECT HotSpotPosRect  
) 
{ 
  FPHOTSPOTBUFFER fpHotSpotBuffer; 
  FPHOTSPOTDATA   fpHotSpotData; 
  WORD            wIndex; 
   
 
  /* No hotspot buffer.  */ 
  if( hHotSpotBuffer == NULL ) return FALSE; 
   
  /* Get pointer to the buffer. */ 
  fpHotSpotBuffer = ( FPHOTSPOTBUFFER ) GlobalLock( hHotSpotBuffer ); 
   
  /* If there are hotspots in the buffer. */ 
  if( fpHotSpotBuffer->wNumRecords != 0 ) 
  { 
    /* Get pointer to the first hotspot info record. */ 
    fpHotSpotData = ( FPHOTSPOTDATA ) GlobalLock( fpHotSpotBuffer->hRecordList ); 
     
    /* For each hotspot in the buffer. */ 
    for( wIndex = 0; wIndex < fpHotSpotBuffer->wNumRecords; wIndex++ ) 
    { 
      /* Is point in hotspot */ 
      if( PtInPosRect( &(fpHotSpotData)->PosRect, PosPoint ) ) 
      { 
        /* Get the hotspots info. */ 
        *fpHotSpotRec    = fpHotSpotData->Info; 
        *HotSpotPosRect  = fpHotSpotData->PosRect; 
         
        /* Unlock hotspot info record. */ 
        GlobalUnlock( fpHotSpotBuffer->hRecordList ); 
       
        return( TRUE ); 
      } 
             
      /* Goto next record. */ 
      fpHotSpotData++; 
    } 
 
    /* Unlock hotspot info record. */ 
    GlobalUnlock( fpHotSpotBuffer->hRecordList ); 
  } 
   
  /* Unlock the hotspot buffer. */ 
  GlobalUnlock( hHotSpotBuffer ); 
 
  /* Point not in hotspot. */ 
  return( FALSE ); 
} 
 
 
 
/********************************************************* 
** 
**  Set all record to invalid. 
** 
**********************************************************/ 
void  ClearPagesHotSpots( HHOTSPOTBUFFER hHotSpotBuffer ) 
{ 
  FPHOTSPOTBUFFER fpHotSpotBuffer; 
 
  /* No hotspot buffer.  */ 
  if( hHotSpotBuffer == NULL ) return; 
   
  /* Get pointer to the buffer. */ 
  fpHotSpotBuffer = ( FPHOTSPOTBUFFER ) GlobalLock( hHotSpotBuffer ); 
   
  /* Set the number of VALID hotspots in the buffer to 0. */ 
  fpHotSpotBuffer->wNumRecords = 0; 
 
  /* Unlock the hotspot buffer. */ 
  GlobalUnlock( hHotSpotBuffer ); 
} 
 
 
/********************************************************* 
** 
**  Is a point in a hotspot rect.  POSTREC uses longs. 
** 
**********************************************************/ 
static BOOL PtInPosRect( FPPOSRECT fpPosRect, POSPOINT PosPoint ) 
{ 
  /* Not in rect? */ 
  if(  
      PosPoint.x < fpPosRect->left ||  
      PosPoint.x > fpPosRect->right||  
      PosPoint.y < fpPosRect->top ||  
      PosPoint.y > fpPosRect->bottom   
    ) 
  { 
    /* Not in rect. */ 
    return( FALSE ); 
  } 
 
  /* In rect. */ 
  return( TRUE ); 
}