Code:
// Lithnet Chat
// Version 0.1s
// By: Steven Merrick
#include <windows.h>
#include <iostream>
// Window dialog definations
#define ID_FILE_LISTEN 1
#define ID_FILE_SLISTEN 2
#define ID_FILE_EXIT 3
#define ID_ABOUT_HELP 10
#define IDC_EDITI 101
#define IDC_EDITO 102
#define IDC_BTNS 103
#define SOCKET_READY WM_USER+1
// Functions
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
// Variables
const char g_szClassName[] = "myWindowClass";
WNDCLASSEX wc;
HMENU hMenu, hSubMenu;
HWND hWnd, hEditIn, hEditOut, hBtnSend;
SOCKET sListen, sClient; // Create listening socket.
RECT rcClient;
MSG Msg;
// Code
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return(0);
}
hWnd = CreateWindowEx(NULL, g_szClassName, "Lithnet Chat - Server", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 600, NULL, NULL, hInstance, NULL);
if(hWnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return(0);
}
/* Winsock Setup */
WSADATA wsaData; // Windows Socket Data.
if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0)
{
MessageBox(NULL, "Error in initializing Winsock", "Error!", NULL);
WSACleanup();
}
SOCKADDR_IN sInfo;
sInfo.sin_family = AF_INET; // Internet.
sInfo.sin_addr.s_addr = INADDR_ANY; // Any incoming address.
sInfo.sin_port = htons(10000); // Port 10000.
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Create an Internet Steam TCP Socket.
if (sListen == INVALID_SOCKET)
{
MessageBox(NULL, "Error in creating socket", "Error!", NULL);
WSACleanup();
}
if (bind(sListen, (LPSOCKADDR)&sInfo, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
MessageBox(NULL, "Error in binding socket", "Error!", NULL);
WSACleanup();
}
/* End Winsock Setup */
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
WSAAsyncSelect(sListen, hWnd, SOCKET_READY, FD_ACCEPT | FD_READ | FD_WRITE | FD_CLOSE);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_LISTEN, "&Listen");
AppendMenu(hSubMenu, MF_STRING, ID_FILE_SLISTEN, "&Stop Listening");
AppendMenu(hSubMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_ABOUT_HELP, "&About");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help");
SetMenu(hWnd, hMenu);
hEditIn = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 294, 500, hWnd, (HMENU)IDC_EDITI, GetModuleHandle(NULL), NULL);
if(hEditIn == NULL)
{
MessageBox(hWnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
}
hEditOut = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 500, 244, 55, hWnd, (HMENU)IDC_EDITO, GetModuleHandle(NULL), NULL);
if(hEditOut == NULL)
{
MessageBox(hWnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
}
hBtnSend = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", NULL, WS_CHILD | WS_VISIBLE, 244, 500, 50, 55, hWnd, (HMENU)IDC_BTNS, GetModuleHandle(NULL), NULL);
if(hBtnSend == NULL)
{
MessageBox(hWnd, "Could not create button.", "Error", MB_OK | MB_ICONERROR);
}
break;
case WM_SIZE:
SetDlgItemText(hWnd, IDC_BTNS, "Send");
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_LISTEN:
if (listen(sListen, 1) == SOCKET_ERROR)
{
MessageBox(NULL, "Error in listening", "Error!", NULL);
WSACleanup();
}
break;
case ID_FILE_SLISTEN:
SetDlgItemText(hWnd, IDC_EDITI, "Winsock Shut Down.");
closesocket(sClient);
closesocket(sListen);
WSACleanup();
break;
case ID_FILE_EXIT:
PostQuitMessage(0);
break;
case ID_ABOUT_HELP:
MessageBox(NULL, "Programmer: Steven Merrick", "About Lithnet Chat", NULL);
break;
case IDC_BTNS:
char buffer[256];
memset(buffer, 0, sizeof(buffer)); // Clears the buffer.
GetDlgItemText(hWnd, IDC_EDITO, buffer, sizeof(buffer));
send(sClient, buffer, sizeof(buffer), 0);
SetDlgItemText(hWnd, IDC_EDITO, "");
break;
}
break;
case SOCKET_READY:
if (WSAGETSELECTERROR(lParam))
{
WSACleanup();
return(0);
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
sClient = accept(sListen, NULL, NULL);
if (sClient == SOCKET_ERROR)
{
MessageBox(NULL, "Error in accepting", "Error!", NULL); // Cout an error message.
WSACleanup(); // Shutdown Winsock
}
SetDlgItemText(hWnd, IDC_EDITI, "Connection recieved.");
break;
case FD_READ:
char buffer[256];
memset(buffer, 0, sizeof(buffer)); // Clears the buffer.
if (recv(sClient, buffer, sizeof(buffer), 0) == SOCKET_ERROR)
{
MessageBox(NULL, "Error in recv()", "Error", NULL);
}
SetDlgItemText(hWnd, IDC_EDITI, buffer);
break;
case FD_CLOSE:
SetDlgItemText(hWnd, IDC_EDITI, "Client disconnected.");
break;
}
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return(0);
}