/*
 * SysLink control
 *
 * Copyright 2004 - 2006 Thomas Weidenmueller <w3seek@reactos.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTES
 *
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on Apr. 4, 2005, by Dimitrie O. Paun.
 * 
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features, or bugs, please note them below.
 */

#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(progress);

INT WINAPI StrCmpNIW(LPCWSTR,LPCWSTR,INT);

typedef struct
{
    int nChars;
    int nSkip;
    RECT rc;
} DOC_TEXTBLOCK, *PDOC_TEXTBLOCK;

#define LIF_FLAGSMASK   (LIF_STATE | LIF_ITEMID | LIF_URL)
#define LIS_MASK        (LIS_FOCUSED | LIS_ENABLED | LIS_VISITED)

typedef enum
{
    slText = 0,
    slLink
} SL_ITEM_TYPE;

typedef struct _DOC_ITEM
{
    struct _DOC_ITEM *Next; /* Address to the next item */
    UINT nText;             /* Number of characters of the text */
    SL_ITEM_TYPE Type;      /* type of the item */
    PDOC_TEXTBLOCK Blocks;  /* Array of text blocks */
    union
    {
        struct
        {
            UINT state;     /* Link state */
            WCHAR *szID;    /* Link ID string */
            WCHAR *szUrl;   /* Link URL string */
        } Link;
        struct
        {
            UINT Dummy;
        } Text;
    } u;
    WCHAR Text[1];          /* Text of the document item */
} DOC_ITEM, *PDOC_ITEM;

typedef struct
{
    HWND      Self;         /* The window handle for this control */
    HWND      Notify;       /* The parent handle to receive notifications */
    DWORD     Style;        /* Styles for this control */
    PDOC_ITEM Items;        /* Address to the first document item */
    BOOL      HasFocus;     /* Whether the control has the input focus */
    int       MouseDownID;  /* ID of the link that the mouse button first selected */
    HFONT     Font;         /* Handle to the font for text */
    HFONT     LinkFont;     /* Handle to the font for links */
    COLORREF  TextColor;    /* Color of the text */
    COLORREF  LinkColor;    /* Color of links */
    COLORREF  VisitedColor; /* Color of visited links */
    WCHAR     BreakChar;    /* Break Character for the current font */
} SYSLINK_INFO;

static const WCHAR SL_LINKOPEN[] =  { '<','a', 0 };
static const WCHAR SL_HREF[] =      { 'h','r','e','f','=','\"',0 };
static const WCHAR SL_ID[] =        { 'i','d','=','\"',0 };
static const WCHAR SL_LINKCLOSE[] = { '<','/','a','>',0 };

/* Control configuration constants */

#define SL_LEFTMARGIN   (0)
#define SL_TOPMARGIN    (0)
#define SL_RIGHTMARGIN  (0)
#define SL_BOTTOMMARGIN (0)

/***********************************************************************
 * SYSLINK_FreeDocItem
 * Frees all data and gdi objects associated with a document item
 */
static VOID SYSLINK_FreeDocItem (PDOC_ITEM DocItem)
{
    if(DocItem->Type == slLink)
    {
        if (DocItem->u.Link.szID != NULL)
        {
            Free(DocItem->u.Link.szID);
        }
        if (DocItem->u.Link.szUrl != NULL)
        {
            Free(DocItem->u.Link.szUrl);
        }
    }

    /* we don't free Text because it's just a pointer to a character in the
       entire window text string */

    Free(DocItem);
}

/***********************************************************************
 * SYSLINK_AppendDocItem
 * Create and append a new document item.
 */
static PDOC_ITEM SYSLINK_AppendDocItem (SYSLINK_INFO *infoPtr, LPCWSTR Text, UINT textlen,
                                        SL_ITEM_TYPE type, PDOC_ITEM LastItem)
{
    PDOC_ITEM Item;

    textlen = min(textlen, lstrlenW(Text));
    Item = Alloc(FIELD_OFFSET(DOC_ITEM, Text[textlen + 1]));
    if(Item == NULL)
    {
        ERR("Failed to alloc DOC_ITEM structure!\n");
        return NULL;
    }

    Item->Next = NULL;
    Item->nText = textlen;
    Item->Type = type;
    Item->Blocks = NULL;
    
    if(LastItem != NULL)
    {
        LastItem->Next = Item;
    }
    else
    {
        infoPtr->Items = Item;
    }
    
    lstrcpynW(Item->Text, Text, textlen + 1);
    
    return Item;
}

/***********************************************************************
 * SYSLINK_ClearDoc
 * Clears the document tree
 */
static VOID SYSLINK_ClearDoc (SYSLINK_INFO *infoPtr)
{
    PDOC_ITEM Item, Next;
    
    Item = infoPtr->Items;
    while(Item != NULL)
    {
        Next = Item->Next;
        SYSLINK_FreeDocItem(Item);
        Item = Next;
    }
    
    infoPtr->Items = NULL;
}

/***********************************************************************
 * SYSLINK_ParseText
 * Parses the window text string and creates a document. Returns the
 * number of document items created.
 */
