/* The original version of this program can be found at http://damb.dk */
#include <windows.h>
#include <commctrl.h>

HINSTANCE InstanceHandle;
HWND      MainWindow;
HWND      StatusBarWindow;
HWND      ToolBarWindow;
enum MenuCommand
{
   FileOpenCmd = 1000,
   FileSaveCmd,
   FileCloseCmd,
   AboutCmd
};

enum WindowId
{
   StatusBarId = 128,
   ToolBarId
};

void SetStatusBarWidths(HWND ParentWindow)
{
   int BoxRight[3];
   RECT ParentRect;
   GetClientRect(ParentWindow, &ParentRect);
   int Width = ParentRect.right - ParentRect.left;
   BoxRight[0] = 100;
   BoxRight[1] = Width - 100;
   BoxRight[2] = -1;
   SendMessage(StatusBarWindow, SB_SETPARTS, 3, (LPARAM )BoxRight);
}

void SetStatusBarText(const char *Text, WORD PartNumber)
{
   SendMessage(StatusBarWindow, SB_SETTEXT, PartNumber, (LPARAM )Text);
}

bool CreateToolBar(HWND ParentWindow)
{
   const int NumButton = 3;
   ToolBarWindow = CreateWindowEx(0,
                                  TOOLBARCLASSNAME,
                                  0,
                                  WS_CHILD|WS_BORDER,
                                  0, 0, 0, 0,
                                  ParentWindow,
                                  (HMENU )ToolBarId,
                                  InstanceHandle,
                                  0);

   SendMessage(ToolBarWindow,
               TB_BUTTONSTRUCTSIZE,
               (WPARAM )sizeof(TBBUTTON),
               0);

   TBADDBITMAP TBaddBitmap;
   TBaddBitmap.hInst = HINST_COMMCTRL;
   TBaddBitmap.nID   = IDB_STD_SMALL_COLOR;
   SendMessage(ToolBarWindow,
               TB_ADDBITMAP,
               (WPARAM )NumButton,
               (LPARAM )&TBaddBitmap);

   TBBUTTON ButtonInfo[NumButton];

   memset(ButtonInfo, 0, sizeof(ButtonInfo));

   int idx;
   idx = SendMessage(ToolBarWindow,
                     TB_ADDSTRING,
                     0,
                     (LPARAM )"Open");
   ButtonInfo[0].iString = idx;
   ButtonInfo[0].iBitmap = STD_FILEOPEN;
   ButtonInfo[0].idCommand = FileOpenCmd;
   ButtonInfo[0].fsState = TBSTATE_ENABLED;
   ButtonInfo[0].fsStyle = TBSTYLE_BUTTON;

   idx = SendMessage(ToolBarWindow,
                     TB_ADDSTRING,
                     0,
                     (LPARAM )"Save");
   ButtonInfo[1].iString = idx;
   ButtonInfo[1].iBitmap = STD_FILESAVE;
   ButtonInfo[1].idCommand = FileSaveCmd;
   ButtonInfo[1].fsState = TBSTATE_ENABLED;
   ButtonInfo[1].fsStyle = TBSTYLE_BUTTON;

   idx = SendMessage(ToolBarWindow,
                     TB_ADDSTRING,
                     0,
                     (LPARAM )"About");
   ButtonInfo[2].iString = idx;
   ButtonInfo[2].iBitmap = STD_HELP;
   ButtonInfo[2].idCommand = AboutCmd;
   ButtonInfo[2].fsState = TBSTATE_ENABLED;
   ButtonInfo[2].fsStyle = TBSTYLE_BUTTON;

   SendMessage(ToolBarWindow,
               TB_ADDBUTTONS,
               NumButton,
               (LPARAM)&ButtonInfo);

   ShowWindow(ToolBarWindow, SW_SHOW);

   return true;
}


LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch (msg)
   {
      case WM_DESTROY:
         PostQuitMessage(0);
         break;
      case WM_SIZE:
         SendMessage(StatusBarWindow, msg, wParam, lParam);
         SendMessage(ToolBarWindow, msg, wParam, lParam);
         SetStatusBarWidths(hwnd);
         break;
      case WM_COMMAND:
         switch(LOWORD(wParam))
         {
         case FileOpenCmd:
             MessageBox(hwnd, "Open", "Test", MB_OK);
             break;
         case FileSaveCmd:
             MessageBox(hwnd, "Save", "Test", MB_OK);
             break;
         case FileCloseCmd:
             MessageBox(hwnd, "Close", "Test", MB_OK);
             break;
         case AboutCmd:
             MessageBox(hwnd, "About", "Test", MB_OK);
             break;
         }
         break;
      default:
         return DefWindowProc(hwnd,msg,wParam,lParam);
   }
   return 0;
}

HWND CreateMainWindow()
{
   WNDCLASS wc;
   memset(&wc, 0, sizeof(WNDCLASS));
   wc.style = CS_HREDRAW | CS_VREDRAW  | CS_DBLCLKS ;
   wc.lpfnWndProc = (WNDPROC )MainWndProc;
   wc.hInstance = InstanceHandle;
   wc.hbrBackground = (HBRUSH )(COLOR_WINDOW + 1);
   wc.lpszClassName = "SimpleWinWndClass";
   wc.lpszMenuName = 0;
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   if(!RegisterClass(&wc))
      return 0;

   HMENU FileMenu = CreateMenu();
   AppendMenu(FileMenu, MF_STRING, FileOpenCmd, "Open");
   AppendMenu(FileMenu, MF_STRING, FileSaveCmd, "Save");
   AppendMenu(FileMenu, MF_SEPARATOR, 0 , 0);
   AppendMenu(FileMenu, MF_STRING, FileCloseCmd, "Close");

   HMENU HelpMenu = CreateMenu();
   AppendMenu(HelpMenu, MF_STRING, AboutCmd, "About");

   HMENU MainMenu = CreateMenu();
   AppendMenu(MainMenu, MF_POPUP, (UINT )FileMenu, "File");
   AppendMenu(MainMenu, MF_POPUP, (UINT )HelpMenu, "Help");

   return CreateWindow("SimpleWinWndClass",
                       "Simple-Window",
                       WS_MINIMIZEBOX | WS_VISIBLE |
                       WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZEBOX |
                       WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_THICKFRAME,
                       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
                       0,
                       MainMenu,
                       InstanceHandle,
                       0);
}

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   INT nCmdShow)
{
   InstanceHandle = hInstance;
   InitCommonControls();
   if((MainWindow = CreateMainWindow()) == (HWND )0)
   {
      MessageBox(0, "Failed to create MainWindow!", "Warning", MB_OK);
      return 0;
   }
   StatusBarWindow = CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_BORDER|SBARS_SIZEGRIP,
                                        "Ready",
                                        MainWindow,
                                        StatusBarId);

   SetStatusBarWidths(MainWindow);
   CreateToolBar(MainWindow);
   ShowWindow(MainWindow, SW_SHOW);
   SetStatusBarText("First",  0);
   SetStatusBarText("Middle", 1);
   SetStatusBarText("Right",  2);
   MSG Msg;
   while(GetMessage(&Msg, 0, 0, 0))
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
   }
   return Msg.wParam;
}