This is a "cheat sheet" for Window Freeze Fix extension by YellowAfterlife.
The extension can be downloaded from itch.io.
Source code can be found on GitHub.
An up-to-date version of this document can always be found online.

Click on sections to expand/collapse them.
Quick display controls: Categories · Sections · Everything ·

Premise

This extension eliminates a certain caveat in GameMaker where the window ceases operation while being dragged around.

This can be desirable for applications that should not be easily interrupted.

Setting up
  1. Enable "Borderless window" in Game Options - Windows - Graphics (GMS2) or Global Game Settings - Windows - Graphics (GMS1).
  2. Import the extension either directly (gmez for GMS1, yymp for GMS2.2, yymps for GMS2.3+) or by picking Add Existing and taking it from the sample projects on GitHub.
  3. Call window_frame_update() in a Step event of a persistent object.
Things To Be Aware Of

Since the extension's initial release in 2017 it has been established that this isn't such a good idea:

  • An extra window may break other extensions that rely on manipulating the game's window.
  • Windows has various undocumented, buggy window behaviours.
    For example, should you comment out the window_frame_force_focus call in window_frame.gml, after entering and exiting fullscreen something strange will happen to the frame window after the game's window is clicked, causing it to become unfocusable and unable to process window button (min/max/close) clicks.
  • Various game overlays (such as Steam overlay) are big black boxes and do whatever they want - for example, it is possible to softlock your game by forcibly opening the overlay when the game does not react to the overlay shortcut.
  • Use of an extra window breaks XInput gamepad polling, which is addressed by the second bundled extension.
  • Use of an extra window also breaks DirectInput gamepad polling, which is not addressable unless you can figure out how GameMaker uses DirectInput API to hook the functions and enforce "global" polling mode.
  • (probably more things that I forgot about)

All in all, unless your application fits the narrow critera where above are acceptable sacrifices (read: it is probably not a videogame) or you have the intricate knowledge of WinAPI required to attempt resolving these issues, I suggest that you do not use this extension.

Size and state
window_frame_update()

Should be called once per frame.

Manages startup and sync (e.g. hiding/unhiding the frame as the game enters/exits fullscreen).


window_frame_set_visible(visible)

Turns the frame on/off.

window_frame_get_visible()​bool

Returns whether the frame is currently being shown.


window_frame_set_fullscreen(enable)

Enables or disables fullscreen.

You must use this in place of regular window_set_fullscreen or you may land yourself or your project's users in an unusual situation involving a fullscreen window that is click-through and cannot be minimized.

window_frame_get_fullscreen()​bool

Counterpart of the above function.


window_frame_has_focus()​focus?

Equivalent to built-in window_has_focus, but counts the frame too.

window_is_maximized()​bool

Returns whether the window (or the frame) is formally maximized.

Note that occupying the entire display area is not the same as maximizing the window, and this will only change to true when clicking the "maximize" button or invoking the command.


window_frame_get_x()​x

Returns X of either the frame (if visible) or the game window.

window_frame_get_y()​y

Returns Y of either the frame (if visible) or the game window.

window_frame_get_width()​width

Returns width of either the frame (if visible) or the game window.

window_frame_get_height()​height

Returns height of either the frame (if visible) or the game window.

window_frame_get_rect()​[x, y, w, h]

Returns a 4-element array containing x/y/width/height of either the frame (if visible) or the game window.

window_frame_set_rect(x, y, w, h)

Equivalent to window_set_rectangle.

Will move either the frame (if active) or the actual game window.


window_frame_set_min_size(minWidth, minHeight)

If the frame is resizable, this function allows to specify minimum user-defined size.

For example,

window_frame_set_min_size(224, 192);
window_frame_set_max_size(maxWidth, maxHeight)

If the frame is resizable, this function allows to specify maximum user-defined size.

For example,

window_frame_set_max_size(1600, 900);

window_frame_set_region(x, y, w, h)

If the frame is active, this moves and/or resizes the game window inside the frame.

From the sample project:

// resize the game to fit the container window if it's visible
// (if you don't do window resizing, you don't need this)
if (window_frame_get_visible()) {
    var w = window_frame_get_width();
    var h = window_frame_get_height();
    if (w > 0 && h > 0 && surface_exists(application_surface)
    && (window_get_width() != w || window_get_height() != h)
    ) {
        // resize room (since we don't use views):
        room_width = w; room_height = h;
        // resize the game inside the frame-window to fit it's size:
        window_frame_set_region(0, 0, w, h);
        // also resize application_surface:
        surface_resize(application_surface, w, h);
    }
}
Extras
window_frame_set_background(color)

Sets the background color shown on the portions of the frame window not occupied by your game. Can be set to -1 to not draw anything there.

window_frame_set_background(make_color_rgb(136, 158, 197));
window_frame_set_caption(text)

Like window_set_caption, but for the frame.

window_frame_sync_icons()

If you are using extensions that change the window icon, you can call this function afterwards to carry them over to the frame window.

(note: copies raw HICON IDs, doesn't store bitmaps)


window_set_topmost(enable)

Changes whether the window (game or frame) will stay on top of other windows.

It is most likely possible to break something with this function and it should not generally be used in videogames.

window_get_topmost()​bool

Returns whether the window (game or frame) is currently marked as stay-on-top.


Window Commands block

The following mirror my other extension:

Supported command constants:

  • window_command_close
  • window_command_maximize
  • window_command_minimize
  • window_command_restore
    The button for un-maximizing the window.
    Disabling this can be generally considered somewhat evil.
  • window_command_resize
    If disabled, the window cannot be resized.
  • window_command_move
    If disabled, the window cannot be dragged around.
  • More command IDs can be found on MSDN (used as 0xF060 etc.)

State:

window_command_set_active(command, enable)​bool

Enables or disables a command.
For example, for buttons this grays out the button.

Returns whether succeeded.

Fails if the extension doesn't have a meaningful way of disabling the said command (in which case you should use hooks instead).

So

window_command_set_active(window_command_minimize, 0);

would disable the ability to minimize the window.

Note that a disabled (or hooked) command can still be ran via window_command_run.

window_command_get_active(command)​enabled?

Returns whether a command is currently enabled, or -1 if unknown.

Hooks:

window_command_hook(command)

Hooks the specified command, intercepting the action and allowing you to check for it using window_command_check. Only button-commands can be hooked.

window_command_unhook(command)

Un-hooks the specified command, allowing it to be performed as usual.

window_command_set_hooked(command, enable)

A convenience function for two of above.

window_command_get_hooked(command)​bool

Returns whether the specified command is currently hooked.

window_command_check(command)​was pressed?

Returns whether the given command's button was pressed since the last call to this function.

Invocation:

window_command_run(wParam, lParam = 0)

Runs the specified command, regardless of whether it is currently hooked.

This essentially invokes WM_SYSCOMMAND on the frame.

lParam is optional since for most (all?) commands it contains the mouse coordinates and is not used by the command processor.

So

window_command_run(window_command_minimize);

would minimize the window when invoked.

NB! Many commands cannot be ran if a mouse button is currently being held down on the window. You'll want to either run commands on mouse_check_button_released or set a flag on press and wait for release.

Exotic functions
window_frame_set_fakefullscreen(enable)

Samuel's borderless fullscreen implementation for the video player extension.

I think this implies disabling the frame yourself beforehand.

window_frame_get_fakefullscreen()​bool

Counterpart of above function.


window_frame_get_handle(buffer_addr)

Takes a buffer_get_address of a buffer and pokes the frame's HWND to beginning of it as buffer_u64.

Rest assured, the buffer should be at least 8 bytes long or your game will hard crash.

window_frame_get_wid()​string

Returns the frame's HWND (a 64-bit integer) as a string.

You should subsequently call int64 on the result to convert it to an actual int64.