A script to stop force close

Started by whitespirits, April 24, 2016, 07:52:11 pm

Previous topic - Next topic

whitespirits

Hi guys so I'm back to messing with rpg maker XP Ace and rmx-os, I'm wondering if a script can be made to stop people closing the client or rpg maker using the X? Maybe something that of its pressed send a message to use end game instead? Thanks

Blizzard

You mean the X button in the top right corner? I rhibk this might be possible.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

There are Ruby methods to do such things. I know in RMXP (Ruby 1.8.1) you can alias exit and that method will be called when the player closes the game normally or presses X. This doesn't work anymore in 1.9.2 (RMVXA/XPA) for some reason.

I could've sworn I did find a solution to that before on accident and I believe it had to do something with Exceptions, specifically SystemExit. Though I've tried a bunch of things and didn't get anywhere. Google didn't help either :|

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

It should be possible to catch the WM_CLOSE event using a hook and do a clean exit with disconnect. It doesn't prevent exiting, but at least a clean disconnect will ensure that stuff is properly saved, etc. WM_CLOSE is also triggered on ALT+F4. I'm not sure you can abort WM_CLOSE with RMs so a clean exit might be the only option.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

whitespirits

Any chance you guys could put something together for me? Thanks!

Mason Wheeler

Wow.  How do you hook window messages in RGSS?

Blizzard

April 25, 2016, 11:47:35 am #6 Last Edit: April 25, 2016, 11:55:05 am by Blizzard
It turns out that once WM_CLOSE has been fired, it can't be stopped. :/ But you can still disable the X button when the game is activated. Just put this on top of your script list.


module DisableX
 
  def self.get_window
    game_name = "\0" * 256
    read_ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'pppplp', 'l')
    read_ini.call('Game', 'Title', '', game_name, 255, './Game.ini')
    game_name += "\0"
    find_window = Win32API.new('user32', 'FindWindowA', 'pp', 'L')
    return find_window.call('RGSS Player', game_name)
  end
 
  window = self.get_window
  if window != 0
    menu = Win32API.new('user32', 'GetSystemMenu', 'll', 'l').call(window, 0)
    if menu != 0
      Win32API.new('user32', 'EnableMenuItem', 'lll', 'l').call(menu, 0xF060, 0x1) # SC_CLOSE, MF_BYCOMMAND | MF_GRAYED
    end
  end
 
end


@Mason: This is a simple piece of C code that can hook messages. If you compile this as a DLL with Visual Studio and link to user32.lib, this will work.


#define NOMINMAX
#include <windows.h>

#define DLL_EXPORT __declspec(dllexport)

LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code >= 0)
{
PCWPSTRUCT msg = (PCWPSTRUCT)lParam;
if (msg->message == WM_CLOSE) // this would be processing some stuff regarding WM_CLOSE
{
// extra code would go here, maybe something like MessageBoxA(0, "TEST", "HELLO THERE", 0);
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}

int initialized = 0;
void DLL_EXPORT Initialize(HWND hwnd) // assuming you get HWND from RUBY using FindWindowA() with the above Ruby code (self.get_window)
{
if (!initialized)
{
HINSTANCE hinstance = (HINSTANCE)GetWindowLongW(hwnd, GWL_HINSTANCE);
DWORD threadId = GetCurrentThreadId(); // some hooks can't be thread specific, but this one can
if (hinstance != 0 && threadId != 0 && SetWindowsHookExW(WH_CALLWNDPROC, CallWndProc, hinstance, threadId) != 0)
{
initialized = 1;
}
}
}


You could call the DLL like this from Ruby:


module MySpecialCode
 
  def self.get_window
    game_name = "\0" * 256
    read_ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', ['p', 'p', 'p', 'p', 'l', 'p'], 'l')
    read_ini.call('Game', 'Title', '', game_name, 255, './Game.ini')
    game_name += "\0"
    find_window = Win32API.new('user32', 'FindWindowA', ['p', 'p'], 'L')
    return find_window.call('RGSS Player', game_name)
  end
 
  window = self.get_window
  if window != 0
    Win32API.new('MyDll', 'Initialize', 'l', 'v').call(window)
  end
 
end
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

whitespirits

thanks Blizz epic! 1 more things can u keep game running when u minimize or change windows? rpg maker xp stops :(

Blizzard

I don't think this one is possible. Altough, maybe if you add a hook and intercept the WM_ACTIVATE event. Not sure how RMXP handles the stopping, but it could be that it handles the WM_ACTIVATE or WM_ACTIVATEAPP event and responds accordingly. So disabling these events through a hook might be able to stop that from happening and keep the game running in background. But somebody else has to try that, I'm not sure I'll have any time over the course of the next week to look into that. xD The C code on top should almost work with some minor edits.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

whitespirits

thanks Blizz I'm testing the DDL that was posted that keeps it running in background, I'm thinking now I need to remove minimize to keep rmx-os running to stop issues

Blizzard

You can intercept these messages as well. Or you can actually hide the top-right by changing the "style of window" as well. Just google around, you just need 1 or 2 Win32API calls for that.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

whitespirits

being as noob as I am could u post something for me man :) ?

Blizzard

April 26, 2016, 10:57:56 am #12 Last Edit: April 26, 2016, 11:00:12 am by Blizzard
This will disable the system menu, but somebody else has to do that WM_ACTIVATE disabling in C.


module DisableSystemMenu
 
  def self.get_window
    game_name = "\0" * 256
    read_ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'pppplp', 'l')
    read_ini.call('Game', 'Title', '', game_name, 255, './Game.ini')
    game_name += "\0"
    find_window = Win32API.new('user32', 'FindWindowA', 'pp', 'L')
    return find_window.call('RGSS Player', game_name)
  end
 
  window = self.get_window
  if window != 0
    style = Win32API.new('user32', 'GetWindowLong', 'll', 'l').call(window, -16) # GWL_STYLE
    style &= ~0x00080000 # removing WS_SYSMENU
    Win32API.new('user32', 'SetWindowLong', 'lll', 'l').call(window, -16, style)
  end
 
end
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.