* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
-#include <windows.h>
-#include <commctrl.h>
-#include <tchar.h>
-
-#include "hexedit.h"
-
+#include <regedit.h>
typedef struct
{
HWND hWndSelf;
HLOCAL hBuffer;
DWORD style;
DWORD MaxBuffer;
- DWORD ColumnsPerLine;
- DWORD nLines;
- DWORD nVisibleLinesComplete;
- DWORD nVisibleLines;
+ INT ColumnsPerLine;
+ INT nLines;
+ INT nVisibleLinesComplete;
+ INT nVisibleLines;
INT Position;
INT LineHeight;
INT CharWidth;
HFONT hFont;
BOOL SbVisible;
-
+
INT LeftMargin;
INT AddressSpacing;
INT SplitSpacing;
-
+
BOOL EditingField;
INT CaretCol;
INT CaretLine;
#define HEHT_ASCIIDUMP (0x6)
#define HEHT_RIGHTMARGIN (0x7)
-LRESULT WINAPI HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
ATOM
STDCALL
RegisterHexEditorClass(HINSTANCE hInstance)
{
WNDCLASSEX WndClass;
-
+
ZeroMemory(&WndClass, sizeof(WNDCLASSEX));
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = CS_DBLCLKS;
WndClass.hCursor = LoadCursor(0, IDC_IBEAM);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
WndClass.lpszClassName = HEX_EDIT_CLASS_NAME;
-
+
return RegisterClassEx(&WndClass);
}
HEXEDIT_MoveCaret(PHEXEDIT_DATA hed, BOOL Scroll)
{
SCROLLINFO si;
-
+
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
-
+
if(Scroll)
{
if(si.nPos > hed->CaretLine)
}
else if(hed->CaretLine >= (hed->nVisibleLinesComplete + si.nPos))
{
- si.nPos = hed->CaretLine - hed->nVisibleLinesComplete + 1;
+ si.nPos = hed->CaretLine - hed->nVisibleLinesComplete + 1;
SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE);
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
InvalidateRect(hed->hWndSelf, NULL, TRUE);
}
}
-
+
if(hed->EditingField)
SetCaretPos(hed->LeftMargin + ((4 + hed->AddressSpacing + (3 * hed->CaretCol)) * hed->CharWidth) - 1, (hed->CaretLine - si.nPos) * hed->LineHeight);
else
SCROLLINFO si;
RECT rcClient;
BOOL SbVisible;
- DWORD bufsize, cvislines;
-
+ INT bufsize, cvislines;
+
GetClientRect(hed->hWndSelf, &rcClient);
hed->style = GetWindowLong(hed->hWndSelf, GWL_STYLE);
-
+
bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0);
hed->nLines = max(bufsize / hed->ColumnsPerLine, 1);
if(bufsize > hed->ColumnsPerLine && (bufsize % hed->ColumnsPerLine) > 0)
{
hed->nLines++;
}
-
+
if(hed->LineHeight > 0)
{
hed->nVisibleLinesComplete = cvislines = rcClient.bottom / hed->LineHeight;
{
hed->nVisibleLines = cvislines = 0;
}
-
+
SbVisible = bufsize > 0 && cvislines < hed->nLines;
ShowScrollBar(hed->hWndSelf, SB_VERT, SbVisible);
-
+
/* update scrollbar */
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMax = ((bufsize > 0) ? hed->nLines - 1 : 0);
si.nPage = ((hed->LineHeight > 0) ? rcClient.bottom / hed->LineHeight : 0);
SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE);
-
+
if(IsWindowVisible(hed->hWndSelf) && SbVisible != hed->SbVisible)
{
InvalidateRect(hed->hWndSelf, NULL, TRUE);
}
-
+
hed->SbVisible = SbVisible;
}
static VOID
HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWORD Last, RECT *rc)
{
- DWORD x, dx, dy, linestart;
+ DWORD dx, dy, linestart;
+ INT x;
PBYTE buf, current, end, line;
UINT bufsize;
TCHAR hex[3], addr[17];
RECT rct;
-
+
FillRect(hDC, rc, (HBRUSH)(COLOR_WINDOW + 1));
-
+
if(hed->hBuffer)
{
bufsize = LocalSize(hed->hBuffer);
{
buf = NULL;
bufsize = 0;
-
+
if(ScrollPos + First == 0)
{
/* draw address */
TextOut(hDC, hed->LeftMargin, First * hed->LineHeight, addr, 4);
}
}
-
+
if(buf)
{
end = buf + bufsize;
linestart = (ScrollPos + First) * hed->ColumnsPerLine;
current = buf + linestart;
Last = min(hed->nLines - ScrollPos, Last);
-
+
while(First <= Last && current < end)
{
DWORD dh;
-
+
dx = hed->LeftMargin;
-
+
/* draw address */
- _stprintf(addr, _T("%04X"), linestart);
+ _stprintf(addr, _T("%04lX"), linestart);
TextOut(hDC, dx, dy, addr, 4);
-
+
dx += ((4 + hed->AddressSpacing) * hed->CharWidth);
dh = (3 * hed->CharWidth);
-
+
rct.left = dx;
rct.top = dy;
rct.right = rct.left + dh;
rct.bottom = dy + hed->LineHeight;
-
+
/* draw hex map */
dx += (hed->CharWidth / 2);
line = current;
{
rct.left += dh;
rct.right += dh;
-
+
_stprintf(hex, _T("%02X"), *(current++));
ExtTextOut(hDC, dx, dy, ETO_OPAQUE, &rct, hex, 2, NULL);
dx += dh;
}
-
+
/* draw ascii map */
dx = ((4 + hed->AddressSpacing + hed->SplitSpacing + (hed->ColumnsPerLine * 3)) * hed->CharWidth);
current = line;
TextOut(hDC, dx, dy, hex, 1);
dx += hed->CharWidth;
}
-
+
dy += hed->LineHeight;
linestart += hed->ColumnsPerLine;
First++;
}
}
-
+
LocalUnlock(hed->hBuffer);
}
static DWORD
HEXEDIT_HitRegionTest(PHEXEDIT_DATA hed, POINTS pt)
{
- WINDOWINFO wi;
int d;
-
+
if(pt.x <= hed->LeftMargin)
{
return HEHT_LEFTMARGIN;
}
-
+
pt.x -= hed->LeftMargin;
d = (4 * hed->CharWidth);
if(pt.x <= d)
{
return HEHT_ADDRESS;
}
-
+
pt.x -= d;
d = (hed->AddressSpacing * hed->CharWidth);
if(pt.x <= d)
{
return HEHT_ADDRESSSPACING;
}
-
+
pt.x -= d;
d = (3 * hed->ColumnsPerLine * hed->CharWidth);
if(pt.x <= d)
{
return HEHT_HEXDUMP;
}
-
+
pt.x -= d;
d = (hed->SplitSpacing * hed->CharWidth);
if(pt.x <= d)
{
return HEHT_HEXDUMPSPACING;
}
-
+
pt.x -= d;
d = (hed->ColumnsPerLine * hed->CharWidth);
if(pt.x <= d)
{
return HEHT_ASCIIDUMP;
}
-
+
return HEHT_RIGHTMARGIN;
}
{
SCROLLINFO si;
DWORD Pos, bufsize;
-
+
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
-
+
EditPos->x = 0;
-
+
if(hed->LineHeight > 0)
{
EditPos->y = min(si.nPos + (pt.y / hed->LineHeight), hed->nLines - 1);
{
EditPos->y = si.nPos;
}
-
+
switch(Hit)
{
case HEHT_LEFTMARGIN:
pt.x -= hed->LeftMargin + ((4 + hed->AddressSpacing) * hed->CharWidth);
*EditField = TRUE;
break;
-
+
default:
pt.x -= hed->LeftMargin + ((4 + hed->AddressSpacing + hed->SplitSpacing + (3 * hed->ColumnsPerLine)) * hed->CharWidth);
*EditField = FALSE;
break;
}
-
+
if(pt.x > 0)
{
INT BlockWidth = (*EditField ? hed->CharWidth * 3 : hed->CharWidth);
EditPos->x = min(hed->ColumnsPerLine, pt.x / BlockWidth);
}
-
+
bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0);
Pos = (EditPos->y * hed->ColumnsPerLine) + EditPos->x;
if(Pos > bufsize)
if(Buffer != NULL && Size > 0)
{
LPVOID buf;
-
+
if(hed->MaxBuffer > 0 && Size > hed->MaxBuffer)
{
Size = hed->MaxBuffer;
}
-
+
if(hed->hBuffer)
{
if(Size > 0)
hed->hBuffer = LocalFree(hed->hBuffer);
hed->Position = 0;
HEXEDIT_Update(hed);
-
+
return 0;
}
}
{
hed->hBuffer = LocalAlloc(LHND, Size);
}
-
+
if(Size > 0)
{
buf = LocalLock(hed->hBuffer);
{
memcpy(buf, Buffer, Size);
}
- else
+ else
Size = 0;
LocalUnlock(hed->hBuffer);
}
-
+
hed->Position = 0;
HEXEDIT_Update(hed);
return Size;
hed->hBuffer = LocalFree(hed->hBuffer);
HEXEDIT_Update(hed);
}
-
+
return 0;
}
HEXEDIT_HEM_COPYBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size)
{
DWORD nCpy;
-
+
if(!hed->hBuffer)
{
return 0;
}
-
+
if(Buffer != NULL && Size > 0)
{
nCpy = min(Size, LocalSize(hed->hBuffer));
if(nCpy > 0)
{
PVOID buf;
-
+
buf = LocalLock(hed->hBuffer);
if(buf)
{
}
return nCpy;
}
-
+
return (LRESULT)LocalSize(hed->hBuffer);
}
hed->hBuffer = LocalReAlloc(hed->hBuffer, hed->MaxBuffer, LMEM_MOVEABLE);
HEXEDIT_Update(hed);
}
+ return 0;
}
/*** Message Proc *************************************************************/
HEXEDIT_WM_NCCREATE(HWND hWnd, CREATESTRUCT *cs)
{
PHEXEDIT_DATA hed;
-
+
if(!(hed = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HEXEDIT_DATA))))
{
return FALSE;
}
-
+
hed->hWndSelf = hWnd;
hed->hWndParent = cs->hwndParent;
hed->style = cs->style;
-
+
hed->ColumnsPerLine = 8;
hed->LeftMargin = 2;
hed->AddressSpacing = 2;
hed->SplitSpacing = 2;
hed->EditingField = TRUE; /* in hexdump field */
-
- SetWindowLong(hWnd, 0, (LONG)hed);
+
+ SetWindowLongPtr(hWnd, 0, (DWORD_PTR)hed);
HEXEDIT_Update(hed);
-
+
return TRUE;
}
{
if(hed->hBuffer)
{
- while(LocalUnlock(hed->hBuffer));
+ //while(LocalUnlock(hed->hBuffer));
LocalFree(hed->hBuffer);
}
-
+
if(hed->hFont)
{
DeleteObject(hed->hFont);
}
-
- SetWindowLong(hed->hWndSelf, 0, 0);
+
+ SetWindowLongPtr(hed->hWndSelf, 0, (DWORD_PTR)0);
HeapFree(GetProcessHeap(), 0, hed);
-
+
return 0;
}
{
int ScrollY;
SCROLLINFO si;
-
+
ZeroMemory(&si, sizeof(SCROLLINFO));
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
-
+
ScrollY = si.nPos;
switch(SbCmd)
{
case SB_TOP:
si.nPos = si.nMin;
break;
-
+
case SB_BOTTOM:
si.nPos = si.nMax;
break;
-
+
case SB_LINEUP:
si.nPos--;
break;
-
+
case SB_LINEDOWN:
si.nPos++;
break;
-
+
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
-
+
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
-
+
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
}
-
+
si.fMask = SIF_POS;
SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE);
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
-
+
if(si.nPos != ScrollY)
{
ScrollWindow(hed->hWndSelf, 0, (ScrollY - si.nPos) * hed->LineHeight, NULL, NULL);
UpdateWindow(hed->hWndSelf);
}
-
+
return 0;
}
HDC hDC;
TEXTMETRIC tm;
HFONT hOldFont = 0;
-
+
if(hFont == 0)
{
hFont = HEXEDIT_GetFixedFont();
}
-
+
hed->hFont = hFont;
hDC = GetDC(hed->hWndSelf);
if(hFont)
SelectObject(hDC, hOldFont);
}
ReleaseDC(hed->hWndSelf, hDC);
-
+
if(bRedraw)
{
InvalidateRect(hed->hWndSelf, NULL, TRUE);
}
-
+
return 0;
}
SCROLLINFO si;
RECT rc;
HBITMAP hbmp, hbmpold;
- DWORD nLines, nFirst;
+ INT nLines, nFirst;
HFONT hOldFont;
HDC hTempDC;
DWORD height;
-
+
if(GetUpdateRect(hed->hWndSelf, &rc, FALSE) && (hed->LineHeight > 0))
{
ZeroMemory(&si, sizeof(SCROLLINFO));
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
-
+
height = (rc.bottom - rc.top);
nLines = height / hed->LineHeight;
if((height % hed->LineHeight) > 0)
nLines = hed->nLines - si.nPos;
}
nFirst = rc.top / hed->LineHeight;
-
+
BeginPaint(hed->hWndSelf, &ps);
if(!(hTempDC = CreateCompatibleDC(ps.hdc)))
{
BitBlt(ps.hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hTempDC, rc.left, rc.top, SRCCOPY);
SelectObject(hTempDC, hOldFont);
SelectObject(hTempDC, hbmpold);
-
+
DeleteObject(hbmp);
DeleteDC(hTempDC);
-
+
epaint:
EndPaint(hed->hWndSelf, &ps);
}
-
+
return 0;
}
{
SCROLLINFO si;
int ScrollY;
-
+
SetFocus(hed->hWndSelf);
-
+
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
-
+
ScrollY = si.nPos;
-
+
si.fMask = SIF_POS;
si.nPos += cyMoveLines;
SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE);
-
+
GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
if(si.nPos != ScrollY)
{
ScrollWindow(hed->hWndSelf, 0, (ScrollY - si.nPos) * hed->LineHeight, NULL, NULL);
UpdateWindow(hed->hWndSelf);
}
-
+
return 0;
}
BOOL NewField;
POINT EditPos;
DWORD Hit = HEXEDIT_HitRegionTest(hed, Pt);
-
- hed->Position = HEXEDIT_PositionFromPoint(hed, Pt, Hit, &EditPos, &NewField);
+
+ SetFocus(hed->hWndSelf);
+
+ hed->Position = HEXEDIT_PositionFromPoint(hed, Pt, Hit, &EditPos, &NewField);
hed->EditingField = NewField;
hed->CaretCol = EditPos.x;
hed->CaretLine = EditPos.y;
-
+
HEXEDIT_MoveCaret(hed, TRUE);
-
+
return 0;
}
{
DWORD bufsize;
BOOL shift, control;
-
+
if(GetKeyState(VK_MENU) & 0x8000)
{
return FALSE;
}
-
+
shift = GetKeyState(VK_SHIFT) & 0x8000;
control = GetKeyState(VK_CONTROL) & 0x8000;
-
+
bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0);
-
+
switch(VkCode)
{
case VK_LEFT:
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
-
+
case VK_RIGHT:
- if(hed->Position < bufsize)
+ if(hed->Position < (INT)bufsize)
{
if(++hed->CaretCol > hed->ColumnsPerLine)
{
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
-
+
case VK_UP:
if(hed->Position > 0)
{
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
-
+
case VK_DOWN:
- if(hed->Position <= bufsize)
+ if(hed->Position <= (INT)bufsize)
{
if(hed->CaretLine < hed->nLines - 1)
{
hed->Position += hed->ColumnsPerLine;
hed->CaretLine++;
- if(hed->Position > bufsize)
+ if(hed->Position > (INT)bufsize)
{
hed->Position = bufsize;
hed->CaretLine = (hed->nLines > 0 ? hed->nLines - 1 : 0);
HEXEDIT_MoveCaret(hed, TRUE);
break;
}
-
+
return FALSE;
}
return 0;
}
-LRESULT
-WINAPI
+INT_PTR CALLBACK
HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PHEXEDIT_DATA hed;
-
- hed = (PHEXEDIT_DATA)GetWindowLong(hWnd, 0);
+
+ hed = (PHEXEDIT_DATA)(LONG_PTR)GetWindowLongPtr(hWnd, (DWORD_PTR)0);
switch(uMsg)
{
case WM_ERASEBKGND:
return TRUE;
-
+
case WM_PAINT:
return HEXEDIT_WM_PAINT(hed);
-
+
case WM_KEYDOWN:
return HEXEDIT_WM_KEYDOWN(hed, (INT)wParam);
-
+
case WM_VSCROLL:
return HEXEDIT_WM_VSCROLL(hed, HIWORD(wParam), LOWORD(wParam));
-
+
case WM_SIZE:
return HEXEDIT_WM_SIZE(hed, (DWORD)wParam, LOWORD(lParam), HIWORD(lParam));
-
+
case WM_LBUTTONDOWN:
return HEXEDIT_WM_LBUTTONDOWN(hed, (INT)wParam, MAKEPOINTS(lParam));
-
+
case WM_MOUSEWHEEL:
{
UINT nScrollLines = 3;
int delta = 0;
-
+
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &nScrollLines, 0);
delta -= (SHORT)HIWORD(wParam);
if(abs(delta) >= WHEEL_DELTA && nScrollLines != 0)
}
break;
}
-
+
case HEM_LOADBUFFER:
return HEXEDIT_HEM_LOADBUFFER(hed, (PVOID)wParam, (DWORD)lParam);
-
+
case HEM_COPYBUFFER:
return HEXEDIT_HEM_COPYBUFFER(hed, (PVOID)wParam, (DWORD)lParam);
-
+
case HEM_SETMAXBUFFERSIZE:
return HEXEDIT_HEM_SETMAXBUFFERSIZE(hed, (DWORD)lParam);
-
+
case WM_SETFOCUS:
return HEXEDIT_WM_SETFOCUS(hed);
-
+
case WM_KILLFOCUS:
return HEXEDIT_WM_KILLFOCUS(hed);
-
+
case WM_GETDLGCODE:
return HEXEDIT_WM_GETDLGCODE((LPMSG)lParam);
-
+
case WM_SETFONT:
return HEXEDIT_WM_SETFONT(hed, (HFONT)wParam, (BOOL)LOWORD(lParam));
-
+
case WM_GETFONT:
return HEXEDIT_WM_GETFONT(hed);
-
+
case WM_CREATE:
return HEXEDIT_WM_CREATE(hed);
-
+
case WM_NCCREATE:
if(!hed)
{
return HEXEDIT_WM_NCCREATE(hWnd, (CREATESTRUCT*)lParam);
}
break;
-
+
case WM_NCDESTROY:
if(hed)
{
}
break;
}
-
+
return CallWindowProc(DefWindowProc, hWnd, uMsg, wParam, lParam);
}