/****************************************************************************

    PROGRAM: Select.c

    PURPOSE: Contains library routines for selecting a region

    FUNCTIONS:

    StartSelection(HWND, POINT, LPRECT, int) - begin selection area
    UpdateSelection(HWND, POINT, LPRECT, int) - update selection area
    EndSelection(POINT, LPRECT) - end selection area
    ClearSelection(HWND, LPRECT, int) - clear selection area

*******************************************************************************/

#include "windows.h"
#include "select.h"

/****************************************************************************
   FUNCTION: LibMain(HANDLE, WORD, WORD, LPSTR)

   PURPOSE:  Is called by LibEntry.  LibEntry is called by Windows when
             the DLL is loaded.  The LibEntry routine is provided in
             the LIBENTRY.OBJ in the SDK Link Libraries disk.  (The
             source LIBENTRY.ASM is also provided.)  

             LibEntry initializes the DLL's heap, if a HEAPSIZE value is
             specified in the DLL's DEF file.  Then LibEntry calls
             LibMain.  The LibMain function below satisfies that call.
             
             The LibMain function should perform additional initialization
             tasks required by the DLL.  In this example, no initialization
             tasks are required.  LibMain should return a value of 1 if
             the initialization is successful.
           
*******************************************************************************/
int FAR PASCAL LibMain(hModule, wDataSeg, cbHeapSize, lpszCmdLine)
HANDLE  hModule;
WORD    wDataSeg;
WORD    cbHeapSize;
LPSTR   lpszCmdLine;
{
    return 1;
}


/****************************************************************************
    FUNCTION:  WEP(int)

    PURPOSE:  Performs cleanup tasks when the DLL is unloaded.  WEP() is
              called automatically by Windows when the DLL is unloaded (no
              remaining tasks still have the DLL loaded).  It is strongly
              recommended that a DLL have a WEP() function, even if it does
              nothing but returns success (1), as in this example.

*******************************************************************************/
int FAR PASCAL __export _WEP (bSystemExit)
int  bSystemExit;
{
    return(1);
}


/****************************************************************************

    FUNCTION: StartSelection(HWND, POINT, LPRECT, int)

    PURPOSE: Begin selection of region

****************************************************************************/

void FAR PASCAL __export StartSelection(hWnd, ptCurrent, lpSelectRect, fFlags)
HWND hWnd;
POINT ptCurrent;
LPRECT lpSelectRect;
int fFlags;
{
    if (lpSelectRect->left != lpSelectRect->right ||
        lpSelectRect->top != lpSelectRect->bottom)
    ClearSelection(hWnd, lpSelectRect, fFlags);

    lpSelectRect->right = ptCurrent.x;
    lpSelectRect->bottom = ptCurrent.y;

    /* If you are extending the box, then invert the current rectangle */

    if ((fFlags & SL_SPECIAL) == SL_EXTEND)
    ClearSelection(hWnd, lpSelectRect, fFlags);

    /* Otherwise, set origin to current location */

    else {
    lpSelectRect->left = ptCurrent.x;
    lpSelectRect->top = ptCurrent.y;
    }
    SetCapture(hWnd);
}

/****************************************************************************

    FUNCTION: UpdateSelection(HWND, POINT, LPRECT, int) - update selection area

    PURPOSE: Update selection

****************************************************************************/

void FAR PASCAL __export UpdateSelection(hWnd, ptCurrent, lpSelectRect, fFlags)
HWND hWnd;
POINT ptCurrent;
LPRECT lpSelectRect;
int fFlags;
{
    HDC hDC;
    short OldROP;

    hDC = GetDC(hWnd);

    switch (fFlags & SL_TYPE) {

    case SL_BOX:
        OldROP = SetROP2(hDC, R2_NOTXORPEN);
        MoveTo(hDC, lpSelectRect->left, lpSelectRect->top);
        LineTo(hDC, lpSelectRect->right, lpSelectRect->top);
        LineTo(hDC, lpSelectRect->right, lpSelectRect->bottom);
        LineTo(hDC, lpSelectRect->left, lpSelectRect->bottom);
        LineTo(hDC, lpSelectRect->left, lpSelectRect->top);
        LineTo(hDC, ptCurrent.x, lpSelectRect->top);
        LineTo(hDC, ptCurrent.x, ptCurrent.y);
        LineTo(hDC, lpSelectRect->left, ptCurrent.y);
        LineTo(hDC, lpSelectRect->left, lpSelectRect->top);
        SetROP2(hDC, OldROP);
        break;
    
    case SL_BLOCK:
        PatBlt(hDC,
        lpSelectRect->left,
        lpSelectRect->bottom,
        lpSelectRect->right - lpSelectRect->left,
        ptCurrent.y - lpSelectRect->bottom,
        DSTINVERT);
        PatBlt(hDC,
        lpSelectRect->right,
        lpSelectRect->top,
        ptCurrent.x - lpSelectRect->right,
        ptCurrent.y - lpSelectRect->top,
        DSTINVERT);
        break;
    }
    lpSelectRect->right = ptCurrent.x;
    lpSelectRect->bottom = ptCurrent.y;
    ReleaseDC(hWnd, hDC);
}

/****************************************************************************

    FUNCTION: EndSelection(POINT, LPRECT)

    PURPOSE: End selection of region, release capture of mouse movement

****************************************************************************/

void FAR PASCAL __export EndSelection(ptCurrent, lpSelectRect)
POINT ptCurrent;
LPRECT lpSelectRect;
{
    lpSelectRect->right = ptCurrent.x;
    lpSelectRect->bottom = ptCurrent.y;
    ReleaseCapture();
}

/****************************************************************************

    FUNCTION: ClearSelection(HWND, LPRECT, int) - clear selection area

    PURPOSE: Clear the current selection

****************************************************************************/

void FAR PASCAL __export ClearSelection(hWnd, lpSelectRect, fFlags)
HWND hWnd;
LPRECT lpSelectRect;
int fFlags;
{
    HDC hDC;
    short OldROP;

    hDC = GetDC(hWnd);
    switch (fFlags & SL_TYPE) {

    case SL_BOX:
        OldROP = SetROP2(hDC, R2_NOTXORPEN);
        MoveTo(hDC, lpSelectRect->left, lpSelectRect->top);
        LineTo(hDC, lpSelectRect->right, lpSelectRect->top);
        LineTo(hDC, lpSelectRect->right, lpSelectRect->bottom);
        LineTo(hDC, lpSelectRect->left, lpSelectRect->bottom);
        LineTo(hDC, lpSelectRect->left, lpSelectRect->top);
        SetROP2(hDC, OldROP);
        break;

    case SL_BLOCK:
        PatBlt(hDC,
        lpSelectRect->left,
        lpSelectRect->top,
        lpSelectRect->right - lpSelectRect->left,
        lpSelectRect->bottom - lpSelectRect->top,
        DSTINVERT);
        break;
    }
    ReleaseDC(hWnd, hDC);
}
