Repository navigation
GameWindow
Bartholomew Ho edited this page Nov 9, 2026
·
1 revision
The game's window: whether it's in front, the cursor over it, the mouse buttons and wheel, and the keyboard. A mouse mod uses it to read the cursor and clicks, to show or hide the cursor, and to catch the wheel.
Thread: any thread. The MouseWheel handlers run on a thread pool thread of their own, and the ShowCursor function is called from the window's own message handling (neither is the game or UI thread).
Shows the cursor in the menus and hides it while driving, and logs each turn of the wheel.
using FH2;
using FH2ModPlatform;
public sealed class MouseCursor : Mod
{
private volatile bool _inMenu;
public override ModInfo Info => new("MouseCursor", "1.0.0");
protected override void OnInit()
{
// Menus.FocusedTypeName is for the UI thread: keep the answer in a flag there.
Menus.Frame += dt => _inMenu = Menus.FocusedTypeName != "UIWindow"; // "UIWindow" while driving
GameWindow.ShowCursor = () => _inMenu;
GameWindow.MouseWheel += delta => Log($"wheel: {delta / 120} notch(es)");
}
}Imports FH2
Imports FH2ModPlatform
Public Class MouseCursor
Inherits [Mod]
Private _inMenu As Boolean
Public Overrides ReadOnly Property Info As ModInfo
Get
Return New ModInfo("MouseCursor", "1.0.0")
End Get
End Property
Protected Overrides Sub OnInit()
' Menus.FocusedTypeName is for the UI thread: keep the answer in a flag there.
AddHandler Menus.Frame, Sub(dt) _inMenu = Menus.FocusedTypeName <> "UIWindow" ' "UIWindow" while driving
GameWindow.ShowCursor = Function() As Boolean?
Return _inMenu
End Function
AddHandler GameWindow.MouseWheel, Sub(delta) Log($"wheel: {delta \ 120} notch(es)")
End Sub
End Class| Member | What it does |
|---|---|
Handle (property, nint) |
The game's window, or 0 until it's there. |
IsForeground (property, bool) |
True while the game's window is the one in front (it has the keyboard). |
ClientSize (property, Vector2) |
The size of the game's picture in the window, in pixels. Zero if there's no window yet. |
Cursor (property, Vector2) |
The cursor in the window's pixels. It may be outside the window. (-1, -1) if there's no window yet. |
IsCursorInside (property, bool) |
True when the window is in front and the cursor is over its picture. |
ShowCursor (property, Func<bool?>?, get/set) |
Whether the cursor shows over the game. Your function is asked each time Windows asks the window (on every mouse move, and after UpdateCursor). Return true to show it, false to hide it, or null to leave it to the game. Set the property to null to leave it to the game always. |
SuppressAltMenu (property, bool, get/set) |
True: a tap of Alt doesn't open the window's system menu, which stalls the game. For mods with Alt on a key. |
| Member | What it does |
|---|---|
SetCursor(Vector2 client) (method) |
Moves the cursor to a point in the window's pixels. |
IsMouseDown(MouseButton button) (method, returns bool) |
True while the mouse button is held and the window is in front. |
IsKeyDown(int virtualKey) (method, returns bool) |
True while the key is held and the window is in front. Takes a Windows virtual-key code (0x41 for A). |
UpdateCursor() (method) |
Asks the window again whether the cursor shows (ShowCursor), without the mouse having to move. Call it when your answer changes. |
| Member | What it does |
|---|---|
MouseWheel (event, Action<int>) |
The mouse wheel turned over the game while it's in front. Positive is away from you, 120 per notch. |
Left, Right, Middle, Back, Forward.
- The game doesn't get the usual mouse messages, so the cursor and buttons are read as they are, straight from Windows. Read them as often as you need (for example in Menus
.FrameorGame.Tick). -
Cursoris in the window's pixels. To get the menus' own pixels, useMenus.ToUi(GameWindow.Cursor). -
IsMouseDownandIsKeyDownare false whenever the game's window isn't in front, so a mod doesn't react to keys typed into another program. -
ShowCursor: the game's own screens (before the game and over it) show their own cursor when you return null. Keep your function quick and only read flags in it: it doesn't run on the game or UI thread. If it throws, it counts as null. -
MouseWheelstarts watching the wheel the first time you subscribe. Each handler runs off the window's thread, and an exception in one is ignored.
- Menus and UiElement: find what's under the cursor and click it.
- GameInput: drive and press buttons from the keyboard.
- Controller
- MapView, PhotoCamera, GarageCamera: the wheel for the garage camera, dragging the map.
- Threads
Playing
Getting started
Writing mods
The FH2 classes
- Game
- Player
- Vehicle
- World
- Garage, CarCatalog, Profile
- UI and Hud
- Camera
- Audio
- ANNA
- Skills
- DebugOverlay
- Controller
- GameInput
- GameWindow
- Menus and UiElement
- SettingsTile
- ButtonIcons and Picture
- MapView, PhotoCamera, GarageCamera
More