Skip to content
Nikita Krapivin edited this page May 11, 2021 · 10 revisions

Welcome to the libmulti wiki, when one window ain't enough for ya.

This wiki implies you have basic understanding of how window_ functions in GameMaker work, and what are windows in general.

Also, keep in mind that if a function mentions width, height, x or y, it means the client area (MSDN terminology) of the window.

The exposed functions only work with the actual working area of the window, keeping all the hard work of calculating borders away from you.

There are only two functions that just allow you to get the width and height of the non-client area. (i.e. the border)

Functions

libmulti_present

Arguments:

  • Takes no arguments.

Purpose:

This function takes advantage of the fact that GM:S will always return 0 if a function is not defined, or a DLL does not exist.

It does nothing and always returns 1, so if the return value is 0, it means that the DLL is not present or the load has failed.

Return value:

  • Success: 1
  • Failure: 0

libmulti_init

Arguments:

  • Takes no arguments.

Purpose:

Initializes the libmulti library and registeres a WNDCLASS named LibMultiNikIsAFool (as a wide string).

That class will be used for all windows you create, and as for now there's no way to redefine it.

Return value:

  • Success: ATOM value of the WNDCLASS which you can pass to other extensions if you really want to.
  • Failure: 0

libmulti_exists

Arguments:

  • window - window index

Purpose:

Checks if the window argument is a valid window.

Return value:

  • Success: 1
  • Failure: 0

libmulti_last_error_code

Arguments:

  • Takes no arguments.

Purpose:

Returns last WinAPI error code the extension had caught.

You usually only need to call this function if the return value from other functions was less than zero.

Return value:

  • Success: WinAPI error code
  • Failure: 0, also means that there was no error.

libmulti_last_error_message

Arguments:

  • Takes no arguments.

Purpose:

Tries to turn the last WinAPI error code into an error message.

You usually only need to call this function if the return value from other functions was less than zero AND you want a string representation of the error.

It will force the English US locale when generating an error message, because you as a game developer wouldn't want to mess with error messages in Russian, am I right?

Return value:

  • Success: Error message as an English US string.
  • Failure: Empty string, or a string starting with !@ and then the reason (e.g. Failed to get the error message)

libmulti_create_window

Arguments:

  • x - x position of the window, or -1 to let Windows decide.
  • y - y position of the window, or -1 to let Windows decide.
  • width - width of the window, or -1 to let Windows decide.
  • height - height of the window, or -1 to let Windows decide.
  • window_style - window style to use, or -1 for WS_OVERLAPPEDWINDOW.
  • ex_style - extended window style to use, or -1/0 to not use any extended styles.
  • sw_show - SW_ constant, or -1 for SW_SHOWDEFAULT.
  • min_width - minimum allowed width of the window, or -1 to not limit the shrinking by width.
  • min_height - minumum allowed height of the window, or -1 to not limit the shrinking by height.
  • max_width - maximum allowed width of the window, or -1 to not limit maximizing by width.
  • max_height - maximum allowed height of the window, or -1 to not limit maximizing by height.

Purpose:

Creates a new window.

This function combines calls to CreateWindowEx, ShowWindow and UpdateWindow at the same time.

Return value:

  • Success: window index, bigger than -1.
  • Failure: value less than zero.

libmulti_destroy

Arguments:

  • window - window index

Purpose:

Tells the window to destroy itself. (calls DestroyWindow and then the window thread will free all resources occupied by the window)

A friendly reminder, this only works with windows, don't attempt to do this to yourself.

Return value:

  • Success: 1
  • Failure: less than 1.

libmulti_set_caption

Arguments:

  • window - window index
  • caption - caption string to set

Purpose:

Changes the caption of the window. (calls SetWindowText)

Return value:

  • Success: 1
  • Failure: less than 1.

libmulti_get_caption

Arguments:

  • window - window index

Purpose:

Returns the window caption.

Return value:

  • Success: the caption as a string
  • Failure: an empty string

