Too flashy

Just starting out? Need help? Post your questions and find answers here.
BlindMan
User
User
Posts: 32
Joined: Thu Aug 30, 2018 11:34 am

Too flashy

Post by BlindMan »

Hi

I'm visually impaired and struggle to locate the mouse pointer on my multiple monitors.

The following code highlights the location of the mouse pointer but screen update too flashy for comfortable use.

Advice on how to modify this code to smooth the display greatly appreciated.

NB: Code below edited since original posting. A mistyped 'mouse' was responsible for flashy display.

Code: Select all


Global DTqty, MouseDesktop, LastMouseDesktop
Global DTxwd, DTyht, DTxog, DTyog, DTmxa, DTmyd
Global DTMouseX, DTMouseY
Global DPgap=40
Global ExitKey=#VK_F12, ExitKeyPressed=0

; Delay(2000)
; Beep_(1000, 500)

DTqty=ExamineDesktops()-1

Procedure MseDT()
    DTMouseX=DesktopMouseX()
    DTMouseY=DesktopMouseY()
    For DTi = 0 To DTqty
      If DTMouseX>=DesktopX(DTi) And DTMouseX<=DesktopX(DTi)+DesktopWidth(DTi) And DTMouseY>=DesktopY(DTi) And DTMouseY<=DesktopY(DTi)+DesktopHeight(DTi)
        MouseDesktop=DTi
        DTxwd=DesktopWidth(MouseDesktop)
        DTyht=DesktopHeight(MouseDesktop)
        DTxog=DesktopX(MouseDesktop)
        DTyog=DesktopY(MouseDesktop)
        ProcedureReturn 
      EndIf
    Next DTi
EndProcedure

Procedure WIinit()
    LastMouseDesktop=MouseDesktop
    CreateImage(0,DTxwd,DTyht,#PB_Image_DisplayFormat)
    OpenWindow(0,DTxog,DTyog,DTxwd,DTyht,"",#PB_Window_BorderLess|#PB_Window_Invisible|#PB_Window_NoActivate)
    ImageGadget(0,0,0,DTxwd,DTyht,ImageID(0))
    StickyWindow(0,#True)
    SmartWindowRefresh(0,#True)
    HideWindow(0,#False)
    SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_NOACTIVATE)
    SetLayeredWindowAttributes_(WindowID(0),0,0,#LWA_COLORKEY)
EndProcedure
  
Procedure DrwLne(lcolor)
    DC=StartDrawing(ImageOutput(0))
   
    Brush.LOGBRUSH
    Brush\lbstyle=#BS_SOLID
    Brush\lbcolor=lcolor
    Brush\lbhatch=0
  
    newpen=ExtCreatePen_(#PS_GEOMETRIC|#PS_SOLID|#PS_ENDCAP_FLAT|#PS_JOIN_MITER,4,@Brush,0,0)
    oldpen=SelectObject_(DC,newpen) 
  
    MoveToEx_(DC,0,0,0)
;   From top left to mouse
    LineTo_(DC,DTmxa-DPgap,DTmyd-DPgap)
        
    MoveToEx_(DC,DTxwd,0,0)
;   From top right to mouse
    LineTo_(DC,DTmxa+DPgap,DTmyd-DPgap)
        
    MoveToEx_(DC,0,DTyht,0)
;   From bottom left to mouse
    LineTo_(DC,DTmxa-DPgap,DTmyd+DPgap)
   
    MoveToEx_(DC,DTxwd,DTyht,0)
;   From bottom right to mouse
    LineTo_(DC,DTmxa+DPgap,DTmyd+DPgap)
    
    LineTo_(DC,DTmxa-DPgap,DTmyd+DPgap)
    LineTo_(DC,DTmxa-DPgap,DTmyd-DPgap)
    LineTo_(DC,DTmxa+DPgap,DTmyd-DPgap)
    LineTo_(DC,DTmxa+DPgap,DTmyd+DPgap)    
  
    SelectObject_(DC,oldpen) 
    DeleteObject_(newpen) 
    StopDrawing()
  
    ImageGadget(0,0,0,DTxwd,DTyht,ImageID(0))
    StickyWindow(0,#True)
    SmartWindowRefresh(0,#True)
    HideWindow(0,#False)
EndProcedure
      
MseDT()
WIinit()
  
; Delay(1000)
; Beep_(2000, 500)

Repeat
  
  DTMouseX=DesktopMouseX()
  DTMouseY=DesktopMouseY()
  
  DTmxa=DTMouseX-DTxog
  DTmyd=DTMouseY-DTyog

  DrwLne($00FF00)
  
  StillMouse=0
  StartTime=ElapsedMilliseconds()
  While DTMouseX=DesktopMouseX() And DTMouseY=DesktopMouseY()
    WaitWindowEvent(25)
    Delay(25)
    If StillMouse=0 And ElapsedMilliseconds()-StartTime>2000
      StillMouse=1
      DrwLne($000000)  
    EndIf
    ExitKeyPressed=GetAsyncKeyState_(ExitKey) & 32768
  Wend
  
  MseDT()
  
  If LastMouseDesktop=MouseDesktop
    DrwLne($000000)  
  Else
    FreeImage(0)
    CloseWindow(0)
    WIinit()
  EndIf
  
Until ExitKeyPressed<>0

Beep_(3000, 500)
End

Last edited by BlindMan on Thu May 16, 2019 11:15 am, edited 1 time in total.
BlindMan
User
User
Posts: 32
Joined: Thu Aug 30, 2018 11:34 am

Re: Too flashy

Post by BlindMan »

Variable viewer tool found problem. Mistype of 'mouse' fixed.
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Too flashy

Post by chi »

Do you really need the connecting lines?

Code: Select all

sizeW = 150
sizeH = 150
borderW = 5
borderH = 5

OpenWindow(0, 0, 0, sizeW, sizeH, "", #PB_Window_BorderLess)
SetWindowColor(0, #Green)

Orgn = CreateRectRgn_(0, 0, sizeW, sizeH)
Irgn = CreateRectRgn_(borderW, borderH, sizeW-borderW, sizeH-borderH)
CombineRgn_(Orgn, Orgn, Irgn, #RGN_DIFF)
SetWindowRgn_(WindowID(0), Orgn, 1)
DeleteObject_(Irgn)

Repeat  
  event = WaitWindowEvent(16)   
  SetWindowPos_(WindowID(0), #HWND_TOPMOST, DesktopMouseX()-(sizeW/2), DesktopMouseY()-(sizeH/2), 0, 0, #SWP_NOSIZE|#SWP_NOACTIVATE) 
Until event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & 1
Et cetera is my worst enemy
BlindMan
User
User
Posts: 32
Joined: Thu Aug 30, 2018 11:34 am

Re: Too flashy

Post by BlindMan »

Thank you Chi. That's a neat alternative solution.

I do find the extra lines helpful though as I can only see a small portion of the screen.
User avatar
Kurzer
Enthusiast
Enthusiast
Posts: 664
Joined: Sun Jun 11, 2006 12:07 am
Location: Near Hamburg

Re: Too flashy

Post by Kurzer »

Interesting, chi, if you compile the code with DPI aware option (PB 5.7x), the position of the rectangle will be calculated wrong the further you move the mouse to the right or downwards.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520, User age in 2023: 56y
"Happiness is a pet." | "Never run a changing system!"
User avatar
oreopa
Enthusiast
Enthusiast
Posts: 281
Joined: Sat Jun 24, 2006 3:29 am
Location: Edinburgh, Scotland.

Re: Too flashy

Post by oreopa »

BlindMan wrote:Variable viewer tool found problem. Mistype of 'mouse' fixed.
You can use EnableExplicit to help with this kind of problem.
Proud supporter of PB! * Musician * C64/6502 Freak
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Too flashy

Post by chi »

kurzer wrote:Interesting, chi, if you compile the code with DPI aware option (PB 5.7x), the position of the rectangle will be calculated wrong the further you move the mouse to the right or downwards.
DesktopMouse?() is returning wrong coordinates when DPI aware is checked. Guess it's a bug :shock:

Workaround:

Code: Select all

sizeW = DesktopScaledX(150)
sizeH = DesktopScaledY(150)
borderW = DesktopScaledX(5)
borderH = DesktopScaledY(5)

OpenWindow(0, 0, 0, sizeW, sizeH, "", #PB_Window_BorderLess)
SetWindowColor(0, #Green)

Orgn = CreateRectRgn_(0, 0, sizeW, sizeH)
Irgn = CreateRectRgn_(borderW, borderH, sizeW-borderW, sizeH-borderH)
CombineRgn_(Orgn, Orgn, Irgn, #RGN_DIFF)
SetWindowRgn_(WindowID(0), Orgn, 1)
DeleteObject_(Irgn)

Repeat 
  event = WaitWindowEvent(16) 
  GetCursorPos_(cp.POINT)
  SetWindowPos_(WindowID(0), #HWND_TOPMOST, cp\x-(sizeW/2), cp\y-(sizeH/2), 0, 0, #SWP_NOSIZE|#SWP_NOACTIVATE)
  ;SetWindowPos_(WindowID(0), #HWND_TOPMOST, DesktopMouseX()-(sizeW/2), DesktopMouseY()-(sizeH/2), 0, 0, #SWP_NOSIZE|#SWP_NOACTIVATE)
  Debug cp\x
  Debug DesktopMouseX()
  Debug ""
Until event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & 1
[/size]
Et cetera is my worst enemy
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Too flashy

Post by chi »

@BlindMan: Following snippet works without (obvious) flickering and is less CPU hungry... Maybe you wanna adapt one or two things in your code ;)

Code: Select all

Global w = GetSystemMetrics_(0)
Global h = GetSystemMetrics_(1)
Global boxW = 50
Global boxH = 50

Procedure Draw(x, y, color)
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(x-(boxW/2), y-(boxH/2), boxW, boxH, color)
  LineXY(0, 0, x-(boxW/2), y-(boxH/2), color)
  LineXY(w, 0, x+(boxW/2), y-(boxH/2), color)
  LineXY(0, h, x-(boxW/2), y+(boxH/2), color)
  LineXY(w, h, x+(boxW/2), y+(boxH/2), color)
EndProcedure

CreateImage(0, w, h)

OpenWindow(0, 0, 0, w, h, "", #PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible)
ImageGadget(0, 0, 0, w, h, 0)

SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0), 0, 0, #LWA_COLORKEY)

HideWindow(0, #False)

Repeat
  event = WindowEvent()
  
  StartDrawing(ImageOutput(0))
    Draw(oldX, oldY, #Black)
    GetCursorPos_(cp.POINT)
    Draw(cp\x, cp\y, #Green)
    oldX = cp\x
    oldY = cp\y
  StopDrawing()
  SetGadgetState(0, ImageID(0))
  
  SetWindowPos_(WindowID(0), #HWND_TOPMOST, 0, 0, 0, 0, #SWP_NOSIZE|#SWP_NOMOVE|#SWP_NOACTIVATE|#SWP_NOREDRAW)
  
  Delay(25)
Until event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & 1
[/size]
@kurzer: Thanks for the bug report 8)
Et cetera is my worst enemy
BlindMan
User
User
Posts: 32
Joined: Thu Aug 30, 2018 11:34 am

Re: Too flashy

Post by BlindMan »

Thank you again. Very much appreciated.

Seeing other ways of coding solution is very educational. I was aware my code was heavy on CPU but unsure how it could be improved.

I've also made small change to your original solution and find it works well for me.

Code: Select all


ExitKey = #VK_F12

sizeW = 250
sizeH = 250
borderW = 16
borderH = 20

OpenWindow(0, 0, 0, sizeW, sizeH, "", #PB_Window_BorderLess)
SetWindowColor(0, #Red)

Orgn = CreateRectRgn_(0, 0, sizeW, sizeH)
Irgn = CreateRectRgn_(borderW, borderH, sizeW-borderW, sizeH-borderH)
CombineRgn_(Orgn, Orgn, Irgn, #RGN_DIFF)
SetWindowRgn_(WindowID(0), Orgn, 1)
DeleteObject_(Irgn)

Repeat  
  StillMouse=0
  StartTime=ElapsedMilliseconds()
  While DTMouseX=DesktopMouseX() And DTMouseY=DesktopMouseY()
    If StillMouse=0 And ElapsedMilliseconds()-StartTime>2000
      StillMouse=1
      HideWindow(0,#True)
    EndIf
    WaitWindowEvent(16)
  Wend
  
  DTMouseX=DesktopMouseX()
  DTMouseY=DesktopMouseY()
  HideWindow(0,#False) 
  SetWindowPos_(WindowID(0), #HWND_TOPMOST, DesktopMouseX()-(sizeW/2), DesktopMouseY()-(sizeH/2), 0, 0, #SWP_NOSIZE|#SWP_NOACTIVATE) 
  WaitWindowEvent(16)   
  ExitKeyPressed=GetAsyncKeyState_(ExitKey) & 32768  
Until ExitKeyPressed<>0

Beep_(3000, 500)
End

User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Too flashy

Post by chi »

np, happy to help ;)
Et cetera is my worst enemy
BlindMan
User
User
Posts: 32
Joined: Thu Aug 30, 2018 11:34 am

Re: Too flashy

Post by BlindMan »

I would like to do the same with the caret but having issues with obtaining caret position.

Is there a better way to get caret position than in my code below?

Code: Select all


Define StringCaretPos.Point

OpenWindow(0, 0, 0, 200, 160, "GetCaretPos", #PB_Window_SystemMenu)

EditorGadget(0, 0, 0, 200, 50, #PB_Editor_WordWrap)
SetGadgetText(0, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")

TextGadget(1, 20,  80, 160, 25, "")
TextGadget(2, 20, 110, 160, 25, "")

Repeat
  
  Event = WaitWindowEvent(100) 
  
  Select Event
      
    Case #PB_Event_CloseWindow
 
      End
      
    Default
             
      ThisID = GetCurrentThreadId_() 
      ForeID = GetWindowThreadProcessId_(GetForegroundWindow_(), 0) 
      
      If ThisID <> ForeID
        AttachThreadInput_(ThisID, ForeID, #True)
      EndIf     
      
      GetCaretPos_(@StringCaretPos)
      
      If (StringCaretPos\x <> 0) Or (StringCaretPos\y <> 0)
        focusedHandle = GetFocus_()      
        ClientToScreen_(focusedHandle, @StringCaretPos)
      EndIf      
      
      If ThisID <> ForeID
        AttachThreadInput_(ThisID, ForeID, #False)
      EndIf
      
      SetGadgetText(1, "Caret X:" + Str(StringCaretPos\x) + ", Y:" + Str(StringCaretPos\y)) 
      
      iters = iters + 1
      SetGadgetText(2, "Iteration " + Str(iters))
      
  EndSelect
  
ForEver


RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4637
Joined: Sun Apr 12, 2009 6:27 am

Re: Too flashy

Post by RASHAD »

- Resize able
- LBUTTONDOWN to move
- Escape to end

Code: Select all

#SC_DragMove      = $F012

CreateImage(0, 140,140,24,$FF0000)

Procedure WndProc(hwnd, uMsg, wParam, lParam)   
result = #PB_ProcessPureBasicEvents       
 Select uMsg
    Case #WM_NCCALCSIZE
      If OSVersion() >= #PB_OS_Windows_10
        *rc.RECT=lParam
        *rc\top - 7
      EndIf 
       
    Case #WM_SIZE
      ResizeImage(0,WindowWidth(0)-10,WindowHeight(0)-10)
      ResizeGadget(0,5,5,WindowWidth(0)-10,WindowHeight(0)-10)
      SetGadgetState(0,ImageID(0))
       
    Case #WM_NCACTIVATE
        Result = 1
       
 EndSelect   
ProcedureReturn result
EndProcedure

OpenWindow(0, 0, 0,150,150 , "Window_0",#PB_Window_BorderLess| #PB_Window_ScreenCentered| #WS_SIZEBOX | #PB_Window_Invisible)
  SetWindowColor(0,$54FC2A)
   
  ImageGadget(0,5,5,WindowWidth(0)-10,WindowHeight(0)-10,ImageID(0))
  
  SetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE, #WS_EX_LAYERED)
  SetLayeredWindowAttributes_(WindowID(0),$FF0000,0, #LWA_COLORKEY)      
  DisableGadget(0,1)

  SetWindowCallback(@WndProc())
  HideWindow(0,0)
     
Repeat
  Select WaitWindowEvent()
    Case #WM_LBUTTONDOWN
      SendMessage_(WindowID(0), #WM_SYSCOMMAND , #SC_DragMove,0)
       
  EndSelect     
Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 = $8000
End
Egypt my love
BarryG
Addict
Addict
Posts: 3293
Joined: Thu Apr 18, 2019 8:17 am

Re: Too flashy

Post by BarryG »

RASHAD wrote:Resize able
It needs error-checking for resizing: I resized it too small (vertically) and it crashes.
BlindMan
User
User
Posts: 32
Joined: Thu Aug 30, 2018 11:34 am

Re: Too flashy

Post by BlindMan »

Is there a way to make your app window display on top of the Windows Start menu?
StickyWindow() doesn't appear to work in this instance.
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Too flashy

Post by Michael Vogel »

Please add the line...

Code: Select all

WindowBounds(0,11,11,9999,9999)
...to Rashad's code, otherwise avoid shrinking the windows to zero size :wink:
Post Reply