Skip to content

Commit 0ad29c5

Browse files
committed
[windows] Add hidden at launch document #51 #39
1 parent 747bfbe commit 0ad29c5

File tree

9 files changed

+141
-34
lines changed

9 files changed

+141
-34
lines changed

README-ZH.md

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
- [Windows](#windows)
3131
- [在启动时隐藏](#在启动时隐藏)
3232
- [macOS](#macos-1)
33+
- [Windows](#windows-1)
3334
- [谁在用使用它?](#谁在用使用它)
3435
- [API](#api)
3536
- [WindowManager](#windowmanager)
@@ -104,7 +105,7 @@
104105

105106
### 安装
106107

107-
将此添加到你的软件包的 pubspec.yaml 文件:
108+
将此添加到你的软件包的 `pubspec.yaml` 文件:
108109

109110
```yaml
110111
dependencies:
@@ -134,11 +135,12 @@ void main() async {
134135

135136
// Use it only after calling `hiddenWindowAtLaunch`
136137
windowManager.waitUntilReadyToShow().then((_) async{
137-
// 设置为无边框窗口
138-
await windowManager.setAsFrameless();
139-
await windowManager.setSize(Size(600, 600));
138+
// 隐藏窗口标题栏
139+
await windowManager.setTitleBarStyle('hidden');
140+
await windowManager.setSize(Size(800, 600));
140141
await windowManager.setPosition(Offset.zero);
141-
windowManager.show();
142+
await windowManager.show();
143+
await windowManager.setSkipTaskbar(false);
142144
});
143145

144146
runApp(MyApp());
@@ -233,13 +235,14 @@ class _HomePageState extends State<HomePage> with WindowListener {
233235
}
234236
}
235237
```
238+
236239
#### 关闭时退出
237240

238241
如果你需要使用 `hide` 方法,你需要禁用 `QuitOnClose`
239242

240243
##### macOS
241244

242-
`macos/Runner/AppDelegate.swift`
245+
更改文件 `macos/Runner/AppDelegate.swift` 如下:
243246

244247
```diff
245248
import Cocoa
@@ -256,7 +259,7 @@ class AppDelegate: FlutterAppDelegate {
256259

257260
##### Windows
258261

259-
`windows/runner/main.cpp`
262+
更改文件 `windows/runner/main.cpp` 如下:
260263

261264
```diff
262265
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
@@ -276,6 +279,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
276279

277280
##### macOS
278281

282+
更改文件 `macos/Runner/MainFlutterWindow.swift` 如下:
283+
279284
```diff
280285
import Cocoa
281286
import FlutterMacOS
@@ -301,6 +306,63 @@ class MainFlutterWindow: NSWindow {
301306

302307
```
303308

309+
##### Windows
310+
311+
更改文件 `windows/runner/win32_window.cpp` 如下:
312+
313+
```diff
314+
bool Win32Window::CreateAndShow(const std::wstring& title,
315+
const Point& origin,
316+
const Size& size) {
317+
...
318+
HWND window = CreateWindow(
319+
- window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
320+
+ window_class, title.c_str(),
321+
+ WS_OVERLAPPEDWINDOW, // do not add WS_VISIBLE since the window will be shown later
322+
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
323+
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
324+
nullptr, nullptr, GetModuleHandle(nullptr), this);
325+
```
326+
327+
确保在 `onWindowFocus` 事件中调用一次 `setState`
328+
329+
```dart
330+
import 'package:flutter/cupertino.dart';
331+
import 'package:window_manager/window_manager.dart';
332+
333+
class HomePage extends StatefulWidget {
334+
@override
335+
_HomePageState createState() => _HomePageState();
336+
}
337+
338+
class _HomePageState extends State<HomePage> with WindowListener {
339+
@override
340+
void initState() {
341+
windowManager.addListener(this);
342+
super.initState();
343+
}
344+
345+
@override
346+
void dispose() {
347+
windowManager.removeListener(this);
348+
super.dispose();
349+
}
350+
351+
@override
352+
Widget build(BuildContext context) {
353+
// ...
354+
}
355+
356+
@override
357+
void onWindowFocus() {
358+
// Make sure to call once.
359+
setState(() {});
360+
// do something
361+
}
362+
}
363+
364+
```
365+
304366
## 谁在用使用它?
305367

306368
- [AuthPass](https://authpass.app/) - 基于Flutter的密码管理器,适用于所有平台。兼容Keepass 2.x(kdbx 3.x)。

README.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ English | [简体中文](./README-ZH.md)
3030
- [Windows](#windows)
3131
- [Hidden at launch](#hidden-at-launch)
3232
- [macOS](#macos-1)
33+
- [Windows](#windows-1)
3334
- [Who's using it?](#whos-using-it)
3435
- [API](#api)
3536
- [WindowManager](#windowmanager)
@@ -104,7 +105,7 @@ English | [简体中文](./README-ZH.md)
104105

105106
### Installation
106107

107-
Add this to your package's pubspec.yaml file:
108+
Add this to your package's `pubspec.yaml` file:
108109

109110
```yaml
110111
dependencies:
@@ -134,11 +135,12 @@ void main() async {
134135

135136
// Use it only after calling `hiddenWindowAtLaunch`
136137
windowManager.waitUntilReadyToShow().then((_) async{
137-
// Set to frameless window
138-
await windowManager.setAsFrameless();
139-
await windowManager.setSize(Size(600, 600));
138+
// Hide window title bar
139+
await windowManager.setTitleBarStyle('hidden');
140+
await windowManager.setSize(Size(800, 600));
140141
await windowManager.setPosition(Offset.zero);
141-
windowManager.show();
142+
await windowManager.show();
143+
await windowManager.setSkipTaskbar(false);
142144
});
143145

144146
runApp(MyApp());
@@ -233,13 +235,14 @@ class _HomePageState extends State<HomePage> with WindowListener {
233235
}
234236
}
235237
```
238+
236239
#### Quit on close
237240

238241
If you need to use the hide method, you need to disable `QuitOnClose`.
239242

240243
##### macOS
241244

242-
`macos/Runner/AppDelegate.swift`
245+
Change the file `macos/Runner/AppDelegate.swift` as follows:
243246

244247
```diff
245248
import Cocoa
@@ -256,7 +259,7 @@ class AppDelegate: FlutterAppDelegate {
256259

257260
##### Windows
258261

259-
`windows/runner/main.cpp`
262+
Change the file `windows/runner/main.cpp` as follows:
260263

261264
```diff
262265
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
@@ -276,7 +279,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
276279

277280
##### macOS
278281

279-
Change the file MainFlutterWindow.swift as follows:
282+
Change the file `macos/Runner/MainFlutterWindow.swift` as follows:
280283

281284
```diff
282285
import Cocoa
@@ -305,7 +308,7 @@ class MainFlutterWindow: NSWindow {
305308

306309
##### Windows
307310

308-
Change the file windows\runner\win32_window.cpp as follows:
311+
Change the file `windows/runner/win32_window.cpp` as follows:
309312

310313
```diff
311314
bool Win32Window::CreateAndShow(const std::wstring& title,
@@ -321,6 +324,45 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
321324
nullptr, nullptr, GetModuleHandle(nullptr), this);
322325
```
323326

327+
Make sure to call `setState` once on the `onWindowFocus` event.
328+
329+
```dart
330+
import 'package:flutter/cupertino.dart';
331+
import 'package:window_manager/window_manager.dart';
332+
333+
class HomePage extends StatefulWidget {
334+
@override
335+
_HomePageState createState() => _HomePageState();
336+
}
337+
338+
class _HomePageState extends State<HomePage> with WindowListener {
339+
@override
340+
void initState() {
341+
windowManager.addListener(this);
342+
super.initState();
343+
}
344+
345+
@override
346+
void dispose() {
347+
windowManager.removeListener(this);
348+
super.dispose();
349+
}
350+
351+
@override
352+
Widget build(BuildContext context) {
353+
// ...
354+
}
355+
356+
@override
357+
void onWindowFocus() {
358+
// Make sure to call once.
359+
setState(() {});
360+
// do something
361+
}
362+
}
363+
364+
```
365+
324366
## Who's using it?
325367

326368
- [AuthPass](https://authpass.app/) - Password Manager based on Flutter for all platforms. Keepass 2.x (kdbx 3.x) compatible.

example/lib/main.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ void main() async {
1010

1111
// Use it only after calling `hiddenWindowAtLaunch`
1212
windowManager.waitUntilReadyToShow().then((_) async {
13-
// await windowManager.setAsFrameless();
13+
// Hide window title bar
14+
await windowManager.setTitleBarStyle('hidden');
1415
await windowManager.setSize(Size(800, 600));
1516
await windowManager.show();
17+
await windowManager.focus();
18+
await windowManager.setSkipTaskbar(false);
1619
});
1720

1821
runApp(MyApp());

example/lib/pages/home.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ class _HomePageState extends State<HomePage> with WindowListener {
7676
PreferenceListItem(
7777
title: Text('show / hide'),
7878
onTap: () async {
79-
windowManager.hide();
79+
await windowManager.hide();
8080
await Future.delayed(Duration(seconds: 2));
81-
windowManager.show();
81+
await windowManager.show();
82+
await windowManager.focus();
8283
},
8384
),
8485
PreferenceListItem(
@@ -573,6 +574,11 @@ class _HomePageState extends State<HomePage> with WindowListener {
573574
);
574575
}
575576

577+
@override
578+
void onWindowFocus() {
579+
setState(() {});
580+
}
581+
576582
@override
577583
void onWindowEvent(String eventName) {
578584
print('[WindowManager] onWindowEvent: $eventName');

example/windows/runner/main.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include "run_loop.h"
77
#include "utils.h"
88

9-
#include <window_manager/window_manager_plugin.h>
10-
119
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
1210
_In_ wchar_t *command_line, _In_ int show_command) {
1311
// Attach to console when present (e.g., 'flutter run') or create a
@@ -29,8 +27,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
2927

3028
project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
3129

32-
HiddenWindowAtLaunch();
33-
3430
FlutterWindow window(&run_loop, project);
3531
Win32Window::Point origin(10, 10);
3632
Win32Window::Size size(1280, 720);

example/windows/runner/win32_window.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
117117
double scale_factor = dpi / 96.0;
118118

119119
HWND window = CreateWindow(
120-
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
120+
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
121121
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
122122
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
123123
nullptr, nullptr, GetModuleHandle(nullptr), this);

windows/include/window_manager/window_manager_plugin.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ extern "C" {
1818
FLUTTER_PLUGIN_EXPORT void WindowManagerPluginRegisterWithRegistrar(
1919
FlutterDesktopPluginRegistrarRef registrar);
2020

21-
#define WMP_FRAMELESS 0x01
22-
#define WMP_HIDDEN_AT_LAUNCH 0x02
23-
24-
FLUTTER_PLUGIN_EXPORT void HiddenWindowAtLaunch();
25-
2621
#if defined(__cplusplus)
2722
} // extern "C"
2823
#endif

windows/window_manager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ void WindowManager::Blur() {
155155
}
156156

157157
void WindowManager::Show() {
158+
HWND hWnd = GetMainWindow();
159+
DWORD gwlStyle = GetWindowLong(hWnd, GWL_STYLE);
160+
gwlStyle = gwlStyle | WS_VISIBLE;
161+
if ((gwlStyle & WS_VISIBLE) == 0) {
162+
SetWindowLong(hWnd, GWL_STYLE, gwlStyle);
163+
::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
164+
}
165+
158166
ShowWindowAsync(GetMainWindow(), SW_SHOW);
159167
SetForegroundWindow(GetMainWindow());
160168
}

windows/window_manager_plugin.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "window_manager.cpp"
1616

1717
namespace {
18-
bool is_hidden_window_at_launch = false;
1918
std::unique_ptr<
2019
flutter::MethodChannel<flutter::EncodableValue>,
2120
std::default_delete<flutter::MethodChannel<flutter::EncodableValue>>>
@@ -377,7 +376,3 @@ void WindowManagerPluginRegisterWithRegistrar(
377376
flutter::PluginRegistrarManager::GetInstance()
378377
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
379378
}
380-
381-
void HiddenWindowAtLaunch() {
382-
is_hidden_window_at_launch = true;
383-
}

0 commit comments

Comments
 (0)