winegstreamer: Check for failure from gst_element_set_state() instead of counting...
[wine.git] / programs / regedit / hexedit.c
blobfc6c3a3b082adbd70317658846d333a897d26ab4
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 "wine/heap.h"
39 #include "main.h"
40 #include "regproc.h"
42 /* spaces dividing hex and ASCII */
43 #define DIV_SPACES 4
45 typedef struct tagHEXEDIT_INFO
47 HWND hwndSelf;
48 HFONT hFont;
49 BOOL bFocus : 1;
50 BOOL bFocusHex : 1; /* TRUE if focus is on hex, FALSE if focus on ASCII */
51 BOOL bInsert : 1; /* insert mode if TRUE, overwrite mode if FALSE */
52 INT nHeight; /* height of text */
53 INT nCaretPos; /* caret pos in nibbles */
54 BYTE *pData;
55 INT cbData;
56 INT nBytesPerLine; /* bytes of hex to display per line of the control */
57 INT nScrollPos; /* first visible line */
58 } HEXEDIT_INFO;
60 const WCHAR szHexEditClass[] = {'H','e','x','E','d','i','t',0};
62 static inline LRESULT HexEdit_SetFont (HEXEDIT_INFO *infoPtr, HFONT hFont, BOOL redraw);
64 static inline BYTE hexchar_to_byte(WCHAR ch)
66 if (ch >= '0' && ch <= '9')
67 return ch - '0';
68 else if (ch >= 'a' && ch <= 'f')
69 return ch - 'a' + 10;
70 else if (ch >= 'A' && ch <= 'F')
71 return ch - 'A' + 10;
72 else
73 return -1;
76 static LPWSTR HexEdit_GetLineText(BYTE *pData, LONG cbData, LONG pad)
78 static const WCHAR percent_02xW[] = {'%','0','2','X',' ',0};
80 WCHAR *lpszLine = heap_xalloc((cbData * 3 + pad * 3 + DIV_SPACES + cbData + 1) * sizeof(WCHAR));
81 LONG i;
83 for (i = 0; i < cbData; i++)
84 wsprintfW(lpszLine + i*3, percent_02xW, pData[i]);
85 for (i = 0; i < pad * 3; i++)
86 lpszLine[cbData * 3 + i] = ' ';
88 for (i = 0; i < DIV_SPACES; i++)
89 lpszLine[cbData * 3 + pad * 3 + i] = ' ';
91 /* attempt an ASCII representation if the characters are printable,
92 * otherwise display a '.' */
93 for (i = 0; i < cbData; i++)
95 /* (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER) */
96 if (isprint(pData[i]))
97 lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + i] = pData[i];
98 else
99 lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + i] = '.';
101 lpszLine[cbData * 3 + pad * 3 + DIV_SPACES + cbData] = 0;
102 return lpszLine;
105 static void
106 HexEdit_Paint(HEXEDIT_INFO *infoPtr)
108 PAINTSTRUCT ps;
109 HDC hdc = BeginPaint(infoPtr->hwndSelf, &ps);
110 INT nXStart, nYStart;
111 COLORREF clrOldText;
112 HFONT hOldFont;
113 BYTE *pData;
114 INT iMode;
115 LONG lByteOffset = infoPtr->nScrollPos * infoPtr->nBytesPerLine;
117 /* Make a gap from the frame */
118 nXStart = GetSystemMetrics(SM_CXBORDER);
119 nYStart = GetSystemMetrics(SM_CYBORDER);
121 if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
122 clrOldText = SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
123 else
124 clrOldText = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
126 iMode = SetBkMode(hdc, TRANSPARENT);
127 hOldFont = SelectObject(hdc, infoPtr->hFont);
129 for (pData = infoPtr->pData + lByteOffset; pData < infoPtr->pData + infoPtr->cbData; pData += infoPtr->nBytesPerLine)
131 LPWSTR lpszLine;
132 LONG nLineLen = min((LONG)((infoPtr->pData + infoPtr->cbData) - pData),
133 infoPtr->nBytesPerLine);
135 lpszLine = HexEdit_GetLineText(pData, nLineLen, infoPtr->nBytesPerLine - nLineLen);
137 /* FIXME: draw hex <-> ASCII mapping highlighted? */
138 TextOutW(hdc, nXStart, nYStart, lpszLine, infoPtr->nBytesPerLine * 3 + DIV_SPACES + nLineLen);
140 nYStart += infoPtr->nHeight;
141 heap_free(lpszLine);
144 SelectObject(hdc, hOldFont);
145 SetBkMode(hdc, iMode);
146 SetTextColor(hdc, clrOldText);
148 EndPaint(infoPtr->hwndSelf, &ps);
151 static void
152 HexEdit_UpdateCaret(HEXEDIT_INFO *infoPtr)
154 HDC hdc;
155 HFONT hOldFont;
156 SIZE size;
157 INT nCaretBytePos = infoPtr->nCaretPos/2;
158 INT nByteLinePos = nCaretBytePos % infoPtr->nBytesPerLine;
159 INT nLine = nCaretBytePos / infoPtr->nBytesPerLine;
160 LONG nLineLen = min(infoPtr->cbData - nLine * infoPtr->nBytesPerLine, infoPtr->nBytesPerLine);
161 LPWSTR lpszLine = HexEdit_GetLineText(infoPtr->pData + nLine * infoPtr->nBytesPerLine, nLineLen, infoPtr->nBytesPerLine - nLineLen);
162 INT nCharOffset;
164 /* calculate offset of character caret is on in the line */
165 if (infoPtr->bFocusHex)
166 nCharOffset = nByteLinePos*3 + infoPtr->nCaretPos % 2;
167 else
168 nCharOffset = infoPtr->nBytesPerLine*3 + DIV_SPACES + nByteLinePos;
170 hdc = GetDC(infoPtr->hwndSelf);
171 hOldFont = SelectObject(hdc, infoPtr->hFont);
173 GetTextExtentPoint32W(hdc, lpszLine, nCharOffset, &size);
175 SelectObject(hdc, hOldFont);
176 ReleaseDC(infoPtr->hwndSelf, hdc);
178 if (!nLineLen) size.cx = 0;
180 heap_free(lpszLine);
182 SetCaretPos(
183 GetSystemMetrics(SM_CXBORDER) + size.cx,
184 GetSystemMetrics(SM_CYBORDER) + (nLine - infoPtr->nScrollPos) * infoPtr->nHeight);
187 static void
188 HexEdit_UpdateScrollbars(HEXEDIT_INFO *infoPtr)
190 RECT rcClient;
191 INT nLines = infoPtr->cbData / infoPtr->nBytesPerLine;
192 INT nVisibleLines;
193 SCROLLINFO si;
195 GetClientRect(infoPtr->hwndSelf, &rcClient);
196 InflateRect(&rcClient, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
198 nVisibleLines = (rcClient.bottom - rcClient.top) / infoPtr->nHeight;
199 si.cbSize = sizeof(si);
200 si.fMask = SIF_RANGE | SIF_PAGE;
201 si.nMin = 0;
202 si.nMax = max(nLines - nVisibleLines, nLines);
203 si.nPage = nVisibleLines;
204 SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, TRUE);
207 static void
208 HexEdit_EnsureVisible(HEXEDIT_INFO *infoPtr, INT nCaretPos)
210 INT nLine = nCaretPos / (2 * infoPtr->nBytesPerLine);
211 SCROLLINFO si;
213 si.cbSize = sizeof(si);
214 si.fMask = SIF_POS | SIF_PAGE;
215 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
216 if (nLine < si.nPos)
217 si.nPos = nLine;
218 else if (nLine >= si.nPos + si.nPage)
219 si.nPos = nLine - si.nPage + 1;
220 else
221 return;
222 si.fMask = SIF_POS;
224 SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, FALSE);
225 SendMessageW(infoPtr->hwndSelf, WM_VSCROLL, MAKELONG(SB_THUMBPOSITION, 0), 0);
229 static LRESULT
230 HexEdit_SetData(HEXEDIT_INFO *infoPtr, INT cbData, const BYTE *pData)
232 heap_free(infoPtr->pData);
233 infoPtr->cbData = 0;
235 infoPtr->pData = heap_xalloc(cbData);
236 memcpy(infoPtr->pData, pData, cbData);
237 infoPtr->cbData = cbData;
239 infoPtr->nCaretPos = 0;
240 HexEdit_UpdateScrollbars(infoPtr);
241 HexEdit_UpdateCaret(infoPtr);
242 InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
243 return TRUE;
246 static LRESULT
247 HexEdit_GetData(HEXEDIT_INFO *infoPtr, INT cbData, BYTE *pData)
249 if (pData)
250 memcpy(pData, infoPtr->pData, min(cbData, infoPtr->cbData));
251 return infoPtr->cbData;
254 static inline LRESULT
255 HexEdit_Char (HEXEDIT_INFO *infoPtr, WCHAR ch)
257 INT nCaretBytePos = infoPtr->nCaretPos/2;
259 assert(nCaretBytePos >= 0);
261 /* backspace is special */
262 if (ch == '\b')
264 if (infoPtr->nCaretPos == 0)
265 return 0;
267 /* if at end of byte then delete the whole byte */
268 if (infoPtr->bFocusHex && (infoPtr->nCaretPos % 2 == 0))
270 memmove(infoPtr->pData + nCaretBytePos - 1,
271 infoPtr->pData + nCaretBytePos,
272 infoPtr->cbData - nCaretBytePos);
273 infoPtr->cbData--;
274 infoPtr->nCaretPos -= 2; /* backtrack two nibble */
276 else /* blank upper nibble */
278 infoPtr->pData[nCaretBytePos] &= 0x0f;
279 infoPtr->nCaretPos--; /* backtrack one nibble */
282 else
284 if (infoPtr->bFocusHex && hexchar_to_byte(ch) == (BYTE)-1)
286 MessageBeep(MB_ICONWARNING);
287 return 0;
290 if ((infoPtr->bInsert && (infoPtr->nCaretPos % 2 == 0)) || (nCaretBytePos >= infoPtr->cbData))
292 /* make room for another byte */
293 infoPtr->cbData++;
294 infoPtr->pData = heap_xrealloc(infoPtr->pData, infoPtr->cbData + 1);
296 /* move everything after caret up one byte */
297 memmove(infoPtr->pData + nCaretBytePos + 1,
298 infoPtr->pData + nCaretBytePos,
299 infoPtr->cbData - nCaretBytePos);
300 /* zero new byte */
301 infoPtr->pData[nCaretBytePos] = 0x0;
304 /* overwrite a byte */
306 assert(nCaretBytePos < infoPtr->cbData);
308 if (infoPtr->bFocusHex)
310 BYTE orig_byte = infoPtr->pData[nCaretBytePos];
311 BYTE digit = hexchar_to_byte(ch);
312 if (infoPtr->nCaretPos % 2) /* set low nibble */
313 infoPtr->pData[nCaretBytePos] = (orig_byte & 0xf0) | digit;
314 else /* set high nibble */
315 infoPtr->pData[nCaretBytePos] = (orig_byte & 0x0f) | digit << 4;
316 infoPtr->nCaretPos++; /* advance one nibble */
318 else
320 infoPtr->pData[nCaretBytePos] = (BYTE)ch;
321 infoPtr->nCaretPos += 2; /* advance two nibbles */
325 HexEdit_UpdateScrollbars(infoPtr);
326 InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
327 HexEdit_UpdateCaret(infoPtr);
328 HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos);
329 return 0;
332 static inline LRESULT
333 HexEdit_Create (HEXEDIT_INFO *infoPtr, LPCREATESTRUCTW lpcs)
335 HexEdit_SetFont(infoPtr, GetStockObject(SYSTEM_FONT), FALSE);
336 HexEdit_UpdateScrollbars(infoPtr);
338 return 0;
342 static inline LRESULT
343 HexEdit_Destroy (HEXEDIT_INFO *infoPtr)
345 HWND hwnd = infoPtr->hwndSelf;
346 heap_free(infoPtr->pData);
347 /* free info data */
348 heap_free(infoPtr);
349 SetWindowLongPtrW(hwnd, 0, 0);
350 return 0;
354 static inline LRESULT
355 HexEdit_EraseBackground (HEXEDIT_INFO *infoPtr, HDC hdc)
357 HBRUSH hBrush, hSolidBrush = NULL;
358 RECT rc;
360 if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
361 hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
362 else
364 hBrush = (HBRUSH)SendMessageW(GetParent(infoPtr->hwndSelf), WM_CTLCOLOREDIT,
365 (WPARAM)hdc, (LPARAM)infoPtr->hwndSelf);
366 if (!hBrush)
367 hBrush = hSolidBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
370 GetClientRect (infoPtr->hwndSelf, &rc);
372 FillRect (hdc, &rc, hBrush);
374 if (hSolidBrush)
375 DeleteObject(hSolidBrush);
377 return -1;
381 static inline LRESULT
382 HexEdit_GetFont (HEXEDIT_INFO *infoPtr)
384 return (LRESULT)infoPtr->hFont;
387 static inline LRESULT
388 HexEdit_KeyDown (HEXEDIT_INFO *infoPtr, DWORD key, DWORD flags)
390 INT nInc = (infoPtr->bFocusHex) ? 1 : 2;
391 SCROLLINFO si;
393 switch (key)
395 case VK_LEFT:
396 infoPtr->nCaretPos -= nInc;
397 if (infoPtr->nCaretPos < 0)
398 infoPtr->nCaretPos = 0;
399 break;
400 case VK_RIGHT:
401 infoPtr->nCaretPos += nInc;
402 if (infoPtr->nCaretPos > infoPtr->cbData*2)
403 infoPtr->nCaretPos = infoPtr->cbData*2;
404 break;
405 case VK_UP:
406 if ((infoPtr->nCaretPos - infoPtr->nBytesPerLine*2) >= 0)
407 infoPtr->nCaretPos -= infoPtr->nBytesPerLine*2;
408 break;
409 case VK_DOWN:
410 if ((infoPtr->nCaretPos + infoPtr->nBytesPerLine*2) <= infoPtr->cbData*2)
411 infoPtr->nCaretPos += infoPtr->nBytesPerLine*2;
412 break;
413 case VK_HOME:
414 infoPtr->nCaretPos = 0;
415 break;
416 case VK_END:
417 infoPtr->nCaretPos = infoPtr->cbData*2;
418 break;
419 case VK_PRIOR: /* page up */
420 si.cbSize = sizeof(si);
421 si.fMask = SIF_PAGE;
422 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
423 if ((infoPtr->nCaretPos - (INT)si.nPage*infoPtr->nBytesPerLine*2) >= 0)
424 infoPtr->nCaretPos -= si.nPage*infoPtr->nBytesPerLine*2;
425 else
426 infoPtr->nCaretPos = 0;
427 break;
428 case VK_NEXT: /* page down */
429 si.cbSize = sizeof(si);
430 si.fMask = SIF_PAGE;
431 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
432 if ((infoPtr->nCaretPos + (INT)si.nPage*infoPtr->nBytesPerLine*2) <= infoPtr->cbData*2)
433 infoPtr->nCaretPos += si.nPage*infoPtr->nBytesPerLine*2;
434 else
435 infoPtr->nCaretPos = infoPtr->cbData*2;
436 break;
437 default:
438 return 0;
441 HexEdit_UpdateCaret(infoPtr);
442 HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos);
444 return 0;
448 static inline LRESULT
449 HexEdit_KillFocus (HEXEDIT_INFO *infoPtr, HWND receiveFocus)
451 infoPtr->bFocus = FALSE;
452 DestroyCaret();
454 return 0;
458 static inline LRESULT
459 HexEdit_LButtonDown (HEXEDIT_INFO *infoPtr)
461 SetFocus(infoPtr->hwndSelf);
463 /* FIXME: hittest and set caret */
465 return 0;
469 static inline LRESULT HexEdit_NCCreate (HWND hwnd, LPCREATESTRUCTW lpcs)
471 HEXEDIT_INFO *infoPtr;
472 SetWindowLongW(hwnd, GWL_EXSTYLE,
473 lpcs->dwExStyle | WS_EX_CLIENTEDGE);
475 /* allocate memory for info structure */
476 infoPtr = heap_xalloc(sizeof(HEXEDIT_INFO));
477 memset(infoPtr, 0, sizeof(HEXEDIT_INFO));
478 SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);
480 /* initialize info structure */
481 infoPtr->nCaretPos = 0;
482 infoPtr->hwndSelf = hwnd;
483 infoPtr->nBytesPerLine = 2;
484 infoPtr->bFocusHex = TRUE;
485 infoPtr->bInsert = TRUE;
487 return DefWindowProcW(infoPtr->hwndSelf, WM_NCCREATE, 0, (LPARAM)lpcs);
490 static inline LRESULT
491 HexEdit_SetFocus (HEXEDIT_INFO *infoPtr, HWND lostFocus)
493 infoPtr->bFocus = TRUE;
495 CreateCaret(infoPtr->hwndSelf, NULL, 1, infoPtr->nHeight);
496 HexEdit_UpdateCaret(infoPtr);
497 ShowCaret(infoPtr->hwndSelf);
499 return 0;
503 static inline LRESULT
504 HexEdit_SetFont (HEXEDIT_INFO *infoPtr, HFONT hFont, BOOL redraw)
506 TEXTMETRICW tm;
507 HDC hdc;
508 HFONT hOldFont = NULL;
509 LONG i;
510 RECT rcClient;
512 infoPtr->hFont = hFont;
514 hdc = GetDC(infoPtr->hwndSelf);
515 if (infoPtr->hFont)
516 hOldFont = SelectObject(hdc, infoPtr->hFont);
518 GetTextMetricsW(hdc, &tm);
519 infoPtr->nHeight = tm.tmHeight + tm.tmExternalLeading;
521 GetClientRect(infoPtr->hwndSelf, &rcClient);
523 for (i = 0; ; i++)
525 BYTE *pData = heap_xalloc(i);
526 WCHAR *lpszLine;
527 SIZE size;
529 memset(pData, 0, i);
530 lpszLine = HexEdit_GetLineText(pData, i, 0);
531 GetTextExtentPoint32W(hdc, lpszLine, lstrlenW(lpszLine), &size);
532 heap_free(lpszLine);
533 heap_free(pData);
534 if (size.cx > (rcClient.right - rcClient.left))
536 infoPtr->nBytesPerLine = i - 1;
537 break;
541 if (infoPtr->hFont)
542 SelectObject(hdc, hOldFont);
543 ReleaseDC (infoPtr->hwndSelf, hdc);
545 if (redraw)
546 InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
548 return 0;
551 static inline LRESULT
552 HexEdit_VScroll (HEXEDIT_INFO *infoPtr, INT action)
554 SCROLLINFO si;
556 /* get all scroll bar info */
557 si.cbSize = sizeof(si);
558 si.fMask = SIF_ALL;
559 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
561 switch (LOWORD(action))
563 case SB_TOP: /* user pressed the home key */
564 si.nPos = si.nMin;
565 break;
567 case SB_BOTTOM: /* user pressed the end key */
568 si.nPos = si.nMax;
569 break;
571 case SB_LINEUP: /* user clicked the up arrow */
572 si.nPos -= 1;
573 break;
575 case SB_LINEDOWN: /* user clicked the down arrow */
576 si.nPos += 1;
577 break;
579 case SB_PAGEUP: /* user clicked the scroll bar above the scroll thumb */
580 si.nPos -= si.nPage;
581 break;
583 case SB_PAGEDOWN: /* user clicked the scroll bar below the scroll thumb */
584 si.nPos += si.nPage;
585 break;
587 case SB_THUMBTRACK: /* user dragged the scroll thumb */
588 si.nPos = si.nTrackPos;
589 break;
591 default:
592 break;
595 /* set the position and then retrieve it to let the system handle the
596 * cases where the position is out of range */
597 si.fMask = SIF_POS;
598 SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si, TRUE);
599 GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &si);
601 if (si.nPos != infoPtr->nScrollPos)
603 ScrollWindow(infoPtr->hwndSelf, 0, infoPtr->nHeight * (infoPtr->nScrollPos - si.nPos), NULL, NULL);
604 infoPtr->nScrollPos = si.nPos;
605 UpdateWindow(infoPtr->hwndSelf);
607 /* need to update caret position since it depends on the scroll position */
608 HexEdit_UpdateCaret(infoPtr);
610 return 0;
614 static LRESULT WINAPI
615 HexEdit_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
617 HEXEDIT_INFO *infoPtr = (HEXEDIT_INFO *)GetWindowLongPtrW(hwnd, 0);
619 if (!infoPtr && (uMsg != WM_NCCREATE))
620 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
622 switch (uMsg)
624 case HEM_SETDATA:
625 return HexEdit_SetData (infoPtr, (INT)wParam, (const BYTE *)lParam);
627 case HEM_GETDATA:
628 return HexEdit_GetData (infoPtr, (INT)wParam, (BYTE *)lParam);
630 case WM_CHAR:
631 return HexEdit_Char (infoPtr, (WCHAR)wParam);
633 case WM_CREATE:
634 return HexEdit_Create (infoPtr, (LPCREATESTRUCTW)lParam);
636 case WM_DESTROY:
637 return HexEdit_Destroy (infoPtr);
639 case WM_ERASEBKGND:
640 return HexEdit_EraseBackground (infoPtr, (HDC)wParam);
642 case WM_GETDLGCODE:
643 return DLGC_WANTCHARS | DLGC_WANTARROWS;
645 case WM_GETFONT:
646 return HexEdit_GetFont (infoPtr);
648 case WM_KEYDOWN:
649 return HexEdit_KeyDown (infoPtr, wParam, lParam);
651 case WM_KILLFOCUS:
652 return HexEdit_KillFocus (infoPtr, (HWND)wParam);
654 case WM_LBUTTONDOWN:
655 return HexEdit_LButtonDown (infoPtr);
657 case WM_NCCREATE:
658 return HexEdit_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);
660 case WM_PAINT:
661 HexEdit_Paint(infoPtr);
662 return 0;
664 case WM_SETFOCUS:
665 return HexEdit_SetFocus (infoPtr, (HWND)wParam);
667 case WM_SETFONT:
668 return HexEdit_SetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));
670 case WM_VSCROLL:
671 return HexEdit_VScroll (infoPtr, (INT)wParam);
673 default:
674 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
676 return 0;
679 void HexEdit_Register(void)
681 WNDCLASSW wndClass;
683 ZeroMemory(&wndClass, sizeof(WNDCLASSW));
684 wndClass.style = 0;
685 wndClass.lpfnWndProc = HexEdit_WindowProc;
686 wndClass.cbClsExtra = 0;
687 wndClass.cbWndExtra = sizeof(HEXEDIT_INFO *);
688 wndClass.hCursor = NULL;
689 wndClass.hbrBackground = NULL;
690 wndClass.lpszClassName = szHexEditClass;
692 RegisterClassW(&wndClass);