Simulate keypress in x86 assembly

I am working on a program which runs in a "DOS" command prompt window.  I would like a function that can toggle the fullscreen mode of this window, like pressing Alt+Enter.  I think that embedding a few lines of assembly in my code is probably the best way to do this.  The easiest way would probably be to simply emulate an Alt+Enter, but if there is an easier way, that is fine also (I read something about an "int 2f" that may work also).  Does anybody have some sample code that can help me accomplish this?
LVL 10
GuruGaryAsked:
Who is Participating?
 
PaulCaswellConnect With a Mentor Commented:
Hi GuruGary,

Heres a reference to int 2f. Not sure if its what you want but there you are:

http://heim.ifi.uio.no/~stanisls/helppc/int_2f.html

Other than that I have no idea how you could do this. I bet this is something games writers used to have to do. Try a link in 'Games'.

Paul
0
 
GuruGaryAuthor Commented:
Hi, Paul.  Thanks for the link.  The link where I found my int 2f info was at http://poli.cs.vsb.cz/misc/rbint/text/2F08.html under "Table 02715".  Does that look like something somebody here could help me with?

It says:
(Table 02715)
Call VSWITCHD entry point with:
      AX = function
          0000h toggle windowed mode (simulate Alt-Enter keypress)
            Return: nothing

But I'm not sure how to "call VSWITCHD entry point".
0
 
PaulCaswellCommented:
Hi GuruGary,

Nice link. Have you tried it:? Do you need help trying it? If you have a MS C compiler int86x should help.

Paul
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
GuruGaryAuthor Commented:
I was going to use DEBUG to assemble and write to a .com file.  But I don't really know what to do.  I have used debug to assemble before, but it is the coding part I am not sure about.

If you look at http://poli.cs.vsb.cz/misc/rbint/text/2F08.html#I0004556 it says to use
AX= 0x1684
BX= 0x7fe0
ES:DI= 0000:0000

then for the goggle windowed mode (what I want to do) it says:
(Table 02715)
Call VSWITCHD entry point with:
     AX = function
         0000h toggle windowed mode (simulate Alt-Enter keypress)

I know how to set AX and BX, but don't know how to set ES:DI= 0000:0000 and I don't know what "call VSWITCHD entry point" means.
0
 
PaulCaswellCommented:
>>how to set ES:DI= 0000:0000
My memory is rusty but you probably want something like:
les di,0

If that doesnt work:

sub ax,ax
mov es,ax
mov di,ax

>>and I don't know what "call VSWITCHD entry point" means
It looks like this function only retrieves a pointer to the function you need to call.

Return: ES:DI -> VxD API entry point (see #02715)

so you need to make sure it isnt null and call it with something like:

call es:[di]

Once you've got something typed up you think will work, post it here and we'll take a look.

Paul
0
 
PaulCaswellCommented:
P.S.

      AX = function
          0000h toggle windowed mode (simulate Alt-Enter keypress)
            Return: nothing
          0001h get windowed mode
            Return: CF clear if VM is windowed
                  CF set if VM is full-screen

Remember to set ax to zero before the call.

Paul
0
 
GuruGaryAuthor Commented:
Thanks for the help Paul.  Here is what I have so far:

From your suggestion on how to set ES:DI= 0000:0000:
sub ax,ax
mov es,ax
mov di,ax

The rest of "get API entry point":
mov ax,1684
mov bx,7fe0
int 2f

Don't know how to make sure ES:DI is not NULL ... so cross my fingres and set set up for function 0:
mov ax,0000
int 2f

Exit:
mov ax,4c00
int 21

Do you think I am close?
0
 
PaulCaswellCommented:
Hi GuruGary,

It looks like it isnt going to work but here's the code anyway (as you'd type it into the debugger):

sub ax,ax
mov es,ax
mov di,ax
mov ax,1684
mov bx,7fe0
int 2f
# I stepped through to here and es and di were 0 so this will go bang. :-)
es:call [di]

Remember you can step through the code using the 'p' command.

It may work if you boot to a command prompt.

Paul
0
 
PaulCaswellCommented:
Hi GuruGary,

P.S.

sub ax,ax
mov es,ax
mov di,ax

can become:

sub di,di
mov es,di

Paul
0
 
PaulCaswellConnect With a Mentor Commented:
Hi GuruGary,

Have you seen this:

http://www.radiks.net/~jimbo/demented/altent.htm


Paul
0
 
GuruGaryAuthor Commented:
Hi, Paul.  Thanks for your help.  I tried the code, and you are right - it is not working.  It doesn't crash (at least no errors and nothing obvious), but it doesn't toggle between windowed and fullscreen mode.

I did see that link, but unfortunately I can't use C for this project.  It has to be pure assembly so I can create a .COM file from DEBUG.EXE (or something else I can do with out a compiler and just native Windows files / commands).  I'll keep searching on my end and let you know if I come up with something.  If you find something else, please let me know.
0
 
PaulCaswellCommented:
Hi GuruGary,

I'd definitely be interested.

I think the main problem is that when you are in a cmd window the DOS is emulated by Windows. In the emulation, a great deal of functionality is deliberately removed to make the system more secure against badly written code.

I suspect you would need to write some Win32 assembler. Sadly, I dont know any methods you can use to do this without a compiler and you will certainly have problems not using a linker.

I hope you find a way. :-)

Paul
0
 
Jose ParrotGraphics ExpertCommented:
Hi,

In the DOS era, it was simple to install TSRs, Terminate and Stay Resident programs. Such programs was intended to stay in memory after finishing.

What you are looking for is a TSR for the keyboard service in the Windows kernel. Humm... Windows doesn't permit it anymore. The DOS time goes on...

The only way is to write a device driver to a keyboard and install it under Windows management.
This, unfortunatelly, is not a few lines of assembly code.

Take a look at http://www.beyondlogic.org/dddtools/dddtools.htm to see a kit on this subject.

Jose
0
 
BrianGEFF719Connect With a Mentor Commented:
If your program is running under windows. This can be done much easier than embeding ASM code into your application. If you are running in windows consider making another program that runs your program via the CreateProcess() api in which you can specify how the program is opened eg (minimized, maximized, normal,centered, etc). If this is the case and you would like a C,C++ or Visual Basic example please let me know.,



Brian
0
 
Jose ParrotConnect With a Mentor Graphics ExpertCommented:
Hi,

My previous comment is applicable only if you want to be in the prompt and change the keyboard service at kernel level. Say, you open the "DOS" window and change its window or fullscreen mode. Right now I am understanding better what you want...

If what you want is *** YOUR APPLICATION *** to change from its own window to fullscreen and vice-versa, it is important to understand if yours is a CONSOLE application or a GUI Win32 application.

Seems it is a console application, so it doesn't have any control over the window (fullscreen console is just a window full size with no borders). On should think as we were in a IBMPC with DOS: there is no window, just a screen.

So, you need compile your console application as a GUI Windows application with no forms. Then you can call Windows to do what you are looking for, by calling:

WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    keybd_event(VK_MENU,0,0,0);                               <-- this "press" the Alt
    keybd_event(VK_RETURN,0,0,0);                            <-- this "press" Enter
    keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);      <-- then release the keys
    keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
}
Jose
0
 
GuruGaryAuthor Commented:
Sorry, guys - I guess I forgot about this for a while.  

My "program" or "application" is only a simple batch file running under a command prompt.  There are some cases where I may want a batch file to toggle the screen mode, or force a fullscreen mode.  Since it isn't a batch file, I don't want to rely on external programs or utilities that don't come with Windows.  The exception to this (and I think the solution) would be if I could use debug.exe and assembly commands to do this with either an int call, or simulating the Alt+Enter that would give the result.

So far, all the ways I have attempted to do this have not worked, and I expected it to be easier (sorry).  JoseParrot has an idea that I haven't tried.  I'll try to put some assembly code together to simulate holding down the Alt key, then pressing Enter, then releasing Alt.  So far, I have only tried the scancode to simulate the single scancode to simulate the keys pressed together.
0
 
GuruGaryAuthor Commented:
Well ... I never did find a solution that worked, but thanks for the help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.