static UINT SYSLINK_ParseText (SYSLINK_INFO *infoPtr, LPCWSTR Text)
{
    LPCWSTR current, textstart = NULL, linktext = NULL, firsttag = NULL;
    int taglen = 0, textlen = 0, linklen = 0, docitems = 0;
    PDOC_ITEM Last = NULL;
    SL_ITEM_TYPE CurrentType = slText;
    LPCWSTR lpID, lpUrl;
    UINT lenId, lenUrl;

    for(current = Text; *current != 0;)
    {
        if(*current == '<')
        {
            if(!StrCmpNIW(current, SL_LINKOPEN, 2) && (CurrentType == slText))
            {
                BOOL ValidParam = FALSE, ValidLink = FALSE;

                if(*(current + 2) == '>')
                {
                    /* we just have to deal with a <a> tag */
                    taglen = 3;
                    ValidLink = TRUE;
                    ValidParam = TRUE;
                    firsttag = current;
                    linklen = 0;
                    lpID = NULL;
                    lpUrl = NULL;
                }
                else if(*(current + 2) == infoPtr->BreakChar)
                {
                    /* we expect parameters, parse them */
                    LPCWSTR *CurrentParameter = NULL, tmp;
                    UINT *CurrentParameterLen = NULL;

                    taglen = 3;
                    tmp = current + taglen;
                    lpID = NULL;
                    lpUrl = NULL;
                    
CheckParameter:
                    /* compare the current position with all known parameters */
                    if(!StrCmpNIW(tmp, SL_HREF, 6))
                    {
                        taglen += 6;
                        ValidParam = TRUE;
                        CurrentParameter = &lpUrl;
                        CurrentParameterLen = &lenUrl;
                    }
                    else if(!StrCmpNIW(tmp, SL_ID, 4))
                    {
                        taglen += 4;
                        ValidParam = TRUE;
                        CurrentParameter = &lpID;
                        CurrentParameterLen = &lenId;
                    }
                    else
                    {
                        ValidParam = FALSE;
                    }
                    
                    if(ValidParam)
                    {
                        /* we got a known parameter, now search until the next " character.
                           If we can't find a " character, there's a syntax error and we just assume it's text */
                        ValidParam = FALSE;
                        *CurrentParameter = current + taglen;
                        *CurrentParameterLen = 0;

                        for(tmp = *CurrentParameter; *tmp != 0; tmp++)
                        {
                            taglen++;
                            if(*tmp == '\"')
                            {
                                ValidParam = TRUE;
                                tmp++;
                                break;
                            }
                            (*CurrentParameterLen)++;
                        }
                    }
                    if(ValidParam)
                    {
                        /* we're done with this parameter, now there are only 2 possibilities:
                         * 1. another parameter is coming, so expect a ' ' (space) character
                         * 2. the tag is being closed, so expect a '<' character
                         */
                        if(*tmp == infoPtr->BreakChar)
                        {
                            /* we expect another parameter, do the whole thing again */
                            taglen++;
                            tmp++;
                            goto CheckParameter;
                        }
                        else if(*tmp == '>')
                        {
                            /* the tag is being closed, we're done */
                            ValidLink = TRUE;
                            taglen++;
                        }
                        else
                            tmp++;
                    }
                }
                
                if(ValidLink && ValidParam)
                {
                    /* the <a ...> tag appears to be valid. save all information
                       so we can add the link if we find a valid </a> tag later */
                    CurrentType = slLink;
                    linktext = current + taglen;
                    linklen = 0;
                    firsttag = current;
                }
                else
                {
                    taglen = 1;
                    lpID = NULL;
                    lpUrl = NULL;
                    if(textstart == NULL)
                    {
                        textstart = current;
                    }
                }
            }
            else if(!StrCmpNIW(current, SL_LINKCLOSE, 4) && (CurrentType == slLink) && firsttag)
            {
                /* there's a <a...> tag opened, first add the previous text, if present */
                if(textstart != NULL && textlen > 0 && firsttag > textstart)
                {
                    Last = SYSLINK_AppendDocItem(infoPtr, textstart, firsttag - textstart, slText, Last);
                    if(Last == NULL)
                    {
                        ERR("Unable to create new document item!\n");
                        return docitems;
                    }
                    docitems++;
                    textstart = NULL;
                    textlen = 0;
                }
                
                /* now it's time to add the link to the document */
                current += 4;
                if(linktext != NULL && linklen > 0)
                {
                    Last = SYSLINK_AppendDocItem(infoPtr, linktext, linklen, slLink, Last);
                    if(Last == NULL)
                    {
                        ERR("Unable to create new document item!\n");
                        return docitems;
                    }
                    docitems++;
                    if(CurrentType == slLink)
                    {
                        int nc;

                        if(!(infoPtr->Style & WS_DISABLED))
                        {
                            Last->u.Link.state |= LIS_ENABLED;
                        }
                        /* Copy the tag parameters */
                        if(lpID != NULL)
                        {
                            nc = min(lenId, strlenW(lpID));
                            nc = min(nc, MAX_LINKID_TEXT - 1);
                            Last->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
                            if(Last->u.Link.szID != NULL)
                            {
                                lstrcpynW(Last->u.Link.szID, lpID, nc + 1);
                            }
                        }
                        else
                            Last->u.Link.szID = NULL;
                        if(lpUrl != NULL)
                        {
                            nc = min(lenUrl, strlenW(lpUrl));
                            nc = min(nc, L_MAX_URL_LENGTH - 1);
                            Last->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
                            if(Last->u.Link.szUrl != NULL)
                            {
                                lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1);
                            }
                        }
                        else
                            Last->u.Link.szUrl = NULL;
                    }
                    linktext = NULL;
                }
                CurrentType = slText;
                firsttag = NULL;
                textstart = NULL;
                continue;
            }
            else
            {
                /* we don't know what tag it is, so just continue */
                taglen = 1;
                linklen++;
                if(CurrentType == slText && textstart == NULL)
                {
                    textstart = current;
                }
            }
            
            textlen += taglen;
            current += taglen;
        }
        else
        {
            textlen++;
            linklen++;

            /* save the pointer of the current text item if we couldn't find a tag */
            if(textstart == NULL && CurrentType == slText)
            {
                textstart = current;
            }
            
            current++;
        }
    }
    
    if(textstart != NULL && textlen > 0)
    {
        Last = SYSLINK_AppendDocItem(infoPtr, textstart, textlen, CurrentType, Last);
        if(Last == NULL)
        {
            ERR("Unable to create new document item!\n");
            return docitems;
        }
        if(CurrentType == slLink)
        {
            int nc;

            if(!(infoPtr->Style & WS_DISABLED))
            {
                Last->u.Link.state |= LIS_ENABLED;
            }
            /* Copy the tag parameters */
            if(lpID != NULL)
            {
                nc = min(lenId, strlenW(lpID));
                nc = min(nc, MAX_LINKID_TEXT - 1);
                Last->u.Link.szID = Alloc((nc + 1) * sizeof(WCHAR));
                if(Last->u.Link.szID != NULL)
                {
                    lstrcpynW(Last->u.Link.szID, lpID, nc + 1);
                }
            }
            else
                Last->u.Link.szID = NULL;
            if(lpUrl != NULL)
            {
                nc = min(lenUrl, strlenW(lpUrl));
                nc = min(nc, L_MAX_URL_LENGTH - 1);
                Last->u.Link.szUrl = Alloc((nc + 1) * sizeof(WCHAR));
                if(Last->u.Link.szUrl != NULL)
                {
                    lstrcpynW(Last->u.Link.szUrl, lpUrl, nc + 1);
                }
            }
            else
                Last->u.Link.szUrl = NULL;
        }
        docitems++;
    }

    if(linktext != NULL && linklen > 0)
    {
        /* we got an unclosed link, just display the text */
        Last = SYSLINK_AppendDocItem(infoPtr, linktext, linklen, slText, Last);
        if(Last == NULL)
        {
            ERR("Unable to create new document item!\n");
            return docitems;
        }
        docitems++;
    }

    return docitems;
}

