Hi Leute,
ich möchte mich für ein kleines nochmal an die Windows-Programmierung wagen. Dabei geht es um was ganz simples, was aber vermutlich wieder Windows-API notwendig macht und wo ich nicht weiß, ob das in Windows 10 überhaupt noch so gut geht.
Und zwar will ich ein ganz schmales randloses Fenster erstellen, dass sich von ganz links bis ganz rechts über den Bildschirm erstreckt, aber nur wenige Pixel hoch ist und einfach nur einfarbig ist. Das Fenster soll immer sichtbar, also always on top sein. Dann möchte ich z.B. durch das Drücken von STRG+ALT und gleichzeitigem Scrollen am Mausrad das Fenster nach oben und unten verschieben können, und zwar ohne dass das Fenster den Fokus haben muss.
Vermutlich sind das wenige Zeilen Code, aber gerade scheitert es bei mir an allem. Always On Top werde ich sicherlich noch irgendwo in der WinAPI-Sammlung von RSBasic finden oder in der Sammlung auf Github von Sicro. Aber die Sache mit dem Abfangen des Scrollrades und der Tasten wird mir vermutlich Probleme bereiten, da man da ja wahrscheinlich Hooks verwenden muss. Sind diese Hooks überhaupt noch erlaubt oder kommt dann gleich der Virenscanner oder sogar Windows selbst und meckert, weil das ja ein Keylogger sein könnte?
Always-On-Top Window, Keyboard- und Mouse-Hooks
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Always-On-Top Window, Keyboard- und Mouse-Hooks
on top ist einfach dünkt mir
Zur Hookerei fällt mir erstmal nichts ein.
ausser
https://www.rsbasic.de/aktualisierung/w ... se-Hook.pb
Code: Alles auswählen
Enumeration
#win1
#win2
#bg
EndEnumeration
ExamineDesktops()
wx=DesktopWidth(0)
Select fenster
Case 1 ; zeigt in der Taskleiste ein Fenster
OpenWindow(#win2,0,0,wx,10,"finster",#PB_Window_BorderLess)
Case 0 ; zeigt in der Taskleiste kein Fenster
OpenWindow(#win1,0,0,0,0,"Parent",#PB_Window_Invisible)
OpenWindow(#win2,0,0,wx,10,"finster",#PB_Window_BorderLess,WindowID(#win1))
EndSelect
StickyWindow(#win2,1)
CanvasGadget(#bg,0,0,WindowWidth(#win2),WindowHeight(#win2))
StartDrawing (CanvasOutput(#bg))
Box(0,0,WindowWidth(#win2),WindowHeight(#win2),#Red)
StopDrawing()
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
ausser
https://www.rsbasic.de/aktualisierung/w ... se-Hook.pb
pb aktuell5.7 - windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Always-On-Top Window, Keyboard- und Mouse-Hooks
Bin gut voran gekommen. Noch eine weitere Frage zu diesem Code:
Wie kann ich es verhindern, dass man Fenster nach links oder rechts verschieben kann? Ich möchte, dass man es nur hoch und runter schieben kann.
Code: Alles auswählen
If OpenWindow(0,0,0,500,250,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
Repeat
EventID=WaitWindowEvent()
Select EventID
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(0),#WM_NCLBUTTONDOWN, #HTCAPTION,0)
EndSelect
Until EventID = #PB_Event_CloseWindow
EndIf
Re: Always-On-Top Window, Keyboard- und Mouse-Hooks
hier ganz ohne API:
(geklaut von Danilo (https://www.purebasic.fr/english/viewto ... 66#p429066) und ein wenig angepasst)
Grüße ... Peter
Code: Alles auswählen
Enumeration
#Window
#Button
#Canvas
EndEnumeration
Procedure Exit()
End
EndProcedure
Procedure LeftMouseDown()
Shared MouseDown, OffsetX, OffsetY
MouseDown = #True
OffsetX = WindowMouseX(#Window)
OffsetY = WindowMouseY(#Window)
EndProcedure
Procedure LeftMouseUp()
Shared MouseDown
MouseDown = #False
EndProcedure
Procedure MouseMove()
Shared MouseDown, OffsetX, OffsetY
If MouseDown And GetGadgetAttribute(#Canvas, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
ResizeWindow(#Window, 0, DesktopMouseY() - OffsetY, #PB_Ignore, #PB_Ignore)
EndIf
EndProcedure
ExamineDesktops()
If OpenWindow(#Window, 0, 0, DesktopWidth(0),20, "Moveable window", #PB_Window_BorderLess)
ButtonGadget(#Button, 0, 0, 20, 20, "X")
BindEvent(#PB_Event_Gadget, @Exit(), #Window, #Button, #PB_EventType_LeftClick)
CanvasGadget(#Canvas, 20, 0, DesktopWidth(0) - 20, 20)
BindEvent(#PB_Event_Gadget, @LeftMouseDown(), #Window, #Canvas, #PB_EventType_LeftButtonDown)
BindEvent(#PB_Event_Gadget, @LeftMouseUp() , #Window, #Canvas, #PB_EventType_LeftButtonUp)
BindEvent(#PB_Event_Gadget, @MouseMove() , #Window, #Canvas, #PB_EventType_MouseMove)
If StartDrawing(CanvasOutput(#Canvas))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()
EndIf
StickyWindow(#Window, #True)
Repeat
WaitWindowEvent()
ForEver
EndIf
Grüße ... Peter
Hygge
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Always-On-Top Window, Keyboard- und Mouse-Hooks
Ich hab mir das jetzt wie folgt so zusammengehackt. Aber zuerst die Bedienung:
STRG+ALT 500ms gedrückt halten und das Fenster wird sichtbar bzw. unsichtbar.
Drückt man STRG+ALT nur kurz während es sichtbar ist, springt das Fenster zur aktuellen Mausposition. Das geht auch mit mehreren Desktops.
Hält man STRG+ALT gedrückt und bewegt die Maus, dann folgt ihr das Fenster. Solange man die Maus bewegt, wird das Fenster nicht nach 500ms unsichtbar.
Gibt man dem Fenster den Fokus, wird es grün und so kann man es auch per Drag&Drop verschieben oder mit dem Mausrad die Höhe ändern.
Beenden geht nur, wenn das Fenster grün ist und man Alt+F4 drückt.
Und noch was zur Qualität des Codes ansich: Er ist definitiv noch nicht ausgereift. Einige Dinge gehen bestimmt eleganter und ohne WindowTimer, sondern mit BindGadget oder ähnlichem. Mal sehen, ob ich das noch ändern will.
STRG+ALT 500ms gedrückt halten und das Fenster wird sichtbar bzw. unsichtbar.
Drückt man STRG+ALT nur kurz während es sichtbar ist, springt das Fenster zur aktuellen Mausposition. Das geht auch mit mehreren Desktops.
Hält man STRG+ALT gedrückt und bewegt die Maus, dann folgt ihr das Fenster. Solange man die Maus bewegt, wird das Fenster nicht nach 500ms unsichtbar.
Gibt man dem Fenster den Fokus, wird es grün und so kann man es auch per Drag&Drop verschieben oder mit dem Mausrad die Höhe ändern.
Beenden geht nur, wenn das Fenster grün ist und man Alt+F4 drückt.
Und noch was zur Qualität des Codes ansich: Er ist definitiv noch nicht ausgereift. Einige Dinge gehen bestimmt eleganter und ohne WindowTimer, sondern mit BindGadget oder ähnlichem. Mal sehen, ob ich das noch ändern will.
Code: Alles auswählen
EnableExplicit
Global lineHeight = 10
#toggleTime = 500
Define.i normalColor = RGB(255, 0, 0)
Define.i activatedColor = RGB(0, 127, 0)
Enumeration Windows
#parentWindow
#mainWindow
EndEnumeration
Global ctrlPressed.i = #False
Global altPressed.i = #False
Define windowDrag.i = #False
Define visible.i = #False
Define singleRefresh.i = #True
Procedure.l KeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Protected pressed.i, used = #True
If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
pressed = #True
EndIf
If wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP
EndIf
Select *p\vkCode
Case %10100010:
ctrlPressed = pressed
Case %10100100:
altPressed = pressed
Default
used = #False
EndSelect
If used
ProcedureReturn 1
PostEvent(#PB_Event_MoveWindow, #mainWindow, 0)
Else
ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndIf
EndProcedure
Procedure.w MouseWheelDelta()
Protected x.w
x.w = ((EventwParam() >> 16) & $FFFF)
ProcedureReturn (x / 120)
EndProcedure
ExamineDesktops()
Define.i windowWidth = DesktopWidth(0)
If Not OpenWindow(#parentWindow, 0, 0, 0, 0, "Parent", #PB_Window_Invisible)
End
EndIf
If Not OpenWindow(#mainWindow, 0, 0, windowWidth, lineHeight, "Lesehilfe", #PB_Window_BorderLess | #PB_Window_Invisible, WindowID(#parentWindow))
End
EndIf
SetWindowsHookEx_(#WH_KEYBOARD_LL, @KeyboardHook(), GetModuleHandle_(0), 0)
SetWindowColor(#mainWindow, normalColor)
SetWindowLongPtr_(WindowID(#mainWindow), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(#mainWindow), #GWL_EXSTYLE) | #WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(#mainWindow), 0, 127, #LWA_ALPHA)
StickyWindow(#mainWindow, #True)
Define.i toggleTimer.i = ElapsedMilliseconds()
Define.i oldY.i = WindowY(#mainWindow), newY.i
Define.i oldX.i = WindowX(#mainWindow), newX.i
AddWindowTimer(#mainWindow, 0, 50)
Repeat
Define eventId.i = WaitWindowEvent()
If (ctrlPressed And altPressed) Or windowDrag Or singleRefresh :
If visible :
newY = DesktopMouseY()
newX = DesktopMouseX()
Define cDesktop.i = ExamineDesktops()
Define desktop
For desktop = 0 To cDesktop - 1
If newY >= DesktopY(desktop) And newY < DesktopY(desktop) + DesktopHeight(desktop) And newX >= DesktopX(desktop) And newX < DesktopX(desktop) + DesktopWidth(desktop)
ResizeWindow(#mainWindow, DesktopX(desktop), newY - lineHeight / 2, DesktopWidth(desktop), lineHeight)
Break
EndIf
Next
If newY <> oldY
toggleTimer = ElapsedMilliseconds()
EndIf
oldY = newY
EndIf
If ElapsedMilliseconds() - #toggleTime > toggleTimer
HideWindow(#mainWindow, visible, #PB_Window_NoActivate)
visible = Bool(Not visible)
toggleTimer = ElapsedMilliseconds()
EndIf
singleRefresh = #False
Else
toggleTimer = ElapsedMilliseconds()
EndIf
If GetActiveWindow() = #mainWindow
SetWindowColor(#mainWindow, activatedColor)
Else
SetWindowColor(#mainWindow, normalColor)
EndIf
Select eventId
Case #WM_LBUTTONDOWN:
windowDrag = #True
Case #WM_LBUTTONUP
windowDrag = #False
Case #WM_MOUSEWHEEL
lineHeight + MouseWheelDelta()
If lineHeight < 4
lineHeight = 4
EndIf
singleRefresh = #True
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver