comctl32/tests: Enable more ListView tests on Comctl32 v6.
[wine.git] / programs / regedit / hexedit.c
blob3f05aa6d65765cd3c84b82bd009c42ab32f1f801
1 /*
2 * Hex Edit control
4 * Copyright 2005 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * TODO:
21 * - Selection support
22 * - Cut, copy and paste
23 * - Mouse support
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <assert.h>
31 #include "windef.h"
32 #include "winbase.h"
33 #include "wingdi.h"
34 #include "winuser.h"
35 #include "winnls.h"
36 #include "commctrl.h"
38 #include "main.h"
39 #include "regproc.h"
41 /* spaces dividing hex and ASCII */
42 #define DIV_SPACES 4
44 typedef struct tagHEXEDIT_INFO
46 HWND hwndSelf;
47 HFONT hFont;
48 BOOL bFocus : 1;
49 BOOL bFocusHex : 1; /* TRUE if focus is on hex, FALSE if focus on ASCII */
50 BOOL bInsert : 1; /* insert mode if TRUE, overwrite mode if FALSE */
51 INT nHeight; /* height of text */
52 INT nCaretPos; /* caret pos in nibbles */
53 BYTE *pData;
54 INT cbData;
55 INT nBytesPerLine; /* bytes of hex to display per line of the control */
56 INT nScrollPos; /* first visible line */
57 } HEXEDIT_INFO;
59 const WCHAR szHexEditClass[] = {'H','e','x','E','d','i','t',0};
61 static inline LRESULT HexEdit_SetFont (HEXEDIT_INFO *infoPtr, HFONT hFont, BOOL redraw);
63 static inline BYTE hexchar_to_byte(WCHAR ch)
65 if (ch >= '0' && ch <= '9')
66 return ch - '0';
67 else if (ch >= 'a' && ch <= 'f')
68 return ch - 'a' + 10;
69 else if (ch >= 'A' && ch <= 'F')
70 return ch - 'A' + 10;
71 else
72 return -1;
75 static LPWSTR HexEdit_GetLineText(BYTE *pData, LONG cbData, LONG pad)
77 static const WCHAR percent_02xW[] = {'%','0','2','X',' ',0};
79 WCHAR *lpszLine = heap_xalloc((cbData * 3 + pad * 3 + DIV_SPACES + cbData + 1) * sizeof(WCHAR));
80 LONG i;
82 for (i = 0; i < cbData; i++)
83 wsprintfW(lpszLine + i*3, percent_02xW, pData[i]);
84 for (i = 0; i < pad * 3; i++)
85 lpszLine[cbData * 3 + i] = ' ';
87 for (i = 0; i < DIV_SPACES; i++)
88 lpszLine[cbData * 3 + pad * 3 + i] = ' ';
90 /* attempt an ASCII representation if the characters are printable,
91 * otherwise display a '.' */
92 for (i = 0; i < cbData; i++)
94 /* (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER) */
95 if (isprint(pData[i]))
96 lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + i] = pData[i];
97 else
98 lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + i] = '.';
100 lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + cbData] = 0;
101 return lpszLine;
104 static void
105 HexEdit_Paint(HEXEDIT_INFO *infoPtr)
107 PAINTSTRUCT ps;
108 HDC hdc = BeginPaint(infoPtr->hwndSelf, &ps);
109 INT nXStart, nYStart;
110 COLORREF clrOldText;
111 HFONT hOldFont;
112 BYTE *pData;
113 INT iMode;
114 LONG lByteOffset = infoPtr->nScrollPos * infoPtr->nBytesPerLine;
116 /* Make a gap from the frame */
117 nXStart = GetSystemMetrics(SM_CXBORDER);
118 nYStart = GetSystemMetrics(SM_CYBORDER);
120 if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
121 clrOldText = SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
122 else
123 clrOldText = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
125 iMode = SetBkMode(hdc, TRANSPARENT);
126 hOldFont = SelectObject(hdc, infoPtr->hFont);
128 for (pData = infoPtr->pData + lByteOffset; pData < infoPtr->pData + infoPtr->cbData; pData += infoPtr->nBytesPerLine)
130 LPWSTR lpszLine;
131 LONG nLineLen = min((LONG)((infoPtr->pData + infoPtr->cbData) - pData),
132 infoPtr->nBytesPerLine);
134 lpszLine = HexEdit_GetLineText(pData, nLineLen, infoPtr->nBytesPerLine - nLineLen);
136 /* FIXME: draw hex <-> ASCII mapping highlighted? */
137 TextOutW(hdc, nXStart, nYStart, lpszLine, infoPtr->nBytesPerLine * 3 + DIV_SPACES + nLineLen);
139 nYStart += infoPtr->nHeight;
140 heap_free(lpszLine);
143 SelectObject(hdc, hOldFont);
144 SetBkMode(hdc, iMode);
145 SetTextColor(hdc, clrOldText);
147 EndPaint(infoPtr->hwndSelf, &ps);
150 static void
151 HexEdit_UpdateCaret(HEXEDIT_INFO *infoPtr)
153 HDC hdc;
154 HFONT hOldFont;
155 SIZE size;
156 INT nCaretBytePos = infoPtr->nCaretPos/2;
157 INT nByteLinePos = nCaretBytePos % infoPtr->nBytesPerLine;
158 INT nLine = nCaretBytePos / infoPtr->nBytesPerLine;
159 LONG nLineLen = min(infoPtr->cbData - nLine * infoPtr->nBytesPerLine, infoPtr->nBytesPerLine);
160 LPWSTR lpszLine = HexEdit_GetLineText(infoPtr->pData + nLine * infoPtr->nBytesPerLine, nLineLen, infoPtr->nBytesPerLine - nLineLen);
161 INT nCharOffset;
163 /* calculate offset of character caret is on in the line */
164 if (infoPtr->bFocusHex)
165 nCharOffset = nByteLinePos*3 + infoPtr->nCaretPos % 2;
166 else
167 nCharOffset = infoPtr->nBytesPerLine*3 + DIV_SPACES + nByteLinePos;
169 hdc = GetDC(infoPtr->hwndSelf);
170 hOldFont = SelectObject(hdc, infoPtr->hFont);
172 GetTextExtentPoint32W(hdc, lpszLine, nCharOffset, &size);
174 SelectObject(hdc, hOldFont);
175 ReleaseDC(infoPtr->hwndSelf, hdc);
177 if (!nLineLen) size.cx = 0;
179 heap_free(lpszLine);
181 SetCaretPos(
182 GetSystemMetrics(SM_CXBORDER) + size.cx,
183 GetSystemMetrics(SM_CYBORDER) + (nLine - infoPtr->nScrollPos) * infoPtr->nHeight);
186 static void
187 HexEdit_UpdateScrollbars(HEXEDIT_INFO *infoPtr)
189 RECT rcClient;
190 INT nLines = infoPtr->cbData / infoPtr->nBytesPerLine;
191 INT nVisibleLines;
192 SCROLLINFO si;
194 GetClientRect(infoPtr->hwndSelf, &rcClient);
195 InflateRect(&rcClient, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
197 nVisibleLines = (rcClient.bottom - rcClient.top) / infoPtr->nHeight;
198 si.cbSize = sizeof(si);
199 si.fMask = SIF_RANGE | SIF_PAGE;
200 si.nMin = 0;
201 si.nMax = max(nLines - nVisibleLines, nLines);
202 si.nPage = nVisibleLines;
203 SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, TRUE);
206 static void
207 HexEdit_EnsureVisible(HEXEDIT_INFO *infoPtr, INT nCaretPos)
209 INT nLine = nCaretPos / (2 * infoPtr->nBytesPerLine);
210 SCROLLINFO si;
212 si.cbSize = sizeof(si);
213 si.fMask = SIF_POS | SIF_PAGE;
214 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
215 if (nLine < si.nPos)
216 si.nPos = nLine;
217 else if (nLine >= si.nPos + si.nPage)
218 si.nPos = nLine - si.nPage + 1;
219 else
220 return;
221 si.fMask = SIF_POS;
223 SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, FALSE);
224 SendMessageW(infoPtr->hwndSelf, WM_VSCROLL, MAKELONG(SB_THUMBPOSITION, 0), 0);
228 static LRESULT
229 HexEdit_SetData(HEXEDIT_INFO *infoPtr, INT cbData, const BYTE *pData)
231 heap_free(infoPtr->pData);
232 infoPtr->cbData = 0;
234 infoPtr->pData = heap_xalloc(cbData);
235 memcpy(infoPtr->pData, pData, cbData);
236 infoPtr->cbData = cbData;
238 infoPtr->nCaretPos = 0;
239 HexEdit_UpdateScrollbars(infoPtr);
240 HexEdit_UpdateCaret(infoPtr);
241 InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
242 return TRUE;
245 static LRESULT
246 HexEdit_GetData(HEXEDIT_INFO *infoPtr, INT cbData, BYTE *pData)
248 if (pData)
249 memcpy(pData, infoPtr->pData, min(cbData, infoPtr->cbData));
250 return infoPtr->cbData;
253 static inline LRESULT
254 HexEdit_Char (HEXEDIT_INFO *infoPtr, WCHAR ch)
256 INT nCaretBytePos = infoPtr->nCaretPos/2;
258 assert(nCaretBytePos >= 0);
260 /* backspace is special */
261 if (ch == '\b')
263 if (infoPtr->nCaretPos == 0)
264 return 0;
266 /* if at end of byte then delete the whole byte */
267 if (infoPtr->bFocusHex && (infoPtr->nCaretPos % 2 == 0))
269 memmove(infoPtr->pData + nCaretBytePos - 1,
270 infoPtr->pData + nCaretBytePos,
271 infoPtr->cbData - nCaretBytePos);
272 infoPtr->cbData--;
273 infoPtr->nCaretPos -= 2; /* backtrack two nibble */
275 else /* blank upper nibble */
277 infoPtr->pData[nCaretBytePos] &= 0x0f;
278 infoPtr->nCaretPos--; /* backtrack one nibble */
281 else
283 if (infoPtr->bFocusHex && hexchar_to_byte(ch) == (BYTE)-1)
285 MessageBeep(MB_ICONWARNING);
286 return 0;
289 if ((infoPtr->bInsert && (infoPtr->nCaretPos % 2 == 0)) || (nCaretBytePos >= infoPtr->cbData))
291 /* make room for another byte */
292 infoPtr->cbData++;
293 infoPtr->pData = heap_xrealloc(infoPtr->pData, infoPtr->cbData + 1);
295 /* move everything after caret up one byte */
296 memmove(infoPtr->pData + nCaretBytePos + 1,
297 infoPtr->pData + nCaretBytePos,
298 infoPtr->cbData - nCaretBytePos);
299 /* zero new byte */
300 infoPtr->pData[nCaretBytePos] = 0x0;
303 /* overwrite a byte */
305 assert(nCaretBytePos < infoPtr->cbData);
307 if (infoPtr->bFocusHex)
309 BYTE orig_byte = infoPtr->pData[nCaretBytePos];
310 BYTE digit = hexchar_to_byte(ch);
311 if (infoPtr->nCaretPos % 2) /* set low nibble */
312 infoPtr->pData[nCaretBytePos] = (orig_byte & 0xf0) | digit;
313 else /* set high nibble */
314 infoPtr->pData[nCaretBytePos] = (orig_byte & 0x0f) | digit << 4;
315 infoPtr->nCaretPos++; /* advance one nibble */
317 else
319 infoPtr->pData[nCaretBytePos] = (BYTE)ch;
320 infoPtr->nCaretPos += 2; /* advance two nibbles */
324 HexEdit_UpdateScrollbars(infoPtr);
325 InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
326 HexEdit_UpdateCaret(infoPtr);
327 HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos);
328 return 0;
331 static inline LRESULT
332 HexEdit_Create (HEXEDIT_INFO *infoPtr, LPCREATESTRUCTW lpcs)
334 HexEdit_SetFont(infoPtr, GetStockObject(SYSTEM_FONT), FALSE);
335 HexEdit_UpdateScrollbars(infoPtr);
337 return 0;
341 static inline LRESULT
342 HexEdit_Destroy (HEXEDIT_INFO *infoPtr)
344 HWND hwnd = infoPtr->hwndSelf;
345 heap_free(infoPtr->pData);
346 /* free info data */
347 heap_free(infoPtr);
348 SetWindowLongPtrW(hwnd, 0, 0);
349 return 0;
353 static inline LRESULT
354 HexEdit_EraseBackground (HEXEDIT_INFO *infoPtr, HDC hdc)
356 HBRUSH hBrush, hSolidBrush = NULL;
357 RECT rc;
359 if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
360 hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
361 else
363 hBrush = (HBRUSH)SendMessageW(GetParent(infoPtr->hwndSelf), WM_CTLCOLOREDIT,
364 (WPARAM)hdc, (LPARAM)infoPtr->hwndSelf);
365 if (!hBrush)
366 hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
369 GetClientRect (infoPtr->hwndSelf, &rc);
371 FillRect (hdc, &rc, hBrush);
373 if (hSolidBrush)
374 DeleteObject(hSolidBrush);
376 return -1;
380 static inline LRESULT
381 HexEdit_GetFont (HEXEDIT_INFO *infoPtr)
383 return (LRESULT)infoPtr->hFont;
386 static inline LRESULT
387 HexEdit_KeyDown (HEXEDIT_INFO *infoPtr, DWORD key, DWORD flags)
389 INT nInc = (infoPtr->bFocusHex) ? 1 : 2;
390 SCROLLINFO si;
392 switch (key)
394 case VK_LEFT:
395 infoPtr->nCaretPos -= nInc;
396 if (infoPtr->nCaretPos < 0)
397 infoPtr->nCaretPos = 0;
398 break;
399 case VK_RIGHT:
400 infoPtr->nCaretPos += nInc;
401 if (infoPtr->nCaretPos > infoPtr->cbData*2)
402 infoPtr->nCaretPos = infoPtr->cbData*2;
403 break;
404 case VK_UP:
405 if ((infoPtr->nCaretPos - infoPtr->nBytesPerLine*2) >= 0)
406 infoPtr->nCaretPos -= infoPtr->nBytesPerLine*2;
407 break;
408 case VK_DOWN:
409 if ((infoPtr->nCaretPos + infoPtr->nBytesPerLine*2) <= infoPtr->cbData*2)
410 infoPtr->nCaretPos += infoPtr->nBytesPerLine*2;
411 break;
412 case VK_HOME:
413 infoPtr->nCaretPos = 0;
414 break;
415 case VK_END:
416 infoPtr->nCaretPos = infoPtr->cbData*2;
417 break;
418 case VK_PRIOR: /* page up */
419 si.cbSize = sizeof(si);
420 si.fMask = SIF_PAGE;
421 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
422 if ((infoPtr->nCaretPos - (INT)si.nPage*infoPtr->nBytesPerLine*2) >= 0)
423 infoPtr->nCaretPos -= si.nPage*infoPtr->nBytesPerLine*2;
424 else
425 infoPtr->nCaretPos = 0;
426 break;
427 case VK_NEXT: /* page down */
428 si.cbSize = sizeof(si);
429 si.fMask = SIF_PAGE;
430 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
431 if ((infoPtr->nCaretPos + (INT)si.nPage*infoPtr->nBytesPerLine*2) <= infoPtr->cbData*2)
432 infoPtr->nCaretPos += si.nPage*infoPtr->nBytesPerLine*2;
433 else
434 infoPtr->nCaretPos = infoPtr->cbData*2;
435 break;
436 default:
437 return 0;
440 HexEdit_UpdateCaret(infoPtr);
441 HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos);
443 return 0;
447 static inline LRESULT
448 HexEdit_KillFocus (HEXEDIT_INFO *infoPtr, HWND receiveFocus)
450 infoPtr->bFocus = FALSE;
451 DestroyCaret();
453 return 0;
457 static inline LRESULT
458 HexEdit_LButtonDown (HEXEDIT_INFO *infoPtr)
460 SetFocus(infoPtr->hwndSelf);
462 /* FIXME: hittest and set caret */
464 return 0;
468 static inline LRESULT HexEdit_NCCreate (HWND hwnd, LPCREATESTRUCTW lpcs)
470 HEXEDIT_INFO *infoPtr;
471 SetWindowLongW(hwnd, GWL_EXSTYLE,
472 lpcs->dwExStyle | WS_EX_CLIENTEDGE);
474 /* allocate memory for info structure */
475 infoPtr = heap_xalloc(sizeof(HEXEDIT_INFO));
476 memset(infoPtr, 0, sizeof(HEXEDIT_INFO));
477 SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);
479 /* initialize info structure */
480 infoPtr->nCaretPos = 0;
481 infoPtr->hwndSelf = hwnd;
482 infoPtr->nBytesPerLine = 2;
483 infoPtr->bFocusHex = TRUE;
484 infoPtr->bInsert = TRUE;
486 return DefWindowProcW(infoPtr->hwndSelf, WM_NCCREATE, 0, (LPARAM)lpcs);
489 static inline LRESULT
490 HexEdit_SetFocus (HEXEDIT_INFO *infoPtr, HWND lostFocus)
492 infoPtr->bFocus = TRUE;
494 CreateCaret(infoPtr->hwndSelf, NULL, 1, infoPtr->nHeight);
495 HexEdit_UpdateCaret(infoPtr);
496 ShowCaret(infoPtr->hwndSelf);
498 return 0;
502 static inline LRESULT
503 HexEdit_SetFont (HEXEDIT_INFO *infoPtr, HFONT hFont, BOOL redraw)
505 TEXTMETRICW tm;
506 HDC hdc;
507 HFONT hOldFont = NULL;
508 LONG i;
509 RECT rcClient;
511 infoPtr->hFont = hFont;
513 hdc = GetDC(infoPtr->hwndSelf);
514 if (infoPtr->hFont)
515 hOldFont = SelectObject(hdc, infoPtr->hFont);
517 GetTextMetricsW(hdc, &tm);
518 infoPtr->nHeight = tm.tmHeight + tm.tmExternalLeading;
520 GetClientRect(infoPtr->hwndSelf, &rcClient);
522 for (i = 0; ; i++)
524 BYTE *pData = heap_xalloc(i);
525 WCHAR *lpszLine;
526 SIZE size;
528 memset(pData, 0, i);
529 lpszLine = HexEdit_GetLineText(pData, i, 0);
530 GetTextExtentPoint32W(hdc, lpszLine, lstrlenW(lpszLine), &size);
531 heap_free(lpszLine);
532 heap_free(pData);
533 if (size.cx > (rcClient.right - rcClient.left))
535 infoPtr->nBytesPerLine = i - 1;
536 break;
540 if (infoPtr->hFont)
541 SelectObject(hdc, hOldFont);
542 ReleaseDC (infoPtr->hwndSelf, hdc);
544 if (redraw)
545 InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
547 return 0;
550 static inline LRESULT
551 HexEdit_VScroll (HEXEDIT_INFO *infoPtr, INT action)
553 SCROLLINFO si;
555 /* get all scroll bar info */
556 si.cbSize = sizeof(si);
557 si.fMask = SIF_ALL;
558 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
560 switch (LOWORD(action))
562 case SB_TOP: /* user pressed the home key */
563 si.nPos = si.nMin;
564 break;
566 case SB_BOTTOM: /* user pressed the end key */
567 si.nPos = si.nMax;
568 break;
570 case SB_LINEUP: /* user clicked the up arrow */
571 si.nPos -= 1;
572 break;
574 case SB_LINEDOWN: /* user clicked the down arrow */
575 si.nPos += 1;
576 break;
578 case SB_PAGEUP: /* user clicked the scroll bar above the scroll thumb */
579 si.nPos -= si.nPage;
580 break;
582 case SB_PAGEDOWN: /* user clicked the scroll bar below the scroll thumb */
583 si.nPos += si.nPage;
584 break;
586 case SB_THUMBTRACK: /* user dragged the scroll thumb */
587 si.nPos = si.nTrackPos;
588 break;
590 default:
591 break;
594 /* set the position and then retrieve it to let the system handle the
595 * cases where the position is out of range */
596 si.fMask = SIF_POS;
597 SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, TRUE);
598 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
600 if (si.nPos != infoPtr->nScrollPos)
602 ScrollWindow(infoPtr->hwndSelf, 0, infoPtr->nHeight * (infoPtr->nScrollPos - si.nPos), NULL, NULL);
603 infoPtr->nScrollPos = si.nPos;
604 UpdateWindow(infoPtr->hwndSelf);
606 /* need to update caret position since it depends on the scroll position */
607 HexEdit_UpdateCaret(infoPtr);
609 return 0;
613 static LRESULT WINAPI
614 HexEdit_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
616 HEXEDIT_INFO *infoPtr = (HEXEDIT_INFO *)GetWindowLongPtrW(hwnd, 0);
618 if (!infoPtr && (uMsg != WM_NCCREATE))
619 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
621 switch (uMsg)
623 case HEM_SETDATA:
624 return HexEdit_SetData (infoPtr, (INT)wParam, (const BYTE *)lParam);
626 case HEM_GETDATA:
627 return HexEdit_GetData (infoPtr, (INT)wParam, (BYTE *)lParam);
629 case WM_CHAR:
630 return HexEdit_Char (infoPtr, (WCHAR)wParam);
632 case WM_CREATE:
633 return HexEdit_Create (infoPtr, (LPCREATESTRUCTW)lParam);
635 case WM_DESTROY:
636 return HexEdit_Destroy (infoPtr);
638 case WM_ERASEBKGND:
639 return HexEdit_EraseBackground (infoPtr, (HDC)wParam);
641 case WM_GETDLGCODE:
642 return DLGC_WANTCHARS | DLGC_WANTARROWS;
644 case WM_GETFONT:
645 return HexEdit_GetFont (infoPtr);
647 case WM_KEYDOWN:
648 return HexEdit_KeyDown (infoPtr, wParam, lParam);
650 case WM_KILLFOCUS:
651 return HexEdit_KillFocus (infoPtr, (HWND)wParam);
653 case WM_LBUTTONDOWN:
654 return HexEdit_LButtonDown (infoPtr);
656 case WM_NCCREATE:
657 return HexEdit_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);
659 case WM_PAINT:
660 HexEdit_Paint(infoPtr);
661 return 0;
663 case WM_SETFOCUS:
664 return HexEdit_SetFocus (infoPtr, (HWND)wParam);
666 case WM_SETFONT:
667 return HexEdit_SetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));
669 case WM_VSCROLL:
670 return HexEdit_VScroll (infoPtr, (INT)wParam);
672 default:
673 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
675 return 0;
678 void HexEdit_Register(void)
680 WNDCLASSW wndClass;
682 ZeroMemory(&wndClass, sizeof(WNDCLASSW));
683 wndClass.style = 0;
684 wndClass.lpfnWndProc = HexEdit_WindowProc;
685 wndClass.cbClsExtra = 0;
686 wndClass.cbWndExtra = sizeof(HEXEDIT_INFO *);
687 wndClass.hCursor = NULL;
688 wndClass.hbrBackground = NULL;
689 wndClass.lpszClassName = szHexEditClass;
691 RegisterClassW(&wndClass);