[Code] WinScreen_Mouse

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
NNSoft
Beiträge: 50
Registriert: 29.11.2006 00:39
Kontaktdaten:

Beitrag von NNSoft »

ts-soft hat geschrieben:Nichts, nur es läuft unter Linux nicht :mrgreen:
Linux, ist das ein neues Waschmittel? :wink:
Benutzeravatar
Dostej
Beiträge: 529
Registriert: 01.10.2004 10:02
Kontaktdaten:

Beitrag von Dostej »

Danke für den Code. Werds mal testen
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

so, hier mal die non-API-version.

es entsteht kein so starker bruch in der bewegung beim betreten/verlassen
des screens wie ich befürchtet hatte.
aber der äußere 1-pixel-bereich an der screengrenze ist nicht nutzbar für die maus,
weil er zum umschalten benutzt wird.

Code: Alles auswählen

;**************************************** 
;*** WinScreen_Mouse_noAPI.pb
;***
;*** Skeleton for Mouse-Pointer Handling
;*** within a WindowedScreen.
;***
;*** by Kaeru Gaman, Dec.20th,2006
;*** PB Ver 4.02 Win
;*** without WinAPI, maybe adoptable for Linux
;**************************************** 

#WSrnW = 800
#WSrnH = 600

EnableExplicit

If Not InitSprite()
  MessageRequester("Error","No Sprite, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitSound()
  MessageRequester("Error","No Sound, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitKeyboard()
  MessageRequester("Error","No Keys, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitMouse()
  MessageRequester("Error","No Mouse, Man!", #MB_ICONERROR)
  End
EndIf
If Not OpenWindow(0, 0, 0, #WSrnW, #WSrnH, "WinScreen_Mouse" , #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget )
  MessageRequester("Error","No Window, Man!", #MB_ICONERROR)
  End
EndIf
If Not OpenWindowedScreen(WindowID(0), 0, 0, #WSrnW, #WSrnH, 0,0,0 )
  MessageRequester("Error","No Screen, Man!", #MB_ICONERROR)
  End
EndIf

;*************************************
;**** Prepare Main
;*************************************

Define WinEventID.l

Define EXIT.l       = 0     ;Exit-Flag
Define MCur.l       = 1     ;Show/Hide Status MousePointer
Define Focus.l      = 1     ;Focus-Flag of Game-Window

Define MPOS.COORD           ;MousePos
Define MLC.l     = 0        ;Mouse LeftClick
Define MRC.l     = 0        ;Mouse RightClick

Define Col.l     = 0        ;Color for Action

ReleaseMouse(0)             ;lock Mouse on screen
MouseLocate(1,1)            ;necessary to avoid check-conflicts on start
;**************************************************************************
;**** M A I N - L O O P
;**************************************************************************
Repeat
  ExamineKeyboard()
  WinEventID   = WindowEvent()

;{*** Focus-Test ***
  If Not IsScreenActive()
    Focus = 0 
  Else 
    Focus = 1 
  EndIf
;}

;*****************************************************
;**** Focus-Check and NoFocus Display
;*****************************************************
If Not Focus
  ClearScreen($404040)
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(100,100,"NoFocus",$C0C0C0)
  StopDrawing()
  Delay(100)
;*****************************************************
;**** Focus-Only 
;*****************************************************
Else
  ClearScreen($201008)

;{*** Mouse Status ***
  If MCur = 1
    ExamineMouse()        ; only check screen-mouse when active
    MPOS\X = MouseX()
    MPOS\Y = MouseY()
    MLC = MouseButton(1)
    MRC = MouseButton(2)
    If MPOS\X = 0 Or MPOS\Y = 0 Or MPOS\X = #WSrnW -1 Or MPOS\Y = #WSrnH -1
      MCur = 0
      ReleaseMouse(1)
    EndIf
  Else
    MPOS\X = WindowMouseX(0)
    MPOS\Y = WindowMouseY(0)
    If MPOS\X > 0 And  MPOS\Y > 0 And MPOS\X < #WSrnW -1 And MPOS\Y < #WSrnH -1
      MCur = 1
      ReleaseMouse(0)
      MouseLocate(MPOS\X,MPOS\Y)  ;necessary, since ReleaseMouse(0) sets screenmouse on 0,0
    EndIf
  EndIf
;}

;{*** Action ***
  If KeyboardPushed(#PB_Key_Space) Or MLC Or MRC
    If MLC
      Col = $2010C0
    ElseIf MRC
      Col = $10C020
    Else
      Col = $808080
    EndIf
    StartDrawing(ScreenOutput())
      FrontColor(Col)
      Circle(MPOS\X,MPOS\Y,32)
    StopDrawing()
  EndIf
;}

;{*** Mouse-Pointer Display ***
  If MCur = 1
    StartDrawing(ScreenOutput())
      FrontColor($20C0C0)
      Line(MPOS\X   ,MPOS\Y   , 24, 16)
      Line(MPOS\X   ,MPOS\Y   , 16, 24)
      Line(MPOS\X+24,MPOS\Y+16,-16, -8)
      Line(MPOS\X+16,MPOS\Y+24, -8,-16)
    StopDrawing()
  EndIf
;}

;{*** Escape - Test ***
  If KeyboardPushed(#PB_Key_Escape)
    EXIT = 1
  EndIf
  If WinEventID = #PB_Event_CloseWindow : EXIT=1 : EndIf
;}

;*****************************************************
;**** E N D  of Focus-Only 
;*****************************************************
EndIf

;**************************************************************************
;**** M A I N - L O O P - E N D
;**************************************************************************
  FlipBuffers()
  Delay(0)
Until EXIT = 1
;*************************************
End
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hier die auch Linux Version:

Code: Alles auswählen

;****************************************
;*** WinScreen_Mouse_noAPI.pb
;***
;*** Skeleton for Mouse-Pointer Handling
;*** within a WindowedScreen.
;***
;*** by Kaeru Gaman, Dec.20th,2006
;*** PB Ver 4.02 Win
;*** without WinAPI, maybe adoptable for Linux
;****************************************

#WSrnW = 800
#WSrnH = 600

EnableExplicit

CompilerIf Defined(COORD, #PB_Structure) = #False
Structure COORD
  X.w
  Y.w
EndStructure
CompilerEndIf

If Not InitSprite()
  MessageRequester("Error","No Sprite, Man!", 0)
  End
EndIf
If Not InitSound()
  MessageRequester("Error","No Sound, Man!", 0)
  End
EndIf
If Not InitKeyboard()
  MessageRequester("Error","No Keys, Man!", 0)
  End
EndIf
If Not InitMouse()
  MessageRequester("Error","No Mouse, Man!", 0)
  End
EndIf
If Not OpenWindow(0, 0, 0, #WSrnW, #WSrnH, "WinScreen_Mouse" , #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget )
  MessageRequester("Error","No Window, Man!", 0)
  End
EndIf
If Not OpenWindowedScreen(WindowID(0), 0, 0, #WSrnW, #WSrnH, 0,0,0 )
  MessageRequester("Error","No Screen, Man!", 0)
  End
EndIf

;*************************************
;**** Prepare Main
;*************************************

Define WinEventID.l

Define EXIT.l       = 0     ;Exit-Flag
Define MCur.l       = 1     ;Show/Hide Status MousePointer
Define Focus.l      = 1     ;Focus-Flag of Game-Window

Define MPOS.COORD           ;MousePos
Define MLC.l     = 0        ;Mouse LeftClick
Define MRC.l     = 0        ;Mouse RightClick

Define Col.l     = 0        ;Color for Action

ReleaseMouse(0)             ;lock Mouse on screen
MouseLocate(1,1)            ;necessary to avoid check-conflicts on start
;**************************************************************************
;**** M A I N - L O O P
;**************************************************************************
Repeat
  ExamineKeyboard()
  WinEventID   = WindowEvent()

;{*** Focus-Test ***
  If Not IsScreenActive()
    Focus = 0
  Else
    Focus = 1
  EndIf
;}

;*****************************************************
;**** Focus-Check and NoFocus Display
;*****************************************************
If Not Focus
  ClearScreen($404040)
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(100,100,"NoFocus",$C0C0C0)
  StopDrawing()
  Delay(100)
;*****************************************************
;**** Focus-Only
;*****************************************************
Else
  ClearScreen($201008)

;{*** Mouse Status ***
  If MCur = 1
    ExamineMouse()        ; only check screen-mouse when active
    MPOS\X = MouseX()
    MPOS\Y = MouseY()
    MLC = MouseButton(1)
    MRC = MouseButton(2)
    If MPOS\X = 0 Or MPOS\Y = 0 Or MPOS\X = #WSrnW -1 Or MPOS\Y = #WSrnH -1
      MCur = 0
      ReleaseMouse(1)
    EndIf
  Else
    MPOS\X = WindowMouseX(0)
    MPOS\Y = WindowMouseY(0)
    If MPOS\X > 0 And  MPOS\Y > 0 And MPOS\X < #WSrnW -1 And MPOS\Y < #WSrnH -1
      MCur = 1
      ReleaseMouse(0)
      MouseLocate(MPOS\X,MPOS\Y)  ;necessary, since ReleaseMouse(0) sets screenmouse on 0,0
    EndIf
  EndIf
;}

;{*** Action ***
  If KeyboardPushed(#PB_Key_Space) Or MLC Or MRC
    If MLC
      Col = $2010C0
    ElseIf MRC
      Col = $10C020
    Else
      Col = $808080
    EndIf
    StartDrawing(ScreenOutput())
      FrontColor(Col)
      Circle(MPOS\X,MPOS\Y,32)
    StopDrawing()
  EndIf
;}

;{*** Mouse-Pointer Display ***
  If MCur = 1
    StartDrawing(ScreenOutput())
      FrontColor($20C0C0)
      Line(MPOS\X   ,MPOS\Y   , 24, 16)
      Line(MPOS\X   ,MPOS\Y   , 16, 24)
      Line(MPOS\X+24,MPOS\Y+16,-16, -8)
      Line(MPOS\X+16,MPOS\Y+24, -8,-16)
    StopDrawing()
  EndIf
;}

;{*** Escape - Test ***
  If KeyboardPushed(#PB_Key_Escape)
    EXIT = 1
  EndIf
  If WinEventID = #PB_Event_CloseWindow : EXIT=1 : EndIf
;}

;*****************************************************
;**** E N D  of Focus-Only
;*****************************************************
EndIf

;**************************************************************************
;**** M A I N - L O O P - E N D
;**************************************************************************
  FlipBuffers()
  Delay(1)
Until EXIT = 1
;*************************************
End
Leider will OpenWindowedScreen nicht so wie es soll :(
Erzeugt mir 2 Fenster und nen Focus bekomme ich nicht hinein. Vielleicht
testet es mal eine anderer (edel-bezeichnung) linux-jünger, damit ich weiß
ob ein Bug vorliegt.

Gruß
Thomas
Zuletzt geändert von ts-soft am 21.12.2006 21:43, insgesamt 1-mal geändert.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

zusatzproblem:

das ReleaseMouse funktioniert nicht, wenn man per Alt-Tab den Task wechselt.

das wird umfangreicher, mach ich nimmer heut..
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Hallo Leute,

mir ist ein kleiner Bug in dem wasserdichten Code aufgefallen, wenn man das Fenster bewegt oder einen Button wie maximizegadget drückt, dann wird sobald die Mouse wieder auf den ScreenBereich kommt, der MouseButton für einen Frame als gedrückt angesehen und dargestellt. Irgendwie scheint also die Überprüfung nicht ganz zu klappen.

[Edit]
Sorry hab leider noch was gefunden, wenn man den Bildschirm nicht bei 0, 0 positioniert, springt die Maus einfach über den grauen Fensterbereich hinweg.
[/Edit]

Ansonsten: Spitze :allright:

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
ReneMiner
Beiträge: 58
Registriert: 20.07.2007 14:54
Wohnort: zwischen Westerwald und Siegerland

Beitrag von ReneMiner »

Kaeru Gaman hat geschrieben:> Warum nutzt du eigentlich API ?

öhm..
eine entsprechung von ShowCursor_() in reinem PB ist mir nicht bekannt...
...

Wieso lädst Du dann nicht einfach ein "unsichtbares" bzw. leeres MouseIcon?
Hat das einen speziellen Grund?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Wieso lädst Du dann nicht einfach ein "unsichtbares" bzw. leeres MouseIcon?
> Hat das einen speziellen Grund?

ginge doch auch nur über API, ist also doch gehuppt wie gesprungen.

...und in meinen augen ist es die "korrektere" lösung, etwas abzuschalten anstatt etwas unsichtbar zu machen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
ReneMiner
Beiträge: 58
Registriert: 20.07.2007 14:54
Wohnort: zwischen Westerwald und Siegerland

Beitrag von ReneMiner »

hmm, mein (Denk)Fehler,
ich dachte pb würde die MouseIcon-Eigenschaft eines Fensters oder Gadgets unterstützen - bin wohl noch zu verwöhnt vom ollen vb6 ;)
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

hier mal eine kleinere variante. ohne API.
alt-tab switch sollte auch gehen.

wenn das fentser nicht den fokus hat und man das fenster mit dem
desktop-cursor lediglich überfährt, bleibt die maus released. die maus
wird also nur captured wenn das fenster aktiviert ist.

Code: Alles auswählen

; by #NULL
InitSprite()
InitMouse()
ww=600
wh=400
hWin=OpenWindow(0, 50,50,ww,wh, "...")
OpenWindowedScreen( hWin, 0,0,ww,wh, 0,0,0)

mouseCaptured=1

Repeat
  ExamineMouse()
  mx=MouseX()
  my=MouseY()
  ; --- a mouse acceleration
  mx + MouseDeltaX()*0.8 ::: If mx<0 : mx=0 :: ElseIf mx>ww-1 : mx=ww-1 :: EndIf
  my + MouseDeltaY()*0.8 ::: If my<0 : my=0 :: ElseIf my>wh-1 : my=wh-1 :: EndIf
  MouseLocate(mx,my)
  ; --- 

  If mouseCaptured
    If mx=0 Or mx=(ww-1) Or my=0 Or my=(wh-1) Or Not IsScreenActive()
      mouseCaptured=0
      ReleaseMouse(1)
    EndIf
  Else;If Not mouseCaptured
    If WindowMouseX(0)>0 And WindowMouseX(0)<(ww-1) And WindowMouseY(0)>0 And WindowMouseY(0)<(wh-1) And IsScreenActive()
      mouseCaptured=1
      ReleaseMouse(0)
      mx=WindowMouseX(0)
      my=WindowMouseY(0)
      MouseLocate(mx,my)
    EndIf
  EndIf

  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_Transparent)
    If mouseCaptured
      ;draw a cursor
      LineXY(mx-3,my,mx+3,my,$00ff00)
      LineXY(mx,my-3,mx,my+3,$00ff00)
    EndIf
    ;debug
    DrawText(10,40,"mouseCaptured:"+Str(mouseCaptured),$666666)
  StopDrawing()

  event = WaitWindowEvent(80)
  FlipBuffers()
  ClearScreen($333333)
  Delay(10)
Until event = #PB_Event_CloseWindow
my pb stuff..
Bild..jedenfalls war das mal so.
Antworten