472,141 Members | 1,037 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,141 software developers and data experts.

PyWin SendMessage

Hello everybody,

I've tryed to use an interprocess communication via
SendMessage on Windows.
Unfortunately, nothing goes on

################################################## #######################
#! /usr/bin/env python

import win32api, win32ui, win32con
import struct, array

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

def packCopyData(nNum, sString):
int_buffer = array.array("L",[nNum])
char_buffer = array.array('c', sString)
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address = char_buffer.buffer_info()[0]
char_buffer_size = char_buffer.buffer_info()[1]
copy_struct = struct.pack("pLp", # dword*, dword, char*
int_buffer_address,
char_buffer_size,
char_buffer)
return copy_struct
# get the window handle
hwnd = win32ui.FindWindow(None, "special window")

# print just for fun
print hwnd

cds = packCopyData(1, '1')
print cds

# try to send it a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
cds)

################################################## #######################

The last parameter shut be an integer, but I think it must be a pointer ?

Any experience or a tip for me ?
gf
Sep 29 '05 #1
8 6304
"g.franzkowiak" <g.***********@onlinehome.de> writes:
Hello everybody,

I've tryed to use an interprocess communication via
SendMessage on Windows.
Unfortunately, nothing goes on

################################################## #######################
#! /usr/bin/env python

import win32api, win32ui, win32con
import struct, array

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

def packCopyData(nNum, sString):
int_buffer = array.array("L",[nNum])
char_buffer = array.array('c', sString)
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address = char_buffer.buffer_info()[0]
char_buffer_size = char_buffer.buffer_info()[1]
copy_struct = struct.pack("pLp", # dword*, dword, char*
int_buffer_address,
char_buffer_size,
char_buffer)
return copy_struct


After packCopyData(...) returns, the arrays are destroyed, which will
probably void their contents. You must keep them alive until you don't
need the COPYDATASTRUCT instance any longer. For this kind of stuff,
ctypes may be easier to use than pywin32.

Thomas
Sep 29 '05 #2
Thomas Heller schrieb:
"g.franzkowiak" <g.***********@onlinehome.de> writes:

Hello everybody,

I've tryed to use an interprocess communication via
SendMessage on Windows.
Unfortunately, nothing goes on

################################################ #########################
#! /usr/bin/env python

import win32api, win32ui, win32con
import struct, array

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

def packCopyData(nNum, sString):
int_buffer = array.array("L",[nNum])
char_buffer = array.array('c', sString)
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address = char_buffer.buffer_info()[0]
char_buffer_size = char_buffer.buffer_info()[1]
copy_struct = struct.pack("pLp", # dword*, dword, char*
int_buffer_address,
char_buffer_size,
char_buffer)
return copy_struct

After packCopyData(...) returns, the arrays are destroyed, which will
probably void their contents. You must keep them alive until you don't
need the COPYDATASTRUCT instance any longer. For this kind of stuff,
ctypes may be easier to use than pywin32.

Thomas


Hmm, have read something in <<http://aspn.activestate.com>>
and the script changed to this:

#---------------------------------------------------------
#! /usr/bin/env python

import win32api, win32ui, win32con, win32gui
import struct, array
from ctypes import *

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

class COPYDATATYPE(Structure):
_fields_ = [("nNum", c_ulong),
("szData", c_char_p)]

class COPYDATASTRUCT(Structure):
_fields_ = [("dwData", c_ulong),
("cbData", c_ulong),
("lpData", POINTER(COPYDATATYPE))]

# get the window handle
hwnd = win32ui.FindWindow(None, "target window")

# print just for fun
# ##print hwnd

# prepare copydata structure for sending data
cpyData = COPYDATATYPE(1, '1')
cds = COPYDATASTRUCT(c_ulong(1),
c_ulong(sizeof(cpyData)),
pointer(cpyData))

# try to send a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
pointer(cds))

#---------------------------------------------------------
and the message for the last line is:
==> TypeError: an integer is required"

This message comes with "pointer(cds)" and with "addressof(cds)"
gerd
Sep 29 '05 #3
"g.franzkowiak" <g.***********@onlinehome.de> writes:
Thomas Heller schrieb:
"g.franzkowiak" <g.***********@onlinehome.de> writes:

Hello everybody,

I've tryed to use an interprocess communication via
SendMessage on Windows.
Unfortunately, nothing goes on

############################################### ##########################
#! /usr/bin/env python

import win32api, win32ui, win32con
import struct, array

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

def packCopyData(nNum, sString):
int_buffer = array.array("L",[nNum])
char_buffer = array.array('c', sString)
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address = char_buffer.buffer_info()[0]
char_buffer_size = char_buffer.buffer_info()[1]
copy_struct = struct.pack("pLp", # dword*, dword, char*
int_buffer_address,
char_buffer_size,
char_buffer)
return copy_struct

After packCopyData(...) returns, the arrays are destroyed, which will
probably void their contents. You must keep them alive until you don't
need the COPYDATASTRUCT instance any longer. For this kind of stuff,
ctypes may be easier to use than pywin32.

Thomas


Hmm, have read something in <<http://aspn.activestate.com>>
and the script changed to this:

#---------------------------------------------------------
#! /usr/bin/env python

import win32api, win32ui, win32con, win32gui
import struct, array
from ctypes import *

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

class COPYDATATYPE(Structure):
_fields_ = [("nNum", c_ulong),
("szData", c_char_p)]

class COPYDATASTRUCT(Structure):
_fields_ = [("dwData", c_ulong),
("cbData", c_ulong),
("lpData", POINTER(COPYDATATYPE))]

# get the window handle
hwnd = win32ui.FindWindow(None, "target window")

# print just for fun
# ##print hwnd

# prepare copydata structure for sending data
cpyData = COPYDATATYPE(1, '1')
cds = COPYDATASTRUCT(c_ulong(1),
c_ulong(sizeof(cpyData)),
pointer(cpyData))

# try to send a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
pointer(cds))

#---------------------------------------------------------
and the message for the last line is:
==> TypeError: an integer is required"

This message comes with "pointer(cds)" and with "addressof(cds)"


That error refers to the first argument - win32ui.FindWindow returns a
PyCWnd object, which is not accepted by win32api.SendMessage.
Changing this brings you one step further. win32api.SendMessage accepts
an integer for the last element, so addressof(cds) should work now.

win32gui.SendMessage is more tolerant in what it accepts as 4th
argument, according to the error message you get when you try it it
expects a string, a buffer, or an integer. So you could use addressof()
or pointer(), what you like best.

Thomas
Sep 29 '05 #4
Thomas Heller schrieb:
"g.franzkowiak" <g.***********@onlinehome.de> writes:

Thomas Heller schrieb:
"g.franzkowiak" <g.***********@onlinehome.de> writes:

Hello everybody,

I've tryed to use an interprocess communication via
SendMessage on Windows.
Unfortunately, nothing goes on

############################################## ###########################
#! /usr/bin/env python

import win32api, win32ui, win32con
import struct, array

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

def packCopyData(nNum, sString):
int_buffer = array.array("L",[nNum])
char_buffer = array.array('c', sString)
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address = char_buffer.buffer_info()[0]
char_buffer_size = char_buffer.buffer_info()[1]
copy_struct = struct.pack("pLp", # dword*, dword, char*
int_buffer_address,
char_buffer_size,
char_buffer)
return copy_struct
After packCopyData(...) returns, the arrays are destroyed, which will
probably void their contents. You must keep them alive until you don't
need the COPYDATASTRUCT instance any longer. For this kind of stuff,
ctypes may be easier to use than pywin32.

Thomas


Hmm, have read something in <<http://aspn.activestate.com>>
and the script changed to this:

#---------------------------------------------------------
#! /usr/bin/env python

import win32api, win32ui, win32con, win32gui
import struct, array
from ctypes import *

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

class COPYDATATYPE(Structure):
_fields_ = [("nNum", c_ulong),
("szData", c_char_p)]

class COPYDATASTRUCT(Structure):
_fields_ = [("dwData", c_ulong),
("cbData", c_ulong),
("lpData", POINTER(COPYDATATYPE))]

# get the window handle
hwnd = win32ui.FindWindow(None, "target window")

# print just for fun
# ##print hwnd

# prepare copydata structure for sending data
cpyData = COPYDATATYPE(1, '1')
cds = COPYDATASTRUCT(c_ulong(1),
c_ulong(sizeof(cpyData)),
pointer(cpyData))

# try to send a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
pointer(cds))

#---------------------------------------------------------
and the message for the last line is:
==> TypeError: an integer is required"

This message comes with "pointer(cds)" and with "addressof(cds)"

That error refers to the first argument - win32ui.FindWindow returns a
PyCWnd object, which is not accepted by win32api.SendMessage.
Changing this brings you one step further. win32api.SendMessage accepts
an integer for the last element, so addressof(cds) should work now.

win32gui.SendMessage is more tolerant in what it accepts as 4th
argument, according to the error message you get when you try it it
expects a string, a buffer, or an integer. So you could use addressof()
or pointer(), what you like best.

Thomas


Hi Thomas,

crazy, operates :-))
Only 'addressof' is possible and
merely the data types on the receiver side are not correct.
I want use an int and char[256], must play...

Thanks
gerd
Sep 29 '05 #5
Thomas Heller schrieb:
"g.franzkowiak" <g.***********@onlinehome.de> writes:

Thomas Heller schrieb:
"g.franzkowiak" <g.***********@onlinehome.de> writes:

Hello everybody,

I've tryed to use an interprocess communication via
SendMessage on Windows.
Unfortunately, nothing goes on

############################################## ###########################
#! /usr/bin/env python

import win32api, win32ui, win32con
import struct, array

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

def packCopyData(nNum, sString):
int_buffer = array.array("L",[nNum])
char_buffer = array.array('c', sString)
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address = char_buffer.buffer_info()[0]
char_buffer_size = char_buffer.buffer_info()[1]
copy_struct = struct.pack("pLp", # dword*, dword, char*
int_buffer_address,
char_buffer_size,
char_buffer)
return copy_struct
After packCopyData(...) returns, the arrays are destroyed, which will
probably void their contents. You must keep them alive until you don't
need the COPYDATASTRUCT instance any longer. For this kind of stuff,
ctypes may be easier to use than pywin32.

Thomas


Hmm, have read something in <<http://aspn.activestate.com>>
and the script changed to this:

#---------------------------------------------------------
#! /usr/bin/env python

import win32api, win32ui, win32con, win32gui
import struct, array
from ctypes import *

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

class COPYDATATYPE(Structure):
_fields_ = [("nNum", c_ulong),
("szData", c_char_p)]

class COPYDATASTRUCT(Structure):
_fields_ = [("dwData", c_ulong),
("cbData", c_ulong),
("lpData", POINTER(COPYDATATYPE))]

# get the window handle
hwnd = win32ui.FindWindow(None, "target window")

# print just for fun
# ##print hwnd

# prepare copydata structure for sending data
cpyData = COPYDATATYPE(1, '1')
cds = COPYDATASTRUCT(c_ulong(1),
c_ulong(sizeof(cpyData)),
pointer(cpyData))

# try to send a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
pointer(cds))

#---------------------------------------------------------
and the message for the last line is:
==> TypeError: an integer is required"

This message comes with "pointer(cds)" and with "addressof(cds)"

That error refers to the first argument - win32ui.FindWindow returns a
PyCWnd object, which is not accepted by win32api.SendMessage.
Changing this brings you one step further. win32api.SendMessage accepts
an integer for the last element, so addressof(cds) should work now.

win32gui.SendMessage is more tolerant in what it accepts as 4th
argument, according to the error message you get when you try it it
expects a string, a buffer, or an integer. So you could use addressof()
or pointer(), what you like best.

Thomas


Super, operates :-))

My last answer must be in the Nirvana, strange ?

Ok, only the version with 'addressof' generates a message and I must
play with the data types. The receiver becomes a wrong data formate.
Expect (int=1, char[256]='1\00'), but the int is 0x31 and the string
somewhat. Must play with my data.

Thanks
gerd
Sep 29 '05 #6
g.franzkowiak escribió:
Thomas Heller schrieb:

"g.franzkowiak" <g.***********@onlinehome.de> writes:

Thomas Heller schrieb:

"g.franzkowiak" <g.***********@onlinehome.de> writes:

>Hello everybody,
>
>I've tryed to use an interprocess communication via
>SendMessage on Windows.
>Unfortunately, nothing goes on
>
>############################################# ############################
>#! /usr/bin/env python
>
>import win32api, win32ui, win32con
>import struct, array
>
>"""
>typedef struct tagCOPYDATASTRUCT { // cds
> DWORD dwData;
> DWORD cbData;
> PVOID lpData;
>} COPYDATASTRUCT;
>"""
>
>def packCopyData(nNum, sString):
> int_buffer = array.array("L",[nNum])
> char_buffer = array.array('c', sString)
> int_buffer_address = int_buffer.buffer_info()[0]
> char_buffer_address = char_buffer.buffer_info()[0]
> char_buffer_size = char_buffer.buffer_info()[1]
> copy_struct = struct.pack("pLp", # dword*, dword, char*
> int_buffer_address,
> char_buffer_size,
> char_buffer)
> return copy_struct
>
>
After packCopyData(...) returns, the arrays are destroyed, which will
probably void their contents. You must keep them alive until you don't
need the COPYDATASTRUCT instance any longer. For this kind of stuff,
ctypes may be easier to use than pywin32.

Thomas
Hmm, have read something in <<http://aspn.activestate.com>>
and the script changed to this:

#---------------------------------------------------------
#! /usr/bin/env python

import win32api, win32ui, win32con, win32gui
import struct, array
from ctypes import *


"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

class COPYDATATYPE(Structure):
_fields_ = [("nNum", c_ulong),
("szData", c_char_p)]

class COPYDATASTRUCT(Structure):
_fields_ = [("dwData", c_ulong),
("cbData", c_ulong),
("lpData", POINTER(COPYDATATYPE))]

# get the window handle
hwnd = win32ui.FindWindow(None, "target window")

# print just for fun
# ##print hwnd

# prepare copydata structure for sending data
cpyData = COPYDATATYPE(1, '1')
cds = COPYDATASTRUCT(c_ulong(1),
c_ulong(sizeof(cpyData)),
pointer(cpyData))

# try to send a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
pointer(cds))

#---------------------------------------------------------
and the message for the last line is:
==> TypeError: an integer is required"

This message comes with "pointer(cds)" and with "addressof(cds)"

That error refers to the first argument - win32ui.FindWindow returns a
PyCWnd object, which is not accepted by win32api.SendMessage.
Changing this brings you one step further. win32api.SendMessage accepts
an integer for the last element, so addressof(cds) should work now.

win32gui.SendMessage is more tolerant in what it accepts as 4th
argument, according to the error message you get when you try it it
expects a string, a buffer, or an integer. So you could use addressof()
or pointer(), what you like best.

Thomas


Super, operates :-))

My last answer must be in the Nirvana, strange ?

Ok, only the version with 'addressof' generates a message and I must
play with the data types. The receiver becomes a wrong data formate.
Expect (int=1, char[256]='1\00'), but the int is 0x31 and the string
somewhat. Must play with my data.

Thanks
gerd


Hi Gerd,

I'm not really sure of, but I think you must use a message value in
range of WM_USER or WM_APP so this fact maybe let the receiver window
getting bad data... have a look to this:

http://msdn.microsoft.com/library/de...es/wm_user.asp

0 through WM_USER
<http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesmessages/wm_user.asp>
0x0400
Messages reserved for use by the system.
*WM_USER* through 0x7FFF Integer messages for use by private window
classes.
*WM_APP* through 0xBFFF Messages available for use by applications.
0xC000 through 0xFFFF String messages for use by applications.
Greater than 0xFFFF Reserved by the system.

I've done the same with PHP GTK and achieved random results sending low
Msg values... until used WM_USER and above. Also, in my case only
PostMessage work fine... try using both... but expect this doesn't
happen with python,

Hope it helps.

Gonzalo
Sep 30 '05 #7
Gonzalo Monzón schrieb:
g.franzkowiak escribió:
Thomas Heller schrieb:

"g.franzkowiak" <g.***********@onlinehome.de> writes:


Thomas Heller schrieb:

> "g.franzkowiak" <g.***********@onlinehome.de> writes:
>
>
>
>
>
>> Hello everybody,
>>
>> I've tryed to use an interprocess communication via
>> SendMessage on Windows.
>> Unfortunately, nothing goes on
>>
>> ################################################## #######################
>>
>> #! /usr/bin/env python
>>
>> import win32api, win32ui, win32con
>> import struct, array
>>
>> """
>> typedef struct tagCOPYDATASTRUCT { // cds
>> DWORD dwData;
>> DWORD cbData;
>> PVOID lpData;
>> } COPYDATASTRUCT;
>> """
>>
>> def packCopyData(nNum, sString):
>> int_buffer = array.array("L",[nNum])
>> char_buffer = array.array('c', sString)
>> int_buffer_address = int_buffer.buffer_info()[0]
>> char_buffer_address = char_buffer.buffer_info()[0]
>> char_buffer_size = char_buffer.buffer_info()[1]
>> copy_struct = struct.pack("pLp", # dword*, dword, char*
>> int_buffer_address,
>> char_buffer_size,
>> char_buffer)
>> return copy_struct
>>
>
> After packCopyData(...) returns, the arrays are destroyed, which will
> probably void their contents. You must keep them alive until you
> don't
> need the COPYDATASTRUCT instance any longer. For this kind of stuff,
> ctypes may be easier to use than pywin32.
>
> Thomas
>

