Index: trunk/src/comctl32/animate.c
===================================================================
--- trunk/src/comctl32/animate.c	(revision 1098)
+++ trunk/src/comctl32/animate.c	(revision 1100)
@@ -1,3 +1,3 @@
-/* $Id: animate.c,v 1.4 1999-08-14 16:13:09 cbratschi Exp $ */
+/* $Id: animate.c,v 1.5 1999-10-01 15:53:31 cbratschi Exp $ */
 /*
  * Animation control
@@ -5,13 +5,8 @@
  * Copyright 1998, 1999 Eric Kohl
  * Copyright 1999 Achim Hasenmueller
+ * Copyright 1999 Christoph Bratschi
  *
- * NOTES
- *   This is just a dummy control. An author is needed! Any volunteers?
- *   I will only improve this control once in a while.
- *     Eric <ekohl@abo.rhein-zeitung.de>
- *
- * TODO:
- *   - All messages.
- *   - All notifications.
+ * Status: can't play videos through MCI -> WINMM stubs
+ * Version: 5.00
  */
 
@@ -23,242 +18,371 @@
 
 
-#define ANIMATE_GetInfoPtr(hwnd) ((ANIMATE_INFO *)GetWindowLongA (hwnd, 0))
-
+#define ANIMATE_GetInfoPtr(hwnd) ((ANIMATE_INFO*)GetWindowLongA(hwnd,0))
+#define TIMER_ID 1
 
 static BOOL
-ANIMATE_LoadResA (ANIMATE_INFO *infoPtr, HINSTANCE hInst, LPSTR lpName)
+ANIMATE_LoadRes(ANIMATE_INFO *infoPtr,HINSTANCE hInst,LPSTR lpName,BOOL unicode)
 {
     HRSRC hrsrc;
     HGLOBAL handle;
-
-    hrsrc = FindResourceA (hInst, lpName, "AVI");
-    if (!hrsrc)
-        return FALSE;
+    LPVOID lpAvi;
+
+    if (unicode)
+    {
+      WCHAR buf[4];
+
+      lstrcpyAtoW(buf,"AVI");
+      hrsrc = FindResourceW(hInst,(LPWSTR)lpName,buf);
+    } else hrsrc = FindResourceA(hInst,lpName,"AVI");
+    if (!hrsrc) return FALSE;
 
     handle = LoadResource (hInst, hrsrc);
+    if (!handle) return FALSE;
+
+    lpAvi = LockResource (handle);
+    if (!lpAvi) return FALSE;
+
+    infoPtr->lpAvi = lpAvi;
+    infoPtr->hRes = handle;
+    infoPtr->cSize = SizeofResource(hInst,hrsrc);
+
+    return TRUE;
+}
+
+static BOOL
+ANIMATE_LoadFile(ANIMATE_INFO *infoPtr,LPSTR lpName,BOOL unicode)
+{
+    HANDLE handle;
+    HFILE hFile;
+    LPVOID lpAvi;
+
+    if (unicode)
+    {
+      hFile = CreateFileW((LPWSTR)lpName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
+      if (!hFile) return FALSE;
+
+      handle = CreateFileMappingW(hFile,NULL,PAGE_READONLY | SEC_COMMIT,0,0,NULL);
+    } else
+    {
+      hFile = CreateFileA (lpName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
+      if (!hFile) return FALSE;
+
+      handle = CreateFileMappingA(hFile,NULL,PAGE_READONLY | SEC_COMMIT,0,0,NULL);
+    }
     if (!handle)
-        return FALSE;
-
-    infoPtr->lpAvi = LockResource (handle);
-    if (!infoPtr->lpAvi)
-        return FALSE;
+    {
+      CloseHandle (hFile);
+      return FALSE;
+    }
+
+    lpAvi = MapViewOfFile (handle, FILE_MAP_READ, 0, 0, 0);
+    if (!lpAvi)
+    {
+      CloseHandle (hFile);
+      return FALSE;
+    }
+
+    infoPtr->lpAvi = lpAvi;
+    infoPtr->hFile = hFile;
+    infoPtr->cSize = GetFileSize(hFile,NULL);
 
     return TRUE;
 }
 
+static VOID
+ANIMATE_GetAviInfo (ANIMATE_INFO *infoPtr)
+{
+
+
+}
+
+static VOID
+ANIMATE_FreeResource(ANIMATE_INFO *infoPtr)
+{
+  if (infoPtr->hFile)
+  {
+    UnmapViewOfFile (infoPtr->lpAvi);
+    CloseHandle (infoPtr->hFile);
+    infoPtr->lpAvi = NULL;
+    infoPtr->hFile = NULL;
+  } else if (infoPtr->hRes)
+  {
+    GlobalFree (infoPtr->hRes);
+    infoPtr->lpAvi = NULL;
+    infoPtr->hRes = NULL;
+  }
+  infoPtr->cSize = 0;
+}
 
 static BOOL
-ANIMATE_LoadFileA (ANIMATE_INFO *infoPtr, LPSTR lpName)
-{
-    HANDLE handle;
-
-    infoPtr->hFile =
-        CreateFileA (lpName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
-                       FILE_ATTRIBUTE_NORMAL, 0);
-    if (!infoPtr->hFile)
-        return FALSE;
-
-    handle =
-        CreateFileMappingA (infoPtr->hFile, NULL, PAGE_READONLY | SEC_COMMIT,
-                              0, 0, NULL);
-    if (!handle) {
-        CloseHandle (infoPtr->hFile);
-        infoPtr->hFile = 0;
-        return FALSE;
-    }
-
-    infoPtr->lpAvi = MapViewOfFile (handle, FILE_MAP_READ, 0, 0, 0);
-    if (!infoPtr->lpAvi) {
-        CloseHandle (infoPtr->hFile);
-        infoPtr->hFile = 0;
-        return FALSE;
-    }
+ANIMATE_IsLoaded(ANIMATE_INFO *infoPtr)
+{
+  return (infoPtr->lpAvi != NULL);
+}
+
+static BOOL
+ANIMATE_IsPlaying(ANIMATE_INFO *infoPtr)
+{
+  return infoPtr->bPlaying;
+}
+
+/* Message handlers */
+
+static LRESULT
+ANIMATE_Close(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+
+  ANIMATE_FreeResource(infoPtr);
+
+  return DefWindowProcA(hwnd,WM_CLOSE,wParam,lParam);
+}
+
+static LRESULT
+ANIMATE_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+
+    /* free avi data */
+    ANIMATE_FreeResource(infoPtr);
+
+    /* free animate info data */
+    COMCTL32_Free(infoPtr);
+
+    return DefWindowProcA(hwnd,WM_DESTROY,wParam,lParam);
+}
+
+static LRESULT
+ANIMATE_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO *infoPtr;
+
+    /* allocate memory for info structure */
+    infoPtr = (ANIMATE_INFO *)COMCTL32_Alloc (sizeof(ANIMATE_INFO));
+
+    /* store pointer to info structure */
+    SetWindowLongA (hwnd,0,(DWORD)infoPtr);
+
+    /* set default settings */
+    infoPtr->lpAvi    = NULL;
+    infoPtr->hFile    = 0;
+    infoPtr->hRes     = 0;
+    infoPtr->cSize    = 0;
+    infoPtr->cRepeat  = 0;
+    infoPtr->wFrom    = 0;
+    infoPtr->wTo      = 0;
+    infoPtr->wPos     = 0;
+    infoPtr->bPlaying = FALSE;
+    infoPtr->cFrames  = 0;
+    infoPtr->pos.x    = 0;
+    infoPtr->pos.y    = 0;
+    infoPtr->size.x   = 0;
+    infoPtr->size.y   = 0;
+    infoPtr->bThread  = 0;
+
+    return DefWindowProcA(hwnd,WM_NCCREATE,wParam,lParam);
+}
+
+static LRESULT
+ANIMATE_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    HBRUSH hBrush;
+    RECT rect;
+    HDC hdc = (HDC)wParam;
+
+    if (GetWindowLongA(hwnd,GWL_STYLE) & ACS_TRANSPARENT)
+    {
+      hBrush = SendMessageA(hwnd,WM_CTLCOLORSTATIC,hdc,hwnd);
+    } else hBrush = GetSysColorBrush(COLOR_WINDOW);
+
+    GetClientRect(hwnd,&rect);
+    FillRect((HDC)wParam,&rect,hBrush);
 
     return TRUE;
 }
 
+static LRESULT
+ANIMATE_NCHitTest(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  return HTTRANSPARENT;
+}
 
 static VOID
-ANIMATE_Free (ANIMATE_INFO *infoPtr)
-{
-    if (infoPtr->hFile) {
-        UnmapViewOfFile (infoPtr->lpAvi);
-        CloseHandle (infoPtr->hFile);
-        infoPtr->lpAvi = NULL;
-    }
-    else {
-        GlobalFree ((HGLOBAL)infoPtr->lpAvi);
-        infoPtr->lpAvi = NULL;
-    }
-}
-
-
-static VOID
-ANIMATE_GetAviInfo (infoPtr)
-{
-
-
-}
-
-
-static LRESULT
-ANIMATE_OpenA (HWND hwnd, WPARAM wParam, LPARAM lParam)
+ANIMATE_DrawFrame(ANIMATE_INFO *infoPtr)
+{
+  //CB: todo
+  //MCI_PUT
+}
+
+static LRESULT
+ANIMATE_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+
+  if (ANIMATE_IsLoaded(infoPtr)) ANIMATE_DrawFrame(infoPtr);
+
+  return 0;
+}
+
+static LRESULT
+ANIMATE_Size(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
+
+  if (ANIMATE_IsPlaying(infoPtr) && dwStyle & ACS_CENTER)
+  {
+    infoPtr->pos.x = (LOWORD(lParam)-infoPtr->size.x)/2;
+    infoPtr->pos.y = (HIWORD(lParam)-infoPtr->size.y)/2;
+  }
+
+  return DefWindowProcA(hwnd,WM_SIZE,wParam,lParam);
+}
+
+static LRESULT
+ANIMATE_StyleChanged(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  //CB: todo
+
+  return 0;
+}
+
+static LRESULT
+ANIMATE_Timer(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+  INT newPos = infoPtr->wPos+1;
+
+  if (wParam != TIMER_ID) return 0;
+
+  if (newPos == infoPtr->wTo || (infoPtr->wTo == -1 && newPos == infoPtr->cFrames-1))
+  {
+    if (infoPtr->cRepeat != -1)
+    {
+      infoPtr->cRepeat--;
+      if (infoPtr->cRepeat == 0) Animate_Stop(hwnd);
+    }
+  } else
+  {
+    infoPtr->wPos++;
+    ANIMATE_DrawFrame(infoPtr);
+  }
+
+  return 0;
+}
+
+/* Control messages */
+
+static LRESULT
+ANIMATE_Open(HWND hwnd,WPARAM wParam,LPARAM lParam,BOOL unicode)
 {
     ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
     HINSTANCE hInstance = (HINSTANCE)wParam;
 
-    ANIMATE_Free (infoPtr);
-
-    if (!lParam) {
-//      TRACE (animate, "closing avi!\n");
-        return TRUE;
-    }
-
-    if (HIWORD(lParam)) {
-//      FIXME (animate, "(\"%s\") empty stub!\n", (LPSTR)lParam);
-
-        if (ANIMATE_LoadResA (infoPtr, hInstance, (LPSTR)lParam)) {
-
-//          FIXME (animate, "AVI resource found!\n");
-
-        }
-        else {
-//          FIXME (animate, "No AVI resource found!\n");
-            if (ANIMATE_LoadFileA (infoPtr, (LPSTR)lParam)) {
-//              FIXME (animate, "AVI file found!\n");
-            }
-            else {
-//              FIXME (animate, "No AVI file found!\n");
-                return FALSE;
-            }
-        }
-    }
-    else {
-//      FIXME (animate, "(%u) empty stub!\n", (WORD)LOWORD(lParam));
-
-        if (ANIMATE_LoadResA (infoPtr, hInstance,
-                                MAKEINTRESOURCEA((INT)lParam))) {
-//          FIXME (animate, "AVI resource found!\n");
-        }
-        else {
-//          FIXME (animate, "No AVI resource found!\n");
-            return FALSE;
-        }
-    }
-
-    ANIMATE_GetAviInfo (infoPtr);
+    ANIMATE_FreeResource(infoPtr);
+
+MessageBoxA(hwnd,"open",NULL,MB_OK);
+    if (!lParam) return TRUE;
+
+    if (HIWORD(lParam))
+    {
+      if (ANIMATE_LoadRes(infoPtr,hInstance,(LPSTR)lParam,unicode));
+      else if (ANIMATE_LoadFile(infoPtr,(LPSTR)lParam,unicode));
+      else return FALSE;
+    } else
+    {
+      if (!ANIMATE_LoadRes(infoPtr,hInstance,unicode ? (LPTSTR)MAKEINTRESOURCEW((INT)lParam):MAKEINTRESOURCEA((INT)lParam),unicode)) return FALSE;
+    }
+
+    ANIMATE_GetAviInfo(infoPtr);
+
+    if (GetWindowLongA(hwnd,GWL_STYLE) & ACS_AUTOPLAY) Animate_Play(hwnd,0,-1,1);
 
     return TRUE;
 }
 
-
-/* << ANIMATE_Open32W >> */
-
-
 static LRESULT
 ANIMATE_Play (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    /* ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd); */
-    INT nFrom   = (INT)LOWORD(lParam);
-    INT nTo     = (INT)HIWORD(lParam);
-    INT nRepeat = (INT)wParam;
-
-#if 0
-    /* nothing opened */
-    if (...)
-        return FALSE;
-#endif
-
-    if (nRepeat == -1) {
-
-//      FIXME (animate, "(loop from=%d to=%d) empty stub!\n",
-//             nFrom, nTo);
-
-    }
-    else {
-
-//      FIXME (animate, "(repeat=%d from=%d to=%d) empty stub!\n",
-//             nRepeat, nFrom, nTo);
-
-    }
-
+    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+    INT wFrom   = (INT)LOWORD(lParam);
+    INT wTo     = (INT)HIWORD(lParam);
+    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
+
+    if (!ANIMATE_IsLoaded(infoPtr)) return FALSE;
+
+    Animate_Stop(hwnd);
+
+    if (wFrom < 0) wFrom = 0;
+    if (wFrom > wTo && wTo != -1) return FALSE;
+    if (wFrom >= infoPtr->cFrames) wFrom = infoPtr->cFrames-1;
+    if (wTo >= infoPtr->cFrames) wTo = infoPtr->cFrames-1;
+
+    infoPtr->cRepeat = (INT)wParam;
+    infoPtr->wFrom   = wFrom;
+    infoPtr->wTo     = wTo;
+    infoPtr->wPos    = infoPtr->wFrom;
+
+    if (dwStyle & ACS_CENTER)
+    {
+      RECT rect;
+
+      GetClientRect(hwnd,&rect);
+      infoPtr->pos.x = (rect.right-infoPtr->size.x)/2;
+      infoPtr->pos.y = (rect.bottom-infoPtr->size.y)/2;
+    } else
+    {
+      infoPtr->pos.x = 0;
+      infoPtr->pos.y = 0;
+    }
+
+    InvalidateRect(hwnd,NULL,FALSE);
+
+    if (wFrom == wTo)
+    {
+      SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),ACN_START),hwnd);
+      SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),ACN_STOP),hwnd);
+
+      return TRUE;
+    }
+
+    infoPtr->bPlaying = TRUE;
+
+    if (dwStyle & ACS_TIMER)
+    {
+      infoPtr->bThread = FALSE;
+      SetTimer(hwnd,TIMER_ID,infoPtr->msFrame,NULL);
+    } else
+    {
+      infoPtr->bThread = TRUE;
+      //CB:todo
+    }
+
+    SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),ACN_START),hwnd);
 
     return TRUE;
 }
 
-
 static LRESULT
 ANIMATE_Stop (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    /* ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd); */
-
-#if 0
-    /* nothing opened */
-    if (...)
-        return FALSE;
-#endif
-
-    return TRUE;
-}
-
-
-
-static LRESULT
-ANIMATE_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    ANIMATE_INFO *infoPtr;
-
-    /* allocate memory for info structure */
-    infoPtr = (ANIMATE_INFO *)COMCTL32_Alloc (sizeof(ANIMATE_INFO));
-    if (!infoPtr) {
-//      ERR (animate, "could not allocate info memory!\n");
-        return 0;
-    }
-
-    /* store pointer to info structure */
-    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
-
-
-    /* set default settings */
-
-
-    return 0;
-}
-
-
-static LRESULT
-ANIMATE_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
-
-
-    /* free avi data */
-    ANIMATE_Free (infoPtr);
-
-    /* free animate info data */
-    COMCTL32_Free (infoPtr);
-
-    return 0;
-}
-
-
-#if 0
-static LRESULT
-ANIMATE_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
-/*
-    HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
-    RECT32 rect;
-
-    GetClientRect32 (wndPtr->hwndSelf, &rect);
-    FillRect32 ((HDC32)wParam, &rect, hBrush);
-    DeleteObject32 (hBrush);
-*/
-    return TRUE;
-}
-#endif
-
-
+  ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
+
+  if (!ANIMATE_IsLoaded(infoPtr)) return FALSE;
+  if (!ANIMATE_IsPlaying(infoPtr)) return TRUE;
+
+  if (infoPtr->bThread)
+  {
+    //CB:todo
+  } else
+  {
+    KillTimer(hwnd,TIMER_ID);
+  }
+
+  infoPtr->bPlaying = FALSE;
+  SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),ACN_STOP),hwnd);
+
+  return TRUE;
+}
 
 static LRESULT WINAPI
@@ -268,31 +392,41 @@
     {
         case ACM_OPENA:
-            return ANIMATE_OpenA (hwnd, wParam, lParam);
-
-/*      case ACM_OPEN32W: */
-/*          return ANIMATE_Open32W (hwnd, wParam, lParam); */
+          return ANIMATE_Open(hwnd,wParam,lParam,FALSE);
+
+        case ACM_OPENW:
+          return ANIMATE_Open(hwnd,wParam,lParam,TRUE);
 
         case ACM_PLAY:
-            return ANIMATE_Play (hwnd, wParam, lParam);
+          return ANIMATE_Play (hwnd, wParam, lParam);
 
         case ACM_STOP:
-            return ANIMATE_Stop (hwnd, wParam, lParam);
-
-
-        case WM_CREATE:
-            return ANIMATE_Create (hwnd, wParam, lParam);
+          return ANIMATE_Stop (hwnd, wParam, lParam);
+
+        case WM_CLOSE:
+          return ANIMATE_Close(hwnd,wParam,lParam);
+
+        case WM_NCCREATE:
+          return ANIMATE_NCCreate(hwnd,wParam,lParam);
 
         case WM_DESTROY:
-            return ANIMATE_Destroy (hwnd, wParam, lParam);
-
-/*      case WM_ERASEBKGND: */
-/*          return ANIMATE_EraseBackground (hwnd, wParam, lParam); */
-
-/*      case WM_NCCREATE: */
-/*      case WM_NCHITTEST: */
-/*      case WM_PAINT: */
-/*      case WM_SIZE: */
-/*      case WM_STYLECHANGED: */
-/*      case WM_TIMER: */
+          return ANIMATE_Destroy (hwnd, wParam, lParam);
+
+        case WM_ERASEBKGND:
+          return ANIMATE_EraseBackground (hwnd, wParam, lParam);
+
+        case WM_NCHITTEST:
+          return ANIMATE_NCHitTest(hwnd,wParam,lParam);
+
+        case WM_PAINT:
+          return ANIMATE_Paint(hwnd,wParam,lParam);
+
+        case WM_SIZE:
+          return ANIMATE_Size(hwnd,wParam,lParam);
+
+      case WM_STYLECHANGED:
+          return ANIMATE_StyleChanged(hwnd,wParam,lParam);
+
+      case WM_TIMER:
+          return ANIMATE_Timer(hwnd,wParam,lParam);
 
         default:
@@ -302,4 +436,5 @@
             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
     }
+
     return 0;
 }
Index: trunk/src/comctl32/hotkey.c
===================================================================
--- trunk/src/comctl32/hotkey.c	(revision 1098)
+++ trunk/src/comctl32/hotkey.c	(revision 1100)
@@ -1,3 +1,3 @@
-/* $Id: hotkey.c,v 1.11 1999-09-25 15:24:12 cbratschi Exp $ */
+/* $Id: hotkey.c,v 1.12 1999-10-01 15:53:32 cbratschi Exp $ */
 /*
  * Hotkey control
@@ -7,5 +7,5 @@
  * Copyright 1999 Christoph Bratschi
  *
- * Status: Development in progress
+ * Status: Complete (perhaps some bugs)
  * Version: 5.00
  */
