Attaching button to existing application (AutoIT) - parent-child

I have an existing .exe program (not mine so I can't edit it) that runs in a window of static size. What I want to do is overlay an extra button (preferably an image in the same style) on top of this window at specific coordinates within that window (and it has to move with the window if dragged elsewhere) to expand on it's functionality.
How do I go about this? I have searched for quite a bit, but wasn't able to find anything. I was able to create a Parent-Child in AutoIT itself, but cannot seem to attach a child to an existing application.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
; NotepadAddOn
ShellExecute('notepad')
WinWaitActive("[CLASS:Notepad]", "")
$pos_A = WinGetPos("[CLASS:Notepad]", "")
$hGui = GUICreate('YOUR GUI', $pos_A[2], 50, $pos_A[0], $pos_A[1] - 50)
GUISetState(#SW_SHOW) ; will display an empty dialog box
AdlibRegister('_WinMove', 10)
; Run the GUI until the dialog is closed
While 1
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
GUIDelete()
Func _WinMove()
$p_A = WinGetPos("[CLASS:Notepad]", "")
WinMove($hGui, "", $p_A[0], $p_A[1] + $p_A[3])
EndFunc ;==>_WinMove

Related

what is the best way to show tile map and some other object in graphicsview?

recently i start to learn Qt and now i'm working on GCS project that it must have a map with some tiled imges and and some graphics item like Plan,the path and also on over off all some gauge.
so we have 3 kind of item:
Tiled map in the background so that its change by scrolling .
in the middle there is a picture of airplane that move by gps changes and also its way .
on the all on off these items there 3 or 4 gauge like speed meter, horizontal gauge and altimeter gauge there are must be solid in somewhere of graphicsview and not change when scrolling down/up or left right
The question is what is the best way to implement this ?
here is first look of my project:
in first look gauge are not over map but i want to be ! i want to have bigger map screen with gauges include it !
And here is map updater code :
void mainMap::update()
{
m_scene->clear();
QString TilePathTemp;
QImage *imageTemp = new QImage();
int X_Start=visibleRect().topLeft().x()/256;
int X_Num=qCeil((float)visibleRect().bottomRight().x()/256.0f-(float)visibleRect().topLeft().x()/256.0f);
int Y_Start=visibleRect().topLeft().y()/256;
int Y_Num=qCeil((float)visibleRect().bottomRight().y()/256.0f-(float)visibleRect().topLeft().y()/256.0f);
LastCenterPoint->setX(visibleRect().center().x());
LastCenterPoint->setY(visibleRect().center().y());
X_Start=(X_Start-X_MAP_MARGIN)>0?(X_Start-X_MAP_MARGIN):0;
Y_Start=(Y_Start-Y_MAP_MARGIN)>0?(Y_Start-Y_MAP_MARGIN):0;
X_Num+=X_MAP_MARGIN;
Y_Num+=Y_MAP_MARGIN;
qDebug()<<"XS:"<<X_Start<<" Num:"<<X_Num;
qDebug()<<"YS:"<<Y_Start<<" Num:"<<Y_Num;
for(int x=X_Start;x<=X_Start+X_Num;x++){
for(int y=Y_Start;y<=Y_Start+Y_Num;y++){
if(Setting->value("MapType",gis::Hybrid).toInt()==gis::Hybrid) TilePathTemp=Setting->value("MapPath","/Users/M410/Documents/Map").toString()+"/Hybrid/gh_"+QString::number(x)+"_"+QString::number(y)+"_"+QString::number(ZoomLevel)+".jpeg" ;
else if(Setting->value("MapType",gis::Sattelite).toInt()==gis::Sattelite) TilePathTemp=Setting->value("MapPath","/Users/M410/Documents/Map").toString()+"/Sattelite/gs_"+QString::number(x)+"_"+QString::number(y)+"_"+QString::number(ZoomLevel)+".jpeg" ;
else if(Setting->value("MapType",gis::Street).toInt()==gis::Street) TilePathTemp=Setting->value("MapPath","/Users/M410/Documents/Map").toString()+"/Street/gm_"+QString::number(x)+"_"+QString::number(y)+"_"+QString::number(ZoomLevel)+".jpeg" ;
QFileInfo check_file(TilePathTemp);
// check if file exists and if yes: Is it really a file and no directory?
if (check_file.exists() && check_file.isFile()) {
// qDebug()<<"Exist!";
imageTemp->load(TilePathTemp);
QPixmap srcImage = QPixmap::fromImage(*imageTemp);
//QPixmap srcImage("qrc:/Map/File1.jpeg");
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(srcImage);
item->setPos(QPointF(x*256, y*256));
m_scene->addItem(item);
// centerOn( width() / 2.0f , height() / 2.0f );
} else {
qDebug()<<"NOT Exist!";
}
}
}
Really, you should consider using QML. The advantage of using QML instead of QGraphicsView is you can iterate a lot faster than if you were working directly in C++. The primary downside is generally increased memory usage and incompatibility with QWidgets.
So if you need unique graphics, and very little "standard widget" stuff, you should use QML first and then QGraphicsView ONLY IF requirements dictate it.
Specific to your project though, Qt has a Map type which could be useful: https://doc.qt.io/qt-5/qml-qtlocation-map.html

Refresh and execute a program in Autoit

I want to make a program in autoit with a GUI - 2 buttons: the first button must refresh a web page (Ex: Google page) every 3 seconds, the second button must stop the refresh and do some operations on the web page. I'm ok with the first button, but I cannot exit from the loop with the second button and execute the operation I want. Can someone help me? Thanks a lot! This is the code:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
$Form1 = GUICreate("Example", 190, 133, 192, 124)
GUISetBkColor(0xFFFF00)
$Button1 = GUICtrlCreateButton("UPDATE", 3, 31 ,179, 37, 0)
$Button2 = GUICtrlCreateButton("EXECUTE", 3, 80 ,179, 37, 0)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlSetBkColor(-1, 0x00FF00)
GUICtrlSetCursor (-1, 0)
GUICtrlSetColor(-1, 0x000000)
GUISetState(#SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $button1
HotKeySet("{x}", "_Exit") ; Sets a shortcut to kill the script quickly. ESC
Opt("WinTitleMatchMode", 3) ; This is to tell the script to only refresh the EXACT window, incase there are similar windows. Such as: Window 1, Window 2.
While 1 ; This begins a While LOOP
Sleep(3000) ; Tell the script to pause for 3 seconds
$title = WinGetTitle("Google - Mozilla Firefox", "") ; Grabs the exactly title and saves it to a variable to do an If statement against.
If WinExists($title) Then ; Check to see if the desired window is running.
WinActivate($title) ; If it is running, first activate the window.
WinWaitActive($title) ; This tells the script to not send the refresh key (F5) until the window has appeared.
Send("{F5}") ; This sends the F5 key to refresh the window.
Else ; This is an else statement to tell the script to do a different operation if the window is not running.
Sleep(10) ; Just a filler item to wait until the desired window is running.
EndIf ; End the If statement to continue the script.
WEnd ; Close the While LOOP
Func _Exit() ; This is the function that is linked to the kill switch, ESC. It tells the script to perform the following actions.
ExitLoop ; Block pressing "x"
EndFunc ; Close the function up.
Case $button2
ExitLoop ; stop the loop and make operations below
Send("{TAB}")
Send("^v")
EndSwitch
WEnd
Something like this?
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
Global $Go2 = True
$Form1 = GUICreate("Example", 190, 133, 192, 124)
GUISetBkColor(0xFFFF00)
$Button1 = GUICtrlCreateButton("UPDATE", 3, 31, 179, 37, 0)
$Button2 = GUICtrlCreateButton("EXECUTE", 3, 80, 179, 37, 0)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlSetBkColor(-1, 0x00FF00)
GUICtrlSetCursor(-1, 0)
GUICtrlSetColor(-1, 0x000000)
GUISetState(#SW_SHOW)
Local $hTimer = TimerInit()
While True
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
$Go2 = True
HotKeySet("!{e}", "_Exit") ; Sets a shortcut to kill the script quickly. ESC
HotKeySet("{s}", "_ExitLoop") ; Sets a shortcut to kill the script quickly. ESC
Opt("WinTitleMatchMode", 3) ; This is to tell the script to only refresh the EXACT window, incase there are similar windows. Such as: Window 1, Window 2.
While $Go2 ; Avoid getting stuck in the while loop forever
If TimerDiff($hTimer) > 3000 Then
ConsoleWrite("Refreshing Mozilla" & #LF)
$title = WinGetTitle("Google - Mozilla Firefox", "") ; Grabs the exactly title and saves it to a variable to do an If statement against.
If WinExists($title) Then ; Check to see if the desired window is running.
WinActivate($title) ; If it is running, first activate the window.
WinWaitActive($title) ; This tells the script to not send the refresh key (F5) until the window has appeared.
Send("{F5}") ; This sends the F5 key to refresh the window.
$hTimer = TimerInit()
HotKeySet("{x}")
Else ; This is an else statement to tell the script to do a different operation if the window is not running.
;~ Sleep(10) ; Just a filler item to wait until the desired window is running.
EndIf ; End the If statement to continue the script.
EndIf
WEnd
$hTimer = TimerInit()
HotKeySet("{x}") ; Release hotkey
HotKeySet("!{e}") ; Release hotkeys
ConsoleWrite("Exited loop" & #LF)
Case $Button2
;you can't exit the loop from the $button1 here but there is a hotkey set to exit it, ALT + E
Send("{TAB}")
Send("^v")
EndSwitch
WEnd
Exit
Func _Exit()
Exit
EndFunc ;==>_Exit
Func _ExitLoop()
$Go2 = Not $Go2
EndFunc
P.S. I avoid using sleep because it pauses the script.
This is how I would do it.
Local $Refresh = 0 ; Set refresh OFF
Local $Timer = TimerInit()
Local $RefreshEvery = 3 ; seconds
Do
$msg = GUIGetMsg()
Select
Case $msg = $BtnRefresh
$Refresh = 1 ; Set refresh ON
Case $msg = $btnStop
$Refresh = 0 ; Set refresh OFF
EndSelect
If $Refresh And (TimerDiff($Timer) > $RefreshEvery*1000) Then
RefreshBrowser()
$Timer = TimerInit()
EndIf
Until $msg = $GUI_EVENT_CLOSE

QTextEdit and cursor interaction

I'm modifying the Qt 5 Terminal example and use a QTextEdit window as a terminal console. I've encountered several problems.
Qt does a strange interpretation of carriage return ('\r') in incoming strings. Ocassionally, efter 3-7 sends, it interprets ('\r') as new line ('\n'), most annoying. When I finally found out I choose to filter out all '\r' from the incoming data.
Is this behaviour due to some setting?
Getting the cursor interaction to work properly is a bit problematic. I want the console to have autoscroll selectable via a checkbox. I also want it to be possible to select text whenever the console is running, without losing the selection when new data is coming.
Here is my current prinout function, that is a slot connected to a signal emitted as soon as any data has arrived:
void MainWindow::printSerialString(QString& toPrint)
{
static int cursPos=0;
//Set the cursorpos to the position from last printout
QTextCursor c = ui->textEdit_console->textCursor();
c.setPosition(cursPos);
ui->textEdit_console->setTextCursor( c );
ui->textEdit_console->insertPlainText(toPrint);
qDebug()<<"Cursor: " << ui->textEdit_console->textCursor().position();
//Save the old cursorposition, so the user doesn't change it
cursPos= ui->textEdit_console->textCursor().position();
toPrint.clear();
}
I had the problem that if the user clicked around in the console, the cursor would change position and the following incoming data would end up in the wrong place. Issues:
If a section is marked by the user, the marking would get lost when new data is coming.
When "forcing" the pointer like this, it gets a rather ugly autoscroll behaviour that isn't possible to disable.
If the cursor is changed by another part of the program between to printouts, I also have to record that somehow.
The append function which sound like a more logical solution, works fine for appending a whole complete string but displays an erratic behaviour when printing just parts of an incoming string, putting characters and new lines everywhere.
I haven't found a single setting regarding this but there should be one? Setting QTextEdit to "readOnly" doesn't disable the cursor interaction.
3.An idea is to have two cursors in the console. One invisible that is used for printouts and that is not possible at all to manipulate for the user, and one visible which enables the user to select text. But how to do that beats me :) Any related example, FAQ or guide are very appreciated.
I've done a QTextEdit based terminal for SWI-Prolog, pqConsole, with some features, like ANSI coloring sequences (subset) decoding, command history management, multiple insertion points, completion, hinting...
It runs a nonblocking user interface while serving a modal REPL (Read/Eval/Print/Loop), the most common interface for interpreted languages, like Prolog is.
The code it's complicated by the threading issues (on user request, it's possible to have multiple consoles, or multiple threads interacting on the main), but the core it's rather simple. I just keep track of the insertion point(s), and allow the cursor moving around, disabling editing when in output area.
pqConsole it's a shared object (I like such kind of code reuse), but for deployment, a stand-alone program swipl-win is more handy.
Here some selected snippets, the status variables used to control output are promptPosition and fixedPosition.
/** display different cursor where editing available
*/
void ConsoleEdit::onCursorPositionChanged() {
QTextCursor c = textCursor();
set_cursor_tip(c);
if (fixedPosition > c.position()) {
viewport()->setCursor(Qt::OpenHandCursor);
set_editable(false);
clickable_message_line(c, true);
} else {
set_editable(true);
viewport()->setCursor(Qt::IBeamCursor);
}
if (pmatched.size()) {
pmatched.format_both(c);
pmatched = ParenMatching::range();
}
ParenMatching pm(c);
if (pm)
(pmatched = pm.positions).format_both(c, pmatched.bold());
}
/** strict control on keyboard events required
*/
void ConsoleEdit::keyPressEvent(QKeyEvent *event) {
using namespace Qt;
...
bool accept = true, ret = false, down = true, editable = (cp >= fixedPosition);
QString cmd;
switch (k) {
case Key_Space:
if (!on_completion && ctrl && editable) {
compinit2(c);
return;
}
accept = editable;
break;
case Key_Tab:
if (ctrl) {
event->ignore(); // otherwise tab control get lost !
return;
}
if (!on_completion && !ctrl && editable) {
compinit(c);
return;
}
break;
case Key_Backtab:
// otherwise tab control get lost !
event->ignore();
return;
case Key_Home:
if (!ctrl && cp > fixedPosition) {
c.setPosition(fixedPosition, (event->modifiers() & SHIFT) ? c.KeepAnchor : c.MoveAnchor);
setTextCursor(c);
return;
}
case Key_End:
case Key_Left:
case Key_Right:
case Key_PageUp:
case Key_PageDown:
break;
}
you can see that most complexity goes in keyboard management...
/** \brief send text to output
*
* Decode ANSI terminal sequences, to output coloured text.
* Colours encoding are (approx) derived from swipl console.
*/
void ConsoleEdit::user_output(QString text) {
#if defined(Q_OS_WIN)
text.replace("\r\n", "\n");
#endif
QTextCursor c = textCursor();
if (status == wait_input)
c.setPosition(promptPosition);
else {
promptPosition = c.position(); // save for later
c.movePosition(QTextCursor::End);
}
auto instext = [&](QString text) {
c.insertText(text, output_text_fmt);
// Jan requested extension: put messages *above* the prompt location
if (status == wait_input) {
int ltext = text.length();
promptPosition += ltext;
fixedPosition += ltext;
ensureCursorVisible();
}
};
// filter and apply (some) ANSI sequence
int pos = text.indexOf('\x1B');
if (pos >= 0) {
int left = 0;
...
instext(text.mid(pos));
}
else
instext(text);
linkto_message_source();
}
I think you should not use a static variable (like that appearing in your code), but rely instead on QTextCursor interface and some status variable, like I do.
Generally, using a QTextEdit for a feature-rich terminal widget seems to be a bad idea. You'll need to properly handle escape sequences such as cursor movements and color mode settings, somehow stick the edit to the top-left corner of current terminal "page", etc. A better solution could be to inherit QScrollArea and implement all the needed painting–selection-scrolling features yourself.
As a temporary workaround for some of your problems I can suggest using ui->textEdit_console->append(toPrint) instead of insertPlainText(toPrint).
To automatically scroll the edit you can move the cursor to the end with QTextEdit::moveCursor() and call QTextEdit::ensureCursorVisible().

contoling an interval in a linedit for ints

I have a lineEdit I use so the user can enter a frequency interval,
// Making the lineedit objects only accept numbers and align it leftside
ui->frequency->setValidator(new QIntValidator(36, 1000, this));
ui->frequency->setAlignment(Qt::AlignRight);
It works fine to the top limit 1000 but the lower dos not. So I created an slot to control it,
// Control freqeuncy interval
void gui::f_interval()
{
QString f = ui->frequency->text();
freq = f.toInt();
if (freq < 36)
{
int status = QMessageBox::warning(this,"Warning","Invalid frequency interval",QMessageBox::Ok);
}
}
and connected it to the signal of the lineEdit,
// Control frequency interval
connect(ui->frequency, SIGNAL(editingFinished()), this, SLOT(f_interval()));
so that when the user enters a number lower than 36 it gets a warning dialog window.
But it doesn't seem to work. can anyone help me?
You want to connect with textChanged signal instead of editingFinished.
LE: also i don't remember having issues with validator, so can you provide more details, like Qt version, Os version, compiler, maybe see if the issue is reproduced in a sample project.

Hiding the console window in a system() call

Continuing from this question
With each system call, the function constructs a set of parameters and sends them off to another program that is just console-based. Is there a way I can make it so that no console window pops up for each call?
I've done a search but the ones that aren't a linker issue just aren't working for me. For instance, I tried the _execl call and System::Diagnostics::Process^ myProcess = gcnew System::Diagnostics::Process; but they aren't working.
The _execl will bring a console window up, scroll a bunch of stuff (from the program I called I guess), then close the my app and not even do what it was supposed to do.
The System::Diagnostics::Process^ myProcess = gcnew System::Diagnostics::Process; doesn't seem to execute what I want either because the output folder that should contain files, contains nothing.
So I'm open for ideas.
The CreateProcess API gives you the control you need. For example:
#include <windows.h>
using namespace System;
int main(array<System::String ^> ^args)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR cmdLine[MAX_PATH] = L"myOtherApp.exe -with -some -args";
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
::CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
Console::ReadLine();
return 0;
}
With the CreateProcess flags set to 0 as above, the secondary app does not open its own console window, and writes its output to the parent's window. To silence the secondary app entirely, look at other CreateProcess flags, e.g. CREATE_NO_WINDOW.

Resources