Guten Abend!
Als "Nebenprodukt" meiner Spielerein im Urlaub für meinen Messenger kam ein kleiner Code heraus der mit allerhand WinAPI-Gehacke mehrere Fenster "simuliert".
Also das ganze ist n bissi ein Fake, daher auch der Titel. Es gibt nach wie vor nur ein Graphics Fenster (welches übrigens von meiner Lib hier verwaltet wird) und von dem werden halt bestimmte Ausschnitte (Regionen) angezeigt.
Man kann damit und etwas weiterghender Spielerei (beispielsweise eigener GUI) mehrere Fenster in B3D darstellen.
Aber nochmal, das Ganze spielt sich auf einem Graphikbuffer ab, daher gibt es Probleme beim Überlappen von "Fenstern"... ich möchte hier nur die Grundlage anbieten, keine Komplettlösung. Je nach verwendeter GUI werdet ihr da selber noch einiges zu managen haben.
Hier die Funktionssammlung:
BlitzBasic: [AUSKLAPPEN] [EINKLAPPEN]
Type region Field x,y,w,h Field radius Field id End Type
Global main_region
Global drag_rgn.region Global drag_x,drag_y Global mouse_x,mouse_y
Global gfx_w,gfx_h Global gfx_off_x,gfx_off_y Global hwnd
SetWindowedFullscreen()
Function SetWindowedFullscreen() Local bank=CreateBank(16) api_SystemParametersInfo($0030,0,bank,0) Local x=PeekInt(bank,0) Local y=PeekInt(bank,4) Local x2=PeekInt(bank,8) Local y2=PeekInt(bank,12) FreeBank bank gfx_w=x2-x gfx_h=y2-y Graphics gfx_w,gfx_h,0,2 hwnd=SystemProperty("AppHWND") gfx_off_x=api_GetSystemMetrics(7) gfx_off_y=api_GetSystemMetrics(4)+api_GetSystemMetrics(8) api_SetWindowPos(hwnd,0,-gfx_off_x,-gfx_off_y,0,0,1) End Function
Const COMPLEXREGION = 3 Const SIMPLEREGION = 2 Const NULLREGION = 1 Const ERRORAPI = 0
Const RGN_AND = 1 Const RGN_COPY = 5 Const RGN_DIFF = 4 Const RGN_OR = 2 Const RGN_XOR = 3
Const WINDING = 2 Const ALTERNATE = 1
Function AddRegion.region(x,y,w,h,radius=0) FreeRegions() Local ret.region=New region ret\x=x ret\y=y ret\w=w ret\h=h ret\radius=radius Insert ret Before First region CreateMainRegion() api_SetWindowRgn(hwnd,main_region,True) Return ret End Function
Const LASTREGION_BEHAVE_NONE=0 Const LASTREGION_BEHAVE_RESTORE=1 Const LASTREGION_BEHAVE_INVISIBE=2 Const LASTREGION_BEHAVE_CLOSE=3
Function RemoveRegion(target.region,behave=LASTREGION_BEHAVE_CLOSE) If target=Null Then Return 0 If After target=Null And Before target=Null And behave=LASTREGION_BEHAVE_NONE Then Return 0 FreeRegions() If After target=Null And Before target=Null Then Select behave Case LASTREGION_BEHAVE_RESTORE main_region=api_CreateRectRgn(0+gfx_off_x,0+gfx_off_y,gfx_w+gfx_off_x,gfx_h+gfx_off_y) api_SetWindowRgn(hwnd,main_region,True) Case LASTREGION_BEHAVE_INVISIBE main_region=api_CreateRectRgn(0,0,0,0) api_SetWindowRgn(hwnd,main_region,True) Case LASTREGION_BEHAVE_CLOSE End End Select Delete target Return 0 EndIf Delete target CreateMainRegion() api_SetWindowRgn(hwnd,main_region,True) Return 1 End Function
Function SetRegionPosition(target.region,x,y) If target=Null Then Return 0 FreeRegions() target\x=x target\y=y CreateMainRegion() api_SetWindowRgn(hwnd,main_region,True) Return 1 End Function
Function FreeRegions() Local rgn.region If main_region<>0 Then api_DeleteObject(main_region) For rgn=Each region api_DeleteObject(rgn\id) Next End Function
Function CreateMainRegion() Local rgn.region For rgn=Each region If rgn\radius>0 Then rgn\id=api_CreateRoundRectRgn(rgn\x+gfx_off_x,rgn\y+gfx_off_y,rgn\w+rgn\x+gfx_off_x+1,rgn\h+rgn\y+gfx_off_y+1,rgn\radius,rgn\radius) Else rgn\id=api_CreateRectRgn(rgn\x+gfx_off_x,rgn\y+gfx_off_y,rgn\w+rgn\x+gfx_off_x,rgn\h+rgn\y+gfx_off_y) EndIf Next rgn.region=First region Local rgn2.region=rgn main_region=rgn\id Local temp,result Repeat rgn2=After rgn2 If rgn2=Null Then Exit temp=api_CreateRectRgn(0,0,0,0) result=api_CombineRgn(temp,main_region,rgn2\id,RGN_OR) If result<>NULLREGION And result<>ERRORAPI Then api_DeleteObject(main_region) main_region=temp EndIf Forever End Function
Function StartDragRegion(rgn.region) If drag_rgn=Null Then GetGlobalMouse() drag_rgn=rgn drag_x=mouse_x-rgn\x drag_y=mouse_y-rgn\y EndIf End Function
Function DragRegion(autostop=True) If drag_rgn<>Null Then GetGlobalMouse() SetRegionPosition(drag_rgn,mouse_x-drag_x,mouse_y-drag_y) If autostop Then If Not MouseDown(1) Then StopDragRegion() EndIf EndIf End Function
Function StopDragRegion() drag_rgn=Null End Function
Function GetGlobalMouse() Local bank=CreateBank(8) api_GetCursorPos(bank) mouse_x=PeekInt(bank,0) mouse_y=PeekInt(bank,4) FreeBank bank End Function
und ein Beispiel dazu:
BlitzBasic: [AUSKLAPPEN] [EINKLAPPEN]
Include "Regionen.bb"
SetBuffer BackBuffer()
Local main.region=AddRegion((gfx_w-120)/2,(gfx_h-70)/2,120,70,20)
Global mx,my,mhit Local rgn.region Local timer=CreateTimer(50)
Repeat mx=MouseX() my=MouseY() mhit=MouseHit(1) DragRegion() For rgn=Each region If rgn<>main Then Rect rgn\x,rgn\y,rgn\w,rgn\h,0 Text rgn\x+rgn\w/2,rgn\y+10,"Drag me!",1 If mx>rgn\x And mx<rgn\x+rgn\w And my>rgn\y And my<rgn\y+rgn\h Then If MouseDown(1) Then StartDragRegion(rgn) EndIf EndIf If Button(rgn\x+10,rgn\y+30,"Schließen") Then RemoveRegion(rgn) EndIf EndIf Next If Button(main\x+10,main\y+10,"Neues Fenster") Then temp2.region=AddRegion(main\x,main\y+main\h,120,60) EndIf If Button(main\x+10,main\y+40,"Beenden") Then End EndIf Flip 0:Cls WaitTimer timer Until KeyHit(1) End
Function Button(x,y,txt$) Rect x,y,100,20,0 Text x+50,y+10,txt$,1,1 If mx>x And mx<x+100 And my>y And my<y+20 Then Rect x+1,y+1,98,18,0 If mhit Then mhit=False Return True EndIf EndIf Return False End Function
Wie schon geschrieben, läuft da vieles über die WinAPI - das einbinden der verlinkten USerlibs würde ich euch bitten selbst zu können...
Ich kann für alle die kein B3D haben auch mal das Beispiel kompilieren.
Zum Abschluß noch ein kleines Danke an the freak der ich in gewisser Maßen auf die Idee brachte
mfG, Christoph.
PS: Mir ist bewußt dass dieser Code am Anfang irgendwie zu nichts taugt und viel zu spezifisch ist... ja er benötigt Einarbeitungszeit aber ich hoffe schon bald im Rahmen meines Projektes für das der Code eigentlich entstand zeigen zu können was damit möglich ist
|