📄 viewer.cpp
字号:
deltaY = pos;
img.scrollY = si.nPos;
}
else
{
deltaX = pos;
img.scrollX = si.nPos;
}
GetClientRect(wnd.hwnd, &rect);
rect.bottom -= wnd.statusHeight;
img.srcX = img.scrollX;
img.srcY = img.scrollY;
ScrollWindowEx(hwnd, deltaX, deltaY, &rect, &rect, NULL, NULL, SW_INVALIDATE);
UpdateWindow(hwnd);
}
return 0;
}
// set image position
void setImagePos(int screenWidth, int screenHeight)
{
SCROLLINFO scroll;
UINT wArrows;
img.dstX = max((screenWidth - img.width) / 2, 0);
img.dstY = max((screenHeight - img.height) / 2, 0);
img.dstWidth = min(screenWidth, img.width);
img.dstHeight = min(screenHeight, img.height);
if (img.scrollX + img.dstWidth >= img.width)
img.scrollX = img.width - img.dstWidth;
if (img.scrollY + img.dstHeight >= img.height)
img.scrollY = img.height - img.dstHeight;
img.srcX = img.scrollX;
img.srcY = img.scrollY;
if (img.width <= screenWidth && img.height <= screenHeight)
{
ShowScrollBar(wnd.hwnd, SB_BOTH, FALSE);
}
else
{
scroll.cbSize = sizeof(scroll);
scroll.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
scroll.nMin = 0;
wArrows = ESB_DISABLE_BOTH;
if (img.width > screenWidth)
{
scroll.nMax = img.width;
scroll.nPage = screenWidth;
scroll.nPos = img.scrollX;
SetScrollInfo(wnd.hwnd, SB_HORZ, &scroll, TRUE);
wArrows = ESB_ENABLE_BOTH;
}
EnableScrollBar(wnd.hwnd, SB_HORZ, wArrows);
wArrows = ESB_DISABLE_BOTH;
if (img.height > screenHeight)
{
scroll.nMax = img.height;
scroll.nPage = screenHeight;
scroll.nPos = img.scrollY;
SetScrollInfo(wnd.hwnd, SB_VERT, &scroll, TRUE);
wArrows = ESB_ENABLE_BOTH;
}
EnableScrollBar(wnd.hwnd, SB_VERT, wArrows);
}
}
// OnCommand
LRESULT OnCommand(HWND hwnd, WORD menuId, LPARAM lParam)
{
switch (menuId)
{
case ID_FILE_OPEN40001:
OnFileOpen();
break;
case ID_FILE_CLOSE40002:
OnFileClose();
break;
case ID_FILE_QUIT:
OnFileQuit();
break;
}
return 0;
}
// File->Open
void OnFileOpen(void)
{
#define MAX_FILE_NAME 256
char filename[MAX_FILE_NAME];
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = wnd.hwnd;
ofn.lpstrFilter = "JPEG files\0*.jpg\0All files\0*.*\0\0\0";
ofn.lpstrFile = & filename[0];
filename[0] = 0;
ofn.nMaxFile = sizeof(filename);
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
if (GetOpenFileName(&ofn))
{
if (readFile(filename))
{
SetWindowText(wnd.hwnd, &filename[ofn.nFileOffset]);
}
}
else
{
if (CommDlgExtendedError())
{
MessageBox(wnd.hwnd, "Cannot create window to open file", "Error", MB_OK);
}
}
}
// File->Close
BOOL OnFileClose(void)
{
freeBitmap();
menuChange(0, MENU_CLOSE);
SetWindowText(wnd.hwnd, WINDOW_TITLE);
SetWindowText(wnd.status, STATUS_INIT);
ShowScrollBar(wnd.hwnd, SB_BOTH, FALSE);
ZeroMemory(&img, sizeof(img));
InvalidateRect(wnd.hwnd, NULL, TRUE);
return TRUE;
}
// File->Quit
void OnFileQuit(void)
{
OnDestroy();
}
// read file in a buffer
BOOL readFile(char* filename)
{
BOOL ret = FALSE;
HANDLE hfile;
BY_HANDLE_FILE_INFORMATION fileinfo;
char* buffer = NULL;
unsigned nbread;
hfile = CreateFile(filename, GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE)
{
if (GetFileInformationByHandle(hfile, &fileinfo))
{
if (fileinfo.nFileSizeHigh == 0)
{
buffer = (char*) allocMem(fileinfo.nFileSizeLow);
if (buffer)
{
if (ReadFile(hfile, buffer, fileinfo.nFileSizeLow, &nbread, NULL))
{
if (nbread == fileinfo.nFileSizeLow)
{
ret = newFileOpened(buffer, nbread);
}
}
freeMem(buffer);
}
}
}
CloseHandle(hfile);
}
return ret;
}
// allocate memory
void* allocMem(int size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
}
// free memory
void freeMem(void* mem)
{
HeapFree(GetProcessHeap(), 0, mem);
}
// new file opened
BOOL newFileOpened(char* buffer, int size)
{
BOOL ret = FALSE;
int code = JPEG_FORMATNOTSUPPORTED;
JPEGIMAGE* jimg;
HDC cdc, wdc;
BITMAPINFO bmi;
BITMAPINFOHEADER* bmhdr;
HBITMAP cbm, oldbm;
unsigned time;
RECT rect;
// decode the buffer
time = GetTickCount();
code = JPEG_Decode(buffer, size, &jimg, 0);
time = GetTickCount() - time;
if (code == JPEG_SUCCESS)
{
// copy the image in a dc
wdc = GetDC(wnd.hwnd);
if (wdc)
{
cdc = CreateCompatibleDC(wdc);
if (cdc)
{
cbm = CreateCompatibleBitmap(wdc, jimg->width, jimg->height);
if (cbm)
{
bmhdr = & bmi.bmiHeader;
bmhdr->biSize = sizeof(*bmhdr);
bmhdr->biWidth = jimg->scanlength;
bmhdr->biHeight = - (int)jimg->height;
bmhdr->biPlanes = 1;
bmhdr->biBitCount = jimg->bitsPixel;
bmhdr->biCompression = BI_RGB;
if (SetDIBits(cdc, cbm, 0,
jimg->height, jimg->pRGB, &bmi,
DIB_RGB_COLORS) == jimg->height)
{
oldbm = (HBITMAP) SelectObject(cdc, cbm);
if (oldbm)
{
// free previous resource
OnFileClose();
img.oldbm = oldbm;
img.dc = cdc;
img.width = jimg->width;
img.height = jimg->height;
menuChange(MENU_CLOSE, 0);
setStatusInfo(time, jimg);
GetClientRect(wnd.hwnd, &rect);
setImagePos(rect.right, rect.bottom - wnd.statusHeight);
InvalidateRect(wnd.hwnd, NULL, TRUE);
ret = TRUE;
}
}
}
}
ReleaseDC(wnd.hwnd, wdc);
}
// free the image
JPEG_Free(jimg);
}
if (ret == FALSE)
{
if (code != JPEG_SUCCESS)
{
displayError(code);
}
else
{
MessageBox(wnd.hwnd, "Error", "can't allocate graphics object", MB_OK);
}
}
return ret;
}
// free bitmap
void freeBitmap(void)
{
HBITMAP hbm;
if (img.dc)
{
hbm = (HBITMAP) SelectObject(img.dc, img.oldbm);
if (hbm)
{
DeleteObject(hbm);
}
DeleteDC(img.dc);
img.width = img.height = 0;
img.dc = NULL;
}
}
// change menu
void menuChange(unsigned set, unsigned reset)
{
UINT id;
unsigned val[2];
unsigned flags;
unsigned i;
UINT state;
HMENU hmenu = GetMenu(wnd.hwnd);
val[0] = set;
val[1] = reset;
if (hmenu)
{
state = MF_ENABLED;
for (i = 0; i < 2; i++)
{
id = FIRST_MENU_ID;
flags = val[i];
while (flags)
{
if (flags & 1)
{
EnableMenuItem(hmenu, id, state);
}
id++;
flags >>= 1;
}
state = MF_GRAYED;
}
}
}
// set status info
void setStatusInfo(unsigned time, JPEGIMAGE* img)
{
char buffer[256];
int nb;
char* str;
if (time)
str = "%dx%d - %s - %d bpp - %d ms";
else
str = "%dx%d - %s - %d bpp - < 1 ms";
nb = wsprintf(buffer, str, img->width, img->width,
img->Nf == 1 ? "Grayscale" : "Color", img->bitsPixel, time);
buffer[nb] = 0;
SetWindowText(wnd.status, buffer);
}
// display error message
void displayError(int code)
{
char* msg;
switch (code)
{
case JPEG_EOF:
msg = "unexpected end of file";
break;
case JPEG_OUTOFMEM:
msg = "out of memory";
break;
case JPEG_CPUNOTSUPPORTED:
msg = "cpu not supported";
break;
case JPEG_BADFILE:
msg = "bad file";
break;
case JPEG_FORMATNOTSUPPORTED:
msg = "format not supported";
break;
default:
msg = "unknown error code";
break;
}
MessageBox(wnd.hwnd, msg, "Error", MB_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -