here are two exe that get o2 version.
the first one is 32 bit, the second one is 64 bit to get 64 bit dll version.
the interprocess communication is done via the simple WM_SETTEXT.
app is drag and drop aware and command line aware.
(https://i.imgur.com/EfhE6qI.png)
//KickResource "D:\Dev\Oxygen\o2\~code\~~~Resource.res" //kick add a manifest for CommonControl-6
//KickSwitch -32 //compile to 32bit
//KickExeArgument "D:\Dev\Oxygen\o2\oxygen.dll" "D:\Dev\Oxygen\o2\oxygen64.dll" //send this command line to the exe
//KickExeFileName "o2version.exe" // Optional exe/dll FileName
//KickEnd //optional, end of kick instructions
'D:\Dev\Oxygen\o2\demos\Unicode\
'in this 32bit exe you have:
' make use of interprocess WM_SETTEXT to get 64bit exe data
' dynamic api loader
' subclassed edit
' read command line arguments with CommandLineToArgvW
' can receive multi dropped files
' FileExist
' SetWindowPos(HWND_NOTOPMOST)
uses dialogs
$ FileName "o2version.exe"
$ o2version64 = "o2version64.exe" 'other exe that use interprocess WM_SETTEXT for 64 bit dll
% Edit 101
% EditHidden 102
% CheckboxTopMost 201
% Grip 301
% SIZE_MINIMIZED 1
% DEFAULT_GUI_FONT 17
% GCL_HICON -14
% MAXDWORD 0xFFFFFFFF
% WM_NCDESTROY 0x082
% SWP_NOSIZE 1
% HWND_DESKTOP 0
% HWND_NOTOPMOST 0xFFFFFFFE
% SIZE_MAXIMIZED 2
% SBS_SIZEGRIP 0x0010
% SM_CXVSCROLL 2
% SM_CYHSCROLL 3
% SEM_FAILCRITICALERRORS = 0X0001
! SetWindowTheme lib "UxTheme.dll" alias "SetWindowTheme"
(byval hwnd as sys, pszSubAppName as wzstring, pszSubIdList as wzstring) as long
'______________________________________________________________________________
sub TextDel(sys hEdit)
'Erase all, Microsoft recommended way
SendMessage(hEdit, WM_SETTEXT, 0, BYVAL 0)
end sub
'_____________________________________________________________________________
sub TextAdd(sys hEdit, byref string sText)
'Move the caret to the end of text
SendMessage(hEdit, EM_SETSEL, -1, -1)
sText += chr(13) + chr(10) 'Add a CRLF if needed
'Insert the string at caret position
SendMessage(hEdit, EM_REPLACESEL, TRUE, sText)
end sub
'_____________________________________________________________________________
function FileExist(string sFileName) as long
dword Attribute = GetFileAttributes(strptr(sFileName))
if Attribute <> INVALID_HANDLE_VALUE then
if (Attribute AND FILE_ATTRIBUTE_DIRECTORY) = 0 then
function = 1
end if
end if
end function
'_____________________________________________________________________________
sub Dynamic_O2_version(sys hEdit, string sFileName)
if right(lcase(sFileName), 4) = ".dll"
dword ExErrMode = SetErrorMode(SEM_FAILCRITICALERRORS) 'prevent pop-up dialogs if device is not present or loaded
sys hLib = LoadLibrary(sFileName)
SetErrorMode(ExErrMode) 'return to old mode
if hLib then
sys pProc = GetProcAddress(hLib, "o2_version")
if pProc then
char* oTwoVer = call pProc
TextAdd(hEdit, "32-bit " & oTwoVer + " - " + sFileName)
else
TextAdd(hEdit, "no o2_version procedure pointer returned - " + sFileName)
endif
FreeLibrary(hLib)
else
sys hEditHidden = GetDlgItem(GetParent(hEdit), EditHidden)
string sCmdLine = "0x" & hex(hEditHidden, 8) & " " & sFileName
ShellExecute(hwnd_desktop, "", o2version64, sCmdLine, "", 0)
endif
else
TextAdd(hEdit, "not a .dll - " + sFileName)
endif
end sub
'_____________________________________________________________________________
function EditProc(sys hEdit, uint wMsg, sys wParam, sys lParam) as sys callback
static sys pEditProc
long index
select case wMsg
case WM_NULL
if hEdit = 0 and pEditProc = 0 then pEditProc = wParam : return(0)
CASE WM_NCDESTROY
SetWindowLongPtr(hEdit, GWL_WNDPROC, pEditProc) 'Unsubclass edit
CASE WM_DROPFILES
sys hDrop = wParam
long DroppedFileCount = DragQueryFileW(hDrop, 0xFFFFFFFF, byval 0, 0)
zstring zFileName[max_path]
for index = 0 to DroppedFileCount - 1
DragQueryFile(hDrop, index, zFileName, MAX_PATH)
Dynamic_O2_version(hEdit, zFileName)
next
DragFinish(hDrop) 'Releases memory that Windows allocated
end select
function = CallWindowProc(pEditProc, hEdit, wMsg, wParam, lParam)
end function
'_____________________________________________________________________________
function DialogProc(sys hDlg, uint uMsg, sys wParam, lParam) as sys callback
static sys hEdit, hIcon, hFont
static rect ButtonRect
static point GripSize
select case uMsg
case WM_INITDIALOG
ShowWindow(GetDlgItem(hDlg, EditHidden), SW_HIDE)
GripSize.x = GetSystemMetrics(SM_CXVSCROLL) 'Width of grip
GripSize.y = GetSystemMetrics(SM_CYHSCROLL) 'Height of grip
SetWindowTheme(GetDlgItem(hDlg, Grip), " ", " ") 'use old theme grip
hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'o
SetClassLongPtr(hDlg, GCL_HICON, hIcon)
hEdit = GetDlgItem(hDlg, Edit)
'subclass listbox with a a one liner and no variables needed...
EditProc(0, WM_NULL, SetWindowLongPtr(hEdit, GWL_WNDPROC, @EditProc), 0)
hFont = CreateFont(14, 0, 'height 14 = 9, 16=12, 15=11, 14=11, width usually 0,
0, 0, 'escapement(angle), orientation
0, 0, 0, 0, 'bold, italic, underline, strikeThru
0, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FF_DONTCARE, "Consolas") 'fixed width font ("Segoe UI", 9 Arial Consolas)
SendMessage(hEdit, WM_SETFONT, hFont, 0)
SendMessage(GetDlgItem(hDlg, IDCANCEL), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
SendMessage(GetDlgItem(hDlg, CheckboxTopMost), WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0)
GetWindowRect(GetDlgItem(hDlg, IDCANCEL), ButtonRect) 'keep PushButton size as defined in winmain()
ButtonRect.right = ButtonRect.right - ButtonRect.left : ButtonRect.left = 0
ButtonRect.bottom = ButtonRect.bottom - ButtonRect.top : ButtonRect.top = 0
TextDel(hEdit)
TextAdd(hEdit, "from windows explorer, drag one or more 32 or 64 bit oxygen .dll here")
TextAdd(hEdit, "(or you may add dll filename to this exe command line)")
TextAdd(hEdit, "-----------------------------------")
long ArgumentCount, index
wchar** ppwArgument 'pointer to the first pointer item of an array of wzstring pointers, same as 'wchar ptr ptr ppwArgument'
@@ppwArgument = (sys) CommandLineToArgvW(GetCommandLineW(), @ArgumentCount)
if ArgumentCount > 1
for index = 2 to ArgumentCount
Dynamic_O2_version(hEdit, ppwArgument[index])
next
endif
if GlobalFree(@@ppwArgument) then Beep(5500, 50) 'use GlobalFree() or LocalFree(), if the function succeeds, the return value is NULL
PostMessage(hEdit, EM_SETSEL, -1, 0) 'set caret at the end of text
return true
case WM_COMMAND
select case loword(wParam)
case IDCANCEL
if hiword(wParam) = BN_CLICKED OR hiword(wParam) = 1
EndDialog(hDlg, null)
endif
case EditHidden
if hiword(wParam) = EN_CHANGE
'message was sent by o2version64
word CharCount = SendMessageW(GetDlgItem(hDlg, EditHidden), EM_LINELENGTH, 0, 0)
if CharCount
if CharCount = 1 then CharCount = 2
string sText = string(CharCount, chr(0))
word WordLen at strptr(sText)
WordLen = CharCount
SendDlgItemMessage(hDlg, EditHidden, EM_GETLINE, 0, BYVAL STRPTR(sText))
TextAdd(hEdit, sText)
endif
endif
case CheckboxTopMost
if hiword(wParam) = BN_CLICKED OR hiword(wParam) = 1
if IsDlgButtonChecked(hDlg, CheckboxTopMost) then
SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
else
SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
endif
endif
end select
case WM_SIZE 'dialog size have changed
'wParam = Resizing requested: SIZE_MAXHIDE SIZE_MAXIMIZED SIZE_MAXSHOW SIZE_MINIMIZED SIZE_RESTORED
'loword lParam is client area width in pixels
'hiword lParam is client area height in pixels
if wParam <> SIZE_MINIMIZED
long ClientSizeX = loword(lParam)
long ClientSizeY = hiword(lParam)
if wparam = SIZE_MAXIMIZED then
SetWindowPos(GetDlgItem(hDlg, Grip), NULL, 0, 0, 0, 0, SWP_NOZORDER) 'size it to zero by zero
else
SetWindowPos(GetDlgItem(hDlg, Grip), NULL, ClientSizeX - GripSize.x,
ClientSizeY - GripSize.y, GripSize.x, GripSize.y, SWP_NOZORDER)
endif
long posY = ClientSizeY - ButtonRect.bottom - 15
MoveWindow(hEdit, 5, 5, ClientSizeX - 10, posY, TRUE)
MoveWindow(GetDlgItem(hDlg, IDCANCEL), (ClientSizeX - ButtonRect.right) \ 2, posY + 10,
ButtonRect.right, ButtonRect.bottom, TRUE)
MoveWindow(GetDlgItem(hDlg, CheckboxTopMost), 10, posY + 10,
ButtonRect.right, ButtonRect.bottom, TRUE)
endif
case WM_CLOSE
EndDialog(hDlg, null)
case WM_DESTROY
DeleteObject(hFont)
DestroyIcon(hIcon)
end select
return 0
end function
'______________________________________________________________________________
sub winmain()
if sizeof(sys) = 8
mbox "This code must be compiled in 32 bit"
else
if FileExist(o2version64) then
Dialog(0, 0, 280, 100, "oxygenbasic version", WS_OVERLAPPEDWINDOW | DS_CENTER)
MultiLineText("", Edit, 1, 1, 198, 80)
PushButton("&close" , IDCANCEL, 80, 85, 40, 12)
AutoCheckBox("&topmost" , CheckboxTopMost, 5, 85, 40, 12)
SCROLLBAR("", Grip, 270, 90, 10, 10, WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN)
EditText("", EditHidden, "", 0, 0, 100, 20)
CreateModalDialog(null, @DialogProc, 0)
else
mbox o2version64 & " not found !"
endif
endif
end sub
'______________________________________________________________________________
winmain()
'______________________________________________________________________________
'
//K ickUseDirectivesFrom "D:\Dev\Oxygen\o2\o2_version3264-01.o2bas"
//KickResource "D:\Dev\Oxygen\o2\~code\~~~Resource.res" //kick add a manifest for CommonControl-6
//KickSwitch -64 //compile to 32bit
//K ickExeArgument "D:\Dev\Oxygen\o2\oxygen.dll" "D:\Dev\Oxygen\o2\oxygen64.dll" //send this command line to the exe
//K ickHelp //show kick help
//KickExeFileName "o2version64.exe" // Optional exe/dll FileName
//KickEnd //optional, end of kick instructions
'in this 64bit exe you have:
' dynamic api loader
' GetCommandLine()
' FileExist
uses corewin
$ FileName "o2version64.exe"
$ o2version = "o2version.exe" 'other exe with dialog for 32 bit dll
% EditHidden 102
% SEM_FAILCRITICALERRORS = 0X0001
macro makdwd(lo, hi)
dword (hi << 16) + lo
end macro
'_____________________________________________________________________________
function FileExist(string sFileName) as long
dword Attribute = GetFileAttributes(strptr(sFileName))
if Attribute <> INVALID_HANDLE_VALUE then
if (Attribute AND FILE_ATTRIBUTE_DIRECTORY) = 0 then
function = 1
end if
end if
end function
'_____________________________________________________________________________
function Dynamic_O2_version(string sFileName) as string
dword ExErrMode = SetErrorMode(SEM_FAILCRITICALERRORS) 'prevent pop-up dialogs if device is not present or loaded
sys hLib = LoadLibrary(sFileName)
SetErrorMode(ExErrMode) 'return to old error mode
if hLib then
sys pProc = GetProcAddress(hLib, "o2_version")
if pProc then
char* oTwoVer = call pProc
function = "64-bit " & oTwoVer + " - " + sFileName
else
function = "no o2_version procedure pointer returned - " + sFileName
endif
FreeLibrary(hLib)
endif
end function
'______________________________________________________________________________
sub winmain()
if sizeof(sys) = 4
mbox "This code must be compiled in 64 bit"
else
if fileExist(o2version) then
zstring ptr pCommandLine = GetCommandLine()
string sCommandLine = pCommandLine
long charPos = instr(2, sCommandLine, chr(34))
if charPos then
sCommandLine = mid(sCommandLine, charPos + 2, len(sCommandLine) - charPos - 1)
if left(sCommandLine, 2) = "0x" then
sys h = val(sCommandLine)
charPos = instr(sCommandLine, chr(32))
sCommandLine = mid(sCommandLine, charPos + 1)
if isWindow(getParent(h)) then
if len(sCommandLine) then
string sResult = Dynamic_O2_version(sCommandLine)
'send text to o2version 32 bit
SendMessage(h, WM_SETTEXT, 0, strptr(sResult))
PostMessage(GetParent(h), WM_COMMAND, MAKDWD(EditHidden, EN_CHANGE), h)
endif
endif
else
mbox "use " & o2version & " !"
endif
endif
else
mbox o2version & " not found !"
endif
endif
end sub
'______________________________________________________________________________
winmain()
'______________________________________________________________________________
'
Thanks Pierre.
Hi Charles,
If you see things that could be done in an easier way in o2,
do not hesitate to suggest, the possibilities are vast
and I have the natural tendency to fall back in pb track.
Hi Pierre,
Have you come across Named Shared Memory? This allows different processes to share a block of memory, and treat it like a file. It requires only 2 function calls, and a static variable mapping (bind .. end bind) in o2. In the example below, a 64bit server shares global variables directly with a 32bit client, in the same memory space.
SERVER: (run first, without clicking "ok")
'-----------------------------------------
'NAMED SHARED MEMORY
'=========================================
'derived from:
'Creating Named Shared Memory
'http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx
'==============
'SERVER PROCESS
'==============
$filename "server4.exe"
uses RTL64
uses CoreWin
' from winbase.h and winnt.h
% PAGE_NOACCESS 0x01
% PAGE_READONLY 0x02
% PAGE_READWRITE 0x04
% PAGE_WRITECOPY 0x08
' Token Specific Access Rights.
% TOKEN_ASSIGN_PRIMARY 0x0001
% TOKEN_DUPLICATE 0x0002
% TOKEN_IMPERSONATE 0x0004
% TOKEN_QUERY 0x0008
% TOKEN_QUERY_SOURCE 0x0010
% TOKEN_ADJUST_PRIVILEGES 0x0020
% TOKEN_ADJUST_GROUPS 0x0040
% TOKEN_ADJUST_DEFAULT 0x0080
% TOKEN_ADJUST_SESSIONID 0x0100
% SECTION_QUERY 0x0001
% SECTION_MAP_WRITE 0x0002
% SECTION_MAP_READ 0x0004
% SECTION_MAP_EXECUTE 0x0008
% SECTION_EXTEND_SIZE 0x0010
% SECTION_ALL_ACCESS 0x001F
% SECTION_MAP_EXECUTE_EXPLICIT 0x0020
% STANDARD_RIGHTS_REQUIRED 0x000F0000L
% FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
sys INVALID_HANDLE_VALUE = -1 'as ptr
% TRUE 1
% FALSE 0
string szName="Local\MyFileMappingObject" 'GLOBAL\ NOT SUPPOERTED
string szMsg="This is a Message from the SERVER process."
string cr=chr(13)+chr(10)
% BUF_SIZE 0x1000
======================
sys hMapFile
sys pBuf
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, ' use paging file
NULL, ' default security
PAGE_READWRITE, ' read/write access
0, ' maximum object size (high-order DWORD)
BUF_SIZE, ' maximum object size (low-order DWORD)
szName) ' name of mapping object
if hMapFile == 0
print "Could not create file mapping object" + cr + GetLastError()
jmp fwd done
endif
' 0x7 read/write permission
pBuf = MapViewOfFile( hMapFile, 0x7, 0, 0, BUF_SIZE)
if pBuf == 0
print "Could not map view of file" + cr +
GetLastError()
CloseHandle(hMapFile)
jmp fwd done
endif
'
bind pBuf
sys p
int i1,i2
float f1,f2
char c1[0x100]
end bind
'
i1=123
i2=456
f1=pi()
c1=szMsg
print "SERVER: " cr +
c1 cr +
i1 " / " i2 ", " f1 cr cr +
"Press OK to terminate"
UnmapViewOfFile(pBuf)
CloseHandle(hMapFile)
jmp fwd done
'
'
=====
done:
=====
CLIENT:
'-------------------
'NAMED SHARED MEMORY
'===================
'derived from:
'Creating Named Shared Memory
'http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx
'==============
'CLIENT PROCESS
'==============
uses CoreWin
' from winbase.h and winnt.h
% PAGE_NOACCESS 0x01
% PAGE_READONLY 0x02
% PAGE_READWRITE 0x04
% PAGE_WRITECOPY 0x08
' Token Specific Access Rights.
% TOKEN_ASSIGN_PRIMARY 0x0001
% TOKEN_DUPLICATE 0x0002
% TOKEN_IMPERSONATE 0x0004
% TOKEN_QUERY 0x0008
% TOKEN_QUERY_SOURCE 0x0010
% TOKEN_ADJUST_PRIVILEGES 0x0020
% TOKEN_ADJUST_GROUPS 0x0040
% TOKEN_ADJUST_DEFAULT 0x0080
% TOKEN_ADJUST_SESSIONID 0x0100
% SECTION_QUERY 0x0001
% SECTION_MAP_WRITE 0x0002
% SECTION_MAP_READ 0x0004
% SECTION_MAP_EXECUTE 0x0008
% SECTION_EXTEND_SIZE 0x0010
% SECTION_ALL_ACCESS 0x001F
% SECTION_MAP_EXECUTE_EXPLICIT 0x0020
% STANDARD_RIGHTS_REQUIRED 0x000F0000L
% FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
sys INVALID_HANDLE_VALUE = -1 'as ptr
% TRUE 1
% FALSE 0
string Name="Local\MyFileMappingObject" 'GLOBAL\ NOT SUPPORTED
string cr=chr(13)+chr(10)
% BUF_SIZE 0x200
function main() as int
======================
sys hMapFile
sys pBuf
hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, Name)
if hMapFile == 0
print "Could not open file mapping object" + chr(13) + GetLastError()
return 1
endif
pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE)
if pBuf == 0
print "Could not map view of file" + chr(13) + GetLastError()
CloseHandle(hMapFile)
return 1
endif
'char*s : strptr(s)=pbuf
bind pBuf
sys p
int i1,i2
float f1,f2
char c1[0x100]
end bind
print "CLIENT: " cr +
c1 cr +
i1 " / " i2 ", " f1 cr cr
UnmapViewOfFile(pBuf)
CloseHandle(hMapFile)
return 0
end function
main
Remember to "ok" on the SERVER MessageBox to close it when done.
Thank you Charles,
I like it, new stuff to study...
Hi Charles,
Now that I had a look at it, yes I got many examples in my PowerBASIC folders.
I think you posted the first process ms example twice. The Server is the same as the client.
It is always interesting to see how you implement your code, much to learn from it.
Take care.
Charles,
From your code, on my pc, UnmapViewOfFile(pBuf) goes systematically to GPF.
pBuf is always OK.
This might be of help...
In my experiment, one time I had:
[Window Title] Kick - Error
[Main Instruction] Oxigen co264 can't compile this code!
[Content] ErrLevel: 31
Header: ASSEMBLER:
Error: mov qword r8,0x20202020!! wrong size for this register: e8
Error in: [D:\Dev\Oxygen\o2\inc\rtl64.inc]
Main file: [d:\dev\oxygen\o2\~code\interprocess\namedsharedmemoryb01.o2bas]
[Goto line 316, column 1 ?] [No]
Note, I got the same problem using UltraEdit or the Oxyde editor.
Do you have an idea on what's wrong?
Hi Pierre,
No, I've checked this version 4 on Oxide, Peroxide & JIT and compiled . UnmapViewOfFile does not cause a GPF.
Hi Charles,
I've tested under Windows 11 and all is fine.
Windows 7, not so...
Server.exe 64-bit 0.9.0 2025-04-15t13:55:16
Client.exe 32-bit 0.9.0 2025-04-15T13:55:03
Windows 7-64 Server gpf systematically on closing on UnmapViewOfFile(pBuf)
Windows 11-64 Server does not gpf at all
Cpu is AMD Ryzen 7 5800x
SharedMem.zip does the same.
Both Windows are on the same machine, no virtual Windows used but different boot partition.
It would be cool if anybody have a W7 around and feel like to test, if not, we will survive. :-)
I might try JIT in a week or so, I will be off the net for a little while.
Bind=eBind is a beauty !
Regards
I have Win7_64bit on Dual core with 2GB ram
(blame me i am lazy to build win10/11 PC..i have parts)
so what exactly i must test?
this program or download latest release?
(again i use older o2_sc604) ;D
Hi Pierre
I am not sure what this examples exactly do
i simply don't make such types of programs
but interesting my code editor written in OxygenBasic
cannot found compiler path ..look in image..
Hi Aurel,
Good to ear from you,
Seems you got the same file I used, aka server part from post #3.
I got no problem to compile the file as is from Oxide.
Under Windows 7/64, I tried eight O2 version, same gpf on all of them.
This include 6.04, so you might have the same gpf since you use this version.
All you have to do to test is compile the server part from post #3,
run it, then when you click the OK button a gpf error message from Windows appear.
It won't appear if I rem the line UnmapViewOfFile(pBuf)
This is the details provided in the gpf message box.
Signature du problème :
Nom d'événement de problème: BEX64
Nom de l'application: NamedSharedMemoryA01.exe
Version de l'application: 0.0.0.0
Horodatage de l'application: 684a3a2c
Nom du module par défaut: StackHash_5d53
Version du module par défaut: 0.0.0.0
Horodateur du module par défaut: 00000000
Décalage de l'exception: 0000010000000001
Code de l'exception: c0000005
Données d'exception: 0000000000000008
Version du système: 6.1.7601.2.1.0.256.48
Identificateur de paramètres régionaux: 3084
Information supplémentaire n° 1: 5d53
Information supplémentaire n° 2: 5d53daca3c00ebb4a7319390a6b37de1
Information supplémentaire n° 3: c8b0
Information supplémentaire n° 4: c8b099d242f1a67858aa0c71c55b8faf
Note that UnmapViewOfFile(pBuf) works fine in the client part.
I found it!
Problem is a conflict between bind and UnmapViewOfFile(pBuf)
if I replace Bind by CopyMemory then UnmapViewOfFile(pBuf) does not gpf anymore.
Bind might prevent UnmapViewOfFile(pBuf) to access memory for desalloating.
'in server code
declare sub CopyMemory lib "kernel32" alias "RtlMoveMemory" _
(byval Destination as sys, byval Source as sys, byval Length as long)
...
'bind pBuf
sys p
int i1, i2
float f1, f2
char c1[0x100]
'end bind
i1 = 123
i2 = 456
f1 = pi()
c1 = szMsg
sys pBuf2
CopyMemory pBuf, @p, sizeof(sys) : pBuf2 = pBuf + sizeof(sys)
CopyMemory pBuf2, @i1, sizeof(int) : pBuf2 += sizeof(sys) '123
CopyMemory pBuf2, @i2, sizeof(int) : pBuf2 += sizeof(sys) '456
CopyMemory pBuf2, @f1, sizeof(float) : pBuf2 += sizeof(sys)
CopyMemory pBuf2, @f2, sizeof(float) : pBuf2 += sizeof(sys)
CopyMemory pBuf2, @c1, len(szMsg)
'
OK then this is similar problem i have with BIND with
SendMessage() function in my awinh.inc file
all fine :D