Skip to content

Commit

Permalink
Migrate to NativeCallable.isolateLocal (#798)
Browse files Browse the repository at this point in the history
  • Loading branch information
halildurmus committed Dec 4, 2023
1 parent 1c397c1 commit b27171a
Show file tree
Hide file tree
Showing 21 changed files with 169 additions and 62 deletions.
17 changes: 9 additions & 8 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ following location:

## Windows shell manipulation (shell32)

| Example | Description |
| ------------------ | ------------------------------------------------------- |
| `knownfolder.dart` | Retrieves known folders from the current user profile |
| `magnifier.dart` | Provides a magnifier window using the Magnification API |
| `recycle_bin.dart` | Queries the recycle bin and adds an item to it |
| `screenshot.dart` | Takes snapshots of all connected displays |
| `shortcut.dart` | Demonstrates creating a Windows shell link |
| `wallpaper.dart` | Shows what wallpaper and background color are set |
| Example | Description |
| -------------------- | ------------------------------------------------------- |
| `knownfolder.dart` | Retrieves known folders from the current user profile |
| `magnifier.dart` | Provides a magnifier window using the Magnification API |
| `recycle_bin.dart` | Queries the recycle bin and adds an item to it |
| `screenshot.dart` | Takes snapshots of all connected displays |
| `shell_notify_icon\` | Demonstrates adding an icon to the system tray |
| `shortcut.dart` | Demonstrates creating a Windows shell link |
| `wallpaper.dart` | Shows what wallpaper and background color are set |

## Win32-style UI development (user32, gdi32, commdlg32)

Expand Down
8 changes: 7 additions & 1 deletion example/customtitlebar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -517,12 +517,17 @@ void main() {
// Register the window class.
final windowClassName = 'WIN32_CUSTOM_TITLEBAR_EXAMPLE'.toNativeUtf16();

final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(
mainWindowProc,
exceptionalReturn: 0,
);

final windowClass = calloc<WNDCLASSEX>()
..ref.cbSize = sizeOf<WNDCLASSEX>()
..ref.lpszClassName = windowClassName
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.hCursor = LoadCursor(NULL, IDC_ARROW)
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(mainWindowProc, 0);
..ref.lpfnWndProc = lpfnWndProc.nativeFunction;

RegisterClassEx(windowClass);

Expand All @@ -544,6 +549,7 @@ void main() {
DispatchMessage(msg);
}

lpfnWndProc.close();
free(msg);
free(windowCaption);
free(windowClass);
Expand Down
10 changes: 8 additions & 2 deletions example/customwin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// Draw a circular window

import 'dart:ffi';
import 'package:ffi/ffi.dart';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

int mainWindowProc(int hWnd, int uMsg, int wParam, int lParam) {
Expand Down Expand Up @@ -60,9 +60,14 @@ void winMain(int hInstance, List<String> args, int nShowCmd) {
// Register the window class.
final className = TEXT('Sample Window Class');

final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(
mainWindowProc,
exceptionalReturn: 0,
);

final wc = calloc<WNDCLASS>()
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(mainWindowProc, 0)
..ref.lpfnWndProc = lpfnWndProc.nativeFunction
..ref.hInstance = hInstance
..ref.lpszClassName = className
..ref.hCursor = LoadCursor(NULL, IDC_ARROW)
Expand Down Expand Up @@ -105,5 +110,6 @@ void winMain(int hInstance, List<String> args, int nShowCmd) {
DispatchMessage(msg);
}

lpfnWndProc.close();
free(className);
}
9 changes: 7 additions & 2 deletions example/dialogbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,21 @@ void main() {
windowSystemClass: 0x0081, // edit
text: 'Enter text');

final lpDialogFunc = Pointer.fromFunction<DlgProc>(dialogReturnProc, 0);
final lpDialogFunc = NativeCallable<DlgProc>.isolateLocal(
dialogReturnProc,
exceptionalReturn: 0,
);

final nResult = DialogBoxIndirectParam(
hInstance, ptr.cast<DLGTEMPLATE>(), NULL, lpDialogFunc, 0);
hInstance, ptr.cast<DLGTEMPLATE>(), NULL, lpDialogFunc.nativeFunction, 0);

if (nResult <= 0) {
print('Error: $nResult');
} else {
print('Entered: $textEntered');
}

lpDialogFunc.close();
free(ptr);
}

Expand Down
13 changes: 8 additions & 5 deletions example/dump.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,19 @@ Map<String, int> getExports(int hProcess, String module) {
}

final mask = '*'.toNativeUtf16();

final callback = NativeCallable<SymEnumSymbolsProc>.isolateLocal(
_enumSymbolProc,
exceptionalReturn: 0,
);

if (SymEnumSymbols(
hProcess,
baseOfDll,
mask,
Pointer.fromFunction<SymEnumSymbolsProc>(_enumSymbolProc, 0),
nullptr) ==
hProcess, baseOfDll, mask, callback.nativeFunction, nullptr) ==
FALSE) {
print('SymEnumSymbols failed.');
}

callback.close();
SymCleanup(hProcess);
free(modulePtr);
free(mask);
Expand Down
8 changes: 6 additions & 2 deletions example/fonts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ int enumerateFonts(
void main() {
final hDC = GetDC(NULL);
final searchFont = calloc<LOGFONT>()..ref.lfCharSet = ANSI_CHARSET;
final callback = Pointer.fromFunction<EnumFontFamExProc>(enumerateFonts, 0);
final lpProc = NativeCallable<EnumFontFamExProc>.isolateLocal(
enumerateFonts,
exceptionalReturn: 0,
);

EnumFontFamiliesEx(hDC, searchFont, callback, 0, 0);
EnumFontFamiliesEx(hDC, searchFont, lpProc.nativeFunction, 0, 0);
lpProc.close();
fontNames.sort();

print('${fontNames.length} font families discovered.');
Expand Down
11 changes: 9 additions & 2 deletions example/hello.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// Basic Petzoldian "hello world" Win32 app

import 'dart:ffi';
import 'package:ffi/ffi.dart';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

int mainWindowProc(int hWnd, int uMsg, int wParam, int lParam) {
Expand Down Expand Up @@ -42,9 +42,15 @@ void main() => initApp(winMain);
void winMain(int hInstance, List<String> args, int nShowCmd) {
// Register the window class.
final className = TEXT('Sample Window Class');

final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(
mainWindowProc,
exceptionalReturn: 0,
);

final wc = calloc<WNDCLASS>()
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(mainWindowProc, 0)
..ref.lpfnWndProc = lpfnWndProc.nativeFunction
..ref.hInstance = hInstance
..ref.lpszClassName = className
..ref.hCursor = LoadCursor(NULL, IDC_ARROW)
Expand Down Expand Up @@ -87,5 +93,6 @@ void winMain(int hInstance, List<String> args, int nShowCmd) {
DispatchMessage(msg);
}

lpfnWndProc.close();
free(msg);
}
20 changes: 16 additions & 4 deletions example/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import 'dart:ffi';
import 'dart:io';
import 'dart:math';
import 'package:ffi/ffi.dart';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

const LLKHF_INJECTED = 0x00000010;
Expand Down Expand Up @@ -193,12 +193,21 @@ int mainWindowProc(int hWnd, int uMsg, int wParam, int lParam) {
void main() => initApp(winMain);

void winMain(int hInstance, List<String> args, int nShowCmd) {
keyHook = SetWindowsHookEx(WH_KEYBOARD_LL,
Pointer.fromFunction<CallWndProc>(lowlevelKeyboardHookProc, 0), NULL, 0);
final lpfn = NativeCallable<CallWndProc>.isolateLocal(
lowlevelKeyboardHookProc,
exceptionalReturn: 0,
);

keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, lpfn.nativeFunction, NULL, 0);

final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(
mainWindowProc,
exceptionalReturn: 0,
);

final wc = calloc<WNDCLASS>()
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(mainWindowProc, 0)
..ref.lpfnWndProc = lpfnWndProc.nativeFunction
..ref.hInstance = hInstance
..ref.lpszClassName = className
..ref.hIcon = LoadIcon(NULL, IDI_APPLICATION)
Expand Down Expand Up @@ -230,4 +239,7 @@ void winMain(int hInstance, List<String> args, int nShowCmd) {
TranslateMessage(msg);
DispatchMessage(msg);
}

lpfnWndProc.close();
lpfn.close();
}
26 changes: 18 additions & 8 deletions example/magnifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// ignore_for_file: constant_identifier_names

import 'dart:ffi';
import 'package:ffi/ffi.dart';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

// For simplicity, the sample uses a constant magnification factor
Expand All @@ -32,16 +32,22 @@ void main() => initApp(winMain);

/// Entry point for the application
void winMain(int hInstance, List<String> args, int nCmdShow) {
if (MagInitialize() == FALSE || !setupMagnifier(hInstance)) {
final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(hostWndProc,
exceptionalReturn: 0);

if (MagInitialize() == FALSE ||
!setupMagnifier(hInstance, lpfnWndProc.nativeFunction)) {
return;
}

ShowWindow(hwndHost, nCmdShow);
UpdateWindow(hwndHost);

final lpTimerFunc = NativeCallable<TimerProc>.isolateLocal(updateMagWindow);

// Create a timer to update the control
final timerId = SetTimer(hwndHost, 0, timerInterval,
Pointer.fromFunction<TimerProc>(updateMagWindow));
final timerId =
SetTimer(hwndHost, 0, timerInterval, lpTimerFunc.nativeFunction);

// Main message loop
final msg = calloc<MSG>();
Expand All @@ -54,6 +60,8 @@ void winMain(int hInstance, List<String> args, int nCmdShow) {
KillTimer(NULL, timerId);
MagUninitialize();

lpTimerFunc.close();
lpfnWndProc.close();
free(msg);
}

Expand Down Expand Up @@ -100,11 +108,12 @@ int hostWndProc(int hWnd, int message, int wParam, int lParam) {

/// Registers the window class for the window that contains the magnification
/// control.
int registerHostWindowClass(int hInstance) {
int registerHostWindowClass(
int hInstance, Pointer<NativeFunction<WindowProc>> lpfnWndProc) {
final wcex = calloc<WNDCLASSEX>()
..ref.cbSize = sizeOf<WNDCLASSEX>()
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(hostWndProc, 0)
..ref.lpfnWndProc = lpfnWndProc
..ref.hInstance = hInstance
..ref.hCursor = LoadCursor(NULL, IDC_ARROW)
..ref.hbrBackground = COLOR_BTNFACE + 1
Expand All @@ -113,7 +122,8 @@ int registerHostWindowClass(int hInstance) {
return RegisterClassEx(wcex);
}

bool setupMagnifier(int hInst) {
bool setupMagnifier(
int hInst, Pointer<NativeFunction<WindowProc>> lpfnWndProc) {
// Set bounds of host window according to screen size
hostWindowRect
..ref.top = 0
Expand All @@ -122,7 +132,7 @@ bool setupMagnifier(int hInst) {
..ref.right = GetSystemMetrics(SM_CXSCREEN);

// Create the host window
registerHostWindowClass(hInst);
registerHostWindowClass(hInst, lpfnWndProc);
hwndHost = CreateWindowEx(
WS_EX_TOPMOST | WS_EX_LAYERED,
windowClassName,
Expand Down
11 changes: 8 additions & 3 deletions example/monitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,22 @@ void printMonitorCapabilities(int capabilitiesBitmask) {
void main() {
var result = FALSE;

final lpfnEnum = NativeCallable<MonitorEnumProc>.isolateLocal(
enumMonitorCallback,
exceptionalReturn: 0,
);

result = EnumDisplayMonitors(
NULL, // all displays
nullptr, // no clipping region
Pointer.fromFunction<MonitorEnumProc>(
enumMonitorCallback, // dwData
0),
lpfnEnum.nativeFunction,
NULL);
if (result == FALSE) {
throw WindowsException(result);
}

lpfnEnum.close();

print('Number of monitors: ${monitors.length}');

final primaryMonitorHandle = findPrimaryMonitor(monitors);
Expand Down
19 changes: 15 additions & 4 deletions example/notepad/notepad.dart
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,13 @@ int mainWindowProc(int hwnd, int message, int wParam, int lParam) {
case IDM_APP_ABOUT:
final pDialog = NotepadResources.loadAboutBox();

final lpDialogFunc =
Pointer.fromFunction<DlgProc>(dialogReturnProc, 0);
DialogBoxIndirect(hInstance, pDialog, hwnd, lpDialogFunc);
final lpDialogFunc = NativeCallable<DlgProc>.isolateLocal(
dialogReturnProc,
exceptionalReturn: 0,
);
DialogBoxIndirect(
hInstance, pDialog, hwnd, lpDialogFunc.nativeFunction);
lpDialogFunc.close();
return 0;
}
return 0;
Expand Down Expand Up @@ -289,9 +293,14 @@ void main() {
// Register the window class.
final className = TEXT(APP_NAME);

final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(
mainWindowProc,
exceptionalReturn: 0,
);

final wc = calloc<WNDCLASS>()
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(mainWindowProc, 0)
..ref.lpfnWndProc = lpfnWndProc.nativeFunction
..ref.hInstance = hInstance
..ref.lpszClassName = className
..ref.hCursor = LoadCursor(NULL, IDC_ARROW)
Expand Down Expand Up @@ -342,5 +351,7 @@ void main() {
}
}
}

lpfnWndProc.close();
free(msg);
}
8 changes: 7 additions & 1 deletion example/paint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,14 @@ void winMain(int hInstance, List<String> args, int nShowCmd) {
// Register the window class.
final className = TEXT('Simple Paint Sample');

final lpfnWndProc = NativeCallable<WindowProc>.isolateLocal(
mainWindowProc,
exceptionalReturn: 0,
);

final wc = calloc<WNDCLASS>()
..ref.style = CS_HREDRAW | CS_VREDRAW
..ref.lpfnWndProc = Pointer.fromFunction<WindowProc>(mainWindowProc, 0)
..ref.lpfnWndProc = lpfnWndProc.nativeFunction
..ref.hInstance = hInstance
..ref.lpszClassName = className
..ref.hCursor = LoadCursor(NULL, IDC_ARROW)
Expand Down Expand Up @@ -97,5 +102,6 @@ void winMain(int hInstance, List<String> args, int nShowCmd) {
DispatchMessage(msg);
}

lpfnWndProc.close();
free(className);
}
Loading

0 comments on commit b27171a

Please sign in to comment.