-1

I've made a pretty simple program that automatically opens my webex links after i select which lesson i currently have. It then positions the cursor to the exact location so i can "press join meeting". However i don't know how i can integrate an automated click into my program so i don't manually have to click (left button). How can i do that? Do you also have any recommendations to make my code cleaner? Any answers are appreciated! PS: ive replaced the links and teachers' names

#include <stdio.h>
 #include <winuser.h>
 
 int main(){
     int number;
     
printf("1. first lesson \n2. second lesson \n3. third lesson \n4. fourth lesson\n5. fifth lesson\n6. sixth lesson\n7. seventh lesson \n8. eighth lesson\n9. neinth lesson\n10. tenth lesson\n11. eleventh lesson \n12. twelveth lesson \n13. thirteenth lesson\n Please enter a number: ");
scanf("%d",&number);

 int ptx=1100;
  int pty=980;

  if (number==1)
  {
     
     system("start link1");
     SetCursorPos(ptx, pty);
  }
else if (number==2)
{
   system ("start link2 ");
   SetCursorPos(ptx, pty);
  
}
else if (number==3)
{
   system ("start link3 ");
   SetCursorPos(ptx, pty);
}
else if (number==4)
{
    system ("start link4");
    SetCursorPos(ptx, pty);
}
else if (number==5)
{
    system ("start link5");
    SetCursorPos(ptx, pty);
}
else if (number==6)
{
   system ("start link6");
   SetCursorPos(ptx, pty);
}
else if (number==7)
{
  system ("start  link7 ");
  SetCursorPos(ptx, pty);
}
else if (number==8)
{ 
   system ("start link8");
   SetCursorPos(ptx, pty);
}
else if (number==9)
{
     system ("start link9");
     SetCursorPos(ptx, pty);
}
else if (number==10)
{
     system ("start link10");
     SetCursorPos(ptx, pty);
} 
else if (number==11)
{
    system ("start  link11");
    SetCursorPos(ptx, pty);
}
else if (number==12)
{
    system ("start  link12");
    SetCursorPos(ptx, pty);
    
}
else if (number==13)
{
     system ("start link13");
     SetCursorPos(ptx, pty);
}
else
{
    printf("Invalid number.Please try again.");
}
 }
dialer
  • 4,348
  • 6
  • 33
  • 56
