📄 hexeditwnd.cpp
字号:
// set title
SetHEWndCaption();
//
// inform about HE_ACTION_FILEACCESSINFO
//
if (pActionHandler)
{
ZERO(act);
act.dwActionCode = HE_ACTION_FILEACCESSINFO;
act.bReadWrite = !fInput.IsFileReadOnly();
pActionHandler(&act);
}
return TRUE; // OK
}
//
// main painting routine
// (back-buffering methode)
//
BOOL HexEditWnd::PaintText(HWND hWnd)
{
HDC hDC, hdcBuff;
DWORD dwOffset;
UINT u, u2, icySel;
char cBuff[40];
BYTE byCur;
RECT rct;
HBITMAP hBmp;
HBRUSH hbrColor;
HGDIOBJ hobjOld;
PAINTSTRUCT ps;
// sth to paint ?
if (!diData.dwSize)
return FALSE; // ERR
//
// paint
//
hDC = BeginPaint(hWnd, &ps);
// create virtual bmp
GetClientRect(hWnd, &rct);
hdcBuff = CreateCompatibleDC(hDC);
hBmp = CreateCompatibleBitmap(hDC,
rct.right - rct.left,
rct.bottom - rct.top - iyHETop);
hobjOld = SelectObject(hdcBuff, hBmp);
// fill bmp
hbrColor = CreateSolidBrush( (COLORREF)0x00FFFFFF );
FillRect(hdcBuff, &rct, hbrColor);
DeleteObject(hbrColor);
// paint to bmp
dwOffset = stat.dwCurOffset;
for (u = 0; u < uMaxLines; u++)
{
// end of buffer ?
if (dwOffset >= diData.dwSize)
break;
//
// paint offset
//
SetTextColor(hdcBuff, RGB_BLACK);
wsprintf(cBuff, H8":", dwOffset);
SelectObject(hdcBuff, hFont);
TextOut(hdcBuff,
0, u * uFontHeight,
cBuff, 9);
//
// paint digit pairs
//
for (u2 = 0; u2 < 16; u2++)
{
// end of buffer ?
if (dwOffset >= diData.dwSize)
break; // upper, same structured decision handles painting end
//
// change at this position?
//
byCur = *(BYTE*)((DWORD)diData.pDataBuff + dwOffset);
if (dwOffset >= diOrgData.dwSize) // out of range of original buffer ?
SetTextColor(hdcBuff, RGB_RED);
else
SetTextColor(
hdcBuff,
*(BYTE*)((DWORD)diOrgData.pDataBuff + dwOffset) != byCur ? RGB_RED : RGB_BLACK);
//
// paint digit pair
//
if (stat.bCaretVisible &&
stat.posCaret.dwOffset == dwOffset &&
stat.posCaret.bTextSection)
SelectObject(hdcBuff, hFontU);
else
SelectObject(hdcBuff, hFont);
wsprintf(cBuff, H2, byCur);
TextOut(hdcBuff,
PAIRS_X + DIGIT_PAIR_WIDTH * u2, u * uFontHeight,
cBuff, 2);
//
// paint character
//
if (stat.bCaretVisible &&
stat.posCaret.dwOffset == dwOffset &&
!stat.posCaret.bTextSection)
SelectObject(hdcBuff, hFontU);
else
SelectObject(hdcBuff, hFont);
if (byCur < 0x20)
lstrcpy(cBuff, ".");
else
wsprintf(cBuff, "%c", byCur);
TextOut(hdcBuff,
CHARS_X + u2 * uFontWidth, u * uFontHeight,
cBuff, 1);
//
// draw sel
//
if (stat.bSel &&
dwOffset >= stat.dwOffSelStart &&
dwOffset <= stat.dwOffSelEnd)
{
if (dwOffset == stat.dwOffSelEnd ||
dwOffset % 16 == 15)
icySel = uFontWidth * 2;
else
icySel = DIGIT_PAIR_WIDTH;
// sel pair
BitBlt(hdcBuff,
PAIRS_X + u2 * DIGIT_PAIR_WIDTH,
u * uFontHeight,
icySel,
uFontHeight,
hdcBuff,
PAIRS_X + u2 * DIGIT_PAIR_WIDTH,
u * uFontHeight,
NOTSRCCOPY);
// sel char
BitBlt(hdcBuff,
CHARS_X + u2 * uFontWidth,
u * uFontHeight,
uFontWidth,
uFontHeight,
hdcBuff,
CHARS_X + u2 * uFontWidth,
u * uFontHeight,
NOTSRCCOPY);
}
// adjust vars
++dwOffset;
}
}
//
// SB stuff
//
// paint SB text
SetTextColor(hdcBuff, RGB_SBGRAY);
SelectObject(hdcBuff, hFont);
TextOut(hdcBuff, 2, rct.bottom - SB_HEIGHT - 28, cSBText, lstrlen(cSBText) );
// copy buffer content to client area
BitBlt(hDC,
rct.left,
rct.top + iyHETop,
rct.right - rct.left,
rct.bottom - rct.top - iyHETop,
hdcBuff,
0, 0, SRCCOPY);
// cleanup
SelectObject(hdcBuff, hobjOld);
DeleteDC(hdcBuff);
DeleteObject(hBmp);
EndPaint(hWnd, &ps);
return TRUE; // OK
}
//
// paints only one offset
// (used to avoid flickering)
//
/*
BOOL HexEditWnd::PaintOffset(HWND hWnd, PHE_POS ppos)
{
HDC hDC;
PAINTSTRUCT ps;
DWORD dwDelta;
UINT uLine, uPair;
char cBuff[10];
BYTE *pby;
RECT rct;
// sth to paint ?
if (!diData.dwSize)
return FALSE; // ERR
// in visible range ?
if (!IsOffsetVisible(ppos->dwOffset))
return FALSE; // ERR
//
// paint
//
pby = (BYTE*)((DWORD)diData.pDataBuff + ppos->dwOffset);
dwDelta = ppos->dwOffset - stat.dwCurOffset;
uLine = dwDelta / uFontHeight;
uPair = dwDelta % 16;
//hDC = BeginPaint(hWnd, &ps);
//SetBkMode(hDC, TRANSPARENT);
// pair
if (stat.bCaretVisible &&
stat.posCaret.dwOffset == ppos->dwOffset &&
stat.posCaret.bTextSection)
SelectObject(hDC, hFontU);
else
SelectObject(hDC, hFont);
wsprintf(cBuff, H2, *pby);
TextOut(hDC,
PAIRS_X + uPair * DIGIT_PAIR_WIDTH,
uLine * uFontHeight,
cBuff, 2);
// character
if (stat.bCaretVisible &&
stat.posCaret.dwOffset == ppos->dwOffset &&
!stat.posCaret.bTextSection)
SelectObject(hDC, hFontU);
else
SelectObject(hDC, hFont);
wsprintf(cBuff, "%c", *pby);
TextOut(hDC,
CHARS_X + uPair * uFontWidth,
uLine * uFontHeight,
cBuff, 1);
//
// invalidate region at pair and char
//
ValidateRect(hWnd, NULL);
rct.left = PAIRS_X + uPair * DIGIT_PAIR_WIDTH;
rct.right = PAIRS_X + uPair * DIGIT_PAIR_WIDTH + 2 * uFontWidth;
rct.top = uLine * uFontHeight;
rct.bottom = (uLine + 1) * uFontHeight;
InvalidateRect(hWnd, &rct, TRUE);
rct.left = CHARS_X + uPair * uFontWidth;
rct.right = CHARS_X + (uPair + 1) * uFontWidth;
rct.top = uLine * uFontHeight;
rct.bottom = (uLine + 1) * uFontHeight;
InvalidateRect(hWnd, &rct, TRUE);
//PaintText(hWnd);
//EndPaint(hWnd, &ps);
return TRUE;
}
*/
void HexEditWnd::HEHandleWM_SETFOCUS(HWND hWnd)
{
//
// handle caret stuff
//
CreateCaret(hWnd, NULL, uFontWidth, uFontHeight);
SetCaretSet(TRUE);
if (stat.bCaretPosValid)
SetCaret(&stat.posCaret);
return;
}
void HexEditWnd::HEHandleWM_KILLFOCUS(HWND hWnd)
{
//
// handle caret stuff
//
if (!stat.bCaretVisible)
HideCaret(hWnd);
DestroyCaret();
SetCaretSet(FALSE);
stat.bCaretVisible = FALSE;
return;
}
//
// save new caret pos and repaints
//
// returns:
// FALSE - mainly if the caret was hidden because it's not in the current visible range
//
BOOL HexEditWnd::SetCaret(PHE_POS ppos)
{
BOOL bRet = FALSE;
DWORD dwOffDelta;
UINT uxPair, uyLine, ux;
if (IsOutOfRange(ppos))
return FALSE; // ERR
SetCaretPosData(ppos);
if (stat.bSel)
return FALSE; // ERR
// new pos in current range?
if (!IsOffsetVisible(ppos->dwOffset))
{
if (stat.bCaretVisible)
HideCaret(hMainWnd);
stat.bCaretVisible = FALSE;
return FALSE; // ERR
}
dwOffDelta = ppos->dwOffset - stat.dwCurOffset;
uyLine = dwOffDelta / 16;
uxPair = dwOffDelta % 16;
// caret in the text section ?
if (ppos->bTextSection)
{
bRet = SetCaretPos(
CHARS_X + uFontWidth * uxPair,
uyLine * uFontHeight + iyHETop);
}
else
{
ux = PAIRS_X + uxPair * DIGIT_PAIR_WIDTH;
if (!ppos->bHiword)
ux += uFontWidth;
bRet = SetCaretPos(
ux,
uyLine * uFontHeight + iyHETop);
}
if (bRet)
{
if (!stat.bCaretVisible)
ShowCaret(hMainWnd);
stat.bCaretVisible = TRUE;
stat.bCaretPosValid = TRUE;
SetCaretSelInfoToStatus();
RepaintClientArea();
return TRUE; // OK
}
else
return FALSE; // ERR
}
//
// overloaded
//
BOOL HexEditWnd::SetCaret(DWORD dwOffset)
{
HE_POS posNew;
if (IsOutOfRange(dwOffset))
return FALSE; // ERR
posNew.bHiword = TRUE;
posNew.bTextSection = FALSE;
posNew.dwOffset = dwOffset;
return SetCaret(&posNew);
}
//
// overloaded
//
BOOL HexEditWnd::SetCaret()
{
return SetCaret(&stat.posCaret);
}
//
// checks whether an Offset is currently visible in the GUI
//
BOOL HexEditWnd::IsOffsetVisible(DWORD dwOffset)
{
DWORD dwBytes2C;
// out of mem range ?
if (dwOffset >= diData.dwSize)
return FALSE; // ERR
// out of visible range ?
dwBytes2C = 16 * uMaxLines;
if (dwBytes2C + stat.dwCurOffset > diData.dwSize)
dwBytes2C = diData.dwSize - stat.dwCurOffset;
if (dwOffset >= stat.dwCurOffset &&
dwOffset < stat.dwCurOffset + dwBytes2C)
return TRUE; // OK
else
return FALSE; // ERR
}
BOOL HexEditWnd::HESetFont(HFONT hf)
{
TEXTMETRIC tm;
HDC hDC;
BOOL bRet = FALSE;
hDC = GetDC(hMainWnd);
if (!hDC)
return FALSE; // FAILURE
SelectObject(hDC, hf);
if (!GetTextMetrics(hDC, &tm))
goto Exit; // FAILURE
uFontHeight = tm.tmHeight;
uFontWidth = tm.tmAveCharWidth;
SendMessage(hMainWnd, WM_SETFONT, (WPARAM)HEdit.hFont, 0);
Exit:
ReleaseDC(hMainWnd, hDC);
return bRet; // EXIT
}
void HexEditWnd::HEHandleWM_SIZE(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
RECT rct;
UINT uWidth, uHeight;
// save pos
if ( wParam != SIZE_MINIMIZED &&
wParam != SIZE_MAXIMIZED)
GetWindowRect( hWnd, &rctLastPos );
//
// handle HE_SET_MINIMIZETOTRAY
//
if (bMinToTray)
{
if (wParam == SIZE_MINIMIZED)
{
HEditToTray();
return; // RET
}
}
// wnd size info -> vars
uWidth = LOWORD(lParam);
uHeight = HIWORD(lParam);
if (uFontHeight) // avoid division through 0
{
// calc max lines
uMaxLines = (uHeight - iyHETop - SB_HEIGHT) / uFontHeight;
// bottom of HE
GetClientRect(hWnd, &rct);
HEdit.iyHEBottom = rct.bottom - SB_HEIGHT;
// get HE rect
rctHE.top = iyHETop;
rctHE.bottom = iyHEBottom;
rctHE.left = 0;
rctHE.right = CHARS_X + 16 * uFontWidth;
}
// resize TB
SendMessage(hTB, TB_AUTOSIZE, 0, 0);
return; // RET
}
//
// install tray icon + hide main win
//
BOOL HexEditWnd::HEditToTray()
{
char *pch;
// add tray icon
ZERO(nidTray);
// build tip
nidTray.cbSize = sizeof(nidTray);
lstrcpy(nidTray.szTip, HEDIT_TRAY_TIP);
if ( IsFileInput() )
{
pch = CPathString::ExtractFileName( fInput.GetFilePath() );
if (pch)
if (sizeof(nidTray.szTip) - sizeof(HEDIT_TRAY_TIP) - 3 >= lstrlen(pch) )
{
lstrcat(nidTray.szTip, " - ");
lstrcat(nidTray.szTip, pch);
lstrlen(nidTray.szTip);
}
}
else
{
lstrcat(nidTray.szTip, " - ");
lstrcat(nidTray.szTip, szMemoryBuff);
}
nidTray.hWnd = hMainWnd;
nidTray.uID = ID_TRAYICON;
nidTray.uFlags = NIF_TIP | NIF_ICON | NIF_MESSAGE;
nidTray.hIcon = (HICON)GetClassLong(hMainWnd, GCL_HICON);
nidTray.uCallbackMessage = WM_TRAYMENU;
if (!Shell_NotifyIcon(NIM_ADD, &nidTray))
return FALSE; // ERR
// hide win
ShowWindow(hMainWnd, SW_HIDE);
return TRUE; // OK
}
BOOL HexEditWnd::HEditKillTrayIcon()
{
return Shell_NotifyIcon(NIM_DELETE, &nidTray);
}
//
// kill tray icon + show main win
//
BOOL HexEditWnd::HEditReturnFromTray()
{
// kill tray icon
if (!HEditKillTrayIcon())
return FALSE; // ERR
// show win
ShowWindow(hMainWnd, SW_RESTORE);
HEditToTop();
return TRUE; // OK
}
BOOL HexEditWnd::HEHandleLButton(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
POINT pClick;
HE_POS pos;
DWORD dwOldOff;
BOOL bSel;
pClick.x = LOWORD(lParam);
pClick.y = HIWORD(lParam);
switch(uMsg)
{
case WM_LBUTTONDOWN:
if (!PointToPos(&pClick, &pos))
{
stat.bLastLBDownPos = FALSE;
return FALSE; // ERR
}
stat.bMouseSelecting = TRUE;
dwOldOff = stat.posCaret.dwOffset;
stat.posLastLButtonDown = pos;
stat.bLastLBDownPos = TRUE;
bSel = KillSelection();
SetCaret(&pos);
if (bSel)
break;
// handle shift key actions ?
if ( TESTBIT(wParam, MK_SHIFT) && stat.bCaretPosValid )
SetSelection( dwOldOff, pos.dwOffset );
break;
case WM_LBUTTONUP:
stat.bMouseSelecting = FALSE;
break;
}
return TRUE; // OK
}
//
// converts a POINT struct to a HE_POS struct
//
// returns:
// FALSE - if POINT is neither in the pair field nor in the text field
//
BOOL HexEditWnd::PointToPos(IN POINT *pp, OUT PHE_POS ppos)
{
UINT uLine, uPair, uxCurPair;
memset(ppos, 0, sizeof(HE_POS));
// in digit pair field ?
if ((DWORD)pp->x >= PAIRS_X &&
(DWORD)pp->x < PAIRS_X + 16 * DIGIT_PAIR_WIDTH &&
(DWORD)pp->y >= iyHETop &&
(DWORD)pp->y < iyHETop + uMaxLines * uFontHeight)
{
uLine = ((DWORD)pp->y - iyHETop) / uFontHeight;
uPair = pp->x - PAIRS_X;
uPair /= DIGIT_PAIR_WIDTH;
// x in space between digit pairs ?
uxCurPair = PAIRS_X + uPair * DIGIT_PAIR_WIDTH; // -> x pos of cur pair
if ((UINT)pp->x > uxCurPair + 2*uFontWidth)
{
// last pair of the line ?
if (uPair == 0xF)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -