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

📄 viewer24.cpp

📁 <B>《3D Engine Design》的随书源代码
💻 CPP
字号:
#include <windows.h>
#include <stdio.h>
#include <float.h>
#include "images.h"

char* caption;
char* filename;

//---------------------------------------------------------------------------
long FAR PASCAL WndProc
(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam
)
{
    static int imdims;
    static int* imdim;
    static int quantity, xdim, ydim, zdim;
    static int imtype;
    static mgcImageFile* imfile;

    static float* imdata = 0;;
    static float min = FLT_MAX;
    static float max = -FLT_MAX;
    static float range;

    static char* bmi = 0;
    static HBITMAP hImage;
    static DWORD* bits;
    static int x, y, z;

    static BOOL ButtonDown = FALSE;
    static HDC dragDC;
    static BOOL display_caption = FALSE;
    static char* pixelstr;

    switch ( message ) {
    case WM_CREATE: 
    {
        int k;

        // get requested image
        imfile = new mgcImageFile(filename,&imdims,&imdim,&imtype);
        xdim = imdim[0];
        ydim = imdim[1];
        if ( imdims == 2 )
            zdim = 1;
        if ( imdims == 3 )
            zdim = imdim[2];

        // allocate image memory for single slice
        quantity = xdim*ydim;
        if ( imtype != mgcRGB8::type )
        {
            imdata = new float[quantity];
            if ( !imdata )
                return -1;
        }

        // allocate bit map
        bits = new DWORD[quantity];
        if ( !bits )
            return -1;
        for (k = 0; k < quantity; k++)
            bits[k] = 0;

        if ( imtype != mgcRGB8::type )
        {
            // compute image min and max
            for (z = 0; z < zdim; z++) 
            {
                imfile->Get(mgcFloat::type,imdata,z*quantity,quantity);
                for (k = 0; k < quantity; k++) 
                {
                    if ( imdata[k] < min )
                        min = imdata[k];
                    if ( imdata[k] > max )
                        max = imdata[k];
                }
            }
            range = max-min;
        }

        // get slice 0
        z = 0;
        if ( imtype != mgcRGB8::type )
        {
            imfile->Get(mgcFloat::type,imdata,0,quantity);
            if ( range > 0 ) // image is not constant
                for (k = 0; k < quantity; k++)
                {
                    DWORD gray = DWORD(255*(imdata[k]-min)/range);
                    bits[k] = gray + (gray << 8) + (gray << 16);
                }
        }
        else
        {
            imfile->Get(mgcRGB8::type,bits,0,quantity);
        }

        // create the bitmap
        bmi = new char[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD*)];
        BITMAPINFOHEADER& bmih = *(BITMAPINFOHEADER*)bmi;
        bmih.biSize = sizeof(BITMAPINFOHEADER);
        bmih.biWidth = xdim;
        bmih.biHeight = -ydim;
        bmih.biPlanes = 1;
        bmih.biBitCount = 32;
        bmih.biCompression = BI_RGB;
        bmih.biSizeImage = xdim*ydim;
        bmih.biXPelsPerMeter = 0;
        bmih.biYPelsPerMeter = 0;
        bmih.biClrUsed = 0;
        bmih.biClrImportant = 0;

        HDC hdc = GetDC(hwnd);
        hImage = CreateDIBitmap(
            hdc,
            &bmih,
            CBM_INIT,
            (const void*) bits,
            (const BITMAPINFO*) bmi,
            DIB_RGB_COLORS
        );
        ReleaseDC(hwnd,hdc);

        // allocate string for pixel display
        pixelstr = new char[128];

        return 0;
    }

    case WM_DESTROY: {
        // deallocate application memory and handles
        delete[] bmi;
        delete[] bits;
        delete[] pixelstr;
        if ( imtype != mgcRGB8::type )
            delete[] imdata;
        delete imfile;
        DeleteObject(hImage);

        // send WM_QUIT message to Windows to terminate application
        PostQuitMessage(0);
    }   return 0;

    case WM_PAINT: {
        // client area needs to be redrawn
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd,&ps);
        HDC imageDC = CreateCompatibleDC(hdc);

        // get the image bitmap and redraw it
        BITMAP bm;
        GetObject(hImage,sizeof(BITMAP),&bm);
        SelectObject(imageDC,hImage);
        BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,imageDC,0,0,SRCCOPY);

        DeleteDC(imageDC);
        EndPaint(hwnd,&ps);
    }   return 0;

    case WM_LBUTTONDOWN: {
        // read and display pixel value at mouse location
        if ( ButtonDown == FALSE ) {
            ButtonDown = TRUE;
            SetCapture(hwnd);  // let window have control of mouse events
            dragDC = GetDC(hwnd);
            x = LOWORD(lParam);
            y = HIWORD(lParam);
            if ( 0 <= x && x < xdim && 0 <= y && y < ydim ) {
                int index = x+xdim*y;
                if ( imtype != mgcRGB8::type )
                {
                    if ( zdim == 1 )
                        sprintf(pixelstr,"(%d,%d) %f",x,y,imdata[index]);
                    else
                        sprintf(pixelstr,"(%d,%d,%d) %f",x,y,z,imdata[index]);
                }
                else
                {
                    unsigned int value = bits[index];
                    if ( zdim == 1 )
                    {
                        sprintf(pixelstr,"(%d,%d) r=%d g=%d b=%d",x,y,
                            mgcRGB8::GetRed(value),
                            mgcRGB8::GetGreen(value),
                            mgcRGB8::GetBlue(value));
                    }
                    else
                    {
                        sprintf(pixelstr,"(%d,%d,%d) r=%d g=%d b=%d",x,y,z,
                            mgcRGB8::GetRed(value),
                            mgcRGB8::GetGreen(value),
                            mgcRGB8::GetBlue(value));
                    }
                }
                SetWindowText(hwnd,pixelstr);
                display_caption = TRUE;
            }
        }
    } return 0;

    case WM_MOUSEMOVE: {
        // allow mouse dragging for continuous update/display of pixel values
        if ( ButtonDown == TRUE ) {
            x = LOWORD(lParam);
            y = HIWORD(lParam);
            if ( 0 <= x && x < xdim && 0 <= y && y < ydim ) {
                int index = x+xdim*y;
                if ( imtype != mgcRGB8::type )
                {
                    if ( zdim == 1 )
                        sprintf(pixelstr,"(%d,%d) %f",x,y,imdata[index]);
                    else
                        sprintf(pixelstr,"(%d,%d,%d) %f",x,y,z,imdata[index]);
                }
                else
                {
                    unsigned int value = bits[index];
                    if ( zdim == 1 )
                    {
                        sprintf(pixelstr,"(%d,%d) r=%d g=%d b=%d",x,y,
                            mgcRGB8::GetRed(value),
                            mgcRGB8::GetGreen(value),
                            mgcRGB8::GetBlue(value));
                    }
                    else
                    {
                        sprintf(pixelstr,"(%d,%d,%d) r=%d g=%d b=%d",x,y,z,
                            mgcRGB8::GetRed(value),
                            mgcRGB8::GetGreen(value),
                            mgcRGB8::GetBlue(value));
                    }
                }
                SetWindowText(hwnd,pixelstr);
                display_caption = TRUE;
            }
            else if ( display_caption == TRUE ) {
                // mouse outside of client area, redisplay window caption once
                SetWindowText(hwnd,caption);
                display_caption = FALSE;
            }
        }
    } return 0;

    case WM_LBUTTONUP: {
        // finished reading pixel values, redisplay window caption
        if ( ButtonDown == TRUE ) {
            ButtonDown = FALSE;
            ReleaseCapture();  // window gives up control of mouse events
            ReleaseDC(hwnd,dragDC);
            SetWindowText(hwnd,caption);
            display_caption = FALSE;
        }
    } return 0;

    case WM_KEYDOWN: {
        switch ( wParam ) {
        case VK_UP: {
            // up-arrow pressed, go to next image slize
            if ( z < zdim-1 ) {
                z++;

                // get slice and convert image values to palette indices
                if ( imtype != mgcRGB8::type)
                {
                    imfile->Get(mgcFloat::type,imdata,z*quantity,quantity);
                    if ( range > 0 )
                        for (int k = 0; k < quantity; k++)
                        {
                            DWORD gray = DWORD(255*(imdata[k]-min)/range);
                            bits[k] = gray + (gray << 8) + (gray << 16);
                        }
                }
                else
                {
                    imfile->Get(mgcRGB8::type,bits,z*quantity,quantity);
                }

                // update bitmap and redraw client area
                HDC hdc = GetDC(hwnd);
                SetDIBits(
                    hdc,
                    hImage,
                    0,
                    ydim,
                    (const void*) bits,
                    (const BITMAPINFO*) bmi,
                    DIB_RGB_COLORS
                );
                ReleaseDC(hwnd,hdc);
                InvalidateRect(hwnd,NULL,FALSE);
            }
        }   break;
        case VK_DOWN: {
            // down-arrow pressed, go to previous image slice
            if ( z > 0 ) {
                z--;

                // get slice and convert image values to palette indices
                if ( imtype != mgcRGB8::type )
                {
                    imfile->Get(mgcFloat::type,imdata,z*quantity,quantity);
                    if ( range > 0 )
                        for (int k = 0; k < quantity; k++)
                        {
                            DWORD gray = DWORD(255*(imdata[k]-min)/range);
                            bits[k] = gray + (gray << 8) + (gray << 16);
                        }
                }
                else
                {
                    imfile->Get(mgcRGB8::type,bits,z*quantity,quantity);
                }

                // update bitmap and redraw client area
                HDC hdc = GetDC(hwnd);
                SetDIBits(
                    hdc,
                    hImage,
                    0,
                    ydim,
                    (const void*) bits,
                    (const BITMAPINFO*) bmi,
                    DIB_RGB_COLORS
                );
                ReleaseDC(hwnd,hdc);
                InvalidateRect(hwnd,NULL,FALSE);
            }
        }   break;
        }
    }   return 0;
    }

    return DefWindowProc(hwnd,message,wParam,lParam);
}
//---------------------------------------------------------------------------
int PASCAL WinMain
(
    HINSTANCE hInstance,        // handle of current instance
    HINSTANCE hPrevInstance,    // handle of previous instance
    LPSTR lpszCmdLine,          // address of command line
    int nCmdShow                // show state of window
)
{
    static char szAppName[] = "Viewer24";

    if ( !hPrevInstance ) {
        // first instance of application, so register the window class
        WNDCLASS wc;
        wc.style         = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance;
        wc.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = szAppName;
        RegisterClass(&wc);
    }

    // Get the command line and strip off the stupid double quotes
    // Win32 puts around the command string.  Win32s did not do this.
    filename = new char[strlen(lpszCmdLine)+1];
    if ( lpszCmdLine[0] == '\"' ) {
        strcpy(filename,lpszCmdLine+1);  // remove leading quote
        if ( lpszCmdLine[strlen(lpszCmdLine)-1] == '\"' )
            filename[strlen(lpszCmdLine)-2] = '\0';  // remove trailing quote
    }
    else
        strcpy(filename,lpszCmdLine);

    // get the image header, support only 2D and 3D images
    int dims;
    int* dim;
    int type;
    mgcImageFile file(filename,&dims,&dim,&type);
    if ( file.error ) {
        MessageBox(NULL,filename,"cannot open file",MB_OK);
        return NULL;
    }
    if ( dims < 2 || dims > 3 ) {
        MessageBox(NULL,filename,"not a 2D or 3D image",MB_OK);
        return NULL;
    }

    // strip off path and use filename for window caption
    caption = strrchr(filename,'\\');
    if ( caption )
        caption++;
    else
        caption = filename;

    // compute image size and create window of appropriate client size
    RECT rect = { 0, 0, dim[0]-1, dim[1]-1 };
    AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,NULL);

    HWND hwnd = CreateWindow (
        szAppName,              // window class name
        caption,                // window caption
        WS_OVERLAPPEDWINDOW,    // window style
        CW_USEDEFAULT,          // initial x position
        CW_USEDEFAULT,          // initial y position
        rect.right-rect.left+1, // initial x size
        rect.bottom-rect.top+1, // initial y size
        NULL,                   // parent window handle
        NULL,                   // window menu handle
        hInstance,              // program instance handle
        NULL                    // creation parameters
    );

    ShowWindow(hwnd,nCmdShow);  // display the window on the screen
    UpdateWindow(hwnd);         // draw the client area

    MSG wmsg;
    while ( GetMessage(&wmsg,NULL,0,0) ) {
        TranslateMessage(&wmsg);  // translate virtual key codes for WM_CHAR
        DispatchMessage(&wmsg);   // send to application message queue
    }

    delete[] filename;
    return wmsg.wParam;
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -