/*
 * 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 <stdio.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"
#include "regproc.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};

    WCHAR *lpszLine = heap_xalloc((cbData * 3 + pad * 3 + DIV_SPACES + cbData + 1) * sizeof(WCHAR));
    LONG i;

    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;
        heap_free(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;

    heap_free(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)
{
    heap_free(infoPtr->pData);
    infoPtr->cbData = 0;

    infoPtr->pData = heap_xalloc(cbData);
    memcpy(infoPtr->pData, pData, cbData);
    infoPtr->cbData = cbData;

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

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 = heap_xrealloc(infoPtr->pData, infoPtr->cbData + 1);

            /* 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;
    heap_free(infoPtr->pData);
    /* free info data */
    heap_free(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 = heap_xalloc(sizeof(HEXEDIT_INFO));
    memset(infoPtr, 0, 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 = heap_xalloc(i);
        WCHAR *lpszLine;
        SIZE size;

        memset(pData, 0, i);
        lpszLine = HexEdit_GetLineText(pData, i, 0);
        GetTextExtentPoint32W(hdc, lpszLine, lstrlenW(lpszLine), &size);
        heap_free(lpszLine);
        heap_free(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);
}