@@ -19,22 +19,293 @@
 
 static VOID
-HOTKEY_Refresh(HWND hwnd)
+HOTKEY_Refresh(HWND hwnd,BOOL notify)
 {
   InvalidateRect(hwnd,NULL,FALSE);
-}
-
+
+  if (notify) SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),EN_CHANGE),hwnd);
+}
+
+static char*
+HOTKEY_ExtKey2Name(BYTE bVKHotKey)
+{
+  switch(bVKHotKey)
+  {
+    case VK_RETURN:
+      return "RETURN";
+
+    case VK_PRIOR:
+      return "PRIOR";
+
+    case VK_NEXT:
+      return "NEXT";
+
+    case VK_END:
+      return "END";
+
+    case VK_HOME:
+      return "HOME";
+
+    case VK_LEFT:
+      return "LEFT";
+
+    case VK_UP:
+      return "UP";
+
+    case VK_RIGHT:
+      return "RIGHT";
+
+    case VK_DOWN:
+      return "DOWN";
+
+    case VK_HELP:
+      return "HELP";
+
+    case VK_0:
+      return "0";
+
+    case VK_1:
+      return "1";
+
+    case VK_2:
+      return "2";
+
+    case VK_3:
+      return "3";
+
+    case VK_4:
+      return "4";
+
+    case VK_5:
+      return "5";
+
+    case VK_6:
+      return "6";
+
+    case VK_7:
+      return "7";
+
+    case VK_8:
+      return "8";
+
+    case VK_9:
+      return "9";
+
+    case VK_A:
+      return "A";
+
+    case VK_B:
+      return "B";
+
+    case VK_C:
+      return "C";
+
+    case VK_D:
+      return "D";
+
+    case VK_E:
+      return "E";
+
+    case VK_F:
+      return "F";
+
+    case VK_G:
+      return "G";
+
+    case VK_H:
+      return "H";
+
+    case VK_I:
+      return "I";
+
+    case VK_J:
+      return "J";
+
+    case VK_K:
+      return "K";
+
+    case VK_L:
+      return "L";
+
+    case VK_M:
+      return "M";
+
+    case VK_N:
+      return "N";
+
+    case VK_O:
+      return "O";
+
+    case VK_P:
+      return "P";
+
+    case VK_Q:
+      return "Q";
+
+    case VK_R:
+      return "R";
+
+    case VK_S:
+      return "S";
+
+    case VK_T:
+      return "T";
+
+    case VK_U:
+      return "U";
+
+    case VK_V:
+      return "V";
+
+    case VK_W:
+      return "W";
+
+    case VK_X:
+      return "Y";
+
+    case VK_Y:
+      return "X";
+
+    case VK_Z:
+      return "Z";
+
+    case VK_NUMPAD0:
+      return "NUMPAD0";
+
+    case VK_NUMPAD1:
+      return "NUMPAD1";
+
+    case VK_NUMPAD2:
+      return "NUMPAD2";
+
+    case VK_NUMPAD3:
+      return "NUMPAD3";
+
+    case VK_NUMPAD4:
+      return "NUMPAD4";
+
+    case VK_NUMPAD5:
+      return "NUMPAD5";
+
+    case VK_NUMPAD6:
+      return "NUMPAD6";
+
+    case VK_NUMPAD7:
+      return "NUMPAD7";
+
+    case VK_NUMPAD8:
+      return "NUMPAD8";
+
+    case VK_NUMPAD9:
+      return "NUMPAD9";
+
+    case VK_MULTIPLY:
+      return "MULTIPLY";
+
+    case VK_ADD:
+      return "ADD";
+
+    case VK_SEPARATOR:
+      return "SEPARATOR";
+
+    case VK_SUBTRACT:
+      return "SUBTRACT";
+
+    case VK_DECIMAL:
+      return "DECIMAL";
+
+    case VK_DIVIDE:
+      return "DIVIDE";
+
+    case VK_F1:
+      return "F1";
+
+    case VK_F2:
+      return "F2";
+
+    case VK_F3:
+      return "F3";
+
+    case VK_F4:
+      return "F4";
+
+    case VK_F5:
+      return "F5";
+
+    case VK_F6:
+      return "F6";
+
+    case VK_F7:
+      return "F7";
+
+    case VK_F8:
+      return "F8";
+
+    case VK_F9:
+      return "F9";
+
+    case VK_F10:
+      return "F10";
+
+    case VK_F11:
+      return "F11";
+
+    case VK_F12:
+      return "F12";
+
+    case VK_F13:
+      return "F13";
+
+    case VK_F14:
+      return "F14";
+
+    case VK_F15:
+      return "F15";
+
+    case VK_F16:
+      return "F16";
+
+    case VK_F17:
+      return "F17";
+
+    case VK_F18:
+      return "F18";
+
+    case VK_F19:
+      return "F19";
+
+    case VK_F20:
+      return "F20";
+
+    case VK_F21:
+      return "F21";
+
+    case VK_F22:
+      return "F22";
+
+    case VK_F23:
+      return "F23";
+
+    case VK_F24:
+      return "F24";
+
+    default:
+      return NULL;
+  }
+}
 
 static BYTE
 HOTKEY_Check(HOTKEY_INFO *infoPtr,BYTE bfMods)
 {
-  if ((infoPtr->fwCombInv & HKCOMB_A && bfMods == HOTKEYF_ALT) ||
-      (infoPtr->fwCombInv & HKCOMB_C && bfMods == HOTKEYF_CONTROL) ||
-      (infoPtr->fwCombInv & HKCOMB_CA && bfMods == HOTKEYF_CONTROL | HOTKEYF_ALT) ||
-      (infoPtr->fwCombInv & HKCOMB_NONE && bfMods == 0) ||
-      (infoPtr->fwCombInv & HKCOMB_S && bfMods == HOTKEYF_SHIFT) ||
-      (infoPtr->fwCombInv & HKCOMB_SA && bfMods == HOTKEYF_SHIFT | HOTKEYF_ALT) ||
-      (infoPtr->fwCombInv & HKCOMB_SC && bfMods == HOTKEYF_SHIFT | HOTKEYF_CONTROL) ||
-      (infoPtr->fwCombInv & HKCOMB_SCA && bfMods == HOTKEYF_SHIFT | HOTKEYF_CONTROL | HOTKEYF_ALT))
-    return infoPtr->fwModInv;
+  BYTE mods = bfMods & ~HOTKEYF_EXT;
+
+  if ((infoPtr->fwCombInv & HKCOMB_A && mods == HOTKEYF_ALT) ||
+      (infoPtr->fwCombInv & HKCOMB_C && mods == HOTKEYF_CONTROL) ||
+      (infoPtr->fwCombInv & HKCOMB_CA && mods == HOTKEYF_CONTROL | HOTKEYF_ALT) ||
+      (infoPtr->fwCombInv & HKCOMB_NONE && mods == 0) ||
+      (infoPtr->fwCombInv & HKCOMB_S && mods == HOTKEYF_SHIFT) ||
+      (infoPtr->fwCombInv & HKCOMB_SA && mods == HOTKEYF_SHIFT | HOTKEYF_ALT) ||
+      (infoPtr->fwCombInv & HKCOMB_SC && mods == HOTKEYF_SHIFT | HOTKEYF_CONTROL) ||
+      (infoPtr->fwCombInv & HKCOMB_SCA && mods == HOTKEYF_SHIFT | HOTKEYF_CONTROL | HOTKEYF_ALT))
+    return infoPtr->fwModInv | bfMods;
   else
     return bfMods;
@@ -50,5 +321,5 @@
   infoPtr->bfMods = HOTKEY_Check(infoPtr,(wParam & 0xFF00)>>8);
 
-  HOTKEY_Refresh(hwnd);
+  HOTKEY_Refresh(hwnd,TRUE);
 
   return 0;
@@ -75,5 +346,5 @@
 
   infoPtr->bfMods = HOTKEY_Check(infoPtr,infoPtr->bfMods);
-  if (infoPtr->bfMods != oldMods) HOTKEY_Refresh(hwnd);
+  if (infoPtr->bfMods != oldMods) HOTKEY_Refresh(hwnd,TRUE);
 
   return 0;
@@ -89,7 +360,9 @@
   {
     infoPtr->bVKHotKey = wParam & 0xFF;
+    infoPtr->bfMods &= ~HOTKEYF_EXT;
     infoPtr->bfMods = HOTKEY_Check(infoPtr,infoPtr->bfMods);
-    HOTKEY_Refresh(hwnd);
+    HOTKEY_Refresh(hwnd,TRUE);
   }
+  infoPtr->bfModsDown = 0;
 
   return 0;
@@ -199,5 +472,15 @@
 
     default:
-         //CB:
+         if (newKey != wParam && HOTKEY_ExtKey2Name(wParam))
+         {
+           infoPtr ->bVKHotKey = wParam & 0xFF;
+           newMods |= HOTKEYF_EXT;
+
+           infoPtr->bfMods = HOTKEY_Check(infoPtr,newMods);
+           HOTKEY_Refresh(hwnd,TRUE);
+           infoPtr->bfModsDown = 0;
+
+           return 0;
+         }
          break;
     }