Kent
  • 25
  • 5
  • You cannot input a click in standard C. Check by reading [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). You could be interested by libraries like [GTK](https://gtk.org/). You want to use a `switch` statement, see [this C reference](https://en.cppreference.com/w/c) – Basile Starynkevitch Mar 02 '21 at 11:55
  • You want to look up the SendInput function – user253751 Mar 02 '21 at 12:07
  • 1
    @BasileStarynkevitch you also can't set the cursor pos in standard C, good thing this is windows where you can! – user253751 Mar 02 '21 at 12:07
  • The technology to automate a UI in Windows goes by the name [UI Automation](https://learn.microsoft.com/en-us/windows/win32/winauto/entry-uiauto-win32). – IInspectable Mar 02 '21 at 12:57
  • @panoskent, I have seen that you have been accepting and unaccepting my answer a couple of times in the last few hours. Please, have read [here](https://stackoverflow.com/help/someone-answers) when you can. Also, if you want some clarifications or further explanations, outside of the scope of your current question, consider asking another question. – BiOS Mar 06 '21 at 08:19
  • @BiOS yeah ..im new to this site and i wasn't aware of what the button did ..I found out though. Thanks! – Kent Mar 06 '21 at 14:54

3 Answers3

3

As you have included winuser.h I assume Windows is the target of your project, thus you could use the Windows API to simulate clicks, which will allow you to use one method, i.e. SendInput, to not only perform the click but to also set the screen coordinate at which you would like the click to occur, thus you won't need two separate functions to set the cursor position and to actually perform the click.

Of course, this solution is a Windows-only compatible one.

Also, it is a good idea that you wrap up your if / else if statements into a switch statement, to have it look cleaner.

#include <stdio.h>
#include <windows.h>

void sendClick(int ptx, int pty)
{
    //Initializing an array of INPUT 
    INPUT Inputs[3] = { 0 };

    //You need the two lines below in order to convert from screen to absolute coordinates
    ptx = MulDiv(ptx, 65535, GetSystemMetrics(SM_CXSCREEN)-1);
    pty = MulDiv(pty, 65535, GetSystemMetrics(SM_CYSCREEN)-1);

    Inputs[0].type = INPUT_MOUSE;
    Inputs[0].mi.dx = ptx; //Your click coordinates (x)
    Inputs[0].mi.dy = pty; //Your click coordinates (y)
    Inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE; //Moving mouse to position

    Inputs[1].type = INPUT_MOUSE;
    Inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; //Left clicking

    Inputs[2].type = INPUT_MOUSE;
    Inputs[2].mi.dwFlags = MOUSEEVENTF_LEFTUP; //Releasing click

    //Sending the inputs
    SendInput(3, Inputs, sizeof(INPUT));
}

int main()
{
    int number;

    printf("1. first lesson \n2. second lesson \n3. third lesson \n4. fourth lesson\n5. fifth lesson\n6. sixth lesson\n7. seventh lesson \n8. eighth lesson\n9. neinth lesson\n10. tenth lesson\n11. eleventh lesson \n12. twelveth lesson \n13. thirteenth lesson\n Please enter a number: ");
    scanf("%d", &number);

    int ptx = 1100;
    int pty = 980;

    switch (number)
    {
    case 1 : system("start link1");
        sendClick(ptx, pty);
        break;
    case 2:
        system("start link2 ");
        sendClick(ptx, pty);
        break;
    case 3:
        system("start link3 ");
        sendClick(ptx, pty);
        break;
    case 4:
        system("start link4");
        sendClick(ptx, pty);
        break;
    case 5:
        system("start link5");
        sendClick(ptx, pty);
        break;
    case 6:
        system("start link6");
        sendClick(ptx, pty);
        break;
    case 7:
        system("start  link7 ");
        sendClick(ptx, pty);
        break;
    case 8:
        system("start link8");
        sendClick(ptx, pty);
        break;
    case 9:
        system("start link9");
        sendClick(ptx, pty);
        break;
    case 10:
        system("start link10");
        sendClick(ptx, pty);
        break;
    case 11:
        system("start  link11");
        sendClick(ptx, pty);
        break;
    case 12:
        system("start  link12");
        sendClick(ptx, pty);
        break;
    case 13:
        system("start link13");
        sendClick(ptx, pty);
        break;
    default:
        printf("Invalid number.Please try again.");
        break;
    }
}

Disclaimer: Note how the sendClick() function performs the operation below:

ptx = MulDiv(ptx, 65535, GetSystemMetrics(SM_CXSCREEN)-1);
pty = MulDiv(pty, 65535, GetSystemMetrics(SM_CYSCREEN)-1);

This is done in order to convert the coordinates of your buttons, which you presumably have as screen-coordinates, i.e. the coordinates relative to your screen size. (For a 1920x1080 screen, the bottom right corner would be x = 1919 and y = 1079).

However, if in the future you would like to input absolute normalized coordinates yourself (expressed as relative figure, from 0 to 65535, for both x and y axes), just comment out the above mentioned lines.

You can read more about Windows Coordinates System here.

BiOS
  • 2,282
  • 3
  • 10
  • 24
  • OP asked for `C`, this solution is only valid for Windows. – Adrian Maire Mar 02 '21 at 12:37
  • 3
    OP has `#include `, he needs a windows based solution. I have however mentioned that in my answer just to make sure that anybody is aware of that. Thanks for pointing out – BiOS Mar 02 '21 at 12:38
  • Maybe it's better to suggest him an alternative to that header/SetCursorPos too. – Adrian Maire Mar 02 '21 at 12:42
  • 1
    @AdrianMaire, I am sure you're pointing this out for the benefit of the readers, but now that the post has been edited with the `winapi` tag we can be sure that OP is looking for a Windows only solution. I see that related questions on other OS are already available on stackoverflow, and maybe adding some cross-platform solutions would only be confusing, what do you think? I have however followed your piece of advice and edited my answer with a disclaimer for mine to be a Windows only solution, as you suggested, thanks! – BiOS Mar 02 '21 at 12:53
-1

I ended up with this code. So basically im not only opening a webex link and joning but i also wanted to close the chrome tab.And thats exactly what i did.

     #include <stdio.h>
 #include <winuser.h>
#include <unistd.h>
 #include <stdlib.h>
 
 int main(){
     int number;
     
printf("1. Lesson1 \n2. Lesson2\n3. Lesson3\n4. Lesson4\n5. Lesson5\n6. Lesson6\n7. lesson7\n8. Lesson8\n9. Lesson9\n10. Lesson10 \n11. Lesson11\n12. Lesson12\n13. Lesson13\n Please enter a number: ");
scanf("%d",&number);

 int ptx=1100;
  int pty=980;
  int ptx2=-20;
  int pty2=10;


  switch (number)
  {
     case 1:
     system("start link1");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 2: 
     system ("start link2");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 3: 
     system ("start link3");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 4:
      system ("start link4");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;
     
     case 5: 
     system ("start link5");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 6: 
     system ("start link6");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 7: 
     system ("start  link7 ");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 8: 
     system ("start link8");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 9:
     system ("start link9");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 10:
     system ("start link10");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 11:
     system ("start link11");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 12: 
     system ("start  link12");
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;

     case 13:
     system ("start link13);
     SetCursorPos(ptx, pty);
     sleep(6);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     sleep(1);
     SetCursorPos(ptx2, pty2);
     mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
     mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
     break;
    
     default: 
     printf("Invalid number.Please try again.");
     break;
  }
 } 



 
   
Kent
  • 25
  • 5
  • 1
    This code doesn't compile. If it did, it would be wrong for more reasons than I can fit in a comment. The documentation for [mouse_event](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mouse_event) explains that you shouldn't be using `mouse_event`. There is no function `sleep` in C, C++, or the Windows API. If there was it would only increase the chance for unwanted user input. Plus, as pointed out in another comment, the *real* solution to the problem you are trying to solve is [UI Automation](https://docs.microsoft.com/en-us/windows/win32/winauto/entry-uiauto-win32). – IInspectable Mar 04 '21 at 04:23
  • Hello! It works for me, i compile and run it perfectly with no problems. – Kent Mar 04 '21 at 06:58
  • `system ("start link13);` isn't valid C or C++ code. It will not compile. That can easily be fixed, unlike your decision to use the wrong approach altogether. That's much harder to fix. – IInspectable Mar 04 '21 at 07:00
  • i know using system() function should be avoided because it's not portable for multiple Operating Systems but since im using windows and that's a quickie project i dont find the reason why not to use it.Furthermore i included stdlib.h and it should be compiled from now on. – Kent Mar 04 '21 at 07:25
  • It's probably because i've replaced the actual links with link1-13. i can send you the actual code on a social platform since i dont want to leak any links:P – Kent Mar 04 '21 at 07:43
  • No. It doesn't compile because it's not valid C code. As literally spelled out in [this comment](https://stackoverflow.com/questions/66438808/how-to-input-a-click-in-c/66461893?noredirect=1#comment117508895_66461893) already. – IInspectable Mar 04 '21 at 07:56
-2

C does not include "clicks" as it is a generic language intended for platforms that might not have GUI or mouse (e.g. embedded, OS development, etc.).

The click is provided by the OS, through a driver to manage the mouse itself (and probably the USB port), and also a number of other systems: Graphical desktop, mouse settings, etc.

Consequently, each OS provides it own API to access mouse functionalities.

Fortunately, and because any good software cares about the freedom of it users (and freedom of it own developers/company), some libraries implement an abstraction layer over the OS, making mostly trivial to develop applications that works on Linux, Windows, MacOS, Solaris, etc, etc...

For pure C, you can user GTK (Simulate button click using GTK+ using gtk_event_put and a GdkEventButton structure)

Or with C++, using Qt (which I suggest because pur-C projects tend to disappear).

Adrian Maire
  • 14,354
  • 9
  • 45
  • 85
  • Actually he was not requesting `Windows` when I wrote the answer, and `winapi` was not added by the OP itself. Good practices are good practices, even if the snippet include an `windows.h` header. – Adrian Maire Mar 02 '21 at 18:23
  • 1
    Thank you for your replies!!! I really didn't specify that im working on windows. Thinking to switch to c++ for the time being. – Kent Mar 02 '21 at 18:38
  • @AdrianMaire Good practice is to not add several megabytes of library just because you want to set the cursor position, when there is a perfectly good function in your operating system already. – user253751 Mar 02 '21 at 23:39
  • On my OS, QT is included as part of the default install, thus, no additional "megabytes" library to add (all depends the POV right?). What is not fair is that for they monopoly games, Microsoft do not follow standards (POSIX or similar) with a huge negative impact for us (software engineers and software companies). Usually, few MBs library is not a big issue for desktops with TBs of storage and tens of GBs of RAM. You can always build a minimal Qt within few KBs if needed. – Adrian Maire Mar 03 '21 at 07:34
  • 1
    The fact that *you* have a library installed on your system is quite meaningless to a client of your code. Unless you are willing to send your computer along. It's an economically questionable approach to have to send a computer along with the software you are trying to distribute. So yes, if you want to ship software only, you **are** going to take a dependency, that doesn't just weigh in with disk space. Your installer gets more complex. Your build system gets more complex. Your test infrastructure gets more complex. And your application has more complex error modes. – IInspectable Mar 03 '21 at 13:53
  • @IInspectable: please read before to answer. (I said Qt is included as part of the default install, aka KDE desktop). That changes your POV right? Or are you suggesting to send me your Windows machine? – Adrian Maire Mar 03 '21 at 14:04
  • 3
    The question is clearly about Windows, and was easily identifiable as such from revision 1. There is no Windows SKU that comes with Qt preinstalled. In context of this question Qt is a sizeable dependency. In context of your setup, Qt is a multiplier for complexity *and* a sizeable dependency. – IInspectable Mar 03 '21 at 14:24