Jump to content
Tuts 4 You
Sign in to follow this  
CodeExplorer

Sending Alt+Pause (Alt+Break) to dosbox debugger???

Rate this topic

Recommended Posts

CodeExplorer
CodeExplorer

For INPUT thing I've defined on first line of StdAfx.h
#define _WIN32_WINNT 0x0500 // so the code would compile

I get the answer from: http://answers.google.com/answers/threadview?id=359697
and now https://batchloaf.wordpress.com/2012/04/17/simulating-a-keystroke-in-win32-c-or-c-using-sendinput/
will compile but still doesn't send the key to dosbox console!

 

Share this post


Link to post
Share on other sites
CodeExplorer

SendInput acts in the same way with:
keybd_event('A', 0, 0, 0);
keybd_event('A', 0, KEYEVENTF_KEYUP, 0);

I found that after executing the code the key is send to the program who made the call to keybd_event
and not the program I wanted even if I set to foreground using:
    HWND w_handle = GetMainWindowHandle(GetPid());
    ::SetForegroundWindow(w_handle);

SendMessage Api won't work at all for this program!
I only could think of CreateRemoteThread(keybd_event)!
 

Share this post


Link to post
Share on other sites
CodeExplorer

I've looked a bit to DOSBOX source code: https://sourceforge.net/p/dosbox/code-0/HEAD/tree/

			/* Non-focus priority is set to pause; check to see if we've lost window or input focus
			 * i.e. has the window been minimised or made inactive?
			 */
			if (sdl.priority.nofocus == PRIORITY_LEVEL_PAUSE) {
				if ((event.active.state & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) && (!event.active.gain)) {
					/* Window has lost focus, pause the emulator.
					 * This is similar to what PauseDOSBox() does, but the exit criteria is different.
					 * Instead of waiting for the user to hit Alt-Break, we wait for the window to
					 * regain window or input focus.
					 */
					bool paused = true;
					SDL_Event ev;

					GFX_SetTitle(-1,-1,true);
					KEYBOARD_ClrBuffer();
//					SDL_Delay(500);
//					while (SDL_PollEvent(&ev)) {
						// flush event queue.
//					}

					while (paused) {
						// WaitEvent waits for an event rather than polling, so CPU usage drops to zero
						SDL_WaitEvent(&ev);

						switch (ev.type) {
						case SDL_QUIT: throw(0); break; // a bit redundant at linux at least as the active events gets before the quit event.
						case SDL_ACTIVEEVENT:     // wait until we get window focus back
							if (ev.active.state & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) {
								// We've got focus back, so unpause and break out of the loop
								if (ev.active.gain) {
									paused = false;
									GFX_SetTitle(-1,-1,false);
								}

								/* Now poke a "release ALT" command into the keyboard buffer
								 * we have to do this, otherwise ALT will 'stick' and cause
								 * problems with the app running in the DOSBox.
								 */
								KEYBOARD_AddKey(KBD_leftalt, false);
								KEYBOARD_AddKey(KBD_rightalt, false);
							}
							break;
						}
					}
				}
			}

And the method PauseDOSBox:

static void PauseDOSBox(bool pressed) {
	if (!pressed)
		return;
	GFX_SetTitle(-1,-1,true);
	bool paused = true;
	KEYBOARD_ClrBuffer();
	SDL_Delay(500);
	SDL_Event event;
	while (SDL_PollEvent(&event)) {
		// flush event queue.
	}

	while (paused) {
		SDL_WaitEvent(&event);    // since we're not polling, cpu usage drops to 0.
		switch (event.type) {

			case SDL_QUIT: KillSwitch(true); break;
			case SDL_KEYDOWN:   // Must use Pause/Break Key to resume.
			case SDL_KEYUP:
			if(event.key.keysym.sym == SDLK_PAUSE) {

				paused = false;
				GFX_SetTitle(-1,-1,false);
				break;
			}
#if defined (MACOSX)
			if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod == KMOD_RMETA || event.key.keysym.mod == KMOD_LMETA) ) {
				/* On macs, all aps exit when pressing cmd-q */
				KillSwitch(true);
				break;
			}
#endif
		}
	}
}

My guess is that:
if(event.key.keysym.sym == SDLK_PAUSE)
is the Alt+Pause key!

 

 

Share this post


Link to post
Share on other sites
CodeExplorer

Found a solution that works:
https://www.codeproject.com/Articles/6819/SendKeys-in-C
Still working at it. The sleep part is important!

Edit: found a way:
    HWND w_handle = GetMainWindowHandle(GetPid());
    CSendKeys sk;
    sk.AppActivate(w_handle);
    //Send "Hello world!"
    sk.SendKeys("{DELAY=22}%{BREAK}");
    sk.SendKeys("{DELAY=22}%{BREAK}");

 

Edited by CodeExplorer (see edit history)

Share this post


Link to post
Share on other sites
CodeExplorer

When I am not debugging all works ok.
Now what I want to do is set breakpoint on read and when the breakpoint is reached press Alt+Pause: also break DOS box debugger: unfortunately doesn't work;

int process_id = GetPid();
if (process_id<0) return;
HardwareBreakpoint bp;

int ThreadID = 0;
m_logs1.SetLimitText(0);

UINT limit = m_logs1.GetLimitText(); //The current text limit, in bytes, for this CEdit object.

	if (RegisterHotKey(
        NULL,
        1,
        MOD_ALT,  //  | MOD_NOREPEAT
        0x43))  //0x43 is 'C'
    {
        _tprintf(_T("Hotkey 'ALT+C' registered!\n"));
    }


if (DebugActiveProcess(process_id))
{

	 bool ss=true;
   	 DEBUG_EVENT DE={0};
   	 while(ss)
   	 {
		 
   		 WaitForDebugEvent(&DE,INFINITE);
   		 LogString(GetDebugEventName(DE.dwDebugEventCode));
   		 switch(DE.dwDebugEventCode)
   		 {

   		 case CREATE_PROCESS_DEBUG_EVENT:
		{
		ThreadID = DE.dwThreadId;
		func OpenThread=(func)GetProcAddress(GetModuleHandle("KERNEL32.dll"), "OpenThread");
		HANDLE threadhandle = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | 
			THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, 0, DE.dwThreadId);

		char txt[10];
		GetDlgItemText(IDC_EDIT1, txt, 10);

		long break_address = strtol(txt, 0, 16);
		bool set_ok = bp.Set(threadhandle, (DWORD)(break_address), 4, HardwareBreakpoint::Read);
		 break;  // 00403010
		}
		 //
		 //ContinueDebugEvent(DE.dwProcessId,DE.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);

   		 case EXIT_PROCESS_DEBUG_EVENT:
   			 ss=false;
   			 break;
		 
   		 case EXCEPTION_DEBUG_EVENT:
		{
			EXCEPTION_DEBUG_INFO& exception = DE.u.Exception;
			switch( exception.ExceptionRecord.ExceptionCode)
				{
				case EXCEPTION_SINGLE_STEP:  // Same value as EXCEPTION_BREAKPOINT
				
				Beep( 750, 300 );
				LogString("Single step");

				MSG msg = {0};
				while (GetMessage(&msg, NULL, 0, 0) != 0)
				 {
				if (msg.message == WM_HOTKEY)
				{
				ContinueDebugEvent(DE.dwProcessId,DE.dwThreadId,DBG_CONTINUE);
				break;
				}

				}



				break;
				}

		ContinueDebugEvent(DE.dwProcessId,DE.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
		}

   		 }
   		 ContinueDebugEvent(DE.dwProcessId,DE.dwThreadId,DBG_CONTINUE);
	}	


}


}

This is the code I'm using
When I do "sk.AppActivate(w_handle);"
which does the fallowing:

bool CSendKeys::AppActivate(HWND wnd)
{
  if (wnd == NULL)
    return false;

  ::SendMessage(wnd, WM_SYSCOMMAND, SC_HOTKEY, (LPARAM) wnd);
  ::SendMessage(wnd, WM_SYSCOMMAND, SC_RESTORE, (LPARAM) wnd);
 
  ::ShowWindow(wnd, SW_SHOW);
  ::SetForegroundWindow(wnd);
  ::SetFocus(wnd);

  return true;
}

my created program stucks!
Any way I could fix this?
 

 

Share this post


Link to post
Share on other sites
CodeExplorer

Found https://sourceforge.net/p/dosbox/code-0/HEAD/tree/dosbox/trunk/src/gui/sdlmain.cpp#l1481

#if C_DEBUG
/* Pause binds with activate-debugger */
#else
MAPPER_AddHandler(&PauseDOSBox, MK_pause, MMOD2, "pause", "Pause DBox");
#endif
 
And found SSL library
https://libsdl.org/download-2.0.php

I couldn't find the "Pause DBox" string in compiled exes.
 
Edited by CodeExplorer (see edit history)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...