Code:
//Main.h
#ifndef MAIN_H
#define MAIN_H

#define dim(x)                (sizeof(x) / sizeof(x[0]))
#define IDC_BUTTON_FORM1      1600
#define IDC_BUTTON_FORM2      1605
#define IDC_BUTTON_FORM3      1610

struct                        WndEventArgs
{
 HWND                         hWnd;
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
};

struct EVENTHANDLER
{
 unsigned int                 iMsg;
 LRESULT                      (*fnPtr)(WndEventArgs&);
};

LRESULT fnWndProc_OnCreate    (WndEventArgs&);  //We need foreward declarations of
LRESULT fnWndProc_OnCommand   (WndEventArgs&);  //the various functions in a main
LRESULT fnWndProc_OnClose     (WndEventArgs&);  //header file so that the event
                                                //handlers can be attached below.
LRESULT fnForm1_OnCreate      (WndEventArgs&);
LRESULT fnForm1_OnPaint       (WndEventArgs&);
LRESULT fnForm1_OnDestroy     (WndEventArgs&);

LRESULT fnForm2_OnCreate      (WndEventArgs&);
LRESULT fnForm2_OnPaint       (WndEventArgs&);
LRESULT fnForm2_OnDestroy     (WndEventArgs&);

LRESULT fnForm3_OnCreate      (WndEventArgs&);
LRESULT fnForm3_OnPaint       (WndEventArgs&);
LRESULT fnForm3_OnClose       (WndEventArgs&);

const EVENTHANDLER            Form1EventHandler[]=
{
 {WM_CREATE,                  fnForm1_OnCreate},
 {WM_PAINT,                   fnForm1_OnPaint},
 {WM_DESTROY,                 fnForm1_OnDestroy}
};

const EVENTHANDLER            Form2EventHandler[]=
{
 {WM_CREATE,                  fnForm2_OnCreate},
 {WM_PAINT,                   fnForm2_OnPaint},
 {WM_DESTROY,                 fnForm2_OnDestroy}
};

const EVENTHANDLER            Form3EventHandler[]=
{
 {WM_PAINT,                   fnForm3_OnPaint},
 {WM_CLOSE,                   fnForm3_OnClose}
};

#endif
Code:
// Main.cpp
// cl Main.cpp Form1.cpp Form2.cpp Form3.cpp /O1 /Os /GS- /W2 /FeMultipleForms.exe TCLib.lib kernel32.lib user32.lib gdi32.lib
// cl Main.cpp Form1.cpp Form2.cpp Form3.cpp /O1 /Os /GS- /MT /FeMultipleForms.exe kernel32.lib user32.lib gdi32.lib 
// 92,160 Bytes x64 VC19 (VS 2015) asci libcmt linked 
// 10,752 Bytes x64 VC19 (VS 2015) wide TCLib  linked
//  9,728 bytes x64 VC19 (VS 2015) asci TCLib  linked
#ifndef UNICODE
   #define UNICODE
#endif
#ifndef _UNICODE
   #define _UNICODE
#endif   
// Main.cpp               //Program displays a main Form/Window/Dialog With Three Buttons on it to simulate
#include <windows.h>      //a program started from a main Form with three modules/options/modalities within
#include <tchar.h>        //which it operates.  When you click the top button a new Form/Window/Dialog is
#include <stdio.h>        //created with CreateWindow() of the "Form1" Window Class, and in the WM_CREATE
#include "Main.h"         //handler of this new window it disables the main form with the three buttons and
#include "Form1.h"        //therefore is an example of a modal dialog.  When you dismiss this modal dialog
#include "Form2.h"        //and click on Button/Option #2 on the Main Form, a CreateWindow() call creates a
#include "Form3.h"        //window of "Form2" Window Class, and in the WM_CREATE handler it sets the visi-
                          // bility of the main window to FALSE.
