下载链接

应用下载

源代码下载

源代码:

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define PORT 60001
#define BUF_MAX 1024
#define MAX_USER 15

#define ID_BTN_SETTING 1001
#define ID_CHAT_BOX    1002
#define ID_EDIT_SEND   1003
#define ID_BTN_SENDMSG 1004

#define ID_RAD_MASTER  2001
#define ID_RAD_MEMBER  2002
#define ID_EDIT_NICK   2003
#define ID_EDIT_CODE   2004
#define ID_LIST_USER   2005
#define ID_BTN_START   2006

HWND g_hMainWnd,g_hChat,g_hInput,g_hSendBtn;
HWND g_hSetWnd=NULL;
HWND g_hNickEd,g_hCodeEd,g_hUserList;

SOCKET g_sock=INVALID_SOCKET;
BOOL g_isMaster=FALSE;
BOOL g_chatRun=FALSE;
char g_groupKey[10]={0};
char g_myName[32]="游客";
char g_ipArr[MAX_USER][32];
int g_ipCnt=0;

void GetTimeStr(char *t)
{
    time_t now=time(NULL);
    struct tm *p=localtime(&now);
    sprintf(t,"%02d:%02d:%02d",p->tm_hour,p->tm_min,p->tm_sec);
}

void SendAllMsg(char *msg)
{
    for(int i=0;i<g_ipCnt;i++)
    {
        sockaddr_in dest;
        memset(&dest,0,sizeof(dest));
        dest.sin_family=AF_INET;
        dest.sin_port=htons(PORT);
        dest.sin_addr.s_addr=inet_addr(g_ipArr[i]);
        sendto(g_sock,msg,strlen(msg),0,(sockaddr*)&dest,sizeof(dest));
    }
}

DWORD WINAPI RecvProc(LPVOID h)
{
    char buf[BUF_MAX];
    sockaddr_in from;
    int len=sizeof(from);
    while(g_chatRun)
    {
        memset(buf,0,BUF_MAX);
        int ret=recvfrom(g_sock,buf,BUF_MAX-1,0,(sockaddr*)&from,&len);
        if(ret>0)
        {
            SendMessage(g_hChat,LB_ADDSTRING,0,(LPARAM)buf);
            SendMessage(g_hChat,LB_SETCURSEL,(WPARAM)SendMessage(g_hChat,LB_GETCOUNT,0,0)-1,0);
        }
        Sleep(50);
    }
    return 0;
}

BOOL CheckKey(char *in)
{
    return strcmp(in,g_groupKey)==0;
}

LRESULT CALLBACK SetWndProc(HWND h,UINT m,WPARAM w,LPARAM l)
{
    switch(m)
    {
        case WM_CREATE:
        {
            CreateWindow("STATIC","身份选择",WS_CHILD|WS_VISIBLE,25,20,80,25,h,0,0,0);
            CreateWindow("BUTTON","群主建群",WS_CHILD|WS_VISIBLE|WS_GROUP,25,50,90,25,h,(HMENU)ID_RAD_MASTER,0,0);
            CreateWindow("BUTTON","成员入群",WS_CHILD|WS_VISIBLE,130,50,90,25,h,(HMENU)ID_RAD_MEMBER,0,0);

            CreateWindow("STATIC","我的昵称",WS_CHILD|WS_VISIBLE,25,85,70,25,h,0,0,0);
            g_hNickEd=CreateWindow("EDIT","",WS_CHILD|WS_VISIBLE|WS_BORDER,25,115,180,25,h,(HMENU)ID_EDIT_NICK,0,0);

            CreateWindow("STATIC","6位邀请码",WS_CHILD|WS_VISIBLE,25,150,80,25,h,0,0,0);
            g_hCodeEd=CreateWindow("EDIT","",WS_CHILD|WS_VISIBLE|WS_BORDER,25,180,180,25,h,(HMENU)ID_EDIT_CODE,0,0);

            CreateWindow("STATIC","在线成员",WS_CHILD|WS_VISIBLE,25,215,70,25,h,0,0,0);
            g_hUserList=CreateWindow("LISTBOX","",WS_CHILD|WS_VISIBLE|WS_BORDER,25,245,180,120,h,(HMENU)ID_LIST_USER,0,0);

            CreateWindow("BUTTON","开启/加入群聊",WS_CHILD|WS_VISIBLE,25,380,180,35,h,(HMENU)ID_BTN_START,0,0);
            break;
        }
        case WM_COMMAND:
        {
            int id=LOWORD(w);
            if(id==ID_RAD_MASTER) g_isMaster=TRUE;
            if(id==ID_RAD_MEMBER) g_isMaster=FALSE;

            if(id==ID_BTN_START)
            {
                char name[32],key[10];
                GetWindowText(g_hNickEd,name,30);
                GetWindowText(g_hCodeEd,key,8);
                if(strlen(name)<2)
                {
                    MessageBox(h,"请输入昵称","提示",MB_OK);
                    break;
                }
                strcpy(g_myName,name);

                if(g_isMaster)
                {
                    if(strlen(key)!=6)
                    {
                        MessageBox(h,"群主必须设置6位数字邀请码","错误",MB_OK);
                        break;
                    }
                    strcpy(g_groupKey,key);
                    g_chatRun=TRUE;
                    CreateThread(NULL,0,RecvProc,0,0,NULL);
                    SendMessage(g_hChat,LB_ADDSTRING,0,(LPARAM)"【系统】群主已创建群聊,等待成员加入");
                }
                else
                {
                    if(strlen(key)!=6||!CheckKey(key))
                    {
                        MessageBox(h,"邀请码错误,无法加入","失败",MB_OK);
                        break;
                    }
                    g_chatRun=TRUE;
                    CreateThread(NULL,0,RecvProc,0,0,NULL);
                    SendMessage(g_hChat,LB_ADDSTRING,0,(LPARAM)"【系统】成功加入群组聊天室");
                }
                ShowWindow(h,SW_HIDE);
            }
            break;
        }
        case WM_CLOSE:
            ShowWindow(h,SW_HIDE);
            return 0;
    }
    return DefWindowProc(h,m,w,l);
}

LRESULT CALLBACK MainWndProc(HWND h,UINT m,WPARAM w,LPARAM l)
{
    switch(m)
    {
        case WM_CREATE:
        {
            WSADATA wsa;
            WSAStartup(MAKEWORD(2,2),&wsa);
            g_sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
            sockaddr_in bindAddr;
            bindAddr.sin_family=AF_INET;
            bindAddr.sin_port=htons(PORT);
            bindAddr.sin_addr.s_addr=INADDR_ANY;
            bind(g_sock,(sockaddr*)&bindAddr,sizeof(bindAddr));

            CreateWindow("BUTTON","设置",WS_CHILD|WS_VISIBLE,10,10,60,28,h,(HMENU)ID_BTN_SETTING,0,0);

            g_hChat=CreateWindow("LISTBOX","",WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,
                10,45,560,380,h,(HMENU)ID_CHAT_BOX,0,0);

            g_hInput=CreateWindow("EDIT","",WS_CHILD|WS_VISIBLE|WS_BORDER,
                10,435,490,28,h,(HMENU)ID_EDIT_SEND,0,0);

            g_hSendBtn=CreateWindow("BUTTON","发送",WS_CHILD|WS_VISIBLE,
                505,435,65,28,h,(HMENU)ID_BTN_SENDMSG,0,0);
            break;
        }
        case WM_COMMAND:
        {
            int id=LOWORD(w);
            if(id==ID_BTN_SETTING)
            {
                if(!g_hSetWnd)
                {
                    WNDCLASS sc={0};
                    sc.lpszClassName="SetWinClass";
                    sc.lpfnWndProc=SetWndProc;
                    sc.hInstance=GetModuleHandle(NULL);
                    RegisterClass(&sc);
                    g_hSetWnd=CreateWindow("SetWinClass","群组设置",
                        WS_CAPTION|WS_SYSMENU,300,200,240,450,
                        g_hMainWnd,NULL,GetModuleHandle(NULL),NULL);
                }
                ShowWindow(g_hSetWnd,SW_SHOW);
                SetForegroundWindow(g_hSetWnd);
            }
            if(id==ID_BTN_SENDMSG&&g_chatRun)
            {
                char msg[BUF_MAX],sendTxt[BUF_MAX],t[20];
                GetWindowText(g_hInput,msg,512);
                if(!strlen(msg))break;
                GetTimeStr(t);
                sprintf(sendTxt,"[%s]%s:%s",t,g_myName,msg);
                SendAllMsg(sendTxt);
                SendMessage(g_hChat,LB_ADDSTRING,0,(LPARAM)sendTxt);
                SendMessage(g_hChat,LB_SETCURSEL,(WPARAM)SendMessage(g_hChat,LB_GETCOUNT,0,0)-1,0);
                SetWindowText(g_hInput,"");
            }
            break;
        }
        case WM_SYSCOMMAND:
            if((w & 0xFFF0) == SC_SIZE) return 0;
            break;
        case WM_DESTROY:
        {
            g_chatRun=FALSE;
            Sleep(100);
            closesocket(g_sock);
            WSACleanup();
            PostQuitMessage(0);
            break;
        }
    }
    return DefWindowProc(h,m,w,l);
}

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPre,LPSTR cmd,int show)
{
    WNDCLASS wc={0};
    wc.lpszClassName="ChatMainClass";
    wc.lpfnWndProc=MainWndProc;
    wc.hInstance=hInst;
    wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
    RegisterClass(&wc);

    g_hMainWnd=CreateWindow("ChatMainClass","邀请码群组聊天室",
        WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,
        100,80,580,500,NULL,NULL,hInst,NULL);

    ShowWindow(g_hMainWnd,show);
    UpdateWindow(g_hMainWnd);

    MSG msg;
    while(GetMessage(&msg,NULL,0,0)>0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}