chaos.mod/desktopext.mod can do that, and more:
Public Domain by hamZta, Suco-X, d-bug
See below:
Public Domain by hamZta, Suco-X, d-bug
See below:
'-- HEADER ---------------------------------------------------------------------------------------------------------------------- Rem bbdoc: DesktopExt about: DesktopExt dient der Komunikation zwischen BMax und dem Desktop, ohne dabei auf MaxGUI Funktionen zurück greifen zu müssen. End Rem Module chaos.desktopext ModuleInfo "Version: 1.13" ModuleInfo "Author: hamZta, Suco-X, d-bug" ModuleInfo "License: Public Domain" ModuleInfo "Contact: d-bug@..." ModuleInfo "Homepage: www.chaos-interactive.de" ModuleInfo "History: 1.13 DesktopRatio hinzu" ModuleInfo "History: 1.12 Macos 'identifer screen not found' bug behoben" ModuleInfo "History: 1.11 Win32 Unterstützung mehrerer Desktops überarbeitet (danke klepto2 und Suco-X)" ModuleInfo "History: 1.10 Unterstützung mehrerer Monitore für Win32 implementiert" ModuleInfo "History: 1.09 Pixmap wird wieder konvertiert" ModuleInfo "History: 1.08 Optionaler Flip und Pixmapformatierung bei DesktopPixmap implementiert" ModuleInfo "History: 1.07 Unterstützung mehrerer Monitore für MacOS implementiert" ModuleInfo "History: 1.06 'TPixmap not found' repariert" ModuleInfo "History: 1.05 DesktopMouseX() bzw DesktopMouseY() für Win32" ModuleInfo "History: 1.04 DesktopPixmap() für Win32" ModuleInfo "History: 1.03 Dokumentation ist ab jetzt in deutsch" ModuleInfo "History: 1.02 Scope von dbug. nach chaos. geändert" ModuleInfo "History: 1.01 ReleaseDC eingefügt" ModuleInfo "History: 1.00 Erster Release (16.05.2006)" SuperStrict Import brl.standardio Import brl.pixmap Import brl.linkedlist ?Win32 Import pub.win32 Private Const SM_CXVIRTUALSCREEN:Int = 78 Const SM_CYVIRTUALSCREEN:Int = 79 Const SM_CMONITORS:Int = 80 Const SM_SAMEDISPLAYFORMAT:Int = 81 Type TDisplay Global List:TList = New TList Field id:Int Field handle:Int Field x:Int Field y:Int Field width:Int Field height:Int End Type Type TRect Field rLeft:Int Field rTop:Int Field rRight:Int Field rBottom:Int End Type Extern "Win32" Function GetSystemMetrics:Int (nIndex:Int)"Win32" Function EnumDisplayMonitors:Int (hdc:Int, lprcClip:Byte Ptr, lpfnEnum:Byte Ptr, dwData:Byte Ptr)"Win32" Function GetCursorPos(lpPoint:Byte Ptr)"Win32" = "GetCursorPos@4" Function GetDIBits(hdc:Int, bitmap:Int, Start:Int, Num:Int, bits:Byte Ptr, lpbi:Byte Ptr, usage:Int)"Win32" Function GetWindowDC(hwnd:Int)"Win32" Function ReleaseDC(hwnd:Int, hdc:Int)"Win32" End Extern Function MonitorEnumProc:Byte (hMonitor:Int,hdcMonitor:Int,lprcMonitor:Byte Ptr,dwData:Int) Local tempRect:TRect = New TRect MemCopy(tempRect, lprcMonitor, SizeOf(tempRect)) Local display:TDisplay = New TDisplay TDisplay.List.AddLast(display) display.id = TDisplay.List.Count() display.handle = hMonitor display.x = tempRect.rLeft display.y = tempRect.rTop display.width = tempRect.rRight - display.x display.height = tempRect.rBottom - display.y Return True End Function EnumDisplayMonitors (Null , Null , MonitorEnumProc , Null) Public ?MacOS Import "macscreen.c" Private Extern Function CGDisplayCurrentMode:Byte Ptr(displayID:Byte Ptr)"MacOS" Function CGGetActiveDisplayList:Byte Ptr(kMaxDisplays:Int, display:Byte Ptr, numDisplays:Int Var)"MacOS" Function MACOS_GetWidth:Int(mode:Byte Ptr)"C" Function MACOS_GetHeight:Int(mode:Byte Ptr)"C" Function MACOS_GetBPP:Int(mode:Byte Ptr)"C" Function MACOS_GetHertz:Int(mode:Byte Ptr)"C" End Extern Public ?Linux Import brl.graphics ? Rem bbdoc: Aspekt-Ratio des Desktops (Monitors) abfragen returns: AspektRatio als String about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr> </table> End Rem Function DesktopRatio:String (screen:Int=0) Function DAR:Int (a:Int, b:Int) Local fudge:Int = 0 Local Result:Int If b mod a <= fudge Result = a Else Result = DAR (b, a mod b) EndIf Return Result End Function Local X:Int = DesktopWidth(screen) Local Y:Int = DesktopHeight(screen) Local Div:Int = DAR(X,Y) Local Result:String = String (X/Div) + ":" + String(Y/Div) Select Result Case "8:5" ; Return "16:10" Default ; Return Result End Select End Function Rem bbdoc: Anzahl der Desktops (Monitore) abfragen returns: Anzahl als Integer about: <table> <tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>X</td><td>X</td><td></td></tr> </table> End Rem Function DesktopCount:Int () ?Win32 Return GetSystemMetrics (SM_CMONITORS) ?MacOS Local display:Byte Ptr[] = New Byte Ptr[1] Local iMode:Byte Ptr = Null Local iCount:Int CGGetActiveDisplayList 1, display, iCount Return iCount ?Linux Return 0 ? End Function Rem bbdoc: X-Koordinate des Desktops (Monitors) abfragen returns: X-koordinate als Integer about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr> </table> End Rem Function DesktopX:Int (screen:Int = 0) If screen < 0 Then screen = 0 ?Win32 For Local display:TDisplay = EachIn TDisplay.List If display.id = screen+1 Return display.X EndIf Next Return 0 ?MacOS Return 0 ?Linux Return 0 ? End Function Rem bbdoc: Y-Koordinate des Desktops (Monitors) abfragen returns: Y-koordinate als Integer about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr> </table> End Rem Function DesktopY:Int (screen:Int = 0) If screen < 0 Then screen = 0 ?Win32 For Local display:TDisplay = EachIn TDisplay.List If display.id = screen+1 Return display.Y EndIf Next Return 0 ?MacOS Return 0 ?Linux Return 0 ? End Function Rem bbdoc: Breite des Desktops (Monitors) abfragen returns: Breite als Integer about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>-1</td><td>Gesammtbreite aller Desktops (Monitore)</td><td>X</td><td></td><td></td></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td>X</td><td></td></tr> </table> End Rem Function DesktopWidth:Int (screen:Int=0) Local width:Int,height:Int,depth:Int,hertz:Int GetDesktopMode (width, height, depth, hertz, screen) Return width End Function Rem bbdoc: Höhe des Desktops (Monitors) abfragen returns: Höhe als Integer about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>-1</td><td>Gesammthöhe aller Desktops (Monitore)</td><td>X</td><td></td><td></td></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td>X</td><td></td></tr> </table> End Rem Function DesktopHeight:Int (screen:Int=0) Local width:Int,height:Int,depth:Int,hertz:Int GetDesktopMode (width, height, depth, hertz, screen) Return height End Function Rem bbdoc: Tiefe des Desktops (Monitors) abfragen returns: Tiefe als Integer about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td></td><td>X</td><td></td></tr> </table> End Rem Function DesktopDepth:Int (screen:Int=0) Local width:Int,height:Int,depth:Int,hertz:Int GetDesktopMode (width, height, depth, hertz, screen) Return depth End Function Rem bbdoc: Wiederholrate des Desktops (Monitors) abfragen returns: Wiederholrate als Integer about: <table> <tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr> <tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td></td><td>X</td><td></td></tr> </table> End Rem Function DesktopHertz:Int (screen:Int=0) Local width:Int,height:Int,depth:Int,hertz:Int GetDesktopMode (width, height, depth, hertz, screen) Return hertz End Function Rem bbdoc: Breite, Höhe, Tiefe und Wiederholrate des Desktops (Monitors) abfragen about: Kompatibilität siehe DesktopWidth(), DesktopHeight(), DesktopDepth() und DesktopHertz() End Rem Function GetDesktopMode:Int (width:Int Var, height:Int Var, depth:Int Var, hertz:Int Var, screen:Int=0) ?Win32 Local hwnd:Int = GetDesktopWindow() Local hdc:Int = GetDC(hwnd) If hdc = Null Then Return -1 depth = GetDeviceCaps(hdc, BITSPIXEL) hertz = GetDeviceCaps(hdc, VREFRESH) ReleaseDC(hwnd,hdc) If screen = -1 width = GetSystemMetrics (SM_CXVIRTUALSCREEN) height = GetSystemMetrics (SM_CYVIRTUALSCREEN) Else Local valid:Byte = True For Local display:TDisplay = EachIn TDisplay.List If display.id = screen+1 width = display.width height = display.height Exit EndIf Next EndIf ?MacOS Local display:Byte Ptr[] = New Byte Ptr[screen+1] Local iMode:Byte Ptr = Null Local iCount:Int CGGetActiveDisplayList screen+1, display, iCount If (screen < iCount) iMode = CGDisplayCurrentMode(display[screen]) Else Throw " [DesktopExt] Screen '"+screen+"' does not exist!" End If width = MACOS_GetWidth(iMode) height = MACOS_GetHeight(iMode) depth = MACOS_GetBPP(iMode) hertz = MACOS_GetHertz(iMode) ?Linux CountGraphicsModes() GetGraphicsMode (0,width,height,depth,hertz) ? End Function Rem bbdoc: Screenshot des Desktops in einer Pixmap erstellen returns: Screenshot als TPixmap about: <table> <tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>X</td><td></td><td></td></tr> </table> End Rem Function DesktopPixmap:TPixmap (flag:Byte = True) 'Original Funktion von Suco-X ?Linux Return Null ?MacOS Return Null ?Win32 Local hwnd:Int = GetDesktopWindow() If Not hwnd Return Null Local hdc:Int = GetWindowDC(hwnd) If Not hdc Return Null Local hdcmem:Int = CreateCompatibleDC(hdc) If Not hdcmem Return Null Local info:BITMAPINFOHEADER = New BITMAPINFOHEADER info.biSize = SizeOf(info) info.biPlanes = 1 info.biCompression = 0 Local hertz:Int,depth:Int GetDesktopMode:Int (info.biWidth,info.biHeight,depth,hertz,-1) info.biBitCount = depth Local bmpmem:Int = CreateCompatibleBitmap(hdc, info.biWidth, info.biHeight) If (Not bmpmem) Or (Not SelectObject(hdcmem, bmpmem)) Return Null If Not BitBlt(hdcmem,0,0,info.biWidth,info.biHeight,hdc,0,0,ROP_SRCCOPY) Return Null Local out:TPixmap = CreatePixmap(info.biWidth, info.biHeight, PF_BGRA8888) If Not GetDIBits(hdcmem, bmpmem, 0, info.biHeight, out.PixelPtr(0,0), info, 0) Return Null DeleteDC(hdcmem) DeleteObject(bmpmem) ReleaseDC(hwnd, hdc) out = out.Convert(PF_BGR888) 'dumm gelaufen, man kann nicht direkt in dem Format grabben If flag = True out = YFlipPixmap(out) Return out ? End Function Rem bbdoc: Globale Maus X-Koordinate abfragen returns: X-Koordinate als Integer about: <table> <tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>X</td><td></td><td></td></tr> </table> End Rem Function DesktopMouseX:Int () ?Linux Return 0 ?MacOS Return 0 ?Win32 Local Coord:Int[2] GetCursorPos(Coord) Return Coord[0] ? End Function Rem bbdoc: Globale Maus Y-Koordinate abfragen returns: Y-Koordinate als Integer about: <table> <tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr> <tr><td>X</td><td></td><td></td></tr> </table> End Rem Function DesktopMouseY:Int () ?Linux Return 0 ?MacOS Return 0 ?Win32 Local Coord:Int[2] GetCursorPos(Coord) Return Coord[1] ? End Function