const EVENTHANDLER         EventHandler[]=        //Since we foreward declared above
{                                                 //the various event handling functions
 {WM_CREATE,               fnWndProc_OnCreate},   //of the various forms, windows, dialogs
 {WM_COMMAND,              fnWndProc_OnCommand},  //above, we can fill out the fields of
 {WM_CLOSE,                fnWndProc_OnClose}     //our EVENTHANDLER structures for the
};                                                //various objects.


LRESULT fnWndProc_OnCreate(WndEventArgs& Wea)      //...for this window it hides or makes invisible the main
{                                                  //window.  After dismssing this window you'll find that you
 DWORD dwStyle=WS_CHILD|WS_VISIBLE;                //can click on the Option #3 button as many times as you like
 TCHAR szClassName[16];                            //because the window-form-dialog it creates neither disables
 WNDCLASSEX wc;                                    //nor makes invisible the main window.  Further note that these
                                                   //Option #3 windows can be interacted with regardless of what-
 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance; //ever is going on with the other windows.
 CreateWindow(_T("button"),_T("Option #1"),dwStyle,65,15,120,25,Wea.hWnd,(HMENU)IDC_BUTTON_FORM1,Wea.hIns,0);
 CreateWindow(_T("button"),_T("Option #2"),dwStyle,65,55,120,25,Wea.hWnd,(HMENU)IDC_BUTTON_FORM2,Wea.hIns,0);
 CreateWindow(_T("button"),_T("Option #3"),dwStyle,65,95,120,25,Wea.hWnd,(HMENU)IDC_BUTTON_FORM3,Wea.hIns,0);

 //Register Window Classes For Form1, Form2 and Form3
 wc.cbSize=sizeof(WNDCLASSEX),                            wc.style=CS_HREDRAW | CS_VREDRAW;
 wc.cbClsExtra=0,                                         wc.cbWndExtra=0;
 wc.hInstance=Wea.hIns,                                   wc.hIcon=LoadIcon(NULL, IDI_APPLICATION);
 wc.hIconSm=0,                                            wc.hCursor=LoadCursor(NULL, IDC_ARROW);
 wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH),    wc.lpszMenuName=NULL;
 _tcscpy(szClassName,_T("Form1")),                        wc.lpszClassName=szClassName;
 wc.lpfnWndProc=fnForm1_WndProc;
 RegisterClassEx(&wc);

 _tcscpy(szClassName,_T("Form2"));
 wc.lpfnWndProc=fnForm2_WndProc;
 wc.lpszClassName=szClassName;                //Note that a WM_CREATE call is akin to a constructor call in typical
 RegisterClassEx(&wc);                        //C++ class architecture.  When you receive this call/message Windows
                                              //has finished doing what it needs to support the Window object, and
 _tcscpy(szClassName,_T("Form3"));            //is 'passing the ball' to you.  In my apps with multiple windows I
 wc.lpszClassName=szClassName;                //typically use the WM_CREATE handler to register any window classes
 wc.lpfnWndProc=fnForm3_WndProc;              //I need in the app, so that I can make CreateWindow() calls when I
 RegisterClassEx(&wc);                        //need to instantiate a window of some type.

 return 0;
}


