summaryrefslogblamecommitdiffstats
path: root/private/oleutest/letest/ole2ui/hatch.c
blob: 1e156a1e0520a913589e9b3c36d3375ef55a45f3 (plain) (tree)




































































































































































































































































































































                                                                                              
/*
 * HATCH.C
 *
 * Miscellaneous API's to generate hatch window for in-place active
 * objects. This is part of the OLE 2.0 User Interface Support Library.
 *
 * Copyright (c)1993 Microsoft Corporation, All Right Reserved
 */

#define STRICT  1
#include "ole2ui.h"

// offsets in the extra bytes stored with the hatch window
#define EB_HATCHWIDTH       0
#define EB_HATCHRECT_LEFT   2
#define EB_HATCHRECT_TOP    4
#define EB_HATCHRECT_RIGHT  6
#define EB_HATCHRECT_BOTTOM 8

// class name of hatch window
#define CLASS_HATCH     TEXT("Hatch Window")

// local function prototypes
LRESULT FAR PASCAL EXPORT HatchWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);


/*
 * HatchRegisterClass
 *
 * Purpose:
 *  Register the hatch window
 *
 * Parameters:
 *  hInst           Process instance
 *
 * Return Value:
 *  TRUE            if successful
 *  FALSE           if failed
 *
 */
STDAPI_(BOOL) RegisterHatchWindowClass(HINSTANCE hInst)
{
    WNDCLASS wc;

    // Register Hatch Window Class
    wc.style = CS_BYTEALIGNWINDOW;
    wc.lpfnWndProc = HatchWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 5 * sizeof(int);    // extra bytes stores
                                        //     uHatchWidth
                                        //     rcHatchRect
    wc.hInstance = hInst;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = CLASS_HATCH;

    if (!RegisterClass(&wc))
        return FALSE;
    else
        return TRUE;
}


/*
 * CreateHatchWindow
 *
 * Purpose:
 *  Create the hatch window
 *
 * Parameters:
 *  hWndParent          parent of hatch window
 *  hInst               instance handle
 *
 * Return Value:
 *  pointer to hatch window         if successful
 *  NULL                            if failed
 *
 */
STDAPI_(HWND) CreateHatchWindow(HWND hWndParent, HINSTANCE hInst)
{
    HWND         hWnd;

    if (!hWndParent || !hInst)
        return NULL;

    hWnd = CreateWindow(
        CLASS_HATCH,
        TEXT("Hatch Window"),
        WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0, 0, 0,
        hWndParent,
        (HMENU)NULL,
        hInst,
        0L
    );

    if (!hWnd)
        return NULL;

    return hWnd;
}

/*
 *  GetHatchWidth
 *
 *  Purpose:
 *      Get width of hatch border
 *
 *  Parameters:
 *      hWndHatch       hatch window handle
 *
 *  Return Value:
 *      width of the hatch border
 */
STDAPI_(UINT) GetHatchWidth(HWND hWndHatch)
{
    if (!IsWindow(hWndHatch))
        return 0;

    return (UINT)GetWindowWord(hWndHatch, EB_HATCHWIDTH);
}

/*
 *  GetHatchRect
 *
 *  Purpose:
 *      Get hatch rect. this is the size of the hatch window if it were
 *      not clipped by the ClipRect.
 *
 *  Parameters:
 *      hWndHatch       hatch window handle
 *      lprcHatchRect   hatch rect
 *
 *  Return Value:
 *      none
 */
STDAPI_(void) GetHatchRect(HWND hWndHatch, LPRECT lprcHatchRect)
{
    if (!IsWindow(hWndHatch)) {
        SetRect(lprcHatchRect, 0, 0, 0, 0);
        return;
    }

    lprcHatchRect->left = GetWindowWord(hWndHatch, EB_HATCHRECT_LEFT);
    lprcHatchRect->top = GetWindowWord(hWndHatch, EB_HATCHRECT_TOP);
    lprcHatchRect->right = GetWindowWord(hWndHatch, EB_HATCHRECT_RIGHT);
    lprcHatchRect->bottom = GetWindowWord(hWndHatch, EB_HATCHRECT_BOTTOM);
}


/* SetHatchRect
 *
 *
 *  Purpose:
 *      Store hatch rect with HatchRect window.
 *      this rect is the size of the hatch window if it were
 *      not clipped by the ClipRect.
 *
 *  Parameters:
 *      hWndHatch       hatch window handle
 *      lprcHatchRect   hatch rect
 *
 *  Return Value:
 *      none
 */
STDAPI_(void) SetHatchRect(HWND hWndHatch, LPRECT lprcHatchRect)
{
    if (!IsWindow(hWndHatch))
        return;

    SetWindowWord(hWndHatch, EB_HATCHRECT_LEFT,  (WORD)lprcHatchRect->left);
    SetWindowWord(hWndHatch, EB_HATCHRECT_TOP,   (WORD)lprcHatchRect->top);
    SetWindowWord(hWndHatch, EB_HATCHRECT_RIGHT, (WORD)lprcHatchRect->right);
    SetWindowWord(hWndHatch, EB_HATCHRECT_BOTTOM,(WORD)lprcHatchRect->bottom);
}


