[BMAX] Win32 Funktionssammlung in einer Datei

Übersicht BlitzBasic DLLs und Userlibs

Neue Antwort erstellen

Trust

Betreff: [BMAX] Win32 Funktionssammlung in einer Datei

BeitragMo, Jan 08, 2018 11:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo, die folgende Sammlung vereinfacht die Zugriffe auf win32 Funktionen in BlitzMax.

Oben steht der ganze Code der die ganze Arbeit erledigt, weiter unten die Wrapperfunktionen die zum benutzen gedacht sind um sich vieles zu vereinfachen.

Diesen Code einfach ins eigene Projekt inkludieren (am besten als separate Datei per "Include".

BlitzMax: [AUSKLAPPEN]


Rem
----------------------------------------------------------
This needs to be imported into the main source file:
Framework Pub.Win32
Import BRL.System
Import BRL.Pixmap
Import BRL.Retro

Import "-ladvapi32"
Import "-lpsapi" <-- If this file cant be found by the bmk.exe, copy it from the Mingw/lib folder into the BMax lib folder
----------------------------------------------------------
End Rem


Extern "Win32"

' Keycodelist: ' For a list of keycodes, visit: https://msdn.microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx

' https://msdn.microsoft.com/de-de/library/windows/Desktop/ms646304(v=vs.85).aspx
Function keybd_event(vKeyCode:Byte, bScan:Byte, dwFlags:Int, dwExtraInfo:Int)

'https://msdn.microsoft.com/en-us/library/windows/Desktop/ms646260(v=vs.85).aspx
Function mouse_event(dwFlags:Int, dx:Int, dy:Int, dwExtraInfo:Int)="mouse_event@20"

' https://msdn.microsoft.com/de-de/library/windows/desktop/ms648394(v=vs.85).aspx
Function SetCursorPos(x:Int, y:Int)

' https://msdn.microsoft.com/de-de/library/windows/Desktop/ms633520(v=vs.85).aspx
Function GetWindowTextA:Int(hwnd:Int, lpstring:Byte Ptr, nMaxCount:Int)

'https://msdn.microsoft.com/de-de/library/windows/Desktop/ms633505(v=vs.85).aspx
Function GetForegroundWindow:Int()

'https://msdn.microsoft.com/de-de/library/windows/Desktop/ms633539(v=vs.85).aspx
Function SetForegroundWindow:Int(hwnd:Int)

' https://msdn.microsoft.com/de-de/library/windows/desktop/ms633499%28v=vs.85%29.aspx
Function FindWindowA(lpClassName:Byte Ptr, lpWindowName:Byte Ptr)

' https://msdn.microsoft.com/de-de/library/windows/Desktop/ms646293(v=vs.85).aspx
Function GetAsyncKeyState:Short(vKey:Int)

Function GetCursorPos:Int(point:Byte Ptr)="GetCursorPos@4"

Function OpenProcess(p1:Int,p2:Int,id:Int)
Function _EnumProcesses(pProcessIds:Byte Ptr,size:Int,byteret:Int Ptr)="EnumProcesses@12"
Function _TerminateProcess(handle:Int,bla:Int)="TerminateProcess@8"
Function CloseHandle(handle:Int)
Function EnumProcessModules(hProcess:Int,lphModule:Byte Ptr,cb:Int,lpcbNeeded:Int Ptr)
Function GetModuleBaseName(hProcess:Int,bla:Int,lpBaseName:Byte Ptr,nSize:Int)="GetModuleBaseNameA@16"

Function _ReadProcessMemory(hProcess:Int,lpBaseAddress:Int,lpBuffer:Byte Ptr,nSize:Int,lpNumberOfBytesRead:Int)="ReadProcessMemory@20"

Function _WriteProcessMemory(hProcess:Int,lpBaseAddress:Int,lpBuffer:Byte Ptr,nSize:Int,lpNumberOfBytesWritten:Int)="WriteProcessMemory@20"

Function QueryFullProcessImageName(hProcess:Int, flags:Int, lpExeName:Byte Ptr, lpDwSize:Int Ptr)="QueryFullProcessImageNameA@16"
End Extern



' Keyup/down event
Const KEYEVENTF_KEYDOWN:Int = $0000
Const KEYEVENTF_KEYUP:Int = $0002

' Process access types
Const PROCESS_VM_READ:Int = 16
Const PROCESS_VM_WRITE:Int = 32
Const PROCESS_VM_OPERATION:Int = 8
Const PROCESS_QUERY_INFORMATION:Int = 1024

Const MOUSEEVENTF_LEFTDOWN:Int = $0002
Const MOUSEEVENTF_LEFTUP:Int = $0004
Const MOUSEEVENTF_MIDDLEDOWN:Int = $0020
Const MOUSEEVENTF_MIDDLEUP:Int = $0040
Const MOUSEEVENTF_RIGHTDOWN:Int = $0008
Const MOUSEEVENTF_RIGHTUP:Int = $0010




Type CString
Field array:Byte[]
Field length:Int
Field maxString:String

Function Create:CString(length:Int = 255)
Local cStr:CString = New CString
cStr.length = length
cStr.array = New Byte[cStr.length]
Return cStr
End Function

Method setArrayFromString(str:String)
For Local i:Int = 0 To str.length -1
Self.array[i] = Asc(Mid(str, i+1, 1))
Next
End Method

Method arrayToMaxString()
Self.maxString = ""
For Local i:Int = 0 To Self.length -1
Self.maxString = Self.maxString + Chr(Self.array[i])
Next
End Method
End Type


' process memory read function
Function ReadProcMemory:Byte[](pid:Int,addr:Int,bytes:Int)
Local handle:Int
Local buff:Byte[bytes]

handle = OpenProcess(PROCESS_VM_READ,0,pid)

If Not handle
RuntimeError("ReadProcMemory: Process does not exist!")
End
EndIf

If Not _ReadProcessMemory(handle,addr,Varptr buff[0],bytes,0)
CloseHandle(handle)
Return Null
EndIf

CloseHandle(handle)
Return buff
End Function


' process memory write function
Function WriteProcMemory:Int(pid:Int,addr:Int,buff:Byte[],p:Byte Ptr=Null,count:Int=0)
Local handle:Int

handle=OpenProcess(PROCESS_VM_WRITE|PROCESS_VM_OPERATION,0,pid)

If Not handle Then RuntimeError("WriteProcMemory: Process does not exist!")
If p
If Not _WriteProcessMemory(handle,addr,p,count,0)
CloseHandle(handle)
Return 0
EndIf
Else
If Not _WriteProcessMemory(handle,addr,Varptr buff[0],buff.length,0)
CloseHandle(handle)
Return 0
EndIf
EndIf

CloseHandle(handle)
Return 1
End Function


Function GetDesktopPixmap:TPixmap()

Extern "Win32"
Function GetDIBits(hdc:Int, bitmap:Int, Start:Int, Num:Int, bits:Byte Ptr, lpbi:Byte Ptr, usage:Int)
Function CreateCompatibleBitmap(hdc:Int, Width:Int, Height:Int)
Function CreateDIBSection(hdc:Int, pbmi:Byte Ptr, usage:Int, Bits:Byte Ptr, hSection:Int, Offset:Int)
Function SelectObject(hdc:Int, obj:Int)
Function CreateCompatibleDC(hdc:Int)
Function GetDesktopWindow()
Function GetWindowDC(hwnd:Int)
Function GetDeviceCaps(hdc:Int, index:Int)
Function DeleteDC(hdc:Int)
Function DeleteObject(obj:Int)
Function ReleaseDC(hwdn:Int, hdc:Int)
Function BitBlt(hdc:Int,x:Int,y:Int,w:Int,h:Int,src_dc:Int,src_x:Int,src_y:Int,dwrop:Int)
End Extern


?Win32

Type BITMAPINFO
Field biSize:Int
Field biWidth:Int
Field biHeight:Int
Field biPlanes:Short
Field biBitCount:Short
Field biCompression:Int
Field biSizeImage:Int
Field biXPelsPerMeter:Int
Field biYPelsPerMeter:Int
Field biClrUsed:Int
Field biClrImportant:Int

Field R:Byte
Field G:Byte
Field B:Byte
Field Res:Byte
End Type


Const HORZRES:Int = 8
Const VERTRES:Int = 10

Local HwndDesktop:Int
Local hdcDesktop:Int
Local hdcMem:Int
Local DesktopWidth:Int
Local DesktopHeight:Int
Local bmpMem:Int
Local INFO:BITMAPINFO
Local FinalPixmap:TPixmap

HwndDesktop = GetDesktopWindow()

If Not HwndDesktop
Return Null
EndIf


hdcDesktop = GetWindowDC(HwndDesktop)

If Not HdcDesktop
Return Null
EndIf


hdcMem = CreateCompatibleDC(hdcDesktop)

If Not HdcMem
Return Null
EndIf


DesktopWidth = GetDeviceCaps(hdcDesktop, HORZRES)
DesktopHeight = GetDeviceCaps(hdcDesktop, VERTRES)

If DesktopWidth = 0 Or DesktopHeight = 0
Return Null
EndIf


bmpMem = CreateCompatibleBitmap(hdcDesktop, DesktopWidth, DesktopHeight)

If Not BmpMem
Return Null
EndIf


If Not SelectObject(HdcMem, bmpMem)
Return Null
EndIf

Info = New BITMAPINFO
Info.bisize = SizeOf(INFO)
info.BiWidth = DesktopWidth
Info.biHeight = DesktopHeight
Info.biPlanes = 1
info.biBitCount = 24
Info.biCompression = 0


If Not BitBlt(hdcMem,0,0,Info.biWidth,Info.biHeight, hdcDesktop,0,0,ROP_SRCCOPY)
Return Null
EndIf

FinalPixmap = CreatePixmap(info.biWidth, info.biHeight, PF_BGR888)

If Not GetDIBits(hdcMem, bmpMem, 0, Info.biHeight, FinalPixmap.PixelPtr(0,0), info, 0)
Return Null
EndIf

FinalPixmap = YFlipPixmap(FinalPixmap)

DeleteDC(HdcMem)
DeleteObject(bmpMem)
ReleaseDC(hwndDesktop, hdcDesktop)

Return FinalPixmap

?

?Linux
Return Null
?

?MacOs
Return Null
?

End Function


' Converts a 32 bit pixel value into r, g, b, values
Function ToRgb(_32BitPixelValue:Int, r:Byte Var, g:Byte Var, b:Byte Var)
Local rgb:Int = _32BitPixelValue
' a:Byte = (rgb & $FF000000) / $1000000
r = (rgb & $FF0000) / $10000
g = (rgb & $FF00) / $100
b = rgb & $FF
End Function








' ###################################################################################
' # #
' # Wrapped functions for the user #
' # #
' ###################################################################################




Function isKeyDown:Short(vkey:Int)
Delay 1
Return (GetAsyncKeyState(vkey) And %1000000000000000)> 0
End Function

' Simulates a keystroke
Function pressKey(keyCode:Int)
keybd_event(keyCode, 0, KEYEVENTF_KEYDOWN, 0)
keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0)
End Function

