Thanks for all your replies, I was using an external keyboard but the different key layouts were making me small again
The InputDirector is BRILLIANT so I don't need to continue working on my solution
Anyhow here's an updated code which can control the mouse cursor position. There's also a change in broadcasting because my notebook's network is not the primary interface (see \BroadcastAddress in the Client code which is used for address\sin_addr in the procedure SendUDPBroadcast).
Code: Select all
; Define Network Client
EnableExplicit
#ApplicationTitle="·MYCLT·"
#MonCode= 666
#MonControl= #MOD_CONTROL|#MOD_SHIFT
#MonKey= #VK_K
Structure AppType
Window.i
BroadcastAddress.s
Icon.i; Network State
IconSize.i
IconArcs.i
DpiScale.i
ConnectionIn.i
ConnectionOut.i
PartnerIP.i
MouseX.i
MouseY.i
MouseButton.i
WindowX.i
WindowY.i
Quit.i
Retry.i
DeadTimer.i
EndStructure
Global App.AppType
Enumeration
#SysTray
#Window
#Icon
#Font
#PopupMenu
#PopupToggle
#PopupQuit
EndEnumeration
; EndDefine
; Define Include Network & More
;#ServerID= #Null
#ServerPort= 5004
#ClientID= #Null
#ClientPort= 5005
Structure ValueType
A.l
B.l
C.l
D.l
EndStructure
Structure MessageType
Type.l
StructureUnion
Record.l[4]
Values.ValueType
EndStructureUnion
Magic.l
EndStructure
Global Message.MessageType
Global Value.ValueType
#Magic=$12345678
Enumeration
#CmdUnknown
#CmdImAlive
#CmdBreak
#CmdGetIP
#CmdSetIP
#CmdSetPassive
#CmdSetActive
#CmdMouseXY
#CmdMouseButton
#CmdKey
EndEnumeration
Enumeration
#StateNoNetwork
#StateIdle
#StateConnected
#StateActive
EndEnumeration
#Ticker= 5
#RepeatTimer= 5000/#Ticker; 5000 ~ 10s
#AliveTimer= 500/#Ticker
#DeadTimer= #AliveTimer*3
#Undefined= -#True
#DpiBits= 12+SizeOf(Integer)
#DpiScale= 1<<#DpiBits
#DrawOpaque= $FF000000
#DrawMilky= $80000000
#DarkRed= $0000A0
#NiceGray= $D0D0D0
#NiceGreen= $35A77C
#NiceBlue= $D3C985
CompilerIf #PB_Compiler_Version>=600
Macro InitNetwork()
#True
EndMacro
CompilerEndIf
Declare ReadMessage()
; EndDefine
Procedure ScaleUp(value)
ProcedureReturn (((value)*App\DpiScale)/#DpiScale)
EndProcedure
Procedure SysTrayIcon(mode)
Protected.s s,t
Protected.i ct,cb
With App
If \DpiScale=#Null
\DpiScale=GetDeviceCaps_(GetDC_(0),#LOGPIXELSX)<<#DpiBits/96
\IconSize=ScaleUp(20)
\IconArcs=ScaleUp(3)
LoadFont(#Font,"Segoe UI",\IconSize*0.55,#PB_Font_Bold)
CreateImage(#Icon,\IconSize,\IconSize,32)
\Icon=#Undefined
EndIf
If mode<>\Icon
DisableMenuItem(#PopupMenu,#PopupToggle,Bool(mode<#StateConnected))
StartDrawing(ImageOutput(#Icon))
ct=#White
Select mode
Case #StateNoNetwork
ct=#Black
cb=#NiceGray
s="X"
t="No Network"
Case #StateIdle
ct=#Black
cb=#NiceBlue
s="N"
t="Not connected"
Case #StateConnected
cb=#NiceGreen
s="C"
t="Connected"
\DeadTimer=#DeadTimer
Case #StateActive
cb=#DarkRed
s="A"
t="Active"
\DeadTimer=#DeadTimer
EndSelect
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,\IconSize,\IconSize,#Null)
RoundBox(0,0,\IconSize,\IconSize,\IconArcs,\IconArcs,#DrawOpaque|cb)
DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AlphaBlend)
RoundBox(0,0,\IconSize,\IconSize,\IconArcs,\IconArcs,#DrawMilky)
DrawingFont(FontID(#Font))
DrawText((\IconSize-TextWidth(s))/2,(\IconSize-TextHeight(s)*1.1)/2,s,#DrawOpaque|ct,#Null)
StopDrawing()
If \Icon=#Undefined
AddSysTrayIcon(#SysTray,\Window,ImageID(#Icon))
Else
ChangeSysTrayIcon(#SysTray,ImageID(#Icon))
EndIf
SysTrayIconToolTip(#SysTray,"My Client by Michael Vogel - "+t)
\Icon=mode
EndIf
EndWith
EndProcedure
Procedure SendUDPBroadcast(type,ip.s,port)
Protected socket
Protected *ip
Protected address.sockaddr_in
socket=socket_(#AF_INET,#SOCK_DGRAM,#IPPROTO_IP)
If (socket<>#SOCKET_ERROR)
Protected one=1
;If (setsockopt_(socket,#SOL_SOCKET,#SO_BROADCAST,@one,SizeOf(one))=#SOCKET_ERROR)
; ProcedureReturn #Null
;EndIf
*ip=Ascii(ip)
address\sin_family= #AF_INET
address\sin_port= htons_(port)
address\sin_addr= inet_addr_(*ip)
;address\sin_addr= #INADDR_BROADCAST; sends to 'first' interface only
FreeMemory(*ip)
Message\Type=type
Message\Magic=#Magic
If (sendto_(socket,@Message,SizeOf(Message),0,@address,SizeOf(address))=#SOCKET_ERROR)
ProcedureReturn #Null
EndIf
closesocket_(socket)
EndIf
ProcedureReturn #True
EndProcedure
Procedure SendUDPBroadcastOld(type,port)
Protected sock,one,bytes
Protected remote.sockaddr_in
sock=socket_(#AF_INET,#SOCK_DGRAM,#IPPROTO_IP)
If (sock=#SOCKET_ERROR)
ProcedureReturn #Null
EndIf
one=1
If (setsockopt_(sock,#SOL_SOCKET,#SO_BROADCAST,@one,SizeOf(one))=#SOCKET_ERROR)
ProcedureReturn #Null
EndIf
remote\sin_family=#AF_INET
remote\sin_port=htons_(port)
remote\sin_addr=#INADDR_BROADCAST
Message\Type=type
Message\Magic=#Magic
If (sendto_(sock,@Message,SizeOf(Message),0,@remote,SizeOf(remote))=#SOCKET_ERROR)
ProcedureReturn #Null
EndIf
closesocket_(sock)
ProcedureReturn #True
EndProcedure
Procedure InitServer()
If initNetwork()
If CreateNetworkServer(#ClientID,#ClientPort,#PB_Network_UDP)
SysTrayIcon(#StateIdle)
App\Retry=10
ProcedureReturn #True
EndIf
EndIf
App\Retry=#RepeatTimer/#Ticker
ProcedureReturn #Null
EndProcedure
Procedure InitConnection()
Protected timer
With App
Debug "BROADCAST"
If SendUDPBroadcast(#CmdGetIP,\BroadcastAddress,#ServerPort)
timer=GetTickCount_()+2000
Repeat
Delay(#Ticker)
If NetworkServerEvent()=#PB_NetworkEvent_Data
\ConnectionIn=EventClient()
If ReadMessage()
If Message\Type=#CmdSetIP
\PartnerIP=GetClientIP(\ConnectionIn)
SysTrayIcon(#StateConnected)
ProcedureReturn #True
EndIf
EndIf
EndIf
Until GetTickCount_()>timer
EndIf
App\Retry=#RepeatTimer/#Ticker
EndWith
EndProcedure
Procedure ReadMessage()
With App
Message\Magic=#Null
Message\Type=#Null
ReceiveNetworkData(\ConnectionIn,@Message,SizeOf(Message))
; Debug "DATA "+Str(Message\Type)+" "+Hex(Message\Values\A)+":"+Hex(Message\Values\B)+":"+Hex(Message\Values\C)+":"+Hex(Message\Values\D)
ProcedureReturn Bool(Message\Magic=#Magic)
EndWith
EndProcedure
Procedure SendMessage(type,*Value.ValueType)
With App
\ConnectionOut=OpenNetworkConnection(IPString(\PartnerIP),#ServerPort,#PB_Network_UDP)
If \ConnectionOut
Message\Type=type
If *Value
CopyMemory(*Value,@Message\Values,SizeOf(ValueType))
Else
FillMemory(@Message\Values,SizeOf(ValueType),#Null,#PB_Long)
EndIf
Message\Magic=#Magic
ProcedureReturn Bool(SendNetworkData(\ConnectionOut,@Message,SizeOf(Message))>=0)
Else
ProcedureReturn #Null
EndIf
EndWith
EndProcedure
; End of Include Network & More
Procedure ToggleMode()
With App
Select \Icon
Case #StateConnected
\WindowX=GetSystemMetrics_(#SM_CXSCREEN)
\WindowY=GetSystemMetrics_(#SM_CYSCREEN)
Value\A=\WindowX
Value\B=\WindowY
Value\C=0
Value\D=0
If SendMessage(#CmdSetActive,@Value)
SysTrayIcon(#StateActive)
;ResizeWindow(#Window,#PB_Ignore,#PB_Ignore,\WindowX,\WindowY)
;HideWindow(#Window,#Null)
;SetWindowLong_(WindowID(#Window),#GWL_EXSTYLE,GetWindowLong_(WindowID(#Window),#GWL_EXSTYLE)|#WS_EX_LAYERED)
;SetLayeredWindowAttributes_(WindowID(#Window), 0, (255*70)/100,#LWA_ALPHA)
Else
\Retry=10
SysTrayIcon(#StateIdle)
EndIf
Case #StateActive
If SendMessage(#CmdSetPassive,#Null)
SysTrayIcon(#StateConnected)
\MouseX=#Undefined
\MouseY=#Undefined
\MouseButton=#Undefined
HideWindow(#Window,#True)
Else
\Retry=10
SysTrayIcon(#StateIdle)
EndIf
EndSelect
EndWith
EndProcedure
Procedure Main()
Protected Cursor.Point
With App
If FindWindow_(0,#ApplicationTitle)=0
\BroadcastAddress="10.0.0.255"
\MouseX=#Undefined
\MouseY=#Undefined
\MouseButton=#Undefined
CreatePopupMenu(#PopupMenu)
MenuItem(#PopupToggle,"Toggle Control"+#TAB$+"Ctrl+Shift+K")
MenuBar()
MenuItem(#PopupQuit,"Quit 'MyClient'...")
\Window=OpenWindow(#Window,0,0,0,0,#ApplicationTitle,#PB_Window_Invisible)
RegisterHotKey_(\Window,#MonCode,#MonControl,#MonKey)
AddWindowTimer(#Window,#Null,#Ticker)
SysTrayIcon(#StateNoNetwork)
InitServer()
Repeat
Select WaitWindowEvent()
Case #PB_Event_SysTray
Select EventType()
Case #PB_EventType_LeftDoubleClick
ToggleMode()
Case #PB_EventType_RightClick
\Quit=#True
Case #PB_EventType_LeftClick
DisplayPopupMenu(#PopupMenu,\Window)
EndSelect
Case #PB_Event_Timer
Select \Icon
Case #StateNoNetwork,#StateIdle
If \Retry
\Retry-1
If \Retry=#Null
If \Icon=#StateNoNetwork
InitServer()
Else
InitConnection()
EndIf
EndIf
EndIf
Case #StateConnected,#StateActive
\DeadTimer-1
If \DeadTimer<0
Debug "Server is dead..."
SysTrayIcon(#StateIdle)
\Retry=10
EndIf
EndSelect
Case #PB_Event_Menu;#PB_Event_Gadget
Select EventGadget()
Case #PopupToggle
ToggleMode()
Case #PopupQuit
\Quit=#True
EndSelect
Case #WM_HOTKEY
If EventwParam()=#MonCode
ToggleMode()
EndIf
Case #WM_MOUSEMOVE
Debug "*"
EndSelect
If \Icon=#StateActive
GetCursorPos_(@Cursor)
If \MouseX<>Cursor\x Or \MouseY<>Cursor\y
\MouseX=Cursor\x
\MouseY=Cursor\y
Value\A=Cursor\x
Value\B=Cursor\y
SendMessage(#CmdMouseXY,@Value)
EndIf
EndIf
Select NetworkServerEvent(#ClientID)
Case #PB_NetworkEvent_Connect
Debug "CONN (never happens)"
Case #PB_NetworkEvent_Data
\ConnectionIn=EventClient()
If ReadMessage()
Debug "MESS "+Str(Message\Type)+" "+Hex(Message\Values\A)+":"+Hex(Message\Values\B)+":"+Hex(Message\Values\C)+":"+Hex(Message\Values\D)
Select Message\Type
Case #CmdImAlive
Debug "Server is alive"
\DeadTimer=#DeadTimer
Case #CmdBreak
If \Icon>#StateIdle
SysTrayIcon(#StateIdle)
\Retry=10
EndIf
Case #CmdGetIP
\PartnerIP=GetClientIP(\ConnectionIn)
\ConnectionOut=OpenNetworkConnection(IPString(\PartnerIP),#ServerPort,#PB_Network_UDP)
If SendMessage(#CmdSetIP,#Null)
SysTrayIcon(#StateConnected)
EndIf
EndSelect
EndIf
Case #PB_NetworkEvent_Disconnect
Debug "DISC (never happens)"
EndSelect
Until \Quit
;If \Icon>#StateIdle
SendMessage(#CmdBreak,#Null)
;EndIf
EndIf
EndWith
EndProcedure
Main()
Code: Select all
; Define Network Server
#ApplicationTitle="·MYSVR·"
EnableExplicit
Structure AppType
Window.i
Icon.i; Network State
IconSize.i
IconArcs.i
DpiScale.i
ConnectionIn.i
ConnectionOut.i
PartnerIP.i
PartnerX.i
PartnerY.i
WindowX.i
WindowY.i
Quit.i
Retry.i
Alive.i
EndStructure
Global App.AppType
Enumeration
#SysTray
#Window
#Icon
#Font
#PopupMenu
#PopupQuit
EndEnumeration
; EndDefine
; Define Include Network & More
#ServerID= #Null
#ServerPort= 5004
#ClientPort= 5005
Structure ValueType
A.l
B.l
C.l
D.l
EndStructure
Structure MessageType
Type.l
StructureUnion
Record.l[4]
Values.ValueType
EndStructureUnion
Magic.l
EndStructure
Global Message.MessageType
#Magic=$12345678
Enumeration
#CmdUnknown
#CmdImAlive
#CmdBreak
#CmdGetIP
#CmdSetIP
#CmdSetPassive
#CmdSetActive
#CmdMouseXY
#CmdMouseButton
#CmdKey
EndEnumeration
Enumeration
#StateNoNetwork
#StateIdle
#StateConnected
#StateActive
EndEnumeration
#Ticker= 5
#RepeatTimer= 5000/#Ticker; 5000 ~ 10s
#AliveTimer= 500/#Ticker
#Undefined= -#True
#DpiBits= 12+SizeOf(Integer)
#DpiScale= 1<<#DpiBits
#DrawOpaque= $FF000000
#DrawMilky= $80000000
#DarkRed= $0000A0
#NiceGray= $D0D0D0
#NiceGreen= $35A77C
#NiceBlue= $D3C985
CompilerIf #PB_Compiler_Version>=600
Macro InitNetwork()
#True
EndMacro
CompilerEndIf
; EndDefine
Procedure ScaleUp(value)
ProcedureReturn (((value)*App\DpiScale)/#DpiScale)
EndProcedure
Procedure SysTrayIcon(mode)
Protected.s s,t
Protected.i ct,cb
With App
If \DpiScale=#Null
\DpiScale=GetDeviceCaps_(GetDC_(0),#LOGPIXELSX)<<#DpiBits/96
\IconSize=ScaleUp(20)
\IconArcs=ScaleUp(3)
LoadFont(#Font,"Segoe UI",\IconSize*0.55,#PB_Font_Bold)
CreateImage(#Icon,\IconSize,\IconSize,32)
\Icon=#Undefined
EndIf
If mode<>\Icon
StartDrawing(ImageOutput(#Icon))
ct=#White
Select mode
Case #StateNoNetwork
ct=#Black
cb=#NiceGray
s="X"
t="No Network"
Case #StateIdle
ct=#Black
cb=#NiceBlue
s="I"
t="Idle"
Case #StateConnected
cb=#NiceGreen
s="C"
t="Connected"
Case #StateActive
cb=#DarkRed
s="A"
t="Active"
EndSelect
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,\IconSize,\IconSize,#Null)
RoundBox(0,0,\IconSize,\IconSize,\IconArcs,\IconArcs,#DrawOpaque|cb)
DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AlphaBlend)
RoundBox(0,0,\IconSize,\IconSize,\IconArcs,\IconArcs,#DrawMilky)
DrawingFont(FontID(#Font))
DrawText((\IconSize-TextWidth(s))/2,(\IconSize-TextHeight(s)*1.1)/2,s,#DrawOpaque|ct,#Null)
StopDrawing()
If \Icon=#Undefined
AddSysTrayIcon(#SysTray,\Window,ImageID(#Icon))
Else
ChangeSysTrayIcon(#SysTray,ImageID(#Icon))
EndIf
SysTrayIconToolTip(#SysTray,"MyServer by Michael Vogel - "+t)
\Icon=mode
EndIf
EndWith
EndProcedure
Procedure InitServer()
If InitNetwork()
If CreateNetworkServer(#ServerID,#ServerPort,#PB_Network_UDP)
SysTrayIcon(#StateIdle)
ProcedureReturn #True
EndIf
EndIf
App\Retry=#RepeatTimer/#Ticker
ProcedureReturn #Null
EndProcedure
Procedure ReadMessage()
With App
Message\Magic=#Null
ReceiveNetworkData(\ConnectionIn,@Message,SizeOf(Message))
; Debug "DATA "+Str(Message\Type)+" "+Hex(Message\Values\A)+"."+Hex(Message\Values\B)+"."+Hex(Message\Values\C)+"."+Hex(Message\Values\D)
ProcedureReturn Bool(Message\Magic=#Magic)
EndWith
EndProcedure
Procedure SendMessage(type,*Value.ValueType)
With App
\ConnectionOut=OpenNetworkConnection(IPString(\PartnerIP),#ClientPort,#PB_Network_UDP)
If \ConnectionOut
Message\Type=type
If *Value
CopyMemory(*Value,@Message\Values,SizeOf(ValueType))
Else
FillMemory(@Message\Values,SizeOf(ValueType),#Null,#PB_Long)
EndIf
Message\Magic=#Magic
Debug "Send message "+type+" to "+IPString(\PartnerIP)
ProcedureReturn Bool(SendNetworkData(\ConnectionOut,@Message,SizeOf(Message))>=0)
Else
ProcedureReturn #Null
EndIf
EndWith
EndProcedure
; End of Include Network & More
Procedure Main()
With App
If FindWindow_(0,#ApplicationTitle)=0
\Window=OpenWindow(#Window,0,0,0,0,#ApplicationTitle,#PB_Window_Invisible)
AddWindowTimer(#Window,#Null,#Ticker)
SysTrayIcon(#StateNoNetwork)
CreatePopupMenu(#PopupMenu)
MenuItem(#PopupQuit,"Quit 'MyServer'...")
InitServer()
Repeat
Select WaitWindowEvent()
Case #PB_Event_SysTray
Select EventType()
Case #PB_EventType_LeftDoubleClick
Case #PB_EventType_RightClick
\Quit=#True
Case #PB_EventType_LeftClick
DisplayPopupMenu(#PopupMenu,\Window)
EndSelect
Case #PB_Event_Timer
Select \Icon
Case #StateNoNetwork
If \Retry
\Retry-1
If \Retry=#Null
InitServer()
EndIf
EndIf
Case #StateConnected,#StateActive
\Alive-1
If \Alive<=#Null
\Alive=#AliveTimer
SendMessage(#CmdImAlive,#Null)
EndIf
EndSelect
Case #PB_Event_Menu;#PB_Event_Gadget
Select EventGadget()
Case #PopupQuit
\Quit=#True
EndSelect
EndSelect
Select NetworkServerEvent(#ServerID)
Case #PB_NetworkEvent_Connect
Debug "CONN (never happens)"
Case #PB_NetworkEvent_Data
\ConnectionIn=EventClient()
If ReadMessage()
Debug "MESS "+Str(Message\Type)+" "+Hex(Message\Values\A)+":"+Hex(Message\Values\B)+":"+Hex(Message\Values\C)+":"+Hex(Message\Values\D)
Select Message\Type
Case #CmdGetIP
\PartnerIP=GetClientIP(\ConnectionIn)
;\ConnectionOut=OpenNetworkConnection(IPString(\PartnerIP),#ClientPort,#PB_Network_UDP)
If SendMessage(#CmdSetIP,#Null)
SysTrayIcon(#StateConnected)
EndIf
Case #CmdSetActive
\PartnerX=Message\Values\A
\PartnerY=Message\Values\B
\WindowX=GetSystemMetrics_(#SM_CXSCREEN)
\WindowY=GetSystemMetrics_(#SM_CYSCREEN)
SysTrayIcon(#StateActive)
Case #CmdSetPassive
SysTrayIcon(#StateConnected)
Case #CmdMouseXY
; Debug "MOUSE "+Str(Message\Values\A)+" | "+Str(Message\Values\B)
SetCursorPos_(MulDiv_(Message\Values\A,\WindowX,\PartnerX),MulDiv_(Message\Values\B,\WindowY,\PartnerX))
Case #CmdBreak
If \Icon>#StateIdle
SysTrayIcon(#StateIdle)
EndIf
EndSelect
EndIf
Case #PB_NetworkEvent_Disconnect
Debug "DISC (never happens)"
EndSelect
Until \Quit
If \Icon>#StateIdle
SendMessage(#CmdBreak,#Null)
EndIf
EndIf
EndWith
EndProcedure
Main()