long btnForm1_Click(WndEventArgs& Wea)                     //This is an 'Event Handler' for a click of the top button on the
{                                                          //main Form.  It uses CreateWindowEx() to instantiate a new Window
 DWORD dwStyle,dwExStyle;                                  //of class "Form1"  Note that the last parameter of the call is
 HWND hDlg;                                                //Wea.hWnd.  That is the HWND of the main program Window.  The
 MSG Msg;                                                  //last parameter is the Creation Parameters parameter.  It can be
                                                           //retrieved (as can all the others) through the CREATIONSTRUCT a
 dwStyle   = WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE;     //pointer to which is received in the lParam of the WM_CREATE
 dwExStyle = WS_EX_DLGMODALFRAME | WS_EX_CONTROLPARENT;    //message for the newly instantiating Window.
 hDlg=CreateWindowEx(dwExStyle,_T("Form1"),_T("Form1"),dwStyle,50,25,310,185,Wea.hWnd,(HMENU)0,GetModuleHandle(0),Wea.hWnd);
 ShowWindow(hDlg,SW_SHOWNORMAL);
 UpdateWindow(hDlg);
 while(GetMessage(&Msg,NULL,0,0))    // The IsDialogMessage function determines whether a message is intended for the specified
 {                                   // dialog box and, if it is, processes the message.  If the message has been processed, the
    if(!IsDialogMessage(hDlg,&Msg))  // return value is nonzero.  If the message has not been processed, the return value is zero.
    {                                // Because the IsDialogMessage function performs all necessary translating and dispatching of
       TranslateMessage(&Msg);       // messages, a message processed by IsDialogMessage must not be passed to the TranslateMessage
       DispatchMessage(&Msg);        // or DispatchMessage function.If the return value is zero, its not a message for hDlg.  So
    }                                // process it.
 }

 return 0;
}


long btnForm2_Click(WndEventArgs& Wea)
{
 HWND hWnd;

 hWnd=CreateWindowEx
 (
   0,
   _T("Form2"),
   _T("Form2"),
   WS_OVERLAPPEDWINDOW,
   200,250,310,185,
   0,
   (HMENU)0,
   GetModuleHandle(0),
   Wea.hWnd
 );
 ShowWindow(hWnd,SW_SHOWNORMAL);
 UpdateWindow(hWnd);

 return 0;
}


long btnForm3_Click(WndEventArgs& Wea)
{
 HWND hWnd;

 hWnd=CreateWindowEx
 (
   0,
   _T("Form3"),
   _T("Form3"),
   WS_OVERLAPPEDWINDOW,
   CW_USEDEFAULT,CW_USEDEFAULT,300,260,
   0,
   (HMENU)0,
   GetModuleHandle(0),
   Wea.hWnd
 );
 ShowWindow(hWnd,SW_SHOWNORMAL);
 UpdateWindow(hWnd);

 return 0;
}


LRESULT fnWndProc_OnCommand(WndEventArgs& Wea)
{
 switch(LOWORD(Wea.wParam))
 {
    case IDC_BUTTON_FORM1:
      return btnForm1_Click(Wea);
    case IDC_BUTTON_FORM2:
      return btnForm2_Click(Wea);
    case IDC_BUTTON_FORM3:
      return btnForm3_Click(Wea);
 }

 return 0;
}


LRESULT fnWndProc_OnClose(WndEventArgs& Wea)     //Search And Destroy Mission For Any Form3
{                                                //Windows Hanging Around.
 HWND hForm;

 if(MessageBox(Wea.hWnd,_T("Do You Wish To Exit?"),_T("Exit App?"),MB_YESNO)==IDYES)
 {
    do                                           //If FindWindow() returns something other
    {                                            //than zero, it found a window matching
      hForm=FindWindow(_T("Form3"),_T("Form3")); //the description of what you are looking
      if(hForm)                                  //for.  In that case, send a WM_CLOSE
         SendMessage(hForm,WM_CLOSE,0,0);        //message.  If NULL is returned then just
      else                                       //break out of the loop and terminate the
         break;                                  //app.  I don't believe this code is really
    }while(TRUE);                                //necessary, but I left it in.
    DestroyWindow(Wea.hWnd);
    PostQuitMessage(0);
 }

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam,LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("Multiple Forms");
 WNDCLASSEX wc={};
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 wc.hInstance=hInstance,                      wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,250,500,260,180,HWND_DESKTOP,0,hInstance,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}
Code:
//Form1.cpp
#ifndef UNICODE
   #define UNICODE
#endif
#ifndef _UNICODE
   #define _UNICODE
#endif   
#include  <Windows.h>
#include  <tchar.h>
#include  "Form1.h"
#include  "Main.h"