Function pressLMouse()
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0)
End Function

Function pressRMouse()
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0)
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0)
End Function

Function pressMMouse()
mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0)
mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0)
End Function

Function mouseLDown()
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0)
End Function

Function mouseLUp()
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0)
End Function

Function mouseRDown()
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0)
End Function

Function mouseRUp()
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0)
End Function

Function mouseMDown()
mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0)
End Function

Function mouseMUp()
mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0)
End Function

Function keybdDown(keyCode:Int)
keybd_event(keyCode, 0, KEYEVENTF_KEYDOWN, 0)
End Function

Function keybdUp(keyCode:Int)
keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0)
End Function

Function setMousePos(x:Int, y:Int)
SetCursorPos(x, y)
End Function

Function getMousePos(x:Int Var, y:Int Var)
Local coords:Int[]
coords = New Int[2]
GetCursorPos(coords)
x = coords[0]
y = coords[1]
End Function

Function getForegroundWnd:Int()
Return GetForegroundWindow()
End Function

' Finds a window with name "name", set's it as foreground window and returns it's handle
Function setForegroundWnd:Int(name:String)
Local windowText:CString = CString.Create(255)

windowText.setArrayFromString(name)

Local targetWindow:Int = FindWindowA(Null, windowText.array)

SetForegroundWindow(targetWindow)
Delay 1
Return targetWindow
End Function

' Returns the title text of the foreground window
Function getForegroundWindowText:String()
Local windowText:CString = CString.Create(255)
GetWindowTextA(GetForegroundWindow(), windowText.array, windowText.length)
windowText.arrayToMaxString()
Return windowText.maxString
End Function

' Returns the title text of the window hwnd
Function getWindowText:String(hwnd:Int)
Local windowText:CString = CString.Create(255)
GetWindowTextA(hwnd, windowText.array, windowText.length)
windowText.arrayToMaxString()
Return windowText.maxString
End Function


Function getPixel:Int(x:Int, y:Int, red:Byte Var, green:Byte Var, blue:Byte Var)
Local desktopScreen:TPixmap = GetDesktopPixmap()
If Not desktopScreen Then Return False
Local pixel:Int = ReadPixel(desktopScreen, x, y)
If Not pixel Then Return False
Local r:Byte ,g:Byte ,b:Byte
ToRgb(pixel, r, g, b)
red = r
green = g
blue = b
Delay 10
Return True
End Function


' retrieve all processes that equals the given name
' returns an integer array containing the pid's
Function getProcessByName:Int[](name:String, buffsize:Int=10)
If buffsize < 10 Then buffsize = 10
name = name.tolower()
Local plist:Int[]
Local i:Int, j:Int
Local buffer:Int[buffsize]
Local ret:Int[]

plist = enumProcesses()

If plist = Null Then Return Null

For i = 0 To plist.length-1
Local procName:String = getProcessName(plist[i]).tolower()
If procName = name Then
buffer[j] = plist[i]
j = j + 1
If(j = buffsize) Then Return getProcessByName(name, buffsize+10)
EndIf
Next

If j = 0 Then Return Null

ret = New Int[j]
MemCopy(ret, buffer, j*4)
Return ret
End Function

' get's the name of a process
' returns name:String
Function getProcessName:String(pid:Int)
Const MAX_PATH:Int = 260
Local handle:Int
Local mem:Byte Ptr
Local cbNeeded:Int

Local hMod:Int
'Local size:Int = MAX_PATH
Print pid
handle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, 0, pid)
If Not handle
'RuntimeError("getProcessName: Process does not exist!")
'End
Print "shit"
Return Null
EndIf

Local szProcessName:Byte[]
szProcessName=New Byte[MAX_PATH]

EnumProcessModules( handle, Varptr hMod, SizeOf(hMod), Varptr cbNeeded)
GetModuleBaseName(handle, hMod, Varptr szProcessName[0], MAX_PATH)
'QueryFullProcessImageName(handle, 0, szProcessName, Varptr size)
'Print "procName: " + szProcessName[0] + " " + String.fromCString(szProcessName)
CloseHandle(handle)

Print String.fromCString(szProcessName)
Return String.fromCString(szProcessName)
End Function

' terminates the process <pid>
' returns True If successfull
Function killProcess:Int(pid:Int)
Local handle:Int
Local success:Int
handle = OpenProcess(1, 0, pid)
If handle = 0 Then Return 0
success = _TerminateProcess(handle, -1)
CloseHandle(handle)
Return success
End Function

'lists all running processes
'returns an integer array holding the pid's
Function enumProcesses:Int[]()
Local mem:Byte Ptr
Local size:Int=100
Local ret:Int
Local array:Int[]

