Programming with Qt creator and Cocoa ( copying the selected text from the current application) - c++

I would like to know if there is a way to use the Cocoa API in a Qt application.
I've already used the Windows API to get the selected text from the active application.
I'd like to do the same with mac os.
I tried to make a simple "hello world" application C++ with xCode, including the <Cocoa/Cocoa.h> but it didn't work as I excepted.
Is there a way to get this "hello word" application to build with Cocoa?
And, also If that is possible, can I get the selected text from the active windows with Cocoa API?
EDIT :
All right, so I successfully build something using Cocoa.h, thanks to this thread : How to mix Qt, C++ and Obj-C/Cocoa.
For the selection problem you could check out the answers I posted which tell you how to do it.

For those who could be interested : I found a way to get the current selected text.
Just by simulating cmd + c :
So thanks to this thread, I changed the code to obtain the "c" key which is represented by the integer 8 (Found in NSEvent.h), so here's the code :
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventRef saveCommandDown = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, YES);
CGEventSetFlags(saveCommandDown, kCGEventFlagMaskCommand);
CGEventRef saveCommandUp = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, NO);
CGEventPost(kCGAnnotatedSessionEventTap, saveCommandDown);
CGEventPost(kCGAnnotatedSessionEventTap, saveCommandUp);
CFRelease(saveCommandUp);
CFRelease(saveCommandDown);
CFRelease(source);
Now you just have to access the clipboard from Qt to get the selection. (If ask, I can put the code to do so)
Anyway, thanks to the stackoverflow community ;)

Related

Making a simple message box using C++/WinRT

I'm having trouble making a simple message dialog in C++/WinRT. Something as simple as "You clicked this: press ok to continue" nothing fancy. In the standard Windows API you can simply write MessageBox() and new popup will show up where you can click ok, and you can do somthing similiar in C++/CX with
auto messageDialog = ref new Windows::UI::Popups::MessageDialog("You clicked on the button!"); messageDialog->ShowAsync();
I've tried using IMessageDialog and ContentDialog classes with no success and can't seem to find a single example out there on how to do it without getting into writing Xaml code which for my perticular project seems unnecisary for something as simple as a message box. Maybe I'm just not setting them up right? But then again there are no examples on how to set it up in the first place (in C++). What am I missing?
Thanks!
I was able to form a simple message dialog using this:
winrt::hstring Title = L"Hello";
winrt::hstring Content = L"Some cool content!";
winrt::Windows::UI::Popups::MessageDialog dialog(Content, Title);
dialog.ShowAsync();
Make sure to also include <winrt/Windows.UI.Core.h> so you can get access to the UI library.
And here is the result:

Problem with Keypress simulation on Linux (Ubuntu 18)

I'm making a hobby project that is basically a bot for a very old flash game, the mouse move and click works fine, but all key presses make the operating system lag/stutter and sometimes stop listening to all keyboard inputs, real or fake.
I started using just XLib with XTests but didn't work, so I tried XSendEvent instead of XTests, but all symptoms stayed the same, so the last attempt was with XDO, which gave better results, but still freezes the OS.
this is the current snippet that I'm trying to use to simulate a keypress:
//Constructor
CheatCore::CheatCore() {
xdo_t x = xdo_new(NULL);
Window *list;
xdo_search_t search;
unsigned int nwindows;
memset(&search, 0, sizeof(xdo_search_t));
search.max_depth = -1;
search.require = xdo_search::SEARCH_ANY;
search.searchmask = SEARCH_CLASS | SEARCH_ONLYVISIBLE;
search.winclass = "Chrome";
int id = xdo_search_windows(x, &search, &list, &nwindows);
qDebug() << nwindows;
if(!nwindows){
qDebug() << "Chrome not found";
return;
}
w = list[0];
//I have to call activate twice to really bring it forward, I suspect that its
//because I use a transparent "overlay" that show stats for the cheat and it is set as Aways on top
//(i used Qt to set it to not get any Events)
xdo_activate_window(x,w);
xdo_activate_window(x,w);
}
//there is a function that executes every second to check if a pixel color has changed,
//if so, then the SendKey is called to Reload weapon magazine pressing the "space" key
void CheatCore::SendKey(){
xdo_activate_window(x,w);
xdo_activate_window(x,w);
xdo_send_keysequence_window(x, w, "space", 500);
}
I'm using a transparent overlay to show the bot status, with just some numbers appearing, it is a widget created using Qt that is AlwaysOnTop and the paint event draws the desired information's, it is another object and don't have direct impact in the CheatCore, but this is the window flags used to draw over a transparent window and ignore events.
setWindowFlags(Qt::WindowTransparentForInput | Qt::FramelessWindowHint |
Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
I didn't manage to understand what could be provoking this weird behavior, could it be the windowing system?
Also, I tried to find a Qt way of simulating mouse/keyboard inputs, but i didn't manage to find any solution to send events to other windows if there is a way possible of achieving this would be great!
The game i'm trying to automate is called "Storm the House"
If interested this is the link to the online repo : link
Can you help me make this work? Thank you!
Context about the setup:
Ubuntu 18.10 using VGA and Nvidia drivers (if it may influence the xserver)
Did you ever try to use xdotool from command line. To use xdotool you need to install package first.
To simualte a key press, you can use.
xdotool key <key>
For example if you want to simulate key press for X you can use this code
xdotool key x
Or any other combination like
xdotool key ctrl+f
Also you can replace key press with another one, for example if you want to replace pressing D with Backspace you can try this one
xdotool key D BackSpace
You can read complete guid online, also you can write script with this tool and use it in many different situations.
Also you can use it for remote connection too.
I hope this helps you with your little problem.
Using evdev is a linux specific option.
It's a simpler solution as you just need to open the correct file and write to it.
Take a look at this similar question to see how to get started.

Why do I need a QTranslator for localized button texts in a QMessageBox on Windows?

I'm developing a Qt application that runs on Linux and Windows. I'm on a German locale.
When building it on Linux, I get the correct translations for the standard buttons displayed by e. g. a QMessageBox::question with QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel buttons set ("Ja", "Nein" and "Abbrechen" in my case).
If I build the code on Windows however, I only get the C locale (English) texts for those buttons ("Yes", "No" and "Cancel").
After some searching, I found a globally working solution by adding
#include <QTranslator>
#include <QLibraryInfo>
and
QTranslator qtTranslator;
if (qtTranslator.load(QLocale::system(), QString::fromUtf8("qt"), QString::fromUtf8("_"),
QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
app.installTranslator(&qtTranslator);
}
to my main.cpp.
Using this, I also get the translated strings on Windows. On Linux however, the qtTranslator.load call fails and thus, nothing happens to the state I had before, so I ended up putting that code inside an #ifdef Q_OS_WIN block.
This works, but seems a bit hacky to me. Plus, I don't understand why I get the translated strings on Linux by default and not on Windows.
Is the way I do it the correct solution? And if so, why do I need that additional code on Windows?
Try to replace your code on this and tested.
static QTranslator qtTr;
qtTr.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
installTranslator(&qtTr);

Is there a Mac OSX version of windows GetFontData function?

We have an application that allows our users to generate print-ready PDF documents using variable data (names, titles, phone numbers, etc) that their customer's enter via an online e-commerce website. To facilitate the variable data we have to embed a font's entire character map. On windows we have been using the windows API function GetFontData(...) like so:
#ifdef Q_WS_WIN
//this is windows specific code
HDC DC = CreateCompatibleDC(NULL);
HFONT hFont = font.handle();
HFONT oFont=(HFONT)SelectObject(DC,hFont);
DWORD fontLength = ::GetFontData(DC, 0, 0, 0, 0);
if(fontLength != GDI_ERROR)
{
fontData.GrowAllocation(fontLength);
if(::GetFontData(DC, 0, 0, fontData.GetBuffer(), fontLength) == GDI_ERROR)
{
fontData.Clear();
}
else
{
fontData.SetLength(fontLength);
returnVal = true;
}
}
SelectObject(DC,oFont);
DeleteDC(DC);
//End of windows specific code
#elif defined(Q_WS_MAC)
#endif
This technique works very successfully on our windows specific version; however, we are porting the application to Qt to target the Mac OSX platform.
My first question: Is there a Qt way of accessing the raw font data from a QFont, QFontDatabase, etc. that we could use to embed in the pdf? We have been unable to find a way. Notice the #ifdef wrapper in the above code. Note that the variable fontData is a self contained memory buffer that manages its own memory, please disregard.
My second question: If there is no Qt way of accessing the font data in an OS agnostic way, what is the OSX equivalent to the windows GetFontData?
Thanks
I've only skimmed documentation for GetFontData, and I don't know much about Qt (though it does sound like a Qt solution would be preferable), but you might want to look at the ObjC class for fonts, NSFont.
The latest (until Apple hires new font people and gets infected with not-invented-here disease again) text and font API is Core Text. I never used it since chasing Apple's mood is harmful to my personal and organization's financial health, I stopped using any Apple-only API. :)
Kidding aside, it looks like CTFont does provide access to all tables in a font. I don't see anything that prepares a font for embedding but this probably gives you the best chance.

Loading Nib and Displaying Window in Objective C++

I am trying to load a Nib from a C++ constructor with Objective C++. I have searched and found enough examples to get some code together but it doesn't display the window. Or any windows for that matter.
Here is an example of the contructor:
JokeSystem::JokeSystem() : fileSystem("/Library/Application Support/Jokes/")
{
try
{
randSystem = new RandSelect<std::string>
(fileSystem.getAllFileContents("%\n"));
}
catch (std::ifstream::failure)
{
NSWindowController * errorWindowControl = [[NSWindowController alloc]
initWithWindowNibName:#"ErrorWindow"];
[errorWindowControl showWindow: nil];
}
}
The purpose of the contructor is to load the contents of a directory into a string. What I am try to do is display the error window when the files fail to open.
ErrorWindow.nib has a single window with an OK button and a NSTextView for the error, I set up a NSWindowController in the nib and connected it to the window.
My only link has been that most examples show this [errorWindowControl showWindow: self];
rather than showWindow: nil but because this is a C++ constructor I it doesn't have self and this doesn't work.
If it matters this contructor is called from the awakeFromNib method of the MainMenu.nib's primary NSObject.
Thanks
A bit of an odd way to approach Cocoa. I would encourage you to step back, learn Objective-C and then write your application with an Objective-C based Cocoa UI layer on top of whatever backing store or model layer you have.
In any case, there isn't anything particularly wrong with that code (save for the odd design).
The first thing to check is the return value of -initWithWindowNibName:. Is errorWindowControl actually non-nil? If it is nil, then the NIB failed to load.
How are you writing the Cocoa application itself? Standard app bundle using Xcode, I hope?
Also, you shouldn't be hardcoding the path to /Library/Application Support/. Actually, your application shouldn't use that directory as the only storage location; many users won't have write access to that directory and won't be able to install your app without administrator access.