HexView.inc is a utility that that is meant to be incoporated to your code while debugging.
It's purpose is to show data in hexadecimal and ansi form, like an HexEdit program.
No global value are used.
You may invoke HexView* functions via a memory pointer and data lenght, or via a string.
Four main output are available...
1) HexViewClip() return data in the clipboard.
2) HexViewCon() retur a string (this can be printed on a console).
3) HexViewBox() show a hooked fixed font MessageBox.
4) HexViewDlg() show a dialog with scrollbar, tooltips, and an optional info text message.
Compiled with 0.6.0 2023-06-04T22:11:35 - oxygen.dll - OxygenBasic0605.zip
Compatible 0.7.0 2023-06-15T07:08:15 - oxygen64.dll - OxygenBasic070.zip
HexView.inc
// KickUseDirectivesFrom "D:\Dev\Oxygen\o2\~code\Hex\HexViewDemoDialog01.o2bas" //HexViewDemoConsole.o2bas
// KickEnd
// Compiled with 0.6.0 2023-06-04T22:11:35 - oxygen.dll - OxygenBasic0605.zip
// Compatible 0.7.0 2023-06-15T07:08:15 - oxygen64.dll - OxygenBasic070.zip
// HexView.inc is a utility that that is meant to be incoporated to your code while debugging.
// It's purpose is to show data in hexadecimal and ansi form, like an HexEdit program.
// No global value are used.
// You may invoke HexView* functions via a memory pointer and data lenght, or via a string.
// Four main output are available...
// 1) HexViewClip() return data in the clipboard.
// 2) HexViewCon() retur a string (this can be printed on a console).
// 3) HexViewBox() show a hooked fixed font MessageBox.
// 4) HexViewDlg() show a dialog with scrollbar, tooltips, and an optional info text message.
// HexViewCon() and HexViewClip() will return CharToOem() data when called from a console.
// MessageBox and Dialog are themed by stealing Shell32.dll manifest,
// the output window will be centered in the calling window or on display if no handle is supplied,
// the calling window icon will be used.
// Dialog unthemed grip control is used for better grip.
// Calling syntaxe (All functions are overloaded):
// HexViewClip(ptr sData, len(sData))
// HexViewClip(string sData) 'Overload
// HexViewCon(ptr sData, len(sData))
// HexViewCon(string sData) 'Overload
// HexViewBox(ptr sData, len(sData))
// HexViewBox(string sData) 'Overload
// HexViewDlg(ptr sData, len(sData))
// HexViewDlg(string sData) 'Overload
uses Dialogs
uses MinWin
uses Tooltips
%Edit 101
%Clip 201
%Grip 901
%SIZE_MINIMIZED 1
%SIZE_MAXIMIZED 2
%DEFAULT_GUI_FONT 17
%GCL_HICON -14
%GCL_HICONSM -34
%HCBT_CREATEWND 3
%HCBT_DESTROYWND 4
%HCBT_ACTIVATE 5
%WH_CBT 5
%HWND_DESKTOP 0
%SBS_SIZEGRIP 0x0010
%SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004
%SM_CXVSCROLL 2
%SM_CYHSCROLL 3
%WM_GETICON 0x7F
%SWP_NOSIZE 1
%HWND_TOP 0
%WM_APP 0x8000
%WM_NCLBUTTONDOWN 0x0A1
%HTCAPTION 2
%MONITOR_DEFAULTTONEAREST 2
%EM_GETSELTEXT WM_USER + 62
%WM_COPY 0x301
%WM_MOUSEACTIVATE 0xH21
%WM_NCDESTROY 0x082
%DLGC_HASSETSEL 0x8
%WM_GETDLGCODE 0x0087
%WM_NCACTIVATE 0x086
%ICC_STANDARD_CLASSES 0x00004000
%MAXWORD 0xFFFF
%WM_SETCURSOR 0x20
%TTF_DI_SETITEM 0x8000
%TTF_TRANSPARENT 0x0100
%SWP_NOACTIVATE 0x0010
%TTM_SETDELAYTIME WM_USER + 3
%TTM_ACTIVATE WM_USER + 1
%TTDT_INITIAL 3
%TTDT_AUTOPOP 2
%TTDT_RESHOW 1
%TTM_UPDATETIPTEXTA WM_USER + 12
%TTM_UPDATETIPTEXTW WM_USER + 57
%TTM_POP %WM_USER + 28
%TTM_POPUP WM_USER + 34
%TTM_UPDATE WM_USER + 29
%TTM_TRACKACTIVATE WM_USER + 17
%PROCESSOR_ARCHITECTURE_INTEL 0
%ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID 0x00000004
%ACTCTX_FLAG_RESOURCE_NAME_VALID 0x00000008
%ACTCTX_FLAG_SET_PROCESS_DEFAULT 0x00000010
TYPE MONITORINFO
DWORD cbSize
RECT rcMonitor
RECT rcWork
DWORD dwFlags
END TYPE
type CBT_CREATEWND
CREATESTRUCT ptr lpcs
sys hWndInsertAfter
end type
type ACTCTXA 'dword fill
ulong cbSize
dword dwFlags
zstring ptr lpSource
word wProcessorArchitecture
word wLangId
zstring ptr lpAssemblyDirectory
zstring ptr lpResourceName
zstring ptr lpApplicationName
sys hModule
end type
! CreateActCtxA lib "kernel32.dll" alias "CreateActCtxA"(pActCtx as ACTCTXA) as dword
! SetWindowTheme lib "UxTheme.dll" alias "SetWindowTheme"
(BYVAL hwnd as sys, pszSubAppName as wzstring, pszSubIdList as wzstring) as long
! GetMonitorInfoA lib "user32.dll" alias "GetMonitorInfoA"
(BYVAL hMonitor as sys, lpmi as sys) as LONG 'lpmi as MONITORINFO
macro makeDword(lo, hi)
dword (hi << 16) + lo
end macro
'_____________________________________________________________________________
SUB ThemeEnable() 'steal CommonControl6 theme from Shell32.dll
ACTCTXA ActivationContext
zstring zSource[15]
zstring zFolder[MAX_PATH]
GetSystemDirectory(@zFolder, MAX_PATH)
zSource = "Shell32.dll" 'the PE image to be used to create the activation context.
ActivationContext.cbSize = SIZEOF(ACTCTXA)
ActivationContext.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID |
ACTCTX_FLAG_SET_PROCESS_DEFAULT
ActivationContext.lpSource = @zSource
ActivationContext.lpAssemblyDirectory = @zFolder 'where to to perform private assembly probing.
ActivationContext.lpResourceName = 124 'resource manifest id
ActivationContext.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL
ActivationContext.wLangId = 0
ActivationContext.lpApplicationName = 0
ActivationContext.hModule = 0
ActivateActCtx(CreateActCtxA(ActivationContext), 0)
END SUB
'____________________________________________________________________________
function CenterWindow(byval sys hParent, byval sys hChild, long SetWindowPosition) as point
rect rcParent, rcChild, long ParentWidth, ParentHeight, ClildWidth, ChildHeight
sys hMonitor, POINT pt, MONITORINFO MonitorSpec
if hParent = 0 then 'No parent so center on the right screen monitor
GetCursorPos @pt
hMonitor = MonitorFromPoint(byval pt, MONITOR_DEFAULTTONEAREST)
MonitorSpec.cbsize = sizeof(MONITORINFO)
MonitorSpec.dwFlags = MONITOR_DEFAULTTONEAREST
GetMonitorInfoA(hMonitor, @MonitorSpec)
rcParent = MonitorSpec.rcMonitor 'Get parent rect
else
GetWindowRect(hParent, rcParent) 'Get parent rect
endif
ParentWidth = rcParent.right - rcParent.left
ParentHeight = rcParent.bottom - rcParent.top
GetWindowRect(hChild, rcChild)
ClildWidth = rcChild.right - rcChild.left
ChildHeight = rcChild.bottom - rcChild.top
POINT WindowPosition
WindowPosition.x = rcParent.left + (ParentWidth - ClildWidth) \ 2
WindowPosition.y = rcParent.top + (ParentHeight - ChildHeight) \ 2
if SetWindowPosition
SetWindowPos(hChild, HWND_TOP, WindowPosition.x, WindowPosition.y, 0, 0, SWP_NOSIZE)
endif
function = WindowPosition
end function
'____________________________________________________________________________
function HexViewTextFormat(sys pDataIn, long LenDataIn) as string 'format the output string to be seen like in a hex editor
string sHexView, sUnPrintableChar, byte bChar
long LineCount, LineIndex, CharIndex, ofset, middle
indexbase 0 'array base index
byte pByte[] at pDataIn 'view the string as an array of bytes
sUnPrintableChar = chr(0, 1, 2, 3, 7, 9, 10, 13, 27, 28, 29, 30, 31, 127, 129, 140, 141, 143, 144, 149, 152, 157) 'edit according to font viewable characters
LineCount = ceil(LenDataIn / 16) '16 char represented in a line
sHexView = space(LineCount * 77) 'LineLenCrLf77, LineLen75 -> used in WM_SETCURSOR
for LineIndex = 0 TO LineCount - 1
mid(sHexView, ofset + 01) = hex(LineIndex * 16, 4) '0x0000 is offset
asc(sHexView, ofset + 05) = 58 'for ":"
asc(sHexView, ofset + 31) = 45 'for "-"
asc(sHexView, ofset + 57) = 59 'for ";"
asc(sHexView, ofset + 76) = 13 'for cr
asc(sHexView, ofset + 77) = 10 'for lf
for CharIndex = 0 TO 15 'work with 16 characters by line
if CharIndex + LineIndex * 16 = LenDataIn then exit for 'end of data reached
bChar = pByte[CharIndex + LineIndex * 16] 'get the asc value of the char
if CharIndex = 8 then middle = 1 'for middle dash or middle space
mid(sHexView, ofset + 07 + CharIndex * 3 + middle * 2) = hex(bChar, 2) 'hex value of byte 00~FF
if instr(sUnPrintableChar, chr(bChar)) then bChar = 46 '. dot if char is unprintable
asc(sHexView, ofset + 59 + CharIndex + middle ) = bChar 'write char
next
middle = 0 'reset
ofset += 77 'next line
next
sHexView = "Oxygen HexView " + sizeof(sys) * 8 + "bit - Data lenght is " &
str(LenDataIn) & " bytes." & chr(13, 10) & sHexView
function = sHexView
end function
'____________________________________________________________________________
function HexViewClip(sys pDataIn, long LenDataIn, optional string sComment) as boolean
string sDataHex = HexViewTextFormat(pDataIn, LenDataIn)
if GetConsoleCP() 'more reliable than GetConsoleWindow()
CharToOem(sDataHex, sDataHex) 'translate to console characters
endif
if len(sComment) then sDataHex = sDataHex + chr(13, 10) + sComment
if OpenClipboard(HWND_DESKTOP)
EmptyClipboard() 'emptyClipboard sets the clipboard owner to NULL; this may causes SetClipboardData to fail.
int DataLen = len(sDataHex) + 1
sys hMem = GlobalAlloc(GMEM_MOVEABLE, DataLen)
if hMem
sys pMem = GlobalLock(hMem)
copy(pMem, strptr(sDataHex, DataLen)
GlobalUnlock(hMem)
IF SetClipboardData(CF_TEXT, hMem) then function = true
endif
'clipboard engine will do GlobalFree(hClipboard) aka frees the global memory object and invalidates its handle
CloseClipboard(HWND_DESKTOP)
endif
end function
'____________________________________________________________________________
function HexViewClip(string sDataIn, optional string sComment) as boolean 'overload function
function = HexViewClip(strptr sDataIn, len(sDataIn), sComment)
end function
'______________________________________________________________________________
function HexViewCon(sys pDataIn, long LenDataIn) as string
string sDataHex = HexViewTextFormat(pDataIn, LenDataIn)
if GetConsoleCP() 'more reliable than GetConsoleWindow()
CharToOem(sDataHex, sDataHex) 'translate to console characters
endif
function = sDataHex 'return hex string
end function
'____________________________________________________________________________
function HexViewCon(string sDataIn) as string 'overload function
function = HexViewCon(strptr sDataIn, len(sDataIn))
end function
'______________________________________________________________________________
function MessageBoxProc(byval dword nCode, byval sys hWin, byval sys lparam) as sys callback 'hooked messagebox
CBT_CREATEWND ptr cbCreateWin
static CREATESTRUCT ptr WinStruct
static point Dialog
static sys hFont, hStatic, hButton, hMsgBox, hParent
static long DialogWidth, DialogHeight, LineCount
zstring zClass[64]
if nCode = 0 then hParent = hWin : LineCount = lparam 'pre init
if nCode = HCBT_CREATEWND then
@cbCreateWin = LParam 'get pointer to CBT_CREATEWND struct so we can...
@WinStruct = cbCreateWin.lpcs 'get a pointer to the CREATESTRUCT struct ...
GetClassName(hWin, zClass, Max_Path) 'for each window / control as it is created
if zClass = "#32770" 'main dialog itself
hMsgBox = hWin
static sys hIcon
if GetConsoleCP() then 'console program
hIcon = SendMessage(hParent, WM_GETICON, ICON_SMALL, 0)
else
hIcon = GetClassLongPtr(hParent, GCL_HICON)
endif
if hIcon = 0 then hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'o
SendMessage(hWin, WM_SETICON, ICON_SMALL, hIcon)
SendMessage(hWin, WM_SETICON, ICON_BIG, hIcon)
Dialog.x = 548 'dialog width
WinStruct.cx = Dialog.x 'Change dialog width
Dialog.y = (LineCount + 9) * 14 'Change dialog height
WinStruct.cy = Dialog.y 'Change dialog height
POINT ParentPos = CenterWindow(hParent, hWin, false) 'SetWindowPosition=false
'at this stage GetWindowRect() return empty in CenterWindow()
WinStruct.x = ParentPos.x - Dialog.x / 2
WinStruct.y = ParentPos.y - Dialog.y / 2
elseif zClass = "Static" then 'static control where the text appear
hStatic = hWin
WinStruct.cx = Dialog.x - 5
WinStruct.cy = Dialog.y - 90
elseif zClass = "Button" Then 'the ok button
hButton = hWin
if WinStruct.hMenu = IDOK
WinStruct.x = Dialog.x \ 2 - WinStruct.cx \ 2
WinStruct.y = Dialog.y - 60
endif
endif
elseif nCode = HCBT_ACTIVATE then
if hFont = 0 'initiate fixed width font
hFont = CreateFont(14, 0, 'Height 14 = 9, 16=12, 15=11, 14=11, Width usually 0,
0, 0, 'Escapement(angle), Orientation
0, 0, 0, 0, 'Bold, Italic, Underline, Strikethru
0, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FF_DONTCARE, "Consolas") 'Fixed width font - "Segoe UI", 9 Arial Consolas
endif
SendMessage(hStatic, WM_SETFONT, hFont, 0)
SendMessage(hButton, WM_SETFONT, hFont, 0)
SetWindowText(GetDlgItem(hMsgBox, IDOK), "Close")
elseif nCode = HCBT_DESTROYWND THEN
DeleteObject(hFont) : hFont = 0
endif
end function
'_____________________________________________________________________________
function HexViewBox(sys hParent, sys pDataIn, long LenDataIn) as string
long index, LineCount
string sDataHex = HexViewTextFormat(pDataIn, LenDataIn)
for index = 1 to len(sDataHex)
if asc(sDataHex, index) = 13 then LineCount ++
next
ThemeEnable()
MessageBoxProc(0, byval hParent, byval LineCount) 'dirty trick to send hParent + LineCount to the hook and avoid global
sys hMsgBoxHook = SetWindowsHookEx(WH_CBT, @MessageBoxProc, GetModuleHandle(""), GetCurrentThreadId())
MessageBox(hParent, sDataHex, "Oxygen HexView " + sizeof(sys) * 8 + "bit - Data lenght is " &
str(LenDataIn) & " bytes.", MB_OK | MB_SYSTEMMODAL | MB_TOPMOST)
UnhookWindowsHookEx(hMsgBoxHook)
function = sDataHex 'return string for convenience
end function
'____________________________________________________________________________
function HexViewBox(sys hParent, string sDataIn) as string 'overload function
function = HexViewBox(hParent, strptr sDataIn, len(sDataIn))
end function
'______________________________________________________________________________
function EditProc(sys hEdit, uint wMsg, sys wParam, sys lParam) as sys callback
static sys pEditProc
select case wMsg
case WM_NULL
if hEdit = 0 and pEditProc = 0 then pEditProc = wParam : return(0) 'get pEditProc
case WM_NCDESTROY
SetWindowLongPtr(hEdit, GWL_WNDPROC, pEditProc) 'unsubclass edit
case WM_LBUTTONDOWN
SetFocus(hEdit) 'make selection possible on first click when focus is not on the Edit control
case WM_CHAR
select case wparam
case 1 'Control-A
SendMessage(hEdit, EM_SETSEL, 0, - 1) 'Select everything
return 0
end select
end select
function = CallWindowProc(pEditProc, hEdit, wMsg, wParam, lParam)
end function
'_____________________________________________________________________________
function HexViewDlgProc(sys hDlg, uint uMsg, sys wParam, sys lParam) as int callback
static rect ButtonRect
static sys hIcon, hFont, hParent, hEdit, hToolTip
static point GripSize
static long SelStart, SelEnd
static TOOLINFO ToolTipInfo
static string sToolTip
select case uMsg
case WM_APP
if hDlg = 0 and hParent = 0 then hParent = wParam
return 0
case WM_INITDIALOG
hEdit = GetDlgItem(hDlg, Edit)
'Subclass listbox with in a one liner, no global variables needed...
EditProc(0, WM_NULL, SetWindowLongPtr(hEdit, GWL_WNDPROC, @EditProc), 0)
hToolTip = CreateWindowEx(0, "Tooltips_Class32", "", TTS_ALWAYSTIP, 0, 0, 0, 0, 0,
null, GetModuleHandle(null), null)
ToolTipInfo.cbSize = sizeof(TOOLINFO)
ToolTipInfo.uFlags = TTF_SUBCLASS | TTF_IDISHWND
ToolTipInfo.hWnd = hDlg
ToolTipInfo.uId = hEdit
ToolTipInfo.hinst = GetModuleHandle(null)
sToolTip = "Hexview"
ToolTipInfo.lpszText = strptr sToolTip
SendMessage(hToolTip, TTM_ADDTOOL, 0, &ToolTipInfo)
SetWindowPos(hToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE)
SendMessage(hToolTip, TTM_SETMAXTIPWIDTH, 0, 300)
SendMessage(hToolTip, TTM_SETDELAYTIME, TTDT_INITIAL, 100) 'stationary within a tool's bounding rectangle before the tooltip window appears.
SendMessage(hToolTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 15000) 'remains visible if the pointer is stationary
SendMessage(hToolTip, TTM_SETDELAYTIME, TTDT_RESHOW, 50) 'subsequent tooltip windows to appear
SendMessage(hToolTip, TTM_ACTIVATE, true, 0)
hFont = CreateFont(14, 0, 'Height 14 = 9, 16=12, 15=11, 14=11, Width usually 0,
0, 0, 'Escapement(angle), Orientation
0, 0, 0, 0, 'Bold, Italic, Underline, Strikethru
0, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FF_DONTCARE, "Consolas") 'Fixed width font
SendDlgItemMessage(hDlg, Edit, WM_SETFONT, hFont, 0)
SendDlgItemMessage(hDlg, IDCANCEL, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendDlgItemMessage(hDlg, Clip, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
GetWindowRect(GetDlgItem(hDlg, IDCANCEL), ButtonRect) 'Keep PushButton size as defined in winmain()
ButtonRect.right = ButtonRect.right - ButtonRect.left : ButtonRect.left = 0
ButtonRect.bottom = ButtonRect.bottom - ButtonRect.top : ButtonRect.top = 0
GripSize.x = GetSystemMetrics(SM_CXVSCROLL) 'Width of grip
GripSize.y = GetSystemMetrics(SM_CYHSCROLL) 'Height of grip
SetWindowTheme(GetDlgItem(hDlg, Grip), " ", " ")
CenterWindow(hParent, hDlg, true) 'SetWindowPosition-true as point
if GetConsoleCP() then
hParent = GetConsoleWindow()
hIcon = SendMessage(hParent, WM_GETICON, ICON_SMALL, 0)
SendMessage(hDlg, WM_SETICON, ICON_SMALL, hIcon)
SendMessage(hDlg, WM_SETICON, ICON_BIG, hIcon)
else
hIcon = GetClassLongPtr(hParent, GCL_HICON)
SetClassLongPtr(hDlg, GCL_HICON, hIcon)
SendMessage(hDlg, WM_SETICON, ICON_SMALL, hIcon)
endif
if hIcon = 0 then hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'o
SetClassLongPtr(hDlg, GCL_HICON, hIcon)
return true
case WM_COMMAND
select case loword(wParam)
case Edit
select case hiword(wParam)
case EN_KILLFOCUS
SendDlgItemMessage(hDlg, Edit, EM_GETSEL, @SelStart, @SelEnd)
case EN_SETFOCUS
SendDlgItemMessage(hDlg, Edit, EM_SETSEL, SelStart, SelEnd)
end select
case Clip
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
SendDlgItemMessage(hDlg, Edit, EM_GETSEL, @SelStart, @SelEnd)
if SelStart = SelEnd then 'No selection made so, copy the whole text
SendDlgItemMessage(hDlg, Edit, EM_SETSEL, 0, -1)
SendDlgItemMessage(hDlg, Edit, WM_COPY, 0, 0)
SendDlgItemMessage(hDlg, Edit, EM_SETSEL, SelStart, SelEnd)
else 'Copy selection
SendDlgItemMessage(hDlg, Edit, WM_COPY, 0, 0)
endif
endif
case IDCANCEL
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
EndDialog(hDlg, null)
endif
end select
case WM_SETCURSOR
'wParam handle to window
'lParam lo hit-test code like HTCLIENT, HTMENU, HTCAPTION, HTGROWBOX, HTTOP, etc
'lParam hi mouse message like WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_RBUTTONUP, WM_XBUTTONDOWN, etc
if wParam = hEdit then
static long CharIndexPrev, LineIndex, LineIndexPrev
static word LineLen
static string sLine
long CharIndex
point pt
GetCursorPos(pt)
ScreenToClient(hEdit, pt)
'char index in lowword, line index in highword
LineIndex = SendMessage(hEdit, EM_CHARFROMPOS, 0, makeDword(pt.X, pt.Y))
CharIndex = loword(LineIndex)
if CharIndex <> CharIndexPrev then
sToolTip = ""
LineIndex = hiword(LineIndex)
long CharCountInPreceedingLine = SendMessage(hEdit, EM_LINEINDEX, LineIndex, 0)
long ColIndex = CharIndex - CharCountInPreceedingLine
if LineIndex <> LineIndexPrev then 'cursor on a new line
'Get whole line...
LineLen = SendMessage(hEdit, EM_LINELENGTH, CharIndex, 0)
sLine = nuls(2 + LineLen)
copyn strptr sLine, @LineLen, 2 'Aka mak_word(2)
SendMessage(hEdit, EM_GETLINE, LineIndex, strptr sLine)
sLine = left(sLine, len(sLine) - 2)
LineIndexPrev = LineIndex
endif
if LineLen = 75 then 'check if lenght of data line is wright
if asc(sLine, 5) = 58 then 'check if fifth char is ":"
if ColIndex < 75 then 'check invalid ColIndex
long hexOffset = 0
if ColIndex < 4 then 'row index
sToolTip = left(sLine, 4)
sToolTip = "0x" + sToolTip + " (" + str(val("0x" + sToolTip)) + ")"
elseif ColIndex = 4 | ColIndex = 30 | ColIndex = 56 | ColIndex = 57 | ColIndex = 66 then 'char [: -;]
'sToolTip will be "", aka do nothing
elseif ColIndex < 56 then 'hex byte numbers
if asc(sLine, ColIndex + 1) > 32 then 'if cursor is not on a space
hexOffset = 0
if asc(sLine, ColIndex) < 33 then 'this char and subsequent char are valid
ColIndex ++
endif
sToolTip = mid(sLine, ColIndex, 2)
long ToolTipVal = val("0x" + sToolTip)
sToolTip = "0x" + sToolTip + " (" + str(ToolTipVal) + ") " + chr(ToolTipVal)
else 'sToolTip = "[s p a c e]"
'sToolTip will be "", aka do nothing
endif
else 'colIndex >= 57, on ansi text at the end
if ColIndex > 65 then hexOffset = -1 else hexOffset = 0 'halfway in ansi = halfway " - " in hex
sToolTip = mid(sLine, 7 + 3 * (ColIndex - 58) + hexOffset, 2)
if sToolTip = " " then
sToolTip = ""
else
long ToolTipVal = val("0x" + sToolTip)
sToolTip = "0x" + sToolTip + " (" + str(ToolTipVal) + ") " + chr(ToolTipVal)
endif
endif
endif
endif
endif
if len(sToolTip) and CharIndexPrev <> CharIndex then
ToolTipInfo.cbSize = sizeof(TOOLINFO)
ToolTipInfo.lpszText = strptr sToolTip
ToolTipInfo.hWnd = hDlg
ToolTipInfo.uId = hEdit
ToolTipInfo.hinst = GetModuleHandle(null)
SendMessage(hToolTip, TTM_UPDATETIPTEXTA, 0, &ToolTipInfo)
SendMessage(hToolTip, TTM_ACTIVATE, true, 0)
else
SendMessage(hToolTip, TTM_ACTIVATE, false, 0)
endif
CharIndexPrev = CharIndex
endif
endif
case WM_SIZE 'dialog size have changed
'wParam = resizing requested: SIZE_MAXHIDE, SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
'loword lParam is client area width in pixels
'hiword lParam is client area height in pixels
if wParam <> SIZE_MINIMIZED
long ClientSizeX = loword(lParam)
long ClientSizeY = hiword(lParam)
if wparam = SIZE_MAXIMIZED then 'no grip on maximized
SetWindowPos(GetDlgItem(hDlg, Grip), NULL, 0, 0, 0, 0, SWP_NOZORDER) 'size grip to zero by zero
else
SetWindowPos(GetDlgItem(hDlg, Grip), NULL, ClientSizeX - GripSize.x, 'grip to normal size
ClientSizeY - GripSize.y, GripSize.x, GripSize.y, SWP_NOZORDER)
endif
long posY = ClientSizeY - ButtonRect.bottom - 15
long posx = (ClientSizeX - ButtonRect.right) \ 2
MoveWindow(GetDlgItem(hDlg, Edit), 5, 5, ClientSizeX - 10, posY, TRUE)
MoveWindow(GetDlgItem(hDlg, IDCANCEL), posX, posY + 10,
ButtonRect.right, ButtonRect.bottom, TRUE)
MoveWindow(GetDlgItem(hDlg, Clip), PosX + 164, posY + 10,
ButtonRect.right, ButtonRect.bottom, TRUE)
endif
case WM_LBUTTONDOWN
if wParam = MK_LBUTTON then
SendMessage(hDlg, WM_NCLBUTTONDOWN, HTCAPTION, byval NULL) 'dialog drag via click down simulation on caption
endif
case WM_CLOSE
EndDialog(hDlg, null)
case WM_DESTROY
DeleteObject(hFont) : hFont = 0
end select
return 0
end function
'______________________________________________________________________________
function HexViewDlg(sys hParent, sys pDataIn, long LenDataIn, optional string sComment) as long
string sDataHex = HexViewTextFormat(pDataIn, LenDataIn)
if len(sComment) then
if LenDataIn / 16 <> LenDataIn \ 16 then sDataHex = sDataHex + chr(13, 10)
sDataHex = sDataHex + chr(13, 10) + sComment
endif
ThemeEnable() 'CommonControl6
HexViewDlgProc(0, WM_APP, hParent, 0) 'give hParent to HexViewDlgProc
Dialog(0, 0, 290, 200, "Oxygen HexView " + sizeof(sys) * 8 + "bit - Data lenght is " &
str(LenDataIn) & " bytes.", WS_OVERLAPPEDWINDOW | DS_CENTER)
PushButton("Close" , IDCANCEL, 80, 85, 40, 12)
PushButton("Clip" , Clip, 105, 85, 40, 12)
MultiLineText(sDataHex, Edit, 1, 1, 198, 80, ES_SAVESEL | ES_NOHIDESEL | ES_READONLY)
Control( "", Grip, "SCROLLBAR", WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP |
SBS_SIZEBOXBOTTOMRIGHTALIGN, 390, 290, 10, 10, 0, 0 )
CreateModalDialog(hParent, @HexViewDlgProc, 0)
end function
'______________________________________________________________________________
function HexViewDlg(sys hParent, string sDataIn, optional string sComment) as long 'overload function
function = HexViewDlg(hParent, strptr sDataIn, len(sDataIn), sComment)
end function
'______________________________________________________________________________
'
HexViewDemoDialog.o2bas
//KickCompiler "D:\Dev\Oxygen\o2\co264.exe"
//KickSwitch -64
//KickResource "D:\Dev\Oxygen\o2\~code\~~PbrDefault00xml.res"
//KickEnd
// Compiled with 0.6.0 2023-06-04T22:11:35 - oxygen.dll - OxygenBasic0605.zi
// Compatible 0.7.0 2023-06-15T07:08:15 - oxygen64.dll - OxygenBasic070.zip
type INIT_COMMON_CONTROLSEX
dword dwSize
dword dwICC
end type
%ICC_TAB_CLASSES 0x08
%ButtonDia 201
%ButtonBox 202
%ButtonClip 203
%CheckboxParent 301
%CheckboxOverLoad 302
%CheckboxTopMost 303
%SIZE_MINIMIZED 1
%DEFAULT_GUI_FONT 17
%GCL_HICON -14
%HWND_NOTOPMOST 0xFFFFFFFE
uses Dialogs 'might gpf with old version > http://forum.it-berater.org/index.php/topic,5879.0.html
use HexView
'______________________________________________________________________________
function DialogProc(sys hDlg, uint uMsg, sys wParam, lParam) as int callback
static rect ButtonRect, string sBuffer
static sys hIcon, hFont, hDialogFlipDesktop
select case uMsg
case WM_INITDIALOG
hDialogFlipDesktop = HWND_DESKTOP 'hDlg
CheckDlgButton(hDlg, CheckboxParent, BST_CHECKED)
hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294 + 1) 'o
SetClassLongPtr(hDlg, GCL_HICON, hIcon)
hFont = CreateFont(14, 0, 'Height 14 = 9, 16=12, 15=11, 14=11, Width usually 0,
0, 0, 'Escapement(angle), Orientation
0, 0, 0, 0, 'Bold, Italic, Underline, Strikethru
0, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FF_DONTCARE, "Consolas") 'Fixed width font
SendMessage(GetDlgItem(hDlg, ButtonDia), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, ButtonBox), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, ButtonClip), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, IDCANCEL), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, IDCANCEL), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, CheckboxParent), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, CheckboxOverLoad), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, CheckboxTopMost), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
GetWindowRect(GetDlgItem(hDlg, IDCANCEL), ButtonRect) 'Keep PushButton size as defined in winmain()
ButtonRect.right = ButtonRect.right - ButtonRect.left : ButtonRect.left = 0
ButtonRect.bottom = ButtonRect.bottom - ButtonRect.top : ButtonRect.top = 0
long index
for index = 0 to 255
sBuffer += chr(index)
next
return true
case WM_COMMAND
select case loword(wParam)
case ButtonDia
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
HexViewDlg(hDialogFlipDesktop, sBuffer, "I am an optional comment... All 256 bytes")
string s = "I am a string, yes, I am a string"
HexViewDlg(hDialogFlipDesktop, strptr s, len(s), "I am a string")
wstring ws = "I am a wide string"
HexViewDlg(hDialogFlipDesktop, strptr ws, len(ws) * 2, "I am a wide string")
dword dw = 0x01020304
HexViewDlg(hDialogFlipDesktop, @dw, sizeof(dw), "I am a big endian dword 0x01020304")
byte b[3] = {1, 2, 3}
HexViewDlg(hDialogFlipDesktop, @b, spanof(b), "I am a three bytes array 01 02 03")
word w[3] = {0x12, 0x23, 0x34}
HexViewDlg(hDialogFlipDesktop, @w, spanof(w) * sizeof(word), "I am a big endian three word array 0x0012, 0x0023, 0x0034")
end if
case ButtonBox
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
HexViewBox(hDialogFlipDesktop, sBuffer)
end if
case ButtonClip
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
HexViewClip(sBuffer)
end if
case IDCANCEL
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
EndDialog(hDlg, null)
end if
case CheckboxParent
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
if IsDlgButtonChecked(hDlg, CheckboxParent) then
hDialogFlipDesktop = HWND_DESKTOP
else
hDialogFlipDesktop = hDlg
end if
end if
case CheckboxTopMost
if hiword(wParam) = BN_CLICKED | hiword(wParam) = 1
if IsDlgButtonChecked(hDlg, CheckboxTopMost) then
SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
else
SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
end if
end if
end select
case WM_SIZE 'dialog size have changed
'wParam = resizing requested: SIZE_MAXHIDE, SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
'loword lParam is client area width in pixels
'hiword lParam is client area height in pixels
if wParam <> SIZE_MINIMIZED
long ClientSizeX = loword(lParam)
long ClientSizeY = hiword(lParam)
long posY = ClientSizeY - ButtonRect.bottom - 15
'MoveWindow(GetDlgItem(hDlg, Edit), 5, 5, ClientSizeX - 10, posY, TRUE)
'MoveWindow(GetDlgItem(hDlg, IDCANCEL), (ClientSizeX - ButtonRect.right) \ 2, posY + 10,
' ButtonRect.right, ButtonRect.bottom, TRUE)
'InvalidateRect(hDlg, BYVAL NULL, TRUE) : UpdateWindow(hDlg)
end if
case WM_CLOSE
EndDialog(hDlg, null)
case WM_DESTROY
DeleteObject(hFont)
'DestroyIcon(hIcon)
end select
return 0
end function
'______________________________________________________________________________
sub winmain()
'string ver = version %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_THICKFRAME OR %WS_SYSMENU
'init_common_controls()
'init_common_controlsEx() InitCommonControlsEx
INIT_COMMON_CONTROLSEX CommonControlsEx
CommonControlsEx.dwSize = sizeof(INIT_COMMON_CONTROLSEX)
CommonControlsEx.dwICC = ICC_STANDARD_CLASSES | ICC_TAB_CLASSES
InitCommonControlsEx(@CommonControlsEx)
'if InitCommonControlsEx(CommonControlsEx) then Beep(5500, 50)
'Dialog( 0, 0, 230, 50, "OxygenBasic " + sizeof(sys) * 8 + " - v." + version, WS_OVERLAPPEDWINDOW | DS_CENTER )
'Dialog( 0, 0, 230, 50, "Oxygen HexView " + sizeof(sys) * 8, WS_OVERLAPPEDWINDOW | DS_CENTER )
Dialog( 0, 0, 230, 55, "Oxygen HexView " + sizeof(sys) * 8, _
WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | DS_CENTER, 9, "Segoe UI")
'MultiLineText("MultiLineText", Edit, 1, 1, 198, 80)
PushButton("Dialog", ButtonDia, 10, 16, 40, 12)
PushButton("MessageBox", ButtonBox, 60, 16, 60, 12)
PushButton("Clipboard", ButtonClip, 130, 16, 40, 12)
PushButton("Close", IDCANCEL, 180, 16, 40, 12)
AutoCheckBox("use HWND_DESKTOP", CheckboxParent, 15, 40, 70, 12)
AutoCheckBox("OverLoad", CheckboxOverLoad, 110, 40, 70, 12)
AutoCheckBox("topMost", CheckboxTopMost, 184, 40, 40, 12)
CreateModalDialog(null, @DialogProc, 0)
end sub
'______________________________________________________________________________
winmain()
'______________________________________________________________________________
'
HexViewDemoConsole.o2bas
//KickCompiler "D:\Dev\Oxygen\o2\co264.exe"
//KickSwitch -run -32
//KickEnd
// Compiled with 0.6.0 2023-06-04T22:11:35 - oxygen.dll - OxygenBasic0605.zi
// Compatible 0.7.0 2023-06-15T07:08:15 - oxygen64.dll - OxygenBasic070.zip
use "Console.inc"
use "HexView.inc"
sys hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294 + 001)
SendMessage(GetConsoleWindow(), WM_SETICON, ICON_SMALL, hIcon)
SendMessage(GetConsoleWindow(), WM_SETICON, ICON_BIG, hIcon)
SetConsoleTitle "Oxygen HexView demo console " + sizeof(sys) * 8 + "bit"
SetWindowPos(GetConsoleWindow(), %NULL, 100, 100, 870, 870, %SWP_NOZORDER)
wstring wsBuffer = "123" & "abcdéfghijklmnöpqrstuvwxyz" & wchr(10,1,2,3) & "eê" & wchr(0)
printl "printl HexViewCon(wsBuffer) OverLoad"
printl HexViewCon(wsBuffer)
printl
printl "printl HexViewCon(strptr wsBuffer, len(wsBuffer))"
printl HexViewCon(strptr wsBuffer, len(wsBuffer))
printl
string sBuffer = "pierre" + NULS(2) + "charles" + NULS(2) + "theo" + NULS(2) + "aurel" + NULS(12)
printl "printl HexViewCon(wsBuffer) OverLoad"
printl HexViewCon(sBuffer)
printl
printl "HexViewCon(strptr sBuffer, len(sBuffer))"
printl HexViewCon(strptr sBuffer, len(sBuffer))
printl
long index
sBuffer = ""
for index = 0 to 255
sBuffer += chr(index)
next
printl "printl HexViewCon(sBuffer)"
printl HexViewCon(strptr sBuffer, len(sBuffer))
printl
printl "printl HexViewCon(sBuffer) OverLoad"
printl HexViewCon(sBuffer)
printl
printl "strike a key to view HexViewBox() and HexViewDlg()" : waitkey
HexViewBox(GetConsoleWindow(), strptr sBuffer, len(sBuffer))
HexViewBox(GetConsoleWindow(), sBuffer)
HexViewDlg(GetConsoleWindow(), strptr sBuffer, len(sBuffer))
HexViewDlg(GetConsoleWindow() ,sBuffer)
if MessageBox(HWND_DESKTOP, "Copy HexViewData to clipboard?", "Oxygen HexView",
MB_YESNO | MB_SYSTEMMODAL | MB_TOPMOST | MB_DEFBUTTON2) = IDYES
HexViewClip(strptr sBuffer, len(sBuffer))
end if
if MessageBox(HWND_DESKTOP, "Copy HexViewData to clipboard? (OverLoad)", "Oxygen HexView",
MB_YESNO | MB_SYSTEMMODAL | MB_TOPMOST | MB_DEFBUTTON2) = IDYES
HexViewClip(sBuffer)
end if
DestroyIcon(hIcon)
end