These tutorials focus mainly on OpenGL, Win32 programming and the ODE physics engine. OpenGL has moved on to great heights and I don't cover the newest features but cover all of the basic concepts you will need with working example programs.

 

Working with the Win32 API is a great way to get to the heart of Windows and is just as relevant today as ever before. Whereas ODE has been marginalized as hardware accelerated physics becomes more common.

 

Games and graphics utilities can be made quickly and easily using game engines like Unity so this and Linux development in general will be the focus of my next tutorials.    

  

 

Listing of resource.h



#define IDI_ICON          101

#define IDR_MENU          102

#define IDM_FILE_NEW      999

#define IDM_FILE_EXIT     1000

#define IDM_ITEM          1001

#define ID_MDI_CLIENT     1002

#define IDC_CHILD_EDIT    1003

#define ID_MDI_FIRSTCHILD 1004

Listing of resource.rc



#include "resource.h"



IDI_ICON ICON "icon.ico"



IDR_MENU MENU

BEGIN

    POPUP "&File"

    BEGIN

        MENUITEM "&New", IDM_FILE_NEW

        MENUITEM "E&xit", IDM_FILE_EXIT

    END

END

Listing of main.cpp



// Win32 Tutorial (Multiple Document Interface)

// Alan Baylis 2004



#include <windows.h>

#include <commctrl.h>

#include "resource.h"



const char ClassName[] = "MainWindowClass";

const char ChildClassName[] = "ChildWindowClass";

HWND hWndClient;



LRESULT CALLBACK ChildProc( HWND    hWnd,

                            UINT    Msg,

                            WPARAM  wParam,

                            LPARAM  lParam )

{

    switch(Msg)

    {

        // Handle messages from the child windows

    }



    return DefMDIChildProc(hWnd, Msg, wParam, lParam);

}





LRESULT CALLBACK WndProc( HWND    hWnd,

                          UINT    Msg,

                          WPARAM  wParam,          

                          LPARAM  lParam )

{

    switch (Msg)

    {

        case WM_CREATE:

        {

            CLIENTCREATESTRUCT ccs;

            ccs.hWindowMenu  = GetSubMenu(GetMenu(hWnd), 0);

            ccs.idFirstChild = ID_MDI_FIRSTCHILD;





            hWndClient = CreateWindowEx(

            WS_EX_CLIENTEDGE, 

            "MDICLIENT", 

            NULL,

            WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,

            CW_USEDEFAULT, 

            CW_USEDEFAULT, 

            CW_USEDEFAULT, 

            CW_USEDEFAULT,

            hWnd, 

            (HMENU)ID_MDI_CLIENT, 

            (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), 

            (LPVOID)&ccs);



            if(!hWndClient)

            {

                MessageBox(hWnd, "Failed To Create The Client Window", "Error", MB_OK);

            }



            ShowWindow(hWndClient, SW_SHOW);

        }

        break;



        case WM_COMMAND: 

        { 

            switch(LOWORD(wParam))

            { 

                case IDM_FILE_EXIT: 

                    PostMessage(hWnd, WM_CLOSE, 0, 0);

                break; 



                case IDM_FILE_NEW:

                {

                    HWND hChild;

                    CREATESTRUCT cs;

                    ZeroMemory(&cs, sizeof(CREATESTRUCT));



                    hChild = CreateWindowEx(

                    WS_EX_MDICHILD,

                    ChildClassName,

                    "Child Window",

                    WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,

                    CW_USEDEFAULT,

                    CW_USEDEFAULT,

                    CW_USEDEFAULT,

                    CW_USEDEFAULT,

                    hWndClient,

                    NULL,

                    (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),

                    &cs);



                    if(!hChild)

                        MessageBox(hWnd, "Failed To Create The Child Window", "Error", MB_OK);

                }

                break;



                default:

                {

                    if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD)

                        DefFrameProc(hWnd, hWndClient, Msg, wParam, lParam);

                    else

                    {

                        HWND hChild;

                        hChild = (HWND)SendMessage(hWndClient, WM_MDIGETACTIVE,0,0);

                        if(hChild)

                            SendMessage(hChild, WM_COMMAND, wParam, lParam);

                    }

                }

            }

            return 0; 

        } 

        break;



        case WM_CLOSE:

            DestroyWindow(hWnd);

        break;



        case WM_DESTROY:

            PostQuitMessage(0);

        break;



        default:

            return DefFrameProc(hWnd, hWndClient, Msg, wParam, lParam);

    }



    return 0;

}



INT WINAPI WinMain( HINSTANCE  hInstance,

                    HINSTANCE  hPrevInstance,

                    LPSTR      lpCmdLine,

                    INT        nCmdShow )

{

    InitCommonControls();



    WNDCLASSEX    wc;



    wc.cbSize           = sizeof(WNDCLASSEX);

    wc.style            = CS_HREDRAW | CS_VREDRAW;

    wc.lpfnWndProc      = (WNDPROC)WndProc;

    wc.cbClsExtra       = 0;

    wc.cbWndExtra       = 0;

    wc.hInstance        = hInstance;

    wc.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));

    wc.hIconSm          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));

    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);

    wc.lpszMenuName     = MAKEINTRESOURCE(IDR_MENU);

    wc.lpszClassName    = ClassName;



    if (!RegisterClassEx(&wc))

    {

        MessageBox(NULL, "Failed To Register The Window Class.", "Error", MB_OK | MB_ICONERROR);

        return 0;

    }



    wc.lpfnWndProc      = (WNDPROC)ChildProc;

    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground    = (HBRUSH)(COLOR_3DSHADOW + 1);

    wc.lpszMenuName     = NULL;

    wc.lpszClassName    = ChildClassName;



    if(!RegisterClassEx(&wc))

    {

        MessageBox(NULL, "Failed To Register The Child Window Class", "Error", MB_OK | MB_ICONERROR);

        return 0;

    }



    HWND    hWnd;



    hWnd = CreateWindowEx(

    WS_EX_CLIENTEDGE,

    ClassName,

    "MDI",

    WS_OVERLAPPEDWINDOW,

    CW_USEDEFAULT,

    CW_USEDEFAULT,

    600,

    400,

    NULL,

    NULL,

    hInstance,

    NULL);



    if (!hWnd)

    {

        MessageBox(NULL, "Window Creation Failed.", "Error", MB_OK | MB_ICONERROR);

        return 0;

    }



    ShowWindow(hWnd, SW_SHOW);

    UpdateWindow(hWnd);



    MSG    Msg;



    while (GetMessage(&Msg, NULL, 0, 0))

    {

        if (!TranslateMDISysAccel(hWndClient, &Msg))

        {

            TranslateMessage(&Msg);

            DispatchMessage(&Msg);

        }

    }



    return Msg.wParam;

}