效果演示
例程实现在编辑框中添加十六进制和ASCII文本,可以通过单选框选择是否显示。
地址也可以通过选择设置,效果如上图。
例程使用的两文件可以在帖子底部使用或直接下载工程源代码使用:
实现过程
1.同样也是新建一个工程,这里建立基于对话框的工程,
按照上图添加单选框,编辑框,与滑块控件,并进行界面排序。
2.复制例程目录两文件HEXEDITCTRL.CPP,HEXEDITCTRL.H到自己工程根目录中,
并导入到工程,两文件源代码可以在帖子底部复制使用。
操作之后,自己的工程目录内就多出了一个集成类CHexEdit,如下图:
3.紧接着就产类的使用。
在主对话框头文件内包含#include "hexeditctrl.h"
并添加变量
//{{AFX_DATA(CCtestDlg)
enum { IDD = IDD_CTEST_DIALOG };
CSliderCtrl m_slider;
CHexEdit m_Edit;
//}}AFX_DATA
void CCtestDlg:oDataExchange(CDataExchange* pDX)
{
CDialog:oDataExchange(pDX);
DDX_Control(pDX, IDC_SLIDER1, m_slider);
DDX_Control(pDX, IDC_HEXEDIT1, m_Edit);
//}}AFX_DATA_MAP
}
并初始化变量
m_slider.SetRange(1, 16);
m_slider.SetPos(8);
编译时会提示少一个菜单ID,CG_IDR_POPUP_HEX_EDIT,
添加或从例程复制使用。
4.添加几个单选框的点击处理函数
- void CHexEditDlg::OnCheck1()
- {
- UpdateData(TRUE);
- m_Edit.SetOptions(m_address, m_hex, m_ascii, m_48);
- m_Edit.RedrawWindow();
- }
- void CHexEditDlg::OnCheck2()
- {
- UpdateData(TRUE);
- m_Edit.SetOptions(m_address, m_hex, m_ascii, m_48);
- m_Edit.RedrawWindow();
- }
- void CHexEditDlg::OnCheck3()
- {
- UpdateData(TRUE);
- m_Edit.SetOptions(m_address, m_hex, m_ascii, m_48);
- m_Edit.RedrawWindow();
- }
- void CHexEditDlg::OnCheck4()
- {
- UpdateData(TRUE);
- m_Edit.SetOptions(m_address, m_hex, m_ascii, m_48);
- m_Edit.RedrawWindow();
- }
复制代码
运行程序,就可以点击界面的几个单选框查看效果,
编辑框自带的文本可以通过去除集成类头文件的#define DEMO 1,去除。
5.最后就滑块功能的实现,在主对话框添加对消息WM_HSCROLL的处理便可:
void CCtestDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
m_Edit.SetBPR(m_slider.GetPos());
m_Edit.RedrawWindow();
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
下面是两个文件的源代码:
- /////////////////////////////////////////////////////////////////////////////
- // CHexEdit window
- class CHexEdit : public CEdit
- {
- // Construction
- public:
- CHexEdit();
- enum EDITMODE{
- EDIT_NONE,
- EDIT_ASCII,
- EDIT_HIGH,
- EDIT_LOW
- } ;
- // Attributes
- public:
- LPBYTE m_pData; // pointer to data
- int m_length; // length of data
- int m_topindex; // offset of first visible byte on screen
- int m_currentAddress; // address under cursor
- EDITMODE m_currentMode; // current editing mode: address/hex/ascii
- int m_selStart; // start address of selection
- int m_selEnd; // end address of selection
- int m_bpr; // byte per row
- int m_lpp; // lines per page
- BOOL m_bShowAddress;
- BOOL m_bShowAscii;
- BOOL m_bShowHex;
- BOOL m_bAddressIsWide;
-
- BOOL m_bNoAddressChange; // internally used
- BOOL m_bHalfPage;
-
- CFont m_Font;
- int m_lineHeight;
- int m_nullWidth;
- BOOL m_bUpdate;
- int m_offHex,
- m_offAscii,
- m_offAddress;
- CPoint m_editPos;
- // Operations
- public:
- // Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CHexEdit)
- public:
- virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
- protected:
- virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
- //}}AFX_VIRTUAL
- // Implementation
- public:
- int GetData(LPBYTE p, int len);
- void SetData(LPBYTE p, int len);
- CSize GetSel(void);
- void SetSel(int s, int e);
- void SetBPR(int bpr);
- void SetOptions(BOOL a, BOOL h, BOOL c, BOOL w);
- virtual ~CHexEdit();
- // Generated message map functions
- protected:
- void ScrollIntoView(int p);
- void RepositionCaret(int p);
- void Move(int x, int y);
- inline BOOL IsSelected(void);
- void UpdateScrollbars(void);
- void CreateEditCaret(void);
- void CreateAddressCaret(void);
- CPoint CalcPos(int x, int y);
- void SelInsert(int s, int l);
- void SelDelete(int s, int e);
- inline void NormalizeSel(void);
- afx_msg void OnContextMenu(CWnd*, CPoint point);
- //{{AFX_MSG(CHexEdit)
- afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
- afx_msg void OnKillFocus(CWnd* pNewWnd);
- afx_msg void OnPaint();
- afx_msg void OnSetFocus(CWnd* pOldWnd);
- afx_msg void OnSize(UINT nType, int cx, int cy);
- afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
- afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
- afx_msg UINT OnGetDlgCode();
- afx_msg BOOL OnEraseBkgnd(CDC* pDC);
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
- afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
- afx_msg void OnEditClear();
- afx_msg void OnEditCopy();
- afx_msg void OnEditCut();
- afx_msg void OnEditPaste();
- afx_msg void OnEditSelectAll();
- afx_msg void OnEditUndo();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
复制代码- // HexEdit.cpp : Defines the class behaviors for the application.
- //
- #include "stdafx.h"
- #include "HexEditCtrl.h"
- #include <ctype.h>
- #include <afxole.h>
- #include <afxdisp.h>
- #include "resource.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- char hextable[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
- #define TOHEX(a, b) {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}
- /////////////////////////////////////////////////////////////////////////////
- // CHexEdit
- #define DEMO 1
- CHexEdit::CHexEdit()
- {
- #if !defined(DEMO)
- m_pData = NULL; // pointer to data
- m_length = 0; // length of data
- #else
- m_pData = (LPBYTE)malloc(0x40);
- for(int i = 0; i < 0x40; i++)
- m_pData[i] = i;
- #endif
- m_length = 0x40;
- m_topindex = 0;
- m_bpr = 8; // byte per row
- m_lpp = 1;
- m_bShowHex = TRUE;
- m_bShowAscii = TRUE;
- m_bShowAddress = TRUE;
- m_bAddressIsWide= TRUE; // 4/8 byte address
- m_offAddress = 0;
- m_offHex = 0;
- m_offAscii = 0;
- m_bUpdate = TRUE; // update font info
- m_bNoAddressChange = FALSE;
- m_currentMode = EDIT_NONE;
- m_editPos.x = m_editPos.y = 0;
- m_currentAddress = 0;
- m_bHalfPage = TRUE;
- m_selStart = 0xffffffff;
- m_selEnd = 0xffffffff;
- m_Font.CreateFont(-12, 0,0,0,0,0,0,0,0,0,0,0,0, "Courier New");
- AfxOleInit();
- }
- CHexEdit::~CHexEdit()
- {
- }
- BEGIN_MESSAGE_MAP(CHexEdit, CEdit)
- ON_WM_CONTEXTMENU()
- //{{AFX_MSG_MAP(CHexEdit)
- ON_WM_CHAR()
- ON_WM_KILLFOCUS()
- ON_WM_PAINT()
- ON_WM_SETFOCUS()
- ON_WM_SIZE()
- ON_WM_VSCROLL()
- ON_WM_HSCROLL()
- ON_WM_GETDLGCODE()
- ON_WM_ERASEBKGND()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONDBLCLK()
- ON_WM_MOUSEMOVE()
- ON_WM_LBUTTONUP()
- ON_WM_KEYDOWN()
- ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
- ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
- ON_COMMAND(ID_EDIT_CUT, OnEditCut)
- ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
- ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
- ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CHexEdit message handlers
- void CHexEdit::OnPaint()
- {
- CPaintDC pdc(this); // device context for painting
- CRect rc;
- GetClientRect(rc);
-
- CDC dc;
- dc.CreateCompatibleDC(CDC::FromHandle(pdc.m_ps.hdc));
- CBitmap bm;
- bm.CreateCompatibleBitmap(CDC::FromHandle(pdc.m_ps.hdc), rc.Width(), rc.Height());
- dc.SelectObject(bm);
- CBrush b;
- b.CreateSolidBrush(RGB(0xff,0xff,0xff));
- dc.FillRect(rc, &b);
- ASSERT(m_currentAddress >= 0);
- ASSERT(m_topindex >= 0);
- dc.SelectObject(m_Font);
- int height = 0;
- int x,y;
- char buf[256];
- x = rc.TopLeft().x;
- y = rc.TopLeft().y;
- dc.SetBoundsRect(&rc, DCB_DISABLE);
- if(m_pData)
- {
- //
- // get char dimensions
- //
- if(m_bUpdate)
- {
- dc.GetCharWidth('0', '0', &m_nullWidth);
- CSize sz = dc.GetTextExtent("0", 1);
- m_lineHeight = sz.cy;
-
- m_offHex = m_bShowAddress ? (m_bAddressIsWide ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
- m_offAscii = m_bShowAddress ? (m_bAddressIsWide ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
- m_offAscii += m_bShowHex ? (m_bpr * 3 * m_nullWidth) : 0;
- m_lpp = rc.Height() / m_lineHeight;
- m_bHalfPage = FALSE;
- if(m_lpp * m_bpr > m_length)
- {
- m_lpp = (m_length + (m_bpr/2)) / m_bpr ;
- if(m_length % m_bpr != 0)
- {
- m_bHalfPage = TRUE;
- m_lpp++;
- }
- }
- m_bUpdate = FALSE;
- UpdateScrollbars();
- }
- TRACE("%i %i\n", m_topindex, m_selStart);
-
- height = rc.Height() / m_lineHeight;
- height *= m_lineHeight;
- if(m_bShowAddress)
- {
- char fmt[8] = {'%','0','8','l','X'};
- fmt[2] = m_bAddressIsWide ? '8' : '4';
- int w = m_bAddressIsWide ? 8 : 4;
- y = 0;
- CRect rcd = rc;
- rcd.TopLeft().x = m_offAddress;
- for(int i = m_topindex; (i < m_length) && (rcd.TopLeft().y < height); i+= m_bpr)
- {
- sprintf(buf, fmt, i);
- dc.DrawText(buf, w, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
- rcd.TopLeft().y += m_lineHeight;
- }
- }
- if(m_bShowHex)
- {
- y = 0;
- CRect rcd = rc;
- rcd.TopLeft().x = x = m_offHex;
- if(m_selStart != 0xffffffff && (m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW))
- {
- int i;
- int n = 0;
- int selStart = m_selStart, selEnd = m_selEnd;
- if(selStart > selEnd)
- selStart ^= selEnd ^= selStart ^= selEnd;
- for(i = m_topindex; (i < selStart) && (y < height); i++)
- {
- char* p = &buf[0];
- TOHEX(m_pData[i], p);
- *p++ = ' ';
- dc.TextOut(x, y, buf, 3);
- x += m_nullWidth * 3;
- n++;
- if(n == m_bpr)
- {
- n = 0;
- x = m_offHex;
- y += m_lineHeight;
- }
- }
- dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
- dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
- for(; (i < selEnd) && (i < m_length) && (y < height); i++)
- {
- char* p = &buf[0];
- TOHEX(m_pData[i], p);
- *p++ = ' ';
- dc.TextOut(x, y, buf, 3);
- x += m_nullWidth * 3;
- n++;
- if(n == m_bpr)
- {
- n = 0;
- x = m_offHex;
- y += m_lineHeight;
- }
- }
- dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
- dc.SetBkColor(GetSysColor(COLOR_WINDOW));
- for(; (i < m_length) && (y < height); i++)
- {
- char* p = &buf[0];
- TOHEX(m_pData[i], p);
- *p++ = ' ';
- dc.TextOut(x, y, buf, 3);
- x += m_nullWidth * 3;
- n++;
- if(n == m_bpr)
- {
- n = 0;
- x = m_offHex;
- y += m_lineHeight;
- }
- }
- }
- else
- {
- for(int i = m_topindex; (i < m_length) && (rcd.TopLeft().y < height);)
- {
- char* p = &buf[0];
- for(int n = 0; (n < m_bpr) && (i < m_length); n++)
- {
- TOHEX(m_pData[i], p);
- *p++ = ' ';
- i++;
- }
- while(n < m_bpr)
- {
- *p++ = ' '; *p++ = ' '; *p++ = ' ';
- n++;
- }
- dc.DrawText(buf, m_bpr*3, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
- rcd.TopLeft().y += m_lineHeight;
- }
- }
- }
- if(m_bShowAscii)
- {
- y = 0;
- CRect rcd = rc;
- rcd.TopLeft().x = x = m_offAscii;
- if(m_selStart != 0xffffffff && m_currentMode == EDIT_ASCII)
- {
- int i;
- int n = 0;
- int selStart = m_selStart, selEnd = m_selEnd;
- if(selStart > selEnd)
- selStart ^= selEnd ^= selStart ^= selEnd;
- for(i = m_topindex; (i < selStart) && (y < height); i++)
- {
- buf[0] = isprint(m_pData[i]) ? m_pData[i] : '.';
- dc.TextOut(x, y, buf, 1);
- x += m_nullWidth;
- n++;
- if(n == m_bpr)
- {
- n = 0;
- x = m_offAscii;
- y += m_lineHeight;
- }
- }
- dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
- dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
- for(; (i < selEnd) && (y < height); i++)
- {
- buf[0] = isprint(m_pData[i]) ? m_pData[i] : '.';
- dc.TextOut(x, y, buf, 1);
- x += m_nullWidth;
- n++;
- if(n == m_bpr)
- {
- n = 0;
- x = m_offAscii;
- y += m_lineHeight;
- }
- }
- dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
- dc.SetBkColor(GetSysColor(COLOR_WINDOW));
- for(; (i < m_length) && y < height; i++)
- {
- buf[0] = isprint(m_pData[i]) ? m_pData[i] : '.';
- dc.TextOut(x, y, buf, 1);
- x += m_nullWidth;
- n++;
- if(n == m_bpr)
- {
- n = 0;
- x = m_offAscii;
- y += m_lineHeight;
- }
- }
- }
- else
- {
- for(int i = m_topindex; (i < m_length) && (rcd.TopLeft().y < height);)
- {
- char* p = &buf[0];
- for(int n = 0; (n < m_bpr) && (i < m_length); n++)
- {
- *p++ = isprint(m_pData[i]) ? m_pData[i] : '.';
- i++;
- }
- dc.DrawText(buf, n, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
- rcd.TopLeft().y += m_lineHeight;
- }
- }
- }
- }
- pdc.BitBlt(0, 0, rc.Width(), rc.Height(), &dc, 0, 0, SRCCOPY);
- }
- void CHexEdit::OnSetFocus(CWnd* pOldWnd)
- {
- if(m_pData && !IsSelected())
- {
- if(m_editPos.x == 0 && m_bShowAddress)
- CreateAddressCaret();
- else
- CreateEditCaret();
- SetCaretPos(m_editPos);
- ShowCaret();
- }
- CWnd::OnSetFocus(pOldWnd);
- }
- void CHexEdit::OnKillFocus(CWnd* pNewWnd)
- {
- DestroyCaret();
- CWnd::OnKillFocus(pNewWnd);
- }
- void CHexEdit::OnSize(UINT nType, int cx, int cy)
- {
- CEdit::OnSize(nType, cx, cy);
- }
- void CHexEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- pScrollBar;
- if(!m_pData)
- return;
- int oa = m_topindex;
- switch(nSBCode)
- {
- case SB_LINEDOWN:
- if(m_topindex < m_length - m_lpp*m_bpr)
- {
- //ScrollWindow(0, -m_lineHeight, rc);
- m_topindex += m_bpr;
- RedrawWindow();
- }
- break;
-
- case SB_LINEUP:
- if(m_topindex > 0)
- {
- //ScrollWindow(0, m_lineHeight, rc);
- m_topindex -= m_bpr;
- RedrawWindow();
- }
- break;
-
- case SB_PAGEDOWN:
- if(m_topindex < m_length - m_lpp*m_bpr)
- {
- m_topindex += m_bpr * m_lpp;
- if(m_topindex > m_length - m_lpp*m_bpr)
- m_topindex = m_length - m_lpp*m_bpr;
- RedrawWindow();
- }
- break;
- case SB_PAGEUP:
- if(m_topindex > 0)
- {
- m_topindex -= m_bpr * m_lpp;
- if(m_topindex < 0)
- m_topindex = 0;
- RedrawWindow();
- }
- break;
- case SB_THUMBTRACK:
- m_topindex = nPos * m_bpr;
- RedrawWindow();
- break;
- }
- ::SetScrollPos(this->m_hWnd, SB_VERT, m_topindex / m_bpr, TRUE);
- if(!m_bNoAddressChange)
- m_currentAddress += (m_topindex - oa);
- RepositionCaret(m_currentAddress);
- }
- void CHexEdit::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- nSBCode;nPos; pScrollBar;
- }
- UINT CHexEdit::OnGetDlgCode()
- {
- return DLGC_WANTALLKEYS;
- }
- BOOL CHexEdit::PreCreateWindow(CREATESTRUCT& cs)
- {
- cs.style |= WS_HSCROLL|WS_VSCROLL;
- return CEdit::PreCreateWindow(cs);
- }
- BOOL CHexEdit::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
- {
- dwStyle |= WS_HSCROLL|WS_VSCROLL;
- BOOL bRet = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
- if(bRet)
- SetFont(&m_Font);
- return bRet;
- }
- BOOL CHexEdit::OnEraseBkgnd(CDC* pDC)
- {
- pDC;
- return TRUE;
- }
- void CHexEdit::SetOptions(BOOL a, BOOL h, BOOL c, BOOL w)
- {
- m_bShowHex = h;
- m_bShowAscii = c;
- m_bShowAddress = a;
- m_bAddressIsWide= w; // 4/8 byte address
- m_bUpdate = TRUE;
- }
- void CHexEdit::SetBPR(int bpr)
- {
- m_bpr = bpr;
- m_bUpdate = TRUE;
- }
- void CHexEdit::OnLButtonDown(UINT nFlags, CPoint point)
- {
- SetFocus();
- if(!m_pData)
- return;
- if(nFlags & MK_SHIFT)
- {
- m_selStart = m_currentAddress;
- }
- CPoint pt = CalcPos(point.x, point.y);
- if(pt.x > -1)
- {
- m_editPos = pt;
- pt.x *= m_nullWidth;
- pt.y *= m_lineHeight;
-
- if(pt.x == 0 && m_bShowAddress)
- CreateAddressCaret();
- else
- CreateEditCaret();
- SetCaretPos(pt);
- if(nFlags & MK_SHIFT)
- {
- m_selEnd = m_currentAddress;
- if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
- m_selEnd++;
- RedrawWindow();
- }
- }
- if(!(nFlags & MK_SHIFT))
- {
- if(DragDetect(this->m_hWnd, point))
- {
- m_selStart = m_currentAddress;
- m_selEnd = m_selStart;
- SetCapture();
- }
- else
- {
- BOOL bsel = m_selStart != 0xffffffff;
- m_selStart = 0xffffffff;
- m_selEnd = 0xffffffff;
- if(bsel)
- RedrawWindow();
- }
- }
- if(!IsSelected())
- {
- ShowCaret();
- }
- }
- void CHexEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
- {
- nFlags; point;
- }
复制代码
|