4 * Copyright (C) 2004 Thomas Weidenmueller <w3seek@reactos.com>
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
31 INT nVisibleLinesComplete
;
51 } HEXEDIT_DATA
, *PHEXEDIT_DATA
;
54 #define HEHT_LEFTMARGIN (0x1)
55 #define HEHT_ADDRESS (0x2)
56 #define HEHT_ADDRESSSPACING (0x3)
57 #define HEHT_HEXDUMP (0x4)
58 #define HEHT_HEXDUMPSPACING (0x5)
59 #define HEHT_ASCIIDUMP (0x6)
60 #define HEHT_RIGHTMARGIN (0x7)
62 INT_PTR CALLBACK
HexEditWndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
66 RegisterHexEditorClass(HINSTANCE hInstance
)
70 ZeroMemory(&WndClass
, sizeof(WNDCLASSEX
));
71 WndClass
.cbSize
= sizeof(WNDCLASSEX
);
72 WndClass
.style
= CS_DBLCLKS
;
73 WndClass
.lpfnWndProc
= (WNDPROC
)HexEditWndProc
;
74 WndClass
.cbWndExtra
= sizeof(PHEXEDIT_DATA
);
75 WndClass
.hInstance
= hInstance
;
76 WndClass
.hCursor
= LoadCursor(0, IDC_IBEAM
);
77 WndClass
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
78 WndClass
.lpszClassName
= HEX_EDIT_CLASS_NAME
;
80 return RegisterClassEx(&WndClass
);
85 UnregisterHexEditorClass(HINSTANCE hInstance
)
87 return UnregisterClass(HEX_EDIT_CLASS_NAME
, hInstance
);
90 /*** Helper functions *********************************************************/
93 HEXEDIT_MoveCaret(PHEXEDIT_DATA hed
, BOOL Scroll
)
97 si
.cbSize
= sizeof(SCROLLINFO
);
99 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
103 if(si
.nPos
> hed
->CaretLine
)
105 si
.nPos
= hed
->CaretLine
;
106 SetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
, TRUE
);
107 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
108 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
110 else if(hed
->CaretLine
>= (hed
->nVisibleLinesComplete
+ si
.nPos
))
112 si
.nPos
= hed
->CaretLine
- hed
->nVisibleLinesComplete
+ 1;
113 SetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
, TRUE
);
114 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
115 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
119 if(hed
->EditingField
)
120 SetCaretPos(hed
->LeftMargin
+ ((4 + hed
->AddressSpacing
+ (3 * hed
->CaretCol
) + hed
->InMid
* 2) * hed
->CharWidth
) - 1, (hed
->CaretLine
- si
.nPos
) * hed
->LineHeight
);
122 SetCaretPos(hed
->LeftMargin
+ ((4 + hed
->AddressSpacing
+ hed
->SplitSpacing
+ (3 * hed
->ColumnsPerLine
) + hed
->CaretCol
) * hed
->CharWidth
) - 2, (hed
->CaretLine
- si
.nPos
) * hed
->LineHeight
);
126 HEXEDIT_Update(PHEXEDIT_DATA hed
)
131 INT bufsize
, cvislines
;
133 GetClientRect(hed
->hWndSelf
, &rcClient
);
134 hed
->style
= GetWindowLongPtr(hed
->hWndSelf
, GWL_STYLE
);
136 bufsize
= (hed
->hBuffer
? (INT
) LocalSize(hed
->hBuffer
) : 0);
137 hed
->nLines
= max(bufsize
/ hed
->ColumnsPerLine
, 1);
138 if(bufsize
> hed
->ColumnsPerLine
&& (bufsize
% hed
->ColumnsPerLine
) > 0)
143 if(hed
->LineHeight
> 0)
145 hed
->nVisibleLinesComplete
= cvislines
= rcClient
.bottom
/ hed
->LineHeight
;
146 hed
->nVisibleLines
= hed
->nVisibleLinesComplete
;
147 if(rcClient
.bottom
% hed
->LineHeight
)
149 hed
->nVisibleLines
++;
154 hed
->nVisibleLines
= cvislines
= 0;
157 SbVisible
= bufsize
> 0 && cvislines
< hed
->nLines
;
158 ShowScrollBar(hed
->hWndSelf
, SB_VERT
, SbVisible
);
160 /* update scrollbar */
161 si
.cbSize
= sizeof(SCROLLINFO
);
162 si
.fMask
= SIF_RANGE
| SIF_PAGE
;
164 si
.nMax
= ((bufsize
> 0) ? hed
->nLines
- 1 : 0);
165 si
.nPage
= ((hed
->LineHeight
> 0) ? rcClient
.bottom
/ hed
->LineHeight
: 0);
166 SetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
, TRUE
);
168 if(IsWindowVisible(hed
->hWndSelf
) && SbVisible
!= hed
->SbVisible
)
170 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
173 hed
->SbVisible
= SbVisible
;
177 HEXEDIT_GetFixedFont(VOID
)
180 GetObject(GetStockObject(ANSI_FIXED_FONT
), sizeof(LOGFONT
), &lf
);
181 return CreateFontIndirect(&lf
);
185 HEXEDIT_PaintLines(PHEXEDIT_DATA hed
, HDC hDC
, DWORD ScrollPos
, DWORD First
, DWORD Last
, RECT
*rc
)
187 DWORD dx
, dy
, linestart
;
188 INT i
, isave
, i0
, i1
, x
;
189 PBYTE buf
, current
, end
, line
;
191 TCHAR hex
[3], addr
[17];
194 FillRect(hDC
, rc
, (HBRUSH
)(COLOR_WINDOW
+ 1));
195 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
197 if (hed
->SelStart
< hed
->SelEnd
)
210 bufsize
= LocalSize(hed
->hBuffer
);
211 buf
= LocalLock(hed
->hBuffer
);
218 if(ScrollPos
+ First
== 0)
221 _stprintf(addr
, _T("%04X"), 0);
222 TextOut(hDC
, hed
->LeftMargin
, First
* hed
->LineHeight
, addr
, 4);
229 dy
= First
* hed
->LineHeight
;
230 linestart
= (ScrollPos
+ First
) * hed
->ColumnsPerLine
;
232 current
= buf
+ linestart
;
233 Last
= min(hed
->nLines
- ScrollPos
, Last
);
235 SetBkMode(hDC
, TRANSPARENT
);
236 while(First
<= Last
&& current
< end
)
240 dx
= hed
->LeftMargin
;
243 _stprintf(addr
, _T("%04lX"), linestart
);
244 TextOut(hDC
, dx
, dy
, addr
, 4);
246 dx
+= ((4 + hed
->AddressSpacing
) * hed
->CharWidth
);
247 dh
= (3 * hed
->CharWidth
);
251 rct
.right
= rct
.left
+ dh
;
252 rct
.bottom
= dy
+ hed
->LineHeight
;
255 dx
+= (hed
->CharWidth
/ 2);
258 for(x
= 0; x
< hed
->ColumnsPerLine
&& current
< end
; x
++)
263 _stprintf(hex
, _T("%02X"), *(current
++));
264 if (i0
<= i
&& i
< i1
)
268 rct2
.right
= dx
+ hed
->CharWidth
* 2 + 1;
269 rct2
.bottom
= dy
+ hed
->LineHeight
;
270 InflateRect(&rct2
, hed
->CharWidth
/ 2, 0);
271 FillRect(hDC
, &rct2
, (HBRUSH
)(COLOR_HIGHLIGHT
+ 1));
272 SetTextColor(hDC
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
273 ExtTextOut(hDC
, dx
, dy
, 0, &rct
, hex
, 2, NULL
);
274 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
277 ExtTextOut(hDC
, dx
, dy
, ETO_OPAQUE
, &rct
, hex
, 2, NULL
);
283 dx
= ((4 + hed
->AddressSpacing
+ hed
->SplitSpacing
+ (hed
->ColumnsPerLine
* 3)) * hed
->CharWidth
);
286 for(x
= 0; x
< hed
->ColumnsPerLine
&& current
< end
; x
++)
288 _stprintf(hex
, _T("%C"), *(current
++));
289 hex
[0] = ((hex
[0] & _T('\x007f')) >= _T(' ') ? hex
[0] : _T('.'));
290 if (i0
<= i
&& i
< i1
)
294 rct2
.right
= dx
+ hed
->CharWidth
;
295 rct2
.bottom
= dy
+ hed
->LineHeight
;
296 FillRect(hDC
, &rct2
, (HBRUSH
)(COLOR_HIGHLIGHT
+ 1));
297 SetTextColor(hDC
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
298 TextOut(hDC
, dx
, dy
, hex
, 1);
299 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
302 TextOut(hDC
, dx
, dy
, hex
, 1);
303 dx
+= hed
->CharWidth
;
307 dy
+= hed
->LineHeight
;
308 linestart
+= hed
->ColumnsPerLine
;
313 LocalUnlock(hed
->hBuffer
);
317 HEXEDIT_HitRegionTest(PHEXEDIT_DATA hed
, POINTS pt
)
321 if(pt
.x
<= hed
->LeftMargin
)
323 return HEHT_LEFTMARGIN
;
326 pt
.x
-= hed
->LeftMargin
;
327 d
= (4 * hed
->CharWidth
);
334 d
= (hed
->AddressSpacing
* hed
->CharWidth
);
337 return HEHT_ADDRESSSPACING
;
341 d
= ((3 * hed
->ColumnsPerLine
+ 1) * hed
->CharWidth
);
348 d
= ((hed
->SplitSpacing
- 1) * hed
->CharWidth
);
351 return HEHT_HEXDUMPSPACING
;
355 d
= (hed
->ColumnsPerLine
* hed
->CharWidth
);
358 return HEHT_ASCIIDUMP
;
361 return HEHT_RIGHTMARGIN
;
365 HEXEDIT_IndexFromPoint(PHEXEDIT_DATA hed
, POINTS pt
, DWORD Hit
, POINT
*EditPos
, BOOL
*EditField
)
368 DWORD Index
, bufsize
;
370 si
.cbSize
= sizeof(SCROLLINFO
);
372 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
376 if(hed
->LineHeight
> 0)
378 EditPos
->y
= min(si
.nPos
+ (pt
.y
/ hed
->LineHeight
), hed
->nLines
- 1);
382 EditPos
->y
= si
.nPos
;
387 case HEHT_LEFTMARGIN
:
389 case HEHT_ADDRESSSPACING
:
391 pt
.x
-= (SHORT
) hed
->LeftMargin
+ ((4 + hed
->AddressSpacing
) * hed
->CharWidth
);
396 pt
.x
-= hed
->LeftMargin
+ ((4 + hed
->AddressSpacing
+ hed
->SplitSpacing
+ (3 * hed
->ColumnsPerLine
)) * hed
->CharWidth
);
403 INT BlockWidth
= (*EditField
? hed
->CharWidth
* 3 : hed
->CharWidth
);
404 EditPos
->x
= min(hed
->ColumnsPerLine
, (pt
.x
+ BlockWidth
/ 2) / BlockWidth
);
407 bufsize
= (hed
->hBuffer
? (DWORD
) LocalSize(hed
->hBuffer
) : 0);
408 Index
= (EditPos
->y
* hed
->ColumnsPerLine
) + EditPos
->x
;
411 INT tmp
= bufsize
% hed
->ColumnsPerLine
;
413 EditPos
->x
= (tmp
== 0 ? hed
->ColumnsPerLine
: tmp
);
418 /*** Control specific messages ************************************************/
421 HEXEDIT_HEM_LOADBUFFER(PHEXEDIT_DATA hed
, PVOID Buffer
, DWORD Size
)
423 if(Buffer
!= NULL
&& Size
> 0)
427 if(hed
->MaxBuffer
> 0 && Size
> hed
->MaxBuffer
)
429 Size
= hed
->MaxBuffer
;
436 if(LocalSize(hed
->hBuffer
) != Size
)
438 hed
->hBuffer
= LocalReAlloc(hed
->hBuffer
, Size
, LMEM_MOVEABLE
| LMEM_ZEROINIT
);
443 hed
->hBuffer
= LocalFree(hed
->hBuffer
);
452 hed
->hBuffer
= LocalAlloc(LHND
, Size
);
457 buf
= LocalLock(hed
->hBuffer
);
460 memcpy(buf
, Buffer
, Size
);
464 LocalUnlock(hed
->hBuffer
);
471 else if(hed
->hBuffer
)
474 hed
->hBuffer
= LocalFree(hed
->hBuffer
);
482 HEXEDIT_HEM_COPYBUFFER(PHEXEDIT_DATA hed
, PVOID Buffer
, DWORD Size
)
491 if(Buffer
!= NULL
&& Size
> 0)
493 nCpy
= min(Size
, LocalSize(hed
->hBuffer
));
498 buf
= LocalLock(hed
->hBuffer
);
501 memcpy(Buffer
, buf
, nCpy
);
505 LocalUnlock(hed
->hBuffer
);
510 return (LRESULT
)LocalSize(hed
->hBuffer
);
514 HEXEDIT_HEM_SETMAXBUFFERSIZE(PHEXEDIT_DATA hed
, DWORD nMaxSize
)
516 hed
->MaxBuffer
= nMaxSize
;
517 if (hed
->MaxBuffer
== 0)
519 hed
->hBuffer
= LocalFree(hed
->hBuffer
);
523 hed
->hBuffer
= LocalReAlloc(hed
->hBuffer
, hed
->MaxBuffer
, LMEM_MOVEABLE
);
525 hed
->hBuffer
= LocalAlloc(LMEM_MOVEABLE
, hed
->MaxBuffer
);
530 /*** Message Proc *************************************************************/
533 HEXEDIT_WM_NCCREATE(HWND hWnd
, CREATESTRUCT
*cs
)
537 if(!(hed
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(HEXEDIT_DATA
))))
542 hed
->hWndSelf
= hWnd
;
543 hed
->hWndParent
= cs
->hwndParent
;
544 hed
->style
= cs
->style
;
546 hed
->ColumnsPerLine
= 8;
548 hed
->AddressSpacing
= 2;
549 hed
->SplitSpacing
= 2;
550 hed
->EditingField
= TRUE
; /* in hexdump field */
552 SetWindowLongPtr(hWnd
, 0, (DWORD_PTR
)hed
);
559 HEXEDIT_WM_NCDESTROY(PHEXEDIT_DATA hed
)
563 //while(LocalUnlock(hed->hBuffer));
564 LocalFree(hed
->hBuffer
);
569 DeleteObject(hed
->hFont
);
572 SetWindowLongPtr(hed
->hWndSelf
, 0, (DWORD_PTR
)0);
573 HeapFree(GetProcessHeap(), 0, hed
);
579 HEXEDIT_WM_CREATE(PHEXEDIT_DATA hed
)
581 UNREFERENCED_PARAMETER(hed
);
586 HEXEDIT_WM_SETFOCUS(PHEXEDIT_DATA hed
)
588 CreateCaret(hed
->hWndSelf
, 0, 1, hed
->LineHeight
);
589 HEXEDIT_MoveCaret(hed
, FALSE
);
590 ShowCaret(hed
->hWndSelf
);
595 HEXEDIT_WM_KILLFOCUS(PHEXEDIT_DATA hed
)
597 UNREFERENCED_PARAMETER(hed
);
603 HEXEDIT_WM_VSCROLL(PHEXEDIT_DATA hed
, WORD ThumbPosition
, WORD SbCmd
)
608 UNREFERENCED_PARAMETER(ThumbPosition
);
610 ZeroMemory(&si
, sizeof(SCROLLINFO
));
611 si
.cbSize
= sizeof(SCROLLINFO
);
613 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
643 si
.nPos
= si
.nTrackPos
;
648 SetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
, TRUE
);
649 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
651 if(si
.nPos
!= ScrollY
)
653 ScrollWindow(hed
->hWndSelf
, 0, (ScrollY
- si
.nPos
) * hed
->LineHeight
, NULL
, NULL
);
654 UpdateWindow(hed
->hWndSelf
);
661 HEXEDIT_WM_SETFONT(PHEXEDIT_DATA hed
, HFONT hFont
, BOOL bRedraw
)
669 hFont
= HEXEDIT_GetFixedFont();
673 hDC
= GetDC(hed
->hWndSelf
);
676 hOldFont
= SelectObject(hDC
, hFont
);
678 GetTextMetrics(hDC
, &tm
);
679 hed
->LineHeight
= tm
.tmHeight
;
680 hed
->CharWidth
= tm
.tmAveCharWidth
;
683 SelectObject(hDC
, hOldFont
);
685 ReleaseDC(hed
->hWndSelf
, hDC
);
689 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
696 HEXEDIT_WM_GETFONT(PHEXEDIT_DATA hed
)
698 return (LRESULT
)hed
->hFont
;
702 HEXEDIT_WM_PAINT(PHEXEDIT_DATA hed
)
707 HBITMAP hbmp
, hbmpold
;
713 if(GetUpdateRect(hed
->hWndSelf
, &rc
, FALSE
) && (hed
->LineHeight
> 0))
715 ZeroMemory(&si
, sizeof(SCROLLINFO
));
716 si
.cbSize
= sizeof(SCROLLINFO
);
718 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
720 height
= (rc
.bottom
- rc
.top
);
721 nLines
= height
/ hed
->LineHeight
;
722 if((height
% hed
->LineHeight
) > 0)
726 if(nLines
> hed
->nLines
- si
.nPos
)
728 nLines
= hed
->nLines
- si
.nPos
;
730 nFirst
= rc
.top
/ hed
->LineHeight
;
732 BeginPaint(hed
->hWndSelf
, &ps
);
733 if(!(hTempDC
= CreateCompatibleDC(ps
.hdc
)))
735 FillRect(ps
.hdc
, &rc
, (HBRUSH
)(COLOR_WINDOW
+ 1));
738 if(!(hbmp
= CreateCompatibleBitmap(ps
.hdc
, ps
.rcPaint
.right
, ps
.rcPaint
.bottom
)))
740 FillRect(ps
.hdc
, &rc
, (HBRUSH
)(COLOR_WINDOW
+ 1));
744 hbmpold
= SelectObject(hTempDC
, hbmp
);
745 hOldFont
= SelectObject(hTempDC
, hed
->hFont
);
746 HEXEDIT_PaintLines(hed
, hTempDC
, si
.nPos
, nFirst
, nFirst
+ nLines
, &ps
.rcPaint
);
747 BitBlt(ps
.hdc
, rc
.left
, rc
.top
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, hTempDC
, rc
.left
, rc
.top
, SRCCOPY
);
748 SelectObject(hTempDC
, hOldFont
);
749 SelectObject(hTempDC
, hbmpold
);
755 EndPaint(hed
->hWndSelf
, &ps
);
762 HEXEDIT_WM_MOUSEWHEEL(PHEXEDIT_DATA hed
, int cyMoveLines
, WORD ButtonsDown
, LPPOINTS MousePos
)
767 UNREFERENCED_PARAMETER(ButtonsDown
);
768 UNREFERENCED_PARAMETER(MousePos
);
770 SetFocus(hed
->hWndSelf
);
772 si
.cbSize
= sizeof(SCROLLINFO
);
774 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
779 si
.nPos
+= cyMoveLines
;
780 SetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
, TRUE
);
782 GetScrollInfo(hed
->hWndSelf
, SB_VERT
, &si
);
783 if(si
.nPos
!= ScrollY
)
785 ScrollWindow(hed
->hWndSelf
, 0, (ScrollY
- si
.nPos
) * hed
->LineHeight
, NULL
, NULL
);
786 UpdateWindow(hed
->hWndSelf
);
793 HEXEDIT_WM_GETDLGCODE(LPMSG Msg
)
795 UNREFERENCED_PARAMETER(Msg
);
796 return DLGC_WANTARROWS
| DLGC_WANTCHARS
;
800 HEXEDIT_WM_LBUTTONDOWN(PHEXEDIT_DATA hed
, INT Buttons
, POINTS Pt
)
806 UNREFERENCED_PARAMETER(Buttons
);
807 SetFocus(hed
->hWndSelf
);
809 if (GetAsyncKeyState(VK_SHIFT
) < 0)
812 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, HEHT_HEXDUMP
, &EditPos
, &NewField
);
814 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, HEHT_ASCIIDUMP
, &EditPos
, &NewField
);
815 hed
->SelEnd
= hed
->Index
;
816 hed
->EditingField
= hed
->SelOnField
;
820 Hit
= HEXEDIT_HitRegionTest(hed
, Pt
);
821 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, Hit
, &EditPos
, &NewField
);
822 hed
->SelStart
= hed
->SelEnd
= hed
->Index
;
823 hed
->SelOnField
= hed
->EditingField
= NewField
;
824 SetCapture(hed
->hWndSelf
);
826 hed
->CaretCol
= EditPos
.x
;
827 hed
->CaretLine
= EditPos
.y
;
829 InvalidateRect(hed
->hWndSelf
, NULL
, FALSE
);
830 HEXEDIT_MoveCaret(hed
, TRUE
);
836 HEXEDIT_WM_LBUTTONUP(PHEXEDIT_DATA hed
, INT Buttons
, POINTS Pt
)
840 if (GetCapture() == hed
->hWndSelf
)
843 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, HEHT_HEXDUMP
, &EditPos
, &NewField
);
845 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, HEHT_ASCIIDUMP
, &EditPos
, &NewField
);
846 hed
->CaretCol
= EditPos
.x
;
847 hed
->CaretLine
= EditPos
.y
;
848 hed
->SelEnd
= hed
->Index
;
850 InvalidateRect(hed
->hWndSelf
, NULL
, FALSE
);
851 HEXEDIT_MoveCaret(hed
, TRUE
);
857 HEXEDIT_WM_MOUSEMOVE(PHEXEDIT_DATA hed
, INT Buttons
, POINTS Pt
)
861 if (GetCapture() == hed
->hWndSelf
)
864 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, HEHT_HEXDUMP
, &EditPos
, &NewField
);
866 hed
->Index
= HEXEDIT_IndexFromPoint(hed
, Pt
, HEHT_ASCIIDUMP
, &EditPos
, &NewField
);
867 hed
->CaretCol
= EditPos
.x
;
868 hed
->CaretLine
= EditPos
.y
;
869 hed
->SelEnd
= hed
->Index
;
870 InvalidateRect(hed
->hWndSelf
, NULL
, FALSE
);
871 HEXEDIT_MoveCaret(hed
, TRUE
);
877 HEXEDIT_WM_KEYDOWN(PHEXEDIT_DATA hed
, INT VkCode
)
883 if(GetKeyState(VK_MENU
) & 0x8000)
888 bufsize
= (hed
->hBuffer
? LocalSize(hed
->hBuffer
) : 0);
890 if (hed
->SelStart
< hed
->SelEnd
)
904 if (hed
->SelStart
!= hed
->SelEnd
)
906 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
909 MoveMemory(buf
+ i0
, buf
+ i1
, bufsize
- i1
);
910 LocalUnlock(hed
->hBuffer
);
912 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- (i1
- i0
));
914 hed
->Index
= hed
->SelStart
= hed
->SelEnd
= i0
;
915 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
916 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
920 if (hed
->InMid
&& hed
->EditingField
)
922 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
925 MoveMemory(buf
+ hed
->Index
, buf
+ hed
->Index
+ 1,
926 bufsize
- hed
->Index
- 1);
927 LocalUnlock(hed
->hBuffer
);
929 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- 1);
932 else if (hed
->Index
< bufsize
)
934 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
937 MoveMemory(buf
+ hed
->Index
, buf
+ hed
->Index
+ 1,
938 bufsize
- hed
->Index
- 1);
939 LocalUnlock(hed
->hBuffer
);
941 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- 1);
944 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
945 HEXEDIT_MoveCaret(hed
, TRUE
);
949 if (hed
->SelStart
!= hed
->SelEnd
)
951 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
954 MoveMemory(buf
+ i0
, buf
+ i1
, bufsize
- i1
);
955 LocalUnlock(hed
->hBuffer
);
957 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- (i1
- i0
));
959 hed
->Index
= hed
->SelStart
= hed
->SelEnd
= i0
;
960 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
961 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
965 if (hed
->InMid
&& hed
->EditingField
)
967 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
970 MoveMemory(buf
+ hed
->Index
, buf
+ hed
->Index
+ 1,
971 bufsize
- hed
->Index
- 1);
972 LocalUnlock(hed
->hBuffer
);
975 else if (hed
->Index
> 0)
977 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
980 MoveMemory(buf
+ hed
->Index
- 1, buf
+ hed
->Index
,
981 bufsize
- hed
->Index
);
982 LocalUnlock(hed
->hBuffer
);
985 hed
->SelStart
= hed
->SelEnd
= hed
->Index
;
986 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
987 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
989 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- 1);
992 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
993 HEXEDIT_MoveCaret(hed
, TRUE
);
1000 if (GetAsyncKeyState(VK_SHIFT
) < 0)
1001 hed
->SelEnd
= hed
->Index
;
1003 hed
->SelStart
= hed
->SelEnd
= hed
->Index
;
1004 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
1005 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
1007 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
1008 HEXEDIT_MoveCaret(hed
, TRUE
);
1013 if (hed
->Index
< (INT
)bufsize
)
1016 if (GetAsyncKeyState(VK_SHIFT
) < 0)
1017 hed
->SelEnd
= hed
->Index
;
1019 hed
->SelStart
= hed
->SelEnd
= hed
->Index
;
1020 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
1021 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
1023 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
1024 HEXEDIT_MoveCaret(hed
, TRUE
);
1029 if (hed
->Index
>= hed
->ColumnsPerLine
)
1031 hed
->Index
-= hed
->ColumnsPerLine
;
1032 if (GetAsyncKeyState(VK_SHIFT
) < 0)
1033 hed
->SelEnd
= hed
->Index
;
1035 hed
->SelStart
= hed
->SelEnd
= hed
->Index
;
1036 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
1037 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
1039 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
1040 HEXEDIT_MoveCaret(hed
, TRUE
);
1045 if (hed
->Index
+ hed
->ColumnsPerLine
<= (INT
) bufsize
)
1046 hed
->Index
+= hed
->ColumnsPerLine
;
1048 hed
->Index
= bufsize
;
1049 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
1050 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
1051 if (GetAsyncKeyState(VK_SHIFT
) < 0)
1052 hed
->SelEnd
= hed
->Index
;
1054 hed
->SelStart
= hed
->SelEnd
= hed
->Index
;
1056 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
1057 HEXEDIT_MoveCaret(hed
, TRUE
);
1065 HEXEDIT_WM_CHAR(PHEXEDIT_DATA hed
, WCHAR ch
)
1071 bufsize
= (hed
->hBuffer
? LocalSize(hed
->hBuffer
) : 0);
1072 if (hed
->SelStart
< hed
->SelEnd
)
1082 if (!hed
->EditingField
)
1084 if (0x20 <= ch
&& ch
<= 0xFF)
1086 if (hed
->SelStart
!= hed
->SelEnd
)
1088 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
1091 MoveMemory(buf
+ i0
, buf
+ i1
, bufsize
- i1
);
1092 LocalUnlock(hed
->hBuffer
);
1094 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- (i1
- i0
));
1096 bufsize
= (hed
->hBuffer
? LocalSize(hed
->hBuffer
) : 0);
1097 hed
->Index
= hed
->SelStart
= hed
->SelEnd
= i0
;
1099 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
+ 1);
1100 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
1103 MoveMemory(buf
+ hed
->Index
+ 1, buf
+ hed
->Index
,
1104 bufsize
- hed
->Index
);
1105 buf
[hed
->Index
] = ch
;
1106 LocalUnlock(hed
->hBuffer
);
1109 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
1110 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
1111 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
1112 HEXEDIT_MoveCaret(hed
, TRUE
);
1118 if (('0' <= ch
&& ch
<= '9') || ('A' <= ch
&& ch
<= 'F') ||
1119 ('a' <= ch
&& ch
<= 'f'))
1121 if (hed
->SelStart
!= hed
->SelEnd
)
1123 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
1126 MoveMemory(buf
+ i0
, buf
+ i1
, bufsize
- i1
);
1127 LocalUnlock(hed
->hBuffer
);
1129 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
- (i1
- i0
));
1131 bufsize
= (hed
->hBuffer
? LocalSize(hed
->hBuffer
) : 0);
1132 hed
->Index
= hed
->SelStart
= hed
->SelEnd
= i0
;
1136 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
1139 if ('0' <= ch
&& ch
<= '9')
1140 buf
[hed
->Index
] |= ch
- '0';
1141 else if ('A' <= ch
&& ch
<= 'F')
1142 buf
[hed
->Index
] |= ch
+ 10 - 'A';
1143 else if ('a' <= ch
&& ch
<= 'f')
1144 buf
[hed
->Index
] |= ch
+ 10 - 'a';
1145 LocalUnlock(hed
->hBuffer
);
1152 HexEdit_SetMaxBufferSize(hed
->hWndSelf
, bufsize
+ 1);
1153 buf
= (PBYTE
) LocalLock(hed
->hBuffer
);
1156 MoveMemory(buf
+ hed
->Index
+ 1, buf
+ hed
->Index
,
1157 bufsize
- hed
->Index
);
1158 if ('0' <= ch
&& ch
<= '9')
1159 buf
[hed
->Index
] = (ch
- '0') << 4;
1160 else if ('A' <= ch
&& ch
<= 'F')
1161 buf
[hed
->Index
] = (ch
+ 10 - 'A') << 4;
1162 else if ('a' <= ch
&& ch
<= 'f')
1163 buf
[hed
->Index
] = (ch
+ 10 - 'a') << 4;
1164 LocalUnlock(hed
->hBuffer
);
1168 hed
->CaretCol
= hed
->Index
% hed
->ColumnsPerLine
;
1169 hed
->CaretLine
= hed
->Index
/ hed
->ColumnsPerLine
;
1170 InvalidateRect(hed
->hWndSelf
, NULL
, TRUE
);
1171 HEXEDIT_MoveCaret(hed
, TRUE
);
1179 HEXEDIT_WM_SIZE(PHEXEDIT_DATA hed
, DWORD sType
, WORD NewWidth
, WORD NewHeight
)
1181 UNREFERENCED_PARAMETER(sType
);
1182 UNREFERENCED_PARAMETER(NewHeight
);
1183 UNREFERENCED_PARAMETER(NewWidth
);
1184 HEXEDIT_Update(hed
);
1189 HexEditWndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1194 hed
= (PHEXEDIT_DATA
)(LONG_PTR
)GetWindowLongPtr(hWnd
, (DWORD_PTR
)0);
1201 return HEXEDIT_WM_PAINT(hed
);
1204 return HEXEDIT_WM_KEYDOWN(hed
, (INT
)wParam
);
1207 return HEXEDIT_WM_CHAR(hed
, (WCHAR
)wParam
);
1210 return HEXEDIT_WM_VSCROLL(hed
, HIWORD(wParam
), LOWORD(wParam
));
1213 return HEXEDIT_WM_SIZE(hed
, (DWORD
)wParam
, LOWORD(lParam
), HIWORD(lParam
));
1215 case WM_LBUTTONDOWN
:
1217 p
.x
= LOWORD(lParam
);
1218 p
.y
= HIWORD(lParam
);
1219 return HEXEDIT_WM_LBUTTONDOWN(hed
, (INT
)wParam
, p
);
1224 p
.x
= LOWORD(lParam
);
1225 p
.y
= HIWORD(lParam
);
1226 return HEXEDIT_WM_LBUTTONUP(hed
, (INT
)wParam
, p
);
1231 p
.x
= LOWORD(lParam
);
1232 p
.y
= HIWORD(lParam
);
1233 return HEXEDIT_WM_MOUSEMOVE(hed
, (INT
)wParam
, p
);
1238 UINT nScrollLines
= 3;
1241 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES
, 0, &nScrollLines
, 0);
1242 delta
-= (SHORT
)HIWORD(wParam
);
1243 if(abs(delta
) >= WHEEL_DELTA
&& nScrollLines
!= 0)
1245 p
.x
= LOWORD(lParam
);
1246 p
.y
= HIWORD(lParam
);
1247 return HEXEDIT_WM_MOUSEWHEEL(hed
, nScrollLines
* (delta
/ WHEEL_DELTA
), LOWORD(wParam
), &p
);
1252 case HEM_LOADBUFFER
:
1253 return HEXEDIT_HEM_LOADBUFFER(hed
, (PVOID
)wParam
, (DWORD
)lParam
);
1255 case HEM_COPYBUFFER
:
1256 return HEXEDIT_HEM_COPYBUFFER(hed
, (PVOID
)wParam
, (DWORD
)lParam
);
1258 case HEM_SETMAXBUFFERSIZE
:
1259 return HEXEDIT_HEM_SETMAXBUFFERSIZE(hed
, (DWORD
)lParam
);
1262 return HEXEDIT_WM_SETFOCUS(hed
);
1265 return HEXEDIT_WM_KILLFOCUS(hed
);
1268 return HEXEDIT_WM_GETDLGCODE((LPMSG
)lParam
);
1271 return HEXEDIT_WM_SETFONT(hed
, (HFONT
)wParam
, (BOOL
)LOWORD(lParam
));
1274 return HEXEDIT_WM_GETFONT(hed
);
1277 return HEXEDIT_WM_CREATE(hed
);
1282 return HEXEDIT_WM_NCCREATE(hWnd
, (CREATESTRUCT
*)lParam
);
1289 return HEXEDIT_WM_NCDESTROY(hed
);
1293 case WM_CONTEXTMENU
:
1294 /* FIXME: Implement Cut, Copy, Paste, Delete and Select All */
1298 /* FIXME: Implement Cut, Copy, Paste, Delete and Select All */
1302 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);