@@ -208,5 +491,5 @@
       infoPtr->bVKHotKey = newKey;
       infoPtr->bfMods = newMods;
-      HOTKEY_Refresh(hwnd);
+      HOTKEY_Refresh(hwnd,TRUE);
     }
 
@@ -218,6 +501,8 @@
 HOTKEY_KeyUp (HWND hwnd, WPARAM wParam, LPARAM lParam,BOOL sysKey)
 {
-  HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
+  HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(hwnd);
   INT newMods = infoPtr->bfModsDown;
+
+  if (!infoPtr->bfModsDown) return 0;
 
   if (sysKey)
@@ -254,5 +539,5 @@
     {
       infoPtr->bfMods = newMods;
-      HOTKEY_Refresh(hwnd);
+      HOTKEY_Refresh(hwnd,TRUE);
     }
 
@@ -319,10 +604,22 @@
   if (infoPtr->bVKHotKey)
   {
-    char char2[2];
-
-    if (text[0]) strcat(text,"+");
-    char2[0] = (char)infoPtr->bVKHotKey;
-    char2[1] = 0;
-    strcat(text,char2);
+    if (infoPtr->bfMods & HOTKEYF_EXT)
+    {
+      char* name = HOTKEY_ExtKey2Name(infoPtr->bVKHotKey);
+
+      if (name)
+      {
+        if (text[0]) strcat(text,"+");
+        strcat(text,name);
+      }
+    } else
+    {
+      char char2[2];
+
+      if (text[0]) strcat(text,"+");
+      char2[0] = (char)infoPtr->bVKHotKey;
+      char2[1] = 0;
+      strcat(text,char2);
+    }
   } else if (infoPtr->bfModsDown) strcat(text,"+");
   if(infoPtr->hFont) oldFont = SelectObject(hdc,infoPtr->hFont);
@@ -391,5 +688,5 @@
     ReleaseDC (hwnd, hdc);
 
-    if (LOWORD(lParam)) HOTKEY_Refresh(hwnd);
+    if (LOWORD(lParam)) HOTKEY_Refresh(hwnd,FALSE);
 
     return 0;
Index: trunk/src/comctl32/trackbar.c
===================================================================
--- trunk/src/comctl32/trackbar.c	(revision 1098)
+++ trunk/src/comctl32/trackbar.c	(revision 1100)
@@ -1,3 +1,3 @@
-/* $Id: trackbar.c,v 1.18 1999-09-15 16:31:48 cbratschi Exp $ */
+/* $Id: trackbar.c,v 1.19 1999-10-01 15:53:32 cbratschi Exp $ */
 /*
  * Trackbar control
@@ -13,4 +13,5 @@
  *
  * Note: TBM_SETTHUMBLENGTH implemented, COMCTL32 5.00 ignores it
+ *       Microsoft(TM) should fix this bug :)
  */
 
@@ -2217,9 +2218,11 @@
 {
   TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
+  BOOL oldFocus = infoPtr->bFocus;
 
   if (wParam) infoPtr->bFocus = (GetFocus() == hwnd);
   else infoPtr->bFocus = FALSE;
 
-  TRACKBAR_Refresh(hwnd);
+  if (oldFocus != infoPtr->bFocus) TRACKBAR_Refresh(hwnd);
+  else TRACKBAR_UpdateThumbPosition(hwnd,infoPtr->nPos,TRUE);
 
   return 0;
