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

enum WindowsId
{
   GoButtonId = 256,
   LinkComboId,
   ExitButtonId,
   AppMsg = WM_APP + 111
};

const char *const UrlList[] =
{
   "www.google.com",
   "www.yahoo.com",
   "http://home20.inet.tele.dk/midgaard/sample.html",
   0
};

HINSTANCE InstanceHandle;
bool First = true;
RECT CurrentRect;

bool operator != (const RECT& lhs, const RECT& rhs)
{
   return lhs.top != rhs.top || lhs.bottom != rhs.bottom || lhs.left != rhs.left || lhs.right != rhs.left;
}

void AddApp(HWND aHwnd)
{
   APPBARDATA AppBarData;
   memset(&AppBarData, 0, sizeof(AppBarData));
   AppBarData.cbSize = sizeof(AppBarData);
   AppBarData.hWnd = aHwnd;
   AppBarData.uCallbackMessage = AppMsg;
   AppBarData.uEdge = ABE_TOP;
   SHAppBarMessage(ABM_NEW, &AppBarData);
}

void RemoveApp(HWND aHwnd)
{
   APPBARDATA AppBarData;
   memset(&AppBarData, 0, sizeof(AppBarData));
   AppBarData.cbSize = sizeof(AppBarData);
   AppBarData.hWnd = aHwnd;
   AppBarData.uCallbackMessage = AppMsg;
   AppBarData.uEdge = ABE_TOP;
   SHAppBarMessage(ABM_REMOVE, &AppBarData);
}

BOOL CALLBACK SetFontFunc(HWND aHwnd, LPARAM lParam)
{
   SendMessage(aHwnd, WM_SETFONT, lParam, 0);
   return TRUE;
}

// This function draws the application background.
void DrawApp(HDC aDc)
{
   HBRUSH BBRush = CreateSolidBrush(RGB(0, 136, 160));
   HPEN Pen1 = CreatePen(PS_SOLID, 1, RGB(0, 160, 255));
   HPEN Pen2 = CreatePen(PS_SOLID, 1, RGB(0, 64, 80));

   HGDIOBJ OldPen = SelectObject(aDc, Pen1);
   MoveToEx(aDc, CurrentRect.left, CurrentRect.bottom, 0);
   LineTo(aDc, CurrentRect.left, CurrentRect.top);
   LineTo(aDc, CurrentRect.right - 1, CurrentRect.top);
   MoveToEx(aDc, CurrentRect.left + 1, CurrentRect.bottom - 1, 0);
   LineTo(aDc, CurrentRect.left + 1, CurrentRect.top + 1);
   LineTo(aDc, CurrentRect.right - 2, CurrentRect.top + 1);
   SelectObject(aDc, Pen2);

   MoveToEx(aDc, CurrentRect.right - 1, CurrentRect.top, 0);
   LineTo(aDc, CurrentRect.right - 1, CurrentRect.bottom - 1);
   LineTo(aDc, CurrentRect.left, CurrentRect.bottom - 1);
   MoveToEx(aDc, CurrentRect.right - 2, CurrentRect.top - 1, 0);
   LineTo(aDc, CurrentRect.right - 2, CurrentRect.bottom - 2);
   LineTo(aDc, CurrentRect.left, CurrentRect.bottom - 2);
   SelectObject(aDc, OldPen);
   RECT R = CurrentRect;
   R.top += 2;
   R.left += 2;
   R.right -= 2;
   R.bottom -= 2;
   FillRect(aDc, &R, BBRush);
   DeleteObject(BBRush);
   DeleteObject(Pen1);
   DeleteObject(Pen2);
}

void RepositionBar(HWND aHwnd)
{
   APPBARDATA AppBarData;
   memset(&AppBarData, 0, sizeof(AppBarData));
   AppBarData.cbSize = sizeof(AppBarData);
   AppBarData.uEdge = ABE_TOP;
   AppBarData.hWnd = aHwnd;

   AppBarData.rc.left = 0;
   AppBarData.rc.top = 0;
   AppBarData.rc.right = GetSystemMetrics(SM_CXFULLSCREEN);
   AppBarData.rc.bottom = 30;
   SHAppBarMessage(ABM_QUERYPOS, &AppBarData);

   AppBarData.uEdge = ABE_TOP;
   AppBarData.hWnd = aHwnd;

   SHAppBarMessage(ABM_SETPOS, &AppBarData);
   if(CurrentRect != AppBarData.rc)
   {
      MoveWindow(aHwnd,
                 AppBarData.rc.left,
                 AppBarData.rc.top,
                 AppBarData.rc.right - AppBarData.rc.left,
                 AppBarData.rc.bottom - AppBarData.rc.top,
                 TRUE);
      CurrentRect = AppBarData.rc;
   }
}

