 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 25.07.2010, 20:39 Titel: [ WINDOWS ] fbWindow - So viele GFX-Fenster wie ihr wollt!! |
|
|
Hallo zusammen, es gibt ein neues "kleines" Projekt von mir:
der fbWindow-Datentyp .. oder Klasse?
Jedes fbWindow-Object erzeugt sein eigenes GFX-Fenster welches man über einen normalen fb-image-buffer ansprechen kann:
hier die fbwindow.bi-Datei:
Code: |
' created by OneCypher ON 2010/07/25
' modified by Cherry ON 2010/07/28
#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "windows.bi"
TYPE fbWindow
'fbWindows can be created WITH default-CONSTRUCTOR.
'Created WITH default CONSTRUCTOR causes the same WINDOW-size AS the gfx-WINDOW AND MS-Windows decides where TO place THIS WINDOW ON the SCREEN
'IF attachHWnd IS used, all other parameters except FrameRate are ignored [by Cherry]
DECLARE CONSTRUCTOR(attachHWnd AS ANY PTR = 0,LEFT AS INTEGER = CW_USEDEFAULT, top AS INTEGER = CW_USEDEFAULT, width1 AS INTEGER = 0, height AS INTEGER = 0, title AS STRING = "", resizable1 AS INTEGER = TRUE,FrameRate1 AS INTEGER = 30)
DECLARE DESTRUCTOR()
PUBLIC:
'The title of THIS WINDOW:
DECLARE PROPERTY title AS STRING
DECLARE PROPERTY title(v AS STRING)
'POINTER TO the image-buffer structure
fbimage AS fb.image PTR
'you can READ its WIDTH WITH: fbimage->WIDTH
'AND its height WITH: fbimage->height
'OR just CALL "imageinfo fbimage, WIDTH, height"
'IF QuitMessage IS true, the used clicked ON the closebutton of THIS WINDOW
QuitMessage AS INTEGER = FALSE
'Set true TO make the WINDOW resizable
Resizable AS INTEGER = TRUE
'DEFINE the framerate of THIS WINDOW
FrameRate AS INTEGER = 30
'CALL DoEvents TO refesh SCREEN, keyboard AND mouse
DECLARE SUB DoEvents()
'IF you want TO CLOSE THIS WINDOW CALL THIS SUB:
DECLARE SUB CLOSE()
'IF you want TO OPEN THIS WINDOW again CALL THIS SUB:
DECLARE SUB reopen(LEFT AS INTEGER = CW_USEDEFAULT, top AS INTEGER = CW_USEDEFAULT, Width1 AS INTEGER = 0, Height AS INTEGER = 0)
'IF you want TO attach THIS instance of fbWindow TO a existing WINDOW (OR owner-drawn control), CALL THIS FUNCTION: [by Cherry]
DECLARE FUNCTION Attach(hWnd2 AS ANY PTR) AS Boolean
'IF you want TO CLEAR the SCREEN:
DECLARE SUB CLS()
'GETMOUSE() similar TO GFX-GETMOUSE
DECLARE SUB GETMOUSE(BYREF mousex AS INTEGER = 0,BYREF mousey AS INTEGER=0,BYREF mouses AS INTEGER=0,BYREF mouseb AS INTEGER=0)
'INKEY() FUNCTION similar TO GFX-INKEY
DECLARE FUNCTION INKEY() AS STRING
'Position of mouse AS a POINT-structure
mpos AS POINT
'X-Mouse position
mx AS INTEGER
'Y-Mouse positionde
my AS INTEGER
'Mousewheel (same scroll-behavior AS GFX)
ms AS INTEGER
'Mousebuttons (only LEFT AND RIGHT mouse-buttons are implemented)
mb AS INTEGER
'DO NOT USE: INKEY-Buffer (internal buffer)
ink AS STRING
declare function Resized as integer
'DO NOT USE: Resized-Message (internal message)
declare property resized_flag aS INTEGER
declare property resized_flag (v as integer)
'DO NOT USE: WINDOW-Handle-Functions (only used internally)
DECLARE FUNCTION onPaint() AS INTEGER
DECLARE FUNCTION onCreate() AS INTEGER
DECLARE FUNCTION onDestroy() AS INTEGER
PRIVATE:
'Pixels points TO the pixel-content of the fb.image-buffer
resized_state as integer
resized_internal as integer
pixels AS ANY PTR
'Remember when you started drawing the last frame
LastFrame AS DOUBLE
'PAINT-Structure TO PAINT the content of the WINDOW
pnt AS PAINTSTRUCT
'the Device-Content of THIS WINDOW
hDC AS HDC
'TmpImage-Buffer .. THIS IS where old buffer go TO die
TmpImage AS fb.image PTR
'The WINDOW-Client coordinates
WinSize AS RECT
'Some Windows-API-Stuff...
wMsg AS MSG
szAppName AS ZSTRING * 30 => "fbWindow"
hWnd AS HWND
wcls AS WNDCLASS
'AND a bitmap-header
bmi AS bitmapv4header
'The title-buffer
title_buffer AS STRING
END TYPE
function fbwindow.resized as integer
function = resized_state
resized_state = false
end function
property fbwindow.resized_flag as integer
return resized_internal
end property
property fbwindow.resized_flag (v as integer)
resized_internal = v
if v then resized_state = v
end property
FUNCTION WndProc ( BYVAL hWnd AS HWND,BYVAL message AS UINT, BYVAL wParam AS WPARAM,BYVAL lParam AS LPARAM ) AS LRESULT
DIM fbw AS fbWindow PTR = getprop(hwnd,"fbWindow")
DIM mwheel AS SHORT
FUNCTION = 0
SELECT CASE AS CONST message
CASE WM_SIZE
IF fbw <> 0 THEN
WITH *fbw
IF .resizable AND (wparam = SIZE_RESTORED OR wparam = Size_maximized) THEN .resized_flag = TRUE
END WITH
END IF
CASE WM_LBUTTONDOWN
IF fbw <> 0 THEN
IF fbw->mb = 2 THEN fbw->mb = 3
IF fbw->mb = 0 THEN fbw->mb = 1
END IF
CASE WM_LBUTTONUP
IF fbw <> 0 THEN
IF fbw->mb = 3 THEN fbw->mb = 2
IF fbw->mb = 1 THEN fbw->mb = 0
END IF
CASE WM_RBUTTONDOWN
IF fbw <> 0 THEN
IF fbw->mb = 1 THEN fbw->mb = 3
IF fbw->mb = 0 THEN fbw->mb = 2
END IF
CASE WM_RBUTTONUP
IF fbw <> 0 THEN
IF fbw->mb = 3 THEN fbw->mb = 1
IF fbw->mb = 2 THEN fbw->mb = 0
END IF
CASE WM_MOUSEMOVE
IF fbw <> 0 THEN
fbw->mx = LOWORD(lParam)
fbw->my = HIWORD(lParam)
END IF
CASE WM_MOUSEWHEEL
mwheel = HIWORD(wParam)
fbw->ms = fbw->ms + (mwheel / WHEEL_DELTA)
CASE WM_CLOSE
' send CLOSE message [by Cherry]
IF fbw <> 0 THEN fbw->ink = CHR(255,ASC("k"))
CASE WM_KEYDOWN
IF fbw <> 0 THEN
IF wparam = 38 THEN fbw->ink = CHR( 255,72)
IF wparam = 40 THEN fbw->ink = CHR( 255,80)
IF wparam = 37 THEN fbw->ink = CHR( 255,75)
IF wparam = 39 THEN fbw->ink = CHR( 255,77)
IF wparam = 46 THEN fbw->ink = CHR( 255,83)
END IF
CASE WM_CHAR
IF fbw <> 0 THEN fbw->ink = CHR(wParam)
CASE WM_TIMER
' use a TIMER FOR painting, in CASE THIS has been attached TO a WINDOW [by Cherry]
IF wParam = 50000 THEN redrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE)
CASE WM_PAINT
IF fbw <> 0 THEN FUNCTION = fbw->Onpaint()
CASE WM_DESTROY
IF fbw <> 0 THEN FUNCTION = fbw->Ondestroy()
CASE ELSE
FUNCTION = DefWindowProc(hWnd, message, wParam, lParam )
END SELECT
END FUNCTION
FUNCTION fbWindow.INKEY() AS STRING
DIM tmp AS STRING = ink
ink = ""
RETURN tmp
END FUNCTION
SUB fbWindow.CLOSE()
QuitMessage = TRUE
DestroyWindow Hwnd
Hwnd = 0
IF fbimage <> 0 THEN
IMAGEDESTROY fbimage
fbimage = 0
END IF
END SUB
FUNCTION fbWindow.Attach(hWnd2 AS ANY PTR) AS Boolean
IF IsWindow(hWnd2) = FALSE THEN RETURN FALSE
FUNCTION = TRUE
QuitMessage = FALSE
IF hWnd <> hWnd2 AND IsWindow(hWnd) THEN THIS.CLOSE
hWnd = hWnd2
GetClientRect(hWnd, @WinSize)
DIM wintitle AS ZSTRING * 500
GetWindowText(hWnd, @wintitle, 500)
title_buffer = wintitle
SetWindowLong(hWnd, GWL_WNDPROC, cast(long, @WndProc))
DIM AS INTEGER iw, ih, p
WITH bmi
.bV4Size = LEN(BITMAPV4HEADER)
.bv4width=WinSize.RIGHT
.bv4height= -(WinSize.bottom)
.bv4planes= 1
.bv4bitcount=32
.bv4v4compression=0
.bv4sizeimage=(WinSize.RIGHT) * (WinSize.bottom) *4
.bV4RedMask = &h0F00
.bV4GreenMask = &h00F0
.bV4BlueMask = &h000F
.bV4AlphaMask = &hF000
END WITH
fbimage = IMAGECREATE(WinSize.RIGHT, WinSize.bottom, RGB(0,0,0))
ImageInfo fbimage,iw,ih,,p,Pixels
WITH WinSize
IF (iw * 4) <> p THEN
bmi.bv4width = .RIGHT + ((p - (iw *4)) / 4)
ELSE
bmi.bv4width = .RIGHT
END IF
bmi.bv4height= -(.bottom)
END WITH
SetProp(hwnd,"fbWindow", @THIS)
' use a TIMER FOR painting, in CASE THIS has been attached TO a WINDOW [by Cherry]
SetTimer(hWnd, 50000, 1000 / FrameRate, 0)
UpdateWindow( hwnd )
END FUNCTION
SUB fbWindow.Reopen(LEFT AS INTEGER = CW_USEDEFAULT, top AS INTEGER = CW_USEDEFAULT, Width1 AS INTEGER = 0, Height AS INTEGER = 0)
QuitMessage = FALSE
IF Hwnd <> 0 THEN THIS.CLOSE
IF Width1 = 0 THEN Width1 = WinSize.RIGHT
IF Height = 0 THEN Height = WinSize.bottom
IF Width1 = 0 AND Height = 0 THEN
SCREENINFO width1, height
END IF
WITH wcls
.style = CS_HREDRAW OR CS_VREDRAW
.lpfnWndProc = @WndProc
.cbClsExtra = 0
.cbWndExtra = 0
.hInstance = GetModuleHandle( NULL )
.hIcon = LoadIcon( NULL, IDI_APPLICATION )
.hCursor = LoadCursor( NULL, IDC_ARROW )
.hbrBackground = GetStockObject(WHITE_BRUSH )
.lpszMenuName = NULL
.lpszClassName = @szAppName
END WITH
RegisterClass @wcls
'GET required WINDOW rect FOR the given client size [by Cherry]
Var wstyles = WS_OVERLAPPEDWINDOW OR WS_CAPTION
IF Resizable = false THEN wstyles AND= NOT (WS_SIZEBOX OR WS_MAXIMIZEBOX)
Var adjustedSize = TYPE<RECT>(0, 0, Width1, Height)
AdjustWindowRect(@adjustedSize, wstyles, FALSE)
Attach(CreateWindowEx(0, szAppName, title, wstyles, LEFT, top, adjustedSize.RIGHT - adjustedSize.LEFT, adjustedSize.bottom - adjustedSize.top, NULL, NULL, wcls.hInstance, NULL))
ShowWindow(hWnd, SW_NORMAL)
END SUB
SUB fbWindow.GETMOUSE(BYREF mousex AS INTEGER = 0,BYREF mousey AS INTEGER=0,BYREF mouses AS INTEGER=0,BYREF mouseb AS INTEGER=0)
mousex = mx: mousey = my: mouses = ms: mouseb = mb
END SUB
SUB fbWindow.DoEvents()
IF QuitMessage = FALSE THEN
IF PeekMessage( @wMsg, NULL, 0,0, PM_Remove) THEN
IF wmsg.message= WM_QUIT THEN
QuitMessage = TRUE
EXIT SUB
END IF
TranslateMessage( @wMsg )
DispatchMessage( @wMsg )
END IF
'IF fbimage <> 0 THEN redrawwindow (hwnd,0,0,rdw_invalidate)
END IF
END SUB
SUB fbWindow.CLS()
DIM AS INTEGER iw, ih
ImageInfo fbimage,iw,ih
LINE fbimage, (0,0)-(iw,ih),RGB(0,0,0),BF
END SUB
FUNCTION fbWindow.onpaint() AS INTEGER
DIM AS INTEGER iw, ih, p
IF QuitMessage = FALSE THEN
hDC = BeginPaint(hWnd, @pnt)
IF TIMER > (LastFrame + (1 / FrameRate)) THEN
WITH WinSize
' use -1 FOR top, otherwise there IS a white LINE (don't ask me why) [by Cherry]
StretchDIBits hDC, 0, -1,.RIGHT - .LEFT+1,.bottom-.top+1, 0, 0, .RIGHT - .LEFT+1, .bottom-.top+1,pixels,CPTR(bitmapinfo PTR, @bmi), DIB_RGB_COLORS, SRCCOPY
END WITH
LastFrame = TIMER
END IF
EndPaint hWnd, @pnt
IF resized_flag THEN
print "resized"
GetClientRect( hWnd, @WinSize)
tmpImage = fbimage
WITH WinSize
fbimage = IMAGECREATE(.RIGHT,.bottom,RGB(0,0,0))
ImageInfo fbimage,iw,ih,,p,Pixels
IF (iw * 4) <> p THEN
bmi.bv4width = .RIGHT + ((p - (iw *4)) / 4)
ELSE
bmi.bv4width = .RIGHT
END IF
bmi.bv4height= -( .bottom)
bmi.bv4sizeimage = (bmi.bv4width) * (.bottom+1) *4
END WITH
IMAGEDESTROY TmpImage
resized_flag = FALSE
END IF
END IF
RETURN 0
END FUNCTION
FUNCTION fbWindow.onDestroy() AS INTEGER
DIM fbw AS fbWindow PTR = getprop(hwnd,"fbWindow")
IF QuitMessage = FALSE THEN
IF fbimage <> 0 THEN
IMAGEDESTROY fbimage
fbimage = 0
END IF
DestroyWindow Hwnd
Hwnd = 0
QuitMessage = TRUE
ENDIF
RETURN 0
END FUNCTION
PROPERTY fbWindow.title AS STRING
RETURN title_buffer
END PROPERTY
PROPERTY fbWindow.title(v AS STRING)
IF v <> title_buffer THEN
title_buffer = v
SetWindowText(hWnd, v)
END IF
END PROPERTY
CONSTRUCTOR fbWindow(attachHWnd AS ANY PTR = 0,LEFT AS INTEGER = CW_USEDEFAULT, top AS INTEGER = CW_USEDEFAULT, width1 AS INTEGER = 0, height AS INTEGER = 0, title1 AS STRING = "", resizable1 AS INTEGER = TRUE,FrameRate1 AS INTEGER = 30)
' IF no real FBGFX SCREEN IS there, create it
IF SCREENPTR = NULL THEN SCREENRES 320, 240, 32, 1, FB.GFX_NULL
FrameRate = FrameRate1
IF IsWindow(attachHWnd) THEN
Attach(attachHWnd)
ELSE
Resizable = resizable1
title_buffer = title1
reopen LEFT,top,width1,height
ENDIF
END CONSTRUCTOR
DESTRUCTOR fbWindow()
THIS.CLOSE
END DESTRUCTOR
|
Und hier ein Beispiel mit fbWindow als Referenz initialisiert:
Code: |
#include "fbwindow.bi"
Dim as integer ScreenWidth, ScreenHeight
screen 14,32
screeninfo ScreenWidth, ScreenHeight
dim screens(1 to 8) as fbwindow
dim ink as string
Do
ink = inkey
for i as integer = 1 to 8
if screens(i).fbimage <> 0 then
imageinfo screens(i).fbimage, ScreenWidth, ScreenHeight
screens(i).cls
draw string screens(i).fbimage, (1,2), "Screen no. " & i, RGB(0,0,0)
draw string screens(i).fbimage, (1,2), "Screen no. " & i, RGB(0,0,0)
draw string screens(i).fbimage, (2,1), "Screen no. " & i, RGB(0,0,0)
draw string screens(i).fbimage, (2,1), "Screen no. " & i, RGB(0,0,0)
draw string screens(i).fbimage, (1,1), "Screen no. " & i, RGB(255,255,255)
line screens(i).fbimage, (int(rnd*ScreenWidth),int(rnd*ScreenHeight))-(int(rnd*ScreenWidth),int(rnd*ScreenHeight)), RGB(int(rnd*255),int(rnd*255),int(rnd*255)),BF
screens(i).doevents
end if
next
if ink = "r" then
for i as integer = 1 to 8
if screens(i).QuitMessage then
print "Reopen screen " & i
screens(i).reopen
end if
next
end if
if ink = "-" then
screens(4).Close
end if
if ink = "+" then
screens(4).reopen
end if
Loop until ink = "q"
|
und hier ein Beispiel wo fbWindow dynamisch dazu und rausgeladen werden kann:
Code: |
#include "fbwindow.bi"
Dim as integer ScreenWidth, ScreenHeight
screen 14,32
screeninfo ScreenWidth, ScreenHeight
dim screens(1 to 8) as fbwindow ptr
for i as integer = 1 to 8
screens(i) = new fbwindow
next
dim ink as string
Do
ink = inkey
for i as integer = 1 to 8
if screens(i) <> 0 then
with *screens(i)
if .fbimage <> 0 then
imageinfo .fbimage, ScreenWidth, ScreenHeight
.cls
draw string .fbimage, (1,2), "Screen no. " & i, RGB(0,0,0)
draw string .fbimage, (1,2), "Screen no. " & i, RGB(0,0,0)
draw string .fbimage, (2,1), "Screen no. " & i, RGB(0,0,0)
draw string .fbimage, (2,1), "Screen no. " & i, RGB(0,0,0)
draw string .fbimage, (1,1), "Screen no. " & i, RGB(255,255,255)
line .fbimage, (int(rnd*ScreenWidth),int(rnd*ScreenHeight))-(int(rnd*ScreenWidth),int(rnd*ScreenHeight)), RGB(int(rnd*255),int(rnd*255),int(rnd*255)),BF
.doevents
end if
end with
end if
next
if ink = "-" then
if screens(4) <> 0 then delete screens(4):screens(4) = 0: print "deleted"
end if
if ink = "+" then
if screens(4) <> 0 then
if screens(4)->quitmessage then screens(4)->reopen: print "reopened"
else
screens(4) = new fbwindow: print "new"
end if
end if
Loop until ink = "q"
|
Kurze beschreibung:
mit der Taste q kann man die Beispiele immer beenden. (man muss allerdings das original GFX-Fenster im fokus haben)
die Taste + und - öffnet und schließt das 4. Fenster.
im 1. Beispiel öffnet die Taste r wieder alle fenster.
(das fehlt im 2. beispiel)
Ich denke, es gäbe noch einiges was man da implementieren könnte. Bin auch noch lange nicht fertig
Aber man kanns schon ganz gut gebrauchen
Vielleicht hat ein Linuxer ja eine Idee wie man sowas für Linux umsetzt.
Dann könnte man eine Plattform-Unabhängige Klasse draus machen.
(Das wäre echt SUPER!!!!)
Viel Spaß beim Ausprobieren, und lasst von euch hören wie es bei euch so funktioniert!!
(bei mir bisher ohne Abstürze oder ähnliches)
Zuletzt bearbeitet von OneCypher am 04.08.2010, 14:23, insgesamt 5-mal bearbeitet |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 25.07.2010, 21:45 Titel: Re: [ WINDOWS ] fbWindow - So viele GFX-Fenster wie ihr woll |
|
|
OneCypher hat Folgendes geschrieben: | Vielleicht hat ein Linuxer ja eine Idee wie man sowas für Linux umsetzt.
Dann könnte man eine Plattform-Unabhängige Klasse draus machen.
(Das wäre echt SUPER!!!!) |
Ja.
Du nimmst ne zweite Binary und lässt deine Klasse mit der Binary über Localsockets quatschen. |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 25.07.2010, 22:36 Titel: |
|
|
Du meinst, die Pixel-Daten per TCP/IP von einem programm zum anderen schicken?
Hatte ich mir auch schon mal überlegt. Aber wenn man eine kompakte ausführbare binary haben will ist das wieder zu umständlich.
Ich bin sogar davon überzeugt, das sowas wie ichs mit der W-API realisiert hatte in der art auch unter linux geht!
Mir sind mal ein paar beispiele zur X11.bi in die hände gefallen die etwas ähnliches machen konnten. Allerdings kam ich da einfach nich mehr weiter... |
|
Nach oben |
|
 |
Cherry
Anmeldungsdatum: 20.06.2007 Beiträge: 249
|
Verfasst am: 25.07.2010, 23:10 Titel: |
|
|
Die WindowTitle-Funktion sollte noch rein, imo. Aber sonst find ich das genial :A |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 26.07.2010, 13:25 Titel: |
|
|
@Cherry: Ich such schon wie bekloppt .. aber ich find einfach kein kommando mit dem man den titel nachträglich ändern kann
Gibts keinen API-Guru der da kurz weiterhelfen kann? |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 26.07.2010, 13:33 Titel: |
|
|
WindowTitle ??
Tut mir leid wenn es jetzt falsch ist, aber ich denke doch, dass es das ist, was ihr sucht, oder?  |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 26.07.2010, 13:38 Titel: |
|
|
@Westbeam: *lol* .. ich wollte noch dazu schreiben, dass jetzt keiner die Referenz für WindowTitle posten soll XXD .. ich mein den Windows-API befehl zum ändern eines Fenster-titels.
Mit "windowtitle" kann man nur den titel des GFX-Fensters ändern. Ich will aber zur laufzeit die Titel von Fenstern ändern, die man per createwindowex() erstellt hat. |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 26.07.2010, 13:48 Titel: |
|
|
Achso, tut mir leid. Dann kann ich dir nicht helfen. Von Windows habe ich keine Ahnung(bin Linuxer)  |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 26.07.2010, 13:54 Titel: |
|
|
Wie wär's mit SetWindowText?  _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
The_Muh aka Mark Aroni

