青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 29,comments - 10,trackbacks - 0

今天學(xué)習(xí)了些關(guān)于VC網(wǎng)絡(luò)編程中關(guān)于Winsock的知識,并做了相應(yīng)的整理。在這里根據(jù)了一個聊天室例子幫助我了解這些知識的用法。
(1)Server端調(diào)用函數(shù)順序:
         WSAStartup()初始化Winsock
         socket()創(chuàng)建一個監(jiān)聽Socket
         bind()為監(jiān)聽Socket指定通信對象
         listen()設(shè)置等待連接狀態(tài)
         accept()接收連接并生成會話Socket
         send和recv進行對話
         closesocket()關(guān)閉socket
(2)Client端調(diào)用函數(shù)順序
         WSAStartup()初始化Winsock
         socket()創(chuàng)建一個監(jiān)聽Socket
         connect()與Server端連接
         send和recv進行對話
         closesocket()關(guān)閉socket
1、程序頭部分,包括引用的頭文件、宏定義、全局變量和函數(shù)聲明

#include "stdafx.h"
#include 
"resource.h"
#include 
<VECTOR>                        //采用STL
#include <algorithm>
#include 
<WINSOCK2.H>                    //調(diào)用winsock                        
#include <ASSERT.H>

#define BUFFER_SIZE 4096               //緩沖區(qū)的大小
#define SERVER_MESSAGE WM_USER+100        //服務(wù)器SOCKET異步消息ID
#define CLIENT_MESSAGE WM_USER+101      //客戶機SOCKET異步消息ID

// Global Variables:
SOCKET g_ListenSocket;                //Listen socket (for server)
std::vector<SOCKET>  g_DataSockets;    //All data sockets with clients (for server)
SOCKET g_ClientSocket;                //Client data socket (for client)
BOOL g_bActive;                        //A tag of active socket (for both server and client)
std::string g_ChatWords;
BOOL g_bClient;                        
//TRUE as a client, FALSE as a server

BOOL ServerInit(HWND hWnd,UINT port);
BOOL ClientInit(HWND hWnd,UINT port,
const char* serverIP);
int OnClientMessage(HWND hWnd, WPARAM wParam, LPARAM lParam);
int OnServerMessage(HWND hWnd, WPARAM wParam, LPARAM lParam);
void SendMessageToPeer(HWND hWnd);
void Send(SOCKET sock, const char* buffer, int length);
void RefreshScreen(HWND hWnd);
void ExitChat(HWND hWnd);
void GetErrorReason();
2、Win32程序函數(shù)入口點WinMain:
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int       nCmdShow)
{
    
// Perform application initialization:
    g_bActive=FALSE;
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_CHAT_DIALOG), NULL, (DLGPROC)WndProc);
    
return 0;
}
3、對話框的消息循環(huán)函數(shù)WndProc:
      WndProc消息循環(huán)中,只處理4中消息:對話框初始化、對話框控件、服務(wù)器SOCKET異步和客戶端SOCKET異步,在對話框初始化中,程序啟動了SOCKET棧。在對話框控件中,程序分別響應(yīng)了各種按鈕消息以及文字輸入框消息EN_UPDATE。在服務(wù)器SOCKET異步消息中,調(diào)用OnServerMessage處理。在客戶端SOCKET異步消息中,調(diào)用了OnclientMessage處理。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND subWnd;
    
char buffer[BUFFER_SIZE];
    UINT port;
    
char serverIP[16];
    
switch (message)
    
{
    
case WM_INITDIALOG:
        
{
            WSADATA wsaData;
            
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
            
{
                MessageBox(hWnd,
"Socket Stack Error!","Error",IDOK);
                
return -1;
            }

        }

        
return TRUE;
    
case WM_COMMAND:
        
{
            
switch(LOWORD(wParam))
            
{
            
case IDOK:
            
case IDCANCEL:
                EndDialog(hWnd,LOWORD(wParam));
                
break;
            
case IDC_CONNECT:
                
{
                    subWnd
=GetDlgItem(hWnd,IDC_LISTEN_PORT_C);
                    GetWindowText(subWnd,buffer, BUFFER_SIZE);
                    port
= UINT(atoi(buffer));
                    subWnd
=GetDlgItem(hWnd,IDC_SERVERIP);
                    GetWindowText(subWnd,buffer,BUFFER_SIZE);
                    strncpy(serverIP,buffer,
16);
                    ClientInit(hWnd,port,serverIP);
                    
//g_ChatWords="";
                }

                
break;
            
case IDC_LISTEN:
                
{
                    subWnd
=GetDlgItem(hWnd,IDC_LISTEN_PORT_S);
                    GetWindowText(subWnd,buffer, BUFFER_SIZE);
                    port
= UINT(atoi(buffer));
                    ServerInit(hWnd,port);
                    
//g_ChatWords="";
                }

                
break;
            
case IDC_INPUTTEXT:
                
{
                    
if(HIWORD(wParam)==EN_UPDATE)
                    
{
                        SendMessageToPeer(hWnd);
                    }

                }

            
default:
                
break;
            }

        }

        
break;
    
case SERVER_MESSAGE:
        
{
            OnServerMessage(hWnd,wParam, lParam);
        }

        
break;
    
case CLIENT_MESSAGE:
        
{
            OnClientMessage(hWnd, wParam, lParam);
        }

        
break;
    }

    
return 0;
}

1)int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
      
wVersionRequested:表示欲使用的Windows Sockets API版本,使用宏MAKEWORDXY)設(shè)置參數(shù)。表示版本為X.Y(本例中為2.2)
4、客戶端初始化函數(shù)ClientInit:

   當(dāng)單擊“連接服務(wù)器“按鈕時,程序分別從子窗口IDC_LISTEN_POST_CIDC_SERVERIP中提取服務(wù)器的IP和監(jiān)聽端口,然后調(diào)用客戶端函數(shù)ClientInit

BOOL ClientInit(HWND hWnd,UINT port,const char* serverIP)
{
    sockaddr_in addr;
    ExitChat(hWnd);
    g_bClient
=TRUE;
    
if(inet_addr(serverIP)==INADDR_NONE)
    
{
        MessageBox(hWnd,
"Invalid IP Address!","Warnning",IDOK);
        
return FALSE;
    }


    
//create tcp/stream data socket
    g_ClientSocket = socket(AF_INET, SOCK_STREAM,0);
    assert(g_ClientSocket 
!= INVALID_SOCKET);

    
//set the socket as async selection tag, the related message is CLIENT_MESSAGE
    
//the async events contain: read, write, close, connect
    WSAAsyncSelect(g_ClientSocket,hWnd,CLIENT_MESSAGE,FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT);

    
//set the server address and port
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr 
= inet_addr(serverIP);
    addr.sin_port 
= htons(port);   //short from host to network format
    
    
//connect to server
    connect(g_ClientSocket, (sockaddr*)&addr, sizeof(addr));

    g_ChatWords
+="Connecting\r\n";
    RefreshScreen(hWnd);
    
return TRUE;
}

1SOCKET socket(int af,int type,int protocol);

       af:指協(xié)議的地址族,如果想建立一個UDPTCP的套接字,則該值設(shè)置成AF_INET,表示在網(wǎng)絡(luò)層采用網(wǎng)際協(xié)議(IP

       type:協(xié)議的套接字類型,可以是SOCK_STREAMSOCK_DGRAM SOCK_RAWSOCK_RDMSOCK_SEQPACKET 當(dāng)采用流連接方式時用SOCK_STREAM,采用數(shù)據(jù)報文方式用SOCK_DGRAM

       proctocol:協(xié)議字段,當(dāng)aftype都指定之后,該值的取值范圍就被去定了,默認(rèn)值為0

2int PASCAL FAR WSAAsyncSelect ( SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent );

S:標(biāo)識一個需要事件通知的套接口的描述符.

hWnd:標(biāo)識一個在網(wǎng)絡(luò)事件發(fā)生時需要接收消息的窗口句柄.

wMsg :在網(wǎng)絡(luò)事件發(fā)生時要接收的消息.

lEvent:位屏蔽碼,用于指明應(yīng)用程序感興趣的網(wǎng)絡(luò)事件集合.

3int connect(SOCKET s,const struct sockaddr FAR * name,int namelen);

       S是建立好的套接字,name指向描述通信對象地址信息的結(jié)構(gòu)體的指針,namelen是該結(jié)構(gòu)體的長度。

4struct sockaddr_in {short sin_family;u_short sin_port;struct in_addr sin_addr;char    sin_zero[8];};

5unsigned long PASCAL FAR inet_addr( const struct FAR* cp);

  cp:一個以Internet標(biāo)準(zhǔn)“.”間隔的字符串。

本函數(shù)解釋cp參數(shù)中的字符串,這個字符串用Internet“.”間隔格式表示一個數(shù)字的Internet地址。

6u_short PASCAL FAR htons( u_short hostshort);

  hostshort:主機字節(jié)順序表達的16位數(shù)。

  本函數(shù)將一個16位數(shù)從主機字節(jié)順序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序。

       其中sin_family是指地址族;sin_port是制定的端口號;sin_addr是制定的IP地址;sin_zero冗余字段,使sockaddr_in結(jié)構(gòu)和SOCKADDR結(jié)構(gòu)大小相同
5、服務(wù)器初始化函數(shù)ServerInit:
   單擊“建立服務(wù)器“按鈕時,程序從子窗口IDC_LISTEN_PORT_S中提取監(jiān)聽端口,然后調(diào)用服務(wù)器初始化函數(shù)ServerInit

BOOL ServerInit(HWND hWnd,UINT port)
{
    sockaddr_in addr;
    
char buffer[BUFFER_SIZE];
    ExitChat(hWnd);
    g_bClient
=FALSE;
    
    
//create a tcp/stream based socket
    g_ListenSocket = socket(AF_INET, SOCK_STREAM,0);
    assert(g_ListenSocket 
!= INVALID_SOCKET);

    
//set the socket as async selection tag, the related message is SERVER_MESSAGE
    
//the async events contain: accept, read, write, close
    WSAAsyncSelect(g_ListenSocket, hWnd, SERVER_MESSAGE, FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE);

    addr.sin_family 
= AF_INET;  //IP layer takes IP router protocol
    addr.sin_addr.S_un.S_addr = INADDR_ANY;    
    addr.sin_port 
= htons(port);//port from short of host to short of network

    
//binding listening socket
    if(bind(g_ListenSocket, (sockaddr*)&addr, sizeof(sockaddr)) == SOCKET_ERROR)
    
{
        sprintf(buffer,
"Port %d has been taken. Change another port.\r\n",port);
        g_ChatWords
+=buffer;
        RefreshScreen(hWnd);
        MessageBox(hWnd,
"Binding Error","Warnning",IDOK);
        
return FALSE;
    }

    
    
//listening
    if(listen(g_ListenSocket, 5== SOCKET_ERROR)
    
{
        strcpy(buffer,
"Listen error.\r\n");
        g_ChatWords
+=buffer;
        RefreshScreen(hWnd);
        MessageBox(hWnd,
"Listen Error.","Warnning",IDOK);
        
return FALSE;
    }


    g_ChatWords
+="Server is listening\r\n";
    RefreshScreen(hWnd);
    g_bActive
=TRUE;
    
return TRUE;
}

1)  int bind(SOCKET s,const struct sockaddr FAR * name,int namelen);

S是建立好的套接字,name指向描述通信對象地址信息的結(jié)構(gòu)體的指針,namelen是該結(jié)構(gòu)體的長度。

2)int listen(SOCKET s,int backlog);

S是建立好的套接字,backlog是并發(fā)連接等待隊列的長度。

6、SendMessageToPeer函數(shù):
   當(dāng)用戶在文本框中輸入文字時,程序會接收到該文本框的
EN_UPDATE消息,函數(shù)SendMessageToPeer負(fù)責(zé)處理該消息。在SendMessageToPeer中,一旦檢測到用戶按下了回車鍵,程序就將文本內(nèi)容刷新到上面的顯示框中,如果當(dāng)前在線,文本內(nèi)容還將發(fā)送到會話的另一端。

void SendMessageToPeer(HWND hWnd)
{
    HWND subwnd;
    
char buffer[BUFFER_SIZE];
    
int i;
    
static int oldNumOfChars=0;

    subwnd
=GetDlgItem(hWnd,IDC_INPUTTEXT);
    GetWindowText(subwnd,buffer,BUFFER_SIZE
-2);
    
if(oldNumOfChars!=strlen(buffer))
    
{
        oldNumOfChars
=strlen(buffer);
        
return;
    }

    
//CString s;
    
//s("%d還是%d",oldNumOfChars,strlen(buffer));
//    g_ChatWords+=s;
    
//empty content of input edit box
    SetWindowText(subwnd,"");
    oldNumOfChars
=0;
    
if(!g_bActive)
    
{
        g_ChatWords
+=buffer;
        g_ChatWords.erase(g_ChatWords.size(),
1);
        g_ChatWords
+="(Hint: you are isolated now.)\r\n";
        RefreshScreen(hWnd);
        
return;
    }

    strcat(buffer,
"\r\n");
    g_ChatWords
+=buffer;
    RefreshScreen(hWnd);
    
if(g_bClient)
    
{
        Send(g_ClientSocket, buffer, strlen(buffer));
    }

    
else
    
{
        
for(i=0;i<g_DataSockets.size();i++)
            Send(g_DataSockets[i],buffer,strlen(buffer));
    }

}

void Send(SOCKET sock, const char* buffer, int length)
{
    
int ret,i;
    i
=0;
    
while(length>0)
    
{
        ret
=send(sock,&(buffer[i]),length,0);
        
if(ret==0)
            
break;
        
else if(ret == SOCKET_ERROR)
        
{
            g_ChatWords
+="Error sending.\r\n";
            
break;
        }

        length
-=ret;
        i
+=ret;
    }

}

1)int send(SOCKET s,const char FAR * buf,int len,int flags);
參數(shù)s是建立連接的套接字。buflen是發(fā)送的數(shù)據(jù)包及其長度。flags一般取0,還有MSG_DONTROUTE要求套接字傳輸?shù)臄?shù)據(jù)不要路由,如果傳輸協(xié)議不支持該選項,則這個要求被忽略。MSG_OOB表示套接字此時傳輸?shù)臄?shù)據(jù)室外帶數(shù)據(jù),需要緊急處理。

7、OnClientMessage函數(shù):

在主循環(huán)的消息循環(huán)中,OnClientMessage函數(shù)用來處理客戶端SOCKET的一部消息CLIENT_MESSAGE。需要指出的是:當(dāng)某個網(wǎng)絡(luò)消息到達窗口時,可能暗含著套接字上發(fā)生了某種網(wǎng)絡(luò)錯誤。此時,應(yīng)該先判斷套接字上是否發(fā)生了錯誤,如果有錯誤發(fā)生就直接關(guān)閉套接字然后返回,只有在沒有錯誤發(fā)生的情況下,才需要處理具體的網(wǎng)絡(luò)消息。在實現(xiàn)上,需要利用消息參數(shù)lParam的高字節(jié),宏WSAGETSELECTERROR可以檢測錯誤。而具體的消息類型是存儲在lParam的低字節(jié),宏WSAGETSELECTEVENT用來獲取該低字節(jié)值。

int OnClientMessage(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    
char buffer[BUFFER_SIZE+1];
    
int retCode;
    sockaddr_in name;
    
int namelen=sizeof(sockaddr_in);

    
if(WSAGETSELECTERROR(lParam))
    
{
        closesocket(g_ClientSocket);
        strcpy(buffer,
"Server has no response.\r\n");
        g_ChatWords
+=buffer;
        RefreshScreen(hWnd);
        g_bActive
=FALSE;
        
return 0;
    }


    
switch(WSAGETSELECTEVENT(lParam))
    
{
        
case FD_CONNECT:
            getpeername(g_ClientSocket,(sockaddr
*)&name,&namelen);
            sprintf(buffer,
"Successfully connected to %s:%d.\r\n",inet_ntoa(name.sin_addr),ntohs(name.sin_port));
            g_ChatWords
+=buffer;
            RefreshScreen(hWnd);
            g_bActive
=TRUE;
            
break;
        
case FD_READ:
            retCode
=recv(g_ClientSocket,buffer,BUFFER_SIZE,0);
            
if(retCode!=SOCKET_ERROR)
            
{
                buffer[retCode]
=NULL;
                g_ChatWords
+=buffer;
            }

            
else
                GetErrorReason();
            RefreshScreen(hWnd);
            
break;
        
case FD_WRITE:
            
break;
        
case FD_CLOSE:
            closesocket(g_ClientSocket);
            strcpy(buffer,
"Server close session.Successfully log out.\r\n");
            g_ChatWords
+=buffer;
            RefreshScreen(hWnd);
            g_bActive
=FALSE;
            
break;
    }

    
return 0;
}

1char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
      in:一個表示Internet主機地址的結(jié)構(gòu)。
   
本函數(shù)將一個用in參數(shù)所表示的Internet地址結(jié)構(gòu)轉(zhuǎn)換成以“.” 間隔的諸如“a.b.c.d”的字符串形式。

2) int recv(SOCKET s,char FAR * buf,int len,int flags);
參數(shù)與send一致

3)int closesocket(SOCKET s);
關(guān)閉套接字

8、OnServerMessage函數(shù):

在主程序的消息循環(huán)中,OnServerMessage函數(shù)用來處理客戶端SOCKET的一部消息SERVER_MESSAGE。在服務(wù)器初始化函數(shù)中的g_ListenSocket被設(shè)置成異步監(jiān)聽socket,所有被g_ListenSocket接收的數(shù)據(jù)socket將同時被設(shè)置成異步socket,并共享同一個消息SERVER_MESSAGE。及時服務(wù)器關(guān)閉了監(jiān)聽socket,會話socket的連接依然有效,除非服務(wù)器同時也將會話socket關(guān)閉。

int OnServerMessage(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    SOCKET socket;
    
int i,retCode,namelen;
    
char buffer[BUFFER_SIZE+1];
    std::vector
<SOCKET>::iterator ite;
    sockaddr_in name;
    namelen
=sizeof(name);

    
if(WSAGETSELECTERROR(lParam))
    
{
        getpeername((SOCKET)wParam,(sockaddr
*)&name,&namelen);
        closesocket((SOCKET)wParam);
        
//erase the client socket from client socks list
        ite=std::find(g_DataSockets.begin(), g_DataSockets.end(),(SOCKET)wParam);
        assert(ite
!=g_DataSockets.end());
        g_DataSockets.erase(ite);
        
//refresh screen
        sprintf(buffer, "Client %s:%d lost contact with us.\r\n", inet_ntoa(name.sin_addr),ntohs(name.sin_port));
        
for(i=0; i<g_DataSockets.size(); i++)
            Send(g_DataSockets[i],buffer,strlen(buffer));
        g_ChatWords
+=buffer;
        RefreshScreen(hWnd);
        
return 0;
    }


    
switch(WSAGETSELECTEVENT(lParam))
    
{
        
case FD_ACCEPT:
            
//accept the client request
            socket= accept(g_ListenSocket,NULL,NULL);
            
//in fact we can get the peer when calling accept, here we use getpeername instead
            getpeername(socket,(sockaddr*)&name,&namelen);
            
//send a message of logining to other clients
            sprintf(buffer,"A guest joins us.(%s:%d)\r\n",inet_ntoa(name.sin_addr),ntohs(name.sin_port));
            g_ChatWords
+=buffer;
            
for(i=0;i<g_DataSockets.size();i++)
                Send(g_DataSockets[i],buffer,strlen(buffer));
            
//send a welcome message to current client
            sprintf(buffer, "Welcome !(You ID is: %s:%d.)\r\n",inet_ntoa(name.sin_addr),ntohs(name.sin_port));
            
//send(socket,buffer,strlen(buffer),0);
            Send(socket,buffer,strlen(buffer));
            
//refresh srceen text
            RefreshScreen(hWnd);
            
//push the client socket down to the client sockets list
            g_DataSockets.push_back(socket);
            
break;
        
case FD_READ:
            
{
                
//get the client message, the client socket ID is wParam
                retCode=recv((SOCKET)wParam,buffer,BUFFER_SIZE,0);
                buffer[retCode]
=NULL;
                
//send the received message to other clients
                for(i=0;i<g_DataSockets.size();i++)
                
{
                    
if(wParam!=g_DataSockets[i])
                        Send(g_DataSockets[i],buffer,strlen(buffer));
                }

                g_ChatWords
+=buffer;
                
//refresh screen
                RefreshScreen(hWnd);
            }

            
break;
        
case FD_WRITE:
            
return 0;
        
case FD_CLOSE: //Client gracefully close the socket
            
//close the client socket who has left, the client socket ID is wParam
            getpeername((SOCKET)wParam,(sockaddr*)&name,&namelen);
            closesocket((SOCKET)wParam);
            
//erase the client socket from client socks list
            ite=std::find(g_DataSockets.begin(), g_DataSockets.end(),(SOCKET)wParam);
            assert(ite
!=g_DataSockets.end());
            g_DataSockets.erase(ite);
            
//refresh screen
            sprintf(buffer, "Client %s:%d left.\r\n", inet_ntoa(name.sin_addr),ntohs(name.sin_port));
            
for(i=0; i<g_DataSockets.size(); i++)
                Send(g_DataSockets[i],buffer,strlen(buffer));
            g_ChatWords
+=buffer;
            RefreshScreen(hWnd);
            
break;
    }

    
return 0;
}

1int PASCAL FAR getpeername( SOCKET s, struct sockaddr FAR* name,int FAR* namelen);

  s:標(biāo)識一已連接套接口的描述字。

  name:接收端地址的名字結(jié)構(gòu)。

namelen:一個指向名字結(jié)構(gòu)的指針。

2u_short PASCAL FAR ntohs( u_short netshort);

netshort:一個以網(wǎng)絡(luò)字節(jié)順序表達的16位數(shù)。

本函數(shù)將一個16位數(shù)由網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機字節(jié)順序。

3) SOCKET accept(SOCKET s,struct sockaddr FAR * addr,int FAR * addrlen);

如果是服務(wù)器并不關(guān)心對方的地址,則可將accept函數(shù)中后兩個參數(shù)設(shè)置為NULL

9、最后,介紹3個輔助函數(shù):ExitChat、GetErrorReason和RefreshScreen
      當(dāng)新建服務(wù)器或鏈接服務(wù)器的時候,首先需要將上一次會話關(guān)閉,ExitChat函數(shù)完成此功能。
      RefreshScreen函數(shù)負(fù)責(zé)刷新顯示內(nèi)容并滾動顯示文本框。
      GetErrorReason函數(shù)負(fù)責(zé)獲得當(dāng)前操作中的具體錯誤原因。
void ExitChat(HWND hWnd)
{
    
int i;
    
char buffer[BUFFER_SIZE];
    
if(g_bActive)
    
{
        
if(g_bClient)
        
{
            closesocket(g_ClientSocket);
            strcpy(buffer,
"Successfully log out.\r\n");
            g_ChatWords
+=buffer;
            RefreshScreen(hWnd);
        }

        
else
        
{
            strcpy(buffer,
"I will leave. Pls clients log out ASAP.\r\n");
            
for(i=0; i<g_DataSockets.size(); i++)
            
{
                Send(g_DataSockets[i],buffer,strlen(buffer));
                closesocket(g_DataSockets[i]);
            }

            g_DataSockets.clear();
            
            closesocket(g_ListenSocket);
            strcpy(buffer,
"Successfully close server.\r\n");
            g_ChatWords
+=buffer;
            RefreshScreen(hWnd);
        }

    }

    g_bActive
=FALSE;
}


void GetErrorReason()
{
    LPVOID lpMsgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,WSAGetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) 
&lpMsgBuf,0,NULL);
    g_ChatWords
+=(char *)lpMsgBuf;
    LocalFree( lpMsgBuf );
}

void RefreshScreen(HWND hWnd)
{
    HWND subWnd;
    std::
string::size_type pos;
    
int n;
    subWnd
=GetDlgItem(hWnd,IDC_SHOWTEXT);
    SetWindowText(subWnd, g_ChatWords.c_str());
    n
=0;
    pos
=0;
    
while((pos=g_ChatWords.find('\n',pos))!=std::string::npos)
    
{
        pos
++;
        n
++;
    }

    SendMessage(subWnd, EM_LINESCROLL, 
0, n);
}

