⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 visualpng.c

📁 game engine, which is useful for everyone who is interested in it. I hope you can enjoy it.
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------
//  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 prototypes

LRESULT 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 variables

static char *szProgName = PROGNAME;
static char *szAppName = LONGNAME;
static char *szIconName = PROGNAME;
static char szCmdFileName [MAX_PATH];

// MAIN routine

int 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 + -