/*
 * 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;

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

static inline BYTE hexchar_to_byte(TCHAR 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 LPTSTR HexEdit_GetLineText(BYTE *pData, LONG cbData, LONG pad)
{
    LPTSTR lpszLine = HeapAlloc(GetProcessHeap(), 0,
        (cbData * 3 + pad * 3 + DIV_SPACES + cbData + 1) * sizeof(TCHAR));
    LONG i;

    if (!lpszLine)
        return NULL;

    for (i = 0; i < cbData; i++)
        wsprintf(lpszLine + i*3, TEXT("%02X "), 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 (GetWindowLong(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)
    {
        LPTSTR 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? */
        TextOut(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);
    LPTSTR 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);

    GetTextExtentPoint32(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);
    SendMessage(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, TCHAR 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, LPCREATESTRUCT 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);
    SetWindowLongPtr(hwnd, 0, 0);
    return 0;
}


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

    if (GetWindowLong(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
        hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    else
    {
        hBrush = (HBRUSH)SendMessage(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, LPCREATESTRUCT lpcs)
{
    HEXEDIT_INFO *infoPtr;
    SetWindowLong(hwnd, GWL_EXSTYLE, 
                  lpcs->dwExStyle | WS_EX_CLIENTEDGE);

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

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

    return DefWindowProc(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)
{
    TEXTMETRIC 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);

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

    GetClientRect(infoPtr->hwndSelf, &rcClient);

    for (i = 0; ; i++)
    {
        BYTE *pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, i);
        LPTSTR lpszLine = HexEdit_GetLineText(pData, i, 0);
        SIZE size;
        GetTextExtentPoint32(hdc, lpszLine, lstrlen(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 *)GetWindowLongPtr (hwnd, 0);

    if (!infoPtr && (uMsg != WM_NCCREATE))
        return DefWindowProc(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, (TCHAR)wParam);

	case WM_CREATE:
	    return HexEdit_Create (infoPtr, (LPCREATESTRUCT)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, (LPCREATESTRUCT)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 DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

void HexEdit_Register(void)
{
    WNDCLASS wndClass;

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

    RegisterClass(&wndClass);
}
