Jump to content
View in the app

A better way to browse. Learn more.

Tuts 4 You

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Featured Replies

  • Author

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!

 

  • Author

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)!
 

  • Author

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!

 

 

  • Author

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

  • Author

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?
 

 

  • Author

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

Create an account or sign in to comment

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.