/*
 * Hex Edit control
 *
 * Copyright 2005 Robert Shearman
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * TODO:
 * - Selection support
 * - Cut, copy and paste
 * - Mouse support
 */
 
#include <stdarg.h>
#include <string.h>
#include <assert.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"

#include "main.h"

/* spaces dividing hex and ASCII */
#define DIV_SPACES 4

typedef struct tagHEXEDIT_INFO
{
    HWND  hwndSelf;
    HFONT hFont;
    BOOL  bFocus : 1;
    BOOL  bFocusHex : 1; /* TRUE if focus is on hex, FALSE if focus on ASCII */
    BOOL  bInsert : 1; /* insert mode if TRUE, overwrite mode if FALSE */
    INT   nHeight; /* height of text */
    INT   nCaretPos; /* caret pos in nibbles */
    BYTE *pData;
    INT   cbData;
    INT   nBytesPerLine; /* bytes of hex to display per line of the control */
    INT   nScrollPos; /* first visible line */
} HEXEDIT_INFO;

const WCHAR szHexEditClass[] = {'H','e','x','E','d','i','t',0};

static inline LRESULT HexEdit_SetFont (HEXEDIT_INFO *infoPtr, HFONT hFont, BOOL redraw);

static inline BYTE hexchar_to_byte(WCHAR ch)
{
    if (ch >= '0' && ch <= '9')
        return ch - '0';
    else if (ch >= 'a' && ch <= 'f')
        return ch - 'a' + 10;
    else if (ch >= 'A' && ch <= 'F')
        return ch - 'A' + 10;
    else
        return -1;
}

static LPWSTR HexEdit_GetLineText(BYTE *pData, LONG cbData, LONG pad)
{
    static const WCHAR percent_02xW[] = {'%','0','2','X',' ',0};

    LPWSTR lpszLine = HeapAlloc(GetProcessHeap(), 0,
        (cbData * 3 + pad * 3 + DIV_SPACES + cbData + 1) * sizeof(WCHAR));
    LONG i;

    if (!lpszLine)
        return NULL;

    for (i = 0; i < cbData; i++)
        wsprintfW(lpszLine + i*3, percent_02xW, pData[i]);
    for (i = 0; i < pad * 3; i++)
        lpszLine[cbData * 3 + i] = ' ';

    for (i = 0; i < DIV_SPACES; i++)
        lpszLine[cbData * 3 + pad * 3 + i] = ' ';

    /* attempt an ASCII representation if the characters are printable,
     * otherwise display a '.' */
    for (i = 0; i < cbData; i++)
    {
        /* (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER) */
        if (isprint(pData[i]))
            lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + i] = pData[i];
        else
            lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + i] = '.';
    }
    lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + cbData] = 0;
    return lpszLine;
}

static void
HexEdit_Paint(HEXEDIT_INFO *infoPtr)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(infoPtr->hwndSelf, &ps);
    INT nXStart, nYStart;
    COLORREF clrOldText;
    HFONT hOldFont;
    BYTE *pData;
    INT iMode;
    LONG lByteOffset = infoPtr->nScrollPos * infoPtr->nBytesPerLine;

    /* Make a gap from the frame */
    nXStart = GetSystemMetrics(SM_CXBORDER);
    nYStart = GetSystemMetrics(SM_CYBORDER);

    if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
        clrOldText = SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
    else
        clrOldText = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));

    iMode = SetBkMode(hdc, TRANSPARENT);
    hOldFont = SelectObject(hdc, infoPtr->hFont);
        
    for (pData = infoPtr->pData + lByteOffset; pData < infoPtr->pData + infoPtr->cbData; pData += infoPtr->nBytesPerLine)
    {
        LPWSTR lpszLine;
        LONG nLineLen = min((LONG)((infoPtr->pData + infoPtr->cbData) - pData),
            infoPtr->nBytesPerLine);

        lpszLine = HexEdit_GetLineText(pData, nLineLen, infoPtr->nBytesPerLine - nLineLen);

        /* FIXME: draw hex <-> ASCII mapping highlighted? */
        TextOutW(hdc, nXStart, nYStart, lpszLine, infoPtr->nBytesPerLine * 3 + DIV_SPACES + nLineLen);

        nYStart += infoPtr->nHeight;
        HeapFree(GetProcessHeap(), 0, lpszLine);
    }

    SelectObject(hdc, hOldFont);
    SetBkMode(hdc, iMode);
    SetTextColor(hdc, clrOldText);

    EndPaint(infoPtr->hwndSelf, &ps);
}

static void
HexEdit_UpdateCaret(HEXEDIT_INFO *infoPtr)
{
    HDC hdc;
    HFONT hOldFont;
    SIZE size;
    INT nCaretBytePos = infoPtr->nCaretPos/2;
    INT nByteLinePos = nCaretBytePos % infoPtr->nBytesPerLine;
    INT nLine = nCaretBytePos / infoPtr->nBytesPerLine;
    LONG nLineLen = min(infoPtr->cbData - nLine * infoPtr->nBytesPerLine, infoPtr->nBytesPerLine);
    LPWSTR lpszLine = HexEdit_GetLineText(infoPtr->pData + nLine * infoPtr->nBytesPerLine, nLineLen, infoPtr->nBytesPerLine - nLineLen);
    INT nCharOffset;

    /* calculate offset of character caret is on in the line */
    if (infoPtr->bFocusHex)
        nCharOffset = nByteLinePos*3 + infoPtr->nCaretPos % 2;
    else
        nCharOffset = infoPtr->nBytesPerLine*3 + DIV_SPACES + nByteLinePos;

    hdc = GetDC(infoPtr->hwndSelf);
    hOldFont = SelectObject(hdc, infoPtr->hFont);

    GetTextExtentPoint32W(hdc, lpszLine, nCharOffset, &size);

    SelectObject(hdc, hOldFont);
    ReleaseDC(infoPtr->hwndSelf, hdc);

    if (!nLineLen) size.cx = 0;

    HeapFree(GetProcessHeap(), 0, lpszLine);

    SetCaretPos(
        GetSystemMetrics(SM_CXBORDER) + size.cx,
        GetSystemMetrics(SM_CYBORDER) + (nLine - infoPtr->nScrollPos) * infoPtr->nHeight);
}

static void
HexEdit_UpdateScrollbars(HEXEDIT_INFO *infoPtr)
{
    RECT rcClient;
    INT nLines = infoPtr->cbData / infoPtr->nBytesPerLine;
    INT nVisibleLines;
    SCROLLINFO si;

    GetClientRect(infoPtr->hwndSelf, &rcClient);
    InflateRect(&rcClient, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));

    nVisibleLines = (rcClient.bottom - rcClient.top) / infoPtr->nHeight;
    si.cbSize = sizeof(si);
    si.fMask = SIF_RANGE | SIF_PAGE;
    si.nMin = 0;
    si.nMax = max(nLines - nVisibleLines, nLines);
    si.nPage = nVisibleLines;
    SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, TRUE);
}

static void
HexEdit_EnsureVisible(HEXEDIT_INFO *infoPtr, INT nCaretPos)
{
    INT nLine = nCaretPos / (2 * infoPtr->nBytesPerLine);
    SCROLLINFO si;

    si.cbSize = sizeof(si);
    si.fMask  = SIF_POS | SIF_PAGE;
    GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
    if (nLine < si.nPos)
        si.nPos = nLine;
    else if (nLine >= si.nPos + si.nPage)
        si.nPos = nLine - si.nPage + 1;
    else
        return;
    si.fMask = SIF_POS;

    SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, FALSE);
    SendMessageW(infoPtr->hwndSelf, WM_VSCROLL, MAKELONG(SB_THUMBPOSITION, 0), 0);
}


static LRESULT
HexEdit_SetData(HEXEDIT_INFO *infoPtr, INT cbData, const BYTE *pData)
{
    HeapFree(GetProcessHeap(), 0, infoPtr->pData);
    infoPtr->cbData = 0;

    infoPtr->pData = HeapAlloc(GetProcessHeap(), 0, cbData);
    if (infoPtr->pData)
    {
        memcpy(infoPtr->pData, pData, cbData);
        infoPtr->cbData = cbData;

        infoPtr->nCaretPos = 0;
        HexEdit_UpdateScrollbars(infoPtr);
        HexEdit_UpdateCaret(infoPtr);
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
        return TRUE;
    }
    return FALSE;
}

static LRESULT
HexEdit_GetData(HEXEDIT_INFO *infoPtr, INT cbData, BYTE *pData)
{
    if (pData)
        memcpy(pData, infoPtr->pData, min(cbData, infoPtr->cbData));
    return infoPtr->cbData;
}

static inline LRESULT
HexEdit_Char (HEXEDIT_INFO *infoPtr, WCHAR ch)
{
    INT nCaretBytePos = infoPtr->nCaretPos/2;

    assert(nCaretBytePos >= 0);

    /* backspace is special */
    if (ch == '\b')
    {
        if (infoPtr->nCaretPos == 0)
            return 0;

        /* if at end of byte then delete the whole byte */
        if (infoPtr->bFocusHex && (infoPtr->nCaretPos % 2 == 0))
        {
            memmove(infoPtr->pData + nCaretBytePos - 1,
                    infoPtr->pData + nCaretBytePos,
                    infoPtr->cbData - nCaretBytePos);
            infoPtr->cbData--;
            infoPtr->nCaretPos -= 2; /* backtrack two nibble */
        }
        else /* blank upper nibble */
        {
            infoPtr->pData[nCaretBytePos] &= 0x0f;
            infoPtr->nCaretPos--; /* backtrack one nibble */
        }
    }
    else
    {
        if (infoPtr->bFocusHex && hexchar_to_byte(ch) == (BYTE)-1)
        {
            MessageBeep(MB_ICONWARNING);
            return 0;
        }
    
        if ((infoPtr->bInsert && (infoPtr->nCaretPos % 2 == 0)) || (nCaretBytePos >= infoPtr->cbData))
        {
            /* make room for another byte */
            infoPtr->cbData++;
            infoPtr->pData = HeapReAlloc(GetProcessHeap(), 0, infoPtr->pData, infoPtr->cbData + 1);
            if (!infoPtr->pData) return 0;
            /* move everything after caret up one byte */
            memmove(infoPtr->pData + nCaretBytePos + 1,
                    infoPtr->pData + nCaretBytePos,
                    infoPtr->cbData - nCaretBytePos);
            /* zero new byte */
            infoPtr->pData[nCaretBytePos] = 0x0;
        }
    
        /* overwrite a byte */
    
        assert(nCaretBytePos < infoPtr->cbData);
    
        if (infoPtr->bFocusHex)
        {
            BYTE orig_byte = infoPtr->pData[nCaretBytePos];
            BYTE digit = hexchar_to_byte(ch);
            if (infoPtr->nCaretPos % 2) /* set low nibble */
                infoPtr->pData[nCaretBytePos] = (orig_byte & 0xf0) | digit;
            else /* set high nibble */
                infoPtr->pData[nCaretBytePos] = (orig_byte & 0x0f) | digit << 4;
            infoPtr->nCaretPos++; /* advance one nibble */
        }
        else
        {
            infoPtr->pData[nCaretBytePos] = (BYTE)ch;
            infoPtr->nCaretPos += 2; /* advance two nibbles */
        }
    }

    HexEdit_UpdateScrollbars(infoPtr);
    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    HexEdit_UpdateCaret(infoPtr);
    HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos);
    return 0;
}

static inline LRESULT
HexEdit_Create (HEXEDIT_INFO *infoPtr, LPCREATESTRUCTW lpcs)
{
    HexEdit_SetFont(infoPtr, GetStockObject(SYSTEM_FONT), FALSE);
    HexEdit_UpdateScrollbars(infoPtr);

    return 0;
}


static inline LRESULT
HexEdit_Destroy (HEXEDIT_INFO *infoPtr)
{
    HWND hwnd = infoPtr->hwndSelf;
    HeapFree(GetProcessHeap(), 0, infoPtr->pData);
    /* free info data */
    HeapFree(GetProcessHeap(), 0, infoPtr);
    SetWindowLongPtrW(hwnd, 0, 0);
    return 0;
}


static inline LRESULT
HexEdit_EraseBackground (HEXEDIT_INFO *infoPtr, HDC hdc)
{
    HBRUSH hBrush, hSolidBrush = NULL;
    RECT   rc;

    if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
        hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    else
    {
        hBrush = (HBRUSH)SendMessageW(GetParent(infoPtr->hwndSelf), WM_CTLCOLOREDIT,
                                      (WPARAM)hdc, (LPARAM)infoPtr->hwndSelf);
        if (!hBrush)
            hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
    }

    GetClientRect (infoPtr->hwndSelf, &rc);

    FillRect (hdc, &rc, hBrush);

    if (hSolidBrush)
        DeleteObject(hSolidBrush);

    return -1;
}


static inline LRESULT
HexEdit_GetFont (HEXEDIT_INFO *infoPtr)
{
    return (LRESULT)infoPtr->hFont;
}

static inline LRESULT
HexEdit_KeyDown (HEXEDIT_INFO *infoPtr, DWORD key, DWORD flags)
{
    INT nInc = (infoPtr->bFocusHex) ? 1 : 2;
    SCROLLINFO si;

    switch (key)
    {
    case VK_LEFT:
        infoPtr->nCaretPos -= nInc;
        if (infoPtr->nCaretPos < 0)
            infoPtr->nCaretPos = 0;
        break;
    case VK_RIGHT:
        infoPtr->nCaretPos += nInc;
        if (infoPtr->nCaretPos > infoPtr->cbData*2)
            infoPtr->nCaretPos = infoPtr->cbData*2;
        break;
    case VK_UP:
        if ((infoPtr->nCaretPos - infoPtr->nBytesPerLine*2) >= 0)
            infoPtr->nCaretPos -= infoPtr->nBytesPerLine*2;
        break;
    case VK_DOWN:
        if ((infoPtr->nCaretPos + infoPtr->nBytesPerLine*2) <= infoPtr->cbData*2)
            infoPtr->nCaretPos += infoPtr->nBytesPerLine*2;
        break;
    case VK_HOME:
        infoPtr->nCaretPos = 0;
        break;
    case VK_END:
        infoPtr->nCaretPos = infoPtr->cbData*2;
        break;
    case VK_PRIOR: /* page up */
        si.cbSize = sizeof(si);
        si.fMask = SIF_PAGE;
        GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
        if ((infoPtr->nCaretPos - (INT)si.nPage*infoPtr->nBytesPerLine*2) >= 0)
            infoPtr->nCaretPos -= si.nPage*infoPtr->nBytesPerLine*2;
        else
            infoPtr->nCaretPos = 0;
        break;
    case VK_NEXT: /* page down */
        si.cbSize = sizeof(si);
        si.fMask = SIF_PAGE;
        GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
        if ((infoPtr->nCaretPos + (INT)si.nPage*infoPtr->nBytesPerLine*2) <= infoPtr->cbData*2)
            infoPtr->nCaretPos += si.nPage*infoPtr->nBytesPerLine*2;
        else
            infoPtr->nCaretPos = infoPtr->cbData*2;
        break;
    default:
        return 0;
    }

    HexEdit_UpdateCaret(infoPtr);
    HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos);

    return 0;
}


static inline LRESULT
HexEdit_KillFocus (HEXEDIT_INFO *infoPtr, HWND receiveFocus)
{
    infoPtr->bFocus = FALSE;
    DestroyCaret();

    return 0;
}


static inline LRESULT
HexEdit_LButtonDown (HEXEDIT_INFO *infoPtr)
{
    SetFocus(infoPtr->hwndSelf);

    /* FIXME: hittest and set caret */

    return 0;
}


static inline LRESULT HexEdit_NCCreate (HWND hwnd, LPCREATESTRUCTW lpcs)
{
    HEXEDIT_INFO *infoPtr;
    SetWindowLongW(hwnd, GWL_EXSTYLE,
                   lpcs->dwExStyle | WS_EX_CLIENTEDGE);

    /* allocate memory for info structure */
    infoPtr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HEXEDIT_INFO));
    SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);

    /* initialize info structure */
    infoPtr->nCaretPos = 0;
    infoPtr->hwndSelf = hwnd;
    infoPtr->nBytesPerLine = 2;
    infoPtr->bFocusHex = TRUE;
    infoPtr->bInsert = TRUE;

    return DefWindowProcW(infoPtr->hwndSelf, WM_NCCREATE, 0, (LPARAM)lpcs);
}

static inline LRESULT
HexEdit_SetFocus (HEXEDIT_INFO *infoPtr, HWND lostFocus)
{
    infoPtr->bFocus = TRUE;

    CreateCaret(infoPtr->hwndSelf, NULL, 1, infoPtr->nHeight);
    HexEdit_UpdateCaret(infoPtr);
    ShowCaret(infoPtr->hwndSelf);

    return 0;
}


static inline LRESULT
HexEdit_SetFont (HEXEDIT_INFO *infoPtr, HFONT hFont, BOOL redraw)
{
    TEXTMETRICW tm;
    HDC hdc;
    HFONT hOldFont = NULL;
    LONG i;
    RECT rcClient;

    infoPtr->hFont = hFont;

    hdc = GetDC(infoPtr->hwndSelf);
    if (infoPtr->hFont)
        hOldFont = SelectObject(hdc, infoPtr->hFont);

    GetTextMetricsW(hdc, &tm);
    infoPtr->nHeight = tm.tmHeight + tm.tmExternalLeading;

    GetClientRect(infoPtr->hwndSelf, &rcClient);

    for (i = 0; ; i++)
    {
        BYTE *pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, i);
        LPWSTR lpszLine = HexEdit_GetLineText(pData, i, 0);
        SIZE size;
        GetTextExtentPoint32W(hdc, lpszLine, lstrlenW(lpszLine), &size);
        HeapFree(GetProcessHeap(), 0, lpszLine);
        HeapFree(GetProcessHeap(), 0, pData);
        if (size.cx > (rcClient.right - rcClient.left))
        {
            infoPtr->nBytesPerLine = i - 1;
            break;
        }
    }

    if (infoPtr->hFont)
        SelectObject(hdc, hOldFont);
    ReleaseDC (infoPtr->hwndSelf, hdc);

    if (redraw)
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}

