Autohotkey macro to switch mouse position between multiple screens - autohotkey

I just want to put this here.
I needed a macro that moves the mouse cursor to the other monitor.
But on the same relative position proportional to the screen resolution.
And not getting stuck at the border.
And not clicking something in the process.
Ctrl+MiddleMouseButton moves the cursor to the next screen now and should work with any number of screens and different resolutions.
I can test it with 2 screens only though.

^MButton::
SysGet, monitors, MonitorCount
SysGet, MonitorCount, MonitorCount
SysGet, MonitorPrimary, MonitorPrimary
current := 0
Loop, %MonitorCount%
{
SysGet, Monitor, Monitor, %A_Index%
CoordMode, Mouse, Screen
MouseGetPos, MouseX, MouseY
if ( (MouseX >= MonitorLeft) && (MouseX < MonitorRight) && (MouseY >= MonitorTop) && (MouseY < MonitorBottom) )
{
current := A_Index
currentRX := (MouseX - MonitorLeft) / (MonitorRight - MonitorLeft)
currentRY := (MouseY - MonitorTop) / (MonitorBottom - MonitorTop)
break
}
}
next := current + 1
if (next > MonitorCount)
next := 1
SysGet, Monitor, Monitor, %next%
newX := MonitorLeft + currentRX*(MonitorRight - MonitorLeft)
newY := MonitorTop + currentRY*(MonitorBottom - MonitorTop)
DllCall("SetCursorPos", "int", newX, "int", newY)
DllCall("SetCursorPos", "int", newX, "int", newY)
return

if you don't care about the cursor keeping it's relative position and just jump to the middle of the next screen use this (alt+middlemouse in this example):
!MButton::
SysGet, monitors, MonitorCount
SysGet, MonitorCount, MonitorCount
SysGet, MonitorPrimary, MonitorPrimary
current := 0
Loop, %MonitorCount%
{
SysGet, Monitor, Monitor, %A_Index%
CoordMode, Mouse, Screen
MouseGetPos, MouseX, MouseY
if ( (MouseX >= MonitorLeft) && (MouseX < MonitorRight) && (MouseY >= MonitorTop) && (MouseY < MonitorBottom) )
{
current := A_Index
break
}
}
next := current + 1
if (next > MonitorCount)
next := 1
SysGet, Monitor, Monitor, %next%
newX := MonitorLeft + 0.5*(MonitorRight - MonitorLeft)
newY := MonitorTop + 0.5*(MonitorBottom - MonitorTop)
DllCall("SetCursorPos", "int", newX, "int", newY)
DllCall("SetCursorPos", "int", newX, "int", newY)
return

Related

Difference between "Mouse X" and "Horizontal" in Unity

I'm a beginner at Unity.
I'm making a camera that applies to the main character. I used this code:
void Update()
{
var x = Input.GetAxis("Mouse X");
var y = Input.GetAxis("Mouse Y");
if (x != MouseX || y != MouseY)
{
rotationX += x * sensX * Time.deltaTime;
rotationY += y * sensY * Time.deltaTime;
rotationY = Mathf.Clamp(rotationY, minY, maxY);
MouseX = x;
MouseY = y;
Camera.transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
}
}
I saw this site but I don't know the difference "Mouse X" and "Horizontal"
URL: https://docs.unity3d.com/ScriptReference/Input.GetAxis.html
'Horizontal' is mapped to the keyboard arrow keys or a joystick and its value ranges from -1 to 1.
'Mouse X' is mapped to the mouse movement which gives the difference between your mouse initial and final position along x axis.
So basically to take a mouse input use 'Mouse X' and for keyboard's arrow keys use 'Horizontal'

PixelSearch only in middle area?

so im playing Ragna and i want to afk some time while leveling my char. my script is doing good, but how can i pixelsearch/attack only the middle area?
heres the picture
loop {
; this is the color of green boxed monsters to attack
PixelSearch, X, Y, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, 0x00FF00, 0, fast
if (ErrorLevel = 0) {
MouseClick, left, %X%, %Y%
}
else {
; if no monster present in screen, press teleport to search monsters
Send {F1}
}
}
return
You should have a look at what the parameters for PixelSearch means:
PixelSearch, OutputVarX, OutputVarY, X1, Y1, X2, Y2, ColorID [, Variation, Fast|RGB]
Source: ahkscript.org docs
So what you are currently doing is creating a box from (0, 0) to (screenWidth, screenHeight). You could of course change it to hardcoded values or do some math based on the resolution, for example selecting a 200x200px box in the middle:
leftBound := A_ScreenWidth / 2 - 100
rightBound := A_ScreenWidth / 2 + 100
topBound := A_ScreenHeight / 2 - 100
bottomBound := A_ScreenHeight / 2 + 100
PixelSearch, X, Y, leftBound, topBound, rightBound, bottomBound, 0x00FF00, 0, fast

Application starts going nuts after a while

I've recently started using corona SDK and I'm trying to build an app for the iPhone. Now the main idea behind it, is that there are birds flying and you have to shoot them. The birds get a random spot on the screen as their target, and navigate towards it. The app runs fine for about 30 secs - 1 minute, but then suddenly it starts speeding up enormously fast and I don't know why.
And help regarded this is deeply appreciated.
display.setDefault("background", 246, 255, 100)
_W = display.contentWidth;
_H = display.contentHeight;
target = {}
birdPosition = {}
print(_W.." ".._H)
--getting a random location on the screen
local x = math.random(_W)
local y = math.random(_H)
--this checks whether the image will be placed partially off the screen
if x > _W - 42 then
x = _W - 42
end
if y > _H - 42 then
y = _H - 42
end
birdPosition[1] = x
birdPosition[2] = y
local equation = 0
--will be used to see whether the movement will be more vertically than horizontally
local moveVertically = false
local bird = display.newImage("images/bird.png", x, y)
--when the bird is touched, it is removed
function bird:touch()
bird:removeSelf()
end
bird:addEventListener("touch", bird)
--get a new random position
function getNewPosition()
--loop = 50
--getting a random next spot to move to + a check
x = math.random(_W)
y = math.random(_H)
if x > _W - 42 then
x = _W - 42
end
if y > _H - 42 then
y = _H - 42
end
--placing the co-ordinates
target[1] = x
target[2] = y
local smallest
birdPosition[1] = bird.x
birdPosition[2] = bird.y
local diffY
--this check is done so we get a positive equation
if x > bird.x then
diffX = x - bird.x
else
diffX = bird.x - x
end
if y > bird.y then
diffY = y - bird.y
else
diffY = bird.y - y
end
--this check is done so that the equation will always be bigger as 1. This also checks
--whether it will move more vertically than horizontally by putting the boolean true or false
if diffX >= diffY then
equation = diffX/diffY
smallest = diffY
moveVertically = false
else
equation = diffY/diffX
smallest = diffX
moveVertically = true
end
--print("birdPosition X: "..birdPosition[1].. " birdPosition Y: "..birdPosition[2])
--print("Target X: " .. target[1].." Target Y: "..target[2])
--[[
if for instance diffX = 100 and diffY = 50:
smallest will be 50, because the move will be vertically and will only have to be executed 50 times
to give it the effect that it flies quick
]]--
tmr = timer.performWithDelay(10, moveBird, smallest)
end
function moveBird()
if moveVertically == true then
if target[1] >= birdPosition[1] then
bird.x = bird.x + 1
else
bird.x = bird.x - 1
end
if target[2] >= birdPosition[2] then
bird.y = bird.y + equation
else
bird.y = bird.y - equation
end
else
if target[1] >= birdPosition[1] then
bird.x = bird.x + equation
else
bird.x = bird.x - equation
end
if target[2] >= birdPosition[2] then
bird.y = bird.y + 1
else
bird.y = bird.y - 1
end
end
--print("Bird X: "..bird.x .. " Bird Y: " .. bird.y)
--this checks every possibility to get a new position
if bird.x == target[1] or bird.y == target[2] or bird.y < 0 or bird.x > 640 or bird.x < 0 or bird.y > 960 then
getNewPosition()
end
end
getNewPosition()
One error in timer.performWithDelay(10, moveBird, smallest).
The timer is not called the correct way: the third argument should be the number of iteration (so 1), and not smallest.
See the doc here