/***********************************************************************
 * SYSLINK_RepaintLink
 * Repaints a link.
 */
static VOID SYSLINK_RepaintLink (SYSLINK_INFO *infoPtr, PDOC_ITEM DocItem)
{
    PDOC_TEXTBLOCK bl;
    int n;

    if(DocItem->Type != slLink)
    {
        ERR("DocItem not a link!\n");
        return;
    }
    
    bl = DocItem->Blocks;
    if (bl != NULL)
    {
        n = DocItem->nText;
        
        while(n > 0)
        {
            InvalidateRect(infoPtr->Self, &bl->rc, TRUE);
            n -= bl->nChars + bl->nSkip;
            bl++;
        }
    }
}

/***********************************************************************
 * SYSLINK_GetLinkItemByIndex
 * Retrieves a document link by its index
 */
static PDOC_ITEM SYSLINK_GetLinkItemByIndex (SYSLINK_INFO *infoPtr, int iLink)
{
    PDOC_ITEM Current = infoPtr->Items;

    while(Current != NULL)
    {
        if((Current->Type == slLink) && (iLink-- <= 0))
        {
            return Current;
        }
        Current = Current->Next;
    }
    return NULL;
}

/***********************************************************************
 * SYSLINK_GetFocusLink
 * Retrieves the link that has the LIS_FOCUSED bit
 */
static PDOC_ITEM SYSLINK_GetFocusLink (SYSLINK_INFO *infoPtr, int *LinkId)
{
    PDOC_ITEM Current = infoPtr->Items;
    int id = 0;

    while(Current != NULL)
    {
        if((Current->Type == slLink))
        {
            if(Current->u.Link.state & LIS_FOCUSED)
            {
                if(LinkId != NULL)
                    *LinkId = id;
                return Current;
            }
            id++;
        }
        Current = Current->Next;
    }
    return NULL;
}

/***********************************************************************
 * SYSLINK_GetNextLink
 * Gets the next link
 */
static PDOC_ITEM SYSLINK_GetNextLink (SYSLINK_INFO *infoPtr, PDOC_ITEM Current)
{
    for(Current = (Current != NULL ? Current->Next : infoPtr->Items);
        Current != NULL;
        Current = Current->Next)
    {
        if(Current->Type == slLink)
        {
            return Current;
        }
    }
    return NULL;
}

/***********************************************************************
 * SYSLINK_GetPrevLink
 * Gets the previous link
 */
static PDOC_ITEM SYSLINK_GetPrevLink (SYSLINK_INFO *infoPtr, PDOC_ITEM Current)
{
    if(Current == NULL)
    {
        /* returns the last link */
        PDOC_ITEM Last = NULL;
        
        for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
        {
            if(Current->Type == slLink)
            {
                Last = Current;
            }
        }
        return Last;
    }
    else
    {
        /* returns the previous link */
        PDOC_ITEM Cur, Prev = NULL;
        
        for(Cur = infoPtr->Items; Cur != NULL; Cur = Cur->Next)
        {
            if(Cur == Current)
            {
                break;
            }
            if(Cur->Type == slLink)
            {
                Prev = Cur;
            }
        }
        return Prev;
    }
}

/***********************************************************************
 * SYSLINK_WrapLine
 * Tries to wrap a line.
 */
static BOOL SYSLINK_WrapLine (HDC hdc, LPWSTR Text, WCHAR BreakChar, int *LineLen,
                             int nFit, LPSIZE Extent, int Width)
{
    WCHAR *Current;

    if(nFit == *LineLen)
    {
        return FALSE;
    }

    *LineLen = nFit;

    Current = Text + nFit;
    
    /* check if we're in the middle of a word */
    if((*Current) != BreakChar)
    {
        /* search for the beginning of the word */
        while(Current > Text && (*(Current - 1)) != BreakChar)
        {
            Current--;
            (*LineLen)--;
        }
        
        if((*LineLen) == 0)
        {
            Extent->cx = 0;
            Extent->cy = 0;
        }
        return TRUE;
    }

    return TRUE;
}

/***********************************************************************
 * SYSLINK_Render
 * Renders the document in memory
 */