static inline LRESULT
HexEdit_VScroll (HEXEDIT_INFO *infoPtr, INT action)
{
    SCROLLINFO si;

    /* get all scroll bar info */
    si.cbSize = sizeof(si);
    si.fMask  = SIF_ALL;
    GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);

    switch (LOWORD(action))
    {
    case SB_TOP: /* user pressed the home key */
        si.nPos = si.nMin;
        break;

    case SB_BOTTOM: /* user pressed the end key */
        si.nPos = si.nMax;
        break;

    case SB_LINEUP: /* user clicked the up arrow */
        si.nPos -= 1;
        break;

    case SB_LINEDOWN: /* user clicked the down arrow */
        si.nPos += 1;
        break;

    case SB_PAGEUP: /* user clicked the scroll bar above the scroll thumb */
        si.nPos -= si.nPage;
        break;

    case SB_PAGEDOWN: /* user clicked the scroll bar below the scroll thumb */
        si.nPos += si.nPage;
        break;

    case SB_THUMBTRACK: /* user dragged the scroll thumb */
        si.nPos = si.nTrackPos;
        break;

    default:
        break; 
    }

    /* set the position and then retrieve it to let the system handle the
     * cases where the position is out of range */
    si.fMask = SIF_POS;
    SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, TRUE);
    GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);

    if (si.nPos != infoPtr->nScrollPos)
    {                    
        ScrollWindow(infoPtr->hwndSelf, 0, infoPtr->nHeight * (infoPtr->nScrollPos - si.nPos), NULL, NULL);
        infoPtr->nScrollPos = si.nPos;
        UpdateWindow(infoPtr->hwndSelf);

        /* need to update caret position since it depends on the scroll position */
        HexEdit_UpdateCaret(infoPtr);
    }
    return 0;
}


static LRESULT WINAPI
HexEdit_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HEXEDIT_INFO *infoPtr = (HEXEDIT_INFO *)GetWindowLongPtrW(hwnd, 0);

    if (!infoPtr && (uMsg != WM_NCCREATE))
        return DefWindowProcW(hwnd, uMsg, wParam, lParam);

    switch (uMsg)
    {
        case HEM_SETDATA:
            return HexEdit_SetData (infoPtr, (INT)wParam, (const BYTE *)lParam);

        case HEM_GETDATA:
            return HexEdit_GetData (infoPtr, (INT)wParam, (BYTE *)lParam);

	case WM_CHAR:
	    return HexEdit_Char (infoPtr, (WCHAR)wParam);

	case WM_CREATE:
	    return HexEdit_Create (infoPtr, (LPCREATESTRUCTW)lParam);

	case WM_DESTROY:
	    return HexEdit_Destroy (infoPtr);

	case WM_ERASEBKGND:
	    return HexEdit_EraseBackground (infoPtr, (HDC)wParam);

	case WM_GETDLGCODE:
	    return DLGC_WANTCHARS | DLGC_WANTARROWS;

	case WM_GETFONT:
	    return HexEdit_GetFont (infoPtr);

	case WM_KEYDOWN:
	    return HexEdit_KeyDown (infoPtr, wParam, lParam);

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

	case WM_LBUTTONDOWN:
	    return HexEdit_LButtonDown (infoPtr);

	case WM_NCCREATE:
	    return HexEdit_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);

	case WM_PAINT:
	    HexEdit_Paint(infoPtr);
	    return 0;

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

	case WM_SETFONT:
	    return HexEdit_SetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));

        case WM_VSCROLL:
            return HexEdit_VScroll (infoPtr, (INT)wParam);

	default:
	    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

void HexEdit_Register(void)
{
    WNDCLASSW wndClass;

    ZeroMemory(&wndClass, sizeof(WNDCLASSW));
    wndClass.style         = 0;
    wndClass.lpfnWndProc   = HexEdit_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(HEXEDIT_INFO *);
    wndClass.hCursor       = NULL;
    wndClass.hbrBackground = NULL;
    wndClass.lpszClassName = szHexEditClass;

    RegisterClassW(&wndClass);
}