Anmeldungsdatum: 11.09.2006 Beiträge: 718
|
Verfasst am: 26.07.2010, 14:07 Titel: |
|
|
Hab mal mit einer DLL rum gespielt die nen gfx-fenster gemacht hat (neben dem Hauptprogramm) hat einigermaßen funktioniert, wenn man das ganze verfeinert kann man das bestimmt benutzen... wenn ich den Code noch hätte würde ich ihn Posten, leider war das ganze für mein damaliges Projekt ungeeignet.
Lief ungefähr so ab: Hauptprogramm läd DLL und ruft init() aus der DLL auf. DLL->init() macht nen gfx-screen und gibt die internen callbacks (zum ausgeben von Grafik) ans Hauptprogramm zurück (in einem type). danach konnte Hauptprogramm in beiden Fenster rumzeichnen. War alles andere als ausgereift, die Benutzung war fürn arsch und es is ab und an abgestürzt - aber es hat funktioniert.
Ob man damit auch mehr als 2 gfx-Fenster machen kann weiß ich aber nicht. ich benutze in letzter Zeit gerne SDL  _________________ // nicht mehr aktiv // |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 26.07.2010, 15:54 Titel: |
|
|
@OneCypher:
Zum einen kann man durch Localsockets ziemlich viel an Daten durchschieben. Zum anderen brauchst du nicht immer Pixeldaten durchschieben, Primitiva kann man so übertragen. Text nicht, da der von den gfx-Fonts abhängt, die der User ´ja auch verändern kann. Put muss Pixeldaten schieben, Get nicht, das kann man mit einem lokalen Puffer machen. |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 26.07.2010, 17:16 Titel: |
|
|
@Jojo: Vielen Dank! Das habe ich gesucht .. UND
Ich habe die fbWindow.bi - Datei oben aktualisiert !!
Jetzt kann man auch zur laufzeit den Fenstertitel lesen und setzen
@The_muh: Ja ich weiss.. aber die lösung ist ziemlicher "mist" wenn ich das mal so ausdrücken darf.. DENN: Wenn man ein GFX-Fenster in einer DLL initialisiert funktionieren Inkey und Getmouse nicht. Und man muss so viele DLL-Dateien vorbereiten, wie man fenster öffnen möchte. Das ist alles andere als elegant!
Und mit SDL kann man leider auch nur ein Fenster öffnen .. bzw ein GFX und ein SDL fenster.. ab da an wars das...
@28398:
Hm.. also, ich denke auf ein und demselben rechner würde sich das nicht lohnen. Als eine art Netzwerkfähiges GFX-Fenster wäre das vielleicht interessant.
Ein Server gibt seine grafik auf den netzwerk-clients aus und die netzwerk-clients geben ihre tastatur und maus-informationen an der server zurück.
Serverseitig könnte man das dann programmieren, wie ein "normales" gfx-fenster.. hmm..
Ist nur die frage wie es dann mitm traffic aussäh.. |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 26.07.2010, 20:41 Titel: |
|
|
Ähm dir ist schon klar, dass unter Unix Localsockets so ziemlich der IPC-Standard sind? |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 26.07.2010, 20:59 Titel: |
|
|
@28398: Ja ich weiss das es unter unix so üblich ist. Hab auch schon programme programmiert die über lo0 miteinander per tcp/ip kommunizieren..
Aber einerseits gehts in dem Fred hier noch um die Windows-Umsetzung und andererseits ist das was du beschreibst, ein separates Projekt wert!
Möchte nur nicht, das sich das jetzt hier zu sehr vermischt... dann gehts ein bischen zu sehr offtopic..
Mit Wine funktioniert dieses fbWindow-Projekt übrigens auch ziemlich gut unter linux  |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 27.07.2010, 16:01 Titel: |
|
|
OneCypher hat Folgendes geschrieben: | Viel Spaß beim Ausprobieren, und lasst von euch hören wie es bei euch so funktioniert!! |
Auf Vista (Business) mit SP2 funktioniert's einwandfrei, soweit ich es bisher getestet habe.
Die Include ist mir bestimmt noch mal irgendwann nützlich. Gute Idee auf jeden Fall.
Allerdings kann man sich die Demoprogramme nicht lange antun... *AugenReib*  _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 27.07.2010, 16:59 Titel: |
|
|
Sowas in der Art hatte ich auch schon erarbeitet, bis ich es verworfen habe, eben aus dem Problem, dass es nicht portierbar ist.
Ein paar Kleinigkeiten, die du eventuell anpassen könntest:
Code: | .style = CS_DBLCLKS Or CS_VREDRAW Or CS_HREDRAW
.hIcon = LoadIcon(.hInstance, "FB_PROGRAM_ICON"):If Not (.hIcon) Then LoadIcon(NULL, IDI_APPLICATION)
.hbrBackground = GetStockObject(BLACK_BRUSH) |
und im Style bei CreateWindowEx:
Code: | WS_OVERLAPPEDWINDOW And Not(WS_THICKFRAME) Or WS_VISIBLE |
So sollte es auch die Icons laden und das Fenster ist FB-ähnlicher. |
|
Nach oben |
|
 |
Cherry
Anmeldungsdatum: 20.06.2007 Beiträge: 249
|
Verfasst am: 27.07.2010, 23:10 Titel: |
|
|
Noch eine kleine, etwas "erweiterte" Idee: Anstatt dass ein Fenster erzeugt und dort reingezeichnet wird, könntest du optional ein hWnd zu einem Ownerdraw Control entgegennehmen und dort hinzeichnen. Damit könnte man z.B. mit WinAPI ein Dialogfenster mit Buttons und Co. machen, und dann ein oder zwei solche Controls reinpappen, wo man dann mit fbWindow reinmalen kann - das wär mal wirklich toll. |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 28.07.2010, 02:28 Titel: |
|
|
Du kannst auch einfach so in nem Dialogfeld mithilfe eines belibiegen Controls rumkritzeln. |
|
Nach oben |
|
 |
Cherry
Anmeldungsdatum: 20.06.2007 Beiträge: 249
|
Verfasst am: 28.07.2010, 09:25 Titel: |
|
|
Ja, aber nicht über die altbekannten FBGFX-Befehle. |
|
Nach oben |
|
 |
Cherry
Anmeldungsdatum: 20.06.2007 Beiträge: 249
|
Verfasst am: 28.07.2010, 14:52 Titel: |
|
|
Ich habe mir erlaubt, das ganze etwas zu erweitern:
Code: | ' modified by Cherry on 2010/07/28
#Include "fbgfx.bi"
#Include Once "windows.bi"
Type fbWindow
'fbWindows can be created with default-constructor.
'Created with default constructor causes the same window-size as the gfx-window and MS-Windows decides where to place this window on the screen
'if attachHWnd is used, all other parameters except FrameRate are ignored [by Cherry]
Declare Constructor(attachHWnd As Any Ptr = 0,Left As Integer = CW_USEDEFAULT, top As Integer = CW_USEDEFAULT, width1 As Integer = 0, height As Integer = 0, title As String = "", resizable1 As Integer = TRUE,FrameRate1 As Integer = 30)
Declare Destructor()
Public:
'The title of this window:
Declare Property title As String
Declare Property title(v As String)
'Pointer to the image-buffer structure
fbimage As fb.image Ptr
'you can read its width with: fbimage->width
'and its height with: fbimage->height
'Or just call "imageinfo fbimage, width, height"
'If QuitMessage is true, the used clicked on the closebutton of this window
QuitMessage As Integer = FALSE
'Set true to make the window resizable
Resizable As Integer = TRUE
'Define the framerate of this window
FrameRate As Integer = 30
'Call DoEvents to refesh screen, keyboard and mouse
Declare Sub DoEvents()
'If you want to close this window call this sub:
Declare Sub Close()
'If you want to open this window again call this sub:
Declare Sub reopen(Left As Integer = CW_USEDEFAULT, top As Integer = CW_USEDEFAULT, Width1 As Integer = 0, Height As Integer = 0)
'If you want to attach this instance of fbWindow to a existing window (or owner-drawn control), call this function: [by Cherry]
Declare Function Attach(hWnd2 As Any Ptr) As Boolean
'If you want to clear the screen:
Declare Sub Cls()
'GetMouse() similar to GFX-GetMouse
Declare Sub GetMouse(ByRef mousex As Integer = 0,ByRef mousey As Integer=0,ByRef mouses As Integer=0,ByRef mouseb As Integer=0)
'Inkey() function similar to GFX-Inkey
Declare Function InKey() As String
'Position of mouse as a point-structure
mpos As Point
'X-Mouse position
mx As Integer
'Y-Mouse position
my As Integer
'Mousewheel (same scroll-behavior as GFX)
ms As Integer
'Mousebuttons (only left and right mouse-buttons are implemented)
mb As Integer
'DO NOT USE: Inkey-Buffer (internal buffer)
ink As String
'DO NOT USE: Resized-Message (internal message)
resized As Integer = FALSE
'DO NOT USE: Window-Handle-Functions (only used internally)
Declare Function onPaint() As Integer
Declare Function onCreate() As Integer
Declare Function onDestroy() As Integer
Private:
'Pixels points to the pixel-content of the fb.image-buffer
pixels As Any Ptr
'Remember when you started drawing the last frame
LastFrame As Double
'Paint-Structure to paint the content of the window
pnt As PAINTSTRUCT
'the Device-Content of this Window
hDC As HDC
'TmpImage-Buffer .. this is where old buffer go to die
TmpImage As fb.image Ptr
'The Window-Client coordinates
WinSize As RECT
'Some Windows-API-Stuff...
wMsg As MSG
szAppName As ZString * 30 => "fbWindow"
hWnd As HWND
wcls As WNDCLASS
'And a bitmap-header
bmi As bitmapv4header
'The title-buffer
title_buffer As String
End Type
Function WndProc ( ByVal hWnd As HWND,ByVal message As UINT, ByVal wParam As WPARAM,ByVal lParam As LPARAM ) As LRESULT
Dim fbw As fbWindow Ptr = getprop(hwnd,"fbWindow")
Dim mwheel As Short
Function = 0
Select Case As Const message
Case WM_SIZE
If fbw <> 0 Then
With *fbw
If .resizable And (wparam = SIZE_RESTORED Or wparam = Size_maximized) Then .resized = TRUE
End With
End If
Case WM_LBUTTONDOWN
If fbw <> 0 Then
If fbw->mb = 2 Then fbw->mb = 3
If fbw->mb = 0 Then fbw->mb = 1
End If
Case WM_LBUTTONUP
If fbw <> 0 Then
If fbw->mb = 3 Then fbw->mb = 2
If fbw->mb = 1 Then fbw->mb = 0
End If
Case WM_RBUTTONDOWN
If fbw <> 0 Then
If fbw->mb = 1 Then fbw->mb = 3
If fbw->mb = 0 Then fbw->mb = 2
End If
Case WM_RBUTTONUP
If fbw <> 0 Then
If fbw->mb = 3 Then fbw->mb = 1
If fbw->mb = 2 Then fbw->mb = 0
End If
Case WM_MOUSEMOVE
If fbw <> 0 Then
fbw->mx = LoWord(lParam)
fbw->my = HiWord(lParam)
End If
Case WM_MOUSEWHEEL
mwheel = HiWord(wParam)
fbw->ms = fbw->ms + (mwheel / WHEEL_DELTA)
Case WM_CLOSE
' send close message [by Cherry]
If fbw <> 0 Then fbw->ink = Chr(255,Asc("k"))
Case WM_KEYDOWN
If fbw <> 0 Then
If wparam = 38 Then fbw->ink = Chr( 255,72)
If wparam = 40 Then fbw->ink = Chr( 255,80)
If wparam = 37 Then fbw->ink = Chr( 255,75)
If wparam = 39 Then fbw->ink = Chr( 255,77)
If wparam = 46 Then fbw->ink = Chr( 255,83)
End If
Case WM_CHAR
If fbw <> 0 Then fbw->ink = Chr(wParam)
Case WM_TIMER
' use a timer for painting, in case this has been attached to a window [by Cherry]
If wParam = 50000 Then RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE)
Case WM_PAINT
If fbw <> 0 Then Function = fbw->Onpaint()
Case WM_DESTROY
If fbw <> 0 Then Function = fbw->Ondestroy()
Case Else
Function = DefWindowProc(hWnd, message, wParam, lParam )
End Select
End Function
Function fbWindow.Inkey() As String
Dim tmp As String = ink
ink = ""
Return tmp
End Function
Sub fbWindow.close()
QuitMessage = TRUE
DestroyWindow Hwnd
Hwnd = 0
If fbimage <> 0 Then
ImageDestroy fbimage
fbimage = 0
End If
End Sub
Function fbWindow.Attach(hWnd2 As Any Ptr) As Boolean
If IsWindow(hWnd2) = FALSE Then Return FALSE
Function = TRUE
QuitMessage = FALSE
If hWnd <> hWnd2 And IsWindow(hWnd) Then This.Close
hWnd = hWnd2
GetClientRect(hWnd, @WinSize)
Dim wintitle As ZString * 500
GetWindowText(hWnd, @wintitle, 500)
title_buffer = wintitle
SetWindowLong(hWnd, GWL_WNDPROC, @WndProc)
Dim As Integer iw, ih, p
With bmi
.bV4Size = Len(BITMAPV4HEADER)
.bv4width=WinSize.right
.bv4height= -(WinSize.bottom)
.bv4planes= 1
.bv4bitcount=32
.bv4v4compression=0
.bv4sizeimage=(WinSize.right) * (WinSize.bottom) *4
.bV4RedMask = &h0F00
.bV4GreenMask = &h00F0
.bV4BlueMask = &h000F
.bV4AlphaMask = &hF000
End With
fbimage = ImageCreate(WinSize.right, WinSize.bottom, RGB(0,0,0))
ImageInfo fbimage,iw,ih,,p,Pixels
With WinSize
If (iw * 4) <> p Then
bmi.bv4width = .right + ((p - (iw *4)) / 4)
Else
bmi.bv4width = .right
End If
bmi.bv4height= -(.bottom)
End With
SetProp(hwnd,"fbWindow", @This)
' use a timer for painting, in case this has been attached to a window [by Cherry]
SetTimer(hWnd, 50000, 1000 / FrameRate, 0)
UpdateWindow( hwnd )
End Function
Sub fbWindow.Reopen(Left As Integer = CW_USEDEFAULT, top As Integer = CW_USEDEFAULT, Width1 As Integer = 0, Height As Integer = 0)
QuitMessage = FALSE
If Hwnd <> 0 Then This.Close
If Width1 = 0 Then Width1 = WinSize.right
If Height = 0 Then Height = WinSize.bottom
If Width1 = 0 And Height = 0 Then
ScreenInfo width1, height
End If
With wcls
.style = CS_HREDRAW Or CS_VREDRAW
.lpfnWndProc = @WndProc
.cbClsExtra = 0
.cbWndExtra = 0
.hInstance = GetModuleHandle( NULL )
.hIcon = LoadIcon( NULL, IDI_APPLICATION )
.hCursor = LoadCursor( NULL, IDC_ARROW )
.hbrBackground = GetStockObject(WHITE_BRUSH )
.lpszMenuName = NULL
.lpszClassName = @szAppName
End With
RegisterClass @wcls
'Get required window rect for the given client size [by Cherry]
Var wstyles = WS_OVERLAPPEDWINDOW Or WS_CAPTION
If Not Resizable Then wstyles And= Not (WS_SIZEBOX Or WS_MAXIMIZEBOX)
Var adjustedSize = Type<RECT>(0, 0, Width1, Height)
AdjustWindowRect(@adjustedSize, wstyles, FALSE)
Attach(CreateWindowEx(0, szAppName, title, wstyles, Left, top, adjustedSize.right - adjustedSize.left, adjustedSize.bottom - adjustedSize.top, NULL, NULL, wcls.hInstance, NULL))
ShowWindow(hWnd, SW_NORMAL)
End Sub
Sub fbWindow.getmouse(ByRef mousex As Integer = 0,ByRef mousey As Integer=0,ByRef mouses As Integer=0,ByRef mouseb As Integer=0)
mousex = mx: mousey = my: mouses = ms: mouseb = mb
End Sub
Sub fbWindow.DoEvents()
If QuitMessage = FALSE Then
If PeekMessage( @wMsg, NULL, 0,0, PM_Remove) Then
If wmsg.message=WM_QUIT Then
QuitMessage = TRUE
Exit Sub
End If
TranslateMessage( @wMsg )
DispatchMessage( @wMsg )
End If
If fbimage <> 0 Then redrawwindow (hwnd,0,0,rdw_invalidate)
End If
End Sub
Sub fbWindow.Cls()
Dim As Integer iw, ih
ImageInfo fbimage,iw,ih
Line fbimage, (0,0)-(iw,ih),RGB(0,0,0),BF
End Sub
Function fbWindow.onpaint() As Integer
Dim As Integer iw, ih, p
If QuitMessage = FALSE Then
hDC = BeginPaint(hWnd, @pnt)
If Timer > (LastFrame + (1 / FrameRate)) Then
With WinSize
' use -1 for top, otherwise there is a white line (don't ask me why) [by Cherry]
StretchDIBits hDC, 0, -1,.Right - .Left+1,.bottom-.top+1, 0, 0, .Right - .Left+1, .bottom-.top+1,pixels,CPtr(bitmapinfo Ptr, @bmi), DIB_RGB_COLORS, SRCCOPY
End With
LastFrame = Timer
End If
EndPaint hWnd, @pnt
If resized Then
GetClientRect( hWnd, @WinSize)
tmpImage = fbimage
With WinSize
fbimage = ImageCreate(.right,.bottom,RGB(0,0,0))
ImageInfo fbimage,iw,ih,,p,Pixels
If (iw * 4) <> p Then
bmi.bv4width = .right + ((p - (iw *4)) / 4)
Else
bmi.bv4width = .right
End If
bmi.bv4height= -( .bottom)
bmi.bv4sizeimage = (bmi.bv4width) * (.bottom+1) *4
End With
ImageDestroy TmpImage
resized = FALSE
End If
End If
Return 0
End Function
Function fbWindow.onDestroy() As Integer
Dim fbw As fbWindow Ptr = getprop(hwnd,"fbWindow")
If QuitMessage = FALSE Then
If fbimage <> 0 Then
ImageDestroy fbimage
fbimage = 0
End If
DestroyWindow Hwnd
Hwnd = 0
QuitMessage = TRUE
EndIf
Return 0
End Function
Property fbWindow.title As String
Return title_buffer
End Property
Property fbWindow.title(v As String)
If v <> title_buffer Then
title_buffer = v
SetWindowText(hWnd, v)
End If
End Property
Constructor fbWindow(attachHWnd As Any Ptr = 0,Left As Integer = CW_USEDEFAULT, top As Integer = CW_USEDEFAULT, width1 As Integer = 0, height As Integer = 0, title1 As String = "", resizable1 As Integer = TRUE,FrameRate1 As Integer = 30)
' if no real FBGFX screen is there, create it
If ScreenPtr = NULL Then ScreenRes 320, 240, 32, 1, FB.GFX_NULL
FrameRate = FrameRate1
If IsWindow(attachHWnd) Then
Attach(attachHWnd)
Else
Resizable = resizable1
title_buffer = title1
reopen Left,top,width1,height
EndIf
End Constructor
Destructor fbWindow()
This.close
End Destructor |
Neuigkeiten:
- Die weiße Linie am oberen Ende des Bildes wurde entfernt
- Dein Workaround mit WinWidth und Co. wurde durch das dafür gedachte AdjustWindowRect ersetzt
- Im Constructor hast du die Property "Title" statt title_buffer aufgerufen, was keinen Sinn ergibt, wenn es noch kein Fenster gibt
- Wenn man bei einem Fenster auf "X" klickt, wird es nun nicht mehr sofort geschlossen, sondern wie beim echten FBGFX ein Chr(255)+"k" in InKey geschrieben
- Ist noch kein FBGFX-Screen vorhanden, wird, um Fehler zu vermeiden, einer erzeugt (unsichtbar, mit 32bpp)
- Es gibt eine neue Function fbWindow.Attach(hWnd), mit der ein bestehendes Window zu einem Screen umfunktioniert werden kann (das ist, was ich oben vorgeschlagen habe), dementsprechend wurde der Constructor um einen attachHWnd-Parameter erweitert. So kann man jetzt einfach mit FBEdit ein Static Control o.ä. in einen Dialog einbauen und es zu einem Screen machen.
- Dafür gibts jetzt einen Timer, der das Fenster invalidatet.
Ein Beispiel dazu:
.bas
Code: | #Include Once "windows.bi"
#define IDD_DLG1 1000
#define IDC_BTN1 1001
#define IDC_STC1 1002
#define IDC_STC2 1003
#Include "fbwindow.bi"
Dim Shared fbw1 As fbWindow Ptr
Dim Shared fbw2 As fbWindow Ptr
Dim Shared hInstance As HMODULE
hInstance = GetModuleHandle(NULL)
Declare Function DlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Function DlgProc(ByVal hWin As HWND,ByVal uMsg As UINT,ByVal wParam As WPARAM,ByVal lParam As LPARAM) As Integer
Dim As Long id, Event, x, y
Select Case uMsg
Case WM_INITDIALOG
fbw1 = New fbWindow(GetDlgItem(hWin, IDC_STC1))
fbw2 = New fbWindow(GetDlgItem(hWin, IDC_STC2))
Draw String fbw1->fbimage, (0, 0), "This is screen 1"
Draw String fbw2->fbimage, (0, 0), "and scrn. 2"
'
Case WM_CLOSE
EndDialog(hWin, 0)
'
Case WM_COMMAND
id=LoWord(wParam)
Event=HiWord(wParam)
Select Case id
Case IDC_BTN1
Circle fbw1->fbimage, (20, 20), 6, RGB(255, 0, 0)
Line fbw2->fbimage, (5, 10)-(15, 30), RGB(0, 255, 0), BF
'
End Select
'
Case Else
Return FALSE
'
End Select
Return TRUE
End Function
Function Main(cmd As String) As Integer
DialogBoxParam(hInstance, IDD_DLG1, NULL, @DlgProc, NULL)
Return 0
End Function
'''
''' Main call
'''
End(Main(Command))
|
.rc
Code: | #define IDD_DLG1 1000
#define IDC_BTN1 1001
#define IDC_STC1 1002
#define IDC_STC2 1003
IDD_DLG1 DIALOGEX 6,5,194,107
CAPTION "Cherry App"
FONT 8,"MS Sans Serif",400,0,0
STYLE 0x10CE0800
BEGIN
CONTROL "Click me",IDC_BTN1,"Button",0x50010000,126,83,64,19
CONTROL "IDC_STC",IDC_STC1,"Static",0x50000000,15,9,123,48
CONTROL "IDC_STC",IDC_STC2,"Static",0x50000000,66,72,57,33
END
|

mfG Cherry |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|