How to make a form float in a workarea as it is the screen (move, size, maximize, minimize)?

I try code published by Freddie Bell at What is the best way to make a Delphi Application completely full screen? question, as is what i needed.
I also set minimun size to be the original size.
with msg.MinMaxInfo^.ptMinTrackSize do
begin
// maximum size when maximised
x := original_width;
y := original_height;
end;
And in Form OnShow event:
original_width := Width;
original_height := Height;
But i have this issue:
- Mainform has two panels, one of it is aligned as alRight, the other as alLeft; so the working_area is the space between the panels. Mainform has no borders and it is fully maximizad to the work area with
SystemParametersInfo(SPI_GETWORKAREA, 0, #working_desktop, 0);
When i move the form, it keeps inside the working_area between the panels.
When i size the form, it keeps inside that working_area.
But, when i size the form in either way (left or right) passing the edge of the working_area, the form increased its size to the other side. i.e., if the form is on left edge, and you select it to resize it and you move to the left (towards the edge), the form increase its width to the right (but it stop at right edge!).
I try with some code (catching WMSIZE or WMSIZING), but i can prevent that behavior?
Thanks you all in advance!
EDIT (David Heffernan): The key code appears to be in this unit.
unit uFormularios;
interface
uses Windows, Messages, Forms, DBGrids, StdCtrls, Menus, Graphics, ComCtrls;
type
TForm_en_ventana = class(TForm)
private
ancho_original, alto_original: integer;
procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
procedure WMWindowPosChanging(Var Msg: TWMWindowPosChanging); Message WM_WINDOWPOSCHANGING;
procedure WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
end;
TForm_en_ventana_centrado = class(TForm_en_ventana)
private
ancho_original, alto_original: integer;
procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
end;
procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE);
procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer);
var ESPACIO_DE_TRABAJO,
VENTANA_DE_TRABAJO : TRect;
implementation
procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE);
begin
LockWindowUpdate(TForm(F).Handle);
TForm(F).Left := ESPACIO_DE_TRABAJO.Left;
if MaximoAncho = 0 then
TForm(F).Width := ESPACIO_DE_TRABAJO.Right
else
begin
if ESPACIO_DE_TRABAJO.Right < MaximoAncho then
TForm(F).Width := ESPACIO_DE_TRABAJO.Right
else
TForm(F).Width := MaximoAncho;
end;
TForm(F).Top := ESPACIO_DE_TRABAJO.Top;
if MaximaAltura = 0 then
TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom
else
begin
if ESPACIO_DE_TRABAJO.Bottom < MaximaAltura then
TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom
else
TForm(F).Height := MaximaAltura;
end;
if ((MaximoAncho <> 0) or (MaximaAltura <> 0)) and (Centrado) then
begin
TForm(F).Left := (ESPACIO_DE_TRABAJO.Right - TForm(F).Width ) div 2;
TForm(F).Top := (ESPACIO_DE_TRABAJO.Bottom - TForm(F).Height) div 2;
end;
LockWindowUpdate(0);
end;
procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer);
begin
VENTANA_DE_TRABAJO.Left := izq;
VENTANA_DE_TRABAJO.Right := der;
VENTANA_DE_TRABAJO.Top := arr;
VENTANA_DE_TRABAJO.Bottom := aba;
end;
procedure TForm_en_ventana.WMWindowPosChanging(var Msg: TWMWINDOWPOSCHANGING);
begin
with Msg.WindowPos^ do
{
x: int; The position of the left edge of the window.
y: int; The position of the top edge of the window.
cx: int; The window width, in pixels.
cy: int; The window height, in pixels.
}
begin
if x <= VENTANA_DE_TRABAJO.Left then
x := VENTANA_DE_TRABAJO.Left;
if x + cx >= VENTANA_DE_TRABAJO.Right then
x := (VENTANA_DE_TRABAJO.Right) - cx;
if y <= VENTANA_DE_TRABAJO.Top then
y := VENTANA_DE_TRABAJO.Top;
if y + cy >= VENTANA_DE_TRABAJO.Bottom then
y := (VENTANA_DE_TRABAJO.Bottom) - cy;
end;
end;
Procedure TForm_en_ventana.WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo);
begin
inherited;
with msg.MinMaxInfo^.ptMaxPosition do
begin
// position of top when maximised
x := VENTANA_DE_TRABAJO.Left;
y := VENTANA_DE_TRABAJO.Top;
end;
with msg.MinMaxInfo^.ptMaxSize do
begin
// width and height when maximized
x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left;
y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top;
end;
with msg.MinMaxInfo^.ptMaxTrackSize do
begin
// maximum size when maximised
x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left;
y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top;
end;
with msg.MinMaxInfo^.ptMinTrackSize do
begin
// maximum size when maximised
x := ancho_original;
y := alto_original;
end;
end;
procedure TForm_en_ventana.WMSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType and $FFF0 = SC_MINIMIZE then
Application.Minimize
else
inherited;
end;
procedure TForm_en_ventana.WMShowWindow(var Message: TWMShowWindow);
begin
ancho_original := Width;
alto_original := Height;
end;
procedure TForm_en_ventana_centrado.WMShowWindow(var Message: TWMShowWindow);
begin
ancho_original := Width;
alto_original := Height;
Left := (((VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left) - Width) div 2) + VENTANA_DE_TRABAJO.Left;
Top := (((VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top) - Height) div 2) + VENTANA_DE_TRABAJO.Top;
end;
initialization
SystemParametersInfo(SPI_GETWORKAREA, 0, #ESPACIO_DE_TRABAJO, 0);
VENTANA_DE_TRABAJO := ESPACIO_DE_TRABAJO;
end.
Your handler for WM_WINDOWPOSCHANGING is fine for moving operations but needs to be different for sizing operations. You can't detect those from within that message handler so you need an alternative. Instead use WM_SIZING and WM_MOVING like this:
procedure WMSizing(Var msg: TMessage); message WM_SIZING;
procedure WMMoving(Var msg: TMessage); message WM_MOVING;
....
procedure TForm_en_ventana.WMSizing(var msg: TMessage);
var
R: PRect;
begin
R := PRect(msg.LParam);
R.Left := Max(R.Left, VENTANA_DE_TRABAJO.Left);
R.Right := Min(R.Right, VENTANA_DE_TRABAJO.Right);
R.Top := Max(R.Top, VENTANA_DE_TRABAJO.Top);
R.Bottom := Min(R.Bottom, VENTANA_DE_TRABAJO.Bottom);
end;
procedure TForm_en_ventana.WMMoving(var msg: TMessage);
var
R: PRect;
dx, dy: Integer;
begin
R := PRect(msg.LParam);
dx := 0;
dy := 0;
if R.Left<VENTANA_DE_TRABAJO.Left then
dx := VENTANA_DE_TRABAJO.Left-R.Left;
if R.Right>VENTANA_DE_TRABAJO.Right then
dx := VENTANA_DE_TRABAJO.Right-R.Right;
if R.Top<VENTANA_DE_TRABAJO.Top then
dy := VENTANA_DE_TRABAJO.Top-R.Top;
if R.Bottom>VENTANA_DE_TRABAJO.Bottom then
dy := VENTANA_DE_TRABAJO.Bottom-R.Bottom;
OffsetRect(R^, dx, dy);
end;
You will need to remove the WM_WINDOWPOSCHANGING altogether.

Drag and drop bitmap on form

I am drawing onformpaint event the same bitmap in diffrent places on the form what i would like to do is add a drag and drop functionality to those bitmaps to enable the user to place them as he wishes on the form.I have an idea but it seems quite rudimentary and i don't want to put useless effort.I would appreciate some implementation ideas from you guys.
Thanks.
P.S I would like to implement an OnClick event over those bitmaps too
Unless you have specific reasons to do so, I would not draw the bitmaps in the OnFormPaint handler as this complicates what you want to achieve very much. Instead you could use Timages on your form, and your second requirement of having OnClick handlers is solved. Drag and Drop of TIamges should not be too complicated either when dealing with TImage components.
Edit:
Inspired by Bruce's answer, I came up with a working sample using the techniques in his mentioned example. I subclassed a TPanel and a TImage to achieve the desired effect. It's important that the TImage is parented in the TPanel. Note, that this is just a quick and dirty sample, no checks ect (like if the parent of the Timahe really is a TParent). In order for the example to work, drop a TPanel on a form and a Timage on the TPanel.
unit Unit66;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, jpeg;
const
sizeBorder = 2;
sc_SizeLeft = $F001; { these are the variations }
sc_SizeRight = $F002; { on the SC_SIZE value }
sc_SizeTop = $F003;
sc_SizeTopLeft = $F004;
sc_SizeTopRight = $F005;
sc_SizeBottom = $F006;
sc_SizeBottomRight = $F008;
sc_SizeBottomLeft = $F007;
sc_DragMove = $F012;
type
TPanel = class(ExtCtrls.TPanel)
public
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: integer); override;
end;
TImage = class(ExtCtrls.TImage)
public
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: integer); override;
end;
TForm66 = class(TForm)
Panel1: TPanel;
Image1: TImage;
procedure Image1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form66: TForm66;
implementation
{$R *.dfm}
{ TImage }
procedure TPanel.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
if Button = mbLeft then
begin
ReleaseCapture;
if (X >= Width - sizeBorder) And NOT((Y <= sizeBorder) or (Y >= Height - sizeBorder)) then
Self.Perform(WM_SysCommand, sc_SizeRight, 0)
else if Not((X <= sizeBorder) or (X >= Width - sizeBorder)) And (Y <= sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeTop, 0)
else if (X <= sizeBorder) And (Y <= sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeTopLeft, 0)
else if (X >= Width - sizeBorder) and (Y <= sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeTopRight, 0)
else if Not((X <= sizeBorder) or (X >= Width - sizeBorder)) And (Y >= Height - sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeBottom, 0)
else if (Y >= Height - sizeBorder) And (X <= sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeBottomLeft, 0)
else if (Y >= Height - sizeBorder) and (X >= Width - sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeBottomRight, 0)
else if Not((Y <= sizeBorder) or (Y >= Height - sizeBorder)) And (X <= sizeBorder) then
Self.Perform(WM_SysCommand, sc_SizeLeft, 0)
else
begin
Self.Perform(WM_SysCommand, sc_DragMove, 0);
end;
end;
end;
procedure TPanel.MouseMove(Shift: TShiftState; X, Y: integer);
begin
if (X <= sizeBorder) or (X >= Width - sizeBorder) then
begin
if (Y >= Height - sizeBorder) then
begin
if (X >= Width - sizeBorder) then
Cursor := crSizeNWSE
else
Cursor := crSizeNESW;
end
else if (Y <= sizeBorder) then
begin
if (X >= Width - sizeBorder) then
Cursor := crSizeNESW
else
Cursor := crSizeNWSE;
end
else
Cursor := crSizeWE;
end
else if (Y <= sizeBorder) or (Y >= Height - sizeBorder) then
begin
Cursor := crSizeNS;
end
else
Cursor := crDefault;
end;
procedure TForm66.Image1Click(Sender: TObject);
begin
ShowMessage('Image clicked');
end;
{ TImage }
type
TWinControlHack = class(TWinControl);
procedure TImage.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
if ssCtrl in Shift then
TWinControlHack(Parent).MouseDown(Button, Shift, X, Y);
end;
procedure TImage.MouseMove(Shift: TShiftState; X, Y: integer);
begin
TWinControlHack(Parent).MouseMove(Shift, X, Y);
end;
end.
Here is a useful example that will let you move or resize TCustomControl descendents at run time.
I think your best option is to use a TImage instead of custom drawing. As iamjoosy points out, the above example won't work with TGraphicControls. There are some freeware components that might be more helpful here and here.