wip II
[sdk] / ecere / src / gui / drivers / Win32Interface.ec
index 517a2ee..b12fb8e 100644 (file)
@@ -6,8 +6,10 @@ import "instance"
 
 #if defined(__WIN32__)
 
+#undef WINVER
 #define WINVER 0x0500
-#define _WIN32_WINNT 0x0500
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
 
 #undef JOY_BUTTON1
 #undef JOY_BUTTON2
@@ -18,7 +20,11 @@ import "instance"
 #define Method _Method
 #define byte _byte
 #define int64 _int64
+#define String _String
+#define Mutex _Mutex
+#define Platform _Platform
 #include <windows.h>
+#include <wincon.h>
 #include <shellapi.h>
 
 
@@ -81,6 +87,9 @@ SetLayeredWindowAttributes(
 #undef Method
 #undef byte
 #undef int64
+#undef String
+#undef Mutex
+#undef Platform
 
 import "Window"
 
@@ -97,7 +106,7 @@ static byte key2VK[256] =
    'D','F','G','H','J','K','L',VK_SEMI,VK_QUOTE,VK_TILDE,VK_SHIFT,VK_BACK_SLASH,'Z','X','C','V',
    'B','N','M',VK_COMMA,VK_PERIOD,VK_DIVIDE,VK_SHIFT,VK_MULTIPLY,VK_LMENU,VK_SPACE,VK_CAPITAL,VK_F1,VK_F2,VK_F3,VK_F4,VK_F5,
    VK_F6,VK_F7,VK_F8,VK_F9,VK_F10,VK_NUMLOCK,VK_SCROLL,VK_NUMPAD7,VK_NUMPAD8,VK_NUMPAD9,VK_SUBTRACT,VK_NUMPAD4,VK_NUMPAD5,VK_NUMPAD6,VK_ADD,VK_NUMPAD1,
-   VK_NUMPAD2,VK_NUMPAD3,VK_NUMPAD0,VK_DELETE,0,0,0,0,0,0,0,0,0,0,0,0,
+   VK_NUMPAD2,VK_NUMPAD3,VK_NUMPAD0,VK_DELETE,0,0,0,VK_F11,VK_F12,0,0,0,0,0,0,0,
    0,0,0,0,0,0,VK_HOME,VK_UP,VK_PRIOR,VK_LEFT,VK_RIGHT,VK_END,VK_DOWN,VK_NEXT,VK_INSERT,VK_DELETE,
    0,0,0,VK_SHIFT,VK_MENU,VK_CONTROL
 };
@@ -243,7 +252,7 @@ class Win32Interface : Interface
       if(time - lastAutoHideCheck > 1)
       {
          APPBARDATA appBarData = { 0 };
-         newTaskBarState = SHAppBarMessage(ABM_GETSTATE, &appBarData);
+         newTaskBarState = (int)SHAppBarMessage(ABM_GETSTATE, &appBarData);
          lastAutoHideCheck = time;
       }
 
@@ -380,19 +389,25 @@ class Win32Interface : Interface
          code = key;
       }
 
-      if(key != leftShift && key != rightShift && ::GetKeyState(VK_SHIFT) & 0x80000)
-         code.shift = true;
-      if(key != leftControl && key != rightControl && ::GetKeyState(VK_CONTROL) & 0x80000 && !frenchShift)
-         code.ctrl = true;
-      if(key != leftAlt && key != rightAlt && ::GetKeyState(VK_MENU) & 0x80000 && !frenchShift)
-         code.alt = true;
-      
       if(msg == WM_MOUSEWHEEL)
       {
+         if(::GetAsyncKeyState(VK_SHIFT) & 0x80000)
+            code.ctrl = true;
+         if(::GetAsyncKeyState(VK_CONTROL) & 0x80000)
+            code.ctrl = true;
+         if(::GetAsyncKeyState(VK_MENU) & 0x80000)
+            code.alt = true;
+
          result = window.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit, code, 0);
       }
       else
       {
+         if(key != leftShift && key != rightShift && ::GetKeyState(VK_SHIFT) & 0x80000)
+            code.shift = true;
+         if(key != leftControl && key != rightControl && ::GetKeyState(VK_CONTROL) & 0x80000 && !frenchShift)
+            code.ctrl = true;
+         if(key != leftAlt && key != rightAlt && ::GetKeyState(VK_MENU) & 0x80000 && !frenchShift)
+            code.alt = true;
          /*
          byte ch = Interface::TranslateKeykey, code.shift);
          if(::GetKeyState(VK_CAPITAL))
@@ -429,7 +444,11 @@ class Win32Interface : Interface
    // --- Window procedure ---
    DWORD CALLBACK ::ApplicationWindow(HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam)
    {
+#ifdef _WIN64
+      Window window = (Window)GetWindowLongPtr(windowHandle, GWLP_USERDATA);
+#else
       Window window = (Window)GetWindowLong(windowHandle, GWL_USERDATA);
+#endif
       static Point lastPos;
       if(window)
       {
@@ -469,21 +488,25 @@ class Win32Interface : Interface
                   {
                      HWND foreground;
                      DWORD id;
-                     uint windowLong;
+                     void * windowLong;
                      foreground = GetForegroundWindow();
                      if(foreground == windowHandle && lParam)
                         foreground = (HWND)lParam;
 
                      GetWindowThreadProcessId(foreground, &id);
 
-                     windowLong = GetWindowLong(foreground, GWL_WNDPROC);
+#ifdef _WIN64
+                     windowLong = (void*)GetWindowLongPtr(foreground, GWLP_WNDPROC);
+#else
+                     windowLong = (void*)GetWindowLong(foreground, GWL_WNDPROC);
+#endif
 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
                      // The != ApplicationWindow check is for not recognizing the Console window as an Ecere Window
                      // That check causes a problem with the OpenGL driver which seems to popup a window of a different class
                      if(window.displaySystem && window.displaySystem.driver == class(OpenGLDisplayDriver))
-                        windowLong = (uint)ApplicationWindow;
+                        windowLong = (void *)ApplicationWindow;
 #endif
-                     if(id != GetCurrentProcessId() || windowLong != (LPARAM)ApplicationWindow)
+                     if(id != GetCurrentProcessId() || windowLong != (void *)ApplicationWindow)
                         window.ExternalActivate(false, true, window, null);
                      // DefWindowProc for WM_NCACTIVATE draws the decorations, make sure it's drawn in the right state
                      return (uint)DefWindowProc(windowHandle, msg, window.active, lParam);
@@ -539,11 +562,11 @@ class Win32Interface : Interface
                               SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOSIZE); //|SWP_NOREDRAW); 
                         */ 
                      }
-                     guiApp.SetAppFocus(wParam);
+                     guiApp.SetAppFocus((bool)wParam);
                   }
                }
                else 
