CodeExplorer Posted February 2, 2019 Share Posted February 2, 2019 Sending Alt+Pause (Alt+Break) to dosbox debugger ??? DosBox uses SDL.dll so I think SendInput function has to be used: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendinput SendInputExamples: https://batchloaf.wordpress.com/2012/04/17/simulating-a-keystroke-in-win32-c-or-c-using-sendinput/ https://stackoverflow.com/questions/6811899/how-would-i-use-keybd-event-to-send-a-for-example https://batchloaf.wordpress.com/2012/10/18/simulating-a-ctrl-v-keystroke-in-win32-c-or-c-using-sendinput/ https://stackoverflow.com/questions/29129987/c-simulating-keystrokes-using-sendinput-method-failure-to-distinguish-right Anyway Visual C++ 6.0 compiler complains about INPUT structure not being found: INPUT structure is defined here: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taginput How to fix it? Link to comment
CodeExplorer Posted February 2, 2019 Author Share Posted February 2, 2019 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! Link to comment
CodeExplorer Posted February 2, 2019 Author Share Posted February 2, 2019 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)! Link to comment
CodeExplorer Posted February 2, 2019 Author Share Posted February 2, 2019 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! Link to comment
CodeExplorer Posted February 3, 2019 Author Share Posted February 3, 2019 (edited) 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 February 3, 2019 by CodeExplorer Link to comment
CodeExplorer Posted February 3, 2019 Author Share Posted February 3, 2019 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? Link to comment
CodeExplorer Posted February 4, 2019 Author Share Posted February 4, 2019 (edited) 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. Found the reason: different DOSBOX version; here is https://sourceforge.net/p/dosbox/code-0/2257/tree/dosbox/trunk/src/gui/sdlmain.cpp#l913 Edited February 4, 2019 by CodeExplorer Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now