libmulti_set_game_window

LEGACY GAMEMAKER USERS, USE libmulti_set_game_window_real INSTEAD!

IT HAS THE SAME SYNTAX, ONLY THE NAME IS DIFFERENT.

Arguments:

  • window_handle - the value returned by window_handle().

Purpose:

Some functions related to focus/active windows need to know what window is managed by the engine.

It's recommended that you tell the extension which window it is, by passing it the result of window_handle().

(e.g. libmulti_set_game_window(window_handle());)

Legacy GameMaker users, you cannot call this function in the Game Start or first Create event.

Because legacy GameMaker will only create it's window once the first Draw event starts.

I'd recommend doing an alarm[0] = 2; or some other way of doing it.

Studio users, you're sane.

Return value:

  • Success: 1
  • Failure: 0

libmulti_get_x

Arguments:

  • window - window index

Purpose:

Works exactly like window_get_x().

Return value:

  • Success: x position of the client area of the window.
  • Failure: value less than zero.

libmulti_get_y

Arguments:

  • window - window index

Purpose:

Works exactly like window_get_y().

Return value:

  • Success: y position of the client area of the window.
  • Failure: value less than zero.

libmulti_get_width

Arguments:

  • window - window index

Purpose:

Works exactly like window_get_width().

Return value:

  • Success: width of the client area of the window.
  • Failure: value less than zero.

libmulti_get_height

Arguments:

  • window - window index

Purpose:

Works exactly like window_get_height().

Return value:

  • Success: height of the client area of the window.
  • Failure: value less than zero.

libmulti_set_x

Arguments:

  • window - window index
  • x - coordinate

Purpose:

Sets the x position of the window.

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_set_y

Arguments:

  • window - window index
  • y - coordinate

Purpose:

Sets the y position of the window.

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_set_width

Arguments:

  • window - window index
  • width - coordinate

Purpose:

Sets the windows's client area width.

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_set_height

Arguments:

  • window - window index
  • height - coordinate

Purpose:

Sets the windows's client area height.

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_set_position

Arguments:

  • window - window index
  • x - coordinate x
  • y - coordinate y

Purpose:

Works exactly like window_set_position().

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_set_size

Arguments:

  • window - window index
  • width - new width
  • height - new height

Purpose:

Works exactly like window_set_size().

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_set_rectangle

Arguments:

  • window - window index
  • x - coordinate x
  • y - coordinate y
  • width - new width
  • height - new height

Purpose:

Works exactly like window_set_rectangle().

Return value:

  • Success: 1
  • Failure: value less than 1.

libmulti_get_nonclient_left

Arguments:

  • window - window index

Purpose:

Returns the left (aka x) offset of the non-client area. (it's usually negative)

Return value:

  • Success: != 0
  • Failure: 0

libmulti_get_nonclient_top

Arguments:

  • window - window index

Purpose:

Returns the top (aka y) offset of the non-client area. (it's usually negative)

Return value:

  • Success: != 0
  • Failure: 0

libmulti_get_nonclient_right

Arguments:

  • window - window index

Purpose:

Returns the right (aka width) offset of the non-client area. (it's usually positive)

Return value:

  • Success: != 0
  • Failure: 0

libmulti_get_nonclient_bottom

Arguments:

  • window - window index

Purpose:

Returns the bottom (aka height) offset of the non-client area. (it's usually positive)

Return value:

  • Success: != 0
  • Failure: 0

libmulti_set_active_window

Arguments:

  • window - window index or -1 for the game's main window.

Purpose:

Sets the passed window as an active, an active window is the one that gets the input.

Usually an active window also becomes foreground asap, but WinAPI is WinAPI and I have no idea I just want to sleep.

Return value:

  • Success: 1
  • Failure: less than 1

libmulti_set_foreground_window

Arguments:

  • window - window index or -1 for the game's main window.

Purpose:

Sets the passed window as foreground, a foreground window is the one that has it's border highlighted.

Again, usually a foreground window also becomes active asap, but as usual, I'd rather sleep than mess with WinAPI.

Return value:

  • Success: 1
  • Failure: less than 1

libmulti_has_focus

Arguments:

  • window - window index or -1 for the game's main window.

Purpose:

Checks to see if the passed window is also a foreground window. (if it is, it also means it's probably active.)

Return value:

  • Success: 1 for yes, and 0 for no.
  • Failure: less than 0.

libmulti_get_active_window

Arguments:

  • Nothing.

Purpose:

Returns the index of the current active window, or -1 if it's the game window.

Return value:

  • Success: -1 or higher.
  • Failure: less than -1.

libmulti_get_foreground_window

Arguments:

  • Nothing.

Purpose:

Returns the index of the current active window, or -1 if it's the game window.

Return value:

  • Success: -1 or higher.
  • Failure: less than -1.

libmulti_register_callbacks

Just ignore it. Don't call it. Never reference this function in your code.

If you do, you will crash stuff. It's only supposed to be called by GM automatically, never by you.

Return value:

  • Nothing, it cannot return anything.

libmulti_make_bitmap_from_file

THIS FUNCTION IS ONLY FOR LEGACY USERS

STUDIO USERS, USE libmulti_make_bitmap INSTEAD

Arguments:

  • window - window index
  • fullpath - full path to a .bmp file to draw inside the window

Purpose:

Since legacy GameMaker had no pointer type, you need to write a .bmp file instead.

Very simple example:

surface_set_target(surf);
draw_clear(c_yellow);
surface_reset_target();

fullpath = temp_directory + "\__temp.bmp"; // must be a full path and end with .bmp
surface_save(surf, fullpath);
libmulti_make_bitmap_from_file(window, fullpath);

After the function returns the file is not used or locked.

libmulti_make_bitmap

THIS FUNCTION WILL ONLY WORK IN GM:STUDIO

LEGACY USERS, USE libmulti_make_bitmap_from_file INSTEAD

Arguments:

  • window - window index
  • width - width of the image
  • height - height of the image
  • buffer_address - buffer_get_address() of the buffer that contains the image

Purpose:

This function creates a Direct2D bitmap from raw BGRA data, where the Alpha channel is ignored.

Then it forces the window to redraw everything inside itself, thus updating the image.

If the window is being dragged or sized while you call this function, the image will get updated once the user stops dragging or sizing the window.

Very simple example of this function:

/// Somewhere in the Draw Event
var surf = surface_create(640, 480);

surface_set_target(surf);
draw_text(32, 32, "hugs are awesome, aren't they?");
surface_reset_target();

var buff = buffer_create(640 * 480 * 4, buffer_fixed, 1);
buffer_get_surface(buff, surf, 0, 0, 0);
surface_free(surf);
libmulti_make_bitmap(window, 640, 480, buffer_get_address(buff));
buffer_delete(buff);

// of course it's a very bad idea to recreate the surface and the buffer every frame.

If the bitmap size does not match the window's size, it will be drawn in the center of the window, surrounded by a black border.

Please be so kind and scale the surface yourself if you don't want the border.

Return value:

  • Success: 1
  • Failure: less than 1

libmulti_quit

Arguments:

  • No arguments.

Purpose:

This function will forcefully destroy all windows created by libmulti, free all Direct2D targets, all bitmaps, and unregister the LibMultiNikIsAFool class.

It's better that you call this function yourself at Game End.

Or if you're too lazy, you can let GM handle that, simply set the Final Function: in the Extension Properties to libmulti_quit.

Return value:

  • Success: 1
  • Failure: 0 if for some reason we failed, or -1 if you're calling this function more than once. (better NOT to do it!)

libmulti_set_window_style

Arguments:

  • window - window index
  • is_extended - true if yes, false if you want regular window style.
  • value - style bitmask

Purpose:

Allows you to set window's styles after creating it.

Keep in mind that doing so may screw up some functions that calculate width/height.

Styles constants can be found here: https://docs.microsoft.com/en-us/windows/win32/winmsg/constants

Return value:

  • Success: previous style bitmask
  • Failure: 0

libmulti_get_window_style

Arguments:

  • window - window index
  • is_extended - true if yes, false if you want regular window style.

Purpose:

Allows you to get the current window/extended style bitmask.

Then you can bitwise OR new parameters to it, etc.

Styles constants can be found here: https://docs.microsoft.com/en-us/windows/win32/winmsg/constants

Return value:

  • Success: the style bitmask
  • Failure: 0

libmulti_set_min_width

Arguments:

  • window - window index
  • width - minimum width

Purpose:

Works exactly like window_set_min_width().

Return value:

  • Success: 1
  • Failure: value less than 1

libmulti_set_min_height

Arguments:

  • window - window index
  • height - minimum height

Purpose:

Works exactly like window_set_min_height().

Return value:

  • Success: 1
  • Failure: value less than 1

libmulti_set_max_width

Arguments:

  • window - window index
  • width - maximum width

Purpose:

Works exactly like window_set_max_width().

Return value:

  • Success: 1
  • Failure: value less than 1

libmulti_set_max_height

Arguments:

  • window - window index
  • width - maximum height

Purpose:

Works exactly like window_set_max_height().

Return value:

  • Success: 1
  • Failure: value less than 1

libmulti_set_min_size

Arguments:

  • window - window index
  • width - minimum width
  • height - minimum height

Purpose:

libmulti_set_min_width and libmulti_set_min_height combined in one function.

Return value:

  • Success: 1
  • Failure: value less than 1

libmulti_set_max_size

Arguments:

  • window - window index
  • width - maximum width
  • height - maximum height

Purpose:

libmulti_set_max_width and libmulti_set_max_height combined in one function.

Return value:

  • Success: 1
  • Failure: value less than 1

libmulti_get_min_width

Arguments:

  • window - window index

Purpose:

Gets the minimum window width, or -1 if there's no limit.

Return value:

  • Success: minimum allowed width or -1
  • Failure: value less than -1

libmulti_get_min_height

Arguments:

  • window - window index

Purpose:

Gets the minimum window height, or -1 if there's no limit.

Return value:

  • Success: minimum allowed height or -1
  • Failure: value less than -1

libmulti_get_max_width

Arguments:

  • window - window index

Purpose:

Gets the maximum window width, or -1 if there's no limit.

Return value:

  • Success: maximum allowed width or -1
  • Failure: value less than -1

libmulti_get_max_height

Arguments:

  • window - window index

Purpose:

Gets the maximum window height, or -1 if there's no limit.

Return value:

  • Success: maximum allowed height or -1
  • Failure: value less than -1

libmulti_mouse_get_x

Arguments:

  • window - window index

Purpose:

Returns the x mouse coordinate relative to the window's client area.

If you want to get the screen position, please use GameMaker's functions for this.

Return value:

  • Success: coordinate
  • Failure: 0

libmulti_mouse_get_y

Arguments:

  • window - window index

Purpose:

Returns the y mouse coordinate relative to the window's client area.

If you want to get the screen position, please use GameMaker's functions for this.

Return value:

  • Success: coordinate
  • Failure: 0

libmulti_set_gms2_pixel_format

Arguments:

  • truefalse - true or false

Purpose:

Enables or disables GMS 2 pixel format.

You must call libmulti_set_gms2_pixel_format(true); if you're using GMS 2.

Otherwise, R and B color channels will be swapped, not something you'd want.

Return value:

  • Success: old value
  • Failure: -1

libmulti_get_gms2_pixel_format

Arguments:

  • No arguments.

Purpose:

Returns true if the GMS 2 pixel format is enabled, false if it isn't.

Return value:

  • Success: true or false
  • Failure: -1
Clone this wiki locally