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

HINSTANCE InstanceHandle;
HWND      MainWindow;

enum MessageId
{
   DisplayLeftMsgId = 1024,
   DisplayTopMsgId,
   DisplayRightMsgId,
   DisplayBottomMsgId,
   Zoom2MsgId,
   Zoom4MsgId,
   Zoom8MsgId,
   Zoom16MsgId,
};

MessageId ZoomPos = DisplayLeftMsgId;
MessageId ZoomFactor = Zoom4MsgId;

void Draw(HDC aDc)
{
   int Zoom = 1 << (ZoomFactor - Zoom2MsgId + 1);

   RECT R;
   GetWindowRect(MainWindow, &R);
   int Width = (R.right - R.left + Zoom - 1)/Zoom;
   int Height = (R.bottom - R.top + Zoom - 1)/Zoom;

   POINT UpperLeft;
   switch(ZoomPos)
   {
   case DisplayLeftMsgId:
      UpperLeft.x = R.left - Width;
      UpperLeft.y = R.top;
      break;
   case DisplayTopMsgId:
      UpperLeft.x = R.left;
      UpperLeft.y = R.top - Height;
      break;
   case DisplayRightMsgId:
      UpperLeft.x = R.right;
      UpperLeft.y = R.top;
      break;
   case DisplayBottomMsgId:
      UpperLeft.x = R.right - Width;
      UpperLeft.y = R.bottom;
      break;
   }
   HDC DC = GetDC(0);
   StretchBlt(aDc,
              0,
              0,
              Width*Zoom,
              Height*Zoom,
              DC,
              UpperLeft.x,
              UpperLeft.y,
              Width,
              Height,
              SRCCOPY);

   ReleaseDC(0, DC);
}

void Draw()
{
   HDC Dc;
   Dc = GetDC(MainWindow);
   Draw(Dc);
   ReleaseDC(MainWindow, Dc);
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch (msg)
   {
   case WM_DESTROY:
      PostQuitMessage(0);
      break;
   case WM_MOVE:
   {
      Draw();
      break;
   }
   case WM_SYSCOMMAND:
   {
      switch(wParam)
      {
      case DisplayLeftMsgId:
      case DisplayTopMsgId:
      case DisplayRightMsgId:
      case DisplayBottomMsgId:
         ZoomPos = (MessageId )wParam;
         Draw();
         break;
      case Zoom2MsgId:
      case Zoom4MsgId:
      case Zoom8MsgId:
      case Zoom16MsgId:
         ZoomFactor = (MessageId )wParam;
         Draw();
         break;
      default:
         return DefWindowProc(hwnd, msg, wParam, lParam);
      }
      break;
   }
   case WM_PAINT:
      PAINTSTRUCT PaintStruct;
      HDC dc;
      dc = BeginPaint(hwnd, &PaintStruct);
      Draw(dc);
      EndPaint(hwnd, &PaintStruct);
      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;

   return CreateWindow("SimpleWinWndClass",
                       "MagnifyingGlass",
                       WS_MINIMIZEBOX | WS_VISIBLE |
                       WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZEBOX |
                       WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_THICKFRAME,
                       100, 100, 100, 100,
                       0,
                       0,
                       InstanceHandle,
                       0);
}

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE,
                   LPSTR,
                   INT)
{
   InstanceHandle = hInstance;

   if((MainWindow = CreateMainWindow()) == (HWND )0)
   {
      MessageBox(0, "Failed to create MainWindow!", "Warning", MB_OK);
      return 0;
   }
   HMENU SysMenu = GetSystemMenu(MainWindow, FALSE);
   AppendMenu(SysMenu, MF_SEPARATOR, 0 , 0);
   AppendMenu(SysMenu, MF_STRING, DisplayLeftMsgId, "Display Left");
   AppendMenu(SysMenu, MF_STRING, DisplayTopMsgId, "Display Top");
   AppendMenu(SysMenu, MF_STRING, DisplayRightMsgId, "Display Right");
   AppendMenu(SysMenu, MF_STRING, DisplayBottomMsgId, "Display Bottom");
   AppendMenu(SysMenu, MF_SEPARATOR, 0 , 0);
   AppendMenu(SysMenu, MF_STRING, Zoom2MsgId, "Zoom * 2");
   AppendMenu(SysMenu, MF_STRING, Zoom4MsgId, "Zoom * 4");
   AppendMenu(SysMenu, MF_STRING, Zoom8MsgId, "Zoom * 8");
   AppendMenu(SysMenu, MF_STRING, Zoom16MsgId, "Zoom * 16");


   ShowWindow(MainWindow, SW_SHOW);
   MSG Msg;
   while(GetMessage(&Msg, 0, 0, 0))
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
   }
   return Msg.wParam;
}