Repeat
size = size + 100
mem=MemAlloc(size)
If Not _EnumProcesses(mem,size,Varptr ret) Then
MemFree(mem)
Return Null
End If
Until size > ret

array = New Int[ret/4]

MemCopy(Varptr array[0],mem,ret)
MemFree(mem)

Return array
End Function

' Reads the memory at address "addr" of the given pid. "bytesToRead" determines how many byte to read.
Function readProcessMemory:Byte[](pid:Int, addr:Int, bytesToRead:Int)
Local a:Byte[] = ReadProcMemory(pid:Int, addr:Int, bytesToRead:Int)
Return a
End Function

' Writes the memory at address "addr" of the given pid. "bytesToWrite" is the byte array with the data to write.
Function writeProcessMemory:Int(pid:Int, addr:Int, bytesToWrite:Byte[])
Local success:Int = WriteProcMemory(pid, addr, bytesToWrite)
Return success
End Function


Hier ist eine komplette Liste aller virtual key codes:
https://msdn.microsoft.com/de-...85%29.aspx


[UPDATE]
Neue Funktionen für Prozesse und Memory sind hinzugekommen:
Prozesse öffnen, Memory lesen und schreiben... usw.

Hinweis
Ab Windows 7 sind die Prozessfunktionen so nur bedingt nutzbar da EnumProcesses nicht alle Prozesse auflistet bzw. OpenProcess nicht alle öffnet wenn die Privilegien nicht gesetzt sind:
Zitat:
To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege. For more information, see Changing Privileges in a Token.


Für mehr informationen: https://msdn.microsoft.com/en-...s.85).aspx
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
  • Zuletzt bearbeitet von Trust am Mi, Jan 10, 2018 1:06, insgesamt 23-mal bearbeitet

count-doku

BeitragMo, Jan 08, 2018 11:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich will dich ja nicht entmutigen, aber unterscheidet sich das, was deine DLL bietet von
\BlitzMax\mod\pub.mod\win32.mod ?

Da sind nämlich bereits alle Externs für die Standard Windows API Bibliotheken definiert...
Siehe auch:
https://github.com/blitz-resea.../win32.mod



lg,
Count-Doku

Trust

BeitragMo, Jan 08, 2018 14:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

finde dort aber einige Sachen nicht wie zB. GetCursorPos, SendInput, keybd_event, OpenProcess, Read/WriteProcessMemory usw. usf. .. Zudem wrappt diese dll einige (später mehr) WinApi Funktionen und macht es so einfacher diese in Bmax zu benutzen. Also kein konvertieren von cstrings oder extra erstellen von Types für korrekte Parameterübergaben usw. nur um den Datenstrukturen/Datentypen von c++ zu entsprechen.

Wenn du dir zB. mal GetCursorPos anschaust: https://msdn.microsoft.com/de-...p/ms648390(v=vs.85).aspx
verlangt die Funktion ein LPPOINT lpPoint als Argument. Also einen Long poiner auf eine POINT struct.
Diese müsste man erst mal in BMax "nachbauen" um GetCursorPos nutzen zu können.
Und dieses Beispiel ist noch relativ simpel. Da gibts andere Sachen wo Types wiederum andere Types enthalten... das kann dann ziemlich aufwändig werden nur um eine WinApi Funktion nutzen zu können. Und dies geschieht dann eben schon in der dll, sodass man mit dieser ganz einfach nur BMax eigene Datentypen verwenden kann.
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.

count-doku

BeitragMo, Jan 08, 2018 22:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok wenn es dabei auch eine Wrapper Ebene gibt, dann macht das natürlich Sinn.

Trust

BeitragMi, Jan 10, 2018 0:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok,

ich habe es mal umgemodelt, es ist nun keine dll mehr, sondern eine einfache BlitzMax-Datei welche einfach ins Projekt inkludiert werden kann. Hinzukommend kann man so den Source sehen und eher nachvollziehen was die Wrapperfunktionen machen.

Denke das ist bequemer.

G,
Trust
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.

Neue Antwort erstellen


Übersicht BlitzBasic DLLs und Userlibs

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group