doc_and_tools/tools/apps/hgjson/hex_edit.cpp

180 lines
3.8 KiB
C++
Raw Normal View History

// hex_edit.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "hex_edit.h"
#include <file/file_util.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// hex_edit
std::wstring hex_edit::fn_prop_key = L"hex-edit-proc";
std::wstring hex_edit::obj_prop_key = L"hex-edit-object";
const wchar_t* hex_edit::hex_z = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£ãģţ<EFBFBD>";
const wchar_t* hex_edit::hex_e = L"0123456789ABCDEF";
hex_edit::hex_edit() : hwnd_(NULL), hz_(false)
{}
hex_edit::~hex_edit()
{
clear();
}
LRESULT __stdcall hex_edit::hex_edit_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
wchar_t now[40] = { 0 };
int len = 0, sel = 0, max_len = 4;
bool all_digit = true;
WNDPROC wndproc = (WNDPROC)GetPropW(hwnd, hex_edit::fn_prop_key.c_str());
hex_edit* obj = (hex_edit*)GetPropW(hwnd, hex_edit::obj_prop_key.c_str());
std::wstring buf(L"");
const wchar_t* hex = obj->hz_ ? hex_edit::hex_z : hex_edit::hex_e;
if (!wndproc)
wndproc = DefWindowProcW;
switch (msg)
{
case WM_CHAR:
GetWindowTextW(hwnd, now, _countof(now));
len = lstrlenW(now);
sel = SendMessage(hwnd, EM_GETSEL, 0, 0);
sel = ((sel >> 16) & 0x0ff) - (sel & 0x0ffff);
if (wp >= ' ' && len - sel >= max_len)
return 0;
if (wp >= '0' && wp <= '9')
wp = hex[wp - '0'];
else if (wp >= 'A' && wp <= 'F')
wp = hex[wp - 'A' + 10];
else if (wp >= 'a' && wp <= 'f')
wp = hex[wp - 'a' + 10];
else if (wp >= ' ')
return 0;
break;
case WM_COPY:
return 0;
case WM_PASTE:
{
size_t l = 0;
if (file_util::get_clipboard(NULL, &l, CF_UNICODETEXT) == ERROR_INSUFFICIENT_BUFFER)
{
buf.resize(l + 4);
l++;
if (file_util::get_clipboard(&buf[0], &l, CF_UNICODETEXT))
l = 0;
}
if (l == 0)
return 0;
lp = (LPARAM)&buf[0];
msg = WM_SETTEXT;
}
case WM_SETTEXT:
for (int i = 0; len < max_len + 1 && i < lstrlenW((wchar_t*)lp); ++i)
{
wchar_t ch = ((wchar_t*)lp)[i];
if (ch >= '0' && ch <= '9')
now[len++] = hex[ch - '0'];
else if (ch >= 'A' && ch <= 'F')
{
now[len++] = hex[ch - 'A' + 10];
all_digit = false;
}
else if (ch >= 'a' && ch <= 'f')
{
now[len++] = hex[ch - 'a' + 10];
all_digit = false;
}
else
break;
}
if (len == 0)
return 0;
if (/*len == max_len + 1 &&*/ all_digit)
{
sel = _wtoi(now);
//if (sel <= 0x0ffff)
{
now[max_len] = 0;
for (int l = max_len - 1; l >= 0; --l, sel >>= 4)
now[l] = hex[sel % 16];
}
//else
// now[max_len] = 0;
}
lp = (LPARAM)now;
break;
}
return wndproc(hwnd, msg, wp, lp);
}
HWND hex_edit::attach(HWND hwnd)
{
HWND old = hwnd_;
clear();
hwnd_ = hwnd;
if (IsWindow(hwnd_))
{
WNDPROC proc = (WNDPROC)GetWindowLong(hwnd_, GWL_WNDPROC);
SetPropW(hwnd_, hex_edit::obj_prop_key.c_str(), (HANDLE)this);
SetPropW(hwnd_, hex_edit::fn_prop_key.c_str(), (HANDLE)proc);
SetWindowLong(hwnd_, GWL_WNDPROC, (LONG)(FARPROC)hex_edit::hex_edit_proc);
}
return old;
}
void hex_edit::clear(void)
{
if (IsWindow(hwnd_))
{
WNDPROC proc = (WNDPROC)GetPropW(hwnd_, hex_edit::fn_prop_key.c_str());
SetWindowLong(hwnd_, GWL_WNDPROC, (LONG)(FARPROC)proc);
SetPropW(hwnd_, hex_edit::obj_prop_key.c_str(), NULL);
SetPropW(hwnd_, hex_edit::fn_prop_key.c_str(), NULL);
}
hwnd_ = NULL;
}
unsigned hex_edit::value(void)
{
unsigned v = 0;
if (IsWindow(hwnd_))
{
wchar_t buf[20] = { 0 };
GetWindowTextW(hwnd_, buf, _countof(buf) - 1);
for (int i = 0; i < _countof(buf) && buf[i]; ++i)
{
if (buf[i] >= L'0' && buf[i] <= L'9')
{
v <<= 4;
v += buf[i] - L'0';
}
else if (buf[i] >= L'A' && buf[i] <= L'F')
{
v <<= 4;
v += buf[i] - L'A' + 10;
}
else if (buf[i] >= L'a' && buf[i] <= L'f')
{
v <<= 4;
v += buf[i] - L'a' + 10;
}
else
break;
}
}
return v;
}
void hex_edit::set_value(unsigned v)
{
if (IsWindow(hwnd_))
{
SetWindowTextW(hwnd_, std::to_wstring(v).c_str());
}
}