这是一个带有所有者绘制 ListBox (size=fixed-sized, sort=false)的解决方案
class CListHex : public CListBox
{
public:
std::vector<BYTE> Buffer;
CRect SaveItemRect;
CEdit Edit;
int Index;
void setup()
{
if (Edit.m_hWnd && IsWindow(Edit.m_hWnd))
return;
Edit.Create(WS_CHILD | WS_BORDER | ES_CENTER, CRect(0, 0, 0, 0), this, 1);
Edit.SetFont(GetFont());
Edit.SetLimitText(2);
SetItemHeight(0, 21);
}
void read()
{
HANDLE hfile = CreateFile(L"in.txt", GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE) //****CHANGED****
{
DWORD size = GetFileSize(hfile, NULL);
Buffer.resize(size);
ReadFile(hfile, &Buffer[0], size, 0, NULL);
CloseHandle(hfile);
for (int i = 0; i <= (int)Buffer.size() / 16; i++)
AddString(0);
}
else
{
MessageBox(L"error");
}
}
void write()
{
HANDLE hFile = CreateFile(L"out.txt", GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE) //****CHANGED****
{
WriteFile(hFile, &Buffer[0], Buffer.size(), 0, 0);
CloseHandle(hFile);
}
else
{
MessageBox(L"error");
}
}
void DrawItem(LPDRAWITEMSTRUCT di)
{
SaveItemRect = di->rcItem;
CRect r = di->rcItem;
r.right = r.left + r.Width() / 16;
HBRUSH brush = (HBRUSH)SelectObject(di->hDC, GetStockObject(WHITE_BRUSH));
FillRect(di->hDC, &di->rcItem, brush);
for (int i = 0; i < 16; i++)
{
unsigned int cursor = di->itemID * 16 + i;
if (cursor >= Buffer.size())
break;
CString s;
s.Format(L"%02X", Buffer[cursor]);
DrawText(di->hDC, s, s.GetLength(), r, DT_EDITCONTROL|DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
}
void OnLButtonDown(UINT f, CPoint p)
{
CListBox::OnLButtonDown(f, p);
setup();
int w = SaveItemRect.Width() / 16;
CRect r = SaveItemRect;
r.right = r.left + w;
for (int i = 0; i < 16; i++)
{
if (r.PtInRect(p))
{
unsigned int index = GetCurSel() * 16 + i;
if (index >= Buffer.size())
return;
Index = index;
GetParent()->SetRedraw(0);
CString s;
s.Format(L"%02X", Buffer[Index]);
Edit.SetWindowText(s);
Edit.SetWindowPos(0, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER | SWP_NOREDRAW | SWP_SHOWWINDOW);
Edit.SetFocus();
GetParent()->SetRedraw(1);
break;
}
r.OffsetRect(w, 0);
}
}
//******CHANGED******
void MeasureItem(LPMEASUREITEMSTRUCT m) { m->itemHeight=21; }
int CompareItem(LPCOMPAREITEMSTRUCT) { return 0; }
//******CHANGED******
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CListHex, CListBox)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
另外,
- 您可以为
CEdit 添加子类
- 覆盖
CMyEdit::OnKillFocus() 以关闭编辑框
- 覆盖
CMyEdit::OnChar 以仅接受十六进制字符
- 读取编辑字符串然后转换为
unsigned char 并将其分配给Buffer[Index]。
- 覆盖
CListHex::OnVScroll 以关闭编辑框
//已更改:
要创建函数,请尝试手动执行,以确保它获得正确的标志:
list.Create(WS_VSCROLL | WS_BORDER | WS_CHILD | WS_VISIBLE | LBS_USETABSTOPS | LBS_OWNERDRAWFIXED , CRect(10, 10, 450, 350), this, 1001);
list.read();