📄 visualpng.c
字号:
//------------------------------------// VisualPng.C -- Shows a PNG image//------------------------------------// Copyright 2000, Willem van Schaik. For conditions of distribution and// use, see the copyright/license/disclaimer notice in png.h// switches// defines#define PROGNAME "VisualPng"#define LONGNAME "Win32 Viewer for PNG-files"#define VERSION "1.0 of 2000 June 07"// constants#define MARGIN 8// standard includes#include <stdio.h>#include <stdlib.h>#include <string.h>#include <windows.h>// application includes#include "png.h"#include "pngfile.h"#include "resource.h"// macros// function prototypesLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;BOOL CenterAbout (HWND hwndChild, HWND hwndParent);BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount, int *pFileIndex);BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex, PTSTR pstrPrevName, PTSTR pstrNextName);BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName, png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels, png_color *pBkgColor);BOOL DisplayImage (HWND hwnd, BYTE **ppDib, BYTE **ppDiData, int cxWinSize, int cyWinSize, BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, BOOL bStretched);BOOL InitBitmap ( BYTE *pDiData, int cxWinSize, int cyWinSize);BOOL FillBitmap ( BYTE *pDiData, int cxWinSize, int cyWinSize, BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, BOOL bStretched);// a few global variablesstatic char *szProgName = PROGNAME;static char *szAppName = LONGNAME;static char *szIconName = PROGNAME;static char szCmdFileName [MAX_PATH];// MAIN routineint WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ HACCEL hAccel; HWND hwnd; MSG msg; WNDCLASS wndclass; int ixBorders, iyBorders; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (hInstance, szIconName) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = NULL; // (HBRUSH) GetStockObject (GRAY_BRUSH); wndclass.lpszMenuName = szProgName; wndclass.lpszClassName = szProgName; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"), szProgName, MB_ICONERROR); return 0; } // if filename given on commandline, store it if ((szCmdLine != NULL) && (*szCmdLine != '\0')) if (szCmdLine[0] == '"') strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2); else strcpy (szCmdFileName, szCmdLine); else strcpy (szCmdFileName, ""); // calculate size of window-borders ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) + GetSystemMetrics (SM_CXDLGFRAME)); iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) + GetSystemMetrics (SM_CYDLGFRAME)) + GetSystemMetrics (SM_CYCAPTION) + GetSystemMetrics (SM_CYMENUSIZE) + 1; /* WvS: don't ask me why? */ hwnd = CreateWindow (szProgName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders,// CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); hAccel = LoadAccelerators (hInstance, szProgName); while (GetMessage (&msg, NULL, 0, 0)) { if (!TranslateAccelerator (hwnd, hAccel, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } return msg.wParam;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static HINSTANCE hInstance ; static HDC hdc; static PAINTSTRUCT ps; static HMENU hMenu; static BITMAPFILEHEADER *pbmfh; static BITMAPINFOHEADER *pbmih; static BYTE *pbImage; static int cxWinSize, cyWinSize; static int cxImgSize, cyImgSize; static int cImgChannels; static png_color bkgColor = {127, 127, 127}; static BOOL bStretched = TRUE; static BYTE *pDib = NULL; static BYTE *pDiData = NULL; static TCHAR szImgPathName [MAX_PATH]; static TCHAR szTitleName [MAX_PATH]; static TCHAR *pPngFileList = NULL; static int iPngFileCount; static int iPngFileIndex; BOOL bOk; switch (message) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; PngFileInitialize (hwnd); strcpy (szImgPathName, ""); // in case we process file given on command-line if (szCmdFileName[0] != '\0') { strcpy (szImgPathName, szCmdFileName); // read the other png-files in the directory for later // next/previous commands BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount, &iPngFileIndex); // load the image from file if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) return 0; // invalidate the client area for later update InvalidateRect (hwnd, NULL, TRUE); // display the PNG into the DIBitmap DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); } return 0; case WM_SIZE: cxWinSize = LOWORD (lParam); cyWinSize = HIWORD (lParam); // invalidate the client area for later update InvalidateRect (hwnd, NULL, TRUE); // display the PNG into the DIBitmap DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); return 0; case WM_INITMENUPOPUP: hMenu = GetMenu (hwnd); if (pbImage) EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED); else EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED); return 0; case WM_COMMAND: hMenu = GetMenu (hwnd); switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // show the File Open dialog box if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName)) return 0; // read the other png-files in the directory for later // next/previous commands BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount, &iPngFileIndex); // load the image from file if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) return 0; // invalidate the client area for later update InvalidateRect (hwnd, NULL, TRUE); // display the PNG into the DIBitmap DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); return 0; case IDM_FILE_SAVE: // show the File Save dialog box if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName)) return 0; // save the PNG to a disk file SetCursor (LoadCursor (NULL, IDC_WAIT)); ShowCursor (TRUE); bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize, bkgColor); ShowCursor (FALSE); SetCursor (LoadCursor (NULL, IDC_ARROW)); if (!bOk) MessageBox (hwnd, TEXT ("Error in saving the PNG image"), szProgName, MB_ICONEXCLAMATION | MB_OK); return 0; case IDM_FILE_NEXT: // read next entry in the directory if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex, NULL, szImgPathName)) { if (strcmp (szImgPathName, "") == 0) return 0; // load the image from file if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) return 0; // invalidate the client area for later update InvalidateRect (hwnd, NULL, TRUE); // display the PNG into the DIBitmap DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); } return 0; case IDM_FILE_PREVIOUS: // read previous entry in the directory if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex, szImgPathName, NULL)) { if (strcmp (szImgPathName, "") == 0) return 0; // load the image from file if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) return 0; // invalidate the client area for later update InvalidateRect (hwnd, NULL, TRUE); // display the PNG into the DIBitmap DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); } return 0; case IDM_FILE_EXIT: // more cleanup needed... // free image buffer if (pDib != NULL) { free (pDib); pDib = NULL; } // free file-list if (pPngFileList != NULL) { free (pPngFileList); pPngFileList = NULL; } // let's go ... exit (0); return 0; case IDM_OPTIONS_STRETCH: bStretched = !bStretched; if (bStretched) CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED); else CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED); // invalidate the client area for later update InvalidateRect (hwnd, NULL, TRUE); // display the PNG into the DIBitmap DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); return 0; case IDM_HELP_ABOUT: DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ; return 0; } // end switch break; case WM_PAINT: hdc = BeginPaint (hwnd, &ps); if (pDib) SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0, 0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS); EndPaint (hwnd, &ps); return 0; case WM_DESTROY: if (pbmfh) { free (pbmfh); pbmfh = NULL; } PostQuitMessage (0); return 0; } return DefWindowProc (hwnd, message, wParam, lParam);}BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_INITDIALOG : ShowWindow (hDlg, SW_HIDE); CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER)); ShowWindow (hDlg, SW_SHOW); return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ;}//---------------// CenterAbout//---------------BOOL CenterAbout (HWND hwndChild, HWND hwndParent){ RECT rChild, rParent, rWorkArea; int wChild, hChild, wParent, hParent; int xNew, yNew; BOOL bResult; // Get the Height and Width of the child window GetWindowRect (hwndChild, &rChild); wChild = rChild.right - rChild.left; hChild = rChild.bottom - rChild.top; // Get the Height and Width of the parent window GetWindowRect (hwndParent, &rParent); wParent = rParent.right - rParent.left; hParent = rParent.bottom - rParent.top; // Get the limits of the 'workarea' bResult = SystemParametersInfo( SPI_GETWORKAREA, // system parameter to query or set sizeof(RECT), &rWorkArea, 0); if (!bResult) { rWorkArea.left = rWorkArea.top = 0; rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -