|
I have a program in VB and this ok but the program in C++ is not ok
Can anybody help me to find the error or translate the VB to C++.
Visual Basiv program and this is OK!
///////////////////////////////////////////////
Private Sub Command1_Click()
Dim fins_cmnd(17) As Byte
fins_cmnd(0) = &H80 'ICF
fins_cmnd(1) = &H0 'RSV
fins_cmnd(2) = &H2 'GCT
fins_cmnd(3) = &H1 'DNA netword
fins_cmnd(4) = &H66 'DA1 node 102
fins_cmnd(5) = &H0 'DA2
fins_cmnd(6) = &H1 'SNA network
fins_cmnd(7) = &H64 'SA1 node 100
fins_cmnd(8) = &H0 'SA2
fins_cmnd(9) = &H1 'SID
fins_cmnd(10) = &H1 'MRC
fins_cmnd(11) = &H1 'SRC
fins_cmnd(12) = &H82 'Datatype
fins_cmnd(13) = &H0 'Startadresse
fins_cmnd(14) = &H64
fins_cmnd(15) = &H0
fins_cmnd(16) = &H0 'Antal ord.
fins_cmnd(17) = &H96
Dim I As Integer
Dim sMsg As String
For I = 0 To 17
sMsg = sMsg & Chr$(fins_cmnd(I))
Next
Winsock1.SendData sMsg
End Sub
Private Sub Form_Load()
With Winsock1
.Protocol = sckUDPProtocol
.LocalPort = 9600
.RemotePort = 9600
.RemoteHost = "192.168.1.102"
End With
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim sData As String
Dim I As Integer
Dim Counter As Integer
Dim sResp As String
Dim stmp As String
Winsock1.GetData sData, , 2010
For I = 1 To Len(sData) Step 1
stmp = Hex(Asc(Mid$(sData, I, 1)))
While Len(stmp) < 2
stmp = "0" & stmp
Wend
sResp = sResp & stmp
Next
List1.Clear
For I = Len(sResp) - 599 To Len(sResp) Step 4
List1.AddItem "DM" & 100 + Counter & " = " & Mid$(sResp, I, 4)
Counter = Counter + 1
Next I
End Sub
//////////////////////////////////////////////
Visual C++ program and this is not ok pleas help me!!
//Miscellaneous variables
INT status;
WSADATA wsaData;
WORD wVer = MAKEWORD(1,1);
SOCKADDR_IN ws_addr;
int nError;
char szError[80];
ULONG icmd;
//Begin: Init Winsock2
status = WSAStartup(wVer,&wsaData);
if (status != NO_ERROR)
{
WSACleanup();
return;
}
//Init socket
Sock = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
if(Sock < 0)
nError = WSAGetLastError();
// Fill out source socket's address information.
ws_addr.sin_family = AF_INET;
ws_addr.sin_port = htons (FINS_UDP_PORT);
ws_addr.sin_addr.s_addr = htonl (INADDR_ANY);
// Associate the source socket's address with the socket, Sock.
if (bind (Sock,
(struct sockaddr FAR *) &ws_addr,
sizeof (ws_addr)) == SOCKET_ERROR)
{
wsprintf (szError, TEXT("Binding socket failed! Error: %d"),
WSAGetLastError ());
MessageBox (szError, TEXT("Error"), MB_OK);
closesocket (Sock);
return;
}
//Disable non-blocking IO for purposes of this example.
icmd = 0;
status = ioctlsocket(Sock,FIONBIO,&icmd);
//GENERATE MEMORYAREA READ COMMAND
//(READ 150 WORDS FROM D00100.)
memset(fins_cmnd, 0, sizeof(fins_cmnd));
fins_cmnd[0]=0x80; /*ICF*/
fins_cmnd[1]=0x00; /*RSV*/
fins_cmnd[2]=0x02; /*GCT*/
fins_cmnd[3]=0x01; /*DNA*/ //network 1
fins_cmnd[4]=0x66; /*DA1*/ //node 102 /*Ethernet Unit FINS NODE NUMBER*/
fins_cmnd[5]=0x00; /*DA2*/ //unit 0
fins_cmnd[6]=0x01; /*SNA*/ //network 1
fins_cmnd[7]=0x64; /*SA1*/ //node 100 /*WS FINS NODE NUMBER*/
fins_cmnd[8]=0x00; /*SA2*/ //unit 0
fins_cmnd[9]=++sid; /*SID*/
fins_cmnd[10]=0x01; /*MRC*/ //command
fins_cmnd[11]=0x01; /*SRC*/
fins_cmnd[12]=0x82; /*VARIABLE TYPE: DM*/
fins_cmnd[13]=0x00; /*READ START ADDRESS: 100*/
fins_cmnd[14]=0x64;
fins_cmnd[15]=0x00;
fins_cmnd[16]=0x00; /*WORDS READ: 150*/
fins_cmnd[17]=0x96;
/*SEND FINS COMMAND*/
// Fill out source socket's address information.
memset(&cv_addr, 0, sizeof(cv_addr));
cv_addr.sin_family = AF_INET;
cv_addr.sin_port = htons (FINS_UDP_PORT);
cv_addr.sin_addr.s_addr = inet_addr (SERV_IP_ADDR);
sendlen = 18;
iRetVal = sendto(Sock, fins_cmnd, sendlen, 0,
(struct sockaddr FAR *)&cv_addr, sizeof(cv_addr));
///////////////////////////////////////////////////////////
|
|
|
|
|
Hello!
I have a strange problem. I have a standard SDI - FormView application. On the form I have two check boxes (which I have set to buttons), they are called IDC_AUTOMAT and IDC_MANUAL. I have used DDX to handle the events(created with ClassWizard), OnAutomat() and OnManual().
My problem is that if I have IDC_MANUEL checked and minimizes the application and then restore it. Somehow the OnAutomat is called. I can't figure out where this happens and how I avoid it?
Please help!
Below is the call stack when I set a breakpoint in OnAutomat().
CCOMSmartistView::OnAutomat() line 1264
_AfxDispatchCmdMsg(CCmdTarget * 0x00442180 {CCOMSmartistView hWnd=0x04c50a10}, unsigned int 2008, int 0, void (void)* 0x004014f6 CCOMSmartistView::OnAutomat(void), void * 0x00000000, unsigned int 12, AFX_CMDHANDLERINFO * 0x00000000) line 88
CCmdTarget::OnCmdMsg(unsigned int 2008, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes
CView::OnCmdMsg(unsigned int 2008, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 162 + 24 bytes
CWnd::OnCommand(unsigned int 2008, long 22088222) line 2088
CWnd::OnWndMsg(unsigned int 273, unsigned int 2008, long 22088222, long * 0x0012f304) line 1597 + 28 bytes
CWnd::WindowProc(unsigned int 273, unsigned int 2008, long 22088222) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x00442180 {CCOMSmartistView hWnd=0x04c50a10}, HWND__ * 0x04c50a10, unsigned int 273, unsigned int 2008, long 22088222) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x04c50a10, unsigned int 273, unsigned int 2008, long 22088222) line 368
AfxWndProcBase(HWND__ * 0x04c50a10, unsigned int 273, unsigned int 2008, long 22088222) line 220 + 21 bytes
USER32! 77e72211()
USER32! 77e7356c()
USER32! 77e86e01()
USER32! 77e85f71()
USER32! 77e72c6a()
USER32! 77e72cf5()
CWnd::DefWindowProcA(unsigned int 7, unsigned int 80022032, long 0) line 1000 + 32 bytes
CWnd::WindowProc(unsigned int 7, unsigned int 80022032, long 0) line 1586 + 26 bytes
AfxCallWndProc(CWnd * 0x00442300 {CButton hWnd=0x01510a1e}, HWND__ * 0x01510a1e, unsigned int 7, unsigned int 80022032, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x01510a1e, unsigned int 7, unsigned int 80022032, long 0) line 368
AfxWndProcBase(HWND__ * 0x01510a1e, unsigned int 7, unsigned int 80022032, long 0) line 220 + 21 bytes
USER32! 77e71303()
USER32! 77e71962()
NTDLL! 77f763ef()
CWnd::OnWndMsg(unsigned int 7, unsigned int 11405702, long 0, long * 0x0012f7bc) line 1872
CWnd::WindowProc(unsigned int 7, unsigned int 11405702, long 0) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x00442180 {CCOMSmartistView hWnd=0x04c50a10}, HWND__ * 0x04c50a10, unsigned int 7, unsigned int 11405702, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x04c50a10, unsigned int 7, unsigned int 11405702, long 0) line 368
AfxWndProcBase(HWND__ * 0x04c50a10, unsigned int 7, unsigned int 11405702, long 0) line 220 + 21 bytes
USER32! 77e71303()
USER32! 77e71962()
NTDLL! 77f763ef()
CFrameWnd::OnSetFocus(CWnd * 0x00000000 {CWnd hWnd=???}) line 1210
CWnd::OnWndMsg(unsigned int 7, unsigned int 0, long 0, long * 0x0012fa38) line 1872
CWnd::WindowProc(unsigned int 7, unsigned int 0, long 0) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x00442700 {CMainFrame hWnd=0x00ae0986}, HWND__ * 0x00ae0986, unsigned int 7, unsigned int 0, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00ae0986, unsigned int 7, unsigned int 0, long 0) line 368
AfxWndProcBase(HWND__ * 0x00ae0986, unsigned int 7, unsigned int 0, long 0) line 220 + 21 bytes
USER32! 77e71303()
USER32! 77e71962()
NTDLL! 77f763ef()
USER32! 77e71350()
USER32! 77e72c6a()
USER32! 77e72cf5()
CWnd::DefWindowProcA(unsigned int 274, unsigned int 61728, long 0) line 1000 + 32 bytes
CWnd::Default() line 249
CWnd::OnSysCommand(unsigned int 61728, unsigned int 61728) line 418 + 15 bytes
CFrameWnd::OnSysCommand(unsigned int 61728, long 0) line 1046
CWnd::OnWndMsg(unsigned int 274, unsigned int 61728, long 0, long * 0x0012fd98) line 1849
CWnd::WindowProc(unsigned int 274, unsigned int 61728, long 0) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x00442700 {CMainFrame hWnd=0x00ae0986}, HWND__ * 0x00ae0986, unsigned int 274, unsigned int 61728, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00ae0986, unsigned int 274, unsigned int 61728, long 0) line 368
AfxWndProcBase(HWND__ * 0x00ae0986, unsigned int 274, unsigned int 61728, long 0) line 220 + 21 bytes
Mike Eriksson
Sonork 100.21825
|
|
|
|
|
Have you checked that the IDC_xx values don't conflict with any standard Windows IDC_xx values. I assume the CWnd::OnSysCommand() is a Restore or Maximize command. Then you get OnSetFocus() which is fine. But why are you then getting OnCommand(). Have any of the controls been disabled.
Neville Franks, Author of ED for Windows. www.getsoft.com
Make money with our new Affilate program
|
|
|
|
|
Hello Neville!
Thanks for your answer!
I recieved an answer from an another source and the problem seems to be with the checkboxes and tab order. If I have the check boxes as the first tabs, i.e. The IDC_AUTOMATIC is tab 1 and therefore default focused. It will generate an ON_COMMAND IDC_AUTOMATIC. If I change tab order and let an editbox get the first tab then everything is OK!
Strange
Mike Eriksson
Sonork 100.21825
|
|
|
|
|
Mike Eriksson wrote:
I recieved an answer from an another source and the problem seems to be with the checkboxes and tab order. If I have the check boxes as the first tabs, i.e. The IDC_AUTOMATIC is tab 1 and therefore default focused. It will generate an ON_COMMAND IDC_AUTOMATIC. If I change tab order and let an editbox get the first tab then everything is OK!
This doesn't make any sense to me. You should see an ON_SETFOCUS but not an ON_COMMAND. It sounds like someone is sending an ON_COMMAND when they shouldn't be. Do you do any SendMessage( .., WM_COMMAND, .. ) in your code.
Also I'd suggest you use Spy++ or WinsSpector and look at precisely what messages the IDC_AUTOMATIC checkbox is getting.
Neville Franks, Author of ED for Windows. www.getsoft.com
Make money with our new Affilate program
|
|
|
|
|
Neville Franks wrote:
This doesn't make any sense to me. You should see an ON_SETFOCUS but not an ON_COMMAND. It sounds like someone is sending an ON_COMMAND when they shouldn't be. Do you do any SendMessage( .., WM_COMMAND, .. ) in your code.
No, I don't use SendMessage(). All message handlers are created with ClassWizard.
Also I'd suggest you use Spy++ or WinsSpector and look at precisely what messages the IDC_AUTOMATIC checkbox is getting.
I will try this, although since the program now works it's nothing I will prioritize
Thanks for your answer, I appriaciate it very much!
Mike Eriksson
Sonork 100.21825
|
|
|
|
|
[This post follows one I've posted earlier]
I'd like to be able to read and write the following registry entry (NT System):
HKEY_CURRENT_USER\Control Panel\International\sDecimal
I do not know how to access it. If this can help, i know that this entry is actually in the hive %User%.dat where %User% is the current user logged on the PC. File is in Win\Profiles\%User%. But i do not know how to read this file, neither how to change it (since it is currently in use).
::SetRegistryKey(KEY) and correspondign functions Get/WriteProfileInt/String only allow to change the entries contained in HKEY_CURRENT_USER\Software\KEY ...
So ... any idea ?
~RaGE();
|
|
|
|
|
Rage wrote:
::SetRegistryKey(KEY) and correspondign functions Get/WriteProfileInt/String only allow to change the entries contained in HKEY_CURRENT_USER\Software\KEY ...
Yes, the Get/WriteProfileInt/String functions do that... but not:
RegOpenKeyEx() , RegQueryValueEx() and then RegSetValueEx() can do what you want!
Look up these in MSDN Library and you'll find more such functions.
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
Thanks a lot. Incredible I've never came across these functions, since I'Ve been searching for registry, key, ... the whole day through MSDN.
~RaGE();
|
|
|
|
|
Well, actually, i cannot open this key.
here's my code : what's wrong ?
PHKEY kHandle=new HKEY;
LPCTSTR Key="Control Panel\\International";
LPTSTR b;
PLONG d;
long int yop=RegOpenKeyEx(HKEY_CURRENT_USER,Key,0,KEY_QUERY_VALUE,kHandle);
if (yop==ERROR_SUCCESS)
{
RegQueryValue(*kHandle,"sDecimal",b,d);
}
yop comes up with 998.
Could you provide me with an example ? The key was
HKEY_CURRENT_USER\Control Panel\International\sDecimal
Thank you very much
~RaGE();
|
|
|
|
|
hi,
this is done like this..I think you are doing right..
except.. in last argument pass address of kHandle..like this and use it like..
RegOpenKeyEx(HKEY_CURRENT_USER, _T("software"), 0, KEY_WRITE|KEY_READ,
&kHandle);
I hope this time it works..
cheers
Himanshu
|
|
|
|
|
|
I'm here again asking for advice for my server that I'm developing.
I'm using blocking sockets and of course it's multithreaded.
I put all my accepted clients in a std::list object and when a client send a message to all clients (or just one), should I always check the list if there is any disconnected clients and then remove them from the list before I send the messages to all clients in the list?
Should I have a timer or something that updating the list every n seconds or would that slow down the system?
Short say: How often or when should I update my std::list ?
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
I highly recommend that you redesign the server using a robust non-blocking I/O such as Overlapped I/O and Completion Port I/O. Under non-blocking I/O, the OS will notify the server the state of the sockets.
In terms of solution for this problem, there is no elegant solution. One solution is to process all sockets and determine their states. The time interval depends on the type of server.
Kuphryn
|
|
|
|
|
kuphryn wrote:
non-blocking I/O
I don't understand non-blocking sockets but I want to.
There is one problem, I have no idea where to read about non-blocking sockets!
So if you could give me a name of a good book or a link to a good and big tutorial, would that be nice!
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
There are several articles on overlapped I/O and I/O completion ports on CP. Look in the internet and networks section. Non blocking sockets, while good, will not tell you whether a client is connected or not (unless you do something else to your code, but then you could do something similar to your existing code too).
Overlapped I/O is simple really. Instead of thinking in terms of threads, clients or sockets, you need to think in terms of events (read, write, send, recieve, etc). Once you get the hang of it, you will find it is more appropriate in many situations. On the other hand, just because non blocking sockets exist, does not mean you should use them in every situation. It takes much longer to implement them, and the gain is not always worth it. Only if your server is always busy, will you see an advantage.
In the mean time, while you are reading up on non blocking sockets, you could try this:
Keep a timer for all your sockets. Every receive resets the timer. If the timer is fired, a function will check to see if the client is disconnected. If it is, the client will be removed from the list. If not, the timer will be reset.
This will only be advisable if there aren't too many clients at the same time. Otherwise a lot of resources might be used up just for the timers. If there are too many clients connected, you may consider overlapped I/O.
Regards,
Rohit Sinha
|
|
|
|
|
Hey Rickard, I do it similar in my chat:
If a client socket gets a disconnect event, it shuts down and then marks itself as dead. One regular server timer will check for dead sockets (in a std::vector or std::list) and remove them from the list. I dont like if objects delete themself on their own, which is possible in C++ of course (but you have to do some locking etc to be thread safe).
A regular timer sounds like a waste... but it doesnt eat much time and for my chat I already needed regular checks, for things like: is client timeout, is client flooding, client needs a welcome etc. ATM I do this checks every second.
So, when the server becomes a message "Rickard greets all" for sending to all clients, it goes through the list and sends it to every client that is not dead (and properly logged in). All dead sockets become removed in regular intervalls and won't polute the socket list for long. You might want to maintain more then one internal list, e.g. one for 'incoming and not logged in crap sockets' and one for 'logged in chat client sockets'.
Hope it helps... hej då, Moak
|
|
|
|
|
Moak wrote:
So, when the server becomes a message "Rickard greets all" for sending to all clients, it goes through the list and sends it to every client that is not dead (and properly logged in). All dead sockets become removed in regular intervalls and won't polute the socket list for long.
Okay, let's say you do start sending to all clients in the list and then suddenly a socket gets closed , the regular interval will delete it after sending because it suddenly became dead (if you know what I mean, perhaps not), that means I will do a send() call to a dead socket. Is that bad? I mean it shouldn't be... doesn't it just return an error code or something if I send to a dead socket?
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
Rickard Andersson wrote:
start sending to all clients in the list and then suddenly a socket gets closed
Well... that is strictly NOT allowed to happen (but it will of course). What you do to prevent such cases does hardly depend on your socket concept.
If you run a nonblocking multi threaded server concept you need to hazzle with locking on your own. E.g. wait in client thread until server thread signs "okay, socket list is available for write attempts" (beware of deadlocks). I mean, two threads writing simultanously on a STL container is a 'no no'. Just sending to an unconnected/dead socket will cause IMHO an uncritical error return value (which you can ignore).
If you have a nonblocking asychronous concept within one thread context you're lucky as it is. Because all client/server events are allready "synchronized" and come one after another. I do it this way in my chat. Regarding your question: in this socket concept one socket event says "receiving data" and you decide to send your stuff to all clients.... the next socket event says "socket disconnected" and you mark socket as dead for later remove. That's it here.
Hope it helps a bit, Moak
|
|
|
|
|
Moak wrote:
If you run a nonblocking multi threaded server concept you need to hazzle with locking on your own. E.g. wait in client thread until server thread signs "okay, socket list is available for write attempts" (beware of deadlocks). I mean, two threads writing simultanously on a STL container is a 'no no'. Just sending to an unconnected/dead socket will cause IMHO an uncritical error return value (which you can ignore).
My first design was almost like this except from my design was with blocking sockets.
But now I trying to use that one you mention below...
Moak wrote:
If you have a nonblocking asychronous concept within one thread context you're lucky as it is. Because all client/server events are allready "synchronized" and come one after another.
Yes, I use that concept for now. It's much more powerful and STABLE than the blocking multi threaded concept!
Moak wrote:
the next socket event says "socket disconnected" and you mark socket as dead for later remove.
Aaah! My regular interval removes it from the list, I just mark it dead!! woohoo!!
Thank you so so much!
You've teached me more than anybody has! I mean it, you're really know this topic!
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
Rickard Andersson wrote:
You've teached me more than anybody has! I mean it, you're really know this topic!
Ah cool, it works and I could help!! prolly I know some stuff b/c I program a chat as well and so do run into same questions. Just ask if there is more...
Greets, Moak
PS: Oh and please don't make your chat better than mine! *kidding*
|
|
|
|
|
Moak wrote:
PS: Oh and please don't make your chat better than mine!
Mowahaha!
I will make a better chat than anyone! A better than ICQ and MSN!!!! Better then ALL chat systems in the whole world!!!
Rickard, stop dreaming....
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
Hey Moak, can you explain how FD_WRITE works!?
I do like this:
case WM_SOCKET:
if (WSAGETSELECTERROR(lParam))
{
closesocket(wParam);
break;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
Accept = accept(wParam, NULL, NULL);
WSAAsyncSelect(Accept, hWnd, WM_SOCKET,
FD_READ | FD_WRITE | FD_CLOSE);
break;
case FD_READ:
MessageBox(NULL, "FD_READ", "FD_READ",MB_OK);
break;
case FD_WRITE:
MessageBox(NULL, "FD_WRITE", "FD_WRITE",MB_OK);
break;
case FD_CLOSE:
MessageBox(NULL, "FD_CLOSE", "CLOSE",MB_OK);
closesocket(wParam);
break;
}
break;
What I have problems with is that I don't really understand the use of FD_WRITE.
When does my WndProc get this message???
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
Rickard Andersson wrote:
What I have problems with is that I don't really understand the use of FD_WRITE.
Hm... when you are allowed to send more data (ATM you don't need to handle with it since you do not send large amount of data).
Doesn't answer your question, right? Well, it's a FAQ so I'm lazy and suggest to read some winsock references. See link in last posts or e.g. here http://www.hal-pc.org/~johnnie2/winsock.html[^]
[EDIT]PS: Have a look into Sockcore.cpp if you want to stick with Winsock's asynchronous mode[/EDIT]
|
|
|
|
|
Moak wrote:
Hm... when you are allowed to send more data
You mean if I send a buffert that is 200 bytes large but I only send 100 bytes at time.. then the FD_WRITE is sent?
Hm.. but wait... I can't send 100 byte and let the socket know there is more data to send? Or?
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|