LRESULT fnForm1_OnCreate(WndEventArgs& Wea)
{
 CREATESTRUCT* pCreateStruct;
 HWND hMain;

 pCreateStruct=(CREATESTRUCT*)Wea.lParam;
 hMain=(HWND)pCreateStruct->lpCreateParams;
 SetWindowLongPtr(Wea.hWnd,GWLP_USERDATA,(LONG_PTR)hMain);
 EnableWindow(hMain,FALSE);

 return 0;
}


LRESULT fnForm1_OnPaint(WndEventArgs& Wea)
{
 PAINTSTRUCT ps;
 HDC hDC;

 hDC=BeginPaint(Wea.hWnd,&ps);
 TextOut(hDC,0,0,_T("This Is Form1.  It Disables The Main"),36);
 TextOut(hDC,0,16,_T("Window, And That Makes It Modal.  Note"),38);
 TextOut(hDC,0,32,_T("That We Passed The Handle Of The Main"),37);
 TextOut(hDC,0,48,_T("Window In The Last Parameter Of The"),35);
 TextOut(hDC,0,64,_T("CreateWindow() Call, And Retrieved It In"),40);
 TextOut(hDC,0,80,_T("fnForm1_OnCreate().  We Then Stored It So"),41);
 TextOut(hDC,0,96,_T("We Could EnableWindow(TRUE) The Main"),36);
 TextOut(hDC,0,112,_T("Window When This Modal Form Is"),30);
 TextOut(hDC,0,128,_T("Dismissed."),10);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}


LRESULT fnForm1_OnDestroy(WndEventArgs& Wea)
{
 HWND hMain;

 hMain=(HWND)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
 EnableWindow(hMain,TRUE);
 PostQuitMessage(0);
 return 0;
}


LRESULT CALLBACK fnForm1_WndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(Form1EventHandler); i++)
 {
     if(Form1EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hWnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*Form1EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hWnd, msg, wParam, lParam));
}
Code:
//Form1.h         //Needs to be included in Main.cpp because the WM_CREATE handler there
#ifndef FORM1_H   //references fnForm1_WndProc as the Window Procedure for the Form1 Class.
#define FORM1_H   //This would be needed to register the class.
LRESULT CALLBACK fnForm1_WndProc(HWND, unsigned int, WPARAM, LPARAM);
#endif
Code:
//Form2.cpp
#ifndef UNICODE
   #define UNICODE
#endif
#ifndef _UNICODE
   #define _UNICODE
#endif   
#include  <Windows.h>
#include  <tchar.h>
#include  "Main.h"
#include  "Form2.h"


LRESULT fnForm2_OnCreate(WndEventArgs& Wea)
{
 CREATESTRUCT* pCreateStruct;
 HWND hMain;

 pCreateStruct=(CREATESTRUCT*)Wea.lParam;
 hMain=(HWND)pCreateStruct->lpCreateParams;
 SetWindowLongPtr(Wea.hWnd,GWLP_USERDATA,(LONG_PTR)hMain);
 ShowWindow(hMain,SW_HIDE);

 return 0;
}


LRESULT fnForm2_OnPaint(WndEventArgs& Wea)
{
 PAINTSTRUCT ps;
 HDC hDC;

 hDC=BeginPaint(Wea.hWnd,&ps);
 TextOut(hDC,0,0,_T("This Is Form2.  It SW_HIDEs The Main"),36);
 TextOut(hDC,0,16,_T("Window, And SW_SHOWs It Upon Closing."),37);
 TextOut(hDC,0,32,_T("This Technique Can Be Used Similiarly"),37);
 TextOut(hDC,0,48,_T("To A Modal Dialog If It Isn't Necessary To"),42);
 TextOut(hDC,0,64,_T("View Simultaneously A Form Underneath The"),41);
 TextOut(hDC,0,80,_T("Dialog With Which You Can't Interact"),36);
 TextOut(hDC,0,96,_T("Anyway"),6);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}


