////////////////////////////////////////////////////////////////////////////////
// Step4.cpp
//
//  A basic bitmap viewing program. Features a resizable window and menus.

#include <windows.h>
#include <tchar.h>
#include "resource.h"

// Get a bitmap file name from the user.
BOOL GetBitmapFileName(TCHAR *filename, int len, HWND hWnd)
{
    OPENFILENAME    ofn;

    ZeroMemory(&ofn, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = hWnd;
    ofn.lpstrFilter = _T("Bitmap Files (*.bmp)\0*.bmp\0All Files (*.*)\0*.*\0\0");
    ofn.lpstrFile = filename;
    ofn.nMaxFile = len;
    ofn.lpstrTitle = _T("Browse");
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    return GetOpenFileName(&ofn);
}

// Read a bitmap file into memory.
HBITMAP LoadBitmapFile(const TCHAR *filename)
{
    return (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}

TCHAR   szBitmapFilename[MAX_PATH];
HBITMAP hBitmap;

// Handle WM_COMMAND messages for the main window.
BOOL MainWindow_OnCommand(HWND hWnd, WORD wCommand, WORD wNotify, HWND hControl)
{
    switch (wCommand)
    {
    case ID_OPEN:
        if (hBitmap != NULL)
            DeleteObject(hBitmap);

        GetBitmapFileName(szBitmapFilename, sizeof(szBitmapFilename) / sizeof(TCHAR), hWnd);
        hBitmap = LoadBitmapFile(szBitmapFilename);
        RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE);
        break;

    case ID_EXIT:
        DestroyWindow(hWnd);
        break;
    }
    return TRUE;
}

// Handle WM_PAINT messages for the main window.
void MainWindow_OnPaint(HWND hWnd, HDC hDC)
{
    if (hBitmap == NULL)
        return;

    DrawState(hDC, NULL, NULL, (LPARAM)hBitmap, 0, 0, 0, 0, 0, DST_BITMAP | DSS_NORMAL);
}

// Handle all messages for the main window.
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC         hDC;

    switch (uMsg)
    {
    case WM_COMMAND:
        MainWindow_OnCommand(hWnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
        return 0;

    case WM_PAINT:
        hDC = BeginPaint(hWnd, &ps);
        MainWindow_OnPaint(hWnd, hDC);
        EndPaint(hWnd, &ps);
        return 0;

    case WM_CLOSE:
        DestroyWindow(hWnd);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

// Register the window class for the main window.
void RegisterWindowClass()
{
    WNDCLASSEX  wcx;

    ZeroMemory(&wcx, sizeof(WNDCLASSEX));
    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.lpfnWndProc = MainWindowProc;
    wcx.hInstance = GetModuleHandle(NULL);
    wcx.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MAIN));
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcx.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN);
    wcx.lpszClassName = "SampleWindowClass";
    RegisterClassEx(&wcx);
}

HWND hWndMain;

// Program entry point.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) 
{
    MSG msg;

    RegisterWindowClass();

    hWndMain = CreateWindowEx(WS_EX_APPWINDOW,
        "SampleWindowClass", "Bitmap Viewer II", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
        NULL, NULL, hInstance, NULL);
    
    ShowWindow(hWndMain, SW_SHOW);

    while (GetMessage(&msg, NULL, 0, 0))
        DispatchMessage(&msg);

    return 0;
}