#define INCL_PM

#include <OS2.h>
#include <StdLib.h>
#include <functional>
#include <typeinfo>

#define t_id(x) ( typeid (x).hash_code () )
#define t_name(x) ( typeid (x).name () )

#define Run int main

//
// ... здесь описания типов данных ... 
//

Run ()
{
  // Создаём структуру с состоянием программы.
  P_PROGRAM_STATE Program_state; Allocate (&Program_state, t_id (PROGRAM_STATE), VM_PROGRAM_STATE | VM_WRITE_ZEROS);

  // Начинаем работу в оконной оболочке.
  HAB Shell_handle = WinInitialize (0);

  // Создаём очередь сообщений.
  HMQ Msg_queue = WinCreateMsgQueue (Shell_handle, 0);

  //
  // ... здесь должно быть создание окон ... 
  //

  // Читаем сообщения и передаём их окнам.
  QMSG Message = {0}; ULONG Rc = 1;

  while (Rc)
  {
    Rc = WinGetMsg (Shell_handle, &Message, 0, 0, 0);

    if (Rc)
    {
      Message.reserved = (ULONG) Program_state; WinDispatchMsg (Shell_handle, &Message);
    }
  }

  //
  // Или так:
  // ReadMessages (Shell_handle, [=] (PQMSG Message) {
  //                                                   ProcessMessage (Program_state, Message);
  //                                                 });
  //
  //

  //
  // Или так:
  // WinMessageBox (HWND_DESKTOP, NULLHANDLE, "Hello World!", "", 0, 0);
  //

  // 
  // А можно было бы и так:
  // WinReadMsgQueue (Msg_queue, Program_state);
  // 

;

  //
  // ... здесь должно быть удаление созданных окон ... 
  //

  // Удаляем очередь.
  WinDestroyMsgQueue (Msg_queue);

  // Завершаем работу в оконной оболочке.
  WinTerminate (Shell_handle);

  // Удаляем структуру с состоянием программы.
  Free (&Program_state);

  return 0;
}