posted on 2009-06-21 00:23 The_Moment 閱讀(1946) 評論(0)  編輯 收藏 引用 所屬分類: VC理論
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品日日摸夜夜摸av| 欧美成人亚洲| 在线看一区二区| 国产一区二区高清不卡| 国产精品揄拍500视频| 国产精品一二三四| 国产一区二区三区四区老人| 国产一区亚洲| 亚洲电影免费在线观看| 亚洲精品一区二区三区四区高清| 亚洲精品小视频| 亚洲永久免费精品| 久久久99国产精品免费| 欧美韩国日本一区| 亚洲伦伦在线| 欧美一区二区视频在线观看2020 | 毛片基地黄久久久久久天堂| 蜜桃av一区二区三区| 欧美日韩免费观看中文| 国产老女人精品毛片久久| 在线观看日韩av| 亚洲每日更新| 久久男人av资源网站| 亚洲日本成人| 亚洲欧美日韩在线一区| 麻豆精品精华液| 国产精品视区| 亚洲美女中出| 久久综合福利| 中文欧美日韩| 欧美精品一区在线| 在线观看欧美视频| 久久成人一区| 一区二区三区国产盗摄| 美女图片一区二区| 国产伦理一区| 亚洲网友自拍| 亚洲人成精品久久久久| 亚洲欧美日韩一区在线| 免费观看成人www动漫视频| 最近中文字幕日韩精品| 久久精品国产亚洲精品| 国产精品国产自产拍高清av| 亚洲精品女av网站| 老司机午夜精品视频| 亚洲影视九九影院在线观看| 欧美理论在线| 99精品国产在热久久下载| 免费人成网站在线观看欧美高清| 亚洲永久网站| 欧美性做爰毛片| 一区二区三区高清视频在线观看| 欧美国产在线观看| 巨乳诱惑日韩免费av| 韩国亚洲精品| 久久久久免费观看| 午夜欧美视频| 国产在线视频欧美| 久久久水蜜桃| 久久成人精品视频| 揄拍成人国产精品视频| 老司机午夜精品视频| 久久人人爽人人爽爽久久| 精品成人a区在线观看| 另类激情亚洲| 久久综合网色—综合色88| 亚洲国产精品成人精品| 欧美成人午夜剧场免费观看| 欧美大片va欧美在线播放| 亚洲日本va午夜在线电影| 欧美国内亚洲| 欧美日韩国产片| 亚洲尤物在线视频观看| 亚洲一区二区在线播放| 国产午夜精品久久久| 久久天天躁狠狠躁夜夜av| 久久久噜噜噜久久中文字幕色伊伊 | 国产精品国产三级国产普通话99| 亚洲一区三区视频在线观看| 亚洲午夜一二三区视频| 国产亚洲在线| 欧美激情视频给我| 欧美视频在线免费看| 欧美尤物一区| 另类图片综合电影| 亚洲在线视频一区| 欧美一级久久| 亚洲日本在线观看| 亚洲一区二区三区高清 | 亚洲精品久久久久中文字幕欢迎你 | 亚洲九九精品| 日韩视频中文| 六月婷婷久久| 亚洲深夜影院| 黑丝一区二区| 亚洲欧洲日夜超级视频| 国产精品主播| 亚洲人永久免费| 国产综合久久久久影院| 亚洲激情在线| 国内精品国产成人| 99成人在线| 亚洲大胆美女视频| 亚洲午夜免费福利视频| 一区在线观看| 亚洲综合大片69999| 尤物yw午夜国产精品视频| 亚洲最新色图| 亚洲国产精品久久人人爱蜜臀 | 久热成人在线视频| 新狼窝色av性久久久久久| 免费日韩成人| 久久久青草婷婷精品综合日韩| 欧美屁股在线| 亚洲第一色中文字幕| 国产一区二区三区最好精华液| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲深夜福利视频| 亚洲免费成人av| 久久午夜羞羞影院免费观看| 性久久久久久久| 欧美午夜精品久久久久免费视 | 久久精品欧美日韩| 欧美一区二区三区另类 | 国产精品一区二区三区四区五区| 亚洲国产另类精品专区| 激情综合色丁香一区二区| 亚洲欧美国产另类| 性欧美video另类hd性玩具| 欧美日韩国产不卡在线看| 亚洲成色999久久网站| 一区二区在线免费观看| 欧美在线不卡视频| 久久精品人人爽| 国产欧美日韩一级| 午夜精品一区二区三区在线| 欧美一区二区三区男人的天堂 | 亚洲欧美日韩国产综合在线 | 国产精品私房写真福利视频 | 亚洲成色精品| 亚洲区一区二| 欧美精品久久一区| 国产一区二区0| 亚洲精品乱码久久久久| 激情视频一区| 久久色在线观看| 欧美成人精品高清在线播放| 亚洲国产欧洲综合997久久| 久久一本综合频道| 亚洲国产成人91精品| 日韩视频三区| 欧美私人啪啪vps| 亚洲欧美亚洲| 久久一区二区三区四区| 亚洲高清一区二| 欧美另类一区| 亚洲一区二区三区精品视频| 久久精品一区四区| 亚洲黄色免费电影| 欧美日韩一区二区视频在线 | 欧美日韩精品免费观看视一区二区| 99国内精品| 久久久久久高潮国产精品视| 在线日韩av永久免费观看| 欧美国产免费| 亚洲综合电影一区二区三区| 久久久久9999亚洲精品| 亚洲日本久久| 国产精品稀缺呦系列在线| 久久精品视频免费| 亚洲精品社区| 久久久综合香蕉尹人综合网| 亚洲精品久久| 国产色婷婷国产综合在线理论片a| 久久久久国产一区二区三区| 亚洲国内在线| 久久九九精品99国产精品| 亚洲靠逼com| 国产一区成人| 欧美天堂亚洲电影院在线播放| 久久狠狠亚洲综合| 亚洲最新色图| 亚洲国产福利在线| 久久久欧美一区二区| 亚洲一区二区三区在线视频| 在线观看三级视频欧美| 国产精品日产欧美久久久久| 欧美国产日本在线| 久久久91精品国产一区二区精品| 一本色道久久99精品综合| 久热精品视频在线观看| 亚洲自拍偷拍麻豆| 亚洲免费高清视频| 伊人成人开心激情综合网| 国产精品嫩草99a| 欧美日本国产一区| 老牛影视一区二区三区| 久久国产精品久久久久久| 一区二区三区四区五区精品视频| 欧美华人在线视频|