Автор работы: Пользователь скрыл имя, 17 Июня 2013 в 00:52, курсовая работа
Активно внедряя автоматизацию в сферу рассылки и получения новостей, руководство Министерства информации четко определило главную цель: повышение качества и уровня доставки информации, создание оптимальных условий для получения информации к пользователю. Успех в этой работе во многом зависит от того, насколько технологически грамотно весь этот сложный программно-технический комплекс будет использован для главной цели его создания – эффективной рассылки и получения новостей посредством технологии клиент – сервер на основе WINDOWS SOCKETS используя API функции.
Целью данной работы является составление программного обеспечения для рассылки и получения.
Введение………………………………………….……………………………………41 Обзор состояния вопроса ель и задачи работы…………….……………………...5
2 Постановка задачи………………………………………………….………..……...7
3 Моделирование ПО……………………………….………………………………...8
3.1 Архитектура ПО…………………………….…………………………………..8
3.2 Интерфейс пользователя………………………………………………………11
3.3 Описание основных функциональных модулей……………………………..14
3.4 Структура классов и объектов………………………………………………...24
4 Реализация ПО……………………………………………………………………..28
5 Руководство пользователя………………………………...………………………29
Заключение…………………………...………………………………………………34Список используемой литературы…………………………………………...……..35
ПРИЛОЖЕНИЕ – ЛИСТИНГ
MAIN. CPP
#include "Client.h"
#include <windows.h>
#include "Output.h"
#include "resource.h"
#define BUFSIZE 512
#define IDC_OUTPUT 555
LRESULT CALLBACK ConnectProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChatProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK EditProc(HWND edit, UINT msg, WPARAM wParam, LPARAM lParam);
void OnReader(const CHAR* buf, int size);
void OnError(int code);
void MessageError(HWND hwnd, int code);
Output* edit_out = NULL;
Client* tcp_client = NULL;
CHAR user_name[17] = "none";
WNDPROC edit_proc = NULL;
HWND chat_wnd = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
xTCPClient::Init();
int result = DialogBoxA(hInstance, MAKEINTRESOURCEA(IDD_CONNECT), NULL, (DLGPROC)ConnectProc);
if(result != 0)
DialogBoxParamA(hInstance, MAKEINTRESOURCEA(IDD_CHAT), NULL, (DLGPROC)ChatProc, (LPARAM)(HINSTANCE)hInstance);
if(tcp_client != NULL)
delete tcp_client;
tcp_client = NULL;
Client::Free();
return 0;
}
LRESULT CALLBACK ChatProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
int len;
switch(msg) {
case WM_INITDIALOG:
chat_wnd = hDlg;
edit_proc = (WNDPROC) SetLong(GetDlgItem(hDlg, IDC_INPUT), GWL_WNDPROC, (LONG)EditProc);
ZeroMemory(buf, sizeof(buf));
SendDlgItemMessage(hDlg, IDC_INPUT, EM_LIMITTEXT, (WPARAM)int(BUFSIZE - 16), 0);
edit_out = new xEditOutput((HINSTANCE)lParam)
edit_out->Create(hDlg, 10, 17, 316, 320, IDC_OUTPUT);
SendDlgItemMessageA(hDlg, IDC_DELETE, BM_SETIMAGE,
IMAGE_ICON, (LPARAM)(HICON)LoadIconA((
return TRUE;
case WM_COMMAND:
if(LOWORD(wParam) == IDC_SEND) {
if(GetWindowTextLengthA(
break;
len = (int)wsprintfA(buf, "%s|", user_name);
GetDlgItemTextA(hDlg, IDC_INPUT, buf + len, BUFSIZE - 1);
if(! tcp_client->Send(buf, len)) {
MessageError(hDlg, len);
break;
}
GetDlgItemTextA(hDlg, IDC_INPUT, buf, BUFSIZE - 1);
edit_out->Add(user_name, buf, true);
SetDlgItemTextA(hDlg, IDC_INPUT, "");
} else if(LOWORD(wParam) == IDC_DELETE) {
if(edit_out->GetSize() == 0u)
break;
if(MessageBoxA(hDlg, "Âû òî÷íî õîòèòå óäàëèòü âñå ñîîáùåíèÿ, Äà èëè Íåò ?", "Óäàëåíèå", MB_YESNO | MB_ICONQUESTION) == IDYES)
edit_out->Clear();
}
break;
case WM_CLOSE:
if(edit_out != NULL)
delete edit_out;
edit_out = NULL;
EndDialog(hDlg, 0);
break;
}
return FALSE;
}
void OnError(int code) {
MessageError(GetActiveWindow()
ExitProcess(0u);
}
void MessageError(HWND hwnd, int code) {
HLOCAL local = NULL;
FormatMessageA(FORMAT_MESSAGE_
NULL, DWORD(code), MAKELANGID(LANG_USER_DEFAULT, SUBLANG_ENGLISH_US), (CHAR*)&local, 0, NULL);
if(local != NULL) {
MessageBoxA(hwnd, (const CHAR*)LocalLock(local), "Îøèáêà", MB_OK | MB_ICONSTOP);
LocalUnlock(local);
LocalFree(local);
local = NULL;
}
}
LRESULT CALLBACK ConnectProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
int err = 0;
CHAR hostname[64] = "localhost";
USHORT port = 7777u;
switch(msg) {
case WM_INITDIALOG:
tcp_client = new xTCPClient();
SetDlgItemTextA(hDlg, IDC_IP_ADDR, hostname);
SetDlgItemInt(hDlg, IDC_PORT, UINT(port), FALSE);
SetDlgItemTextA(hDlg, IDC_USERNAME, user_name);
SendDlgItemMessage(hDlg, IDC_USERNAME, EM_LIMITTEXT, (WPARAM)16, 0);
SendDlgItemMessage(hDlg, IDC_IP_ADDR, EM_LIMITTEXT, (WPARAM)64, 0);
return TRUE;
case WM_COMMAND:
if(LOWORD(wParam) == IDC_CONNECT) {
if(GetWindowTextLengthA(
break;
GetDlgItemTextA(hDlg, IDC_IP_ADDR, hostname, sizeof(hostname) - 1);
port = (USHORT) GetDlgItemInt(hDlg, IDC_PORT, NULL, FALSE) & 0xFFFF;
if(GetWindowTextLengthA(
MessageBoxA(hDlg, "Âû íå çàäàëè èìÿ â ÷àòå !", "Îøèáêà", MB_OK | MB_ICONEXCLAMATION);
break;
}
GetDlgItemTextA(hDlg, IDC_USERNAME, user_name, 16);
if(! tcp_client->Create(hostname, port, err, OnReader, OnError)) {
MessageError(hDlg, err);
break;
}
EndDialog(hDlg, 1);
} else if(LOWORD(wParam) == IDC_EXIT)
EndDialog(hDlg, 0);
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
}
return FALSE;
}
LRESULT CALLBACK EditProc(HWND edit, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_CHAR:
if((LOWORD(wParam) == VK_RETURN) && int(SendDlgItemMessage(chat_
SendMessage(chat_wnd, WM_COMMAND, MAKEWPARAM(IDC_SEND, 0), 0);
PeekMessage(NULL, edit, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE);
return 0;
}
break;
}
return CallWindowProcA(edit_proc, edit, msg, wParam, lParam);
}
OUTPUT.CPP
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include "xEditOutput.h"
#define CLASS_NAME "Output"
Output:: Output(HINSTANCE hInstance) {
cparent = NULL;
cwnd = NULL;
cInstance = hInstance;
cid = 0u;
font = NULL;
bitmap = NULL;
bdc = NULL;
bmp_border = NULL;
dc_border = NULL;
bmp_border2 = NULL;
dc_border2 = NULL;
brush_back = NULL;
brush_back2 = NULL;
size_txt.cx = 0L;
size_txt.cy = 0L;
}
BOOL Output::Create(HWND parent, int x, int y, int width, int height, UINT ID) {
CHAR cls[32] = {'\0'};
wsprintfA(cls, "%s%u", CLASS_NAME, ID);
WNDCLASSA struc = {
0u, Output::WndProc, 0, 0, cInstance, NULL,
LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW)), NULL, NULL, cls
};
if(! RegisterClassA(&struc))
return FALSE;
size_txt.cx = (long)width - GetSystemMetrics(SM_CXVSCROLL)
size_txt.cy = 0L;
ZeroMemory(§ion, sizeof(CRITICAL_SECTION));
InitializeCriticalSection(&
cwnd = CreateWindowA(cls, "", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, x, y, width, height,
parent, (HMENU)ID, cInstance, (LPVOID)this);
if(! cwnd) {
UnregisterClassA(cls, cInstance);
return FALSE;
}
ShowWindow(cwnd, SW_SHOW);
UpdateWindow(cwnd);
cparent = parent;
cid = ID;
return TRUE;
}
// Îáðàáîò÷èê ñîáûòèé-ñîîáùåíèé ýëåìåíòà óïðàâëåíèÿ(îêíî)
LRESULT Output::ControlProc(UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
RECT rect;
SIZE size;
HGDIOBJ old;
PAINTSTRUCT paint;
SCROLLINFO sinfo;
int i, off;
switch(msg) {
case WM_CREATE:
hdc = GetDC(cwnd);
// çàëèâêà öâåò-êîíòðîëà
FillRect(bdc, &rect, (HBRUSH)GetStockObject(WHITE_
SetBkMode(bdc, TRANSPARENT);
SelectObject(bdc, font);
if(! GetTextExtentPointA(bdc, "a", 1, &size))
GetTextExtentPoint32A(bdc, "a", 1, &size);
font_cy = abs(size.cy);
// ñîçäà¸ì îñòàëüíûå àòðèáóòû òåêñòîâûõ áëîêîâ
brush_back = CreateSolidBrush(RGB(200, 245, 255));
brush_back2 = CreateSolidBrush(RGB(230, 230, 230));
GetClientRect(cwnd, &rect);
dc_border = CreateCompatibleDC(hdc);
bmp_border = CreateCompatibleBitmap(hdc, size_txt.cx + 4, font_cy);
SelectObject(dc_border, bmp_border);
dc_border2 = CreateCompatibleDC(hdc);
bmp_border2 = CreateCompatibleBitmap(hdc, size_txt.cx + 4, font_cy);
SelectObject(dc_border2, bmp_border2);
old = SelectObject(dc_border, (HGDIOBJ)GetStockObject(DC_
for(i = 0; i < font_cy; i++) {
SetDCPenColor(dc_border, RGB(200 - i * 5, 255 - i * 5, 255 - i * 5));
MoveToEx(dc_border, 0, i, NULL);
LineTo(dc_border, size_txt.cx, i);
}
SelectObject(dc_border, old);
old = SelectObject(dc_border2, (HGDIOBJ)GetStockObject(DC_
for(i = 0; i < font_cy; i++) {
SetDCPenColor(dc_border2, RGB(255 - min(i * 7, 255), 255 - min(i * 7, 255), 255 - min(i * 7, 255)));
MoveToEx(dc_border2, 0, i, NULL);
LineTo(dc_border2, size_txt.cx, i);
}
SelectObject(dc_border2, old);
ReleaseDC(cwnd, hdc);
break;
case WM_PAINT:
hdc = BeginPaint(cwnd, &paint);
BitBlt(hdc, 0, paint.rcPaint.top, paint.rcPaint.right, paint.rcPaint.bottom, bdc, 0, 0, SRCCOPY);
EndPaint(cwnd, &paint);
break;
case WM_NCPAINT:
InvalidateRect(cwnd, NULL, FALSE);
break;
case WM_MOUSEMOVE:
SetFocus(cwnd);
break;
case WM_MOUSEWHEEL:
if(HIWORD(wParam) > 120)
SendMessage(cwnd, WM_VSCROLL, MAKEWPARAM(SB_PAGEDOWN, 0), 0);
else
SendMessage(cwnd, WM_VSCROLL, MAKEWPARAM(SB_PAGEUP, 0), 0);
break;
case WM_VSCROLL:
sinfo.cbSize = sizeof(SCROLLINFO);
sinfo.fMask = SIF_ALL;
GetScrollInfo(cwnd, SB_VERT, &sinfo);
off = sinfo.nPos;
sinfo.fMask = SIF_POS;
switch(LOWORD(wParam)) {
case SB_THUMBTRACK:
sinfo.nPos = sinfo.nTrackPos;
break;
case SB_LINEUP:
sinfo.nPos--;
break;
case SB_LINEDOWN:
sinfo.nPos++;
break;
case SB_PAGEUP:
sinfo.nPos -= 8;
break;
case SB_PAGEDOWN:
sinfo.nPos += 8;
break;
}
SetScrollInfo(cwnd, SB_VERT, &sinfo, TRUE);
i = GetScrollPos(cwnd, SB_VERT);
if(off != i) {
this->update(true);
ScrollWindow(cwnd, 0, off - i, NULL, NULL);
UpdateWindow(cwnd);
InvalidateRect(cwnd, NULL, TRUE);
}
break;
case WM_DESTROY:
this->Destroy();
break;
}
return DefWindowProcA(cwnd, msg, wParam, lParam);
void Output::Destroy(void) {
DeleteCriticalSection(&
if(bmp_border != NULL)
DeleteObject(bmp_border);
bmp_border = NULL;
if(dc_border != NULL)
DeleteDC(dc_border);
dc_border = NULL;
if(bmp_border2 != NULL)
DeleteObject(bmp_border2);
bmp_border2 = NULL;
if(dc_border2 != NULL)
DeleteDC(dc_border2);
dc_border2 = NULL;
if(brush_back != NULL)
DeleteObject(brush_back);
brush_back = NULL;
if(brush_back2 != NULL)
DeleteObject(brush_back2);
brush_back2 = NULL;
if(bitmap != NULL)
DeleteObject(bitmap);
bitmap = NULL;
if(bdc != NULL)
DeleteDC(bdc);
bdc = NULL;
if(cwnd != NULL)
DestroyWindow(cwnd);
cwnd = NULL;
if(msgs.size() > 0u)
msgs.clear();
size_txt.cx = size_txt.cy = font_cy = 0L;
}
LRESULT CALLBACK Output::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
Output* obj = NULL;
if(msg == WM_CREATE) {
LPCREATESTRUCTA ptr = (LPCREATESTRUCTA)lParam;
SetLong(hwnd, GWL_USERDATA, (DWORD)ptr->lpCreateParams);
((Output*)ptr->lpCreateParams)
}
if((obj = reinterpret_cast<xEditOutput*>
return obj->ControlProc(msg, wParam, lParam);
return DefWindowProcA(hwnd, msg, wParam, lParam);
}
void Output::Clear(void) {
if(msgs.size() > 0u) {
EnterCriticalSection(§ion)
msgs.clear();
size_txt.cy = 0L;
this->update();
InvalidateRect(cwnd, NULL, TRUE);
LeaveCriticalSection(§ion)
void xEditOutput::Add(const CHAR* user, const CHAR* msg, bool my) {
SYSTEMTIME tcur;
ZeroMemory(&tcur, sizeof(SYSTEMTIME));
GetLocalTime(&tcur);
CHAR buf[10];
wsprintfA(buf, "%02d:%02d:%02d", tcur.wHour, tcur.wMinute, tcur.wSecond);
RECT rect;
SetRect(&rect, 0, 0, size_txt.cx, font_cy);
int height = DrawTextA(bdc, msg, lstrlenA(msg), &rect, DT_WORDBREAK | DT_LEFT | DT_CALCRECT);
EnterCriticalSection(§ion)
msgs.push_back(xMsg(user, msg, buf, rect.bottom + font_cy, my));
size_txt.cy += (rect.bottom + font_cy);
this->update(false);
InvalidateRect(cwnd, NULL, TRUE);
LeaveCriticalSection(§ion)
}
void xEditOutput::update(bool reset) {
SCROLLINFO sinfo;
COLORREF col1, col2, col3;
HBRUSH brush;
int y = 0;
RECT rect;
RECT rc;
GetClientRect(cwnd, &rc);
PatBlt(bdc, 0, 0, rc.right, rc.bottom, WHITENESS);
y -= GetScrollPos(cwnd, SB_VERT);
for(size_t i = 0u; i < msgs.size(); i++) {
if(y > -100) {
if(msgs[i].my) {
col1 = RGB(47, 47, 47);
col2 = RGB(111, 111, 111);
col3 = RGB(100, 100, 100);
brush = brush_back2;
BitBlt(bdc, 2, y, size_txt.cx, font_cy, dc_border2, 0, 0, SRCCOPY);
} else {
col1 = RGB(0, 99, 99);
col2 = RGB(60, 175, 175);
col3 = RGB(0, 0, 0);
brush = brush_back;
BitBlt(bdc, 2, y, size_txt.cx, font_cy, dc_border, 0, 0, SRCCOPY);
}
SetTextColor(bdc, col1);
TextOutA(bdc, 4, y, msgs[i].user, msgs[i].len_user);
SetTextColor(bdc, col2);
TextOutA(bdc, size_txt.cx - 43, y, msgs[i].date, msgs[i].len_date);
SetRect(&rect, 4, y + font_cy, size_txt.cx, y + msgs[i].height);
InflateRect(&rect, 2, 0);
FillRect(bdc, &rect, brush);
Resourse. h
#define IDD_CONNECT
#define IDD_CHAT
#define IDI_ICON1
#define IDI_ICON3
#define IDC_IP_ADDR
#define IDC_PORT 1001
#define IDC_CONNECT
#define IDC_EXIT
#define IDC_USERNAME
#define IDC_INPUT
#define IDC_SEND
#define IDC_ENTER 1008
#define IDC_DELETE
#define IDC_SAVE
#define IDCHAT
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE
#define _APS_NEXT_COMMAND_VALUE
#define _APS_NEXT_CONTROL_VALUE
#define _APS_NEXT_SYMED_VALUE
#endif
#endif
OUTPUT. H
#if ! defined(__)
#define _
#pragma once
#include <vector>
#ifdef WIN32
#define GetLong(wnd, index) GetWindowLongA(wnd, index)
#define SetLong(wnd, index, val) SetWindowLongA(wnd, index, val)
#else // WIN64
#define GetLong(wnd, index) GetWindowLongPtrA(wnd, index)
#define SetLong(wnd, index, val) SetWindowLongPtrA(wnd, index, val)
#endif
struct xMsg {
CHAR user[16];
CHAR msg[512 - 16];
CHAR date[10];
int len_user;
int len_msg;
int len_date;
int height;
bool my;
xMsg(void) {}
xMsg(const CHAR* user, const CHAR* msg, const CHAR* date, int height, bool my) {
lstrcpyA(this->user, user);
lstrcpyA(this->msg, msg);
lstrcpyA(this->date, date);
this->height = height;
this->my = my;
len_user = (int)lstrlenA(user);
len_msg = (int)lstrlenA(msg);
len_date = (int)lstrlenA(date);
}
};
class Output {
private:
HWND cparent;
HWND cwnd;
HINSTANCE cInstance;
UINT cid;
HFONT font;
HBITMAP bitmap;
HDC bdc;
SIZE size_txt;
long font_cy;
HBITMAP bmp_border;
HDC dc_border;
HBITMAP bmp_border2;
HDC dc_border2;
HBRUSH brush_back;
HBRUSH brush_back2;
CRITICAL_SECTION section;
std::vector<xMsg> msgs;
public:
Output(HINSTANCE hInstance);
~Output();
public:
BOOL Create(HWND parent, int x, int y, int width, int height, UINT ID);
void Destroy(void);
void Add(const CHAR* user, const CHAR* msg, bool my = false);
void Clear(void);
size_t GetSize(void) const {
return msgs.size();
}
private:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT ControlProc(UINT message, WPARAM wParam, LPARAM lParam);
private:
void update(bool reset = false);
};
#endif
CLIENT.H
#if ! defined(__)
#define __
#pragma once
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define BUFSIZE 512
class Client {
typedef void (OnRead)(const CHAR* buf, int size);
typedef void (OnError)(int code);
private:
SOCKET client;
HANDLE thread;
OnRead* reader;
OnError* error;
volatile BOOL loop;
public:
Client(void) {
thread = NULL;
client = 0u;
loop = FALSE;
reader = NULL;
error = NULL;
}
~Client() {
this->Close();
}
public:
BOOL Create(const CHAR* host_ip, USHORT port, int& err, OnRead* on_read = NULL, OnError* on_error = NULL) {
hostent* host = NULL;
// ñîçäà¸ì ñîêåò
client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(client == INVALID_SOCKET) { // WSAGetLastError
err = WSAGetLastError();
return FALSE;
}
sockaddr_in addr;
ZeroMemory(&addr, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(host_ip);
if(addr.sin_addr.s_addr == INADDR_NONE) {
if((host = gethostbyname(host_ip)) == NULL) {
err = WSAGetLastError();
return FALSE;
}
CopyMemory(&addr.sin_addr, host->h_addr_list[0], host->h_length);