LRESULT CALLBACK DialogProc(HWND aHwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
   case WM_CREATE:
      CreateWindow("BUTTON",
                   "Exit",
                   WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                   5, 5, 60, 20,
                   aHwnd,
                   (HMENU)(ExitButtonId),
                   InstanceHandle,
                   0);

      CreateWindow("COMBOBOX",
                   0,
                   WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST|WS_GROUP,
                   70, 4, 300, 100,
                   aHwnd,
                   (HMENU)(LinkComboId),
                   InstanceHandle,
                   0);

      CreateWindow("BUTTON",
                   "Go",
                   WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                   375, 5, 60, 20,
                   aHwnd,
                   (HMENU)(GoButtonId),
                   InstanceHandle,
                   0);
      int i;
      for(i = 0; UrlList[i]; i++)
         SendDlgItemMessage(aHwnd, LinkComboId, CB_ADDSTRING, 0, (LPARAM )UrlList[i]);
      SendDlgItemMessage(aHwnd, LinkComboId, CB_SETCURSEL, 0, 0);
      EnumChildWindows(aHwnd, (WNDENUMPROC )SetFontFunc, (LPARAM )GetStockObject(DEFAULT_GUI_FONT));
      break;
   case AppMsg:
      RepositionBar(aHwnd);
      if(First)
      {
         ShowWindow(aHwnd, SW_SHOW);
         First = false;
      }
      break;
   case WM_PAINT:
      {
         PAINTSTRUCT PaintStruct;
         DrawApp(BeginPaint(aHwnd, &PaintStruct));
         EndPaint(aHwnd, &PaintStruct);
         return FALSE;
      }
   case WM_COMMAND:
      if(HIWORD(wParam) == BN_CLICKED)
      {
         if(LOWORD(wParam) == ExitButtonId)
         {
            RemoveApp(aHwnd);
            DestroyWindow(aHwnd);
         }
         else if(LOWORD(wParam) == GoButtonId)
         {
            int Index = SendDlgItemMessage(aHwnd, LinkComboId, CB_GETCURSEL, 0, 0);
            ShellExecute(aHwnd, "Open", UrlList[Index], 0, 0, SW_SHOW);
         }
      }
      break;
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   }
   return DefWindowProc(aHwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
{
   InstanceHandle = hInstance;
   WNDCLASS wc;
   memset(&wc, 0, sizeof(WNDCLASS));
   wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
   wc.lpfnWndProc = DialogProc;
   wc.hInstance = InstanceHandle;
   wc.hbrBackground = (HBRUSH )(COLOR_BTNFACE + 1);
   wc.lpszClassName = "WhateverClass";
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   if(!RegisterClass(&wc))
      return FALSE;


   HWND WindowHandle = CreateWindowEx(WS_EX_TOOLWINDOW, // Don't want our app to appear on the process bar
                                      "WhateverClass",
                                       "",
                                       WS_MINIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, // Create hidden, show when we know the position
                                       100, 100, 140, 160,
                                       NULL,
                                       NULL,
                                       InstanceHandle,
                                       0);

   SetWindowLong(WindowHandle, GWL_STYLE, GetWindowLong(WindowHandle, GWL_STYLE) & ~(WS_CAPTION | WS_SYSMENU | WS_BORDER));

   AddApp(WindowHandle);
   MSG Msg;
   while(GetMessage(&Msg, 0, 0, 0xFFFF) > 0)
   {
      if(!IsDialogMessage(WindowHandle, &Msg))
      {
         TranslateMessage(&Msg);
         DispatchMessage(&Msg);
      }
   }
   RemoveApp(WindowHandle);
   return 0;
}