LRESULT fnForm2_OnDestroy(WndEventArgs& Wea)
{
 HWND hMain;

 hMain=(HWND)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
 EnableWindow(hMain,TRUE);
 ShowWindow(hMain,TRUE);

 return 0;
}


LRESULT CALLBACK fnForm2_WndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(Form2EventHandler); i++)
 {
     if(Form2EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hWnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*Form2EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hWnd, msg, wParam, lParam));
}
Code:
//Form2.h        //Needs to be included in Main.cpp because the WM_CREATE handler there
#ifndef FORM2_H  //references fnForm2_WndProc as the Window Procedure for the Form1 Class.
#define FORM2_H  //This would be needed to register the class.
LRESULT CALLBACK fnForm2_WndProc(HWND, unsigned int, WPARAM, LPARAM);
#endif
Code:
//Form3.cpp
#ifndef UNICODE
   #define UNICODE
#endif
#ifndef _UNICODE
   #define _UNICODE
#endif   
#include  <Windows.h>
#include  <tchar.h>
#include  "Main.h"
#include  "Form3.h"


LRESULT fnForm3_OnPaint(WndEventArgs& Wea)
{
 PAINTSTRUCT ps;
 HDC hDC;

 hDC=BeginPaint(Wea.hWnd,&ps);
 TextOut(hDC,0,0,_T("This Is Form3.  Not Only Does It Neither"),40);
 TextOut(hDC,0,16,_T("Hide Nor Disable The Main Window, But"),37);
 TextOut(hDC,0,32,_T("You'll Find That You Can Create As Many"),39);
 TextOut(hDC,0,48,_T("Of These As You Like By Continually"),35);
 TextOut(hDC,0,64,_T("Clicking The Bottom Button On The Main"),38);
 TextOut(hDC,0,80,_T("Form.  However, You'll Have To Drag One"),39);
 TextOut(hDC,0,96,_T("From On Top Of The Other Because They"),37);
 TextOut(hDC,0,112,_T("All Appear In The Same Location (I"),34);
 TextOut(hDC,0,128,_T("Changed That).  You May Further Note"),36);
 TextOut(hDC,0,144,_T("That Since These Windows Are Neither"),36);
 TextOut(hDC,0,160,_T("Disabled Nor Hidden At Any Time, You"),36);
 TextOut(hDC,0,176,_T("May Interact With Them Irregardless Of"),38);
 TextOut(hDC,0,192,_T("The State Of Form1 Or Form2. Pretty"),35);
 TextOut(hDC,0,208,_T("Neat, Don't You Think?"),22);
 EndPaint(Wea.hWnd,&ps);

 return 0;
}


LRESULT fnForm3_OnClose(WndEventArgs& Wea)
{
 HWND hMain;

 MessageBox
 (
  Wea.hWnd,
  _T("Good Way To Release Any Resources, Memory, etc., You May Have Allocated"),
  _T("Window Close Report!"),
  MB_OK
 );
 hMain=(HWND)GetWindowLongPtr(Wea.hWnd,GWLP_USERDATA);
 EnableWindow(hMain,TRUE);
 DestroyWindow(Wea.hWnd);
 ShowWindow(hMain,TRUE);

 return 0;
}


LRESULT CALLBACK fnForm3_WndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(Form3EventHandler); i++)
 {
     if(Form3EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hWnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*Form3EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hWnd, msg, wParam, lParam));
}
Code:
//Form3.h        //Needs to be included in Main.cpp because the WM_CREATE handler there
#ifndef FORM3_H  //references fnForm3_WndProc as the Window Procedure for the Form1 Class.
#define FORM3_H  //This would be needed to register the class.
LRESULT CALLBACK fnForm3_WndProc(HWND, unsigned int, WPARAM, LPARAM);
#endif
A worthwhile addition to the above program would be modifications to enable resolution independence at altered user DPI (dots per inch) settings.