QB64 Phoenix Edition
_Glue statement coming anytime soon? - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: _Glue statement coming anytime soon? (/showthread.php?tid=3604)



_Glue statement coming anytime soon? - Pete - 04-09-2025

No, not GLUT, GLUE!

So try this. Run the IDE in a window, mouse on the title bar, hold the left button down, and drag it around like crazy! (Really fast) It's hard to shake the mouse pointer off the initial drag position on the title bar, right?

Okay, well trying to go apples to apples here (or perhaps better stated, PC to PC) Here is a WINDOWS API window dragger I put together that works okay, but not as well as what we have in our Windows Operating Systems...

Code: (Select All)
Dim WinMse As POINTAPI
Type POINTAPI
    X_Pos As Long
    Y_Pos As Long
End Type

Declare Dynamic Library "User32"
    Function GetWindowLongA& (ByVal hwnd As Long, ByVal nIndex As Long)
    Function SetWindowLongA& (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long)
    Function SetWindowPos& (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
    Function GetAsyncKeyState% (ByVal vkey As Long)
    Function GetCursorPos (lpPoint As POINTAPI)
    Function SetCursorPos (ByVal x As Integer, ByVal y As Integer)
End Declare

Dim As Integer setxy, DragXPos, DragYPos, fw, fh, WinWidth, x, y, oldxpos, oldypos, lb
Width 50, 25
Do: Loop Until _ScreenExists
GWL_STYLE = -16 ' Borderless window.
ws_border = &H800000
WS_VISIBLE = &H10000000
hwnd& = _WindowHandle
winstyle& = GetWindowLongA&(hwnd&, GWL_STYLE)
_Delay .25
a& = SetWindowLongA&(hwnd&, GWL_STYLE, winstyle& And WS_VISIBLE)
a& = SetWindowPos&(hwnd&, 0, 0, 200, 400, 0, 39)
Locate 1, 1: Color 0, 7: Print Space$(_Width); ' Add a cheapo homemade title bar.
fw = _FontWidth: fh = _FontHeight
WinWidth = _Width * fw
x = _ScreenX: y = _ScreenY
Do
    _Limit 30
    If GetAsyncKeyState(1) < 0 Then ' Poll windows mouse.
        If lb = 0 Then lb = 1 ' Left mouse button key is down.
    Else
        If lb Then ' Disengage drag.
            setxy = SetCursorPos(x + DragXPos, y + DragYPos)
            lb = 0: DragXPos = 0: DragYPos = 0
        End If
    End If
    z& = GetCursorPos(WinMse) ' Get the windows mouse cursor position.
    If lb Then
        If DragXPos Then ' Drag is active so let's see if the window should be moved.
            If WinMse.X_Pos <> oldxpos Or WinMse.Y_Pos <> oldypos Then ' Move window if on title bar and mouse cursor has moved.
                j1% = (WinMse.X_Pos - oldxpos)
                j2% = (WinMse.Y_Pos - oldypos)
                x = x + j1%: y = y + j2%
                _ScreenMove x, y ' Window moves here.
                setxy = SetCursorPos(x + DragXPos, y + DragYPos) ' Mouse cursor re-aligns here.
            End If
        Else ' Set drag cursor position in title bar.
            If WinMse.Y_Pos >= _ScreenY And WinMse.Y_Pos <= _ScreenY + fh Then
                If WinMse.X_Pos >= _ScreenX And WinMse.X_Pos <= _ScreenX + WinWidth Then
                    x = _ScreenX: y = _ScreenY ' Cloumn and row of desktop occupied by our program window.
                    DragXPos = (WinMse.X_Pos - x) ' Drag initiation column
                    DragYPos = (WinMse.Y_Pos - y) ' Drag initiation row
                End If
            End If
        End If
    End If
    If Len(InKey$) Then System
    oldypos = WinMse.Y_Pos: oldxpos = WinMse.X_Pos ' Monitor last mouse cursor position.
Loop

So anyone have any method, Windows or QB64 to make the mouse pointer glued to the title bar... WITHOUT making it jerk around like it fell into paint shaker?

For QB64 the only things I can come up with are using _MOUSEMOVE maybe with _MOUSEHIDE and _MOUSESHOW or doing something really off-the-wall like hide the mouse and glue a hardware image of the mouse pointer to the title bar. Remove the image and show the mouse when the drag event is over. 

I think I tried the _MOUSEMOVE approach years ago, but it gave a restrictive and jitter effect with 'crazy' fast drag speed.

Pete


RE: _Glue statement coming anytime soon? - SMcNeill - 04-10-2025

Just give this a run and be happy with it:

Code: (Select All)
Declare Dynamic Library "User32"
Function GetWindowLongA& (ByVal hwnd As Long, ByVal nIndex As Long)
Function SetWindowLongA& (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long)
Function SetWindowPos& (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
End Declare

Width 50, 25
Do: Loop Until _ScreenExists
GWL_STYLE = -16
ws_border = &H800000
WS_VISIBLE = &H10000000
_Title "No Border"
hwnd& = _WindowHandle
winstyle& = GetWindowLongA&(hwnd&, GWL_STYLE)
a& = SetWindowLongA&(hwnd&, GWL_STYLE, winstyle& And WS_VISIBLE)
a& = SetWindowPos&(hwnd&, 0, 0, 200, 400, 0, 39)



Do
k = _KeyHit
x = _ScreenX: y = _ScreenY
Select Case k
Case 19200: _ScreenMove x - 10, y
Case 19712: _ScreenMove x + 10, y
Case 18432: _ScreenMove x, y - 10
Case 20480: _ScreenMove x, y + 10
End Select
_Limit 30
Print "Much";
Print " easier";
Print " than";
Print " Pete's";
Print " method!";
_Display
Loop Until k = 27

Who needs a mouse when you have... arrow keys?! Big Grin Big Grin Big Grin


RE: _Glue statement coming anytime soon? - Pete - 04-10-2025

No, no, no!

Quit trying to STEER us in the wrong direction. Window without mouse is like ox without balls!

For fun, and this one doesn't use Win API, here is a simulation of the one I posted using the QB64 mouse.

Note: It will make a fake replica of your DESKTOP, so don't freak out if you haven't used _SCREENIMAGE before. Press any key to quit the program.

Code: (Select All)
Dim As Integer WinWidth, fw, fh, WinX, WinY, lb
_Delay .25
_ScreenHide
_Delay .25
tmp& = _ScreenImage
imgdesk& = _CopyImage(tmp&, 33)
_FreeImage tmp&
Width _DesktopWidth \ 8 + 8, _DesktopHeight \ 16 - 2
_Font 16
_ScreenMove -16, -32
_ScreenShow
WinWidth = 25: fw = _FontWidth: fh = _FontHeight
t& = _NewImage(100, 150, 32)
_Dest t&
Cls , _RGB32(190, 190, 190)
Line (0, 0)-(WinWidth * _FontWidth, _FontHeight), _RGB32(0, 0, 255), BF ' Title bar.
win& = _CopyImage(t&, 33)
_FreeImage (t&)
_Dest 0
WinX = 30: WinY = 15
Locate , , 0
Do
    _Limit 60
    _PutImage (0, 0), imgdesk&
    _PutImage ((WinX - 1) * fw, (WinY - 1) * fh), win&
    While _MouseInput: Wend
    mx = _MouseX
    my = _MouseY
    lb = _MouseButton(1)
    If lb Then
        If Drag Then ' Drag is active so let's move the window.
            WinX = mx - Drag: WinY = my
        Else ' Set drag cursor position in title bar.
            If mx >= WinX And mx <= WinX + WinWidth And my >= WinY And my <= WinY + 1 Then
                Drag = mx - WinX
            End If
        End If
    Else
        If Drag Then Drag = 0
    End If
    If Len(InKey$) Then System
    Rem If Drag Then _MouseMove WinX + Drag, WinY
    _Display
Loop

So the mouse drag lag is even more noticeable. I don't know how the windows guys did it, but real windows mouse drag really does a great job of gluing that mouse pointer to the drag point.

Anyone else have an idea how that is done?

Pete


RE: _Glue statement coming anytime soon? - eoredson - 04-12-2025

I recently wrote this box function when trapping control-break, it is called BreakBox, and the
reason for the function in this thread is that it does allow dragging the box around when using:

Mouse hover over titlebar - click and hold left mousebutton - move box - release mousebutton.

Also traps mousewheel.

Code: (Select All)
Rem sample box function in a window PD 2025.
Rem $Dynamic
DefLng A-Z

' declare ascii character variables.
Dim Shared Hline As Integer, Vline As Integer
Dim Shared ULcorner As Integer, URcorner As Integer
Dim Shared LLcorner As Integer, LRcorner As Integer

' declare all common mouse variables.
Dim Shared MouseX As Integer, MouseY As Integer
Dim Shared MouseButton1 As Integer, MouseButton2 As Integer
Dim Shared MouseButton3 As Integer, MouseWheel As Integer

' init ascii characters.
Hline = 205: Vline = 186
ULcorner = 201: URcorner = 187
LLcorner = 200: LRcorner = 188

Width 80, 25
Cls
_ScreenMove _Middle
Color 15, 1
Print "sample breakbox.."
Color 7, 0
x = BreakBox
If x Then Print "Returned OK."
If x = 0 Then Print "Returned Cancel."
End

Rem BreakBox with OK/Quit
Function BreakBox
  Dim TempArrayY3(1 To 2000) As Integer
  Dim TempArrayZ3(1 To 2000) As Integer

  ' clear mouse activity.
  MouseButton1 = 0
  MouseButton2 = 0
  MouseButton3 = 0

  'Call ClearMouse
  While _MouseInput: Wend ' empty buffer

  ' store screen area.
  CurrentX = CsrLin
  CurrentY = Pos(0)
  GoSub SaveScreenX

  ' declare break box coordinates.
  Xcoor3 = 10
  Ycoor3 = 10

  ' set break box colors
  BreakBoxBorderColor = 14
  BreakBoxTitleColor = 15
  BreakBoxTextColor = 15
  BreakBoxButton1Color = 15
  BreakBoxButton2Color = 7
  BreakBackGround1 = 1
  BreakBackGround2 = 0

  ' draw box
  BoxButton = 1
  GoSub DrawBreakBox

  ' wait for keypress or mouse
  _KeyClear
  Do
      _Limit 75
      X$ = InKey$
      If Len(X$) Then
        Select Case Len(X$)
            Case 1
              Select Case UCase$(X$)
                  Case "O"
                    BoxButton = 1
                    Exit Do
                  Case "Q"
                    BoxButton = 2
                    Exit Do
                  Case Chr$(13)
                    Exit Do
                  Case Chr$(27)
                    BoxButton = 1
                    Exit Do
                  Case Chr$(9) ' tab
                    If BoxButton = 1 Then
                        BoxButton = 2
                    Else
                        BoxButton = 1
                    End If
                    GoSub DrawBreakBoxButtons
                  Case Chr$(1) ' ctrl-a
                    BreakBackGround1 = BreakBackGround1 + 1
                    If BreakBackGround1 = 8 Then
                        BreakBackGround1 = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(2) ' ctrl-b
                    BreakBackGround2 = BreakBackGround2 + 1
                    If BreakBackGround2 = 8 Then
                        BreakBackGround2 = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(4) ' ctrl-d
                    BreakBoxBorderColor = BreakBoxBorderColor + 1
                    If BreakBoxBorderColor = 16 Then
                        BreakBoxBorderColor = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(5) ' ctrl-e
                    BreakBoxTitleColor = BreakBoxTitleColor + 1
                    If BreakBoxTitleColor = 16 Then
                        BreakBoxTitleColor = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(6) ' ctrl-f
                    BreakBoxTextColor = BreakBoxTextColor + 1
                    If BreakBoxTextColor = 16 Then
                        BreakBoxTextColor = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(7) ' ctrl-g
                    BreakBoxButton1Color = BreakBoxButton1Color + 1
                    If BreakBoxButton1Color = 16 Then
                        BreakBoxButton1Color = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(8) ' ctrl-h
                    BreakBoxButton2Color = BreakBoxButton2Color + 1
                    If BreakBoxButton2Color = 16 Then
                        BreakBoxButton2Color = 0
                    End If
                    GoSub DrawBreakBox
              End Select
            Case 2
              Select Case Asc(Right$(X$, 1))
                  Case 75, 15 ' left/shift-tab
                    If BoxButton = 2 Then
                        BoxButton = 1
                    Else
                        BoxButton = 2
                    End If
                    GoSub DrawBreakBoxButtons
                  Case 77 ' right
                    If BoxButton = 1 Then
                        BoxButton = 2
                    Else
                        BoxButton = 1
                    End If
                    GoSub DrawBreakBoxButtons
                  Case 76, 143 ' keypad-5 center
                    X$ = ""
                    Xcoor3 = 10
                    Ycoor3 = 10
                    GoSub RestoreScreenX
                    GoSub DrawBreakBox
                    _KeyClear
                  Case 72, 141 ' up/ctrl-up
                    X$ = ""
                    If Xcoor3 > 2 Then
                        Xcoor3 = Xcoor3 - 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 80, 145 ' down/ctrl-down
                    If Status Then
                        Z = 23
                    Else
                        Z = 24
                    End If
                    X$ = ""
                    If Xcoor3 + 7 < Z Then
                        Xcoor3 = Xcoor3 + 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 115 ' ctrl-left
                    X$ = ""
                    If Ycoor3 > 1 Then
                        Ycoor3 = Ycoor3 - 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 116 ' ctrl-right
                    X$ = ""
                    If Ycoor3 < 49 Then
                        Ycoor3 = Ycoor3 + 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 152 ' alt-up
                    X$ = ""
                    If Xcoor3 > 5 Then
                        Xcoor3 = Xcoor3 - 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Xcoor3 > 2 Then
                          Xcoor3 = 2
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
                  Case 160 ' alt-dn
                    If Status Then
                        Z = 23
                    Else
                        Z = 24
                    End If
                    X$ = ""
                    If Xcoor3 + 7 < Z - 4 Then
                        Xcoor3 = Xcoor3 + 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Xcoor3 + 7 < Z Then
                          Xcoor3 = Z - 7
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
                  Case 155 ' alt-left
                    X$ = ""
                    If Ycoor3 > 4 Then
                        Ycoor3 = Ycoor3 - 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Ycoor3 > 1 Then
                          Ycoor3 = 1
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
                  Case 157 ' alt-right
                    X$ = ""
                    If Ycoor3 < 45 Then
                        Ycoor3 = Ycoor3 + 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Ycoor3 < 49 Then
                          Ycoor3 = 49
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
              End Select
        End Select
      End If
      If Status Then
        Z = 23
      Else
        Z = 24
      End If
      X = MouseDriver
      If MouseButton1 Then
        ' hover over titlebar
        If MouseX = Xcoor3 Then
            If MouseY >= Ycoor3 And MouseY <= Ycoor3 + 31 Then
              ' store mouse XY during click
              MouseTempX = MouseX
              MouseTempY = MouseY
              Do
                  X = MouseDriver
                  If MouseX Or MouseY Then ' drag
                    MoveBox = 0
                    ' difference in mouse X
                    If MouseX <> MouseTempX Then
                        If MouseX >= 2 And MouseX <= Z - 7 Then
                          Xcoor3 = MouseX
                          MouseTempX = MouseX
                          MoveBox = -1
                        End If
                    End If
                    ' difference in mouse Y
                    If MouseY <> MouseTempY Then
                        MoveY = Ycoor3 + (MouseY - MouseTempY)
                        If MoveY >= 1 And MoveY <= 49 Then
                          Ycoor3 = MoveY
                          MouseTempY = MouseY
                          MoveBox = -1
                        End If
                    End If
                    ' move box
                    If MoveBox Then
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                  End If
              Loop Until MouseButton1 = 0
            End If
        Else
            If MouseX = Xcoor3 + 5 Then
              If MouseY >= Ycoor3 + 2 And MouseY <= Ycoor3 + 5 Then
                  BoxButton = 1
                  Exit Do
              End If
              If MouseY >= Ycoor3 + 8 And MouseY <= Ycoor3 + 13 Then
                  BoxButton = 2
                  Exit Do
              End If
            End If
        End If
      Else
        If MouseX = Xcoor3 + 5 Then
            If MouseY >= Ycoor3 + 2 And MouseY <= Ycoor3 + 5 Then
              If BoxButton = 2 Then
                  BoxButton = 1
                  GoSub DrawBreakBoxButtons
              End If
            End If
            If MouseY >= Ycoor3 + 8 And MouseY <= Ycoor3 + 15 Then
              If BoxButton = 1 Then
                  BoxButton = 2
                  GoSub DrawBreakBoxButtons
              End If
            End If
        End If
      End If
      If MouseWheel Then
        If MouseWheel = -1 Then
            I$ = Chr$(0) + Chr$(72) ' up
            MousePressed = -1
            MouseWheel = 0
            X$ = ""
            If Xcoor3 > 2 Then
              Xcoor3 = Xcoor3 - 1
              GoSub RestoreScreenX
              GoSub DrawBreakBox
            End If
            _KeyClear
        End If
        If MouseWheel = 1 Then
            I$ = Chr$(0) + Chr$(80) ' down
            MousePressed = -1
            MouseWheel = 0
            If Status Then
              Z = 23
            Else
              Z = 24
            End If
            X$ = ""
            If Xcoor3 + 7 < Z Then
              Xcoor3 = Xcoor3 + 1
              GoSub RestoreScreenX
              GoSub DrawBreakBox
            End If
            _KeyClear
        End If
      End If
  Loop
  _Delay .2
  _KeyClear
  _Delay .2

  ' restore screen area.
  GoSub RestoreScreenX
  Color 7, 0
  Locate CurrentX, CurrentY, 1
  If BoxButton = 1 Then
      BreakBox = -1
  Else
      BreakBox = 0
  End If
  Exit Function

  ' draw box
  DrawBreakBox:
  Color BreakBoxBorderColor, BreakBackGround1
  Locate Xcoor3, Ycoor3, 0
  Print Chr$(ULcorner) + String$(30, Hline) + Chr$(URcorner);
  For RowX1 = Xcoor3 + 1 To Xcoor3 + 6
      Locate RowX1, Ycoor3, 0
      Print Chr$(Vline) + Space$(30) + Chr$(Vline);
  Next
  Locate Xcoor3 + 7, Ycoor3, 0
  Print Chr$(LLcorner) + String$(30, Hline) + Chr$(LRcorner);

  ' display box title
  Var0$ = " Break "
  TempX = 16 - Len(Var0$) \ 2 ' center of titlebar
  TempX = Ycoor3 + TempX
  If TempX < 1 Then TempX = 1
  Color BreakBoxTitleColor
  Locate Xcoor3, TempX, 0
  Print Var0$;

  ' display error text
  Color BreakBoxTextColor

  Var1$ = "Control-Break trap."
  Locate Xcoor3 + 1, Ycoor3 + 2, 0
  Print Var1$

  Var2$ = "Press <OK> to continue."
  Locate Xcoor3 + 2, Ycoor3 + 2, 0
  Print Var2$

  Var3$ = "Press <Quit> to end program."
  Locate Xcoor3 + 3, Ycoor3 + 2, 0
  Print Var3$

  GoSub DrawBreakBoxButtons
  Locate , , , 8, 8
  Return

  ' display buttuns
  DrawBreakBoxButtons:
  If BoxButton = 1 Then
      Locate Xcoor3 + 5, Ycoor3 + 2, 0
      Color BreakBoxButton1Color, BreakBackGround2
      Print "<OK>";
      Locate Xcoor3 + 5, Ycoor3 + 3, 0
      Color 13
      Print "O";

      Locate Xcoor3 + 5, Ycoor3 + 8, 0
      Color BreakBoxButton2Color, BreakBackGround2
      Print "<Quit>";
      Locate Xcoor3 + 5, Ycoor3 + 9, 0
      Color 13
      Print "Q";
  Else
      Locate Xcoor3 + 5, Ycoor3 + 2, 0
      Color BreakBoxButton2Color, BreakBackGround2
      Print "<OK>";
      Locate Xcoor3 + 5, Ycoor3 + 3, 0
      Color 13
      Print "O";

      Locate Xcoor3 + 5, Ycoor3 + 8, 0
      Color BreakBoxButton1Color, BreakBackGround2
      Print "<Quit>";
      Locate Xcoor3 + 5, Ycoor3 + 9, 0
      Color 13
      Print "Q";
  End If
  Color 7, 0
  Return

  ' screen save
  SaveScreenX:
  If Status Then
      V = 23
  Else
      V = 24
  End If
  For Var1 = 2 To V
      For Var2 = 1 To 80
        TempZ1 = Screen(Var1, Var2) ' screen char
        TempZ2 = Screen(Var1, Var2, 1) ' char color
        TempArrayY3((Var1 - 1) * 80 + Var2) = TempZ1
        TempArrayZ3((Var1 - 1) * 80 + Var2) = TempZ2
      Next
  Next
  Return

  ' screen restore
  RestoreScreenX:
  If Status Then
      V = 23
  Else
      V = 24
  End If
  For Var1 = 2 To V
      For Var2 = 1 To 80
        VarB = Int(TempArrayZ3((Var1 - 1) * 80 + Var2) / 16)
        VarF = TempArrayZ3((Var1 - 1) * 80 + Var2) Mod 16
        TempZ1 = TempArrayY3((Var1 - 1) * 80 + Var2)
        Locate Var1, Var2, 1
        Color VarF, VarB
        Print Chr$(TempZ1);
      Next
  Next
  Return
End Function

Rem processes mouse activity.
Function MouseDriver
  Static X1 As Integer, Y1 As Integer ' store old values
  MouseX = 0: MouseY = 0
  If _MouseInput Then
      X = CInt(_MouseX): Y = CInt(_MouseY) ' X,Y return single
      If X <> X1 Or Y <> Y1 Then
        X1 = X: Y1 = Y
        MouseX = Y: MouseY = X ' X,Y are reversed
        While _MouseInput: Wend ' empty buffer
        MousePressed = -1
      End If
      MouseButton1 = _MouseButton(1)
      If MouseButton1 Then
        MouseX = Y1
        MouseY = X1
        MousePressed = -1
      End If
      MouseButton2 = _MouseButton(2)
      If MouseButton2 Then
        MouseX = Y1
        MouseY = X1
        MousePressed = -1
      End If
      MouseButton3 = _MouseButton(3)
      If MouseButton3 Then
        MousePressed = -1
      End If
      MouseWheel = _MouseWheel
      If MouseWheel Then
        ' reverse mousewheel value
        If WheelReverse Then
            If MouseWheel = -1 Then
              MouseWheel = 1
            Else
              If MouseWheel = 1 Then
                  MouseWheel = -1
              End If
            End If
        End If
      End If
  End If
  MouseDriver = -1
End Function



RE: _Glue statement coming anytime soon? - SMcNeill - 04-12-2025

Here's one trick which is guaranteed to work for you...

Make a copy of the screen.
Make a copy of a mouse cursor.
Put the mouse cursor on the screen as a graphic.
_Mousehide the current cursor while the screen is being dragged.
Drag the screen with the fake mouse on it where you want it.
_Mousemove the mouse to the proper position, then show it.
Replace the screen with the original screen without the fake mouse on it.


RE: _Glue statement coming anytime soon? - eoredson - 04-12-2025

@steve: wow! so you CAN be terse at times!? I thought you would blow up into a page of response..

My snippete in the above already stores screen/moves box/restores screen..

If it is GUI then I dunno?

-ejo


RE: _Glue statement coming anytime soon? - Pete - 04-12-2025

(04-09-2025, 11:47 PM)Pete Wrote: ...

For QB64 the only things I can come up with are using _MOUSEMOVE maybe with _MOUSEHIDE and _MOUSESHOW or doing something really off-the-wall like hide the mouse and glue a hardware image of the mouse pointer to the title bar. Remove the image and show the mouse when the drag event is over. 

...

Pete

So yes, Steve, we're on that same page again. I was really hoping someone had a method that wouldn't require doing that. I mean unless I missed something even the Windows method I put together doesn't achieve that feat.

Erik, thanks for posting your routine. Our drag routines for the QB64 mouse, see my second post above, are quite similar. Both will end up with the mouse cursor in the same place after the drag is finished, but both have about the same amount of separation when a drag is being done quickly, or when dragging quickly in circles like doing donuts in my old GTO with a 455 big block....

[Image: shifting-gears-matt.jpg]

Pete


RE: _Glue statement coming anytime soon? - eoredson - 04-13-2025

Find the improved breakbox with new:

  custom Inkey$ function which
  traps keypad-5 and ctrl-keypad-5.

Code: (Select All)
Rem sample box function in a window PD 2025.
Rem $Dynamic
DefLng A-Z

' declare ascii character variables.
Dim Shared Hline As Integer, Vline As Integer
Dim Shared ULcorner As Integer, URcorner As Integer
Dim Shared LLcorner As Integer, LRcorner As Integer

' declare all common mouse variables.
Dim Shared MouseX As Integer, MouseY As Integer
Dim Shared MouseButton1 As Integer, MouseButton2 As Integer
Dim Shared MouseButton3 As Integer, MouseWheel As Integer
Dim Shared WheelReverse As Integer ' toggle up/down
Dim Shared MousePressed As Integer, KeyPressed As Integer

' init ascii characters.
Hline = 205: Vline = 186
ULcorner = 201: URcorner = 187
LLcorner = 200: LRcorner = 188

Width 80, 25
Cls
_ScreenMove _Middle
Color 15, 1
Print "sample breakbox.."
Color 7, 0
x = BreakBox
If x Then Print "Returned OK."
If x = 0 Then Print "Returned Cancel."
End

Rem BreakBox with OK/Quit
Function BreakBox
  Dim TempArrayY3(1 To 2000) As Integer
  Dim TempArrayZ3(1 To 2000) As Integer

  ' clear mouse activity.
  MouseButton1 = 0
  MouseButton2 = 0
  MouseButton3 = 0

  'Call ClearMouse
  While _MouseInput: Wend ' empty buffer

  ' store screen area.
  CurrentX = CsrLin
  CurrentY = Pos(0)
  GoSub SaveScreenX

  ' declare break box coordinates.
  Xcoor3 = 10
  Ycoor3 = 10

  ' set break box colors
  BreakBoxBorderColor = 14
  BreakBoxTitleColor = 15
  BreakBoxTextColor = 15
  BreakBoxButton1Color = 15
  BreakBoxButton2Color = 7
  BreakBackGround1 = 1
  BreakBackGround2 = 0

  ' draw box
  BoxButton = 1
  GoSub DrawBreakBox

  ' wait for keypress or mouse
  _KeyClear
  Do
      '_Limit 75
      X$ = INKEYz$
      If Len(X$) Then
        Select Case Len(X$)
            Case 1
              Select Case UCase$(X$)
                  Case "O"
                    BoxButton = 1
                    Exit Do
                  Case "Q"
                    BoxButton = 2
                    Exit Do
                  Case Chr$(13)
                    Exit Do
                  Case Chr$(27)
                    BoxButton = 1
                    Exit Do
                  Case Chr$(9) ' tab
                    If BoxButton = 1 Then
                        BoxButton = 2
                    Else
                        BoxButton = 1
                    End If
                    GoSub DrawBreakBoxButtons
                  Case Chr$(1) ' ctrl-a
                    BreakBackGround1 = BreakBackGround1 + 1
                    If BreakBackGround1 = 8 Then
                        BreakBackGround1 = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(2) ' ctrl-b
                    BreakBackGround2 = BreakBackGround2 + 1
                    If BreakBackGround2 = 8 Then
                        BreakBackGround2 = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(4) ' ctrl-d
                    BreakBoxBorderColor = BreakBoxBorderColor + 1
                    If BreakBoxBorderColor = 16 Then
                        BreakBoxBorderColor = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(5) ' ctrl-e
                    BreakBoxTitleColor = BreakBoxTitleColor + 1
                    If BreakBoxTitleColor = 16 Then
                        BreakBoxTitleColor = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(6) ' ctrl-f
                    BreakBoxTextColor = BreakBoxTextColor + 1
                    If BreakBoxTextColor = 16 Then
                        BreakBoxTextColor = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(7) ' ctrl-g
                    BreakBoxButton1Color = BreakBoxButton1Color + 1
                    If BreakBoxButton1Color = 16 Then
                        BreakBoxButton1Color = 0
                    End If
                    GoSub DrawBreakBox
                  Case Chr$(8) ' ctrl-h
                    BreakBoxButton2Color = BreakBoxButton2Color + 1
                    If BreakBoxButton2Color = 16 Then
                        BreakBoxButton2Color = 0
                    End If
                    GoSub DrawBreakBox
              End Select
            Case 2
              Select Case Asc(Right$(X$, 1))
                  Case 75, 15 ' left/shift-tab
                    If BoxButton = 2 Then
                        BoxButton = 1
                    Else
                        BoxButton = 2
                    End If
                    GoSub DrawBreakBoxButtons
                  Case 77 ' right
                    If BoxButton = 1 Then
                        BoxButton = 2
                    Else
                        BoxButton = 1
                    End If
                    GoSub DrawBreakBoxButtons
                  Case 76, 143 ' keypad-5 center
                    X$ = ""
                    Xcoor3 = 10
                    Ycoor3 = 10
                    GoSub RestoreScreenX
                    GoSub DrawBreakBox
                    _KeyClear
                  Case 72, 141 ' up/ctrl-up
                    X$ = ""
                    If Xcoor3 > 2 Then
                        Xcoor3 = Xcoor3 - 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 80, 145 ' down/ctrl-down
                    If Status Then
                        Z = 23
                    Else
                        Z = 24
                    End If
                    X$ = ""
                    If Xcoor3 + 7 < Z Then
                        Xcoor3 = Xcoor3 + 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 115 ' ctrl-left
                    X$ = ""
                    If Ycoor3 > 1 Then
                        Ycoor3 = Ycoor3 - 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 116 ' ctrl-right
                    X$ = ""
                    If Ycoor3 < 49 Then
                        Ycoor3 = Ycoor3 + 1
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                    _KeyClear
                  Case 152 ' alt-up
                    X$ = ""
                    If Xcoor3 > 5 Then
                        Xcoor3 = Xcoor3 - 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Xcoor3 > 2 Then
                          Xcoor3 = 2
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
                  Case 160 ' alt-dn
                    If Status Then
                        Z = 23
                    Else
                        Z = 24
                    End If
                    X$ = ""
                    If Xcoor3 + 7 < Z - 4 Then
                        Xcoor3 = Xcoor3 + 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Xcoor3 + 7 < Z Then
                          Xcoor3 = Z - 7
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
                  Case 155 ' alt-left
                    X$ = ""
                    If Ycoor3 > 4 Then
                        Ycoor3 = Ycoor3 - 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Ycoor3 > 1 Then
                          Ycoor3 = 1
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
                  Case 157 ' alt-right
                    X$ = ""
                    If Ycoor3 < 45 Then
                        Ycoor3 = Ycoor3 + 4
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    Else
                        If Ycoor3 < 49 Then
                          Ycoor3 = 49
                          GoSub RestoreScreenX
                          GoSub DrawBreakBox
                        End If
                    End If
                    _KeyClear
              End Select
        End Select
      End If
      If Status Then
        Z = 23
      Else
        Z = 24
      End If
      X = MouseDriver
      If MouseButton1 Then
        ' hover over titlebar
        If MouseX = Xcoor3 Then
            If MouseY >= Ycoor3 And MouseY <= Ycoor3 + 31 Then
              ' store mouse XY during click
              MouseTempX = MouseX
              MouseTempY = MouseY
              Do
                  X = MouseDriver
                  If MouseX Or MouseY Then ' drag
                    MoveBox = 0
                    ' difference in mouse X
                    If MouseX <> MouseTempX Then
                        If MouseX >= 2 And MouseX <= Z - 7 Then
                          Xcoor3 = MouseX
                          MouseTempX = MouseX
                          MoveBox = -1
                        End If
                    End If
                    ' difference in mouse Y
                    If MouseY <> MouseTempY Then
                        MoveY = Ycoor3 + (MouseY - MouseTempY)
                        If MoveY >= 1 And MoveY <= 49 Then
                          Ycoor3 = MoveY
                          MouseTempY = MouseY
                          MoveBox = -1
                        End If
                    End If
                    ' move box
                    If MoveBox Then
                        GoSub RestoreScreenX
                        GoSub DrawBreakBox
                    End If
                  End If
              Loop Until MouseButton1 = 0
            End If
        Else
            If MouseX = Xcoor3 + 5 Then
              If MouseY >= Ycoor3 + 2 And MouseY <= Ycoor3 + 5 Then
                  BoxButton = 1
                  Exit Do
              End If
              If MouseY >= Ycoor3 + 8 And MouseY <= Ycoor3 + 13 Then
                  BoxButton = 2
                  Exit Do
              End If
            End If
        End If
      Else
        If MouseX = Xcoor3 + 5 Then
            If MouseY >= Ycoor3 + 2 And MouseY <= Ycoor3 + 5 Then
              If BoxButton = 2 Then
                  BoxButton = 1
                  GoSub DrawBreakBoxButtons
              End If
            End If
            If MouseY >= Ycoor3 + 8 And MouseY <= Ycoor3 + 15 Then
              If BoxButton = 1 Then
                  BoxButton = 2
                  GoSub DrawBreakBoxButtons
              End If
            End If
        End If
      End If
      If MouseWheel Then
        If MouseWheel = -1 Then
            I$ = Chr$(0) + Chr$(72) ' up
            MousePressed = -1
            MouseWheel = 0
            X$ = ""
            If Xcoor3 > 2 Then
              Xcoor3 = Xcoor3 - 1
              GoSub RestoreScreenX
              GoSub DrawBreakBox
            End If
            _KeyClear
        End If
        If MouseWheel = 1 Then
            I$ = Chr$(0) + Chr$(80) ' down
            MousePressed = -1
            MouseWheel = 0
            If Status Then
              Z = 23
            Else
              Z = 24
            End If
            X$ = ""
            If Xcoor3 + 7 < Z Then
              Xcoor3 = Xcoor3 + 1
              GoSub RestoreScreenX
              GoSub DrawBreakBox
            End If
            _KeyClear
        End If
      End If
  Loop
  _Delay .2
  _KeyClear
  _Delay .2

  ' restore screen area.
  GoSub RestoreScreenX
  Color 7, 0
  Locate CurrentX, CurrentY, 1
  If BoxButton = 1 Then
      BreakBox = -1
  Else
      BreakBox = 0
  End If
  Exit Function

  ' draw box
  DrawBreakBox:
  Color BreakBoxBorderColor, BreakBackGround1
  Locate Xcoor3, Ycoor3, 0
  Print Chr$(ULcorner) + String$(30, Hline) + Chr$(URcorner);
  For RowX1 = Xcoor3 + 1 To Xcoor3 + 6
      Locate RowX1, Ycoor3, 0
      Print Chr$(Vline) + Space$(30) + Chr$(Vline);
  Next
  Locate Xcoor3 + 7, Ycoor3, 0
  Print Chr$(LLcorner) + String$(30, Hline) + Chr$(LRcorner);

  ' display box title
  Var0$ = " Break "
  TempX = 16 - Len(Var0$) \ 2 ' center of titlebar
  TempX = Ycoor3 + TempX
  If TempX < 1 Then TempX = 1
  Color BreakBoxTitleColor
  Locate Xcoor3, TempX, 0
  Print Var0$;

  ' display error text
  Color BreakBoxTextColor

  Var1$ = "Control-Break trap."
  Locate Xcoor3 + 1, Ycoor3 + 2, 0
  Print Var1$

  Var2$ = "Press <OK> to continue."
  Locate Xcoor3 + 2, Ycoor3 + 2, 0
  Print Var2$

  Var3$ = "Press <Quit> to end program."
  Locate Xcoor3 + 3, Ycoor3 + 2, 0
  Print Var3$

  GoSub DrawBreakBoxButtons
  Locate , , , 8, 8
  Return

  ' display buttuns
  DrawBreakBoxButtons:
  If BoxButton = 1 Then
      Locate Xcoor3 + 5, Ycoor3 + 2, 0
      Color BreakBoxButton1Color, BreakBackGround2
      Print "<OK>";
      Locate Xcoor3 + 5, Ycoor3 + 3, 0
      Color 13
      Print "O";

      Locate Xcoor3 + 5, Ycoor3 + 8, 0
      Color BreakBoxButton2Color, BreakBackGround2
      Print "<Quit>";
      Locate Xcoor3 + 5, Ycoor3 + 9, 0
      Color 13
      Print "Q";
  Else
      Locate Xcoor3 + 5, Ycoor3 + 2, 0
      Color BreakBoxButton2Color, BreakBackGround2
      Print "<OK>";
      Locate Xcoor3 + 5, Ycoor3 + 3, 0
      Color 13
      Print "O";

      Locate Xcoor3 + 5, Ycoor3 + 8, 0
      Color BreakBoxButton1Color, BreakBackGround2
      Print "<Quit>";
      Locate Xcoor3 + 5, Ycoor3 + 9, 0
      Color 13
      Print "Q";
  End If
  Color 7, 0
  Return

  ' screen save
  SaveScreenX:
  If Status Then
      V = 23
  Else
      V = 24
  End If
  For Var1 = 2 To V
      For Var2 = 1 To 80
        TempZ1 = Screen(Var1, Var2) ' screen char
        TempZ2 = Screen(Var1, Var2, 1) ' char color
        TempArrayY3((Var1 - 1) * 80 + Var2) = TempZ1
        TempArrayZ3((Var1 - 1) * 80 + Var2) = TempZ2
      Next
  Next
  Return

  ' screen restore
  RestoreScreenX:
  If Status Then
      V = 23
  Else
      V = 24
  End If
  For Var1 = 2 To V
      For Var2 = 1 To 80
        VarB = Int(TempArrayZ3((Var1 - 1) * 80 + Var2) / 16)
        VarF = TempArrayZ3((Var1 - 1) * 80 + Var2) Mod 16
        TempZ1 = TempArrayY3((Var1 - 1) * 80 + Var2)
        Locate Var1, Var2, 1
        Color VarF, VarB
        Print Chr$(TempZ1);
      Next
  Next
  Return
End Function

Rem processes mouse activity.
Function MouseDriver
  Static X1 As Integer, Y1 As Integer ' store old values
  MouseX = 0: MouseY = 0
  If _MouseInput Then
      X = CInt(_MouseX): Y = CInt(_MouseY) ' X,Y return single
      If X <> X1 Or Y <> Y1 Then
        X1 = X: Y1 = Y
        MouseX = Y: MouseY = X ' X,Y are reversed
        While _MouseInput: Wend ' empty buffer
        MousePressed = -1
      End If
      MouseButton1 = _MouseButton(1)
      If MouseButton1 Then
        MouseX = Y1
        MouseY = X1
        MousePressed = -1
      End If
      MouseButton2 = _MouseButton(2)
      If MouseButton2 Then
        MouseX = Y1
        MouseY = X1
        MousePressed = -1
      End If
      MouseButton3 = _MouseButton(3)
      If MouseButton3 Then
        MousePressed = -1
      End If
      MouseWheel = _MouseWheel
      If MouseWheel Then
        ' reverse mousewheel value
        If WheelReverse Then
            If MouseWheel = -1 Then
              MouseWheel = 1
            Else
              If MouseWheel = 1 Then
                  MouseWheel = -1
              End If
            End If
        End If
      End If
  End If
  MouseDriver = -1
End Function

Function INKEYz$
  _Limit 100
  X = _KeyHit
  If X Then
      If X < 0 Then
        Select Case X
            Case -12 ' keypad-5
              INKEYz$ = Chr$(0) + Chr$(76)
              KeyPressed = -1
            Case -108 ' ctrl-keypad-5
              INKEYz$ = Chr$(0) + Chr$(143)
              KeyPressed = -1
        End Select
      Else
        X$ = InKey$
        If Len(X$) Then
            INKEYz$ = X$
            KeyPressed = -1
        End If
      End If
  End If
End Function