開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 WinHexDmp
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

参考

WinHexDmp.cpp
// Unicode文字セット
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include "resource.h"
 
#define CLASS_NAME _T("WinHexDmp")
#define WINDOW_NAME _T("WinHexDmp")
#define COL_LINE 16	// 列数/ライン
#define LINE_HEIGHT 16	// ラインの高さ
 
// 関数プロトタイプ宣言
void itoh(int value, char *string, int count);
void Trace(LPCTSTR format, ...);
int OpenMemMapFile(HWND hWnd);
void CloseMemMapFile(void);
 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnPaint(HWND hWnd);
void OnVScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
void OnMouseWheel(HWND hWnd, WPARAM wParam, LPARAM lParam);
BOOL OnCommand(HWND hWnd, WPARAM wParam);
void OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam);
void OnDropFiles(HWND hWnd, WPARAM wParam);
void OnCreate(HWND hWnd);
void OnDestroy(void);
void NewDocument(HWND hWnd);
 
// 外部変数構造体
static struct {
	SCROLLINFO siVert;
	HFONT hFont;
	TCHAR szPath[MAX_PATH];
	HANDLE hFile;
	HANDLE hMap;
	LPBYTE pBaseAddr;
	DWORD dwFileSize;
} g;
 
//==============================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wcx;
	HWND hWnd;
	HACCEL hAccelTable;
	MSG msg;
	LPTSTR pszCmdLine;
	LPTSTR *argv;
	int argc;
 
	// コマンド引数の取得
	pszCmdLine = GetCommandLine();
	argv = CommandLineToArgvW(pszCmdLine, &argc);
	if (2 <= argc) {
		_tcscpy_s(g.szPath, argv[1]);
	}
 
	// ウィンドウクラスの登録
	ZeroMemory(&wcx, sizeof (WNDCLASSEX));
	wcx.cbSize		= sizeof (WNDCLASSEX);
	wcx.style		= CS_HREDRAW | CS_VREDRAW;
	wcx.lpfnWndProc		= WindowProc;
	wcx.hInstance		= hInstance;
	wcx.hCursor		= LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
	wcx.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
	wcx.lpszClassName	= CLASS_NAME;
	if (RegisterClassEx(&wcx) == 0) {
		return 0;
	}
 
	// ウィンドウの作成
	hWnd = CreateWindowEx(
		WS_EX_ACCEPTFILES,	// Drag & Drop
		CLASS_NAME, WINDOW_NAME,
		WS_OVERLAPPEDWINDOW | WS_VSCROLL,
		CW_USEDEFAULT, 0,
		800, 600,
		NULL, NULL, hInstance, NULL);
	if (hWnd == NULL) {
		return 0;
	}
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
 
	// メッセージループ
	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
	while (GetMessage(&msg, NULL, 0, 0)) {
		if (TranslateAccelerator(msg.hwnd, hAccelTable, &msg) == 0) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
 
	CloseMemMapFile();
	return msg.wParam;
}
 
//------------------------------------------------------------------------------
void itoh(int value, char *string, int count)
{
	static const char hex[] = "0123456789abcdef";
 
	while (count--) {
		*string++ = hex[(value >> (count << 2)) & 0xf];
	}
}
 
//------------------------------------------------------------------------------
void Trace(LPCTSTR format, ...)
{
	va_list arg_ptr;
	TCHAR buffer[256];
	int size;
 
	va_start(arg_ptr, format);
	size = _vsntprintf_s(buffer, _TRUNCATE, format, arg_ptr);
	va_end(arg_ptr);
	OutputDebugString(buffer);
	if (size < 0) {
		OutputDebugString(_T("...\n"));
	}
}
 