-                  guiApp.SetAppFocus(wParam);
+                  guiApp.SetAppFocus((bool)wParam);
                break;
             case WM_PAINT:
             {
@@ -593,8 +616,8 @@ class Win32Interface : Interface
                static int lastRes = 0;
                if(lastBits != wParam || lastRes != lParam)
                {
-                  lastBits = wParam;
-                  lastRes = lParam;
+                  lastBits = (int)wParam;
+                  lastRes = (int)lParam;
                
                   externalDisplayChange = true;
                   if(guiApp.desktop.DisplayModeChanged())
@@ -637,12 +660,20 @@ class Win32Interface : Interface
                incref window;
                if(msg == WM_CHAR || msg == WM_DEADCHAR || PeekMessage(&charMsg, windowHandle, min, max, PM_REMOVE))
                {
-                  ch = (msg == WM_CHAR || msg == WM_DEADCHAR) ? wParam : (unichar)charMsg.wParam;
+                  ch = (msg == WM_CHAR || msg == WM_DEADCHAR) ? (unichar)wParam : (unichar)charMsg.wParam;
+                  // TOCHECK: What is this for again? Fixing some obscure activation status?
+                  // -- I believe this was somehow allowing 'unmaximizing', but was causing problems
+                  // as there was no way to prevent AltEnter from doing so (e.g. when it is used for a node property)
+                  // Worked around by fixing ProcessHotKeys to properly check for sysButtons in parent.parent when sys buttons
+                  // are placed inside a menu bar for a document
+                  /*
                   if(msg == WM_SYSKEYDOWN && ch == 13)
                   {
-                     ShowWindow(window.windowHandle, SW_SHOWNORMAL);
+                     ShowWindow(window.windowHandle, window.state == maximized ? SW_MAXIMIZE : SW_SHOWNORMAL);
+                     // This last line been commented out for a long time:
                      // window.ExternalActivate(true, true, window, null);
                   }
+                  */
                   if(msg == WM_SYSKEYUP || msg == WM_KEYUP)
                   {
                      if(!ProcessKeyMessage(window, WM_KEYDOWN, 0x40000000, 0, ch))
@@ -705,7 +736,7 @@ class Win32Interface : Interface
                      font.lfOutPrecision = OUT_DEFAULT_PRECIS;
                      font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
                      font.lfQuality = DEFAULT_QUALITY;
-                     font.lfPitchAndFamily = (byte)DEFAULT_PITCH|FF_DONTCARE; // TODO: Fix compiler 0 | 0 to produce byte, not int
+                     font.lfPitchAndFamily = (byte)(DEFAULT_PITCH|FF_DONTCARE); // TODO: Fix compiler 0 | 0 to produce byte, not int
                      UTF8toUTF16Buffer(res.faceName, font.lfFaceName, LF_FACESIZE);
 
                      ImmSetCompositionFont(ctx, &font);
@@ -741,16 +772,7 @@ class Win32Interface : Interface
             */
             case WM_NCHITTEST:
                if(window.nativeDecorations)
-               {
-                  uint result = (uint)DefWindowProc(windowHandle, msg, wParam, lParam);
-                  // Reset the cursor on native decorations
-                  if(result != HTCLIENT && lastCursor != arrow)
-                  {
-                     SetCursor(systemCursors[arrow]);
-                     lastCursor = arrow;
-                  }
-                  return result;
-               }
+                  return (uint)DefWindowProc(windowHandle, msg, wParam, lParam);
                else
                // return HTCAPTION;
                   return HTCLIENT;
@@ -776,8 +798,8 @@ class Win32Interface : Interface
             case WM_NCRBUTTONDOWN:
             case WM_NCRBUTTONDBLCLK:
             case WM_NCMBUTTONDOWN:
-            case WM_NCMBUTTONDBLCLK:
-            case WM_NCMOUSEMOVE:*/
+            case WM_NCMBUTTONDBLCLK:*/
+            case WM_NCMOUSEMOVE:
             {
                Modifiers code = 0;
                bool consequential = false;
@@ -785,7 +807,7 @@ class Win32Interface : Interface
                x += (short)LOWORD(lParam);
                y += (short)HIWORD(lParam);
 
-               if(window.nativeDecorations)
+               if(window.nativeDecorations && msg != WM_NCMOUSEMOVE)
                {
                   x += window.clientStart.x;
                   y += window.clientStart.y - (window.hasMenuBar ? skinMenuHeight : 0);
@@ -809,7 +831,7 @@ class Win32Interface : Interface
                incref window;
                switch(msg)
                {
-                  //case WM_NCMOUSEMOVE:
+                  case WM_NCMOUSEMOVE:
                   case WM_MOUSEMOVE:
                      window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x,y,&code, consequential, false);
                      break;
@@ -820,7 +842,7 @@ class Win32Interface : Interface
                   //case WM_NCLBUTTONDOWN:
                   case WM_LBUTTONDOWN:
                      window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown,x,y,&code, false, 
-                                             (msg == WM_LBUTTONDBLCLK) ? false: true);
+                                             /*(msg == WM_LBUTTONDBLCLK) ? false: */true);
                      break;
                   //case WM_NCLBUTTONUP:
                   case WM_LBUTTONUP:      window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp, x,y,&code, false, false);break;
@@ -852,6 +874,8 @@ class Win32Interface : Interface
                      break;
                }
                delete window;
+               if(msg == WM_NCMOUSEMOVE)
+                  return (uint)DefWindowProc(windowHandle, msg, wParam, lParam);
                break;
             }
             case WM_SETCURSOR:
@@ -1131,7 +1155,11 @@ class Win32Interface : Interface
       /// DRIVER IMPLEMENTATION /////////////
    ****************************************************************************/
 
+#ifdef _WIN64
+   void CALLBACK ::TimerProc(UINT uTimerID, UINT uMsg, uint64 dwUser, uint64 dw1, uint64 dw2)
+#else
    void CALLBACK ::TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+#endif
    {
       guiApp.SignalEvent();
    }
@@ -1148,6 +1176,7 @@ class Win32Interface : Interface
          null,
          className
       };
+      AttachConsole(-1);
       wcl.hInstance = hInstance = GetModuleHandle(null);
       RegisterClass(&wcl);
 
@@ -1335,46 +1364,26 @@ class Win32Interface : Interface
          DWORD style = 0;
          DWORD exStyle = 0;
          HWND parentWindow = null; //HWND_DESKTOP; // we get different behaviors with desktop...
+         Window master = window.master, rootWindow = (master && master != guiApp.desktop) ? master.rootWindow : null;
          if(window.style.stayOnTop)
             exStyle |= WS_EX_TOPMOST;
 
-         // exStyle |= WS_EX_TOOLWINDOW;
-
-         if(window.master.rootWindow && window.master.rootWindow != guiApp.desktop && (window.style.modal || window.style.interim))
-         {
-            Window master = window.master;
-            Window rootWindow = window.master.rootWindow;
-
+         if(rootWindow && (window._isModal || window.style.interim))
             parentWindow = rootWindow.is3D ? rootWindow.parent.windowHandle : rootWindow.windowHandle;
-
-            // parentWindow = window.master.rootWindow.is3D ? window.master.rootWindow.parent.windowHandle : window.master.rootWindow.windowHandle;
-         }
             
          if(window.alphaBlend)
          // if(window.background.a < 255) //&& window.style & ES_REDRAW) Not needed anymore?
             exStyle |= WS_EX_LAYERED; // | WS_EX_TRANSPARENT;
 
-         if(window.style.showInTaskBar)
+         // Toolwindow will disappear if they don't have AppWindow set
+         if(window.style.showInTaskBar || (!parentWindow && window.style.thin))
          {
             exStyle |= WS_EX_APPWINDOW;
             parentWindow = null;
-            //style |= WS_SYSMENU;
          }
-         else if(window.master.rootWindow && window.master.rootWindow != guiApp.desktop)
-         {
+
+         if(window.style.thin)
             exStyle |= WS_EX_TOOLWINDOW;
-            //exStyle |=  WS_EX_APPWINDOW;
-            //style |= WS_SYSMENU;
-         }
-         else
-         {
-            // exStyle |= WS_EX_APPWINDOW;
-            //style |= WS_SYSMENU;
-         }
-         /*else if(parentWindow)
-            exStyle |= WS_EX_TOOLWINDOW;*/
-         /*if(window.interim)
-            parentWindow = window.master.rootWindow.windowHandle;*/
 
          if(window.windowHandle)
             windowHandle = window.windowHandle;
@@ -1401,7 +1410,6 @@ class Win32Interface : Interface
                style | (window.systemParent ? WS_CHILD : 
                (WS_POPUP | (window.style.hasMinimize ? WS_MINIMIZEBOX : 0))),
                   0,0,1,1, parentWindow, null, hInstance, null);
-               
    #if 0
             if(exStyle & WS_EX_LAYERED)
                SetLayeredWindowAttributes(windowHandle, 0, 255 /*A(window.background)*/, LWA_ALPHA);
@@ -1409,25 +1417,42 @@ class Win32Interface : Interface
          }
       }
       delete text;
+#ifdef _WIN64
+      SetWindowLongPtr(windowHandle, GWLP_USERDATA, (int64)window);
+#else
       SetWindowLong(windowHandle, GWL_USERDATA, (DWORD)window);