Hmm, have read something in <<http://aspn.activestate.com>>
and the script changed to this:

#---------------------------------------------------------
#! /usr/bin/env python

import win32api, win32ui, win32con, win32gui
import struct, array

from ctypes import *

"""
typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
"""

class COPYDATATYPE(Structure):
_fields_ = [("nNum", c_ulong),
("szData", c_char_p)]

class COPYDATASTRUCT(Structure):
_fields_ = [("dwData", c_ulong),
("cbData", c_ulong),
("lpData", POINTER(COPYDATATYPE))]

# get the window handle
hwnd = win32ui.FindWindow(None, "target window")

# print just for fun
# ##print hwnd

# prepare copydata structure for sending data
cpyData = COPYDATATYPE(1, '1')
cds = COPYDATASTRUCT(c_ulong(1),
c_ulong(sizeof(cpyData)),
pointer(cpyData))

# try to send a message
win32api.SendMessage(hwnd,
win32con.WM_COPYDATA,
0,
pointer(cds))

#---------------------------------------------------------
and the message for the last line is:
==> TypeError: an integer is required"

This message comes with "pointer(cds)" and with "addressof(cds)"
That error refers to the first argument - win32ui.FindWindow returns a
PyCWnd object, which is not accepted by win32api.SendMessage.
Changing this brings you one step further. win32api.SendMessage accepts
an integer for the last element, so addressof(cds) should work now.

win32gui.SendMessage is more tolerant in what it accepts as 4th
argument, according to the error message you get when you try it it
expects a string, a buffer, or an integer. So you could use addressof()
or pointer(), what you like best.

Thomas

Super, operates :-))

My last answer must be in the Nirvana, strange ?

Ok, only the version with 'addressof' generates a message and I must
play with the data types. The receiver becomes a wrong data formate.
Expect (int=1, char[256]='1\00'), but the int is 0x31 and the string
somewhat. Must play with my data.

Thanks
gerd


Hi Gerd,

I'm not really sure of, but I think you must use a message value in
range of WM_USER or WM_APP so this fact maybe let the receiver window
getting bad data... have a look to this:

http://msdn.microsoft.com/library/de...es/wm_user.asp
0 through WM_USER
<http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesmessages/wm_user.asp>
0x0400
Messages reserved for use by the system.
*WM_USER* through 0x7FFF Integer messages for use by private window
classes.
*WM_APP* through 0xBFFF Messages available for use by applications.
0xC000 through 0xFFFF String messages for use by applications.
Greater than 0xFFFF Reserved by the system.

I've done the same with PHP GTK and achieved random results sending low
Msg values... until used WM_USER and above. Also, in my case only
PostMessage work fine... try using both... but expect this doesn't
happen with python,

Hope it helps.

Gonzalo

Hi Gonzalo,

thank you for your interest and for your tips.
With your links was it possible to learn something over messages in user
applications. I'm not the windows guru, like the open source scene.

My problem was not the message type and I think the WM_COPYDATA is the
right thing for interprocess communication between python and C++.
I've changed in my script the COPYDATATYPE field szData from c_char_p to
c_char * 256 and the memory is correct initialized. The first situation
was according to **data and in consequence the wrong content on the
receiver side.
Now is it a good thing :-)

gerd

Sep 30 '05 #8
Gonzalo Monzón <gm*@serveisw3.net> wrote:

Hi Gerd,

I'm not really sure of, but I think you must use a message value in
range of WM_USER or WM_APP so this fact maybe let the receiver window
getting bad data...


No. WM_COPYDATA is designed specifically for his use case -- interprocess
communication. The WM_USER range is only if you are inventing a custom
message for some new purpose.
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Oct 2 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by JSK | last post: by
18 posts views Thread by Lars Netzel | last post: by
6 posts views Thread by Charles Krug | last post: by
7 posts views Thread by Mr. Roboto | last post: by
4 posts views Thread by Abubakar | last post: by
1 post views Thread by Necromis | last post: by
5 posts views Thread by michelqa | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.