static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
{
    RECT rc;
    PDOC_ITEM Current;
    HGDIOBJ hOldFont;
    int x, y, LineHeight;
    
    GetClientRect(infoPtr->Self, &rc);
    rc.right -= SL_RIGHTMARGIN;
    rc.bottom -= SL_BOTTOMMARGIN;
    
    if(rc.right - SL_LEFTMARGIN < 0 || rc.bottom - SL_TOPMARGIN < 0) return;
    
    hOldFont = SelectObject(hdc, infoPtr->Font);
    
    x = SL_LEFTMARGIN;
    y = SL_TOPMARGIN;
    LineHeight = 0;
    
    for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
    {
        int n, nBlocks;
        LPWSTR tx;
        PDOC_TEXTBLOCK bl, cbl;
        INT nFit;
        SIZE szDim;
        
        if(Current->nText == 0)
        {
            continue;
        }
        
        tx = Current->Text;
        n = Current->nText;

        if (Current->Blocks != NULL)
        {
            Free(Current->Blocks);
            Current->Blocks = NULL;
        }
        bl = NULL;
        nBlocks = 0;
        
        if(Current->Type == slText)
        {
            SelectObject(hdc, infoPtr->Font);
        }
        else if(Current->Type == slLink)
        {
            SelectObject(hdc, infoPtr->LinkFont);
        }
        
        while(n > 0)
        {
            int SkipChars = 0;

            /* skip break characters unless they're the first of the doc item */
            if(tx != Current->Text || x == SL_LEFTMARGIN)
            {
                while(n > 0 && (*tx) == infoPtr->BreakChar)
                {
                    tx++;
                    SkipChars++;
                    n--;
                }
            }

            if((n == 0 && SkipChars != 0) ||
               GetTextExtentExPointW(hdc, tx, n, rc.right - x, &nFit, NULL, &szDim))
            {
                int LineLen = n;
                BOOL Wrap = FALSE;
                
                if(n != 0)
                {
                    Wrap = SYSLINK_WrapLine(hdc, tx, infoPtr->BreakChar, &LineLen, nFit, &szDim, rc.right - x);

                    if(LineLen == 0)
                    {
                        if(x > SL_LEFTMARGIN)
                        {
                            /* move one line down, the word didn't fit into the line */
                            x = SL_LEFTMARGIN;
                            y += LineHeight;
                            LineHeight = 0;
                            continue;
                        }
                        else
                        {
                            /* the word starts at the beginning of the line and doesn't
                               fit into the line, so break it at the last character that fits */
                            LineLen = max(nFit, 1);
                        }
                    }

                    if(LineLen != n)
                    {
                        if(!GetTextExtentExPointW(hdc, tx, LineLen, rc.right - x, NULL, NULL, &szDim))
                        {
                            if(bl != NULL)
                            {
                                Free(bl);
                                bl = NULL;
                                nBlocks = 0;
                            }
                            break;
                        }
                    }
                }
                
                if(bl != NULL)
                {
                    PDOC_TEXTBLOCK nbl = ReAlloc(bl, (nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
                    if (nbl != NULL)
                    {
                        bl = nbl;
                        nBlocks++;
                    }
                    else
                    {
                        Free(bl);
                        bl = NULL;
                        nBlocks = 0;
                    }
                }
                else
                {
                    bl = Alloc(sizeof(DOC_TEXTBLOCK));
                    if (bl != NULL)
                        nBlocks++;
                }
                
                if(bl != NULL)
                {
                    cbl = bl + nBlocks - 1;
                    
                    cbl->nChars = LineLen;
                    cbl->nSkip = SkipChars;
                    cbl->rc.left = x;
                    cbl->rc.top = y;
                    cbl->rc.right = x + szDim.cx;
                    cbl->rc.bottom = y + szDim.cy;
                    
                    if(LineLen != 0)
                    {
                        x += szDim.cx;
                        LineHeight = max(LineHeight, szDim.cy);

                        if(Wrap)
                        {
                            x = SL_LEFTMARGIN;
                            y += LineHeight;
                            LineHeight = 0;
                        }
                    }
                }
                else
                {
                    ERR("Failed to alloc DOC_TEXTBLOCK structure!\n");
                    break;
                }
                n -= LineLen;
                tx += LineLen;
            }
            else
            {
                n--;
            }
        }

        if(nBlocks != 0)
        {
            Current->Blocks = bl;
        }
    }
    
    SelectObject(hdc, hOldFont);
}

/***********************************************************************
 * SYSLINK_Draw
 * Draws the SysLink control.
 */
static LRESULT SYSLINK_Draw (SYSLINK_INFO *infoPtr, HDC hdc)
{
    RECT rc;
    PDOC_ITEM Current;
    HFONT hOldFont;
    COLORREF OldTextColor, OldBkColor;

    hOldFont = SelectObject(hdc, infoPtr->Font);
    OldTextColor = SetTextColor(hdc, infoPtr->TextColor);
    OldBkColor = SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
    
    GetClientRect(infoPtr->Self, &rc);
    rc.right -= SL_RIGHTMARGIN + SL_LEFTMARGIN;
    rc.bottom -= SL_BOTTOMMARGIN + SL_TOPMARGIN;

    if(rc.right < 0 || rc.bottom < 0) return 0;

    for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
    {
        int n;
        LPWSTR tx;
        PDOC_TEXTBLOCK bl;
        
        bl = Current->Blocks;
        if(bl != NULL)
        {
            tx = Current->Text;
            n = Current->nText;

            if(Current->Type == slText)
            {
                 SelectObject(hdc, infoPtr->Font);
                 SetTextColor(hdc, infoPtr->TextColor);
            }
            else
            {
                 SelectObject(hdc, infoPtr->LinkFont);
                 SetTextColor(hdc, (!(Current->u.Link.state & LIS_VISITED) ? infoPtr->LinkColor : infoPtr->VisitedColor));
            }

            while(n > 0)
            {
                tx += bl->nSkip;
                ExtTextOutW(hdc, bl->rc.left, bl->rc.top, ETO_OPAQUE | ETO_CLIPPED, &bl->rc, tx, bl->nChars, NULL);
                if((Current->Type == slLink) && (Current->u.Link.state & LIS_FOCUSED) && infoPtr->HasFocus)
                {
                    COLORREF PrevTextColor;
                    PrevTextColor = SetTextColor(hdc, infoPtr->TextColor);
                    DrawFocusRect(hdc, &bl->rc);
                    SetTextColor(hdc, PrevTextColor);
                }
                tx += bl->nChars;
                n -= bl->nChars + bl->nSkip;
                bl++;
            }
        }
    }

    SetBkColor(hdc, OldBkColor);
    SetTextColor(hdc, OldTextColor);
    SelectObject(hdc, hOldFont);
    
    return 0;
}


/***********************************************************************
 * SYSLINK_Paint
 * Handles the WM_PAINT message.
 */
static LRESULT SYSLINK_Paint (SYSLINK_INFO *infoPtr, HDC hdcParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    hdc = hdcParam ? hdcParam : BeginPaint (infoPtr->Self, &ps);
    if (hdc)
    {
        SYSLINK_Draw (infoPtr, hdc);
        if (!hdcParam) EndPaint (infoPtr->Self, &ps);
    }
    return 0;
}


/***********************************************************************
 *           SYSLINK_SetFont
 * Set new Font for the SysLink control.
 */
static HFONT SYSLINK_SetFont (SYSLINK_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
{
    HDC hdc;
    LOGFONTW lf;
    TEXTMETRICW tm;
    HFONT hOldFont = infoPtr->Font;
    infoPtr->Font = hFont;
    
    /* free the underline font */
    if(infoPtr->LinkFont != NULL)
    {
        DeleteObject(infoPtr->LinkFont);
        infoPtr->LinkFont = NULL;
    }

    /* Render text position and word wrapping in memory */
    hdc = GetDC(infoPtr->Self);
    if(hdc != NULL)
    {
        /* create a new underline font */
        if(GetTextMetricsW(hdc, &tm) &&
           GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf))
        {
            lf.lfUnderline = TRUE;
            infoPtr->LinkFont = CreateFontIndirectW(&lf);
            infoPtr->BreakChar = tm.tmBreakChar;
        }
        else
        {
            ERR("Failed to create link font!\n");
        }

        SYSLINK_Render(infoPtr, hdc);
        ReleaseDC(infoPtr->Self, hdc);
    }
    
    if(bRedraw)
    {
        RedrawWindow(infoPtr->Self, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
    }
    
    return hOldFont;
}

/***********************************************************************
 *           SYSLINK_SetText
 * Set new text for the SysLink control.
 */
static LRESULT SYSLINK_SetText (SYSLINK_INFO *infoPtr, LPCWSTR Text)
{
    int textlen;

    /* clear the document */
    SYSLINK_ClearDoc(infoPtr);
    
    if(Text == NULL || (textlen = lstrlenW(Text)) == 0)
    {
        return TRUE;
    }
    
    /* let's parse the string and create a document */
    if(SYSLINK_ParseText(infoPtr, Text) > 0)
    {
        /* Render text position and word wrapping in memory */
        HDC hdc = GetDC(infoPtr->Self);
        if (hdc != NULL)
        {
            SYSLINK_Render(infoPtr, hdc);
            ReleaseDC(infoPtr->Self, hdc);

            InvalidateRect(infoPtr->Self, NULL, TRUE);
        }
    }
    
    return TRUE;
}

/***********************************************************************
 *           SYSLINK_SetFocusLink
 * Updates the focus status bits and focusses the specified link.
 * If no document item is specified, the focus bit will be removed from all links.
 * Returns the previous focused item.
 */
static PDOC_ITEM SYSLINK_SetFocusLink (SYSLINK_INFO *infoPtr, PDOC_ITEM DocItem)
{
    PDOC_ITEM Current, PrevFocus = NULL;
    
    for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
    {
        if(Current->Type == slLink)
        {
            if((PrevFocus == NULL) && (Current->u.Link.state & LIS_FOCUSED))
            {
                PrevFocus = Current;
            }
            
            if(Current == DocItem)
            {
                Current->u.Link.state |= LIS_FOCUSED;
            }
            else
            {
                Current->u.Link.state &= ~LIS_FOCUSED;
            }
        }
    }
    
    return PrevFocus;
}

/***********************************************************************
 *           SYSLINK_SetItem
 * Sets the states and attributes of a link item.
 */
static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
{
    PDOC_ITEM di;
    int nc;
    PWSTR szId = NULL;
    PWSTR szUrl = NULL;
    BOOL Repaint = FALSE;

    if(!(Item->mask & LIF_ITEMINDEX) || !(Item->mask & (LIF_FLAGSMASK)))
    {
        ERR("Invalid Flags!\n");
        return FALSE;
    }

    di = SYSLINK_GetLinkItemByIndex(infoPtr, Item->iLink);
    if(di == NULL)
    {
        ERR("Link %d couldn't be found\n", Item->iLink);
        return FALSE;
    }

    if(Item->mask & LIF_ITEMID)
    {
        nc = min(lstrlenW(Item->szID), MAX_LINKID_TEXT - 1);
        szId = Alloc((nc + 1) * sizeof(WCHAR));
        if(szId)
        {
            lstrcpynW(szId, Item->szID, nc + 1);
        }
        else
        {
            ERR("Unable to allocate memory for link id\n");
            return FALSE;
        }
    }

    if(Item->mask & LIF_URL)
    {
        nc = min(lstrlenW(Item->szUrl), L_MAX_URL_LENGTH - 1);
        szUrl = Alloc((nc + 1) * sizeof(WCHAR));
        if(szUrl)
        {
            lstrcpynW(szUrl, Item->szUrl, nc + 1);
        }
        else
        {
            if (szId)
            {
                Free(szId);
            }

            ERR("Unable to allocate memory for link url\n");
            return FALSE;
        }
    }

    if(Item->mask & LIF_ITEMID)
    {
        if(di->u.Link.szID)
        {
            Free(di->u.Link.szID);
        }
        di->u.Link.szID = szId;
    }

    if(Item->mask & LIF_URL)
    {
        if(di->u.Link.szUrl)
        {
            Free(di->u.Link.szUrl);
        }
        di->u.Link.szUrl = szUrl;
    }

    if(Item->mask & LIF_STATE)
    {
        UINT oldstate = di->u.Link.state;
        /* clear the masked bits */
        di->u.Link.state &= ~(Item->stateMask & LIS_MASK);
        /* copy the bits */
        di->u.Link.state |= (Item->state & Item->stateMask) & LIS_MASK;
        Repaint = (oldstate != di->u.Link.state);
        
        /* update the focus */
        SYSLINK_SetFocusLink(infoPtr, ((di->u.Link.state & LIS_FOCUSED) ? di : NULL));
    }
    
    if(Repaint)
    {
        SYSLINK_RepaintLink(infoPtr, di);
    }
    
    return TRUE;
}

/***********************************************************************
 *           SYSLINK_GetItem
 * Retrieves the states and attributes of a link item.
 */
static LRESULT SYSLINK_GetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
{
    PDOC_ITEM di;
    
    if(!(Item->mask & LIF_ITEMINDEX) || !(Item->mask & (LIF_FLAGSMASK)))
    {
        ERR("Invalid Flags!\n");
        return FALSE;
    }
    
    di = SYSLINK_GetLinkItemByIndex(infoPtr, Item->iLink);
    if(di == NULL)
    {
        ERR("Link %d couldn't be found\n", Item->iLink);
        return FALSE;
    }
    
    if(Item->mask & LIF_STATE)
    {
        Item->state = (di->u.Link.state & Item->stateMask);
        if(!infoPtr->HasFocus)
        {
            /* remove the LIS_FOCUSED bit if the control doesn't have focus */
            Item->state &= ~LIS_FOCUSED;
        }
    }
    
    if(Item->mask & LIF_ITEMID)
    {
        if(di->u.Link.szID)
        {
            lstrcpyW(Item->szID, di->u.Link.szID);
        }
        else
        {
            Item->szID[0] = 0;
        }
    }
    
    if(Item->mask & LIF_URL)
    {
        if(di->u.Link.szUrl)
        {
            lstrcpyW(Item->szUrl, di->u.Link.szUrl);
        }
        else
        {
            Item->szUrl[0] = 0;
        }
    }
    
    return TRUE;
}

/***********************************************************************
 *           SYSLINK_PtInDocItem
 * Determines if a point is in the region of a document item
 */
static BOOL SYSLINK_PtInDocItem (PDOC_ITEM DocItem, POINT pt)
{
    PDOC_TEXTBLOCK bl;
    int n;

    bl = DocItem->Blocks;
    if (bl != NULL)
    {
        n = DocItem->nText;

        while(n > 0)
        {
            if (PtInRect(&bl->rc, pt))
            {
                return TRUE;
            }
            n -= bl->nChars + bl->nSkip;
            bl++;
        }
    }
    
    return FALSE;
}

/***********************************************************************
 *           SYSLINK_HitTest
 * Determines the link the user clicked on.
 */
static LRESULT SYSLINK_HitTest (SYSLINK_INFO *infoPtr, PLHITTESTINFO HitTest)
{
    PDOC_ITEM Current;
    int id = 0;

    for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
    {
        if(Current->Type == slLink)
        {
            if(SYSLINK_PtInDocItem(Current, HitTest->pt))
            {
                HitTest->item.mask = 0;
                HitTest->item.iLink = id;
                HitTest->item.state = 0;
                HitTest->item.stateMask = 0;
                if(Current->u.Link.szID)
                {
                    lstrcpyW(HitTest->item.szID, Current->u.Link.szID);
                }
                else
                {
                    HitTest->item.szID[0] = 0;
                }
                if(Current->u.Link.szUrl)
                {
                    lstrcpyW(HitTest->item.szUrl, Current->u.Link.szUrl);
                }
                else
                {
                    HitTest->item.szUrl[0] = 0;
                }
                return TRUE;
            }
            id++;
        }
    }
    
    return FALSE;
}

/***********************************************************************
 *           SYSLINK_GetIdealHeight
 * Returns the preferred height of a link at the current control's width.
 */
static LRESULT SYSLINK_GetIdealHeight (SYSLINK_INFO *infoPtr)
{
    HDC hdc = GetDC(infoPtr->Self);
    if(hdc != NULL)
    {
        LRESULT height;
        TEXTMETRICW tm;
        HGDIOBJ hOldFont = SelectObject(hdc, infoPtr->Font);
        
        if(GetTextMetricsW(hdc, &tm))
        {
            height = tm.tmHeight;
        }
        else
        {
            height = 0;
        }
        SelectObject(hdc, hOldFont);
        ReleaseDC(infoPtr->Self, hdc);
        
        return height;
    }
    return 0;
}

/***********************************************************************
 *           SYSLINK_SendParentNotify
 * Sends a WM_NOTIFY message to the parent window.
 */
static LRESULT SYSLINK_SendParentNotify (SYSLINK_INFO *infoPtr, UINT code, PDOC_ITEM Link, int iLink)
{
    NMLINK nml;

    nml.hdr.hwndFrom = infoPtr->Self;
    nml.hdr.idFrom = GetWindowLongPtrW(infoPtr->Self, GWLP_ID);
    nml.hdr.code = code;

    nml.item.mask = 0;
    nml.item.iLink = iLink;
    nml.item.state = 0;
    nml.item.stateMask = 0;
    if(Link->u.Link.szID)
    {
        lstrcpyW(nml.item.szID, Link->u.Link.szID);
    }
    else
    {
        nml.item.szID[0] = 0;
    }
    if(Link->u.Link.szUrl)
    {
        lstrcpyW(nml.item.szUrl, Link->u.Link.szUrl);
    }
    else
    {
        nml.item.szUrl[0] = 0;
    }

    return SendMessageW(infoPtr->Notify, WM_NOTIFY, (WPARAM)nml.hdr.idFrom, (LPARAM)&nml);
}

/***********************************************************************
 *           SYSLINK_SetFocus
 * Handles receiving the input focus.
 */
static LRESULT SYSLINK_SetFocus (SYSLINK_INFO *infoPtr, HWND PrevFocusWindow)
{
    PDOC_ITEM Focus;
    
    infoPtr->HasFocus = TRUE;

    /* We always select the first link, even if we activated the control using
       SHIFT+TAB. This is the default behavior */
    Focus = SYSLINK_GetNextLink(infoPtr, NULL);
    if(Focus != NULL)
    {
        SYSLINK_SetFocusLink(infoPtr, Focus);
    }
    
    SYSLINK_RepaintLink(infoPtr, Focus);
    
    return 0;
}

/***********************************************************************
 *           SYSLINK_KillFocus
 * Handles losing the input focus.
 */
static LRESULT SYSLINK_KillFocus (SYSLINK_INFO *infoPtr, HWND NewFocusWindow)
{
    PDOC_ITEM Focus;
    
    infoPtr->HasFocus = FALSE;
    Focus = SYSLINK_GetFocusLink(infoPtr, NULL);
    
    if(Focus != NULL)
    {
        SYSLINK_RepaintLink(infoPtr, Focus);
    }

    return 0;
}

/***********************************************************************
 *           SYSLINK_LinkAtPt
 * Returns a link at the specified position
 */
static PDOC_ITEM SYSLINK_LinkAtPt (SYSLINK_INFO *infoPtr, POINT *pt, int *LinkId, BOOL MustBeEnabled)
{
    PDOC_ITEM Current;
    int id = 0;

    for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
    {
        if((Current->Type == slLink) && SYSLINK_PtInDocItem(Current, *pt) &&
           (!MustBeEnabled || (MustBeEnabled && (Current->u.Link.state & LIS_ENABLED))))
        {
            if(LinkId != NULL)
            {
                *LinkId = id;
            }
            return Current;
        }
        id++;
    }

    return NULL;
}

/***********************************************************************
 *           SYSLINK_LButtonDown
 * Handles mouse clicks
 */
static LRESULT SYSLINK_LButtonDown (SYSLINK_INFO *infoPtr, DWORD Buttons, POINT *pt)
{
    PDOC_ITEM Current, Old;
    int id;

    Current = SYSLINK_LinkAtPt(infoPtr, pt, &id, TRUE);
    if(Current != NULL)
    {
      SetFocus(infoPtr->Self);

      Old = SYSLINK_SetFocusLink(infoPtr, Current);
      if(Old != NULL && Old != Current)
      {
          SYSLINK_RepaintLink(infoPtr, Old);
      }
      infoPtr->MouseDownID = id;
      SYSLINK_RepaintLink(infoPtr, Current);
    }

    return 0;
}

/***********************************************************************
 *           SYSLINK_LButtonUp
 * Handles mouse clicks
 */
static LRESULT SYSLINK_LButtonUp (SYSLINK_INFO *infoPtr, DWORD Buttons, POINT *pt)
{
    if(infoPtr->MouseDownID > -1)
    {
        PDOC_ITEM Current;
        int id;
        
        Current = SYSLINK_LinkAtPt(infoPtr, pt, &id, TRUE);
        if((Current != NULL) && (Current->u.Link.state & LIS_FOCUSED) && (infoPtr->MouseDownID == id))
        {
            SYSLINK_SendParentNotify(infoPtr, NM_CLICK, Current, id);
        }
    }

    infoPtr->MouseDownID = -1;

    return 0;
}

/***********************************************************************
 *           SYSLINK_OnEnter
 * Handles ENTER key events
 */
static BOOL SYSLINK_OnEnter (SYSLINK_INFO *infoPtr)
{
    if(infoPtr->HasFocus)
    {
        PDOC_ITEM Focus;
        int id;
        
        Focus = SYSLINK_GetFocusLink(infoPtr, &id);
        if(Focus != NULL)
        {
            SYSLINK_SendParentNotify(infoPtr, NM_RETURN, Focus, id);
            return TRUE;
        }
    }
    return FALSE;
}

/***********************************************************************
 *           SYSKEY_SelectNextPrevLink
 * Changes the currently focused link
 */
static BOOL SYSKEY_SelectNextPrevLink (SYSLINK_INFO *infoPtr, BOOL Prev)
{
    if(infoPtr->HasFocus)
    {
        PDOC_ITEM Focus;
        int id;

        Focus = SYSLINK_GetFocusLink(infoPtr, &id);
        if(Focus != NULL)
        {
            PDOC_ITEM NewFocus, OldFocus;

            if(Prev)
                NewFocus = SYSLINK_GetPrevLink(infoPtr, Focus);
            else
                NewFocus = SYSLINK_GetNextLink(infoPtr, Focus);

            if(NewFocus != NULL)
            {
                OldFocus = SYSLINK_SetFocusLink(infoPtr, NewFocus);

                if(OldFocus != NewFocus)
                {
                    SYSLINK_RepaintLink(infoPtr, OldFocus);
                }
                SYSLINK_RepaintLink(infoPtr, NewFocus);
                return TRUE;
            }
        }
    }
    return FALSE;
}

/***********************************************************************
 *           SYSKEY_SelectNextPrevLink
 * Determines if there's a next or previous link to decide whether the control
 * should capture the tab key message
 */
static BOOL SYSLINK_NoNextLink (SYSLINK_INFO *infoPtr, BOOL Prev)
{
    PDOC_ITEM Focus, NewFocus;

    Focus = SYSLINK_GetFocusLink(infoPtr, NULL);
    if(Prev)
        NewFocus = SYSLINK_GetPrevLink(infoPtr, Focus);
    else
        NewFocus = SYSLINK_GetNextLink(infoPtr, Focus);

    return NewFocus == NULL;
}

/***********************************************************************
 *           SysLinkWindowProc
 */
static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
                                        WPARAM wParam, LPARAM lParam)
{
    SYSLINK_INFO *infoPtr;

    TRACE("hwnd=%p msg=%04x wparam=%x lParam=%lx\n", hwnd, message, wParam, lParam);

    infoPtr = (SYSLINK_INFO *)GetWindowLongPtrW(hwnd, 0);

    if (!infoPtr && message != WM_CREATE)
        goto HandleDefaultMessage;

    switch(message) {
    case WM_PRINTCLIENT:
    case WM_PAINT:
        return SYSLINK_Paint (infoPtr, (HDC)wParam);

    case WM_SETCURSOR:
    {
        LHITTESTINFO ht;
        DWORD mp = GetMessagePos();
        
        ht.pt.x = (short)LOWORD(mp);
        ht.pt.y = (short)HIWORD(mp);
        
        ScreenToClient(infoPtr->Self, &ht.pt);
        if(SYSLINK_HitTest (infoPtr, &ht))
        {
            SetCursor(LoadCursorW(0, (LPCWSTR)IDC_HAND));
            return TRUE;
        }
        /* let the default window proc handle this message */
        goto HandleDefaultMessage;
    }

    case WM_SIZE:
    {
        HDC hdc = GetDC(infoPtr->Self);
        if(hdc != NULL)
        {
          SYSLINK_Render(infoPtr, hdc);
          ReleaseDC(infoPtr->Self, hdc);
        }
        return 0;
    }

    case WM_GETFONT:
        return (LRESULT)infoPtr->Font;

    case WM_SETFONT:
        return (LRESULT)SYSLINK_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);

    case WM_SETTEXT:
        SYSLINK_SetText(infoPtr, (LPWSTR)lParam);
        goto HandleDefaultMessage;

    case WM_LBUTTONDOWN:
    {
        POINT pt;
        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        return SYSLINK_LButtonDown(infoPtr, wParam, &pt);
    }
    case WM_LBUTTONUP:
    {
        POINT pt;
        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        return SYSLINK_LButtonUp(infoPtr, wParam, &pt);
    }
    
    case WM_KEYDOWN:
    {
        switch(wParam)
        {
        case VK_RETURN:
            SYSLINK_OnEnter(infoPtr);
            return 0;
        case VK_TAB:
        {
            BOOL shift = GetKeyState(VK_SHIFT) & 0x8000;
            SYSKEY_SelectNextPrevLink(infoPtr, shift);
            return 0;
        }
        }
        goto HandleDefaultMessage;
    }
    
    case WM_GETDLGCODE:
    {
        LRESULT Ret = DLGC_HASSETSEL;
        int vk = (lParam != 0 ? (int)((LPMSG)lParam)->wParam : 0);
        switch(vk)
        {
        case VK_RETURN:
            Ret |= DLGC_WANTMESSAGE;
            break;
        case VK_TAB:
        {
            BOOL shift = GetKeyState(VK_SHIFT) & 0x8000;
            if(!SYSLINK_NoNextLink(infoPtr, shift))
            {
                Ret |= DLGC_WANTTAB;
            }
            else
            {
                Ret |= DLGC_WANTCHARS;
            }
            break;
        }
        }
        return Ret;
    }
    
    case WM_NCHITTEST:
    {
        POINT pt;
        RECT rc;
        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        
        GetClientRect(infoPtr->Self, &rc);
        ScreenToClient(infoPtr->Self, &pt);
        if(pt.x < 0 || pt.y < 0 || pt.x > rc.right || pt.y > rc.bottom)
        {
            return HTNOWHERE;
        }

        if(SYSLINK_LinkAtPt(infoPtr, &pt, NULL, FALSE))
        {
            return HTCLIENT;
        }
        
        return HTTRANSPARENT;
    }

    case LM_HITTEST:
        return SYSLINK_HitTest(infoPtr, (PLHITTESTINFO)lParam);

    case LM_SETITEM:
        return SYSLINK_SetItem(infoPtr, (PLITEM)lParam);

    case LM_GETITEM:
        return SYSLINK_GetItem(infoPtr, (PLITEM)lParam);

    case LM_GETIDEALHEIGHT:
        return SYSLINK_GetIdealHeight(infoPtr);

    case WM_SETFOCUS:
        return SYSLINK_SetFocus(infoPtr, (HWND)wParam);

    case WM_KILLFOCUS:
        return SYSLINK_KillFocus(infoPtr, (HWND)wParam);

    case WM_ENABLE:
	infoPtr->Style &= ~WS_DISABLED;
	infoPtr->Style |= (wParam ? 0 : WS_DISABLED);
	InvalidateRect (infoPtr->Self, NULL, FALSE);
	return 0;

    case WM_STYLECHANGED:
        if (wParam == GWL_STYLE)
        {
            infoPtr->Style = ((LPSTYLESTRUCT)lParam)->styleNew;

            InvalidateRect(infoPtr->Self, NULL, TRUE);
        }
        return 0;

    case WM_CREATE:
        /* allocate memory for info struct */
        infoPtr = Alloc (sizeof(SYSLINK_INFO));
        if (!infoPtr) return -1;
        SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

        /* initialize the info struct */
        infoPtr->Self = hwnd;
        infoPtr->Notify = ((LPCREATESTRUCTW)lParam)->hwndParent;
        infoPtr->Style = ((LPCREATESTRUCTW)lParam)->style;
        infoPtr->Font = 0;
        infoPtr->LinkFont = 0;
        infoPtr->Items = NULL;
        infoPtr->HasFocus = FALSE;
        infoPtr->MouseDownID = -1;
        infoPtr->TextColor = GetSysColor(COLOR_WINDOWTEXT);
        infoPtr->LinkColor = GetSysColor(COLOR_HIGHLIGHT);
        infoPtr->VisitedColor = GetSysColor(COLOR_HIGHLIGHT);
        infoPtr->BreakChar = ' ';
        TRACE("SysLink Ctrl creation, hwnd=%p\n", hwnd);
        SYSLINK_SetText(infoPtr, ((LPCREATESTRUCTW)lParam)->lpszName);
        return 0;

    case WM_DESTROY:
        TRACE("SysLink Ctrl destruction, hwnd=%p\n", hwnd);
        SYSLINK_ClearDoc(infoPtr);
        if(infoPtr->Font != 0) DeleteObject(infoPtr->Font);
        if(infoPtr->LinkFont != 0) DeleteObject(infoPtr->LinkFont);
        SetWindowLongPtrW(hwnd, 0, 0);
        Free (infoPtr);
        return 0;

    default:
HandleDefaultMessage:
        if ((message >= WM_USER) && (message < WM_APP))
        {
	        ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam );
        }
        return DefWindowProcW(hwnd, message, wParam, lParam);
    }
}


/***********************************************************************
 * SYSLINK_Register [Internal]
 *
 * Registers the SysLink window class.
 */
VOID SYSLINK_Register (void)
{
    WNDCLASSW wndClass;

    ZeroMemory (&wndClass, sizeof(wndClass));
    wndClass.style         = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
    wndClass.lpfnWndProc   = SysLinkWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof (SYSLINK_INFO *);
    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
    wndClass.lpszClassName = WC_LINK;

    RegisterClassW (&wndClass);
}


/***********************************************************************
 * SYSLINK_Unregister [Internal]
 *
 * Unregisters the SysLink window class.
 */
VOID SYSLINK_Unregister (void)
{
    UnregisterClassW (WC_LINK, NULL);
}