//------------------------------------------------------------------------------
int OpenMemMapFile(HWND hWnd)
{
	CloseMemMapFile();
 
	g.hFile = CreateFile(g.szPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (g.hFile == INVALID_HANDLE_VALUE) {
		MessageBox(hWnd, _T("CreateFileに失敗しました"), NULL, MB_OK);
		return -1;
	}
 
	g.hMap = CreateFileMapping(g.hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (g.hMap == NULL) {
		MessageBox(hWnd, _T("CreateFileMappingに失敗しました"), NULL, MB_OK);
		return -1;
	}
 
	g.pBaseAddr = (LPBYTE)MapViewOfFile(g.hMap, FILE_MAP_READ, 0, 0, 0);
	if (g.pBaseAddr == NULL) {
		MessageBox(hWnd, _T("MapViewOfFileに失敗しました"), NULL, MB_OK);
		return -1;
	}
 
	g.dwFileSize = GetFileSize(g.hFile, NULL);	// GetFileSizeEx
	if (g.dwFileSize == INVALID_FILE_SIZE) {
		g.dwFileSize = 0;	// INVALID_FILE_SIZEを取り扱うのは好ましくない
		MessageBox(hWnd, _T("GetFileSizeに失敗しました"), NULL, MB_OK);
		return -1;
	}
 
	return 0;
}
 
//------------------------------------------------------------------------------
void CloseMemMapFile(void)
{
	BOOL br;
 
	g.dwFileSize = 0;
	if (g.pBaseAddr) {
		br = UnmapViewOfFile(g.pBaseAddr);
		g.pBaseAddr = NULL;
	}
	if (g.hMap) {
		br = CloseHandle(g.hMap);
		g.hMap = NULL;
	}
	if (g.hFile) {
		br = CloseHandle(g.hFile);
		g.hFile = NULL;
	}
}
 
//==============================================================================
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_PAINT:
		OnPaint(hWnd);
		return 0;
	case WM_VSCROLL:
		OnVScroll(hWnd, wParam, lParam);
		return 0;
	case WM_MOUSEWHEEL:
		OnMouseWheel(hWnd, wParam, lParam);
		return 0;
	case WM_COMMAND:
		if (OnCommand(hWnd, wParam)) {
			return 0;
		}
		break;
	case WM_SIZE:
		OnSize(hWnd, wParam, lParam);
		return 0;
	case WM_DROPFILES:
		OnDropFiles(hWnd, wParam);
		DragFinish((HDROP)wParam);
		return 0;
	case WM_CREATE:
		OnCreate(hWnd);
		return 0;
	case WM_DESTROY:
		OnDestroy();
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
//------------------------------------------------------------------------------
void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	if (g.dwFileSize == 0) goto Exit;
 
	RECT rc;
	GetClientRect(hWnd, &rc);
	HGDIOBJ hFontOld = SelectObject(hdc, g.hFont);
	DWORD dwRowStart = ps.rcPaint.top / LINE_HEIGHT;	// 描画開始行
	DWORD dwRowEnd = (ps.rcPaint.bottom + LINE_HEIGHT - 1) / LINE_HEIGHT;	// 描画終了行
	Trace(_T("OnPaint %u, %u\n"), dwRowStart, dwRowEnd);
 
	for (DWORD dwRow = dwRowStart; dwRow < dwRowEnd; dwRow++) {
		DWORD dwAddr = COL_LINE * (g.siVert.nPos + dwRow);	// 行先頭アドレス
		DWORD dwColNum = g.dwFileSize - dwAddr;	// 列数
		if (COL_LINE < dwColNum) dwColNum = COL_LINE;
		if (dwColNum == 0) break;
 
		char szLine[80];
		strcpy_s(szLine,
		"        |           -           -           -           |                ");
	//      "HHHHHHHH:HH HH HH HH-HH HH HH HH-HH HH HH HH-HH HH HH HH:XXXXXXXXXXXXXXXX"
		itoh(dwAddr, szLine, 8);
 
		for (DWORD dwCol = 0; dwCol < dwColNum; dwCol++) {
			BYTE byChar = g.pBaseAddr[dwAddr + dwCol];
			// 16進表記
			itoh(byChar, szLine + 9 + dwCol * 3, 2);
			// 文字
			if (isprint(byChar) == 0) {
				byChar = '.';
			}
			szLine[57 + dwCol] = byChar;
		}
		TextOutA(hdc, 0, LINE_HEIGHT * dwRow, szLine, strlen(szLine));
		if (dwColNum < COL_LINE) break;
	}
	SelectObject(hdc, hFontOld);
Exit:
	EndPaint(hWnd, &ps);
}
 
//------------------------------------------------------------------------------
void OnVScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	SCROLLINFO si;
	int nPos;
	int nPosMax;
 
	nPos = g.siVert.nPos;
	nPosMax = g.siVert.nMax - g.siVert.nPage + 1;
 
	switch (LOWORD(wParam)) {
	case SB_LINEUP:		// 0
		nPos -= 1;
		break;
	case SB_LINEDOWN:	// 1
		nPos += 1;
		break;
	case SB_PAGEUP:		// 2
		nPos -= g.siVert.nPage;
		break;
	case SB_PAGEDOWN:	// 3
		nPos += g.siVert.nPage;
		break;
	case SB_THUMBTRACK:	// 5
		si.cbSize	= sizeof si;
		si.fMask	= SIF_TRACKPOS;
		if (GetScrollInfo(hWnd, SB_VERT, &si) != 0) {
			nPos = si.nTrackPos;
		}
		break;
	case SB_TOP:		// 6
		nPos = 0;
		break;
	case SB_BOTTOM:		// 7
		nPos = nPosMax;
		break;
	}
 
	nPos = min(nPos, nPosMax);
	nPos = max(nPos, 0);
	if (nPos == g.siVert.nPos) {
		return;
	}
	ScrollWindowEx(hWnd, 0, LINE_HEIGHT * (g.siVert.nPos - nPos),
		NULL, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE);
	g.siVert.nPos = nPos;
	SetScrollInfo(hWnd, SB_VERT, &g.siVert, TRUE);
	UpdateWindow(hWnd);
//	InvalidateRect(hWnd, NULL, TRUE);
}
 
//------------------------------------------------------------------------------
void OnMouseWheel(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	short zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
	int nScrollCode;
 
	if (0 < zDelta) {
		nScrollCode = SB_LINEUP;
	} else {
		nScrollCode = SB_LINEDOWN;
	}
	SendMessage(hWnd, WM_VSCROLL, nScrollCode, (LPARAM)NULL);
}
 
