FormView Dialog

This example is composed of three files:

Source code(formview.cpp)
//=============================================================================
//'FORMVIEW' DIALOG - Copyright © 2000,2005 Ken Fitlike
//=============================================================================
//API functions used: CreateDialog,CreateWindowEx,DefWindowProc,DestroyWindow,
//DispatchMessage,GetDlgItem,GetMessage,GetSystemMetrics,IsDialogMessage,
//IsWindow,LoadImage,MessageBox,PostQuitMessage,RegisterClassEx,SetFocus,
//SetWindowLongPtr,SetWindowPos,ShowWindow,UpdateWindow,TranslateMessage,
//WinMain.
//=============================================================================
//Demonstrates the creation of a 'formview' - a window where the client area is
//covered with a modeless dialog box without any borders.
//
//MinGW    - There seems to be a bug in MinGW v293.3 because the modeless  
//           dialog is NOT created with the styles specified in the resource 
//           script, nor is the parent properly set by the CreateDialog fn call  
//           so need to explicitly set both the parent and the dialog box  
//           window styles. This is not a problem with later versions. Rather 
//           than use preprocessor fiddling to get it to work with such an  
//           ancient version, just upgrade mingw to a later version.
//MSVC2003 - Compile with multi-threaded libs (/MT switch)
//=============================================================================
#include <windows.h>  //include all the basics
#include <tchar.h>    //string and other mapping macros
#include <string>
#include "resources.h"

//define an unicode string type alias
typedef std::basic_string<TCHAR> ustring;
//=============================================================================
//main window message processing function declarations
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int OnCreate(const HWND,CREATESTRUCT*);
void OnSize(const HWND,int,int,UINT);

//dialog box message processing function declarations
INT_PTR CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);
void OnCommandDlg(const HWND,int,int,const HWND);
void OnInitDlg(const HWND,LPARAM);

//non-message function declarations
inline int ErrMsg(const ustring&);
//=============================================================================
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR pStr,int nCmd)
{
ustring classname=_T("SIMPLEWND");
WNDCLASSEX wcx={0};  //used for storing information about the wnd 'class'

wcx.cbSize         = sizeof(WNDCLASSEX);           
wcx.lpfnWndProc    = WndProc;             //wnd Procedure pointer
wcx.hInstance      = hInst;               //app instance
//use 'LoadImage' to load wnd class icon and cursor as it supersedes the 
//obsolete functions 'LoadIcon' and 'LoadCursor', although these functions will 
//still work. Because the icon and cursor are loaded from system resources ie 
//they are shared, it is not necessary to free the image resources with either 
//'DestroyIcon' or 'DestroyCursor'.
wcx.hIcon         = reinterpret_cast<HICON>(LoadImage(0,IDI_APPLICATION,
                                            IMAGE_ICON,0,0,LR_SHARED));
wcx.hCursor       = reinterpret_cast<HCURSOR>(LoadImage(0,IDC_ARROW,
                                              IMAGE_CURSOR,0,0,LR_SHARED));
//Since the dialog box (the 'form') will cover the window's client area, a
//background brush is unnecessary; this also reduces flicker when the window
//is resized as only the dialog's background is drawn. The value is explicitly
//set to zero here to draw attention to this fact - it's already set to zero
//with the declaration of wcx, above.                                              
wcx.hbrBackground = 0; 
wcx.lpszClassName = classname.c_str(); 
//the window 'class' (not c++ class) has to be registered with the system
//before windows of that 'class' can be created
if (!RegisterClassEx(&wcx))
  {
  ErrMsg(_T("Failed to register wnd class"));
  return -1;
  }

int desktopwidth=GetSystemMetrics(SM_CXSCREEN);
int desktopheight=GetSystemMetrics(SM_CYSCREEN);

HWND hwnd=CreateWindowEx(0,                     //extended styles
                         classname.c_str(),     //name: wnd 'class'
                         _T("Dialogs: 'FormView' Window"), //wnd title
                         WS_OVERLAPPEDWINDOW,   //wnd style
                         desktopwidth/4,        //position:left
                         desktopheight/4,       //position: top
                         desktopwidth/2,        //width
                         desktopheight/2,       //height
                         0,                     //parent wnd handle
                         0,                     //menu handle/wnd id
                         hInst,                 //app instance
                         0);                    //user defined info
if (!hwnd)
  {
  ErrMsg(_T("Failed to create wnd"));
  return -1;
  }

ShowWindow(hwnd,nCmd); 
UpdateWindow(hwnd);
//start message loop - windows applications are 'event driven' waiting on user,
//application or system signals to determine what action, if any, to take. Note 
//that an error may cause GetMessage to return a negative value so, ideally,  
//this result should be tested for and appropriate action taken to deal with 
//it(the approach taken here is to simply quit the application).
MSG msg;
HWND hDlg=GetDlgItem(hwnd,IDD_DIALOG1);
while (GetMessage(&msg,0,0,0)>0)
  {
  //make sure that default, system dialog box behaviour occurs
  if (!IsWindow(hDlg) || !IsDialogMessage(hDlg,&msg))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
  }
return static_cast<int>(msg.wParam);
}
//=============================================================================
//main window message processing functions
//=============================================================================
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
  {
  case WM_CREATE:
    return OnCreate(hwnd,reinterpret_cast<CREATESTRUCT*>(lParam));
  case WM_DESTROY:
    DestroyWindow(GetDlgItem(hwnd,IDD_DIALOG1));
    PostQuitMessage(0);    //signal end of application
    return 0;
  case WM_SIZE:
    OnSize(hwnd,LOWORD(lParam),HIWORD(lParam),static_cast<UINT>(wParam));
    return 0;
  default:
    //let system deal with msg
    return DefWindowProc(hwnd,uMsg,wParam,lParam);  
  }
}
//=============================================================================
int OnCreate(const HWND hwnd,CREATESTRUCT *cs)
{
//handles the WM_CREATE message of the main, parent window; return -1 to fail
//window creation

CreateDialog(cs->hInstance,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,DlgProc);

return 0;
}
//=============================================================================
void OnSize(const HWND hwnd,int cx,int cy,UINT uFlags)
{
//handles the WM_SIZE message of the main, parent window; make sure the dialog
//box always covers the main window's client area
HWND hDlg=GetDlgItem(hwnd,IDD_DIALOG1);
if (IsWindow(hDlg))
  {
  SetWindowPos(hDlg,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);
  }
}
//=============================================================================
//dialog box message processing functions
//=============================================================================
INT_PTR CALLBACK DlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
  {
  case WM_COMMAND:
    OnCommandDlg(hwnd,LOWORD(wParam),HIWORD(wParam),
                 reinterpret_cast<HWND>(lParam));
    return 0;
  case WM_INITDIALOG:
    OnInitDlg(hwnd,lParam);
    return 0;
  default:
    return 0;
  }
}
//=============================================================================
void OnCommandDlg(const HWND hwnd,int id,int nCode,const HWND hCntrl)
{
//handles WM_COMMAND message of the dialog box
switch (id)
  {
  case IDCANCEL:    //'cancel' btn selected, 'esc' key pressed
    {
    //since destruction of the dialog box 'form' implies quitting the 
    //application, destroy the parent window. This has the effect of destroying
    //all child windows of the main, parent window (including the dialog box)
    //and posting the quit message.
    DestroyWindow(GetParent(hwnd));    
    }
  }
}
//=============================================================================
void OnInitDlg(const HWND hwnd,LPARAM lParam)
{
//handles WM_INITDIALOG message of the dialog box

//explicitly set the dialog id so that the GetDlgItem api fn will return a 
//valid handle for the dialog box.
SetWindowLongPtr(hwnd,GWLP_ID,IDD_DIALOG1);

SetFocus(GetDlgItem(hwnd,IDOK));    //set focus to 'ok' btn
}
//=============================================================================
//non-message processing functions
//=============================================================================
inline int ErrMsg(const ustring& s)
{
return MessageBox(0,s.c_str(),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);
}
//=============================================================================
Resource Definitions(resources.h)
//=============================================================================
//Resource script constants for FormView Dialog example.
//=============================================================================
#define IDD_DIALOG1                200
Resource Script(script.rc)
//=============================================================================
//FORMVIEW DIALOG - Copyright (c) 2000,2005 Ken Fitlike
//resource script
//=============================================================================
#if !defined __BORLANDC__
#include <afxres.h>
#endif
#include "resources.h"
//=============================================================================
//Resource languages: Codes for languages and sub-languages are declared in 
//winnt.h eg. for US english replace SUBLANG_ENGLISH_UK with SUBLANG_ENGLISH_US
//eg. for FRENCH replace LANG_ENGLISH with LANG_FRENCH and then replace 
//SUBLANG_ENGLISH_UK with either SUBLANG_FRENCH,SUBLANG_FRENCH_BELGIAN,
//SUBLANG_FRENCH_CANADIAN,SUBLANG_FRENCH_SWISS,SUBLANG_FRENCH_LUXEMBOURG,
//SUBLANG_FRENCH_MONACO depending on which national or regional variation of
//the language corresponds best with your requirements.
//
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK  
//=============================================================================
//Dialog
//=============================================================================
IDD_DIALOG1 DIALOGEX 0, 0, 252, 149
STYLE WS_CHILD | WS_CLIPCHILDREN
FONT 8, "MS Sans Serif"
  {
  DEFPUSHBUTTON   "OK",IDOK,22,62,50,14
  PUSHBUTTON      "Cancel",IDCANCEL,111,63,50,14
  }
//=============================================================================