/* SetHatchWindowSize
 *
 *
 *  Purpose:
 *      Move/size the HatchWindow correctly given the rect required by the
 *      in-place server object window and the lprcClipRect imposed by the
 *      in-place container. both rect's are expressed in the client coord.
 *      of the in-place container's window (which is the parent of the
 *      HatchWindow).
 *
 *      OLE2NOTE: the in-place server must honor the lprcClipRect specified
 *      by its in-place container. it must NOT draw outside of the ClipRect.
 *      in order to achieve this, the hatch window is sized to be
 *      exactly the size that should be visible (rcVisRect). the
 *      rcVisRect is defined as the intersection of the full size of
 *      the HatchRect window and the lprcClipRect.
 *      the ClipRect could infact clip the HatchRect on the
 *      right/bottom and/or on the top/left. if it is clipped on the
 *      right/bottom then it is sufficient to simply resize the hatch
 *      window. but if the HatchRect is clipped on the top/left then
 *      in-place server document window (child of HatchWindow) must be moved
 *      by the delta that was clipped. the window origin of the
 *      in-place server window will then have negative coordinates relative
 *      to its parent HatchWindow.
 *
 *  Parameters:
 *      hWndHatch       hatch window handle
 *      lprcIPObjRect   full size of in-place server object window
 *      lprcClipRect    clipping rect imposed by in-place container
 *      lpptOffset      offset required to position in-place server object
 *                      window properly. caller should call:
 *                          OffsetRect(&rcObjRect,lpptOffset->x,lpptOffset->y)
 *
 *  Return Value:
 *      none
 */
STDAPI_(void) SetHatchWindowSize(
        HWND        hWndHatch,
        LPRECT      lprcIPObjRect,
        LPRECT      lprcClipRect,
        LPPOINT       lpptOffset
)
{
    RECT        rcHatchRect;
    RECT        rcVisRect;
    UINT        uHatchWidth;
    POINT       ptOffset;

    if (!IsWindow(hWndHatch))
        return;

    rcHatchRect = *lprcIPObjRect;
    uHatchWidth = GetHatchWidth(hWndHatch);
    InflateRect((LPRECT)&rcHatchRect, uHatchWidth + 1, uHatchWidth + 1);

    IntersectRect((LPRECT)&rcVisRect, (LPRECT)&rcHatchRect, lprcClipRect);
    MoveWindow(
            hWndHatch,
            rcVisRect.left,
            rcVisRect.top,
            rcVisRect.right-rcVisRect.left,
            rcVisRect.bottom-rcVisRect.top,
            TRUE    /* fRepaint */
    );
    InvalidateRect(hWndHatch, NULL, TRUE);

    ptOffset.x = -rcHatchRect.left + (rcHatchRect.left - rcVisRect.left);
    ptOffset.y = -rcHatchRect.top + (rcHatchRect.top - rcVisRect.top);

    /* convert the rcHatchRect into the client coordinate system of the
    **    HatchWindow itself
    */
    OffsetRect((LPRECT)&rcHatchRect, ptOffset.x, ptOffset.y);

    SetHatchRect(hWndHatch, (LPRECT)&rcHatchRect);

    // calculate offset required to position in-place server doc window
    lpptOffset->x = ptOffset.x;
    lpptOffset->y = ptOffset.y;
}


/*
 *  HatchWndProc
 *
 *  Purpose:
 *      WndProc for hatch window
 *
 *  Parameters:
 *      hWnd
 *      Message
 *      wParam
 *      lParam
 *
 *  Return Value:
 *      message dependent
 */
LRESULT FAR PASCAL EXPORT HatchWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    int nBorderWidth;

    switch (Message) {

        case WM_CREATE:
            nBorderWidth = GetProfileInt(
                TEXT("windows"),
                TEXT("oleinplaceborderwidth"),
                DEFAULT_HATCHBORDER_WIDTH
            );
            SetWindowWord(hWnd, EB_HATCHWIDTH, (WORD)nBorderWidth);
            break;

        case WM_PAINT:
        {
            HDC hDC;
            PAINTSTRUCT ps;
            RECT rcHatchRect;

            nBorderWidth = GetHatchWidth(hWnd);
            hDC = BeginPaint(hWnd, &ps);
            GetHatchRect(hWnd, (LPRECT)&rcHatchRect);
            OleUIDrawShading(&rcHatchRect, hDC, OLEUI_SHADE_BORDERIN,
                    nBorderWidth);
            InflateRect((LPRECT)&rcHatchRect, -nBorderWidth, -nBorderWidth);
            OleUIDrawHandles(&rcHatchRect, hDC, OLEUI_HANDLES_OUTSIDE,
                    nBorderWidth+1, TRUE);
            EndPaint(hWnd, &ps);
            break;
        }

        /* OLE2NOTE: Any window that is used during in-place activation
        **    must handle the WM_SETCURSOR message or else the cursor
        **    of the in-place parent will be used. if WM_SETCURSOR is
        **    not handled, then DefWindowProc sends the message to the
        **    window's parent.
        */
        case WM_SETCURSOR:
            SetCursor(LoadCursor( NULL, MAKEINTRESOURCE(IDC_ARROW) ) );
            return (LRESULT)TRUE;

        default:
            return DefWindowProc(hWnd, Message, wParam, lParam);
    }

    return 0L;
}