//------------------------------------------------------------------------------
BOOL OnCommand(HWND hWnd, WPARAM wParam)
{
	int nScrollCode;
 
	switch (LOWORD(wParam)) {
	case ID_ESC:
		DestroyWindow(hWnd);
		return TRUE;
	case ID_PAGEUP:
		nScrollCode = SB_PAGEUP;
		break;
	case ID_PAGEDOWN:
		nScrollCode = SB_PAGEDOWN;
		break;
	case ID_END:
		nScrollCode = SB_BOTTOM;
		break;
	case ID_HOME:
		nScrollCode = SB_TOP;
		break;
	case ID_UP:
		nScrollCode = SB_LINEUP;
		break;
	case ID_DOWN:
		nScrollCode = SB_LINEDOWN;
		break;
	default:
		return FALSE;
	}
	SendMessage(hWnd, WM_VSCROLL, nScrollCode, (LPARAM)NULL);
	return TRUE;
}
 
//------------------------------------------------------------------------------
void OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	WORD wHeight = HIWORD(lParam);
	int nPosMax;
 
	switch (wParam) {
	case SIZE_MAXHIDE:
	case SIZE_MINIMIZED:
		return;
	}
 
	// スクロール情報の更新
	g.siVert.nPage = wHeight / LINE_HEIGHT;
	nPosMax = g.siVert.nMax - g.siVert.nPage + 1;
	if (nPosMax < 0) {
		nPosMax = 0;
	}
	if (nPosMax < g.siVert.nPos) {
		g.siVert.nPos = nPosMax;
	}
	SetScrollInfo(hWnd, SB_VERT, &g.siVert, TRUE);
}
 
//------------------------------------------------------------------------------
void OnDropFiles(HWND hWnd, WPARAM wParam)
{
	HDROP hDrop = (HDROP)wParam;
	UINT ur;
 
	ur = DragQueryFile(hDrop, 0, g.szPath, _countof(g.szPath));
	NewDocument(hWnd);
	InvalidateRect(hWnd, NULL, TRUE);
}
 
//------------------------------------------------------------------------------
void OnCreate(HWND hWnd)
{
	LOGFONT lf;
 
	// スクロール情報の初期化
	ZeroMemory(&g.siVert, sizeof g.siVert);
	g.siVert.cbSize	= sizeof g.siVert;
	g.siVert.fMask	= SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL;
	SetScrollInfo(hWnd, SB_VERT, &g.siVert, FALSE);
 
	// フォントの作成
	ZeroMemory(&lf, sizeof lf);
	lf.lfHeight = -LINE_HEIGHT;
	_tcscpy_s(lf.lfFaceName, _T("MS ゴシック"));
	g.hFont = CreateFontIndirect(&lf);
 
	if (g.szPath[0]) {
		NewDocument(hWnd);
	}
}
 
//------------------------------------------------------------------------------
void OnDestroy(void)
{
	DeleteObject(g.hFont);
}
 
//------------------------------------------------------------------------------
void NewDocument(HWND hWnd)
{
	TCHAR szTitle[280];
	RECT rc;
	int nRowNum;	// 行数
 
	OpenMemMapFile(hWnd);
 
	// タイトルの更新
	_stprintf_s(szTitle, _T("%s - %s"), g.szPath, WINDOW_NAME);
	SetWindowText(hWnd, szTitle);
 
	GetClientRect(hWnd, &rc);
	nRowNum = (g.dwFileSize + COL_LINE - 1) / COL_LINE;
 
	// スクロール情報の更新
	g.siVert.nMin	= 0;
	g.siVert.nMax	= nRowNum - 1;
	g.siVert.nPage	= rc.bottom / LINE_HEIGHT;
	g.siVert.nPos	= 0;
	SetScrollInfo(hWnd, SB_VERT, &g.siVert, TRUE);
}
 

resource.h
#define IDR_MAINFRAME	128
#define ID_ESC		129
#define ID_PAGEUP	130
#define ID_PAGEDOWN	131
#define ID_END		132
#define ID_HOME		133
#define ID_UP		134
#define ID_DOWN		135
 

WinHexDmp.rc
// resource script
#include <windows.h>
#include "resource.h"
 
//------------------------------------------------------------------------------
// アクセラレータ
IDR_MAINFRAME ACCELERATORS
BEGIN
	VK_ESCAPE,	ID_ESC,		VIRTKEY		// 0x1B
	VK_PRIOR,	ID_PAGEUP,	VIRTKEY		// 0x21
	VK_NEXT,	ID_PAGEDOWN,	VIRTKEY		// 0x22
	VK_END,		ID_END,		VIRTKEY		// 0x23
	VK_HOME,	ID_HOME,	VIRTKEY		// 0x24
	VK_UP,		ID_UP,		VIRTKEY		// 0x26
	VK_DOWN,	ID_DOWN,	VIRTKEY		// 0x28
END
 
最終更新:2012年10月23日 06:08