Thread: C program, catching special keypresses.

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    4

    C program, catching special keypresses.

    Hi!
    I was hoping to get some help with a little C-program i'm working on atm.

    The program is supposed to do various tasks, such as: starting a program when i press a certain key combination.

    It is mean to be run in the background, but for now it works with a console-input thing.

    On to the point:
    I need to catch certain key combos when pressed.. such as: ctrl+alt+f1, ctrl+shift+l etc.

    I thought about using the GetAsyncKeyState function on ie. VK_CTRL, then if true move on to VK_SHIFT and VK_ALT, If one of those are true, then move on to checking ALL other keys... However, IMO that is a VERY ugly way of doing it..

    I read something about creating virtual keys, but i do not know how to implement it..


    here's the code if anyone cares :-)
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <process.h>
    
    #define MAX_ALIASES 10
    
    char *aliasnames[MAX_ALIASES];
    char *aliasstrings[MAX_ALIASES];
    int aliascount          = 0;
    
    
    const int EXEC          = 0;
    const int ECHO          = 1;
    const int ALIAS         = 2;
    const int ALIASES       = 3;
    char usage[][38] = 
    {
        "usage: exec <configfilename>",
        "usage: echo <text to print>",
        "usage: alias aliasname \"command\"",
        "usage: aliases (NO ARGUMENTS)"
    };
    
    
    const int FOPEN           = 0;
    const int FCLOSE          = 1;
    const int FWRITE          = 2;
    const int FREAD           = 3;
    const int MALLOC          = 4;
    const int CMD             = 5;
    const int ERRORREADCONFIG = 6;
    const int BAILOUT         = 7;
    const int UNKNOWNCOMMAND  = 8;
    const int NOALIASFOUND    = 9;
    char errors[][30] = 
    {
         "Error opening file",
         "Error closing file",
         "Error writing file",
         "Error reading file",
         "Error allocing memory",
         "Error parsing command",
         "Error reading config",
         "Bailing out!",
         "Unknown command!",
         "No array to clear!"
    };
    
    
    const int STARTUP           = 0;
    const int DONEREADCONFIG    = 1;
    const int CONFIGWRITTEN     = 2;
    char infos[][38] = 
    {
         "Starting up...!",
         "Done reading config",
         "A new configfile have been written",
    };
    
    
    const int NOCONFIGFOUND     = 0;
    const int QUITTING          = 1;
    char notifys[][138] = 
    {
         "There seems to be no configfile present in working directory\n[!] Attempting to write a new configfile\n",
         "Quitting!"
    };
    
    
    const char VERSION[] = "0.1";
    const char configfilename[] = "quickstart.cfg";
    const char defaultconfig[] = "#This is a comment!\n#This is also a comment!\necho Starting up...1!\necho Starting up...2!\necho Starting up...3!\necho DONE!!\n";
    
    
    
    int run_config();
    int configremake();
    int cmd(char*);
    int print_error(int);
    int print_usage(int);
    int print_info(int);
    int print_notify(int);
    
    int main(int argc, char *argv[])
    {
        int i;
        for(i=0;i<MAX_ALIASES;i++)
        {
            aliasnames[i]=NULL;
            aliasstrings[i]=NULL;
        }
        print_info(STARTUP);
        if(run_config(configfilename)==-1)
        {
            print_error(ERRORREADCONFIG);
            quit(-1);
        }
        print_info(DONEREADCONFIG);
        char input[128];
        while(1)
        {
            memset(input,0,sizeof(input));
            putchar('\n');
            putchar('|');
            fgets(input,sizeof(input)-1,stdin);
            input[strlen(input)-1] = '\x00';
            cmd(input);
        }
        
        return 0;
    }
    
    int configremake()
    {
        FILE *f;
        print_notify(NOCONFIGFOUND);
    
        if((f=fopen(configfilename,"w"))==NULL)
        {
            print_error(FOPEN);
            return -1;
        }
        if(fwrite(defaultconfig,1,strlen(defaultconfig),f)<strlen(defaultconfig))
        {
            print_error(FWRITE);
            return -1;
        }
        if(fclose(f)!=0)
        {
            print_error(FCLOSE);
            return -1;
        }
        print_info(CONFIGWRITTEN);
        
        return 1;
    }
    
    int run_config(char *cfg)
    {
        FILE *f;
        int s,cmdp=0,cmds=0,cmde=0;
        char *b, *t;
        if(cfg!=NULL)
        {
            f=fopen(cfg,"r");
        }
        else
        {
            f=fopen(configfilename,"r");
        }
        if(f==NULL)
        {
            print_error(FOPEN);
            if(cfg==NULL)
            {
                return configremake();
            }
            else
            {
                return -1;
            }
        }
        
        fseek(f,0,SEEK_END);
        
        if((s=ftell(f))<3)
        {
            if(fclose(f)!=0)
            {
                print_error(FCLOSE);
                if(cfg==NULL)
                {
                    return configremake();
                }
                else
                {
                    return 0;
                }
            }
        }
        
        rewind(f);
        if((b=(char*)malloc(s+1))==NULL)
        {
            print_error(MALLOC);
            return -1;
        }
        memset(b,'\x00',s+1);
        
        if(fread(b,1,s,f)==0)
        {
            print_error(FREAD);
            free(b);
            return -1;
        }
        
        t=(char*)strtok(b,"\n");
        
        while(t!=NULL)
        {
            if(t[0]!='#')
            {
                if(cmd(t)==-1)
                {
                    printf("&#37;s\n",CMD);
                    cmde++;
                }
                else
                {
                    cmdp++;
                }
            }
            else
            {
                cmds++;
            }
            t=(char*)strtok(NULL,"\n");
        }
        free(b);
        if(fclose(f)!=0)
        {
            print_error(FCLOSE);
            return -1;
        }
        return 0;
    }
    
    int cmd(char *tok)
    {
        int r;
        if(!strncmp(tok,"echo",4))
        {
            console_print(tok+4);
        }
        else if(!strcmp(tok,"quit"))
        {
             quit(0);
        }
        else if(!strcmp(tok,"exit"))
        {
             quit(0);
        }
        else if(!strncmp(tok,"exec",4))
        {
             config_exec(tok+4);
        }
        else if(!strncmp(tok,"aliases",7))
        {
             if(tok[7]=='\x00')
             {
                 print_aliases();
             }
             else
             {
                 print_usage(ALIASES);
             }
        }
        else if(!strncmp(tok,"alias",5))
        {
             if((tok[5]==' ')&&(tok[6]!='\x00'))
             {
                 new_alias(tok+6);
             }
             else
             {
                 print_usage(ALIAS);
             }
        }
        else if((r=alias_exist(tok))==-1)
        {
            print_error(UNKNOWNCOMMAND);
        }
        else
        {
            cmd(aliasstrings[r]);
        }
        
        return 0;
    }
    
    int print_aliases()
    {
        int i=0,f=0;
        putchar('\n');
        while((i<MAX_ALIASES)&&(f<aliascount))
        {
            if(aliasnames[i]!=NULL)
            {
                printf("%s = \"%s\"\n",aliasnames[i],aliasstrings[i]);
                f++;
            }
            i++;
        }
        return 0;
    }
    
    int new_alias(char *tok)
    {
        int i=0,k,j,l1,f,l=strlen(tok);
        while((tok[i]!=' ')&&(tok[i]!='\x00'))i++;
        
        char *b;
        b=(char*)malloc(i+1);
        if((tok[0]=='\"')||(tok[i-1]=='\"'))
        {
            if((tok[0]=='\"')&&(tok[i-1]=='\"'))
            {
    /*            for(k=1;k<i-2;k++)
                {
                    b[k-1]=tok[k];
                }
                b[k-1]='\x00';*/
                strncpy(b,tok+1,i-2);
                b[i-1]=0;
            }
            else
            {
                print_usage(ALIAS);
                return 0;
            }
        }
        else
        {
            strncpy(b,tok,i);
            b[i]=0;
        }
        f=alias_exist(b);
        if((tok[i]==' ')&&(tok[i+1]=='\"'))
        {
            if(tok[i+2]=='\"')
            {
                if(f!=-1)
                {
                    free(aliasnames[f]);
                    free(aliasstrings[f]);
                    aliasnames[f]=NULL;
                    aliasstrings[f]=NULL;
                }
                else
                {
                    print_error(NOALIASFOUND);
                }
            }
            i+=2;
            k=0;
            while((k<l-i)&&(tok[i+k]!='\"'))k++;
            if(tok[i+k]=='\"')
            {
                if(f!=-1)
                {
                    free(aliasstrings[f]);
                    aliasstrings[f]=(char*)malloc(k+1);
                    strncpy(aliasstrings[f],tok+i,k);
                    aliasstrings[f][k]='\x00';
                    printf("%s = \"%s\"\n",aliasnames[j],aliasstrings[j]);
                    return 0;
                }
                else
                {
                    j=0;
                    while(j<MAX_ALIASES)
                    {
                        if(aliasnames[j]==NULL)
                        {
                            aliasnames[j]=(char*)malloc(strlen(b)+1);
                            strcpy(aliasnames[j],b);
                            aliasnames[j][strlen(b)]='\x00';
                            free(b);
                            
                            aliasstrings[j]=(char*)malloc(k+1);
                            strncpy(aliasstrings[j],tok+i,k);
                            aliasstrings[j][k]='\x00';
                            
                            aliascount++;
                            
                            printf("%s = \"%s\"\n",aliasnames[j],aliasstrings[j]);
                            return 0;
                        }
                        j++;
                    }
                }
            }
        }
        else if(tok[i]=='\x00')
        {
            if(f!=-1)
            {
                printf("%s = \"%s\"\n",aliasnames[j],aliasstrings[j]);
                free(b);
                return 0;
            }
        }
    
        free(b);
        print_usage(ALIAS);
        return 0;
    }
    
    int alias_exist(char *b)
    {
        int i=0,f=0;
        while((i<MAX_ALIASES)&&(f<aliascount))
        {
            if(aliasnames[i]!=NULL)
            {
                if(!strcmp(b,aliasnames[i]))
                {
                    return i;
                }
                f++;
            }
            i++;
        }
        return -1;
    }
    
    int console_print(char *b)
    {
        if((b[0]!=' ')||(b[1]=='\x00'))
        {
            print_usage(ECHO);
        }
        else
        {
            printf("%s\n",b+1);
        }
    }
    
    int config_exec(char *b)
    {
        if((b[0]!=' ')||(b[1]=='\x00'))
        {
            print_usage(EXEC);
        }
        else
        {
            if(run_config(b+1)==-1)
            {
                print_error(ERRORREADCONFIG);
            }
            else
            {
                print_info(DONEREADCONFIG);
            }
        }
    }
    
    int print_error(int errnum)
    {
        printf("\n[-] %s\n",errors[errnum]);
        return 0;
    }
    
    int print_notify(int notifynum)
    {
        printf("\n[!] %s\n",notifys[notifynum]);
        return 0;
    }
    
    int print_info(int infonum)
    {
        printf("\n[+] %s\n",infos[infonum]);
        return 0;
    }
    
    int print_usage(int usagenum)
    {
        printf("\n[?] %s\n",usage[usagenum]);
        return 0;
    }
    
    int quit(int m)
    {
        if(!m)
        {
            print_notify(QUITTING);
        }
        else
        {
            print_error(BAILOUT);
        }
        system("pause");
        exit(0);
    }
    If you read the code you might want to know this: I plan on adding these possibilitys in cmd():
    run <path\to\program.exe>
    and
    bind key+key+key <code to be parsed by cmd on press>

    If there are some built in function that would just wait for a keypress, then return the key when a key is pressed... It would be GREAT!

    Any suggestions welcomed...(Suggestions other than the solution also appreciated as this code is not really tested alot, it most likely have some major flaws)

    Thanks.
    Last edited by naeo; 07-23-2007 at 12:16 AM.

  2. #2
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    RegisterHotKey() comes to mind. See MSDN.

    Use it with a bit of care... one of my image programs seems to use it instead of accelerator keys. So while that program is open, if I push Ctrl+C, V, or X, it gets the key press, regardless of what actually has focus. (Which is very annoying.) But if you let the user change the keys / don't map common key combos, its fine.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with a program, theres something in it for you
    By engstudent363 in forum C Programming
    Replies: 1
    Last Post: 02-29-2008, 01:41 PM
  2. Replies: 4
    Last Post: 02-21-2008, 10:39 AM
  3. catching keypresses
    By elmutt in forum Windows Programming
    Replies: 10
    Last Post: 08-01-2007, 09:24 AM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM