📄 viewer.cpp
字号:
#include <windows.h>
#include <winuser.h>
#include <commdlg.h>
#include <commctrl.h>
#include "resource.h"
#include "jpeg_dec.h"
// Constants
#define FIRST_MENU_ID ID_FILE_OPEN40001
#define MENU_OPEN (1 << 0)
#define MENU_CLOSE (1 << 1)
#define MENU_QUIT (1 << 2)
const char WINDOW_TITLE[] = "JPEG Viewer by Dr. Manhattan";
const char STATUS_INIT[] = "Ready";
// Global variable
struct
{
HINSTANCE hinst;
HWND hwnd, status;
int statusHeight;
} wnd;
struct
{
HDC dc;
HBITMAP oldbm;
int width, height;
int dstX, dstY, dstWidth, dstHeight, srcX, srcY;
int scrollX, scrollY;
} img;
// Function prototypes.
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
InitApplication(HINSTANCE);
InitInstance(HINSTANCE, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT OnCreate(HWND hwnd);
LRESULT OnPaint(HWND hwnd, WPARAM wParam, LPARAM lParam);
LRESULT OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam);
LRESULT OnDestroy(void);
LRESULT OnScroll(HWND hwnd, WPARAM wParam, LPARAM lParam, int fnBar);
LRESULT OnCommand(HWND hwnd, WORD menuId, LPARAM lParam);
void OnFileOpen(void);
BOOL OnFileClose(void);
void OnFileQuit(void);
BOOL getFileName(void);
BOOL readFile(char* filename);
void* allocMem(int size);
void freeMem(void* mem);
BOOL newFileOpened(char* buffer, int size);
void freeBitmap(void);
void menuChange(unsigned set, unsigned reset);
HWND createStatusBar(HWND hwnd, HINSTANCE hinst);
void setStatusInfo(unsigned time, JPEGIMAGE* img);
void displayError(int code);
void setImagePos(int width, int height);
// Application entry point.
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet = FALSE;
#ifdef _DEBUG
/* dummy floating point operation to use sprintf */
float f = 0.0;
#endif
if (InitApplication(hinstance))
{
if (InitInstance(hinstance, nCmdShow))
{
while ((bRet = GetMessage(&msg, (HWND) NULL, 0, 0)))
{
if (bRet != -1)
{
DispatchMessage(&msg);
}
}
bRet = TRUE;
}
}
UNREFERENCED_PARAMETER(lpCmdLine);
return bRet;
}
BOOL InitApplication(HINSTANCE hinstance)
{
WNDCLASSEX wcx;
// Fill in the window class structure with parameters
// that describe the main window.
// size of structure
wcx.cbSize = sizeof(wcx);
// redraw if size changes
wcx.style = CS_HREDRAW | CS_VREDRAW;
// points to window procedure
wcx.lpfnWndProc = MainWndProc;
// no extra class memory
wcx.cbClsExtra = 0;
// no extra window memory
wcx.cbWndExtra = 0;
// handle to instance
wcx.hInstance = hinstance;
// predefined app. icon
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
// predefined arrow
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
// white background brush
wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
// name of menu resource
wcx.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
// name of window class
wcx.lpszClassName = "MainWClass";
wcx.hIconSm = (HICON) LoadImage(hinstance,
MAKEINTRESOURCE(5),
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTCOLOR);
// Register the window class.
return RegisterClassEx(&wcx);
}
BOOL InitInstance(HINSTANCE hinstance, int nCmdShow)
{
HWND hwnd;
BOOL ret = FALSE;
RECT rect;
// Save the application-instance handle.
wnd.hinst = hinstance;
// Create the main window.
hwnd = CreateWindow("MainWClass", // name of window class
WINDOW_TITLE, // title-bar string
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, // top-level window
CW_USEDEFAULT, // default horizontal position
CW_USEDEFAULT, // default vertical position
CW_USEDEFAULT, // default width
CW_USEDEFAULT, // default height
(HWND) NULL, // no owner window
(HMENU) NULL, // use class menu
hinstance, // handle to application instance
(LPVOID) NULL); // no window-creation data
if (hwnd)
{
// create status bar
wnd.status = createStatusBar(hwnd, wnd.hinst);
if (wnd.status)
{
if (GetClientRect(wnd.status, &rect))
{
wnd.statusHeight = rect.bottom;
}
}
// hide scroll bar
ShowScrollBar(wnd.hwnd, SB_BOTH, FALSE);
// Show the window and send a WM_PAINT message to the window
// procedure.
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
ret = TRUE;
}
return ret;
}
HWND createStatusBar(HWND hwnd, HINSTANCE hinst)
{
HWND statusWnd = NULL;
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_BAR_CLASSES;
if (InitCommonControlsEx(&icc))
{
statusWnd = CreateWindow(STATUSCLASSNAME,
STATUS_INIT,
WS_CHILD | WS_VISIBLE,
0,
0,
0,
0,
hwnd,
NULL,
hinst,
NULL);
}
return statusWnd;
}
// WndProc
LRESULT CALLBACK MainWndProc(HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
LRESULT ret = 0;
switch (uMsg)
{
// Initialize the window.
case WM_COMMAND:
if (HIWORD(wParam) == 0)
{
ret = OnCommand(hwnd, LOWORD(wParam), lParam);
}
break;
// Initialize the window.
case WM_CREATE:
ret = OnCreate(hwnd);
break;
// Paint the window's client area.
case WM_PAINT:
ret = OnPaint(hwnd, wParam, lParam);
break;
// Set the size and position of the window.
case WM_SIZE:
ret = OnSize(hwnd, wParam, lParam);
break;
// Clean up window-specific data objects.
case WM_DESTROY:
ret = OnDestroy();
break;
// horizontal scrolling
case WM_HSCROLL:
ret = OnScroll(hwnd, wParam, lParam, SB_HORZ);
break;
// vertical scrolling
case WM_VSCROLL:
ret = OnScroll(hwnd, wParam, lParam, SB_VERT);
break;
// Process other messages.
default:
ret = DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return ret;
}
// OnCreate
LRESULT OnCreate(HWND hwnd)
{
wnd.hwnd = hwnd;
return 0;
}
// OnDestroy
LRESULT OnDestroy(void)
{
PostQuitMessage(0);
return 0;
}
// OnPaint
LRESULT OnPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HDC dc;
PAINTSTRUCT ps;
dc = BeginPaint(hwnd, &ps);
if (dc)
{
if (img.dc)
{
BitBlt(dc, img.dstX, img.dstY, img.dstWidth, img.dstHeight, img.dc, img.srcX, img.srcY, SRCCOPY);
}
}
EndPaint(hwnd, &ps);
SendMessage(wnd.status, WM_PAINT, wParam, lParam);
return 0;
}
// OnSize
LRESULT OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
int newWidth, newHeight;
if (wParam != SIZE_MINIMIZED)
{
if (img.dc)
{
newWidth = LOWORD(lParam);
newHeight = HIWORD(lParam) - wnd.statusHeight;
setImagePos(newWidth, newHeight);
}
}
SendMessage(wnd.status, WM_SIZE, wParam, lParam);
return 0;
}
// vertical scrolling
LRESULT OnScroll(HWND hwnd, WPARAM wParam, LPARAM lParam, int fnBar)
{
SCROLLINFO si;
int pos;
int deltaX, deltaY;
RECT rect;
// Get all the scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, fnBar, &si);
// Save the position for comparison later on
pos = si.nPos;
switch (LOWORD(wParam))
{
// user clicked the top arrow
case SB_LINEUP:
si.nPos -= 1;
break;
// user clicked the bottom arrow
case SB_LINEDOWN:
si.nPos += 1;
break;
// user clicked the shaft above the scroll box
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
// user clicked the shaft below the scroll box
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default:
break;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
SetScrollInfo(hwnd, fnBar, &si, TRUE);
GetScrollInfo(hwnd, fnBar, &si);
// If the position has changed, scroll window and update it
pos -= si.nPos;
if (pos)
{
deltaX = deltaY = 0;
if (fnBar == SB_VERT)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -