Hej her er sourcen
Main:
#include <windows.h>
#include <commctrl.h>
#include <string.h>
#include <stdio.h>
#include "chatres.h"
#include "registry.h"
#define RX_THREAD_MESSAGE WM_APP
#define REG_KEY "Software\\\\4lph4Apps\\\\P2P-Chat"
const short SocketPort = 5011;
static BOOL CALLBACK DialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
SOCKET Socket;
char IPAddressStr[128];
void CleanUp(HWND aHwnd);
struct in_addr RxAddr;
bool HasRxAddr;
bool RunRxThread = true;
bool RxThreadDone = false;
/* Add a line of text to the list box
** Make sure the line is visible Scroll as requred
** Adjust the horz scrollbar */
void AddListText(HWND aMainWnd, const char *aMsg)
{
static int MaxWidth;
int idx;
HWND List;
HDC dc;
HFONT Font, OldFont;
SIZE TextSize, SizeExtra;
List = GetDlgItem(aMainWnd, IDC_LIST);
idx = SendMessage(List, LB_ADDSTRING, 0, (LPARAM )aMsg);
SendMessage(List, LB_SETCARETINDEX, idx, 0);
dc = GetDC(List);
Font = (HFONT )SendMessage(aMainWnd, WM_GETFONT, 0, 0);
OldFont = (HFONT )SelectObject(dc, Font);
GetTextExtentPoint32(dc, aMsg, strlen(aMsg), &TextSize);
GetTextExtentPoint32(dc, "WWW", 3, &SizeExtra);
TextSize.cx += SizeExtra.cx;
if(TextSize.cx > MaxWidth)
{
MaxWidth = TextSize.cx;
SendMessage(List, LB_SETHORIZONTALEXTENT, MaxWidth, 0);
}
SelectObject(dc, OldFont);
ReleaseDC(List, dc);
}
/* Grab the text from the edit-box and send it on the socket.
** The text is appended to the list-box
*/
void HandleSend(HWND aHwnd)
{
char text[128], buffer[130];
struct sockaddr_in sockaddr;
GetDlgItemText(aHwnd, IDC_EDIT, text, sizeof(text));
sprintf(buffer, ">%s", text);
AddListText(aHwnd, buffer);
SetDlgItemText(aHwnd, IDC_EDIT, "");
memset((char *)&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
if(IPAddressStr[0])
sockaddr.sin_addr.s_addr = inet_addr(IPAddressStr);
else if(HasRxAddr)
sockaddr.sin_addr.s_addr = RxAddr.s_addr;
else
{
MessageBox(aHwnd, "No peer address", "P2P-Chat", MB_OK);
return;
}
if(sockaddr.sin_addr.s_addr == INADDR_NONE)
{
MessageBox(aHwnd, "Failed to convert IPAddress!", "P2P-Chat", MB_OK);
return;
}
sockaddr.sin_port = htons(SocketPort);
if(sendto(Socket, text, strlen(text) + 1, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
char Msg[1024];
sprintf(Msg, "Error: %d", WSAGetLastError());
MessageBox(aHwnd, Msg, "P2P-Chat", MB_OK);
}
}
/* Dialog Function for the SetupDialog */
static BOOL CALLBACK SetupDialogFunc(HWND aDlg, UINT aMsg, WPARAM wParam, LPARAM lParam)
{
switch(aMsg)
{
case WM_INITDIALOG:
{
RegistryClass Registry(REG_KEY);
Registry.GetString("IPAddress", IPAddressStr, sizeof(IPAddressStr));
SetDlgItemText(aDlg, IDC_SETUP_EDIT, IPAddressStr);
}
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
GetDlgItemText(aDlg, IDC_SETUP_EDIT, IPAddressStr, sizeof(IPAddressStr));
RegistryClass Registry(REG_KEY);
Registry.WriteString("IPAddress", IPAddressStr);
EndDialog(aDlg, 1);
return 1;
}
}
break;
case WM_CLOSE:
EndDialog(aDlg, 0);
return TRUE;
}
return FALSE;
}
/* Show the Setupdialog */
BOOL DoSetupDialog(HINSTANCE hinst)
{
return DialogBox(hinst, MAKEINTRESOURCE(IDD_SETUP_DLG), NULL, (DLGPROC )SetupDialogFunc);
}
DWORD WINAPI RxThreadProc(LPVOID Param)
{
bool First = true;
while(RunRxThread)
{
fd_set ReadSet;
FD_ZERO(&ReadSet);
FD_SET(Socket, &ReadSet);
timeval TimeOut;
TimeOut.tv_sec = 1;
TimeOut.tv_usec = 0;
if(select(Socket + 1, &ReadSet, 0, 0, &TimeOut) == 1)
{
const int MaxLineLength = 256;
char *buffer = new char [MaxLineLength];
sockaddr_in RxSockAddr;
int FromLen = sizeof(RxSockAddr);
if(recvfrom(Socket, buffer, MaxLineLength, 0, (sockaddr *)&RxSockAddr, &FromLen) != SOCKET_ERROR)
{
PostMessage((HWND )Param, RX_THREAD_MESSAGE, (WPARAM )buffer, 0);
RxAddr = RxSockAddr.sin_addr;
HasRxAddr = true;
}
else
{
delete [] buffer;
if(First)
{
char Buf[256];
sprintf(Buf, "Error: %d", WSAGetLastError());
MessageBox((HWND )Param, Buf, "P2P-Chat", MB_OK);
First = false;
}
}
}
}
RxThreadDone = true;
return 0;
}
int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, int nCmdShow)
{
if(!DoSetupDialog(hinst))
{
return 1;
}
return DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINDIALOG), 0, (DLGPROC )DialogFunc);
}
/*
** Create the socket, and start the RX thread.
*/
int SetupSocket(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
WSADATA wsaData;
struct sockaddr_in sockaddr;
if(WSAStartup(MAKEWORD(1, 1), &wsaData))
{
MessageBox(hDlg, "Failed to start WSA", "P2P-Chat", MB_OK);
return 1;
}
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if(Socket == INVALID_SOCKET)
{
MessageBox(hDlg, "Failed To Create Socket!", "P2P-Chat", MB_OK);
return 1;
}
memset((char *)&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(SocketPort);
BOOL Flag = TRUE;
setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&Flag, sizeof(Flag));
if(bind(Socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
{
MessageBox(0, "Failed to bind socket!", "P2P-Chat", MB_OK);
return 1;
}
DWORD RxThreadID;
CreateThread(0, 0, RxThreadProc, (LPVOID )hDlg, 0, &RxThreadID);
return 1;
}
void OnSize(HWND aMainWnd, int aWidth, int aHeight)
{
HWND hwnd;
hwnd = GetDlgItem(aMainWnd, IDC_SEND);
MoveWindow(hwnd, 5, aHeight - 25, 50, 20, TRUE);
hwnd = GetDlgItem(aMainWnd, IDOK);
MoveWindow(hwnd, 70, aHeight - 25, 50, 20, TRUE);
hwnd = GetDlgItem(aMainWnd, IDC_EDIT);
MoveWindow(hwnd, 5, aHeight - 55, aWidth - 10, 25, TRUE);
hwnd = GetDlgItem(aMainWnd, IDC_LIST);
MoveWindow(hwnd, 5, 5, aWidth - 10, aHeight - 65, TRUE);
}
/*
** This is the main function for the main dialog. It handles all messages.
*/
static BOOL CALLBACK DialogFunc(HWND aDlg, UINT aMsg, WPARAM wParam, LPARAM lParam)
{
switch(aMsg)
{
case WM_INITDIALOG:
{
SetupSocket(aDlg, wParam, lParam);
HWND Edit = GetDlgItem(aDlg, IDC_EDIT);
SetFocus(Edit);
RegistryClass Registry(REG_KEY);
RECT R;
R.left = Registry.GetInt("LeftPos", -1);
if(R.left != -1)
{
R.right = Registry.GetInt("RightPos", R.left + 200);
R.top = Registry.GetInt("TopPos", 100);
R.bottom = Registry.GetInt("BottomPos", R.top + 200);
MoveWindow(aDlg, R.left, R.top, R.right - R.left, R.bottom - R.top, TRUE);
}
else
{
GetClientRect(aDlg, &R);
OnSize(aDlg, R.right - R.left, R.bottom - R.top);
}
return FALSE;
}
case RX_THREAD_MESSAGE:
{
char *text = (char *)wParam;
AddListText(aDlg, text);
delete [] text;
break;
}
case WM_GETMINMAXINFO:
{
MINMAXINFO *MinMaxInfo = (MINMAXINFO *)lParam;
MinMaxInfo->ptMinTrackSize.x = 200;
MinMaxInfo->ptMinTrackSize.y = 200;
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
CleanUp(aDlg);
EndDialog(aDlg,1);
return 1;
case IDC_SEND:
HandleSend(aDlg);
return 0;
}
break;
case WM_CLOSE:
CleanUp(aDlg);
EndDialog(aDlg, 0);
return TRUE;
case WM_SIZE:
OnSize(aDlg, LOWORD(lParam), HIWORD(lParam));
return 0;
}
return FALSE;
}
void CleanUp(HWND aHwnd)
{
RunRxThread = false;
RegistryClass Registry(REG_KEY);
RECT R;
GetWindowRect(aHwnd, &R);
Registry.WriteInt("LeftPos", R.left);
Registry.WriteInt("RightPos", R.right);
Registry.WriteInt("TopPos", R.top);
Registry.GetInt("BottomPos", R.bottom);
while(!RxThreadDone)
Sleep(100);
if(Socket)
closesocket(Socket);
Socket = 0;
WSACleanup();
}
Header:
#define IDD_MAINDIALOG 100
#define IDC_SEND 101
#define IDC_LIST 102
#define IDC_EDIT 103
#define IDD_SETUP_DLG 200
#define IDC_SETUP_EDIT 201
Registry Header:
#ifndef REGISTRY_H_INC
#define REGISTRY_H_INC
class RegistryClass
{
public:
RegistryClass(const char *aKey)
{
if(RegOpenKey(HKEY_CURRENT_USER, aKey, &KeyHandle) != ERROR_SUCCESS)
{
if(RegCreateKeyEx(HKEY_CURRENT_USER, aKey, 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &KeyHandle, 0) != ERROR_SUCCESS)
KeyHandle = 0;
}
}
~RegistryClass()
{
if(KeyHandle)
RegCloseKey(KeyHandle);
}
int GetInt(const char *aKey, int aDefaultValue = 0)
{
if(!KeyHandle)
return aDefaultValue;
DWORD Type = REG_DWORD, Size = sizeof(DWORD);
int Value;
if(RegQueryValueEx(KeyHandle, aKey, 0, &Type, (BYTE *)&Value, &Size) != ERROR_SUCCESS)
return aDefaultValue;
return Value;
}
void WriteInt(const char *aKey, int aValue)
{
if(!KeyHandle)
return;
RegSetValueEx(KeyHandle, aKey, 0, REG_DWORD, (BYTE *)&aValue, sizeof(aValue));
}
char *GetString(const char *aKey, char *aBuffer, int aMaxSize)
{
if(!KeyHandle)
{
*aBuffer = 0;
return aBuffer;
}
DWORD Type = REG_SZ, Size = aMaxSize;
if(RegQueryValueEx(KeyHandle, aKey, 0, &Type, (BYTE *)aBuffer, &Size) != ERROR_SUCCESS)
*aBuffer = 0;
return aBuffer;
}
void WriteString(const char *aKey, const char *aBuffer)
{
if(!KeyHandle)
return;
RegSetValueEx(KeyHandle, aKey, 0, REG_SZ, (BYTE *)aBuffer, strlen(aBuffer));
}
private:
HKEY KeyHandle;
};
#endif
Resource:
#ifndef __BORLANDC__
#include <windows.h>
#endif
#include "chatres.h"
IDD_MAINDIALOG DIALOG 0, 0, 230, 230
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER | WS_THICKFRAME
CAPTION "P2P-Chat"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "Send", IDC_SEND, 5, 210, 40, 14, NOT WS_TABSTOP
PUSHBUTTON "Exit", IDOK, 50, 210, 40, 14
EDITTEXT IDC_EDIT, 5, 190, 220, 12, ES_AUTOHSCROLL
LISTBOX IDC_LIST, 5, 5, 220, 180, WS_VSCROLL | WS_HSCROLL | WS_TABSTOP | LBS_NOINTEGRALHEIGHT
END
IDD_SETUP_DLG DIALOG 0, 0, 140, 86
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "P2P-Chat - Setup"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter a peer IP-Address,\\r\\nor leave it empty to wait for\\r\\nan incomming message", -1, 5, 5, 150, 40
LTEXT "IP-Address:", -1, 5, 40, 100, 8
EDITTEXT IDC_SETUP_EDIT, 5, 50, 130, 12, ES_AUTOHSCROLL
PUSHBUTTON "Ok", IDOK, 10, 67, 40, 14
END
Indlæg senest redigeret d. 14.05.2008 11:59 af Bruger #10613