+#endif
 
       return windowHandle;
    }
 
    void DestroyRootWindow(Window window)
    {
-      HICON oldIcon = (HICON)SendMessage(window.windowHandle, WM_GETICON, ICON_BIG, 0);
+      HICON oldIcon;
+      int c, lockCount = guiApp.lockMutex.lockCount;
+      for(c = 0; c < lockCount; c++)
+         guiApp.lockMutex.Release();
+
+      oldIcon = (HICON)SendMessage(window.windowHandle, WM_GETICON, ICON_BIG, 0);
+#ifdef _WIN64
+      if(oldIcon && oldIcon != (HICON)GetClassLongPtr(window.windowHandle, GCLP_HICON))
+#else
       if(oldIcon && oldIcon != (HICON)GetClassLong(window.windowHandle, GCL_HICON))
-      {
+#endif
          DestroyIcon(oldIcon);
-      }
 
-      // TO FIX LOCK UP PROBLEMS...  WOULD NEED TO UNLOCK ALL RECURSIONS ((GuiApplication)__thisModule.application).Unlock();
        ShowWindow(window.windowHandle, SW_HIDE);
-      // TO FIX LOCK UP PROBLEMS...  WOULD NEED TO LOCK ALL RECURSIONS((GuiApplication)__thisModule.application).Lock();
 
+#ifdef _WIN64
+      SetWindowLongPtr(window.windowHandle, GWLP_USERDATA, (int64)null);
+#else
       SetWindowLong(window.windowHandle, GWL_USERDATA, 0);
+#endif
       DestroyWindow(window.windowHandle);
+
+      for(c = 0; c < lockCount; c++)
+         guiApp.lockMutex.Wait();
+
       window.windowHandle = null;
    }
 
@@ -1436,7 +1461,9 @@ class Win32Interface : Interface
    void SetRootWindowCaption(Window window, char * name)
    {
       uint16 * text = UTF8toUTF16(name, null);
+      guiApp.Unlock();
       SetWindowText(window.windowHandle, text);
+      guiApp.Lock();
       delete text;
    }
 
@@ -1515,7 +1542,7 @@ class Win32Interface : Interface
          {
             case maximized:
             case normal:
-               ShowWindow(window.windowHandle, (window.creationActivation == activate && !externalDisplayChange) ? 
+               ShowWindow(window.windowHandle, ((window.active || window.creationActivation == activate) && !externalDisplayChange) ? 
                   ((window.nativeDecorations && state == maximized) ? SW_MAXIMIZE : SW_SHOWNORMAL) : SW_SHOWNOACTIVATE);
                break;
             case minimized:
@@ -1542,7 +1569,9 @@ class Win32Interface : Interface
       flashInfo.hwnd = window.windowHandle;
       flashInfo.uCount = 1;
       flashInfo.dwFlags = FLASHW_TRAY; // FLASHW_ALL;
+      guiApp.Unlock();
       FlashWindowEx((void *)&flashInfo);
+      guiApp.Lock();
    }
 
    // --- Mouse-based window movement ---
@@ -1803,6 +1832,20 @@ class Win32Interface : Interface
       HICON icon = null;
       HICON oldIcon = (HICON)SendMessage(window.windowHandle, WM_GETICON, ICON_BIG, 0);
 
+      // Dialogs Inherit master's icon if none set
+      if(!window.style.showInTaskBar && window.hasClose)
+      {
+         Window master = window.master;
+         while(master && !resource)
+         {
+            Window rootWindow = (master && master != guiApp.desktop) ? master.rootWindow : null;
+            if(rootWindow && rootWindow.icon)
+               resource = rootWindow.icon;
+            else
+               master = master.master;
+         }
+      }
+
       // WARNING -- putting this here as it is right after CreateRootWindow
       // Take out Layered flag if we're not in 24 bit
       {
@@ -1816,7 +1859,11 @@ class Win32Interface : Interface
          }
       }
 
+#ifdef _WIN64
+      if(oldIcon && oldIcon != (HICON)GetClassLongPtr(window.windowHandle, GCLP_HICON))
+#else
       if(oldIcon && oldIcon != (HICON)GetClassLong(window.windowHandle, GCL_HICON))
+#endif
       {
          DestroyIcon(oldIcon);
       }