2015-09-25 43 views
12

我正在用NW.JS(node-webkit)編寫桌面應用程序。在我的應用程序中,用戶可能會打開很多窗口,我希望將它們從程序切換器(alt +選項卡)和任務欄中隱藏起來。我已經找到了從taksbar隱藏窗口的選項,但是找不到任何方法將它從程序切換器中隱藏起來。它甚至有可能嗎?或者至少是否可以將所有窗口分組爲一個窗口(就像在Windows上的便利貼)?從程序切換器隱藏窗口NW.JS

回答

0

我從來沒有使用NW.JS,所以這可能是完全錯誤的,但它看起來像NM.JS的Native UI模塊。我會想象使用這個模塊,你應該能夠創建本地窗口,並給他們一個WS_EX_TOOLWINDOW風格。看到這個答案:Best way to hide a window from the Alt-Tab program switcher。如果您只針對Windows,這似乎是通知的最佳路徑。

另一個想到的是使用IFRAMES構建應用程序,以便只有一個本地窗口。然後,您可以使用JavaScript和您自己的界面來決定顯示哪些IFRAMES。

1

此功能可能會在某些時候出現,但從版本0.12.3開始,node-webkit不提供用於實現工具類型窗口的任何接口,因此無法使用JavaScript或使用項目的包來實現此目的.json文件。我可以在這裏想到兩種選擇。

1.自己構建node-webkit。 The guide是非常直接和全面的。您需要修改的NativeWindowAura構造中native_aurora_aura.cc,特別是該位:

#if defined(OS_WIN) 
    HWND hwnd = views::HWNDForWidget(window_->GetTopLevelWidget()); 
    int current_style = ::GetWindowLong(hwnd, GWL_STYLE); 
    ::SetWindowLong(hwnd, GWL_STYLE, current_style | WS_CAPTION); //This is the importante line 
#endif 

到:

::SetWindowLong(hwnd, GWL_STYLE, current_style | WS_CAPTION | WS_EX_TOOLWINDOW); 

請注意,這是一個簡單的解決方案,這將導致所有新窗口,默認工具樣式並且在切換窗口時不可見。使清單文件或window API可用此功能需要更改多個文件。

2.編寫並部署加載打包項目(或您的項目文件夾)的啓動應用程序,連續搜索具有特定標題的窗口並設置窗口樣式。下面是一個使用C#控制檯應用程序的例子,但是你可以使用也可以使用C++或任何.NET語言是:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Runtime.InteropServices; 
using System.Timers; 
using System.Diagnostics; 

namespace nw 
{ 
    class Program 
    { 
     const int GWL_EXSTYLE  = -0x14; 
     const int WS_EX_APPWINDOW = 0x40000; 
     const int WS_EX_TOOLWINDOW = 0x80; 
     const int WS_EX_COMPOSITED = 0x02000000; 

     [DllImport("user32", CharSet = CharSet.Auto)] 
     static extern int GetWindowLong(IntPtr hwnd, int index); 

     [DllImport("User32.Dll")] 
     static extern int SetWindowLong(IntPtr hwnd, int index, int newLong); 

     [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
     static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount); 

     [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
     static extern int GetWindowTextLength(IntPtr hWnd); 

     [DllImport("user32.dll")] 
     static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); 

     [DllImport("user32.dll")] 
     static extern IntPtr SetWindowText(IntPtr HWND, string Text); 

     delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); 


     //------------------------------------------------------------------ 
     static void Main(string[] args) 
     { 
     // Test an unpackaged app like: 
     // Process.Start(<path\to\nw.exe>, <path\to\project-folder>); 

     Process.Start("packaged-nw-app.js"); 

     Timer timer = new Timer() { Interval = 100, Enabled = true }; 
     timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 

     Console.ReadLine(); 
     } 


     //------------------------------------------------------------------ 
     static void OnTimedEvent(object source, ElapsedEventArgs e) 
     { 
     // Find our target windows (change "nw-tool-window" to your window title) 
     IEnumerable<IntPtr> windows = FindWindowsWithText("nw-tool-window"); 

     foreach (var window in windows) 
     { 
      // Apply WS_EX_TOOLWINDOW to the current style 
      SetWindowLong(window, GWL_EXSTYLE, (GetWindowLong(window, GWL_EXSTYLE) | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW); 
      // Change title to flag as changed 
      SetWindowText(window, "nw-tool-window-hidden"); 
     } 
     } 


     //------------------------------------------------------------------ 
     static string GetWindowText(IntPtr hwnd) 
     { 
     int size = GetWindowTextLength(hwnd); 

     if (size > 0) 
     { 
      var builder = new StringBuilder(size + 1); 
      GetWindowText(hwnd, builder, builder.Capacity); 
      return builder.ToString(); 
     } 

     return String.Empty; 
     } 


     //------------------------------------------------------------------ 
     static IEnumerable<IntPtr> FindWindows(EnumWindowsProc filter) 
     { 
     IntPtr found = IntPtr.Zero; 
     List<IntPtr> windows = new List<IntPtr>(); 

     EnumWindows(delegate(IntPtr wnd, IntPtr param) 
     { 
      if (filter(wnd, param)) 
      { 
       windows.Add(wnd); 
      } 

      return true; 
     }, IntPtr.Zero); 

     return windows; 
     } 


     //------------------------------------------------------------ 
     static IEnumerable<IntPtr> FindWindowsWithText(string titleText) 
     { 
     return FindWindows(delegate(IntPtr wnd, IntPtr param) 
     { 
      return GetWindowText(wnd).Contains(titleText); 
     }); 
     } 
    } 
} 

代碼查找標題從here服用。如果你只對你的主窗口感興趣,你可以擺脫上面的大部分代碼,只需使用FindWindowSetWindowLong即可。您也應該隱藏控制檯或窗口(如果您使用Forms或WPF執行此操作),那麼有足夠的信息來說明如何在SO上完成此操作。

第二種方法是有點哈克,但我寧願去第一個。也許可以實現它,而不是硬編碼和打開拉請求:)

+1

謝謝,這似乎是實現它的方式。我會看看我是否可以抽出時間來嘗試一下。如果我想出一個好的解決方案,我會做一個拉取請求,因爲這個特性非常適合通過他們的API。 – thebreiflabb