* 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;
+ INT ColumnsPerLine;
+ INT nLines;
+ INT nVisibleLinesComplete;
+ INT nVisibleLines;
+ INT Position;
INT LineHeight;
INT CharWidth;
HFONT hFont;
+ BOOL SbVisible;
+
INT LeftMargin;
- INT TopMargin;
- INT CaretX;
- INT CaretY;
+ INT AddressSpacing;
+ INT SplitSpacing;
+
+ BOOL EditingField;
+ INT CaretCol;
+ INT CaretLine;
} HEXEDIT_DATA, *PHEXEDIT_DATA;
-LRESULT WINAPI HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+/* hit test codes */
+#define HEHT_LEFTMARGIN (0x1)
+#define HEHT_ADDRESS (0x2)
+#define HEHT_ADDRESSSPACING (0x3)
+#define HEHT_HEXDUMP (0x4)
+#define HEHT_HEXDUMPSPACING (0x5)
+#define HEHT_ASCIIDUMP (0x6)
+#define HEHT_RIGHTMARGIN (0x7)
+
+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 | CS_PARENTDC;
+ WndClass.style = CS_DBLCLKS;
WndClass.lpfnWndProc = (WNDPROC)HexEditWndProc;
WndClass.cbWndExtra = sizeof(PHEXEDIT_DATA);
WndClass.hInstance = hInstance;
WndClass.hCursor = LoadCursor(0, IDC_IBEAM);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
WndClass.lpszClassName = HEX_EDIT_CLASS_NAME;
-
+
return RegisterClassEx(&WndClass);
}
/*** Helper functions *********************************************************/
static VOID
-HEXEDIT_MoveCaret(PHEXEDIT_DATA hed, INT Col, INT Line)
+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)
+ {
+ si.nPos = hed->CaretLine;
+ SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE);
+ GetScrollInfo(hed->hWndSelf, SB_VERT, &si);
+ InvalidateRect(hed->hWndSelf, NULL, TRUE);
+ }
+ else if(hed->CaretLine >= (hed->nVisibleLinesComplete + si.nPos))
+ {
+ 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
+ SetCaretPos(hed->LeftMargin + ((4 + hed->AddressSpacing + hed->SplitSpacing + (3 * hed->ColumnsPerLine) + hed->CaretCol) * hed->CharWidth) - 2, (hed->CaretLine - si.nPos) * hed->LineHeight);
+}
+
+static VOID
+HEXEDIT_Update(PHEXEDIT_DATA hed)
+{
+ SCROLLINFO si;
+ RECT rcClient;
+ BOOL SbVisible;
+ 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 = hed->nVisibleLinesComplete;
+ if(rcClient.bottom % hed->LineHeight)
+ {
+ hed->nVisibleLines++;
+ }
+ }
+ else
+ {
+ 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.nMin = 0;
+ 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 HFONT
+HEXEDIT_GetFixedFont(VOID)
{
- /* FIXME - include the scroll position */
- SetCaretPos(hed->LeftMargin + (Col * hed->CharWidth), hed->TopMargin + (Line * hed->LineHeight));
+ LOGFONT lf;
+ GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf);
+ return CreateFontIndirect(&lf);
+}
+
+static VOID
+HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWORD Last, RECT *rc)
+{
+ 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 = LocalLock(hed->hBuffer);
+ }
+ else
+ {
+ buf = NULL;
+ bufsize = 0;
+
+ if(ScrollPos + First == 0)
+ {
+ /* draw address */
+ _stprintf(addr, _T("%04X"), 0);
+ TextOut(hDC, hed->LeftMargin, First * hed->LineHeight, addr, 4);
+ }
+ }
+
+ if(buf)
+ {
+ end = buf + bufsize;
+ dy = First * hed->LineHeight;
+ 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("%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;
+ for(x = 0; x < hed->ColumnsPerLine && current < end; x++)
+ {
+ 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;
+ for(x = 0; x < hed->ColumnsPerLine && current < end; x++)
+ {
+ _stprintf(hex, _T("%C"), *(current++));
+ hex[0] = ((hex[0] & _T('\x007f')) >= _T(' ') ? hex[0] : _T('.'));
+ 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)
+{
+ 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;
+}
+
+static DWORD
+HEXEDIT_PositionFromPoint(PHEXEDIT_DATA hed, POINTS pt, DWORD Hit, POINT *EditPos, BOOL *EditField)
+{
+ 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);
+ }
+ else
+ {
+ EditPos->y = si.nPos;
+ }
+
+ switch(Hit)
+ {
+ case HEHT_LEFTMARGIN:
+ case HEHT_ADDRESS:
+ case HEHT_ADDRESSSPACING:
+ case HEHT_HEXDUMP:
+ 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)
+ {
+ INT tmp = bufsize % hed->ColumnsPerLine;
+ Pos = bufsize;
+ EditPos->x = (tmp == 0 ? hed->ColumnsPerLine : tmp);
+ }
+ return Pos;
}
/*** Control specific messages ************************************************/
if(Buffer != NULL && Size > 0)
{
LPVOID buf;
-
+
if(hed->MaxBuffer > 0 && Size > hed->MaxBuffer)
{
Size = hed->MaxBuffer;
}
-
+
if(hed->hBuffer)
{
if(Size > 0)
else
{
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;
}
else if(hed->hBuffer)
{
+ hed->Position = 0;
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);
}
{
/* truncate the buffer */
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;
-
- SetWindowLong(hWnd, 0, (LONG)hed);
-
+
+ hed->ColumnsPerLine = 8;
+ hed->LeftMargin = 2;
+ hed->AddressSpacing = 2;
+ hed->SplitSpacing = 2;
+ hed->EditingField = TRUE; /* in hexdump field */
+
+ 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);
}
-
- SetWindowLong(hed->hWndSelf, 0, 0);
+
+ if(hed->hFont)
+ {
+ DeleteObject(hed->hFont);
+ }
+
+ SetWindowLongPtr(hed->hWndSelf, 0, (DWORD_PTR)0);
HeapFree(GetProcessHeap(), 0, hed);
-
+
return 0;
}
static LRESULT
HEXEDIT_WM_CREATE(PHEXEDIT_DATA hed)
{
- hed->LeftMargin = 2;
- hed->TopMargin = 2;
return 1;
}
static LRESULT
HEXEDIT_WM_SETFOCUS(PHEXEDIT_DATA hed)
{
- CreateCaret(hed->hWndSelf, 0, 2, hed->LineHeight);
- HEXEDIT_MoveCaret(hed, 0, 0);
+ CreateCaret(hed->hWndSelf, 0, 1, hed->LineHeight);
+ HEXEDIT_MoveCaret(hed, FALSE);
ShowCaret(hed->hWndSelf);
return 0;
}
return 0;
}
+static LRESULT
+HEXEDIT_WM_VSCROLL(PHEXEDIT_DATA hed, WORD ThumbPosition, WORD SbCmd)
+{
+ 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;
+}
+
static LRESULT
HEXEDIT_WM_SETFONT(PHEXEDIT_DATA hed, HFONT hFont, BOOL bRedraw)
{
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;
+}
+
+static LRESULT
+HEXEDIT_WM_GETFONT(PHEXEDIT_DATA hed)
+{
+ return (LRESULT)hed->hFont;
+}
+
+static LRESULT
+HEXEDIT_WM_PAINT(PHEXEDIT_DATA hed)
+{
+ PAINTSTRUCT ps;
+ SCROLLINFO si;
+ RECT rc;
+ HBITMAP hbmp, hbmpold;
+ 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++;
+ }
+ if(nLines > hed->nLines - si.nPos)
+ {
+ nLines = hed->nLines - si.nPos;
+ }
+ nFirst = rc.top / hed->LineHeight;
+
+ BeginPaint(hed->hWndSelf, &ps);
+ if(!(hTempDC = CreateCompatibleDC(ps.hdc)))
+ {
+ FillRect(ps.hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1));
+ goto epaint;
+ }
+ if(!(hbmp = CreateCompatibleBitmap(hTempDC, ps.rcPaint.right, ps.rcPaint.bottom)))
+ {
+ FillRect(ps.hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1));
+ DeleteDC(hTempDC);
+ goto epaint;
+ }
+ hbmpold = SelectObject(hTempDC, hbmp);
+ hOldFont = SelectObject(hTempDC, hed->hFont);
+ HEXEDIT_PaintLines(hed, hTempDC, si.nPos, nFirst, nFirst + nLines, &ps.rcPaint);
+ 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;
+}
+
+static LRESULT
+HEXEDIT_WM_MOUSEWHEEL(PHEXEDIT_DATA hed, int cyMoveLines, WORD ButtonsDown, LPPOINTS MousePos)
+{
+ 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;
+}
+
+static LRESULT
+HEXEDIT_WM_GETDLGCODE(LPMSG Msg)
+{
+ return DLGC_WANTARROWS | DLGC_WANTCHARS;
+}
+
+static LRESULT
+HEXEDIT_WM_LBUTTONDOWN(PHEXEDIT_DATA hed, INT Buttons, POINTS Pt)
+{
+ BOOL NewField;
+ POINT EditPos;
+ DWORD Hit = HEXEDIT_HitRegionTest(hed, Pt);
+
+ 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;
+}
+
+static BOOL
+HEXEDIT_WM_KEYDOWN(PHEXEDIT_DATA hed, INT VkCode)
+{
+ 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:
+ if(hed->Position > 0)
+ {
+ if(--hed->CaretCol < 0)
+ {
+ hed->CaretLine--;
+ hed->CaretCol = hed->ColumnsPerLine;
+ }
+ else
+ hed->Position--;
+ }
+ HEXEDIT_MoveCaret(hed, TRUE);
+ break;
+
+ case VK_RIGHT:
+ if(hed->Position < (INT)bufsize)
+ {
+ if(++hed->CaretCol > hed->ColumnsPerLine)
+ {
+ hed->CaretCol = 0;
+ hed->CaretLine++;
+ }
+ else
+ hed->Position++;
+ }
+ HEXEDIT_MoveCaret(hed, TRUE);
+ break;
+
+ case VK_UP:
+ if(hed->Position > 0)
+ {
+ if(hed->CaretLine <= 0)
+ {
+ hed->CaretCol = 0;
+ hed->Position = 0;
+ }
+ else
+ {
+ hed->CaretLine--;
+ hed->Position -= hed->ColumnsPerLine;
+ }
+ }
+ HEXEDIT_MoveCaret(hed, TRUE);
+ break;
+
+ case VK_DOWN:
+ if(hed->Position <= (INT)bufsize)
+ {
+ if(hed->CaretLine < hed->nLines - 1)
+ {
+ hed->Position += hed->ColumnsPerLine;
+ hed->CaretLine++;
+ if(hed->Position > (INT)bufsize)
+ {
+ hed->Position = bufsize;
+ hed->CaretLine = (hed->nLines > 0 ? hed->nLines - 1 : 0);
+ hed->CaretCol = bufsize % hed->ColumnsPerLine;
+ }
+ }
+ else
+ {
+ INT tmp = bufsize % hed->ColumnsPerLine;
+ hed->Position = bufsize;
+ hed->CaretCol = (tmp == 0 ? hed->ColumnsPerLine : tmp);
+ }
+ }
+ HEXEDIT_MoveCaret(hed, TRUE);
+ break;
+ }
+
+ return FALSE;
+}
+
+static LRESULT
+HEXEDIT_WM_SIZE(PHEXEDIT_DATA hed, DWORD sType, WORD NewWidth, WORD NewHeight)
+{
+ HEXEDIT_Update(hed);
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)
+ {
+ return HEXEDIT_WM_MOUSEWHEEL(hed, nScrollLines * (delta / WHEEL_DELTA), LOWORD(wParam), &MAKEPOINTS(lParam));
+ }
+ 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);
}
+