// hex_edit.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "hex_edit.h" #include #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"£°£±£²£³£´£µ£¶£·£¸£¹£Á£Â£Ã£Ä£Å£Æ"; 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()); } }