📄 viewer.c
字号:
//======================================================================
// Viewer - A file view control
//
// Written for the book Programming Windows CE
// Copyright (C) 1998 Douglas Boling
//
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <windowsx.h> // For message crackers
#include "fileview.h" // Program-specific stuff
#include "viewer.h" // Control-specific stuff
//----------------------------------------------------------------------
// Internal function prototypes
LRESULT CALLBACK ViewerWndProc (HWND, UINT, WPARAM, LPARAM);
// Message handlers
LRESULT DoCreateViewer (HWND, UINT, WPARAM, LPARAM);
LRESULT DoSizeViewer (HWND, UINT, WPARAM, LPARAM);
LRESULT DoPaintViewer (HWND, UINT, WPARAM, LPARAM);
LRESULT DoVScrollViewer (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyViewer (HWND, UINT, WPARAM, LPARAM);
LRESULT DoOpenViewer (HWND, UINT, WPARAM, LPARAM);
HFONT GetFixedEquiv (HWND hWnd, HFONT hFontIn);
#define BUFFSIZE 4096
//----------------------------------------------------------------------
// Global data
//
extern HINSTANCE hInst; // Program instance handle
HANDLE g_hFile = 0; // Handle to the opened file
LONG g_lFileSize; // Size of the file
PBYTE g_pBuff = 0; // Pointer to file data buffer
LONG g_lFilePtr = 0; // Pointer to current offset
// into file
LONG g_lBuffBase = 0; // Offset into file of buffer data
INT g_nBuffLen = 0; // Size of data in file buffer
HFONT g_hFont = 0; // Fixed pitch font used for text
INT g_nPageLen = 0; // Number of bytes displayed / page
const TCHAR szViewerCls[] = TEXT ("Viewer");
// Message dispatch table for ViewerWindowProc
const struct decodeUINT ViewerMessages[] = {
WM_CREATE, DoCreateViewer,
WM_PAINT, DoPaintViewer,
WM_SIZE, DoSizeViewer,
WM_VSCROLL, DoVScrollViewer,
WM_DESTROY, DoDestroyViewer,
VM_OPEN, DoOpenViewer,
};
//----------------------------------------------------------------------
// RegisterCtl - Register the viewer control.
//
int RegisterCtl (HINSTANCE hInstance) {
WNDCLASS wc;
// Register application viewer window class.
wc.style = 0; // Window style
wc.lpfnWndProc = ViewerWndProc; // Callback function
wc.cbClsExtra = 0; // Extra class data
wc.cbWndExtra = 0; // Extra window data
wc.hInstance = hInstance; // Owner handle
wc.hIcon = NULL, // Application icon
wc.hCursor = NULL; // Default cursor
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL; // Menu name
wc.lpszClassName = szViewerCls; // Window class name
if (RegisterClass (&wc) == 0) return 1;
return 0;
}
//----------------------------------------------------------------------
// CreateViewer - Create a viewer control.
//
HWND CreateViewer (HWND hParent, RECT *prect, int nID) {
HWND hwndCtl;
// Create viewer control.
hwndCtl = CreateWindowEx (0, szViewerCls, TEXT (""),
WS_VISIBLE | WS_CHILD | WS_VSCROLL |
WS_BORDER,
prect->left, prect->top,
prect->right - prect->left,
prect->bottom - prect->top,
hParent, (HMENU)nID,
hInst, NULL);
return hwndCtl;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermViewer (HINSTANCE hInstance, int nDefRC) {
if (g_hFile)
CloseHandle (g_hFile); // Close the opened file.
if (g_pBuff)
LocalFree (g_pBuff); // Free buffer.
if (g_hFont)
DeleteObject (g_hFont);
return nDefRC;
}
//======================================================================
// Message handling procedures for ViewerWindow
//
//----------------------------------------------------------------------
// ViewerWndProc - Callback function for viewer window.
//
LRESULT CALLBACK ViewerWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
INT i;
//
// Search message list to see if we need to handle this
// message. If in list, call function.
//
for (i = 0; i < dim(ViewerMessages); i++) {
if (wMsg == ViewerMessages[i].Code)
return (*ViewerMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
//----------------------------------------------------------------------
// DoCreateViewer - Process WM_CREATE message for window.
//
LRESULT DoCreateViewer (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
LPCREATESTRUCT lpcs;
// Convert lParam into pointer to create struct.
lpcs = (LPCREATESTRUCT) lParam;
// Allocate a buffer.
g_pBuff = LocalAlloc (LMEM_FIXED, BUFFSIZE);
if (!g_pBuff) {
MessageBox (NULL, TEXT ("Not enough memory"),
TEXT ("Error"), MB_OK);
return 0;
}
// Create a fixed-pitch font.
g_hFont = GetFixedEquiv (hWnd, 0);
return 0;
}
//----------------------------------------------------------------------
// DoSizeViewer - Process WM_SIZE message for window
//
LRESULT DoSizeViewer (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam){
return 0;
}
//----------------------------------------------------------------------
// ComposeLine - Converts hex buff to unicode string
//
int ComposeLine (INT nOffset, LPTSTR szOut) {
INT i, nLen, nBuffOffset;
TCHAR szTmp[16];
LPBYTE pPtr;
DWORD cBytes;
szOut[0] = TEXT ('\0');
if (g_hFile == 0) // If no file open, no text
return 0;
// Make sure we have enough bytes in buffer for dump.
if ((nOffset + 16 > g_lBuffBase + g_nBuffLen) ||
(nOffset < g_lBuffBase)) {
// Move file pointer to new place and read data.
SetFilePointer (g_hFile, nOffset, NULL, FILE_BEGIN);
if (!ReadFile (g_hFile, g_pBuff, BUFFSIZE, &cBytes, NULL))
return 0;
g_lBuffBase = nOffset;
g_nBuffLen = cBytes;
}
nBuffOffset = nOffset - g_lBuffBase;
if (nBuffOffset > g_nBuffLen)
return 0;
// Now create the text for the line.
wsprintf (szOut, TEXT ("%08X "), nOffset);
pPtr = g_pBuff + nBuffOffset;
nLen = g_nBuffLen - nBuffOffset;
if (nLen > 16)
nLen = 16;
for (i = 0; i < nLen; i++) {
wsprintf (szTmp, TEXT ("%02X"), *pPtr++);
lstrcat (szOut, szTmp);
if (i == 7)
lstrcat (szOut, TEXT ("-"));
else
lstrcat (szOut, TEXT (" "));
}
return nLen;
}
//----------------------------------------------------------------------
// DoPaintViewer - Process WM_PAINT message for window.
//
LRESULT DoPaintViewer (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
INT nFontHeight;
INT i, yCurrent;
TEXTMETRIC tm;
PAINTSTRUCT ps;
HFONT hOldFont;
RECT rect;
HDC hdc;
hdc = BeginPaint (hWnd, &ps);
GetClientRect (hWnd, &rect);
hOldFont = SelectObject (hdc, g_hFont);
// Get the height of the default font.
GetTextMetrics (hdc, &tm);
nFontHeight = tm.tmHeight + tm.tmExternalLeading;
i = 0;
yCurrent = rect.top;
while (yCurrent < rect.bottom) {
i += ComposeLine (g_lFilePtr+i, szOut);
ExtTextOut (hdc, 5, yCurrent, 0, NULL,
szOut, lstrlen (szOut), NULL);
// Update new draw point.
yCurrent += nFontHeight;
}
SelectObject (hdc, hOldFont);
EndPaint (hWnd, &ps);
g_nPageLen = i;
return 0;
}
//----------------------------------------------------------------------
// DoVScrollViewer - Process WM_VSCROLL message for window.
//
LRESULT DoVScrollViewer (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
RECT rect;
SCROLLINFO si;
INT sOldPos = g_lFilePtr;
GetClientRect (hWnd, &rect);
switch (LOWORD (wParam)) {
case SB_LINEUP:
g_lFilePtr -= 16;
break;
case SB_LINEDOWN:
g_lFilePtr += 16;
break;
case SB_PAGEUP:
g_lFilePtr -= g_nPageLen;
break;
case SB_PAGEDOWN:
g_lFilePtr += g_nPageLen;
break;
case SB_THUMBPOSITION:
g_lFilePtr = HIWORD (wParam);
break;
}
// Check range
if (g_lFilePtr < 0)
g_lFilePtr = 0;
if (g_lFilePtr > g_lFileSize-16)
g_lFilePtr = (g_lFileSize - 16) & 0xfffffff0;
// If scroll position changed, update scrollbar and
// force redraw of window.
if (g_lFilePtr != sOldPos) {
si.cbSize = sizeof (si);
si.nPos = g_lFilePtr;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
InvalidateRect (hWnd, NULL, TRUE);
}
return 0;
}
//----------------------------------------------------------------------
// DoDestroyViewer - Process WM_DESTROY message for window.
//
LRESULT DoDestroyViewer (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
if (g_hFile)
CloseHandle (g_hFile);
g_hFile = 0;
return 0;
}
//----------------------------------------------------------------------
// DoOpenViewer - Process VM_OPEN message for window.
//
LRESULT DoOpenViewer (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam){
SCROLLINFO si;
if (g_hFile)
CloseHandle (g_hFile);
// Open the file.
g_hFile = CreateFile ((LPTSTR)lParam, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (g_hFile == INVALID_HANDLE_VALUE) {
g_hFile = 0;
return GetLastError();
}
g_lFilePtr = wParam;
g_lFileSize = GetFileSize (g_hFile, NULL);
si.cbSize = sizeof (si);
si.nMin = 0;
si.nMax = g_lFileSize;
si.nPos = g_lFilePtr;
si.fMask = SIF_POS | SIF_RANGE;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
InvalidateRect (hWnd, NULL, TRUE);
return 0;
}
//----------------------------------------------------------------------
HFONT GetFixedEquiv (HWND hWnd, HFONT hFontIn) {
HDC hdc;
TEXTMETRIC tm;
LOGFONT lf;
HFONT hOldFont;
hdc = GetDC (hWnd);
if (hFontIn == 0)
hFontIn = GetStockObject (SYSTEM_FONT);
hOldFont = SelectObject (hdc, hFontIn);
GetTextMetrics (hdc, &tm);
SelectObject (hdc, hOldFont);
ReleaseDC (hWnd, hdc);
memset (&lf, 0, sizeof (lf));
lf.lfHeight = -(tm.tmHeight);
lf.lfWeight = tm.tmWeight;
lf.lfItalic = tm.tmItalic;
lf.lfUnderline = tm.tmUnderlined;
lf.lfStrikeOut = tm.tmStruckOut;
lf.lfCharSet = tm.tmCharSet;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = (tm.tmPitchAndFamily & 0xf0) | TMPF_FIXED_PITCH;
lf.lfFaceName[0] = TEXT ('\0');
// Create the font from the LOGFONT structure passed.
return CreateFontIndirect (&lf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -